mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-13 21:01:21 +08:00
48 lines
2.1 KiB
TypeScript
48 lines
2.1 KiB
TypeScript
import { IncomingMessage, ServerResponse } from "http";
|
|
import { getRelativePart } from "./urls";
|
|
|
|
class ServerResponseWithBodyChunks extends ServerResponse {
|
|
bodyChunks: Uint8Array[] = [];
|
|
|
|
// note: we actually override this, even though it's private in the parent
|
|
_send(data: string, encoding: BufferEncoding, callback?: (() => void) | null, byteLength?: number) {
|
|
if (typeof encoding === "function") {
|
|
callback = encoding;
|
|
encoding = "utf-8";
|
|
}
|
|
const encodedBuffer = new Uint8Array(Buffer.from(data, encoding));
|
|
this.bodyChunks.push(encodedBuffer);
|
|
callback?.();
|
|
}
|
|
}
|
|
|
|
export async function createNodeHttpServerDuplex(options: {
|
|
method: string,
|
|
originalUrl?: URL,
|
|
url: URL,
|
|
headers: Headers,
|
|
body: Uint8Array,
|
|
}): Promise<[IncomingMessage, ServerResponseWithBodyChunks]> {
|
|
// See https://github.com/nodejs/node/blob/main/lib/_http_incoming.js
|
|
// and https://github.com/nodejs/node/blob/main/lib/_http_common.js (particularly the `parserXyz` functions)
|
|
|
|
const incomingMessage = new IncomingMessage({
|
|
encrypted: options.originalUrl?.protocol === "https:", // trick frameworks into believing this is an HTTPS request
|
|
} as any);
|
|
incomingMessage.httpVersionMajor = 1;
|
|
incomingMessage.httpVersionMinor = 1;
|
|
incomingMessage.httpVersion = '1.1';
|
|
incomingMessage.method = options.method;
|
|
incomingMessage.url = getRelativePart(options.url);
|
|
(incomingMessage as any).originalUrl = options.originalUrl && getRelativePart(options.originalUrl); // originalUrl is an extension used by some servers; for example, oidc-provider reads it to construct the paths for the .well-known/openid-configuration
|
|
const rawHeaders = [...options.headers.entries()].flat();
|
|
(incomingMessage as any)._addHeaderLines(rawHeaders, rawHeaders.length);
|
|
incomingMessage.push(Buffer.from(options.body));
|
|
incomingMessage.complete = true;
|
|
incomingMessage.push(null); // to emit end event, see: https://github.com/nodejs/node/blob/4cf6fabce20eb3050c5b543d249e931ea3d3cad5/lib/_http_common.js#L150
|
|
|
|
const serverResponse = new ServerResponseWithBodyChunks(incomingMessage);
|
|
|
|
return [incomingMessage, serverResponse];
|
|
}
|