Skip to content

Commit c73680e

Browse files
authored
Fix for file-like objects without names (#368)
1 parent 4501f99 commit c73680e

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

storages/backends/s3boto3.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,18 @@ def _save(self, name, content):
430430
if self.preload_metadata:
431431
self._entries[encoded_name] = obj
432432

433+
# If both `name` and `content.name` are empty or None, your request
434+
# can be rejected with `XAmzContentSHA256Mismatch` error, because in
435+
# `django.core.files.storage.Storage.save` method your file-like object
436+
# will be wrapped in `django.core.files.File` if no `chunks` method
437+
# provided. `File.__bool__` method is Django-specific and depends on
438+
# file name, for this reason`botocore.handlers.calculate_md5` can fail
439+
# even if wrapped file-like object exists. To avoid Django-specific
440+
# logic, pass internal file-like object if `content` is `File`
441+
# class instance.
442+
if isinstance(content, File):
443+
content = content.file
444+
433445
self._save_content(obj, content, parameters=parameters)
434446
# Note: In boto3, after a put, last_modified is automatically reloaded
435447
# the next time it is accessed; no need to specifically reload it.

tests/test_s3boto3.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def test_storage_save(self):
8080

8181
obj = self.storage.bucket.Object.return_value
8282
obj.upload_fileobj.assert_called_with(
83-
content,
83+
content.file,
8484
ExtraArgs={
8585
'ContentType': 'text/plain',
8686
'ACL': self.storage.default_acl,
@@ -96,7 +96,7 @@ def test_storage_save_gzipped(self):
9696
self.storage.save(name, content)
9797
obj = self.storage.bucket.Object.return_value
9898
obj.upload_fileobj.assert_called_with(
99-
content,
99+
content.file,
100100
ExtraArgs={
101101
'ContentType': 'application/octet-stream',
102102
'ContentEncoding': 'gzip',

0 commit comments

Comments
 (0)