diff --git a/.changeset/shy-needles-warn.md b/.changeset/shy-needles-warn.md new file mode 100644 index 000000000000..543a36d18102 --- /dev/null +++ b/.changeset/shy-needles-warn.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: support HTTP/2 in dev and production. Revert the changes from [#12907](https://github.com/sveltejs/kit/pull/12907) to downgrade HTTP/2 to TLS as now being unnecessary diff --git a/packages/kit/src/exports/node/index.js b/packages/kit/src/exports/node/index.js index b3fe17c5a4f7..c4def8f89cd0 100644 --- a/packages/kit/src/exports/node/index.js +++ b/packages/kit/src/exports/node/index.js @@ -106,11 +106,25 @@ function get_raw_body(req, body_size_limit) { // TODO 3.0 make the signature synchronous? // eslint-disable-next-line @typescript-eslint/require-await export async function getRequest({ request, base, bodySizeLimit }) { + let headers = /** @type {Record} */ (request.headers); + if (request.httpVersionMajor >= 2) { + // the Request constructor rejects headers with ':' in the name + headers = Object.assign({}, headers); + // https://www.rfc-editor.org/rfc/rfc9113.html#section-8.3.1-2.3.5 + if (headers[':authority']) { + headers.host = headers[':authority']; + } + delete headers[':authority']; + delete headers[':method']; + delete headers[':path']; + delete headers[':scheme']; + } + return new Request(base + request.url, { // @ts-expect-error duplex: 'half', method: request.method, - headers: /** @type {Record} */ (request.headers), + headers: Object.entries(headers), body: request.method === 'GET' || request.method === 'HEAD' ? undefined diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 40fa4c6edb56..e6521e979560 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -349,22 +349,6 @@ async function kit({ svelte_config }) { * Stores the final config. */ configResolved(config) { - // we search for this plugin by name because we can't detect it - // since it doesn't directly modify the https config unlike the mkcert plugin - const vite_basic_ssl = config.plugins.find(({ name }) => name === 'vite:basic-ssl'); - - // by default, when enabling HTTPS in Vite, it also enables HTTP/2 - // however, undici has not yet enabled HTTP/2 by default: https://github.com/nodejs/undici/issues/2750 - // we set a no-op proxy config to force Vite to downgrade to TLS-only - // see https://vitejs.dev/config/#server-https - if ((config.server.https || vite_basic_ssl) && !config.server.proxy) { - config.server.proxy = {}; - } - - if ((config.preview.https || vite_basic_ssl) && !config.preview.proxy) { - config.preview.proxy = {}; - } - vite_config = config; } }; diff --git a/packages/kit/src/exports/vite/preview/index.js b/packages/kit/src/exports/vite/preview/index.js index 37e04f72f602..481fa087eab7 100644 --- a/packages/kit/src/exports/vite/preview/index.js +++ b/packages/kit/src/exports/vite/preview/index.js @@ -185,7 +185,7 @@ export async function preview(vite, vite_config, svelte_config) { // SSR vite.middlewares.use(async (req, res) => { - const host = req.headers['host']; + const host = req.headers[':authority'] || req.headers.host; const request = await getRequest({ base: `${protocol}://${host}`,