summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--swift/proxy/controllers/base.py11
-rw-r--r--test/unit/proxy/controllers/test_base.py22
2 files changed, 26 insertions, 7 deletions
diff --git a/swift/proxy/controllers/base.py b/swift/proxy/controllers/base.py
index 080d726aa..e857f575c 100644
--- a/swift/proxy/controllers/base.py
+++ b/swift/proxy/controllers/base.py
@@ -772,14 +772,16 @@ class ResumingGetter(object):
this request. This will change the Range header
so that the next req will start where it left off.
- :raises ValueError: if invalid range header
:raises HTTPRequestedRangeNotSatisfiable: if begin + num_bytes
> end of range + 1
:raises RangeAlreadyComplete: if begin + num_bytes == end of range + 1
"""
- if 'Range' in self.backend_headers:
- req_range = Range(self.backend_headers['Range'])
+ try:
+ req_range = Range(self.backend_headers.get('Range'))
+ except ValueError:
+ req_range = None
+ if req_range:
begin, end = req_range.ranges[0]
if begin is None:
# this is a -50 range req (last 50 bytes of file)
@@ -803,6 +805,9 @@ class ResumingGetter(object):
else:
self.backend_headers['Range'] = 'bytes=%d-' % num_bytes
+ # Reset so if we need to do this more than once, we don't double-up
+ self.bytes_used_from_backend = 0
+
def pop_range(self):
"""
Remove the first byterange from our Range header.
diff --git a/test/unit/proxy/controllers/test_base.py b/test/unit/proxy/controllers/test_base.py
index 1ab0037fa..b427739b2 100644
--- a/test/unit/proxy/controllers/test_base.py
+++ b/test/unit/proxy/controllers/test_base.py
@@ -875,18 +875,32 @@ class TestFuncs(unittest.TestCase):
node = {'ip': '1.2.3.4', 'port': 6200, 'device': 'sda'}
- source1 = TestSource(['abcd', '1234', 'abc', None])
- source2 = TestSource(['efgh5678'])
+ data = ['abcd', '1234', 'efgh', '5678', 'lots', 'more', 'data']
+
+ # NB: content length on source1 should be correct
+ # but that reversed piece never makes it to the client
+ source1 = TestSource(data[:2] + [data[2][::-1], None] + data[3:])
+ source2 = TestSource(data[2:4] + ['nope', None])
+ source3 = TestSource(data[4:])
req = Request.blank('/v1/a/c/o')
handler = GetOrHeadHandler(
self.app, req, 'Object', None, None, None, {},
client_chunk_size=8)
+ range_headers = []
+ sources = [(source2, node), (source3, node)]
+
+ def mock_get_source_and_node():
+ range_headers.append(handler.backend_headers['Range'])
+ return sources.pop(0)
+
app_iter = handler._make_app_iter(req, node, source1)
with mock.patch.object(handler, '_get_source_and_node',
- lambda: (source2, node)):
+ side_effect=mock_get_source_and_node):
client_chunks = list(app_iter)
- self.assertEqual(client_chunks, ['abcd1234', 'efgh5678'])
+ self.assertEqual(range_headers, ['bytes=8-27', 'bytes=16-27'])
+ self.assertEqual(client_chunks, [
+ 'abcd1234', 'efgh5678', 'lotsmore', 'data'])
def test_client_chunk_size_resuming_chunked(self):