From 1538773c2fa98a1cf61d0d3fd8a0713a7379171a Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Sat, 9 Dec 2023 23:10:33 +0000 Subject: [PATCH 1/2] feat: add `PORT_HEADER` env var for reverse proxies with non-standard ports Add support for the `PORT_HEADER` environment variable, that can be used to read the original port of a request from a reverse proxy, which is needed if the reverse proxy is hosted on a non-standard port (e.g. not port 80 for http nor port 443 for https). This port is normally added as part of a [`x-forwarded-port`][1], which is used by many reverse proxies, although it's not as popular as the more common [`x-forwarded-proto`][2] and [`x-forwarded-host`][3] headers. [1]: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html#x-forwarded-port [2]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto [3]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host --- .changeset/thick-pears-own.md | 5 +++++ documentation/docs/25-build-and-deploy/40-adapter-node.md | 4 +++- packages/adapter-node/src/env.js | 1 + packages/adapter-node/src/handler.js | 8 +++++++- 4 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 .changeset/thick-pears-own.md 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 f3c04bfa85c3..2e75032b3a81 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`](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html#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 bae1854bdd7e..985923208ddd 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)); @@ -167,7 +168,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( From 3a64fab733cea19d140147d571ba81f7eaa3a675 Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Sun, 10 Dec 2023 01:06:58 +0000 Subject: [PATCH 2/2] fixup! feat: add `PORT_HEADER` env var for reverse proxies with non-standard ports Remove link to AWS docs. --- documentation/docs/25-build-and-deploy/40-adapter-node.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2e75032b3a81..15b2c808958e 100644 --- a/documentation/docs/25-build-and-deploy/40-adapter-node.md +++ b/documentation/docs/25-build-and-deploy/40-adapter-node.md @@ -82,7 +82,7 @@ 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`](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html#x-forwarded-port), you can also set `PORT_HEADER=x-forwarded-port`. +> 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):