0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-02-17 22:44:24 -05:00

fix(vercel): update getRequest to use undici (#6380)

* fix(vercel): update getRequest to use undici

* Changeset

* haha ts-expect-error is a double-edged sword

---------

Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
This commit is contained in:
Juan Martín Seery 2023-03-01 16:00:52 -03:00 committed by GitHub
parent 2678264f51
commit 0e378c3b87
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 22 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/vercel': patch
---
Fixed undici-related bug

View file

@ -2,11 +2,9 @@ import type { App } from 'astro/app';
import type { IncomingMessage, ServerResponse } from 'node:http'; import type { IncomingMessage, ServerResponse } from 'node:http';
import { splitCookiesString } from 'set-cookie-parser'; import { splitCookiesString } from 'set-cookie-parser';
const clientAddressSymbol = Symbol.for('astro.clientAddress');
/* /*
Credits to the SvelteKit team Credits to the SvelteKit team
https://github.com/sveltejs/kit/blob/dd380b38c322272b414a7ec3ac2911f2db353f5c/packages/kit/src/exports/node/index.js https://github.com/sveltejs/kit/blob/8d1ba04825a540324bc003e85f36559a594aadc2/packages/kit/src/exports/node/index.js
*/ */
function get_raw_body(req: IncomingMessage, body_size_limit?: number): ReadableStream | null { function get_raw_body(req: IncomingMessage, body_size_limit?: number): ReadableStream | null {
@ -32,7 +30,8 @@ function get_raw_body(req: IncomingMessage, body_size_limit?: number): ReadableS
if (!length) { if (!length) {
length = body_size_limit; length = body_size_limit;
} else if (length > body_size_limit) { } else if (length > body_size_limit) {
throw new Error( throw new HTTPError(
413,
`Received content-length of ${length}, but only accept up to ${body_size_limit} bytes.` `Received content-length of ${length}, but only accept up to ${body_size_limit} bytes.`
); );
} }
@ -66,7 +65,8 @@ function get_raw_body(req: IncomingMessage, body_size_limit?: number): ReadableS
if (size > length) { if (size > length) {
cancelled = true; cancelled = true;
controller.error( controller.error(
new Error( new HTTPError(
413,
`request body size exceeded ${ `request body size exceeded ${
content_length ? "'content-length'" : 'BODY_SIZE_LIMIT' content_length ? "'content-length'" : 'BODY_SIZE_LIMIT'
} of ${length}` } of ${length}`
@ -99,26 +99,20 @@ export async function getRequest(
req: IncomingMessage, req: IncomingMessage,
bodySizeLimit?: number bodySizeLimit?: number
): Promise<Request> { ): Promise<Request> {
let headers = req.headers as Record<string, string>; return new Request(base + req.url, {
if (req.httpVersionMajor === 2) { // @ts-expect-error
// we need to strip out the HTTP/2 pseudo-headers because node-fetch's duplex: 'half',
// Request implementation doesn't like them
headers = Object.assign({}, headers);
delete headers[':method'];
delete headers[':path'];
delete headers[':authority'];
delete headers[':scheme'];
}
const request = new Request(base + req.url, {
method: req.method, method: req.method,
headers, headers: req.headers as Record<string, string>,
body: get_raw_body(req, bodySizeLimit), body: get_raw_body(req, bodySizeLimit),
}); });
Reflect.set(request, clientAddressSymbol, headers['x-forwarded-for']);
return request;
} }
export async function setResponse(app: App, res: ServerResponse, response: Response) { export async function setResponse(
app: App,
res: ServerResponse,
response: Response
): Promise<void> {
const headers = Object.fromEntries(response.headers); const headers = Object.fromEntries(response.headers);
let cookies: string[] = []; let cookies: string[] = [];
@ -129,8 +123,9 @@ export async function setResponse(app: App, res: ServerResponse, response: Respo
} }
if (app.setCookieHeaders) { if (app.setCookieHeaders) {
const setCookieHeaders = Array.from(app.setCookieHeaders(response)); for (const setCookieHeader of app.setCookieHeaders(response)) {
cookies.push(...setCookieHeaders); cookies.push(setCookieHeader);
}
} }
res.writeHead(response.status, { ...headers, 'set-cookie': cookies }); res.writeHead(response.status, { ...headers, 'set-cookie': cookies });
@ -188,3 +183,16 @@ export async function setResponse(app: App, res: ServerResponse, response: Respo
} }
} }
} }
class HTTPError extends Error {
status: number;
constructor(status: number, reason: string) {
super(reason);
this.status = status;
}
get reason() {
return super.message;
}
}