Fix max-parts, part-number-marker, and encoding-type in queries of List Parts
I've fixed ToDo in qeuries of List Part. encoding-type: Requests Amazon S3 to encode the response and specifies the encoding method to use. max-parts: Sets the maximum number of parts to return in the response body. part-number-marker: Specifies the part after which listing should begin. Only parts with higher part numbers will be listed. For details, refer to the following. http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadListParts.html Change-Id: I1a3b3a0aba188fcb928e89e78ad8859dbecca2e8
This commit is contained in:
@@ -56,6 +56,7 @@ from swift3.exception import BadSwiftRequest
|
||||
from swift3.utils import LOGGER, unique_id, MULTIUPLOAD_SUFFIX
|
||||
from swift3.etree import Element, SubElement, fromstring, tostring, \
|
||||
XMLSyntaxError, DocumentInvalid
|
||||
from swift3.cfg import CONF
|
||||
|
||||
DEFAULT_MAX_PARTS = 1000
|
||||
DEFAULT_MAX_UPLOADS = 1000
|
||||
@@ -280,6 +281,13 @@ class UploadController(Controller):
|
||||
"""
|
||||
Handles List Parts.
|
||||
"""
|
||||
def filter_part_num_marker(o):
|
||||
try:
|
||||
num = int(os.path.basename(o['name']))
|
||||
return num > part_num_marker
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
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'
|
||||
@@ -288,11 +296,43 @@ class UploadController(Controller):
|
||||
upload_id = req.params['uploadId']
|
||||
_check_upload_info(req, self.app, upload_id)
|
||||
|
||||
maxparts = DEFAULT_MAX_PARTS
|
||||
part_num_marker = 0
|
||||
|
||||
# TODO: add support for max-parts and part-number-marker queries.
|
||||
if 'max-parts' in req.params:
|
||||
try:
|
||||
maxparts = int(req.params['max-parts'])
|
||||
if maxparts < 0 or CONF.max_parts < maxparts:
|
||||
err_msg = 'Argument max-parts must be an integer between 0 and' \
|
||||
' %d' % CONF.max_parts
|
||||
raise InvalidArgument('max-parts',
|
||||
req.params['max-parts'],
|
||||
err_msg)
|
||||
except ValueError:
|
||||
err_msg = 'Provided max-parts not an integer or within ' \
|
||||
'integer range'
|
||||
raise InvalidArgument('max-parts', req.params['max-parts'],
|
||||
err_msg)
|
||||
|
||||
if 'part-number-marker' in req.params:
|
||||
try:
|
||||
part_num_marker = int(req.params['part-number-marker'])
|
||||
if part_num_marker < 0 or CONF.max_parts < part_num_marker:
|
||||
err_msg = 'Argument part-number-marker must be an integer ' \
|
||||
'between 0 and %d' % CONF.max_parts
|
||||
raise InvalidArgument('part-number-marker',
|
||||
req.params['part-number-marker'],
|
||||
err_msg)
|
||||
except ValueError:
|
||||
err_msg = 'Provided part-number-marker not an integer or ' \
|
||||
'within integer range'
|
||||
raise InvalidArgument('part-number-marker',
|
||||
req.params['part-number-marker'],
|
||||
err_msg)
|
||||
|
||||
query = {
|
||||
'format': 'json',
|
||||
'limit': maxparts + 1,
|
||||
'prefix': '%s/%s/' % (req.object_name, upload_id),
|
||||
'delimiter': '/'
|
||||
}
|
||||
@@ -304,11 +344,24 @@ class UploadController(Controller):
|
||||
|
||||
last_part = 0
|
||||
|
||||
# pylint: disable-msg=E1103
|
||||
objects.sort(key=lambda o: int(o['name'].split('/')[-1]))
|
||||
# If the caller requested a list starting at a specific part number,
|
||||
# construct a sub-set of the object list.
|
||||
objList = filter(filter_part_num_marker, objects)
|
||||
|
||||
if len(objects) > 0:
|
||||
o = objects[-1]
|
||||
# pylint: disable-msg=E1103
|
||||
objList.sort(key=lambda o: int(o['name'].split('/')[-1]))
|
||||
|
||||
if len(objList) > maxparts:
|
||||
objList = objList[:maxparts]
|
||||
truncated = True
|
||||
else:
|
||||
truncated = False
|
||||
# TODO: We have to retrieve object list again when truncated is True
|
||||
# and some objects filtered by invalid name because there could be no
|
||||
# enough objects for limit defined by maxparts.
|
||||
|
||||
if objList:
|
||||
o = objList[-1]
|
||||
last_part = os.path.basename(o['name'])
|
||||
|
||||
result_elem = Element('ListPartsResult')
|
||||
@@ -326,11 +379,14 @@ class UploadController(Controller):
|
||||
SubElement(result_elem, 'StorageClass').text = 'STANDARD'
|
||||
SubElement(result_elem, 'PartNumberMarker').text = str(part_num_marker)
|
||||
SubElement(result_elem, 'NextPartNumberMarker').text = str(last_part)
|
||||
SubElement(result_elem, 'MaxParts').text = str(DEFAULT_MAX_PARTS)
|
||||
# TODO: add support for EncodingType
|
||||
SubElement(result_elem, 'IsTruncated').text = 'false'
|
||||
SubElement(result_elem, 'MaxParts').text = str(maxparts)
|
||||
if 'encoding-type' in req.params:
|
||||
SubElement(result_elem, 'EncodingType').text = \
|
||||
req.params['encoding-type']
|
||||
SubElement(result_elem, 'IsTruncated').text = \
|
||||
'true' if truncated else 'false'
|
||||
|
||||
for i in objects:
|
||||
for i in objList:
|
||||
part_elem = SubElement(result_elem, 'Part')
|
||||
SubElement(part_elem, 'PartNumber').text = i['name'].split('/')[-1]
|
||||
SubElement(part_elem, 'LastModified').text = \
|
||||
|
||||
Reference in New Issue
Block a user