6

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

原始问题

我正在使用django_storage 的 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”。

转义内容类型

如果你说它不应该重要,它确实重要。谷歌浏览器的内置 pdf 阅读器会挂在内容类型无效的 pdf 上,一个客户引起了我的注意。

这是通过 django-storages/boto 上传的文件示例。如果您使用的是 chrome 的内置 pdf 阅读器,我认为它会挂起,就像我和报告此问题的客户一样。如果您使用的是非 chrome 浏览器或 adobe 插件,或者将文件下载到磁盘,您可能会没事。

如果我通过 AWS 控制台手动将内容类型元数据更改为“应用程序/pdf”(它提供的标准选择之一),那就没问题了。

我认为这是一个内部错误,boto 构造 AWS 策略文档以上传文件的方式,因为我没有在此处的标准用法之外做任何事情。但是,我已经逐步完成了 boto 代码,但找不到它实际上在哪里进行转义。

有人可以建议解决方法,或者指导我使用 boto 中的违规代码,以便我可以修补它并提交拉取请求吗?

boto==2.9.5 django-storages==1.1.8

4

2 回答 2

4

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

如果由于某种原因您不能切换到 cuddly-buddly 进行测试,请告诉我,我会尝试设置一个简单的 Django 项目来上传一些 PDF。

于 2013-08-26T04:11:37.940 回答
1

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

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

于 2013-10-25T23:46:54.903 回答