Skip to content

fix(httpx): honor -pr http11 in h2 probe client#2416

Closed
wh0amibjm wants to merge 3 commits intoprojectdiscovery:devfrom
wh0amibjm:fix/algora-2240-http11-no-h2-fallback-followup
Closed

fix(httpx): honor -pr http11 in h2 probe client#2416
wh0amibjm wants to merge 3 commits intoprojectdiscovery:devfrom
wh0amibjm:fix/algora-2240-http11-no-h2-fallback-followup

Conversation

@wh0amibjm
Copy link

@wh0amibjm wh0amibjm commented Feb 20, 2026

Follow-up to #2414 and issue #2240.

This patch ensures explicit -pr http11 is honored across both retry fallback and HTTP/2 probe paths:

  • sets httpx.client2 = httpx.client.HTTPClient in HTTP11 mode
  • keeps dedicated HTTP/2 client only when protocol is not forced to HTTP11
  • adds/updates tests for both behaviors
  • adds dialer cleanup via t.Cleanup in protocol tests

Validation:

go test ./common/httpx -run TestNew_ -count=1

/claim #2240

Summary by CodeRabbit

  • New Features

    • HTTP/1.1 mode now disables HTTP/2 fallback and routes both client paths through a single shared client.
    • Protocol selection controls whether a dedicated HTTP/2 transport is created or skipped.
  • Tests

    • Added unit tests verifying shared-client behavior for HTTP/1.1 and dedicated HTTP/2 transport for non-HTTP/1.1.

@neo-by-projectdiscovery-dev
Copy link

neo-by-projectdiscovery-dev bot commented Feb 20, 2026

Neo Security Audit

No security issues found

Hardening Notes
  • Semgrep flagged TLS settings at lines 193-196, but these are pre-existing configurations (also present at lines 144, 149-151) that were moved into conditional logic, not newly introduced vulnerabilities
  • The PR correctly implements protocol forcing by setting both httpx.client.HTTPClient2 and httpx.client2 to the HTTP/1.1 client when Protocol == HTTP11
  • Test coverage includes proper cleanup of resources (dialer, GODEBUG env var) via t.Cleanup
  • No user-controlled input flows through the changed code paths - this is internal client configuration logic

Comment @neo help for available commands. · Open in Neo

@coderabbitai
Copy link

coderabbitai bot commented Feb 20, 2026

Walkthrough

Replaces a string-literal protocol check with a HTTP11 constant and, when selected, reuses the primary HTTP client for both client paths (skipping separate http2.Transport creation); retains prior HTTP/2 transport initialization for non-HTTP/1.1. Two tests validate both behaviors.

Changes

Cohort / File(s) Summary
Core HTTP client behavior
common/httpx/httpx.go
Replaces "http11" literal with HTTP11 constant; when HTTP11 is set, assigns httpx.client.HTTPClient2 = httpx.client.HTTPClient and httpx.client2 = httpx.client.HTTPClient (no separate http2.Transport); else continues to create a dedicated http2.Transport. SNI, proxy, TLS, and GODEBUG handling retained.
Protocol tests
common/httpx/httpx_protocol_test.go
Adds two unit tests: one asserting HTTP/1.1 mode reuses the same client and avoids an http2.Transport; another asserting non-HTTP/1.1 mode creates a distinct http2.Transport and separate client. Includes dialer cleanup and transport-type assertions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I tunneled through options, found a neat switch,
HTTP/1.1 snugly reuses the same stitch,
HTTP/2 keeps its bouncy new gear,
Tests hop along to make it clear,
A tiny change, a confident twitch.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and concisely describes the main change: ensuring the HTTP/1.1 protocol flag is honored in the HTTP/2 probe client logic.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
common/httpx/httpx.go (1)

186-206: Use the HTTP11 typed constant instead of the "http11" string literal

The test file uses opts.Protocol = HTTP11 (the typed Proto constant defined in proto.go), but the production code at lines 156 and 188 compares against the bare string "http11". Using the constant in both places keeps the comparison DRY and eliminates a silent mismatch risk if the constant value ever changes.

