Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix "ValueError: seek of closed file" bug - closes #382 #905

Closed
wants to merge 3 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 30 additions & 13 deletions storages/backends/s3boto3.py
Expand Up @@ -436,20 +436,37 @@ def _open(self, name, mode='rb'):
return f

def _save(self, name, content):
cleaned_name = self._clean_name(name)
name = self._normalize_name(cleaned_name)
params = self._get_write_parameters(name, content)

if (self.gzip and
params['ContentType'] in self.gzip_content_types and
'ContentEncoding' not in params):
content = self._compress_content(content)
params['ContentEncoding'] = 'gzip'

obj = self.bucket.Object(name)
"""
We create a clone of the content file as when this is passed to
boto3 it wrongly closes the file upon upload where as the storage
backend expects it to still be open
"""
# Seek our content back to the start
content.seek(0, os.SEEK_SET)
obj.upload_fileobj(content, ExtraArgs=params)
return cleaned_name

# Create a temporary file that will write to disk after a specified
# size. This file will be automatically deleted when closed by
# boto3 or after exiting the `with` statement if the boto3 is fixed
with SpooledTemporaryFile() as content_autoclose:
# Write our original content into our copy that will be closed by boto3
content_autoclose.write(content.read())

# Upload the object which will auto close the
# content_autoclose instance
cleaned_name = self._clean_name(name)
name = self._normalize_name(cleaned_name)
params = self._get_write_parameters(name, content)

if (self.gzip and
params['ContentType'] in self.gzip_content_types and
'ContentEncoding' not in params):
content = self._compress_content(content)
params['ContentEncoding'] = 'gzip'

obj = self.bucket.Object(name)
content.seek(0, os.SEEK_SET)
nikolas marked this conversation as resolved.
Show resolved Hide resolved
obj.upload_fileobj(content, ExtraArgs=params)
nikolas marked this conversation as resolved.
Show resolved Hide resolved
return cleaned_name

def delete(self, name):
name = self._normalize_name(self._clean_name(name))
Expand Down