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 * as fs from 'fs';
|
||||||
import { IncomingMessage } from 'http';
|
import { IncomingMessage } from 'http';
|
||||||
|
import { TLSSocket } from 'tls';
|
||||||
import { deserializeManifest } from './common.js';
|
import { deserializeManifest } from './common.js';
|
||||||
import { App, MatchOptions } from './index.js';
|
import { App, MatchOptions } from './index.js';
|
||||||
|
|
||||||
const clientAddressSymbol = Symbol.for('astro.clientAddress');
|
const clientAddressSymbol = Symbol.for('astro.clientAddress');
|
||||||
|
|
||||||
function createRequestFromNodeRequest(req: IncomingMessage, body?: Uint8Array): Request {
|
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>;
|
let rawHeaders = req.headers as Record<string, any>;
|
||||||
const entries = Object.entries(rawHeaders);
|
const entries = Object.entries(rawHeaders);
|
||||||
const method = req.method || 'GET';
|
const method = req.method || 'GET';
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import type { NodeApp } from 'astro/app/node';
|
import type { NodeApp } from 'astro/app/node';
|
||||||
|
import https from 'https';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { createServer } from './http-server.js';
|
import { createServer } from './http-server.js';
|
||||||
|
@ -53,8 +54,9 @@ export default function startServer(app: NodeApp, options: Options) {
|
||||||
handler
|
handler
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const protocol = server.server instanceof https.Server ? 'https' : 'http';
|
||||||
// eslint-disable-next-line no-console
|
// 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();
|
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:');
|
||||||
|
});
|
||||||
|
});
|
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
|
@ -3109,6 +3109,14 @@ importers:
|
||||||
'@astrojs/node': link:../../..
|
'@astrojs/node': link:../../..
|
||||||
astro: link:../../../../../astro
|
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:
|
packages/integrations/node/test/fixtures/well-known-locations:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@astrojs/node': workspace:*
|
'@astrojs/node': workspace:*
|
||||||
|
|
Loading…
Add table
Reference in a new issue