♻️ Proposed change (applies to lines 156 and 188)
-	if httpx.Options.Protocol == "http11" {
+	if httpx.Options.Protocol == HTTP11 {
 		// ... protocol handling
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@common/httpx/httpx.go` around lines 186 - 206, Replace the string literal
"http11" comparisons with the typed constant HTTP11 (the Proto constant defined
in proto.go) so the checks use httpx.Options.Protocol == HTTP11 instead of ==
"http11"; update both locations where the literal is used (the branch deciding
HTTP/1.1 mode and the related branch later in the file) to reference the HTTP11
constant to keep comparisons consistent and DRY.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@common/httpx/httpx_protocol_test.go`:
- Around line 11-24: The test leaks a process-wide GODEBUG change because
New(&opts) with opts.Protocol = HTTP11 calls os.Setenv("GODEBUG",
"http2client=0") and never restores it; modify
TestNew_HTTP11DisablesRetryableHTTP2Fallback to capture the original
os.Getenv("GODEBUG") before calling New, and register a t.Cleanup that restores
the original value (use os.Setenv to restore non-empty original, or os.Unsetenv
if it was empty) so the GODEBUG setting is returned to its prior state after the
test; reference the New function, opts.Protocol/HTTP11 setup, and the
os.Setenv("GODEBUG", ...) side effect when applying the fix.

---

Nitpick comments:
In `@common/httpx/httpx.go`:
- Around line 186-206: Replace the string literal "http11" comparisons with the
typed constant HTTP11 (the Proto constant defined in proto.go) so the checks use
httpx.Options.Protocol == HTTP11 instead of == "http11"; update both locations
where the literal is used (the branch deciding HTTP/1.1 mode and the related
branch later in the file) to reference the HTTP11 constant to keep comparisons
consistent and DRY.

@wh0amibjm
Copy link
Author

Addressed CodeRabbit follow-up in 58e14d4:

  • replaced string literals with typed constant HTTP11 in protocol checks
  • added GODEBUG restore cleanup in TestNew_HTTP11DisablesRetryableHTTP2Fallback

Validation:

go test ./common/httpx -run TestNew_ -count=1

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@common/httpx/httpx_protocol_test.go`:
- Around line 16-23: The code correctly uses os.LookupEnv to capture
originalGODEBUG and hadGODEBUG and restores state in t.Cleanup using os.Setenv
or os.Unsetenv; keep this implementation as-is (no change needed) and ensure the
variables originalGODEBUG, hadGODEBUG and the t.Cleanup block remain present so
an originally unset GODEBUG is restored to unset rather than set to an empty
string.

@wh0amibjm
Copy link
Author

Quick follow-up after latest bot review pass:

  • re-checked current branch (58e14d4) against prior actionable feedback
  • no remaining actionable review items detected on my side
  • tests for touched area still pass locally:
    • go test ./common/httpx -run TestNew_ -count=1

Ready for maintainer review/merge when convenient.

@wh0amibjm
Copy link
Author

Pushed a small follow-up to address the docstring-coverage warning by adding doc comments to the exported protocol tests (no functional changes).

Proof:

go test ./common/httpx -run TestNew_ -count=1

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@common/httpx/httpx_protocol_test.go`:
- Around line 48-49: Add a nil-guard before dereferencing ht.client2: ensure
ht.client2 is non-nil (e.g., call require.NotNil(t, ht.client2)) before doing
the type assertion on ht.client2.Transport; this prevents a nil-pointer panic
when require.NotSame passes and lets the test fail cleanly if client2 is nil.

---

Duplicate comments:
In `@common/httpx/httpx_protocol_test.go`:
- Around line 17-24: The GODEBUG save/restore is already correct: os.LookupEnv
is used to distinguish unset vs empty and t.Cleanup is registered before any
environment modification (e.g., before New changes GODEBUG), so no change is
needed—leave the os.LookupEnv, hadGODEBUG assignment and the t.Cleanup restore
logic as-is.

Comment on lines +48 to +49
require.NotSame(t, ht.client.HTTPClient, ht.client2)
_, isHTTP2 := ht.client2.Transport.(*http2.Transport)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a nil guard for ht.client2 before accessing .Transport.

require.NotSame at line 48 passes silently when ht.client2 is nil (nil address ≠ non-nil address), so execution reaches line 49 and panics with a nil-pointer dereference instead of producing a clean test-failure message. Test 1 is safe because require.Same would fail if client2 were nil, but require.NotSame provides no such protection here.

🛡️ Proposed fix
 	require.NotSame(t, ht.client.HTTPClient, ht.client2)
+	require.NotNil(t, ht.client2)
 	_, isHTTP2 := ht.client2.Transport.(*http2.Transport)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
require.NotSame(t, ht.client.HTTPClient, ht.client2)
_, isHTTP2 := ht.client2.Transport.(*http2.Transport)
require.NotSame(t, ht.client.HTTPClient, ht.client2)
require.NotNil(t, ht.client2)
_, isHTTP2 := ht.client2.Transport.(*http2.Transport)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@common/httpx/httpx_protocol_test.go` around lines 48 - 49, Add a nil-guard
before dereferencing ht.client2: ensure ht.client2 is non-nil (e.g., call
require.NotNil(t, ht.client2)) before doing the type assertion on
ht.client2.Transport; this prevents a nil-pointer panic when require.NotSame
passes and lets the test fail cleanly if client2 is nil.

@dogancanbakir
Copy link
Member

Hi, thanks for your interest in contributing! Just a heads up, we ask contributors to work on 1 active issue at a time (see).

Also, we welcome AI-assisted development, but submissions must be complete, tested, and ready to merge. Please also make sure to fill out the PR template with proof that your changes work.

We're closing this PR along with your other open submissions. Once you're ready, feel free to pick one issue to focus on and resubmit; we'd be happy to review it.

Appreciate your understanding!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants