Skip to content

refactor(request): align jsdocs with getRequestHost#1316

Merged
pi0 merged 4 commits into
mainfrom
fix/get-request-host-default
Mar 14, 2026
Merged

refactor(request): align jsdocs with getRequestHost#1316
pi0 merged 4 commits into
mainfrom
fix/get-request-host-default

Conversation

@productdevbook

@productdevbook productdevbook commented Mar 14, 2026

Copy link
Copy Markdown
Member

Summary

  • getRequestHost() returned "" when no host header was found, but its JSDoc documented "localhost" as the default — now returns "localhost" to match
  • Updated getRequestURL() to only override the URL host when an actual x-forwarded-host header is present, preventing the "localhost" fallback from incorrectly replacing a valid host in the request URL
  • Added tests for getRequestHost covering default value, x-forwarded-host, and multi-value scenarios

Test plan

  • All existing utils tests pass (77/77)
  • New getRequestHost tests pass in both web and node modes

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved request host resolution: when no Host header is present it returns empty instead of defaulting, and parsing of forwarded-host headers now uses the first value and handles ports correctly.
  • Tests

    • Added tests covering Host and forwarded-host resolution and multi-value forwarded headers.
  • Documentation

    • Updated docs to reflect the new host-resolution behavior when Host header is absent.

@productdevbook
productdevbook requested a review from pi0 as a code owner March 14, 2026 15:51
@coderabbitai

coderabbitai Bot commented Mar 14, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

getRequestURL now parses the x-forwarded-host header directly (uses first comma-separated value, clears port if absent). getRequestHost docstring now states it returns an empty string when no Host header exists. getRequestHost was exported and covered by new tests.

Changes

Cohort / File(s) Summary
Request utils
src/utils/request.ts
Docstring for getRequestHost updated to state it returns an empty string when Host is missing. getRequestURL now directly parses x-forwarded-host, uses the first comma-separated host value for url.host, and clears url.port when the forwarded host has no port.
Public API export
src/index.ts
Added getRequestHost to public exports.
Tests
test/utils.test.ts
Added tests for getRequestHost: returns Host header, honors x-forwarded-host when enabled, and selects the first value from comma-separated hosts.
Docs
docs/2.utils/1.request.md
Documentation updated to state getRequestHost returns an empty string if no Host header is present (no default to "localhost").

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibble headers, light and quick,
I take the first when commas pick,
If Host is absent, I leave it bare,
I clear the port with tidy care,
Tests clap paws — a hop, a tick. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The PR title mentions 'align jsdocs with getRequestHost', but the actual changes show that getRequestHost was updated to return 'localhost' (not an empty string) to match documentation, and getRequestURL was refactored to use direct header parsing instead of delegating to getRequestHost—broader changes than just JSDoc alignment. Consider a more specific title like 'fix(request): update getRequestHost default and refactor getRequestURL' to accurately reflect both the function behavior change and the getRequestURL refactoring.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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
  • Commit unit tests in branch fix/get-request-host-default
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@pkg-pr-new

pkg-pr-new Bot commented Mar 14, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/h3@1316

commit: 55c12e4

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/utils/request.ts (1)

388-397: Intentional divergence from getRequestHost is correct.

The direct header parsing here (duplicating lines 331-332) is the right approach. Using getRequestHost would incorrectly apply the "localhost" fallback, potentially overwriting a valid host already present in the request URL. This ensures url.host is only modified when an actual x-forwarded-host header exists.

The port clearing logic on lines 394-396 correctly handles cases where the forwarded host doesn't include a port.

If desired, the shared parsing logic could be extracted to a private helper to reduce duplication:

♻️ Optional: Extract parsing helper
+function _parseFirstForwardedHost(header: string | null): string | undefined {
+  return (header || "").split(",").shift()?.trim() || undefined;
+}
+
 export function getRequestHost(event: HTTPEvent, opts: { xForwardedHost?: boolean } = {}): string {
   if (opts.xForwardedHost) {
-    const _header = event.req.headers.get("x-forwarded-host");
-    const xForwardedHost = (_header || "").split(",").shift()?.trim();
+    const xForwardedHost = _parseFirstForwardedHost(event.req.headers.get("x-forwarded-host"));
     if (xForwardedHost) {
       return xForwardedHost;
     }
   }
   return event.req.headers.get("host") || "localhost";
 }

