S3: Fix IfModifiedSince handling in S3 get_object/head_object (#5673)

This commit is contained in:
Lukáš Lalinský 2022-11-16 22:12:48 +01:00 committed by GitHub
parent fe64a02851
commit fa77d22d72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 4 deletions

View File

@ -1285,14 +1285,14 @@ class S3Response(BaseResponse):
raise InvalidObjectState(storage_class="GLACIER")
if if_unmodified_since:
if_unmodified_since = str_to_rfc_1123_datetime(if_unmodified_since)
if key.last_modified > if_unmodified_since:
if key.last_modified.replace(microsecond=0) > if_unmodified_since:
raise PreconditionFailed("If-Unmodified-Since")
if if_match and key.etag not in [if_match, '"{0}"'.format(if_match)]:
raise PreconditionFailed("If-Match")
if if_modified_since:
if_modified_since = str_to_rfc_1123_datetime(if_modified_since)
if key.last_modified < if_modified_since:
if key.last_modified.replace(microsecond=0) <= if_modified_since:
return 304, response_headers, "Not Modified"
if if_none_match and key.etag == if_none_match:
return 304, response_headers, "Not Modified"
@ -1575,14 +1575,14 @@ class S3Response(BaseResponse):
if if_unmodified_since:
if_unmodified_since = str_to_rfc_1123_datetime(if_unmodified_since)
if key.last_modified > if_unmodified_since:
if key.last_modified.replace(microsecond=0) > if_unmodified_since:
return 412, response_headers, ""
if if_match and key.etag != if_match:
return 412, response_headers, ""
if if_modified_since:
if_modified_since = str_to_rfc_1123_datetime(if_modified_since)
if key.last_modified < if_modified_since:
if key.last_modified.replace(microsecond=0) <= if_modified_since:
return 304, response_headers, "Not Modified"
if if_none_match and key.etag == if_none_match:
return 304, response_headers, "Not Modified"

View File

@ -1617,6 +1617,28 @@ def test_delete_versioned_bucket_returns_meta():
assert "VersionId" not in del_resp2
@mock_s3
def test_get_object_if_modified_since_refresh():
s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
bucket_name = "blah"
s3.create_bucket(Bucket=bucket_name)
key = "hello.txt"
s3.put_object(Bucket=bucket_name, Key=key, Body="test")
response = s3.get_object(Bucket=bucket_name, Key=key)
with pytest.raises(botocore.exceptions.ClientError) as err:
s3.get_object(
Bucket=bucket_name,
Key=key,
IfModifiedSince=response["LastModified"],
)
e = err.value
e.response["Error"].should.equal({"Code": "304", "Message": "Not Modified"})
@mock_s3
def test_get_object_if_modified_since():
s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
@ -1711,6 +1733,28 @@ def test_head_object_if_modified_since():
e.response["Error"].should.equal({"Code": "304", "Message": "Not Modified"})
@mock_s3
def test_head_object_if_modified_since_refresh():
s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
bucket_name = "blah"
s3.create_bucket(Bucket=bucket_name)
key = "hello.txt"
s3.put_object(Bucket=bucket_name, Key=key, Body="test")
response = s3.head_object(Bucket=bucket_name, Key=key)
with pytest.raises(botocore.exceptions.ClientError) as err:
s3.head_object(
Bucket=bucket_name,
Key=key,
IfModifiedSince=response["LastModified"],
)
e = err.value
e.response["Error"].should.equal({"Code": "304", "Message": "Not Modified"})
@mock_s3
def test_head_object_if_unmodified_since():
s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME)