Skip to content

Commit

Permalink
feat(node): add PORT_HEADER env var for reverse proxies with non-st…
Browse files Browse the repository at this point in the history
…andard ports (#11249)

* 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

* fixup! feat: add `PORT_HEADER` env var for reverse proxies with non-standard ports

Remove link to AWS docs.
  • Loading branch information
aloisklink authored Jan 9, 2024
1 parent 9556aba commit e2504f1
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/thick-pears-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-node': minor
---

feat: add `PORT_HEADER` env var for reverse proxies with non-standard ports
4 changes: 3 additions & 1 deletion documentation/docs/25-build-and-deploy/40-adapter-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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):

Expand Down
1 change: 1 addition & 0 deletions packages/adapter-node/src/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const expected = new Set([
'ADDRESS_HEADER',
'PROTOCOL_HEADER',
'HOST_HEADER',
'PORT_HEADER',
'BODY_SIZE_LIMIT'
]);

Expand Down
8 changes: 7 additions & 1 deletion packages/adapter-node/src/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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(
Expand Down

0 comments on commit e2504f1

Please sign in to comment.