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