mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
fix: support HTTP/2 in astro dev
(#11284)
* wip * chore: add tests * Add changeset * Add comments
This commit is contained in:
parent
cb4d07819f
commit
f4b029b082
13 changed files with 194 additions and 12 deletions
7
.changeset/six-fans-kiss.md
Normal file
7
.changeset/six-fans-kiss.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes an issue that would break `Astro.request.url` and `Astro.request.headers` in `astro dev` if HTTP/2 was enabled.
|
||||
|
||||
HTTP/2 is now enabled by default in `astro dev` if `https` is configured in the Vite config.
|
|
@ -229,6 +229,7 @@
|
|||
"rollup": "^4.18.0",
|
||||
"sass": "^1.77.5",
|
||||
"srcset-parse": "^1.1.0",
|
||||
"undici": "^6.19.2",
|
||||
"unified": "^11.0.4"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
@ -173,10 +173,6 @@ export async function createVite(
|
|||
process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'production'
|
||||
? false
|
||||
: undefined, // disable HMR for test
|
||||
// handle Vite URLs
|
||||
proxy: {
|
||||
// add proxies here
|
||||
},
|
||||
watch: {
|
||||
// Prevent watching during the build to speed it up
|
||||
ignored: mode === 'build' ? ['**'] : undefined,
|
||||
|
|
|
@ -50,7 +50,13 @@ export function createRequest({
|
|||
? undefined
|
||||
: headers instanceof Headers
|
||||
? headers
|
||||
: new Headers(Object.entries(headers as Record<string, any>));
|
||||
: new Headers(
|
||||
// Filter out HTTP/2 pseudo-headers. These are internally-generated headers added to all HTTP/2 requests with trusted metadata about the request.
|
||||
// Examples include `:method`, `:scheme`, `:authority`, and `:path`.
|
||||
// They are always prefixed with a colon to distinguish them from other headers, and it is an error to add the to a Headers object manually.
|
||||
// See https://httpwg.org/specs/rfc7540.html#HttpRequest
|
||||
Object.entries(headers as Record<string, any>).filter(([name]) => !name.startsWith(':'))
|
||||
);
|
||||
|
||||
if (typeof url === 'string') url = new URL(url);
|
||||
|
||||
|
|
|
@ -25,7 +25,9 @@ export async function handleRequest({
|
|||
incomingResponse,
|
||||
}: HandleRequest) {
|
||||
const { config, loader } = pipeline;
|
||||
const origin = `${loader.isHttps() ? 'https' : 'http'}://${incomingRequest.headers.host}`;
|
||||
const origin = `${loader.isHttps() ? 'https' : 'http'}://${
|
||||
incomingRequest.headers[':authority'] ?? incomingRequest.headers.host
|
||||
}`;
|
||||
|
||||
const url = new URL(origin + incomingRequest.url);
|
||||
let pathname: string;
|
||||
|
|
37
packages/astro/test/astro-dev-http2.test.js
Normal file
37
packages/astro/test/astro-dev-http2.test.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
import assert from 'node:assert/strict';
|
||||
import { after, before, describe, it } from 'node:test';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
describe('Astro HTTP/2 support', () => {
|
||||
let fixture;
|
||||
let devServer;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/astro-dev-http2/',
|
||||
});
|
||||
devServer = await fixture.startDevServer();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
describe('dev', () => {
|
||||
it('returns custom headers for valid URLs', async () => {
|
||||
const result = await fixture.fetch('/');
|
||||
assert.equal(result.status, 200);
|
||||
const html = await result.text();
|
||||
console.log(result.headers);
|
||||
const $ = cheerio.load(html);
|
||||
const urlString = $('main').text();
|
||||
assert.equal(Boolean(urlString), true);
|
||||
const url = new URL(urlString);
|
||||
// Not asserting host because of all the ways localhost can be represented
|
||||
assert.equal(url.protocol, 'https:');
|
||||
assert.equal(url.port, '4321');
|
||||
assert.equal($('p').text(), '2.0');
|
||||
});
|
||||
});
|
||||
});
|
24
packages/astro/test/fixtures/astro-dev-http2/.cert/cert.pem
vendored
Normal file
24
packages/astro/test/fixtures/astro-dev-http2/.cert/cert.pem
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIEHDCCAoSgAwIBAgIRAIWPzjvpgZGzQqe1TFcdGmAwDQYJKoZIhvcNAQELBQAw
|
||||
ZTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMR0wGwYDVQQLDBRhbGV4
|
||||
QERFU0tUT1AtMFM5OFUzMDEkMCIGA1UEAwwbbWtjZXJ0IGFsZXhAREVTS1RPUC0w
|
||||
Uzk4VTMwMB4XDTI0MDIyNjAwNDkyOVoXDTI2MDUyNTIzNDkyOVowSDEnMCUGA1UE
|
||||
ChMebWtjZXJ0IGRldmVsb3BtZW50IGNlcnRpZmljYXRlMR0wGwYDVQQLDBRhbGV4
|
||||
QERFU0tUT1AtMFM5OFUzMDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
AMRj8/YGXRRWkpIxdaWbL+v2RZoI7iGOyJliC2Iudag5/irpiBAFgZAqpjSb1i1E
|
||||
OKkXRQlCx21jQWe/jEFGqEPIqjeLPrXHATKU+6prOH2FV2qF7PDd0gi1gkR0cxX7
|
||||
dUA9kUeqm1HHkogUuhRjg5uCklyCraN49yz6QU6U7uiTo4ZM9mjfig0EfG2W1DBp
|
||||
G0bKkEhgkSKw3v1mvGVYN5yAv6unLjDVJGwLKqTTpDpsahG47h+ZPHj7wjSOQiDB
|
||||
tXR+HNLJdSe59+GQ8D5/M7hRG6rZ+8GzaNjQWRl8BK6Ls0k1qtMgcEFeNDLEWTj1
|
||||
16yNmd4/IX4irMmSA+F7PgUCAwEAAaNkMGIwDgYDVR0PAQH/BAQDAgWgMBMGA1Ud
|
||||
JQQMMAoGCCsGAQUFBwMBMB8GA1UdIwQYMBaAFE+Vk1SZFKjFDIsieTVT/860OBs6
|
||||
MBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAYEA
|
||||
szcc7pdwdYu3uIN8f8LHFABDhxiPDLMqmyEJXym5z8c44Mtl0mfGnKs0uIzl/XtL
|
||||
F1aLH8yHubZ1LJkIczAypcryekmk+VzTsNdv1aKelhsZ9QJUxg/NsrMXe5DZ9Eeu
|
||||
KxlJBJKo+oRpDsxRYo1l5FvIljcVvOUTaKR3UtY6FU2xdDMNMtoJDbaJCPAg143H
|
||||
ZnSa7xEv7fGDTcn9oKFc1fc1BnCy4qCHkxF8pIeXbXEZ/q1fqNNtp87/PigPT7YO
|
||||
ppcYvEsj4Y+6yuDfIrWAZNcbtiOfFUyPXy1KN+/VxZhcZ/MuAbl4EiESDFbE5j8U
|
||||
whIHlRXUY6B09PL9NVNGyjNDH3NMQkSKVFA2KVeaFeDIROjPeMkrKY56lWVpEiru
|
||||
HVLuFVpM27uJEKgSNeAYttfOEvsvr20Otmt29Uu59qfX+w0crQUEElcUJB4DgRH+
|
||||
NVoYZLYMm88B5aVUsmwkkrJJrAJ+M6UnzIhdN2alJxXojW38jDWzn+dWbc0a2hIB
|
||||
-----END CERTIFICATE-----
|
28
packages/astro/test/fixtures/astro-dev-http2/.cert/key.pem
vendored
Normal file
28
packages/astro/test/fixtures/astro-dev-http2/.cert/key.pem
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEY/P2Bl0UVpKS
|
||||
MXWlmy/r9kWaCO4hjsiZYgtiLnWoOf4q6YgQBYGQKqY0m9YtRDipF0UJQsdtY0Fn
|
||||
v4xBRqhDyKo3iz61xwEylPuqazh9hVdqhezw3dIItYJEdHMV+3VAPZFHqptRx5KI
|
||||
FLoUY4ObgpJcgq2jePcs+kFOlO7ok6OGTPZo34oNBHxtltQwaRtGypBIYJEisN79
|
||||
ZrxlWDecgL+rpy4w1SRsCyqk06Q6bGoRuO4fmTx4+8I0jkIgwbV0fhzSyXUnuffh
|
||||
kPA+fzO4URuq2fvBs2jY0FkZfASui7NJNarTIHBBXjQyxFk49desjZnePyF+IqzJ
|
||||
kgPhez4FAgMBAAECggEBAL+70d89ATys9LYT4YcIBnY5XmRvGYXbr47IANMfBrFx
|
||||
xOpCSxtRNNf6O4AbMLPK6gJzfGv5LVhnUeCnSpgkEnzy+PP3VwcDPfETMMyFl4Y8
|
||||
W0bdb6EM/1SPWJnaks1ATY2lTiQItVDXJgEDM1Raf4+gn6H/1uRFYhQgUwgUMVcP
|
||||
rb/6qk+vFJXGuyx1R1DoIoqz+8iBfcsddUplx8ulJv74/Lgn5B/5sZ6I6cnW8lva
|
||||
FskuY1DL2RUywuV2J2fnFGNuGPPvc5elE0ORYLjlUGDMHQq+a9UxXsfCC4gHoks1
|
||||
P4vYZjzOVGRA3o+F8khuZLeCebMsKnoyzmkeRGejlzUCgYEA8d+TtwU3qlFUl3sa
|
||||
TGJm+tD5sgLaZHDssMhkkTtTVzYIllFSyvT8UI7/9ZwYinq0JOnGN0Cb7TsH4AGQ
|
||||
jQzHfiudibvODK4HL3rVkiOwj+kdjH+oTMlCTGsCj9uZhEajzKpXgpSlYkpqhDR2
|
||||
zCdMdFXCE+SpJCJaTI+jcbup6P8CgYEAz9xUBQIk8CdySkgIB0gmpIgtvS1EwYod
|
||||
YvYu+coQ1lEtALetDdbx5VfasWd1A18sIFlkfZZMKr5+1QXVuKOFhx2n49XIev/6
|
||||
t+Hgx8aToIpB0tz/3CTea5HGK8FvX6t5QKDL6XqDrRGO1FVdMSWl9WLfmpTynJdj
|
||||
sNHr7JFwNPsCgYAz5OE/ekoYK7z3hzz8OHyZwa5hCAWtWSEfSM9y7YSTCI/NGIOn
|
||||
8eoUqqm2G5iUVYFDDjkt75nEy06EPDG0YZKHunnhbD7oL4pxIGykHy4poj1pwJXu
|
||||
a5vi4264SMhmPfW02rNN2/Cj5w11cgAvCxt3NlMei4fSreAr3wGVTEtHJwKBgEBw
|
||||
QIfQ81yUDgVjMUH4pyoooW1dRExvoc6VHVkIwJGAVuA7EOYSdakwxDZtKURjU82v
|
||||
iMy6NGCn76/ggDIeV33cvriOBPnEs5gf6Uxljkydr+xL4PIBaAaXCYV1ES7qfMuB
|
||||
TdXSylFz+QBwelSLJFjfTwygElpjQF+HpIkRSWTTAoGBAJIqeQ4edg4weut00+32
|
||||
A8rQEpiz5SByPYNUPCI5BReKd+/Dw2QdXnfJNVg7/NFfuUdvPVkmptsisYdfWhlp
|
||||
y+KFAwdbgDUU+ruPuv5fHU4sA85Uuxazr/YXZIB6wmsQKt8cNezqNhjY6UovTOdZ
|
||||
7qnkPUO8VGcnrRZiav8WIevg
|
||||
-----END PRIVATE KEY-----
|
26
packages/astro/test/fixtures/astro-dev-http2/astro.config.ts
vendored
Normal file
26
packages/astro/test/fixtures/astro-dev-http2/astro.config.ts
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { defineConfig } from "astro/config";
|
||||
import { readFileSync } from "fs";
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
output: "hybrid",
|
||||
vite: {
|
||||
server: {
|
||||
https: {
|
||||
key: readFileSync(new URL(".cert/key.pem", import.meta.url)),
|
||||
cert: readFileSync(new URL(".cert/cert.pem", import.meta.url)),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
{
|
||||
name: 'http-version-plugin',
|
||||
// This plugin allows tests to track the version of HTTP used in the request
|
||||
configureServer: (server) => {
|
||||
server.middlewares.use((req, res, next) => {
|
||||
req.headers['x-http-version'] = req.httpVersion;
|
||||
next();
|
||||
});
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
8
packages/astro/test/fixtures/astro-dev-http2/package.json
vendored
Normal file
8
packages/astro/test/fixtures/astro-dev-http2/package.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "@test/astro-dev-http2",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*"
|
||||
}
|
||||
}
|
17
packages/astro/test/fixtures/astro-dev-http2/src/pages/index.astro
vendored
Normal file
17
packages/astro/test/fixtures/astro-dev-http2/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
const url = Astro.request.url
|
||||
const httpVersion = Astro.request.headers.get('x-http-version')
|
||||
export const prerender = false
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
</head>
|
||||
<body>
|
||||
<main>{url}</main>
|
||||
<p>{httpVersion}</p>
|
||||
</body>
|
||||
</html>
|
|
@ -5,6 +5,7 @@ import { fileURLToPath } from 'node:url';
|
|||
import { execa } from 'execa';
|
||||
import fastGlob from 'fast-glob';
|
||||
import stripAnsi from 'strip-ansi';
|
||||
import { Agent } from 'undici';
|
||||
import { check } from '../dist/cli/check/index.js';
|
||||
import build from '../dist/core/build/index.js';
|
||||
import { RESOLVED_SPLIT_MODULE_ID } from '../dist/core/build/plugins/plugin-ssr.js';
|
||||
|
@ -122,8 +123,13 @@ export async function loadFixture(inlineConfig) {
|
|||
// Load the config.
|
||||
const { astroConfig: config } = await resolveConfig(inlineConfig, 'dev');
|
||||
|
||||
const protocol = config.vite?.server?.https ? 'https' : 'http';
|
||||
|
||||
const resolveUrl = (url) =>
|
||||
`http://${config.server.host || 'localhost'}:${config.server.port}${url.replace(/^\/?/, '/')}`;
|
||||
`${protocol}://${config.server.host || 'localhost'}:${config.server.port}${url.replace(
|
||||
/^\/?/,
|
||||
'/'
|
||||
)}`;
|
||||
|
||||
// A map of files that have been edited.
|
||||
let fileEdits = new Map();
|
||||
|
@ -171,6 +177,21 @@ export async function loadFixture(inlineConfig) {
|
|||
config,
|
||||
resolveUrl,
|
||||
fetch: async (url, init) => {
|
||||
if (config.vite?.server?.https) {
|
||||
init = {
|
||||
// Use a custom fetch dispatcher. This is an undici option that allows
|
||||
// us to customize the fetch behavior. We use it here to allow h2.
|
||||
dispatcher: new Agent({
|
||||
connect: {
|
||||
// We disable cert validation because we're using self-signed certs
|
||||
rejectUnauthorized: false,
|
||||
},
|
||||
// Enable HTTP/2 support
|
||||
allowH2: true,
|
||||
}),
|
||||
...init,
|
||||
};
|
||||
}
|
||||
const resolvedUrl = resolveUrl(url);
|
||||
try {
|
||||
return await fetch(resolvedUrl, init);
|
||||
|
|
|
@ -836,6 +836,9 @@ importers:
|
|||
srcset-parse:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0
|
||||
undici:
|
||||
specifier: ^6.19.2
|
||||
version: 6.19.2
|
||||
unified:
|
||||
specifier: ^11.0.4
|
||||
version: 11.0.4
|
||||
|
@ -2073,6 +2076,12 @@ importers:
|
|||
specifier: workspace:*
|
||||
version: link:../../..
|
||||
|
||||
packages/astro/test/fixtures/astro-dev-http2:
|
||||
dependencies:
|
||||
astro:
|
||||
specifier: workspace:*
|
||||
version: link:../../..
|
||||
|
||||
packages/astro/test/fixtures/astro-directives:
|
||||
dependencies:
|
||||
astro:
|
||||
|
@ -11531,9 +11540,9 @@ packages:
|
|||
undici-types@5.26.5:
|
||||
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
|
||||
|
||||
undici@6.13.0:
|
||||
resolution: {integrity: sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw==}
|
||||
engines: {node: '>=18.0'}
|
||||
undici@6.19.2:
|
||||
resolution: {integrity: sha512-JfjKqIauur3Q6biAtHJ564e3bWa8VvT+7cSiOJHFbX4Erv6CLGDpg8z+Fmg/1OI/47RA+GI2QZaF48SSaLvyBA==}
|
||||
engines: {node: '>=18.17'}
|
||||
|
||||
unicorn-magic@0.1.0:
|
||||
resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
|
||||
|
@ -13332,7 +13341,7 @@ snapshots:
|
|||
'@octokit/plugin-paginate-rest': 11.3.0(@octokit/core@6.1.2)
|
||||
'@octokit/plugin-rest-endpoint-methods': 13.2.1(@octokit/core@6.1.2)
|
||||
'@octokit/types': 13.5.0
|
||||
undici: 6.13.0
|
||||
undici: 6.19.2
|
||||
|
||||
'@octokit/auth-action@5.1.1':
|
||||
dependencies:
|
||||
|
@ -18705,7 +18714,7 @@ snapshots:
|
|||
|
||||
undici-types@5.26.5: {}
|
||||
|
||||
undici@6.13.0: {}
|
||||
undici@6.19.2: {}
|
||||
|
||||
unicorn-magic@0.1.0: {}
|
||||
|
||||
|
|
Loading…
Reference in a new issue