diff --git a/packages/vinxi/runtime/server.js b/packages/vinxi/runtime/server.js index e34c9556..026abeaa 100644 --- a/packages/vinxi/runtime/server.js +++ b/packages/vinxi/runtime/server.js @@ -95,7 +95,6 @@ import { toNodeListener, toPlainHandler, toWebHandler, - toWebRequest as toWebRequestH3, unsealSession, // updateSession, use, useBase, // useSession, @@ -132,14 +131,65 @@ export function defineMiddleware(options) { return options; } + + +/** + * The web request utils are copied from `h3` with a few bug fixes regaring multiple access to + * `readBody` and when the body is an ArrayBuffer, such as in Deno, Edge Functions, etc. + * + * We intend to remove this section once this is upstreamed in h3. + */ + +function toWebRequestH3(/** @type {import('h3').H3Event} */ event) { + /** + * @type {ReadableStream | undefined} + */ + let readableStream; + + const url = getRequestURL(event); + const base = { + // @ts-ignore Undici option + duplex: "half", + method: event.method, + headers: event.headers, + }; + + if (event.node.req.body instanceof ArrayBuffer) { + return new Request(url, { + ...base, + body: event.node.req.body, + }); + } + + return new Request(url, { + ...base, + get body() { + if (readableStream) { + return readableStream; + } + readableStream = getRequestWebStream(event); + return readableStream; + }, + }); +} + export function toWebRequest(/** @type {import('h3').H3Event} */ event) { - event.web ??= { - request: toWebRequestH3(event), + const request = toWebRequestH3(event); + event.web ??= { + request, url: getRequestURL(event), }; return event.web.request; } +/** + * The session utils are copied from `h3` with a few bug fixe regaring locking when sealing happens + * so things dont get stuck. + * + * We intend to remove this section once this is upstreamed in h3. + * + */ + const DEFAULT_NAME = "h3"; const DEFAULT_COOKIE = { path: "/",