Skip to content

fix: enforce -pr http11 across retry fallback path#2421

Open
juzigu40-ui wants to merge 4 commits intoprojectdiscovery:devfrom
juzigu40-ui:codex/v100-httpx-2240
Open

fix: enforce -pr http11 across retry fallback path#2421
juzigu40-ui wants to merge 4 commits intoprojectdiscovery:devfrom
juzigu40-ui:codex/v100-httpx-2240

Conversation

@juzigu40-ui
Copy link

@juzigu40-ui juzigu40-ui commented Feb 25, 2026

Proposed Changes

This PR keeps -pr http11 deterministic by preventing retry fallback from switching protocol unexpectedly, while keeping change scope minimal.

What changed

  • In common/httpx/httpx.go:
    • use HTTP11 constant for protocol gating
    • disable HTTP/2 at transport scope via TLSNextProto in HTTP/1.1 mode
    • avoid mutating process-wide GODEBUG in client initialization
    • keep retry fallback on the same HTTP/1.1-configured client when -pr http11 is requested:
      • httpx.client.HTTPClient2 = httpx.client.HTTPClient
  • In common/httpx/httpx_test.go:
    • TestHTTP11DisablesRetryableHTTP2Fallback
    • TestDefaultProtocolKeepsRetryableHTTP2Fallback

Why this approach

retryablehttp-go fallback path currently calls HTTPClient2 on malformed HTTP/2 framing errors. For explicit HTTP/1.1 mode, this patch keeps fallback on the HTTP/1.1 client path and avoids protocol drift.

Proof

go test ./common/httpx -run 'TestHTTP11DisablesRetryableHTTP2Fallback|TestDefaultProtocolKeepsRetryableHTTP2Fallback' -count=1
go test ./common/httpx -count=1

Checklist

  • PR created against dev
  • Tests added/updated for regression coverage
  • Local validation run
  • /claim #2240 included

Ref: #2240

/claim #2240

Summary by CodeRabbit

  • Bug Fixes

    • Internal retry logic now preserves an explicitly selected HTTP/1.1 protocol so retries no longer fall back to HTTP/2.
  • Tests

    • Added test coverage validating HTTP/1.1 enforcement, mixed-case protocol handling, and default protocol fallback behavior.
  • Refactor

    • Minor internal cleanup to simplify protocol detection and initialization.

@auto-assign auto-assign bot requested a review from dwisiswant0 February 25, 2026 05:06
@coderabbitai
Copy link

coderabbitai bot commented Feb 25, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 95b25bc1-4f74-4181-ae08-2a1509c02aed

📥 Commits

Reviewing files that changed from the base of the PR and between e1550f8 and 8542673.

📒 Files selected for processing (2)
  • common/httpx/httpx.go
  • common/httpx/httpx_test.go

Walkthrough

When Protocol is HTTP11, New uses isHTTP11Protocol and sets the retry client's HTTPClient2 to the same instance as HTTPClient. The GODEBUG-based environment toggle for HTTP/2 and the unused os import were removed. Three unit tests were added to verify behavior.

Changes

Cohort / File(s) Summary
HTTPX core changes
common/httpx/httpx.go
Replaced direct protocol string comparison with isHTTP11Protocol(protocol) helper; removed GODEBUG env manipulation and unused os import; when protocol is HTTP/1.1 assign client.HTTPClient2 = client.HTTPClient to disable retryable HTTP/2 fallback.
Tests
common/httpx/httpx_test.go
Added three tests: TestHTTP11DisablesRetryableHTTP2Fallback, TestHTTP11MixedCaseDisablesRetryableHTTP2Fallback, and TestDefaultProtocolKeepsRetryableHTTP2Fallback to assert identity or difference of HTTPClient and HTTPClient2 for HTTP/1.1 (including mixed case) and default protocol.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I nibbled code with gentle paws,
Merged two clients without a cause,
No env var tangles, neat and clean,
Tests hop in to prove the scene,
A tiny carrot, logic seen. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: enforcing HTTP/1.1 protocol across the retry fallback path, which is the core objective of the PR.

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

✨ Finishing Touches
🧪 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.

@neo-by-projectdiscovery-dev
Copy link

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

Neo - PR Security Review

No security issues found

Highlights

  • Simplified test cleanup in TestHTTP11DisablesRetryableHTTP2Fallback by removing GODEBUG environment variable restoration code
  • Reduced test complexity from 22 lines to core assertion logic (9 lines net reduction)
  • No changes to the core HTTP/1.1 enforcement logic in httpx.go
Hardening Notes
  • The incremental diff between ba8ea42 and e1550f8 contains only test code simplification and PR description updates
  • The core security-relevant logic (HTTP/1.1 protocol enforcement at httpx.go:183-186) remains unchanged in this commit

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

