Skip to content

Commit 3912a89

Browse files
pomegraniteddennisv
authored andcommitted
Adds SWIFT_CONTENT_LENGTH_FROM_FD (#100)
* Bumps version to 1.2.19
1 parent 27d34cf commit 3912a89

File tree

4 files changed

+33
-3
lines changed

4 files changed

+33
-3
lines changed

README.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ Troubleshooting
186186
discussion <http://support.rc.nectar.org.au/forum/viewtopic.php?f=6&t=272>`__.
187187
If you are using temporary URLs, verify that your key is set
188188
correctly.
189+
- **I'm getting empty or truncated file uploads**: Issues with some content
190+
types may cause an incorrect `content_length` header to be sent with file
191+
uploads, resulting in 0 byte or truncated files. To avoid this, set
192+
`SWIFT_CONTENT_LENGTH_FROM_FD: True`.
193+
189194

190195
Quickstart
191196
----------

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name='django-storage-swift',
5-
version='1.2.18',
5+
version='1.2.19',
66
description='OpenStack Swift storage backend for Django',
77
long_description=open('README.rst').read(),
88
url='https://github.com/dennisv/django-storage-swift',

swift/storage.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ class SwiftStorage(Storage):
142142
auto_overwrite = setting('SWIFT_AUTO_OVERWRITE', False)
143143
lazy_connect = setting('SWIFT_LAZY_CONNECT', False)
144144
content_type_from_fd = setting('SWIFT_CONTENT_TYPE_FROM_FD', False)
145+
content_length_from_fd = setting('SWIFT_CONTENT_LENGTH_FROM_FD', True)
145146
_token_creation_time = 0
146147
_token = ''
147148
_swift_conn = None
@@ -265,7 +266,12 @@ def _save(self, name, content, headers=None):
265266
content.seek(0)
266267
else:
267268
content_type = mimetypes.guess_type(name)[0]
268-
content_length = content.size
269+
270+
if self.content_length_from_fd:
271+
content_length = content.size
272+
else:
273+
content_length = None
274+
269275
self.swift_conn.put_object(self.container_name,
270276
name,
271277
content,

tests/tests.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,12 +288,31 @@ def test_save_non_rewound(self):
288288
content_file.seek(5)
289289

290290
def mocked_put_object(cls, url, token, container, name=None,
291-
contents=None, *args, **kwargs):
291+
contents=None, content_length=None, *args, **kwargs):
292292
content['saved'] = contents.read()
293+
content['size'] = content_length
293294

294295
with patch('tests.utils.FakeSwift.put_object', new=classmethod(mocked_put_object)):
295296
self.backend.save('test.txt', content_file)
296297
self.assertEqual(content['saved'], content['orig'])
298+
self.assertEqual(content['size'], len(content['orig']))
299+
300+
def test_no_content_length_from_fd(self):
301+
"""Test disabling content_length_from_fd on save"""
302+
backend = self.default_storage('v3', content_length_from_fd=False)
303+
content = dict(orig="Hello world!")
304+
content_file = ContentFile("")
305+
content_file.write(content['orig'])
306+
307+
def mocked_put_object(cls, url, token, container, name=None,
308+
contents=None, content_length=None, *args, **kwargs):
309+
content['saved'] = contents.read()
310+
content['size'] = content_length
311+
312+
with patch('tests.utils.FakeSwift.put_object', new=classmethod(mocked_put_object)):
313+
backend.save('test.txt', content_file)
314+
self.assertEqual(content['saved'], content['orig'])
315+
self.assertIsNone(content['size'])
297316

298317
def test_open(self):
299318
"""Attempt to open a object"""

0 commit comments

Comments
 (0)