Skip to content

feat(ws): support replacing forwarded headers - #171

Open
DavidIlie wants to merge 3 commits into
unjs:mainfrom
DavidIlie:codex/ws-forwarded-replace
Open

DavidIlie wants to merge 3 commits into
unjs:mainfrom
DavidIlie:codex/ws-forwarded-replace

Conversation

@DavidIlie

@DavidIlie DavidIlie commented Sep 10, 2026

Copy link
Copy Markdown

Summary

Adds xfwd: "replace" to standalone proxyUpgrade for applications that want to discard the incoming forwarding chain.

The mode removes incoming Forwarded and X-Forwarded-* fields and generates new forwarding values from the incoming socket. The address comes from remoteAddress, the port from localPort with an 80/443 fallback, and the protocol from the socket's encryption. It does not use the client-controlled Host port. Caller-supplied headers take precedence case-insensitively in every mode, including replacement.

Default and true modes append forwarding values; false adds none. A missing remote address does not generate an x-forwarded-for value. Forwarding does not mutate the incoming request headers or raw headers.

Verification

  • pnpm vitest run test/ws.test.ts
  • pnpm test
  • pnpm build
  • Focused tests pass on Node 24.11.1 and 26.5.0.
  • Regression coverage includes replacement, spoofed Host ports, caller overrides, missing remote addresses, and request-header immutability.

@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 59 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 96eac341-e35a-42c1-9514-649c769aa91b

📥 Commits

Reviewing files that changed from the base of the PR and between 54e4263 and 66e35e6.

📒 Files selected for processing (5)
  • AGENTS.md
  • README.md
  • src/ws.ts
  • test/types.test-d.ts
  • test/ws.test.ts

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.

pi0 added 2 commits September 15, 2026 18:54
…roxy

- Replace `Object.create(req)` with header defaults merged under `opts.headers`
- Omit `x-forwarded-for` when the socket has no `remoteAddress`
- Drop implementation-specific read-only/setter tests
- Note that `x-forwarded-port` derives from client-controlled `Host`
- Fix stale `upgrade.ts` references in AGENTS.md
@pi0x

pi0x commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Thanks for the PR! I've pushed a follow-up commit with some changes to the xfwd: "replace" design:

  • x-forwarded-port in replace mode comes from req.socket.localPort, falling back to 80/443, instead of the Host header. Replace mode is meant for trust boundaries, so it shouldn't pass along a port the client controls. Append mode still reads Host, as before.
  • Caller headers now win in replace mode too. Incoming Forwarded and X-Forwarded-* headers are removed, the generated for/port/proto values are added, and anything passed via headers (checked case-insensitively) takes precedence. This matches the boolean modes and lets callers add trusted values like x-forwarded-host.
  • Simpler flow. _getForwardedHeaders() builds the generated values for both append and replace. They're merged with caller headers before setupOutgoing, and replace mode then only removes the forwarding headers copied from the incoming request.
  • Docs. README and AGENTS.md are updated. AGENTS.md now also notes that x-forwarded-for is omitted, rather than sent as "undefined", when the socket has no remoteAddress.

New tests cover a spoofed Host port and caller overrides in replace mode. Both fail on the previous version. pnpm test passes.

Note

This review and follow-up commit were generated with an AI assistant.

@codecov

codecov Bot commented Sep 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.16%. Comparing base (54e4263) to head (66e35e6).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #171      +/-   ##
==========================================
+ Coverage   95.03%   95.16%   +0.13%     
==========================================
  Files           8        8              
  Lines         805      827      +22     
  Branches      331      339       +8     
==========================================
+ Hits          765      787      +22     
  Misses         35       35              
  Partials        5        5              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@DavidIlie
DavidIlie marked this pull request as ready for review September 18, 2026 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants