Fix copying S3 objects, when using MetadataDirective='REPLACE' (#4883)
This commit is contained in:
parent
b6f4584737
commit
e84cc20abe
@ -2016,6 +2016,7 @@ class S3Backend(BaseBackend, CloudWatchMetricProvider):
|
||||
encryption=None,
|
||||
kms_key_id=None,
|
||||
bucket_key_enabled=False,
|
||||
mdirective=None,
|
||||
):
|
||||
if (
|
||||
src_key.name == dest_key_name
|
||||
@ -2025,6 +2026,7 @@ class S3Backend(BaseBackend, CloudWatchMetricProvider):
|
||||
and encryption == src_key.encryption
|
||||
and kms_key_id == src_key.kms_key_id
|
||||
and bucket_key_enabled == (src_key.bucket_key_enabled or False)
|
||||
and mdirective != "REPLACE"
|
||||
):
|
||||
raise CopyObjectMustChangeSomething
|
||||
|
||||
|
@ -1468,6 +1468,8 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
||||
== "true"
|
||||
)
|
||||
|
||||
mdirective = request.headers.get("x-amz-metadata-directive")
|
||||
|
||||
self.backend.copy_object(
|
||||
key,
|
||||
bucket_name,
|
||||
@ -1477,12 +1479,12 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
||||
kms_key_id=kms_key_id,
|
||||
encryption=encryption,
|
||||
bucket_key_enabled=bucket_key_enabled,
|
||||
mdirective=mdirective,
|
||||
)
|
||||
else:
|
||||
raise MissingKey(key=src_key)
|
||||
|
||||
new_key = self.backend.get_object(bucket_name, key_name)
|
||||
mdirective = request.headers.get("x-amz-metadata-directive")
|
||||
if mdirective is not None and mdirective == "REPLACE":
|
||||
metadata = metadata_from_headers(request.headers)
|
||||
new_key.set_metadata(metadata, replace=True)
|
||||
|
@ -704,6 +704,30 @@ def test_copy_key_without_changes_should_error_boto3():
|
||||
)
|
||||
|
||||
|
||||
@mock_s3
|
||||
def test_copy_key_without_changes_should_not_error_boto3():
|
||||
client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
||||
bucket_name = "my_bucket"
|
||||
s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME)
|
||||
key_name = "my_key"
|
||||
key = s3.Object(bucket_name, key_name)
|
||||
|
||||
s3.create_bucket(Bucket=bucket_name)
|
||||
key.put(Body=b"some value")
|
||||
|
||||
client.copy_object(
|
||||
Bucket=bucket_name,
|
||||
CopySource="{}/{}".format(bucket_name, key_name),
|
||||
Key=key_name,
|
||||
Metadata={"some-key": "some-value"},
|
||||
MetadataDirective="REPLACE",
|
||||
)
|
||||
|
||||
new_object = client.get_object(Bucket=bucket_name, Key=key_name)
|
||||
|
||||
assert new_object["Metadata"] == {"some-key": "some-value"}
|
||||
|
||||
|
||||
@freeze_time("2012-01-01 12:00:00")
|
||||
@mock_s3
|
||||
def test_last_modified_boto3():
|
||||
|
Loading…
Reference in New Issue
Block a user