fix: discard buffered headers of the dropped 503 response - #60
Open
antoinemichea wants to merge 1 commit into
Open
fix: discard buffered headers of the dropped 503 response#60antoinemichea wants to merge 1 commit into
antoinemichea wants to merge 1 commit into
Conversation
When the load balancer aborts with http.Error(503) because the service
has no available server (e.g. a scaled-to-zero backend waking up), the
response writer drops the status code and the body, but kept the
headers http.Error wrote into the buffered map ("Content-Type:
text/plain; charset=utf-8", "X-Content-Type-Options: nosniff"). On the
final flush they leaked into the waiting page and overrode its
text/html Content-Type — browsers rendered the page as plain text.
Reset the buffered headers when discarding the 503 so the waiting page
keeps its own headers.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Fixes #59.
What
When the load balancer aborts with
http.Error(503)(service with no available server — typical for a scaled-to-zero backend whose session is ready but whose pods are still starting), the buffering writer drops the 503's status and body but keeps the headershttp.Errorwrote into the buffered map (Content-Type: text/plain; charset=utf-8,X-Content-Type-Options: nosniff). The finalWriteHeaderflush then merges them over the waiting page's own headers: the page is served astext/plainand browsers render the raw HTML as text (full mechanism in #59).How
Reset the buffered header map inside the not-ready-503 guard: if the 503 response is discarded, everything it wrote is discarded, headers included.
Tests
TestSablierMiddleware_ServeHTTP_WaitingPageContentTypeAfterLB503— end-to-end throughServeHTTP: Sablier answersready+Content-Type: text/html, the next handler doeshttp.Error(503)without firing the httptrace callbacks (exactly what Traefik's load balancer does with no backend). Asserts the waiting page keepsContent-Type: text/htmland noX-Content-Type-Optionsleaks. Fails onmain, passes with the fix.Independent from #58 (different lines, both branches based on
main); together they cover the two ways the buffered flush corrupts the final response.