Skip to content

Commit

Permalink
fix: don't include port twice from x-forwarded-host and x-forwarded-p…
Browse files Browse the repository at this point in the history
…ort headers (withastro#10917)

* fix: don't include port twice from x-forwarded-host and x-forwarded-port headers

* add changeset

* add test for port both in forwarded host and forwarded port

* don't include port if undefined

* Update .changeset/forty-wolves-turn.md

Co-authored-by: Florian Lefebvre <[email protected]>

---------

Co-authored-by: Florian Lefebvre <[email protected]>
  • Loading branch information
jakobhellermann and florian-lefebvre authored May 3, 2024
1 parent 2dcbcdb commit 3412535
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/forty-wolves-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"astro": patch
---

Fixes a case where the local server would crash when the host also contained the port, eg. with `X-Forwarded-Host: hostname:8080` and `X-Forwarded-Port: 8080` headers
7 changes: 6 additions & 1 deletion packages/astro/src/core/app/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ export class NodeApp extends App {
const hostname =
req.headers['x-forwarded-host'] ?? req.headers.host ?? req.headers[':authority'];
const port = req.headers['x-forwarded-port'];
const url = `${protocol}://${hostname}${port ? `:${port}` : ''}${req.url}`;

const portInHostname =
typeof hostname === 'string' && typeof port === 'string' && hostname.endsWith(port);
const hostnamePort = portInHostname ? hostname : hostname + (port ? `:${port}` : '');

const url = `${protocol}://${hostnamePort}${req.url}`;
const options: RequestInit = {
method: req.method || 'GET',
headers: makeRequestHeaders(req),
Expand Down
20 changes: 20 additions & 0 deletions packages/integrations/node/test/url.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,24 @@ describe('URL', () => {

assert.equal($('body').text(), 'https://abc.xyz:444/');
});

it('accepts port in forwarded host and forwarded port', async () => {
const { handler } = await import('./fixtures/url/dist/server/entry.mjs');
let { req, res, text } = createRequestAndResponse({
headers: {
'X-Forwarded-Proto': 'https',
'X-Forwarded-Host': 'abc.xyz:444',
'X-Forwarded-Port': '444',
},
url: '/',
});

handler(req, res);
req.send();

const html = await text();
const $ = cheerio.load(html);

assert.equal($('body').text(), 'https://abc.xyz:444/');
});
});

0 comments on commit 3412535

Please sign in to comment.