Repository navigation
Answer conditional requests with 304 - #72
Merged
Merged
Conversation
- Compare If-None-Match against the response etag after fetching the source. - Skip decode, transformation, and encode on a match. - Carry the incoming headers through the Lambda transport.
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.
The service sent an
ETagand never readIf-None-Match, so it answered every revalidation in full. A CDN checking whether its copy is still good got the whole image back regardless.Where the check goes
After the source is fetched, before anything is decoded.
That placement is forced by how the etag is built: it hashes the commands, the image URL, and the origin's own etag, so it cannot be known until the source has been retrieved. There is no cache mapping a response etag back to a source etag, so the fetch cannot be skipped.
What a
304does skip is the decode, the transformation, and the encode. Measurements taken while looking at request cost put that at 200 to 400 ms for an ordinary resize and 3.2 s for a large upscale, against a download that is usually a fraction of it. The expensive half is the half this avoids.Matching
If-None-Matchis compared per RFC 9110:*matches anything, a comma separated list is searched, and the comparison is weak, so aW/prefix on either side is ignored.No origin etag means no response etag, and then no conditional handling. That is unchanged behaviour, since
Etag()already returned empty in that case.Lambda
aws.NewRequestbuilt itshttp.Requestwith a URL and nothing else, so no request header ever reached the shared code. The incoming headers are now copied across, which makes the conditional check work there as well rather than silently returning false.SendNotModifiedis implemented separately for that transport, as it builds a streaming response rather than writing to aResponseWriter.Tests
TestNotModifiedcovers an exact match, a weak validator, a list, a wildcard, a non-matching value, an absent header, and an absent origin etag.TestSendNotModifiedasserts the response carries the cache headers, has status 304, and has no body orContent-Length.TestSendNotModifiedOnlyCommitsOnceextends the commit guard from #63 to this path.Verification
In
ghcr.io/beetlebugorg/go-dims:builder:gofmt,go vet, andgo test -race ./...all pass.