fix(gateway): buffer response headers to prevent superfluous WriteHeader#35
Merged
olamide226 merged 1 commit intomainfrom Mar 16, 2026
Merged
Conversation
The inject middleware's responseRecorder was letting upstream handlers write headers directly to the real ResponseWriter. When httputil.ReverseProxy called Flush(), this prematurely committed headers and caused a second WriteHeader call when the middleware later wrote its own status code. Fix by giving the recorder its own http.Header map so upstream headers are buffered until the middleware is ready to write back. Flush() is now a no-op since the middleware must buffer the full response before deciding whether to inject. Headers are copied back via copyHeaders() before WriteHeader.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a header-commit ordering issue in the gateway’s HTML injection middleware by buffering response headers (instead of delegating directly to the underlying ResponseWriter), preventing upstream handlers from committing headers early and triggering superfluous response.WriteHeader warnings.
Changes:
- Make
responseRecorderown its ownhttp.Headermap and delay copying headers to the real writer until writeback time. - Make
responseRecorder.Flush()a no-op to prevent premature header/body commitment. - Add tests covering upstream
Flush()behavior and header buffering behavior; add.gocache/to.gitignore.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
gateway/internal/inject/inject.go |
Buffers headers in the recorder and copies them to the real writer only when committing the final response. |
gateway/internal/inject/inject_test.go |
Adds regression tests ensuring upstream flush doesn’t commit early and that headers are preserved through buffering. |
.gitignore |
Ignores .gocache/ directory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
Summary
responseRecorderdelegatedHeader()to the realResponseWriter, so upstream handlers (e.g.httputil.ReverseProxy) wrote headers directly to the client. WhenFlush()was called, headers were prematurely committed, causingsuperfluous response.WriteHeaderwarnings on the subsequent writeback.http.Headermap. Upstream headers are buffered there, then copied back to the real writer viacopyHeaders()only when the middleware is ready to commit.Flush()is a no-op to prevent premature commitment..gocache/to.gitignoreTest plan
go test -race ./internal/inject/passessuperfluous response.WriteHeaderwarning no longer appears in gateway logs