summaryrefslogtreecommitdiff
path: root/swiftclient
diff options
context:
space:
mode:
authorTim Burke <tim.burke@gmail.com>2016-01-18 11:38:44 -0800
committerTim Burke <tim.burke@gmail.com>2016-05-04 15:21:26 -0700
commitfd5579a154694418c66075d97f43e5d9d741058b (patch)
tree611819f2d2c63159982669a6131306ad5e035209 /swiftclient
parent5050027610cb4c8f20c85b7c60c1cc7f2c44121c (diff)
downloadpython-swiftclient-fd5579a154694418c66075d97f43e5d9d741058b.tar.gz
Check responses when retrying bodies
Previously, if a Range request came back 200 OK (rather than 206 Partial Content), we would mangle the response body. This could happen if there was a middleware that would silently drop Range headers, for example. Now, if the response does not include a Content-Range header, we will log a warning and seek to our previous position in the stream. If the Content-Range header has an unexpected value, we will raise an exception. Change-Id: I94d4536cc1489968d45a2b6ba7edd70c85800275
Diffstat (limited to 'swiftclient')
-rw-r--r--swiftclient/client.py17
1 files changed, 17 insertions, 0 deletions
diff --git a/swiftclient/client.py b/swiftclient/client.py
index a5c4dc3..6990ea3 100644
--- a/swiftclient/client.py
+++ b/swiftclient/client.py
@@ -249,6 +249,23 @@ class _RetryBody(_ObjectBody):
response_dict=self.response_dict,
headers=self.headers,
attempts=self.conn.attempts)
+ expected_range = 'bytes %d-%d/%d' % (
+ self.bytes_read,
+ self.expected_length - 1,
+ self.expected_length)
+ if 'content-range' not in hdrs:
+ # Server didn't respond with partial content; manually seek
+ logger.warning('Received 200 while retrying %s/%s; seeking...',
+ self.container, self.obj)
+ to_read = self.bytes_read
+ while to_read > 0:
+ buf = body.resp.read(min(to_read, self.chunk_size))
+ to_read -= len(buf)
+ elif hdrs['content-range'] != expected_range:
+ msg = ('Expected range "%s" while retrying %s/%s '
+ 'but got "%s"' % (expected_range, self.container,
+ self.obj, hdrs['content-range']))
+ raise ClientException(msg)
self.resp = body.resp
buf = self.read(length)
return buf