2012-09-21 21 views
9

Estoy usando django-storage con Amazon S3. Veo el siguiente error un tanto intermitente:django-storage y amazon s3 - operación sospechosa

name = self._normalize_name(self._clean_name(name))\n\n File \"/app/.heroku/venv/lib/python2.7/site-packages/storages/backends/s3boto.py\", line 237, in _normalize_name\n name)\n\nSuspiciousOperation: Attempted access to 'https:/plantvillage.s3.amazonaws.com/avatar/hans9_avatar.jpg' 

Nota la única / después https:.

¿Alguien sabe por qué aparece esto? No sucede todo el tiempo. Puedo hacer esto con éxito en otros casos.

+0

¿Alguien tiene una solución? –

Respuesta

1

Todavía no he conseguido que el almacenamiento S3 funcione en mi propio proyecto, pero acabo de encontrarme con este error y es posible que pueda orientarlo en la dirección correcta.

Si mira S3BotoStorage._clean_name(), es solo: return os.path.normpath(name).replace('\\', '/'). os.path.normpath() convierte el // en su URL para \\, y luego .replace() convierte a que \. Luego, S3BotoStorage._normalize_name() comprueba para asegurarse de que esta URL rota forma parte de la ubicación que representa, lo que por supuesto no es. Ahí es donde se genera el error SuspiciousOperation.

Así que 'nombre' parece que debe ser una ruta local, en lugar de toda la URL de AWS. En mi caso, la causa inmediata fue FILEBROWSER_DIRECTORY = MEDIA_URL + "uploads/" en settings.py, que había intentado con la esperanza de corregir un error diferente sobre una carpeta de carga faltante.

2

Al utilizar métodos default_storage asegúrese de utilizar el file.name:

correcta:

default_storage.delete(file.name) 

incorrecto:

default_storage.delete(file.url) 

incorrecto:

default_storage.delete(file) 

Todos tres ejemplos es anterior a trabajar con archivos locales, pero cuando usa s3 se encontrará con este error a menos que use file.name.

+0

'file.url' se procesa de forma diferente que' file.name'. También he hecho esto, pero parece más un truco que una solución real. ¿Hay alguna fuente que indique que esto es realmente correcto, además del hecho de que este método no genera una excepción? – Bryan

+0

No que yo sepa. – arctelix

+0

salvavidas amigo. – 101110101100111111101101

0

Configuración

MEDIA_ROOT='' 

solucionado el problema para mí.

3

_normalize_name hace un montón de fantasía y sobre todo innecesario en cosas de Django con la URL. En mi caso me acaba de anular el S3BotoStorage así:

class S3CustomStorage(S3BotoStorage): 
def _normalize_name(self, name): 
    """ 
    Get rid of this crap: http://stackoverflow.com/questions/12535123/django-storages-and-amazon-s3-suspiciousoperation 
    """ 
    return name 

luego utilizarlo en la propiedad de almacenamiento:

ImageField(storage=S3CustomStorage()) 

y funcionó para Django sencilla ImageField con esta configuración básica:

AWS_ACCESS_KEY_ID = 'TTTT' 
AWS_SECRET_ACCESS_KEY = 'XXXX' 
AWS_STORAGE_BUCKET_NAME = 'ZZZZ' 
-1

Lo arreglé para agregar SuspiciousOperation excepto:

class S3CustomStorage(S3BotoStorage): 
    def _normalize_name(self, name): 
     try: 
      return safe_join(self.location, name) 
     except (SuspiciousOperation, ValueError): 
      return ""