summaryrefslogtreecommitdiff
path: root/tests/unit/test_swiftclient.py
diff options
context:
space:
mode:
authorTim Burke <tim.burke@gmail.com>2015-12-30 11:15:02 -0800
committerTim Burke <tim.burke@gmail.com>2015-12-30 11:56:36 -0800
commit39b1a31d8a187534f54e32e9aec2cb2bb839a390 (patch)
tree7f751227c62507e686582ab54e1a20cbab434e9f /tests/unit/test_swiftclient.py
parentab65eef4ce4096410bdfec9ea7d8780f800321df (diff)
downloadpython-swiftclient-39b1a31d8a187534f54e32e9aec2cb2bb839a390.tar.gz
Wrap raw iterators to ensure we send entire contents to server
Currently, if you attempt to stream an upload from an iterator, as in def data(): yield 'foo' yield '' yield 'bar' conn.put_object('c', 'o', data()) ... requests will faithfully emit a zero-length chunk, ending the transfer. Swift will then close the connection, possibly (if Connection: keep-alive was set) after attempting to parse the next chunk as a new request. Now, Swift will receive all of the bytes from the iterable, and any zero-byte chunks will be ignored. This will be fixed in requests [1], but not until an eventual 3.0.0 release. [1] https://github.com/kennethreitz/requests/pull/2631 Change-Id: I19579ed7a0181ac3f488433e7c1839f7f7a040b8
Diffstat (limited to 'tests/unit/test_swiftclient.py')
-rw-r--r--tests/unit/test_swiftclient.py20
1 files changed, 20 insertions, 0 deletions
diff --git a/tests/unit/test_swiftclient.py b/tests/unit/test_swiftclient.py
index 317a6b5..1909c04 100644
--- a/tests/unit/test_swiftclient.py
+++ b/tests/unit/test_swiftclient.py
@@ -984,6 +984,26 @@ class TestPutObject(MockHttpTest):
data += chunk
self.assertEqual(data, raw_data)
+ def test_iter_upload(self):
+ def data():
+ for chunk in ('foo', '', 'bar'):
+ yield chunk
+ conn = c.http_connection(u'http://www.test.com/')
+ resp = MockHttpResponse(status=200)
+ conn[1].getresponse = resp.fake_response
+ conn[1]._request = resp._fake_request
+
+ c.put_object(url='http://www.test.com', http_conn=conn,
+ contents=data())
+ req_headers = resp.requests_params['headers']
+ self.assertNotIn('Content-Length', req_headers)
+ req_data = resp.requests_params['data']
+ self.assertTrue(hasattr(req_data, '__iter__'))
+ # If we emit an empty chunk, requests will go ahead and send it,
+ # causing the server to close the connection. So make sure we don't
+ # do that.
+ self.assertEqual(['foo', 'bar'], list(req_data))
+
def test_md5_mismatch(self):
conn = c.http_connection('http://www.test.com')
resp = MockHttpResponse(status=200, verify=True,