Skip to content

Commit

Permalink
[s3] Pass object parameters to head_object in exists
Browse files Browse the repository at this point in the history
When using server-side-encryption with customer-provided keys (SSE-C),
the head_object call needs the SSE-C key and algorithm - otherwise the
call will fail with `botocore.exceptions.ClientError: An error occurred (400)
when calling the HeadObject operation: Bad Request` if the file already
exists.
  • Loading branch information
czosel committed Sep 17, 2024
1 parent b85d021 commit b655506
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
3 changes: 2 additions & 1 deletion storages/backends/s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,8 +583,9 @@ def exists(self, name):
return False

name = self._normalize_name(clean_name(name))
params = _filter_download_params(self.get_object_parameters(name))
try:
self.connection.meta.client.head_object(Bucket=self.bucket_name, Key=name)
self.connection.meta.client.head_object(Bucket=self.bucket_name, Key=name, **params)
return True
except ClientError as err:
if err.response["ResponseMetadata"]["HTTPStatusCode"] == 404:
Expand Down
12 changes: 12 additions & 0 deletions tests/test_s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,18 @@ def test_storage_exists(self):
Key="file.txt",
)

def test_storage_exists_ssec(self):
params = {"SSECustomerKey": "xyz", "CacheControl": "never"}
self.storage.get_object_parameters = lambda name: params

self.storage.file_overwrite = False
self.assertTrue(self.storage.exists("file.txt"))
self.storage.connection.meta.client.head_object.assert_called_with(
Bucket=self.storage.bucket_name,
Key="file.txt",
SSECustomerKey="xyz"
)

def test_storage_exists_false(self):
self.storage.file_overwrite = False
self.storage.connection.meta.client.head_object.side_effect = ClientError(
Expand Down

0 comments on commit b655506

Please sign in to comment.