fix: respect -pr http11 flag by disabling HTTP/2 fallback#2450
fix: respect -pr http11 flag by disabling HTTP/2 fallback#2450VoidChecksum wants to merge 1 commit intoprojectdiscovery:devfrom
Conversation
When users specify -pr http11 to force HTTP/1.1-only connections, httpx correctly disables HTTP/2 on the primary transport. However, retryablehttp-go's fallback mechanism automatically retries failed HTTP/1.x requests with an HTTP/2 client (HTTPClient2), effectively bypassing the explicit protocol restriction. Disable the HTTP/2 fallback when HTTP/1.1-only mode is requested so the protocol flag is respected throughout the entire request lifecycle, including retries. Fixes projectdiscovery#2240
Neo - PR Security ReviewNo security issues found Highlights
Hardening Notes
Comment |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughRefactors HTTP client setup in httpx to ensure HTTP/1.1 protocol configuration is consistently applied to retryablehttp's retry mechanism. When HTTP/1.1 mode is enabled, the HTTPClient2 fallback client in retryablehttp is replaced with the primary client, preventing unintended HTTP/2 protocol fallback during retries. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip CodeRabbit can generate a title for your PR based on the changes with custom instructions.Set the |
There was a problem hiding this comment.
Pull request overview
This PR ensures the -pr http11 (HTTP/1.1-only) setting is respected end-to-end by preventing retryablehttp-go from silently retrying failed requests using its internal HTTP/2-capable fallback client.
Changes:
- Refactors HTTP client construction into a named
httpClientvariable for reuse. - When
Protocolis HTTP/1.1-only, overridesretryablehttp’sHTTPClient2fallback to use the same HTTP/1.1 client/transport.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| // responses. Override that fallback client with the same HTTP/1.1 transport | ||
| // so the -pr http11 flag is respected throughout the entire request | ||
| // lifecycle, including retries. | ||
| if httpx.Options.Protocol == "http11" { |
| httpClient := &http.Client{ | ||
| Transport: transport, | ||
| Timeout: httpx.Options.Timeout, | ||
| CheckRedirect: redirectFunc, | ||
| }, retryablehttpOptions) | ||
| } | ||
| httpx.client = retryablehttp.NewWithHTTPClient(httpClient, retryablehttpOptions) | ||
|
|
||
| // When HTTP/1.1-only mode is requested, the retryablehttp-go library still | ||
| // has an internal fallback (HTTPClient2) that retries with a native HTTP/2 | ||
| // client when it encounters certain error messages about malformed HTTP/2 | ||
| // responses. Override that fallback client with the same HTTP/1.1 transport | ||
| // so the -pr http11 flag is respected throughout the entire request | ||
| // lifecycle, including retries. | ||
| if httpx.Options.Protocol == "http11" { | ||
| httpx.client.HTTPClient2 = httpClient | ||
| } |
Summary
When users specify
-pr http11to force HTTP/1.1-only connections, httpx correctly disables HTTP/2 on the primary transport viatransport.TLSNextProto = map[string]...{}. However,retryablehttp-go's fallback mechanism silently retries failed requests with an HTTP/2-capable client (HTTPClient2), effectively bypassing the explicit protocol restriction.This means
-pr http11is not actually enforced — any target that returns malformed HTTP/1.x responses triggers an automatic HTTP/2 retry through a completely separate client that ignores the user's protocol preference.Root Cause
In
retryablehttp-go/do.go, theDo()method contains:HTTPClient2is initialized internally withhttp2.ConfigureTransport(), making it HTTP/2-capable regardless of the user's-prflag.Fix
After creating the retryablehttp client with the HTTP/1.1-only
*http.Client, override the fallbackHTTPClient2with the same client whenProtocol == "http11":This ensures the
-pr http11flag is respected end-to-end, including during the HTTP/2 fallback path in retries.Test plan
-pr http11against an HTTP/2-only server: requests fail cleanly instead of silently upgrading-prflag): HTTP/2 fallback works as before (no behavioral change)-pr http2mode: unaffectedRelated
Fixes #2240
Summary by CodeRabbit