This is minor and optional—the current duplication is just 4 lines and the intent is clear.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/request.ts` around lines 388 - 397, The direct parsing of the
x-forwarded-host header in this block is correct: ensure you only set url.host
when xForwardedHost (derived from event.req.headers.get("x-forwarded-host")) is
truthy and clear url.port when xForwardedHost does not include ":" (preserve the
existing url.host/url.port assignments), and keep the current behavior rather
than calling getRequestHost (which applies a "localhost" fallback). Optionally,
if you want to remove the small duplication, extract the
header-splitting/trimming logic into a private helper (e.g., parseForwardedHost)
and call it from both this block and getRequestHost, but this is not required.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/utils/request.ts`:
- Around line 388-397: The direct parsing of the x-forwarded-host header in this
block is correct: ensure you only set url.host when xForwardedHost (derived from
event.req.headers.get("x-forwarded-host")) is truthy and clear url.port when
xForwardedHost does not include ":" (preserve the existing url.host/url.port
assignments), and keep the current behavior rather than calling getRequestHost
(which applies a "localhost" fallback). Optionally, if you want to remove the
small duplication, extract the header-splitting/trimming logic into a private
helper (e.g., parseForwardedHost) and call it from both this block and
getRequestHost, but this is not required.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9e1d9f67-3412-4e35-876f-e1b96bac6cae

📥 Commits

Reviewing files that changed from the base of the PR and between c28356e and f204f92.

📒 Files selected for processing (2)
  • src/utils/request.ts
  • test/utils.test.ts

Comment thread src/utils/request.ts Outdated
}
}
return event.req.headers.get("host") || "";
return event.req.headers.get("host") || "localhost";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we should fix jsdocs instead, and do not fallback to localhost (it can lead to wrong asusmptions in code logic)

productdevbook and others added 2 commits March 14, 2026 23:25
- `getRequestHost` returned empty string when no host header was found,
  but the JSDoc documented "localhost" as the default. Now returns
  "localhost" to match the documented behavior.
- Updated `getRequestURL` to only override the URL host when an actual
  `x-forwarded-host` header is present, preventing the "localhost"
  fallback from incorrectly replacing a valid host in the request URL.
- Added tests for `getRequestHost` covering default, x-forwarded-host,
  and multi-value scenarios.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Per maintainer review: returning "localhost" as fallback can lead to
wrong assumptions in code logic. Keep the empty string return and
fix the JSDoc to match the actual behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@productdevbook
productdevbook force-pushed the fix/get-request-host-default branch from f204f92 to 1419122 Compare March 14, 2026 20:26
Comment thread src/utils/request.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@src/utils/request.ts`:
- Around line 388-395: The check that clears url.port uses
xForwardedHost.includes(":") which misclassifies bracketed IPv6 literals (e.g.
"[2001:db8::1]") as having a port; change the logic to detect an explicit port
instead (e.g. test for a trailing :port with a regex like /:\d+$/) and only keep
url.port when that test matches; update the block that reads xForwardedHost and
sets url.host/url.port (references: xForwardedHost, url.host, url.port) so
bracketed IPv6 hosts without a port correctly clear url.port.

In `@test/utils.test.ts`:
- Around line 88-93: The test currently only asserts truthiness of
getRequestHost result which misses regressions for the no-Host case; add an
explicit assertion that simulates a request with no Host header (e.g., await
t.fetch("/", { headers: {} }) or explicitly remove the Host header) and assert
the response equals the known fallback value used by getRequestHost (import or
reference the fallback constant/behavior from getRequestHost) so the test
verifies both the normal client-set Host and the explicit no-host fallback.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1cb80c88-aa2f-4e94-b846-cb20e0ba1e39

📥 Commits

Reviewing files that changed from the base of the PR and between f204f92 and 9224fdd.

📒 Files selected for processing (3)
  • docs/2.utils/1.request.md
  • src/utils/request.ts
  • test/utils.test.ts

Comment thread src/utils/request.ts Outdated
Comment thread test/utils.test.ts
Per maintainer review: revert the x-forwarded-host inline parsing
back to using getRequestHost(event, opts) as before.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@pi0 pi0 changed the title fix(request): align getRequestHost default with documentation refactor(request): align jsdocs with getRequestHost Mar 14, 2026
@pi0
pi0 merged commit 10bc7ce into main Mar 14, 2026
8 checks passed
@pi0
pi0 deleted the fix/get-request-host-default branch March 14, 2026 22:02
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.

2 participants