From fd5579a154694418c66075d97f43e5d9d741058b Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Mon, 18 Jan 2016 11:38:44 -0800 Subject: 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 --- swiftclient/client.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'swiftclient/client.py') 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 -- cgit v1.2.1