Skip to content

[vite-plugin] Preserve the port on requests that arrive over HTTP/2 - #15237

Open
amitvijapur wants to merge 3 commits into
cloudflare:mainfrom
amitvijapur:fix/vite-plugin-http2-authority-port
Open

[vite-plugin] Preserve the port on requests that arrive over HTTP/2#15237
amitvijapur wants to merge 3 commits into
cloudflare:mainfrom
amitvijapur:fix/vite-plugin-http2-authority-port

Conversation

@amitvijapur

@amitvijapur amitvijapur commented Aug 17, 2026

Copy link
Copy Markdown

Closes #14931

Serving the Vite dev server over HTTPS could drop the port from request.url
and X-Forwarded-Host, so a Worker saw https://localhost where the browser
had asked for https://localhost:5173. Auth libraries that rebuild redirect
URLs from the request — Clerk's handshake in the original report — then
redirected to the wrong origin and could loop. Plain HTTP was unaffected,
which is what made it look HTTPS-specific.

Cause

Browsers usually negotiate HTTP/2 over HTTPS, and HTTP/2 carries the authority
in the :authority pseudo-header rather than in Host. createHeaders drops
pseudo-headers when building the Fetch Request, so createRequestForIncomingMessage
found no Host and fell back to a bare "localhost", losing the port:

const host = options?.host ?? headers.get("Host") ?? "localhost";

toMiniflareRequest was gated on the same missing header, so X-Forwarded-Host
was not set at all on those requests.

Change

  • New exported helper getRequestAuthority, which reads :authority from the
    Node request when Host is absent. It mirrors the shape of the neighbouring
    getForwardedProto helper added for the X-Forwarded-Proto work.
  • X-Forwarded-Host falls back to the resolved request URL, which now carries
    the correct authority.

Host is still preferred whenever it is present, so HTTP/1.1 requests are
unchanged. This is the port/authority half of the host and protocol forwarding
addressed in #8706 and #13920.

Verification

  • vitest run src/__tests__ — 20 files, 203 tests passing
  • tsc --build — clean
  • oxfmt --check and oxlint --deny-warnings — clean

7 new unit tests sit alongside the existing getForwardedProto block, covering
Host present, the :authority fallback, Host preferred when both are set, a
non-default port surviving into the reconstructed origin, array header values,
and empty or whitespace-only values.

I could not reproduce the original Clerk handshake loop end to end, since that
needs an HTTPS dev server with a Clerk app, so the tests target the host
resolution directly rather than the redirect behaviour.


  • Tests included/updated
  • Documentation not necessary because: this restores the documented behaviour of the dev server rather than changing any public API or configuration surface — no user-facing option is added or altered.

Over HTTPS the dev server could lose the port from `request.url` and
`X-Forwarded-Host`, so a Worker saw `https://localhost` where the browser had
asked for `https://localhost:5173`. Auth libraries that rebuild redirect URLs
from the request then redirected to the wrong origin and could loop. Plain
HTTP was unaffected.

Browsers usually negotiate HTTP/2 over HTTPS, and HTTP/2 carries the authority
in the `:authority` pseudo-header rather than in `Host`. `createHeaders` drops
pseudo-headers when building the Fetch `Request`, so no `Host` was found and
the host fell back to a bare `localhost`. `toMiniflareRequest` was gated on the
same missing header, so `X-Forwarded-Host` was not set at all.

Read the authority from `:authority` when `Host` is absent, and fall back to
the resolved request URL when forwarding the host. `Host` is still preferred
whenever present, so HTTP/1.1 requests are unchanged.

This completes the host and protocol forwarding work in cloudflare#8706, cloudflare#13920.

Closes cloudflare#14931
@changeset-bot

changeset-bot Bot commented Aug 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e70475b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@cloudflare/vite-plugin Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-project-automation github-project-automation Bot moved this to Untriaged in workers-sdk Aug 17, 2026
@workers-devprod
workers-devprod requested review from a team and emily-shen and removed request for a team August 17, 2026 10:50
@workers-devprod

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/vite-plugin-http2-authority-port.md: [@cloudflare/wrangler]
  • packages/vite-plugin-cloudflare/src/tests/utils.spec.ts: [@cloudflare/wrangler]
  • packages/vite-plugin-cloudflare/src/utils.ts: [@cloudflare/wrangler]

devin-ai-integration[bot]

This comment was marked as resolved.

@pkg-pr-new

pkg-pr-new Bot commented Aug 17, 2026

Copy link
Copy Markdown
@cloudflare/autoconfig

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/autoconfig@15237

@cloudflare/build-output-utils

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/build-output-utils@15237

@cloudflare/codemods

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/codemods@15237

@cloudflare/config

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/config@15237

create-cloudflare

npm i https://pkg.pr.new/cloudflare/workers-sdk/create-cloudflare@15237

@cloudflare/deploy-helpers

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/deploy-helpers@15237

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/kv-asset-handler@15237

miniflare

npm i https://pkg.pr.new/cloudflare/workers-sdk/miniflare@15237

@cloudflare/pages-functions

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/pages-functions@15237

@cloudflare/pages-shared

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/pages-shared@15237

@cloudflare/unenv-preset

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/unenv-preset@15237

@cloudflare/vite-plugin

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/vite-plugin@15237

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/vitest-pool-workers@15237

@cloudflare/workers-auth

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/workers-auth@15237

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/workers-editor-shared@15237

@cloudflare/workers-utils

npm i https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/workers-utils@15237

wrangler

npm i https://pkg.pr.new/cloudflare/workers-sdk/wrangler@15237

commit: e70475b

REVIEW.md requires changesets to target users rather than maintainers, so the
request-conversion mechanics are dropped in favour of the effect a user sees.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

@cloudflare/vite-plugin: HTTPS/HTTP2 Host/:authority handling drops non-default port from request.url (breaks Clerk handshake redirects)

2 participants