Skip to content

Commit

Permalink
Merge "proxy: Use the right ranges when going to multiple object serv…
Browse files Browse the repository at this point in the history
…ers" into stable/pike
  • Loading branch information
Jenkins authored and openstack-gerrit committed Sep 27, 2017
2 parents 69a7be6 + 02ee5c1 commit 0344d6e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
11 changes: 8 additions & 3 deletions swift/proxy/controllers/base.py
Expand Up @@ -787,14 +787,16 @@ def fast_forward(self, num_bytes):
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)
Expand All @@ -818,6 +820,9 @@ def fast_forward(self, num_bytes):
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.
Expand Down
22 changes: 18 additions & 4 deletions test/unit/proxy/controllers/test_base.py
Expand Up @@ -900,18 +900,32 @@ def getheaders(self):

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):

Expand Down

0 comments on commit 0344d6e

Please sign in to comment.