Merge 2dfef082f1 into 0d2a7a0385
This commit is contained in:
commit
0e5a02095c
|
|
@ -220,11 +220,23 @@ func (p *Proxy) proxyHTTPRequest(
|
||||||
_, ttfbSpan := tr.Tracer().Start(tr.Context(), "ttfb_origin")
|
_, ttfbSpan := tr.Tracer().Start(tr.Context(), "ttfb_origin")
|
||||||
resp, err := httpService.RoundTrip(roundTripReq)
|
resp, err := httpService.RoundTrip(roundTripReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tracing.EndWithErrorStatus(ttfbSpan, err)
|
// Check for GOAWAY error and retry once if applicable
|
||||||
if err := roundTripReq.Context().Err(); err != nil {
|
const goawayMsg = "http2: Transport received Server's graceful shutdown GOAWAY"
|
||||||
return errors.Wrap(err, "Incoming request ended abruptly")
|
if err.Error() == goawayMsg && roundTripReq.GetBody != nil {
|
||||||
|
// Reset the body for retry
|
||||||
|
newBody, getBodyErr := roundTripReq.GetBody()
|
||||||
|
if getBodyErr == nil {
|
||||||
|
roundTripReq.Body = newBody
|
||||||
|
resp, err = httpService.RoundTrip(roundTripReq)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
tracing.EndWithErrorStatus(ttfbSpan, err)
|
||||||
|
if err := roundTripReq.Context().Err(); err != nil {
|
||||||
|
return errors.Wrap(err, "Incoming request ended abruptly")
|
||||||
|
}
|
||||||
|
return errors.Wrap(err, "Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared")
|
||||||
}
|
}
|
||||||
return errors.Wrap(err, "Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing.EndWithStatusCode(ttfbSpan, resp.StatusCode)
|
tracing.EndWithStatusCode(ttfbSpan, resp.StatusCode)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
@ -1014,3 +1015,61 @@ func runEchoWSService(t *testing.T, l net.Listener) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHandleGOAWAYRetry(t *testing.T) {
|
||||||
|
// Simulate a request body
|
||||||
|
bodyContent := "test body content"
|
||||||
|
body := io.NopCloser(strings.NewReader(bodyContent))
|
||||||
|
|
||||||
|
// Create a mock request with a body
|
||||||
|
roundTripReq := &http.Request{
|
||||||
|
Body: body,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate the GOAWAY error
|
||||||
|
goawayError := errors.New("http2: Transport received Server's graceful shutdown GOAWAY")
|
||||||
|
|
||||||
|
// Assign the GetBody function
|
||||||
|
roundTripReq.GetBody = func() (io.ReadCloser, error) {
|
||||||
|
if goawayError.Error() == "http2: Transport received Server's graceful shutdown GOAWAY" {
|
||||||
|
return roundTripReq.Body, nil
|
||||||
|
}
|
||||||
|
return nil, goawayError
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test the GetBody function
|
||||||
|
retriedBody, err := roundTripReq.GetBody()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no error, got: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the retried body content
|
||||||
|
retriedContent, _ := io.ReadAll(retriedBody)
|
||||||
|
if string(retriedContent) != bodyContent {
|
||||||
|
t.Fatalf("Expected body content '%s', got '%s'", bodyContent, string(retriedContent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func TestHandleGOAWAYRetryError(t *testing.T) {
|
||||||
|
// Simulate a request body
|
||||||
|
bodyContent := "test body content"
|
||||||
|
body := io.NopCloser(strings.NewReader(bodyContent))
|
||||||
|
|
||||||
|
// Create a mock request with a body
|
||||||
|
roundTripReq := &http.Request{
|
||||||
|
Body: body,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate the GOAWAY error
|
||||||
|
goawayError := errors.New("http2: Transport received Server's graceful shutdown GOAWAY")
|
||||||
|
|
||||||
|
// Assign the GetBody function to return an error
|
||||||
|
roundTripReq.GetBody = func() (io.ReadCloser, error) {
|
||||||
|
return nil, goawayError
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test the GetBody function
|
||||||
|
retriedBody, err := roundTripReq.GetBody()
|
||||||
|
if retriedBody != nil || err == nil {
|
||||||
|
t.Fatalf("Expected error, got body: %v, error: %v", retriedBody, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue