diff --git a/storages/backends/s3boto.py b/storages/backends/s3boto.py index d5d53d0e2..e5dc1fbd2 100644 --- a/storages/backends/s3boto.py +++ b/storages/backends/s3boto.py @@ -390,8 +390,9 @@ def _save(self, name, content): cleaned_name = self._clean_name(name) name = self._normalize_name(cleaned_name) headers = self.headers.copy() + _type, encoding = mimetypes.guess_type(name) content_type = getattr(content, 'content_type', - mimetypes.guess_type(name)[0] or self.key_class.DefaultContentType) + _type or self.key_class.DefaultContentType) # setting the content_type in the key object is not enough. headers.update({'Content-Type': content_type}) @@ -399,6 +400,9 @@ def _save(self, name, content): if self.gzip and content_type in self.gzip_content_types: content = self._compress_content(content) headers.update({'Content-Encoding': 'gzip'}) + elif encoding: + # If the content already has a particular encoding, set it + headers.update({'Content-Encoding': encoding}) content.name = cleaned_name encoded_name = self._encode_name(name) diff --git a/tests/test_s3boto.py b/tests/test_s3boto.py index cfcc293ab..f5bde762a 100644 --- a/tests/test_s3boto.py +++ b/tests/test_s3boto.py @@ -130,6 +130,25 @@ def test_storage_save(self): rewind=True ) + def test_storage_save_gzipped(self): + """ + Test saving a gzipped file + """ + name = 'test_storage_save.gz' + content = ContentFile("I am gzip'd") + self.storage.save(name, content) + key = self.storage.bucket.get_key.return_value + key.set_metadata.assert_called_with('Content-Type', + 'application/octet-stream') + key.set_contents_from_file.assert_called_with( + content, + headers={'Content-Type': 'application/octet-stream', + 'Content-Encoding': 'gzip'}, + policy=self.storage.default_acl, + reduced_redundancy=self.storage.reduced_redundancy, + rewind=True, + ) + def test_storage_save_gzip(self): """ Test saving a file with gzip enabled.