Skip to content

fix: match weak, list and wildcard for if-none-match file backend - #1424

Merged
ferhatelmas merged 1 commit into
masterfrom
ferhat/none-match-file
Sep 22, 2026
Merged

ferhatelmas merged 1 commit into
masterfrom
ferhat/none-match-file

Conversation

@ferhatelmas

Copy link
Copy Markdown
Member

What kind of change does this PR introduce?

Bug fix

What is the current behavior?

304 only when the whole header equals the strong etag, anything else is a miss.

What is the new behavior?

304 when the header matches under RFC 9110 §13.1.2 weak comparison.

Additional context

Related to #1422
https://datatracker.ietf.org/doc/html/rfc9110#section-13.1.2

@ferhatelmas
ferhatelmas requested a review from a team as a code owner September 21, 2026 14:21
Copilot AI lite review requested due to automatic review settings September 21, 2026 14:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, straightforward and well-tested RFC-compliance fix.

What was reviewed: the new ifNoneMatchMatches() helper (wildcard, comma-separated list splitting, W/ weak-prefix stripping) in src/storage/backend/file.ts, its single call site replacing the old strict-equality check, and the corresponding parametrized tests in file.test.ts covering weak tag, multi-tag list, wildcard, and no-match cases. Confirmed the object's eTag is always quoted (via the private etag() method), so comparisons against header tags are apples-to-apples and commas can't appear inside an eTag value, so the naive split(',') is safe for this codebase.

Extended reasoning...

Overview

The PR modifies FileBackend's If-None-Match handling in src/storage/backend/file.ts, replacing a naive strict string-equality check with a small helper ifNoneMatchMatches() that correctly implements RFC 9110 §13.1.2 weak-comparison semantics: bare * matches anything, comma-separated tag lists are split and trimmed, and W/ weak-validator prefixes are stripped before comparing each tag to the object's eTag. The test file adds four new cases (weak tag, tag list containing a match, wildcard, and a list with no match) alongside the existing conditional-read test suite.

Security risks

None identified. This is a caching/conditional-request correctness fix, not an auth or data-exposure path — at worst a wrong 304 vs 200 status affects cache freshness, not access control. The change only affects response status code selection for GET/HEAD reads and doesn't touch write paths, path resolution, or credentials.

Level of scrutiny

Light-to-moderate scrutiny is appropriate: the change is small (about 10 lines of logic), self-contained to a single method, has a clear RFC citation backing the correctness claim, and ships with targeted unit tests exercising every new branch. I verified the object's eTag format (always wrapped in quotes by the private etag() method for both md5 and mtime algorithms) to confirm the new comparison logic is consistent with existing eTag values, and confirmed other backends (S3) don't share this code path since they delegate If-None-Match handling to the AWS SDK/S3 service directly, so this fix is correctly scoped to FileBackend only.

Other factors

No CLAUDE.md conventions apply. No bug-hunting findings were reported, and I found no additional concerns beyond what's already tested. The change is mechanical enough, and sufficiently well-tested, that I'm comfortable approving without requiring further human review.

@coveralls

coveralls commented Sep 21, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 35700558832

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage increased (+0.02%) to 83.352%

Details

  • Coverage increased (+0.02%) from the base build.
  • Patch coverage: 4 of 4 lines across 1 file are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 14182
Covered Lines: 12252
Line Coverage: 86.39%
Relevant Branches: 8673
Covered Branches: 6798
Branch Coverage: 78.38%
Branches in Coverage %: Yes
Coverage Strength: 3087.76 hits per line

💛 - Coveralls

Signed-off-by: Ferhat Elmas <elmas.ferhat@gmail.com>
@ferhatelmas
ferhatelmas force-pushed the ferhat/none-match-file branch from 583f348 to 26aab97 Compare September 22, 2026 07:37
@ferhatelmas
ferhatelmas enabled auto-merge (squash) September 22, 2026 07:37
@ferhatelmas
ferhatelmas merged commit 6b212c8 into master Sep 22, 2026
32 checks passed
@ferhatelmas
ferhatelmas deleted the ferhat/none-match-file branch September 22, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants