Skip to content

Commit

Permalink
Fix Astro.url.protocol when using the @astrojs/node SSR adapter wit…
Browse files Browse the repository at this point in the history
…h HTTPS (#5992)
  • Loading branch information
HiDeoo committed Jan 26, 2023
1 parent d47a907 commit 60b32d5
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .changeset/odd-rats-drop.md
@@ -0,0 +1,6 @@
---
'astro': patch
'@astrojs/node': patch
---

Fix `Astro.url.protocol` when using the @astrojs/node SSR adapter with HTTPS
7 changes: 6 additions & 1 deletion packages/astro/src/core/app/node.ts
Expand Up @@ -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';
Expand Down
4 changes: 3 additions & 1 deletion packages/integrations/node/src/standalone.ts
@@ -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';
Expand Down Expand Up @@ -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();
}
@@ -0,0 +1,9 @@
{
"name": "@test/url-protocol",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*",
"@astrojs/node": "workspace:*"
}
}
@@ -0,0 +1,11 @@
---
---

<html lang="en">
<head>
<title>url-protocol</title>
</head>
<body>
{Astro.url.protocol}
</body>
</html>
73 changes: 73 additions & 0 deletions packages/integrations/node/test/url-protocol.test.js
@@ -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 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 60b32d5

Please sign in to comment.