Fix response of Get Bucket when IsTruncated is true and delimiter is specified

When IsTruncated is true and delimiter is specified, add NextMarker tag to
response body.

Change-Id: Ifb2c71cf232b1a5b52518ce4d61131aac730ff74
This commit is contained in:
Naoto Nishizono
2014-12-25 11:09:06 +09:00
parent f5bd78c29b
commit c03a1b5b4b
2 changed files with 42 additions and 7 deletions

View File

@@ -76,6 +76,20 @@ class BucketController(Controller):
SubElement(elem, 'Name').text = req.container_name SubElement(elem, 'Name').text = req.container_name
SubElement(elem, 'Prefix').text = req.params.get('prefix') SubElement(elem, 'Prefix').text = req.params.get('prefix')
SubElement(elem, 'Marker').text = req.params.get('marker') SubElement(elem, 'Marker').text = req.params.get('marker')
# in order to judge that truncated is valid, check whether
# max_keys + 1 th element exists in swift.
is_truncated = max_keys > 0 and len(objects) > max_keys
objects = objects[:max_keys]
if is_truncated and 'delimiter' in req.params:
if 'name' in objects[-1]:
SubElement(elem, 'NextMarker').text = \
objects[-1]['name']
if 'subdir' in objects[-1]:
SubElement(elem, 'NextMarker').text = \
objects[-1]['subdir']
SubElement(elem, 'MaxKeys').text = str(max_keys) SubElement(elem, 'MaxKeys').text = str(max_keys)
if 'delimiter' in req.params: if 'delimiter' in req.params:
@@ -84,13 +98,10 @@ class BucketController(Controller):
if encoding_type is not None: if encoding_type is not None:
SubElement(elem, 'EncodingType').text = encoding_type SubElement(elem, 'EncodingType').text = encoding_type
if max_keys > 0 and len(objects) == max_keys + 1: SubElement(elem, 'IsTruncated').text = \
is_truncated = 'true' 'true' if is_truncated else 'false'
else:
is_truncated = 'false'
SubElement(elem, 'IsTruncated').text = is_truncated
for o in objects[:max_keys]: for o in objects:
if 'subdir' not in o: if 'subdir' not in o:
contents = SubElement(elem, 'Contents') contents = SubElement(elem, 'Contents')
SubElement(contents, 'Key').text = o['name'] SubElement(contents, 'Key').text = o['name']
@@ -103,7 +114,7 @@ class BucketController(Controller):
SubElement(owner, 'DisplayName').text = req.user_id SubElement(owner, 'DisplayName').text = req.user_id
SubElement(contents, 'StorageClass').text = 'STANDARD' SubElement(contents, 'StorageClass').text = 'STANDARD'
for o in objects[:max_keys]: for o in objects:
if 'subdir' in o: if 'subdir' in o:
common_prefixes = SubElement(elem, 'CommonPrefixes') common_prefixes = SubElement(elem, 'CommonPrefixes')
SubElement(common_prefixes, 'Prefix').text = o['subdir'] SubElement(common_prefixes, 'Prefix').text = o['subdir']

View File

@@ -217,6 +217,30 @@ class TestSwift3Bucket(Swift3TestCase):
self.assertEquals(args['marker'], '\xef\xbc\xa2') self.assertEquals(args['marker'], '\xef\xbc\xa2')
self.assertEquals(args['prefix'], '\xef\xbc\xa3') self.assertEquals(args['prefix'], '\xef\xbc\xa3')
def test_bucket_GET_with_delimiter_max_keys(self):
bucket_name = 'junk'
req = Request.blank('/%s?delimiter=a&max-keys=2' % bucket_name,
environ={'REQUEST_METHOD': 'GET'},
headers={'Authorization': 'AWS test:tester:hmac'})
status, headers, body = self.call_swift3(req)
self.assertEquals(status.split()[0], '200')
elem = fromstring(body, 'ListBucketResult')
self.assertEquals(elem.find('./NextMarker').text, 'viola')
self.assertEquals(elem.find('./MaxKeys').text, '2')
self.assertEquals(elem.find('./IsTruncated').text, 'true')
def test_bucket_GET_subdir_with_delimiter_max_keys(self):
bucket_name = 'junk_subdir'
req = Request.blank('/%s?delimiter=a&max-keys=1' % bucket_name,
environ={'REQUEST_METHOD': 'GET'},
headers={'Authorization': 'AWS test:tester:hmac'})
status, headers, body = self.call_swift3(req)
self.assertEquals(status.split()[0], '200')
elem = fromstring(body, 'ListBucketResult')
self.assertEquals(elem.find('./NextMarker').text, 'rose')
self.assertEquals(elem.find('./MaxKeys').text, '1')
self.assertEquals(elem.find('./IsTruncated').text, 'true')
@s3acl @s3acl
def test_bucket_PUT_error(self): def test_bucket_PUT_error(self):
code = self._test_method_error('PUT', '/bucket', swob.HTTPCreated, code = self._test_method_error('PUT', '/bucket', swob.HTTPCreated,