Merge "Fix max-uploads, key-marker, prefix and upload-id-marker in queries of List Multipart Uploads"

This commit is contained in:
Jenkins
2015-01-13 01:41:13 +00:00
committed by Gerrit Code Review
2 changed files with 272 additions and 31 deletions

View File

@@ -131,27 +131,62 @@ class UploadsController(Controller):
"""
Handles List Multipart Uploads
"""
def filter_max_uploads(o):
name = o.get('name', '')
return name.count('/') == 1
encoding_type = req.params.get('encoding-type')
if encoding_type is not None and encoding_type != 'url':
err_msg = 'Invalid Encoding Method specified in Request'
raise InvalidArgument('encoding-type', encoding_type, err_msg)
# TODO: add support for prefix, key-marker, upload-id-marker, and
# max-uploads queries.
# TODO: add support for delimiter query.
keymarker = req.params.get('key-marker', '')
uploadid = req.params.get('upload-id-marker', '')
maxuploads = DEFAULT_MAX_UPLOADS
if 'max-uploads' in req.params:
try:
maxuploads = int(req.params['max-uploads'])
if maxuploads < 0 or DEFAULT_MAX_UPLOADS < maxuploads:
err_msg = 'Argument max-uploads must be an integer ' \
'between 0 and %d' % DEFAULT_MAX_UPLOADS
raise InvalidArgument('max-uploads', maxuploads, err_msg)
except ValueError:
err_msg = 'Provided max-uploads not an integer or within ' \
'integer range'
raise InvalidArgument('max-uploads', req.params['max-uploads'],
err_msg)
query = {
'format': 'json',
'limit': maxuploads + 1,
}
if uploadid and keymarker:
query.update({'marker': '%s/%s' % (keymarker, uploadid)})
elif keymarker:
query.update({'marker': '%s/~' % (keymarker)})
if 'prefix' in req.params:
query.update({'prefix': req.params['prefix']})
container = req.container_name + MULTIUPLOAD_SUFFIX
resp = req.get_response(self.app, container=container, query=query)
objects = loads(resp.body)
uploads = []
for o in objects:
obj, upid = split_path('/' + o['name'], 1, 2, True)
if '/' in upid:
# This is a part object.
continue
objects = filter(filter_max_uploads, objects)
if len(objects) > maxuploads:
objects = objects[:maxuploads]
truncated = True
else:
truncated = False
uploads = []
prefixes = []
for o in objects:
obj, upid = split_path('/' + o['name'], 1, 2)
uploads.append(
{'key': obj,
'upload_id': upid,
@@ -166,17 +201,17 @@ class UploadsController(Controller):
result_elem = Element('ListMultipartUploadsResult')
SubElement(result_elem, 'Bucket').text = req.container_name
SubElement(result_elem, 'KeyMarker').text = ''
SubElement(result_elem, 'UploadIdMarker').text = ''
SubElement(result_elem, 'KeyMarker').text = keymarker
SubElement(result_elem, 'UploadIdMarker').text = uploadid
SubElement(result_elem, 'NextKeyMarker').text = nextkeymarker
SubElement(result_elem, 'NextUploadIdMarker').text = nextuploadmarker
SubElement(result_elem, 'MaxUploads').text = str(DEFAULT_MAX_UPLOADS)
if 'prefix' in req.params:
SubElement(result_elem, 'Prefix').text = req.params['prefix']
SubElement(result_elem, 'MaxUploads').text = str(maxuploads)
if encoding_type is not None:
SubElement(result_elem, 'EncodingType').text = encoding_type
SubElement(result_elem, 'IsTruncated').text = 'false'
SubElement(result_elem, 'IsTruncated').text = \
'true' if truncated else 'false'
# TODO: don't show uploads which are initiated before this bucket is
# created.
@@ -194,6 +229,10 @@ class UploadsController(Controller):
SubElement(upload_elem, 'Initiated').text = \
u['last_modified'][:-3] + 'Z'
for p in prefixes:
elem = SubElement(result_elem, 'CommonPrefixes')
SubElement(elem, 'Prefix').text = p
body = tostring(result_elem, encoding_type=encoding_type)
return HTTPOk(body=body, content_type='application/xml')