summaryrefslogtreecommitdiff
path: root/swiftclient/client.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 /swiftclient/client.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 'swiftclient/client.py')
-rw-r--r--swiftclient/client.py6
1 files changed, 5 insertions, 1 deletions
diff --git a/swiftclient/client.py b/swiftclient/client.py
index 925b396..ae723a3 100644
--- a/swiftclient/client.py
+++ b/swiftclient/client.py
@@ -32,7 +32,7 @@ import six
from swiftclient import version as swiftclient_version
from swiftclient.exceptions import ClientException
from swiftclient.utils import (
- LengthWrapper, ReadableToIterable, parse_api_response)
+ iter_wrapper, LengthWrapper, ReadableToIterable, parse_api_response)
# Defautl is 100, increase to 256
http_client._MAXHEADERS = 256
@@ -1126,6 +1126,10 @@ def put_object(url, token=None, container=None, name=None, contents=None,
warn_msg = ('%s object has no "read" method, ignoring chunk_size'
% type(contents).__name__)
warnings.warn(warn_msg, stacklevel=2)
+ # Match requests's is_stream test
+ if hasattr(contents, '__iter__') and not isinstance(contents, (
+ six.text_type, six.binary_type, list, tuple, dict)):
+ contents = iter_wrapper(contents)
conn.request('PUT', path, contents, headers)
resp = conn.getresponse()