Add versionid header in complete multipart if enabled (#3643)

* Add versionid header in complete multipart if enabled
- addresses https://github.com/localstack/localstack/issues/3514

* remove unnecessary code

* fix lint

* fix lint test

* add test case for boto3
This commit is contained in:
Rahul Ranjan 2021-02-02 15:21:17 +05:30 committed by GitHub
parent 78a5661093
commit 7d066cea2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 2 deletions

View File

@ -1750,8 +1750,15 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
upload_id = query["uploadId"][0]
key = self.backend.complete_multipart(bucket_name, upload_id, body)
template = self.response_template(S3_MULTIPART_COMPLETE_RESPONSE)
return template.render(
headers = {}
if key.version_id:
headers["x-amz-version-id"] = key.version_id
return (
200,
headers,
template.render(
bucket_name=bucket_name, key_name=key.name, etag=key.etag
),
)
elif "restore" in query:
es = minidom.parseString(body).getElementsByTagName("Days")

View File

@ -255,6 +255,23 @@ def test_multipart_etag():
bucket.get_key("the-key").etag.should.equal(EXPECTED_ETAG)
@mock_s3_deprecated
@reduced_min_part_size
def test_multipart_version():
# Create Bucket so that test can run
conn = boto.connect_s3("the_key", "the_secret")
bucket = conn.create_bucket("mybucket")
bucket.configure_versioning(versioning=True)
multipart = bucket.initiate_multipart_upload("the-key")
part1 = b"0" * REDUCED_PART_SIZE
multipart.upload_part_from_file(BytesIO(part1), 1)
# last part, can be less than 5 MB
part2 = b"1"
multipart.upload_part_from_file(BytesIO(part2), 2)
resp = multipart.complete_upload()
resp.version_id.should_not.be.none
@mock_s3_deprecated
@reduced_min_part_size
def test_multipart_invalid_order():
@ -2569,6 +2586,54 @@ def test_boto3_multipart_etag():
resp["ETag"].should.equal(EXPECTED_ETAG)
@mock_s3
@reduced_min_part_size
def test_boto3_multipart_version():
# Create Bucket so that test can run
s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
s3.create_bucket(Bucket="mybucket")
s3.put_bucket_versioning(
Bucket="mybucket", VersioningConfiguration={"Status": "Enabled"}
)
upload_id = s3.create_multipart_upload(Bucket="mybucket", Key="the-key")["UploadId"]
part1 = b"0" * REDUCED_PART_SIZE
etags = []
etags.append(
s3.upload_part(
Bucket="mybucket",
Key="the-key",
PartNumber=1,
UploadId=upload_id,
Body=part1,
)["ETag"]
)
# last part, can be less than 5 MB
part2 = b"1"
etags.append(
s3.upload_part(
Bucket="mybucket",
Key="the-key",
PartNumber=2,
UploadId=upload_id,
Body=part2,
)["ETag"]
)
response = s3.complete_multipart_upload(
Bucket="mybucket",
Key="the-key",
UploadId=upload_id,
MultipartUpload={
"Parts": [
{"ETag": etag, "PartNumber": i} for i, etag in enumerate(etags, 1)
]
},
)
response["VersionId"].should.should_not.be.none
@mock_s3
@reduced_min_part_size
def test_boto3_multipart_part_size():