diff --git a/.changeset/thick-pears-own.md b/.changeset/thick-pears-own.md new file mode 100644 index 000000000000..b78d4caf1aa1 --- /dev/null +++ b/.changeset/thick-pears-own.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-node': minor +--- + +feat: add `PORT_HEADER` env var for reverse proxies with non-standard ports diff --git a/documentation/docs/25-build-and-deploy/40-adapter-node.md b/documentation/docs/25-build-and-deploy/40-adapter-node.md index a4765d6ffe83..d6801ffd251f 100644 --- a/documentation/docs/25-build-and-deploy/40-adapter-node.md +++ b/documentation/docs/25-build-and-deploy/40-adapter-node.md @@ -63,7 +63,7 @@ Alternatively, the server can be configured to accept connections on a specified SOCKET_PATH=/tmp/socket node build ``` -### `ORIGIN`, `PROTOCOL_HEADER` and `HOST_HEADER` +### `ORIGIN`, `PROTOCOL_HEADER`, `HOST_HEADER`, and `PORT_HEADER` HTTP doesn't give SvelteKit a reliable way to know the URL that is currently being requested. The simplest way to tell SvelteKit where the app is being served is to set the `ORIGIN` environment variable: @@ -81,6 +81,8 @@ PROTOCOL_HEADER=x-forwarded-proto HOST_HEADER=x-forwarded-host node build ``` > [`x-forwarded-proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto) and [`x-forwarded-host`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host) are de facto standard headers that forward the original protocol and host if you're using a reverse proxy (think load balancers and CDNs). You should only set these variables if your server is behind a trusted reverse proxy; otherwise, it'd be possible for clients to spoof these headers. +> +> If you're hosting your proxy on a non-standard port and your reverse proxy supports `x-forwarded-port`, you can also set `PORT_HEADER=x-forwarded-port`. If `adapter-node` can't correctly determine the URL of your deployment, you may experience this error when using [form actions](form-actions): diff --git a/packages/adapter-node/src/env.js b/packages/adapter-node/src/env.js index 841bddf2c237..ce754a36a8e9 100644 --- a/packages/adapter-node/src/env.js +++ b/packages/adapter-node/src/env.js @@ -9,6 +9,7 @@ const expected = new Set([ 'ADDRESS_HEADER', 'PROTOCOL_HEADER', 'HOST_HEADER', + 'PORT_HEADER', 'BODY_SIZE_LIMIT' ]); diff --git a/packages/adapter-node/src/handler.js b/packages/adapter-node/src/handler.js index 09bf98f63a11..dcb478f5e13a 100644 --- a/packages/adapter-node/src/handler.js +++ b/packages/adapter-node/src/handler.js @@ -18,6 +18,7 @@ const xff_depth = parseInt(env('XFF_DEPTH', '1')); const address_header = env('ADDRESS_HEADER', '').toLowerCase(); const protocol_header = env('PROTOCOL_HEADER', '').toLowerCase(); const host_header = env('HOST_HEADER', 'host').toLowerCase(); +const port_header = env('PORT_HEADER', '').toLowerCase(); const body_size_limit = parseInt(env('BODY_SIZE_LIMIT', '524288')); const dir = path.dirname(fileURLToPath(import.meta.url)); @@ -158,7 +159,12 @@ function sequence(handlers) { function get_origin(headers) { const protocol = (protocol_header && headers[protocol_header]) || 'https'; const host = headers[host_header]; - return `${protocol}://${host}`; + const port = port_header && headers[port_header]; + if (port) { + return `${protocol}://${host}:${port}`; + } else { + return `${protocol}://${host}`; + } } export const handler = sequence(