diff --git a/common/httpx/http11_fallback_test.go b/common/httpx/http11_fallback_test.go new file mode 100644 index 00000000..e7626f74 --- /dev/null +++ b/common/httpx/http11_fallback_test.go @@ -0,0 +1,23 @@ +package httpx + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNew_HTTP11DisablesRetryableHTTP2Fallback(t *testing.T) { + opts := DefaultOptions + opts.Protocol = HTTP11 + + ht, err := New(&opts) + require.NoError(t, err) + require.NotNil(t, ht) + require.NotNil(t, ht.client) + require.NotNil(t, ht.client.HTTPClient) + require.NotNil(t, ht.client.HTTPClient2) + + // Protocol pinning expectation: when forced to HTTP/1.1, retry fallback should + // stay on the same client/transport instead of switching to dedicated HTTP/2. + require.Same(t, ht.client.HTTPClient, ht.client.HTTPClient2) +} diff --git a/common/httpx/httpx.go b/common/httpx/httpx.go index 039f4c4c..39a6d0ce 100644 --- a/common/httpx/httpx.go +++ b/common/httpx/httpx.go @@ -183,6 +183,13 @@ func New(options *Options) (*HTTPX, error) { CheckRedirect: redirectFunc, }, retryablehttpOptions) + // When protocol is explicitly forced to HTTP/1.1, prevent retryablehttp from + // falling back to its dedicated HTTP/2 client path on malformed HTTP/2 errors. + // Keep retries enabled, but pinned to the same HTTP/1.1 transport settings. + if httpx.Options.Protocol == HTTP11 { + httpx.client.HTTPClient2 = httpx.client.HTTPClient + } + transport2 := &http2.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true,