Repository navigation
fix(s3): honor If-Match and If-Unmodified-Since on GetObject - #1446
Merged
Merged
Conversation
Shub3am
force-pushed
the
fix/s3-get-object-if-match
branch
from
October 1, 2026 03:47
5d46400 to
68f471c
Compare
The S3 GetObject route dropped If-Match and If-Unmodified-Since, so a read with a stale ETag or an old date returned 200 or 206 instead of 412. Clients such as boto3 and the AWS CLI send If-Match on the ranged GETs of a multipart download to detect the object changing mid-download, so an overwrite during a download could silently produce a mixed file. Accept both headers on the route, pass them through the S3 handler and evaluate them in both backends. Invalid dates are ignored like If-Modified-Since, and If-Unmodified-Since is ignored when If-Match is present.
Signed-off-by: Ferhat Elmas <[email protected]>
ferhatelmas
force-pushed
the
fix/s3-get-object-if-match
branch
from
October 1, 2026 11:31
68f471c to
ba0c931
Compare
ferhatelmas
approved these changes
Oct 1, 2026
Coverage Report for CI Build 36855870214Coverage increased (+0.08%) to 83.903%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats💛 - Coveralls |
This was referenced Oct 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What broke
S3
GetObjectignoresIf-MatchandIf-Unmodified-Since. A read with a stale ETag or an old date gets a 200 (or a 206 for a range) instead of a 412:This matters in practice. Recent boto3 and AWS CLI versions (s3transfer) send
If-Matchon every ranged GET of a multipart download so they can tell when the object changes mid-download. Because we drop the header, an overwrite during a download silently gives you a file that is half the old object and half the new one, with no error.Why
The route schema only accepted
range,if-none-matchandif-modified-since, so the other two headers never reached the handler.BrowserCacheHeadershad no field for them, and neither backend checked them.What changed
get-object.ts: acceptif-matchandif-unmodified-sinceon both GetObject routes. The date goes through the same "ignore invalid dates" parser asIf-Modified-Since, which I renamed toparseConditionalDatesince it now handles both.s3-handler.ts/adapter.ts: passifMatchandifUnmodifiedSincethrough to the backend.IfMatch/IfUnmodifiedSince. The upstream 412 already maps to a proper S3 error response.If-Unmodified-Sinceis ignored whenIf-Matchis present), and throw the same 412PreconditionFailed.How I tested it
s3-protocol.test.ts(If-Match mismatch on a ranged GET, If-Unmodified-Since in the past) and file backend unit tests. They fail on master and pass with the fix.s3-protocol.test.ts: 127/128 pass. The one failure (CopyObjectCommand > will not preserve omitted metadata when replacing it) also fails on master for me, because I ran against rustfs locally instead of minio and it defaults the content type differently.npm run lintandtsc --noEmitare all clean.