使用S3BotoStorage上传到S3的文件最终会导致无效转义的内容类型元数据

时间:2013-08-15 23:30:43

标签: django amazon-s3 boto django-storage

FACEPALM UPDATE :事实证明我忘记/忽略了我使用https://github.com/gtaylor/django-athumb的旧版S3BotoStorage作为我的默认存储空间(即使我安装了django-storage) )。当前版本的django-storages没有遇到这个问题。问题是内容类型标题在击中boto时是unicode,而boto在将其发送到AWS之前使用urllib.quoteplus转义unicode。这不是Boto的错,因为每个HTTP都必须以某种方式将头转换为非unicode字符串。有关更深入的分析,请参阅https://github.com/boto/boto/issues/1669

原始问题

我正在将django_storage's S3BotoStorage与FileField结合使用,以将文件上传到Amazon S3。这是我的领域:

downloadable_file = FileField(max_length=255, upload_to="widgets/filedownloads", verbose_name="file") 

在设置中:

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' 

就上传/下载而言,一切都有效。

然而,文件存储在我的存储桶中,内容类型不正确。当我查看AWS S3控制台中文件的元数据时,文件的Content-Type显示为“application%2Fpdf”而不是“application / pdf”。

Escaped content type

如果您说它无关紧要,那就很重要了。谷歌Chrome的内置pdf阅读器将挂在pdf上,内容类型无效,客户端会引起我的注意。

Here's an example of a file uploaded through django-storages/boto.如果你正在使用chrome的内置pdf阅读器,我认为它会挂起,就像我和报告此内容的客户一样。如果您使用的是非Chrome浏览器或adobe插件,或者将文件下载到磁盘,您可能会没问题。

如果我通过AWS控制台手动将内容类型元数据更改为'application / pdf'(它提供的标准选项之一),那么就可以了。

我认为这是一个内部错误,boto构建AWS策略文档以上传文件的方式,因为我没有在标准用法之外做任何事情。但是,我已经介绍了boto代码,无法找到它实际逃逸的位置。

有人可以推荐一个解决方法,或者引导我查看boto中的违规代码,以便我可以修补它并提交拉取请求吗?

博托== 2.9.5 Django的存储器== 1.1.8

2 个答案:

答案 0 :(得分:4)

不是您问题的直接答案,但可能是有用的解决方法。我在使用S3的django-storage时遇到了问题。我最终尝试cuddly-buddly,并对此非常满意。作者基于django-storages的S3模块,并添加了许多修复程序。我浏览了可爱的提交,并且有一些修改影响了内容类型标题,但是我无法在没有设置新的django项目的情况下测试PDF上传。但是,我可以验证通过Django上传的所有文件在S3元数据的content-type字段中没有损坏的斜杠。

如果由于某种原因你无法转换为可爱的兄弟进行测试,请告诉我,我将尝试设置一个简单的Django项目来上传一些PDF。

答案 1 :(得分:1)

问题是我使用的是django存储的分叉/过时版本,它在将内容类型标头发送到boto之前没有正确地将内容类型标头转换为字符串,后者将unicode字符串转换为ascii字符串(根据HTTP标头的要求) )使用urllib的quoteplus转义机制。通过切换到当前版本的django-storage来解决该问题。

有关该问题的更详细分析,请参阅:https://github.com/boto/boto/issues/1669#issuecomment-27132112