@juzigu40-ui juzigu40-ui force-pushed the codex/v100-httpx-2240 branch from 5af6e9f to 83b3c34 Compare March 4, 2026 09:37
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_test.go`:
- Around line 36-37: After calling New(&opts) in the test (which sets
GODEBUG=http2client=0 via the code in New), restore the original GODEBUG
environment variable to avoid cross-test state leakage: capture
os.Getenv("GODEBUG") before calling New(&opts) and defer restoring it with
os.Setenv (or os.Unsetenv if it was empty) after the call so subsequent tests
don't inherit the modified GODEBUG; update the test around the New(&opts)
invocation to save/restore the environment.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d82d46ac-5d3e-4596-a485-29903e301ec1

📥 Commits

Reviewing files that changed from the base of the PR and between 5af6e9f and 83b3c34.

📒 Files selected for processing (2)
  • common/httpx/httpx.go
  • common/httpx/httpx_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • common/httpx/httpx.go

@juzigu40-ui
Copy link
Author

Update: refreshed this PR to a clean single-commit patch on top of current dev and re-ran validation.

Proof:
go test ./common/httpx -run TestHTTP11DisablesRetryableHTTP2Fallback -count=1
go test ./common/httpx -count=1

Change scope remains minimal (2 files):

  • common/httpx/httpx.go
  • common/httpx/httpx_test.go

This keeps HTTP/1.1 behavior deterministic when -pr http11 is explicitly requested.

@juzigu40-ui
Copy link
Author

Addressed the CodeRabbit isolation finding.

What changed:

  • restored GODEBUG state in TestHTTP11DisablesRetryableHTTP2Fallback via test cleanup to avoid cross-test leakage.

Validation re-run:

  • go test ./common/httpx -run TestHTTP11DisablesRetryableHTTP2Fallback -count=1
  • go test ./common/httpx -count=1

@juzigu40-ui
Copy link
Author

@Mzack9999 @dogancanbakir quick update:

  • /attempt #2240 is now registered on the issue.
  • /claim #2240 is included in this PR body.
  • Addressed test-isolation concern by restoring GODEBUG in TestHTTP11DisablesRetryableHTTP2Fallback.
  • Revalidated with:
    • go test ./common/httpx -run TestHTTP11DisablesRetryableHTTP2Fallback -count=1
    • go test ./common/httpx -count=1

Patch scope remains minimal (2 files) and focused on #2240 behavior.

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_test.go (1)

32-47: Add one mixed-case protocol regression test

These tests are solid for the lowercase constant path. Please add a case using opts.Protocol = Proto("HTTP11") to lock in behavior for the case-insensitive CLI contract as well.

🧪 Suggested test
+func TestHTTP11MixedCaseDisablesRetryableHTTP2Fallback(t *testing.T) {
+	opts := DefaultOptions
+	opts.Protocol = Proto("HTTP11")
+
+	ht, err := New(&opts)
+	require.NoError(t, err)
+	require.Same(t, ht.client.HTTPClient, ht.client.HTTPClient2)
+}
🤖 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 32 - 47, Add a new test that mirrors
TestHTTP11DisablesRetryableHTTP2Fallback but sets opts.Protocol =
Proto("HTTP11") (mixed-case) to ensure the protocol handling is
case-insensitive; instantiate with New(&opts), assert no error, and assert
ht.client.HTTPClient and ht.client.HTTPClient2 are the same (using
require.Same), similar to the existing test patterns; place it next to
TestHTTP11DisablesRetryableHTTP2Fallback so it covers the CLI contract for
mixed-case input.
🤖 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.go`:
- Around line 155-158: The protocol checks use exact equality against the HTTP11
constant so case-variants (e.g., "HTTP11" or "http11") slip through; update the
checks that compare httpx.Options.Protocol to HTTP11 (the branches that set
transport.TLSNextProto and the related branch around lines ~183-186) to perform
a case-insensitive comparison (e.g., use strings.EqualFold or normalize to
upper/lowercase) when evaluating httpx.Options.Protocol, ensuring any casing of
the CLI flag correctly triggers the HTTP/1.1-only behavior.

---

Nitpick comments:
In `@common/httpx/httpx_test.go`:
- Around line 32-47: Add a new test that mirrors
TestHTTP11DisablesRetryableHTTP2Fallback but sets opts.Protocol =
Proto("HTTP11") (mixed-case) to ensure the protocol handling is
case-insensitive; instantiate with New(&opts), assert no error, and assert
ht.client.HTTPClient and ht.client.HTTPClient2 are the same (using
require.Same), similar to the existing test patterns; place it next to
TestHTTP11DisablesRetryableHTTP2Fallback so it covers the CLI contract for
mixed-case input.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c555fb4f-8566-4fea-b636-de1449836447

📥 Commits

Reviewing files that changed from the base of the PR and between ba8ea42 and e1550f8.

📒 Files selected for processing (2)
  • common/httpx/httpx.go
  • common/httpx/httpx_test.go

@juzigu40-ui
Copy link
Author

@Mzack9999 quick review ping on #2240:

This PR keeps scope intentionally small (2 files in common/httpx) and does not introduce new retryablehttp-go options. It enforces HTTP/1.1 deterministically by reusing the already-configured HTTP/1.1 client on retry fallback when -pr http11 is set.

Current regression coverage in this PR:

  • TestHTTP11DisablesRetryableHTTP2Fallback
  • TestHTTP11MixedCaseDisablesRetryableHTTP2Fallback
  • TestDefaultProtocolKeepsRetryableHTTP2Fallback

Revalidated with:

  • go test ./common/httpx -run TestHTTP11DisablesRetryableHTTP2Fallback -count=1
  • go test ./common/httpx -count=1

If you prefer this minimal-path approach, I can follow up immediately with any requested adjustments.

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.

1 participant