Answer a revisit 304 whether its ETag comes back weak or strong - #380
Conversation
nginx's gzip turns the service's strong ETags weak on the way out (W/"..."), and the browser sends back what it was given. The boards tree, the wizard, the builds explorer and httpx.WriteJSON all compared If-None-Match with their ETag as strings, so through the front door every revisit got the whole body again -- while the same request straight to the service got its 304, which is why only the conformance suite against openipc.org noticed (TestTheBoardTreeIsJSONRevalidatedByETagAndSetsNothing). httpx.ETagMatches does the weak comparison RFC 9110 prescribes for If-None-Match -- W/ ignored on both sides, a list of tags, or * -- and the four handlers use it.
PR Summary by QodoRestore 304 responses for weak and strong ETag revisits
AI Description
Diagram
High-Level Assessment
Files changed (5)
|
Code Review by Qodo
1.
|
…on * - A request may carry If-None-Match more than once; httpx.Revisited reads every field as one list, where Header.Get saw only the first. - A value that is not a well-formed list of entity-tags matches nothing, even when it holds the current tag: saying no costs only a full response. - "*" matches nothing. Every handler decides 304 before it has looked the resource up, so it answered 304 for a board or platform that does not exist; no browser sends it on a GET.
The bug. nginx's gzip turns the service's strong ETags into weak ones on the way out (
W/"…"), and the browser sends back what it was given. Four places comparedIf-None-Matchwith their own ETag as an exact string:httpx.WriteJSONSo every revisit through the front door got the whole body again, never a 304. The same request straight to the service got its 304, which is why only the conformance suite run against https://openipc.org caught it:
TestTheBoardTreeIsJSONRevalidatedByETagAndSetsNothingfails there witha revisit with the ETag: 200.Reproduced by hand:
curl -H 'Accept-Encoding: gzip'gets backETag: W/"13c1…".If-None-Matchgets 200.127.0.0.1:3002, the same request gets 304.The fix.
httpx.ETagMatchesdoes the weak comparison RFC 9110 (13.1.2) prescribes forIf-None-Match:W/is ignored on both sides;*matches anything.It walks the quoted tags rather than splitting on commas, since a comma is legal inside an entity-tag. All four handlers now use it.
etag_test.gocovers the case that failed, along with lists,*and malformed headers.Checks.
service/run.sh testpasses forinternal/httpx,boards,wizardandbuilds. Next: validation on dev through nginx (gzip revisit gets 304, plus the conformance suite), then production.