Skip to content

fix: discard buffered headers of the dropped 503 response - #60

Open
antoinemichea wants to merge 1 commit into
sablierapp:mainfrom
antoinemichea:fix/discard-503-headers
Open

fix: discard buffered headers of the dropped 503 response#60
antoinemichea wants to merge 1 commit into
sablierapp:mainfrom
antoinemichea:fix/discard-503-headers

Conversation

@antoinemichea

Copy link
Copy Markdown

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 headers http.Error wrote into the buffered map (Content-Type: text/plain; charset=utf-8, X-Content-Type-Options: nosniff). The final WriteHeader flush then merges them over the waiting page's own headers: the page is served as text/plain and 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 through ServeHTTP: Sablier answers ready + Content-Type: text/html, the next handler does http.Error(503) without firing the httptrace callbacks (exactly what Traefik's load balancer does with no backend). Asserts the waiting page keeps Content-Type: text/html and no X-Content-Type-Options leaks. Fails on main, 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.

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>
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.

bug: waiting page served as text/plain when the load balancer aborts with 503 (discarded 503 headers leak into the buffered flush)

2 participants