Repository navigation
Conversation
static_file compared the whole header against the entity-tag with ==, so only
a client echoing the tag byte for byte got a 304. Measured against a file
served by static_file:
If-None-Match: <etag> 304 (worked)
If-None-Match: * 200 should be 304
If-None-Match: "<etag>" 200 should be 304
If-None-Match: "other", <etag> 200 should be 304
If-None-Match: W/<etag> 200 should be 304
The header is a comma-separated list of entity-tags or a lone `*`, and
sec 8.8.3.2 requires the weak comparison for it, so the quotes and any `W/`
prefix are not part of the value being compared. Every line above except the
first silently defeated caching.
`*` now answers 304 whenever the file exists, including when the caller passed
etag=False, because it asks whether any representation exists rather than
comparing tags.
Not changed here: static_file emits the tag unquoted, which rfc9110 sec 8.8.3
does not allow (an opaque-tag is a quoted-string). Comparing after
normalisation means both spellings work, so this commit fixes the matching
without changing a header that callers may already depend on. Happy to follow
up on the emitted form separately.
This contribution is released into the public domain.
ai-assisted-by: Claude Code (Claude Opus 5)
Signed-off-by: Roshan Ramani <roshanramani.dev@gmail.com>
Member
|
Hmm, looks like
|
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.
static_filecompares the wholeIf-None-Matchheader against the entity-tag with==, so only a client echoing the tag byte for byte gets a 304. Measured against a file it serves:If-None-Match<etag>*"<etag>""other", <etag>W/<etag>"nope"The header is a comma-separated list of entity-tags or a lone
*(sec 13.1.2), and sec 8.8.3.2 requires the weak comparison for it, so the surrounding quotes and anyW/prefix are not part of the value. Every row above except the first and last silently defeated caching — the client asked "only send it if it changed", and got the whole file back.parse_etag_listandetag_matchesare module-level so they can be reused by anIf-Matchimplementation later, and are named in the same style as the existingparse_date/parse_range_header.Two decisions worth your eye:
*now answers 304 whenever the file exists, including when the caller passedetag=False, because it asks whether any representation exists rather than comparing tags. That is what the spec says, but it does meanetag=Falseno longer suppresses every conditional. Say the word and I'll gate it on an ETag being present instead.entity-tagper sec 8.8.3 (anopaque-tagis a quoted-string). Comparing after normalisation means both spellings match, so this fixes the behaviour without changing a header that callers may already depend on. Worth a separate PR if you want it.Verification:
python3 -m pytest test— 372 pass. Reverting onlybottle.pyfails exactly the two new tests and nothing else. The new cases cover*, quoted,W/in both spellings, a list on either side of the tag, and the non-matching cases including an empty header.Existing behaviour I checked stays put:
test_etag_overrides_imsstill passes, so If-None-Match still takes precedence over If-Modified-Since as of b73bd1d.Per
AGENTS.md: this contribution is released into the public domain; AI usage is disclosed in the commit'sai-assisted-by:trailer (Claude Code, Claude Opus 5). @rawsun007 reviewed the diff, ran the suite, and authorised the sign-off. This is our only open AI-assisted PR here.