2012-09-21 2 views
9

Я использую django-хранилища с Amazon S3. Я вижу следующее сообщение об ошибке несколько прерывистых:django-хранилища и amazon s3 - подозрительная операция

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' 

Примечания сингла / после https:.

Кто-нибудь знает, почему это происходит? Это происходит не всегда. Я могу это сделать в других случаях.

+0

У кого-нибудь есть решение? –

ответ

1

У меня еще нет хранилища S3, работающего над моим собственным проектом, но я просто пробежал эту ошибку и мог бы указать вам в правильном направлении.

Если вы посмотрите на S3BotoStorage._clean_name(), это просто: return os.path.normpath(name).replace('\\', '/'). os.path.normpath() преобразует // в ваш URL-адрес в \\, а затем .replace() преобразует его в \. Затем S3BotoStorage._normalize_name() проверяет, является ли этот сломанный URL частью своего местоположения, что, конечно же, нет. Здесь возникает ошибка SuspiciousOperation.

Так что «имя» похоже, что оно предназначено для локального пути, а не для всего URL AWS. В моем случае, непосредственная причина была FILEBROWSER_DIRECTORY = MEDIA_URL + "uploads/" в settings.py, которую я пробовал надеяться исправить другую ошибку в отношении отсутствующей папки для загрузки.

2

При использовании default_storage методы убедитесь, что использовать file.name:

Correct:

default_storage.delete(file.name) 

Wrong:

default_storage.delete(file.url) 

Wrong:

default_storage.delete(file) 

All три примера es выше работают с локальными файлами, но при использовании s3 вы столкнетесь с этой ошибкой, если не используете file.name.

+0

'file.url' обрабатывается иначе, чем' file.name'. Я также сделал это, но это скорее похоже на взломать, чем фактическое решение. Есть ли источники, которые указывают, что это действительно правильно, кроме того, что этот метод не вызывает исключения? – Bryan

+0

Не то, что я знаю. – arctelix

+0

спасатель чувак. – 101110101100111111101101

0

Установка

MEDIA_ROOT='' 

исправлена ​​проблема для меня.

3

_normalize_name делает много причудливых и в основном ненужных вещей Django с URL-адресом. В моем случае я просто переопределить S3BotoStorage так:

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 

Затем используйте его в собственность хранения:

ImageField(storage=S3CustomStorage()) 

И работал Джанго простой ImageField с этой базовой конфигурации:

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

Я исправил это, добавив Подозрительные операции за исключением:

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