Fix S3 backend operations with VersionId (#2055)

* fix s3 issues

* fix merge conflict

* fix and add test cases
This commit is contained in:
Alexander Mohr 2019-05-25 12:19:33 -07:00 committed by Terry Cain
commit 7271fb9391
3 changed files with 42 additions and 9 deletions

View file

@ -912,12 +912,11 @@ class S3Backend(BaseBackend):
return multipart.set_part(part_id, value)
def copy_part(self, dest_bucket_name, multipart_id, part_id,
src_bucket_name, src_key_name, start_byte, end_byte):
src_key_name = clean_key_name(src_key_name)
src_bucket = self.get_bucket(src_bucket_name)
src_bucket_name, src_key_name, src_version_id, start_byte, end_byte):
dest_bucket = self.get_bucket(dest_bucket_name)
multipart = dest_bucket.multiparts[multipart_id]
src_value = src_bucket.keys[src_key_name].value
src_value = self.get_key(src_bucket_name, src_key_name, version_id=src_version_id).value
if start_byte is not None:
src_value = src_value[start_byte:end_byte + 1]
return multipart.set_part(part_id, src_value)

View file

@ -707,6 +707,8 @@ class ResponseObject(_TemplateEnvironmentMixin):
if 'x-amz-copy-source' in request.headers:
src = unquote(request.headers.get("x-amz-copy-source")).lstrip("/")
src_bucket, src_key = src.split("/", 1)
src_key, src_version_id = src_key.split("?versionId=") if "?versionId=" in src_key else (src_key, None)
src_range = request.headers.get(
'x-amz-copy-source-range', '').split("bytes=")[-1]
@ -716,9 +718,13 @@ class ResponseObject(_TemplateEnvironmentMixin):
except ValueError:
start_byte, end_byte = None, None
key = self.backend.copy_part(
bucket_name, upload_id, part_number, src_bucket,
src_key, start_byte, end_byte)
if self.backend.get_key(src_bucket, src_key, version_id=src_version_id):
key = self.backend.copy_part(
bucket_name, upload_id, part_number, src_bucket,
src_key, src_version_id, start_byte, end_byte)
else:
return 404, response_headers, ""
template = self.response_template(S3_MULTIPART_UPLOAD_RESPONSE)
response = template.render(part=key)
else:
@ -757,8 +763,13 @@ class ResponseObject(_TemplateEnvironmentMixin):
lstrip("/").split("/", 1)
src_version_id = parse_qs(src_key_parsed.query).get(
'versionId', [None])[0]
self.backend.copy_key(src_bucket, src_key, bucket_name, key_name,
storage=storage_class, acl=acl, src_version_id=src_version_id)
if self.backend.get_key(src_bucket, src_key, version_id=src_version_id):
self.backend.copy_key(src_bucket, src_key, bucket_name, key_name,
storage=storage_class, acl=acl, src_version_id=src_version_id)
else:
return 404, response_headers, ""
new_key = self.backend.get_key(bucket_name, key_name)
mdirective = request.headers.get('x-amz-metadata-directive')
if mdirective is not None and mdirective == 'REPLACE':