django-storages和amazon s3 - 可疑操作

时间:2012-09-21 17:15:01

标签: django amazon-s3 django-storage

我在Amazon S3上使用django-storage。我间歇地看到以下错误:

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:

有谁知道为什么会出现这种情况?它不会一直发生。我可以在其他情况下成功地做到这一点。

5 个答案:

答案 0 :(得分:3)

_normalize_name 在使用URL的Django内容上做了很多花哨和大多数不必要的事情。在我的情况下,我只是覆盖 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())

它适用于具有此基本配置的django simple ImageField:

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

答案 1 :(得分:2)

使用default_storage方法时,请确保使用file.name:

正确:

default_storage.delete(file.name)

错:

default_storage.delete(file.url)

错:

default_storage.delete(file)

上面的所有三个示例都使用本地文件,但是当使用s3时,除非使用file.name,否则将遇到此错误。

答案 2 :(得分:1)

我还没有让S3存储工作在我自己的项目上,但我确实遇到了这个错误,并且可能会指出你正确的方向。

如果你看一下S3BotoStorage._clean_name(),它只是:return os.path.normpath(name).replace('\\', '/')。 os.path.normpath()将URL中的 // 转换为 \\ ,然后.replace()将其转换为 \ 。然后,S3BotoStorage._normalize_name()检查以确保这个损坏的URL是它所代表的位置的一部分,当然它不是。这就是提出SuspiciousOperation错误的地方。

所以'name'看起来像是本地路径,而不是整个AWS URL。在我的情况下,立即原因是settings.py中的FILEBROWSER_DIRECTORY = MEDIA_URL + "uploads/",我曾试图修复有关丢失上传文件夹的其他错误。

答案 3 :(得分:0)

设置

MEDIA_ROOT=''

为我解决了这个问题。

答案 4 :(得分:-1)

我修复此问题,添加了SuspiciousOperation,除了:

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