Fix Astro.url.protocol
when using the @astrojs/node SSR adapter with HTTPS (#5992)
This commit is contained in:
parent
d47a9075bf
commit
60b32d5856
7 changed files with 116 additions and 2 deletions
6
.changeset/odd-rats-drop.md
Normal file
6
.changeset/odd-rats-drop.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
'astro': patch
|
||||
'@astrojs/node': patch
|
||||
---
|
||||
|
||||
Fix `Astro.url.protocol` when using the @astrojs/node SSR adapter with HTTPS
|
|
@ -3,13 +3,18 @@ import type { SerializedSSRManifest, SSRManifest } from './types';
|
|||
|
||||
import * as fs from 'fs';
|
||||
import { IncomingMessage } from 'http';
|
||||
import { TLSSocket } from 'tls';
|
||||
import { deserializeManifest } from './common.js';
|
||||
import { App, MatchOptions } from './index.js';
|
||||
|
||||
const clientAddressSymbol = Symbol.for('astro.clientAddress');
|
||||
|
||||
function createRequestFromNodeRequest(req: IncomingMessage, body?: Uint8Array): Request {
|
||||
let url = `http://${req.headers.host}${req.url}`;
|
||||
const protocol =
|
||||
req.socket instanceof TLSSocket || req.headers['x-forwarded-proto'] === 'https'
|
||||
? 'https'
|
||||
: 'http';
|
||||
let url = `${protocol}://${req.headers.host}${req.url}`;
|
||||
let rawHeaders = req.headers as Record<string, any>;
|
||||
const entries = Object.entries(rawHeaders);
|
||||
const method = req.method || 'GET';
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import type { NodeApp } from 'astro/app/node';
|
||||
import https from 'https';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { createServer } from './http-server.js';
|
||||
|
@ -53,8 +54,9 @@ export default function startServer(app: NodeApp, options: Options) {
|
|||
handler
|
||||
);
|
||||
|
||||
const protocol = server.server instanceof https.Server ? 'https' : 'http';
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Server listening on http://${host}:${port}`);
|
||||
console.log(`Server listening on ${protocol}://${host}:${port}`);
|
||||
|
||||
return server.closed();
|
||||
}
|
||||
|
|
9
packages/integrations/node/test/fixtures/url-protocol/package.json
vendored
Normal file
9
packages/integrations/node/test/fixtures/url-protocol/package.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/url-protocol",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/node": "workspace:*"
|
||||
}
|
||||
}
|
11
packages/integrations/node/test/fixtures/url-protocol/src/pages/index.astro
vendored
Normal file
11
packages/integrations/node/test/fixtures/url-protocol/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>url-protocol</title>
|
||||
</head>
|
||||
<body>
|
||||
{Astro.url.protocol}
|
||||
</body>
|
||||
</html>
|
73
packages/integrations/node/test/url-protocol.test.js
Normal file
73
packages/integrations/node/test/url-protocol.test.js
Normal file
|
@ -0,0 +1,73 @@
|
|||
import { TLSSocket } from 'tls';
|
||||
import nodejs from '../dist/index.js';
|
||||
import { loadFixture, createRequestAndResponse } from './test-utils.js';
|
||||
import { expect } from 'chai';
|
||||
|
||||
describe('URL protocol', () => {
|
||||
/** @type {import('./test-utils').Fixture} */
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/url-protocol/',
|
||||
output: 'server',
|
||||
adapter: nodejs({ mode: 'standalone' }),
|
||||
});
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('return http when non-secure', async () => {
|
||||
const { handler } = await import('./fixtures/url-protocol/dist/server/entry.mjs');
|
||||
let { req, res, text } = createRequestAndResponse({
|
||||
url: '/',
|
||||
});
|
||||
|
||||
handler(req, res);
|
||||
req.send();
|
||||
|
||||
const html = await text();
|
||||
expect(html).to.include('http:');
|
||||
});
|
||||
|
||||
it('return https when secure', async () => {
|
||||
const { handler } = await import('./fixtures/url-protocol/dist/server/entry.mjs');
|
||||
let { req, res, text } = createRequestAndResponse({
|
||||
socket: new TLSSocket(),
|
||||
url: '/',
|
||||
});
|
||||
|
||||
handler(req, res);
|
||||
req.send();
|
||||
|
||||
const html = await text();
|
||||
expect(html).to.include('https:');
|
||||
});
|
||||
|
||||
it('return http when the X-Forwarded-Proto header is set to http', async () => {
|
||||
const { handler } = await import('./fixtures/url-protocol/dist/server/entry.mjs');
|
||||
let { req, res, text } = createRequestAndResponse({
|
||||
headers: { 'X-Forwarded-Proto': 'http' },
|
||||
url: '/',
|
||||
});
|
||||
|
||||
handler(req, res);
|
||||
req.send();
|
||||
|
||||
const html = await text();
|
||||
expect(html).to.include('http:');
|
||||
});
|
||||
|
||||
it('return https when the X-Forwarded-Proto header is set to https', async () => {
|
||||
const { handler } = await import('./fixtures/url-protocol/dist/server/entry.mjs');
|
||||
let { req, res, text } = createRequestAndResponse({
|
||||
headers: { 'X-Forwarded-Proto': 'https' },
|
||||
url: '/',
|
||||
});
|
||||
|
||||
handler(req, res);
|
||||
req.send();
|
||||
|
||||
const html = await text();
|
||||
expect(html).to.include('https:');
|
||||
});
|
||||
});
|
|
@ -3109,6 +3109,14 @@ importers:
|
|||
'@astrojs/node': link:../../..
|
||||
astro: link:../../../../../astro
|
||||
|
||||
packages/integrations/node/test/fixtures/url-protocol:
|
||||
specifiers:
|
||||
'@astrojs/node': workspace:*
|
||||
astro: workspace:*
|
||||
dependencies:
|
||||
'@astrojs/node': link:../../..
|
||||
astro: link:../../../../../astro
|
||||
|
||||
packages/integrations/node/test/fixtures/well-known-locations:
|
||||
specifiers:
|
||||
'@astrojs/node': workspace:*
|
||||
|
|
Loading…
Reference in a new issue