fix: [engines] buffer request body and set Request.GetBody to support HTTP/2 GOAWAY retries#1020
Open
thinker0 wants to merge 1 commit into
Open
Conversation
… HTTP/2 GOAWAY retries Signed-off-by: thinker0 <thinker0@gmail.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.
Description
This pull request solves the
502 Bad Gatewayerror on POST/PUT requests when the upstream server returns an HTTP/2 GOAWAY frame (e.g., during keep-alive rotation or rolling updates).Root cause:
In
pkg/proxy/engines/httpproxy.go, upstream requests with bodies (like POST requests) did not define the Go standard libraryhttp.Request.GetBodyfield. When the Gohttp2.Transport(orhttp.Transportfor reused connections) receives a GOAWAY or connection-level error, it tries to automatically retry the request, but ONLY ifRequest.GetBodyis set. WithoutGetBody, the transport cannot re-read the request body, aborts the retry, and Trickster proxy returns502 Bad Gateway(under the log signaturenil response from upstream originwith detailhttp2: Transport: cannot retry err after Request.Body was written; define Request.GetBody to avoid this error).Solution:
Before calling
o.HTTPClient.Do(r)inPrepareFetchReader, we read the request body into a memory buffer and setr.GetBodyto return a newio.ReadCloserreading from that buffer. This allows Go's HTTP client/transport to clone and re-read the body during transient network/HTTP2 connection failure retries.Also added clean unit tests (
TestPrepareFetchReader_GetBodyandTestHTTP2GOAWAYRetryinhttpproxy_test.go) to verify body replication and the end-to-end transport retry flow.Type of Change
AI Disclosure