fix: respect -pr http11 flag by disabling HTTP/2 fallback#2408
fix: respect -pr http11 flag by disabling HTTP/2 fallback#2408285729101 wants to merge 1 commit intoprojectdiscovery:devfrom
Conversation
…ehttp When httpx is run with `-pr http11`, the transport is correctly configured to disable HTTP/2 negotiation. However, retryablehttp-go's fallback logic in do.go switches to HTTPClient2 (an HTTP/2-capable client) when it encounters "malformed HTTP version" errors, bypassing the user's explicit protocol selection. Fix this by setting HTTPClient2 to the same client as HTTPClient when Protocol == "http11", so the fallback path cannot switch protocols. Fixes projectdiscovery#2240
WalkthroughThis change fixes the HTTP/1.1 protocol flag being ignored due to HTTP/2 fallback in retryablehttp-go. When protocol is set to "http11", the HTTP/2 fallback client is reassigned to use the standard HTTP client, preventing unintended protocol switches on connection errors. Changes
Estimated Code Review Effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. 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 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
common/httpx/httpx_test.go (1)
51-58: Minor:&DefaultOptionsis passed directly, whichNew()may mutate.
New()callsparseCustomCookies()on the options pointer (line 74 of httpx.go). Passing&DefaultOptionsdirectly could mutate the package-level variable, potentially causing test interference depending on execution order. Consider copying like the http11 test does:- ht, err := New(&DefaultOptions) + opts := DefaultOptions + ht, err := New(&opts)The same pattern exists in
TestDo(line 13), but since you're already doing it correctly inTestHTTP11DisablesHTTP2Fallback, it'd be good to be consistent.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@common/httpx/httpx_test.go` around lines 51 - 58, TestDefaultProtocolKeepsHTTP2Fallback passes &DefaultOptions directly which New() (via parseCustomCookies) may mutate; change the test to pass a local copy of DefaultOptions (e.g., create a local variable like opt := DefaultOptions and call New(&opt)) so New() mutates the copy not the package-level DefaultOptions—follow the same pattern used in TestHTTP11DisablesHTTP2Fallback and TestDo.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@common/httpx/httpx_test.go`:
- Around line 51-58: TestDefaultProtocolKeepsHTTP2Fallback passes
&DefaultOptions directly which New() (via parseCustomCookies) may mutate; change
the test to pass a local copy of DefaultOptions (e.g., create a local variable
like opt := DefaultOptions and call New(&opt)) so New() mutates the copy not the
package-level DefaultOptions—follow the same pattern used in
TestHTTP11DisablesHTTP2Fallback and TestDo.
Proposed Changes
/claim #2240
Fixes #2240
Problem
When running httpx with
-pr http11, the transport is correctly configured to disable HTTP/2:However, retryablehttp-go creates a separate
HTTPClient2with HTTP/2 enabled. Indo.go, when certain protocol errors are encountered, it falls back toHTTPClient2:This bypasses the user's explicit HTTP/1.1 protocol selection, making
-pr http11unreliable.Solution
After creating the retryablehttp client, when
Protocol == "http11", setHTTPClient2to the same client asHTTPClient. This prevents retryablehttp's fallback from switching to an HTTP/2-capable client:This approach:
Proof
All tests pass locally (fully offline, no external network calls):
Tests Added
TestHTTP11DisablesHTTP2Fallback- verifiesHTTPClient2 == HTTPClient(pointer identity) when-pr http11is setTestDefaultProtocolKeepsHTTP2Fallback- verifiesHTTPClient2 != HTTPClientin default mode (HTTP/2 fallback preserved)TestDoto usehttptest.NewServerinstead of external URLs for offline testingChecklist
dev)Summary by CodeRabbit
Bug Fixes
Tests