diff --git a/storages/backends/s3boto3.py b/storages/backends/s3boto3.py index 1ada4936e..327f56743 100644 --- a/storages/backends/s3boto3.py +++ b/storages/backends/s3boto3.py @@ -434,8 +434,9 @@ def _save(self, name, content): cleaned_name = self._clean_name(name) name = self._normalize_name(cleaned_name) parameters = self.object_parameters.copy() + _type, encoding = mimetypes.guess_type(name) content_type = getattr(content, 'content_type', - mimetypes.guess_type(name)[0] or self.default_content_type) + _type or self.default_content_type) # setting the content_type in the key object is not enough. parameters.update({'ContentType': content_type}) @@ -443,6 +444,9 @@ def _save(self, name, content): if self.gzip and content_type in self.gzip_content_types: content = self._compress_content(content) parameters.update({'ContentEncoding': 'gzip'}) + elif encoding: + # If the content already has a particular encoding, set it + parameters.update({'ContentEncoding': encoding}) encoded_name = self._encode_name(name) obj = self.bucket.Object(encoded_name) diff --git a/tests/test_s3boto3.py b/tests/test_s3boto3.py index 09e823b4a..7bfdc95a2 100644 --- a/tests/test_s3boto3.py +++ b/tests/test_s3boto3.py @@ -126,6 +126,23 @@ def test_storage_save(self): } ) + 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) + obj = self.storage.bucket.Object.return_value + obj.upload_fileobj.assert_called_with( + content, + ExtraArgs={ + 'ContentType': 'application/octet-stream', + 'ContentEncoding': 'gzip', + 'ACL': self.storage.default_acl, + } + ) + def test_storage_save_gzip(self): """ Test saving a file with gzip enabled.