UNPKG

@whatwg-node/server

Version:

Fetch API compliant HTTP Server adapter

119 lines (118 loc) 3.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.sendResponseToUwsOpts = exports.getRequestFromUWSRequest = exports.isUWSResponse = exports.useUWSAdapter = void 0; const utils_js_1 = require("../utils.js"); function useUWSAdapter() { const uwsResponseMap = new WeakMap(); return { onRequestAdapt({ args: [res, req, ...restOfCtx], setRequest, setServerContext, fetchAPI }) { if (isUWSResponse(res)) { const request = getRequestFromUWSRequest({ req: req, res, fetchAPI, }); uwsResponseMap.set(request, res); setRequest(request); const defaultServerContext = { req, res, }; const serverContext = restOfCtx.length > 0 ? (0, utils_js_1.completeAssign)(...restOfCtx) : defaultServerContext; setServerContext(serverContext); } }, onResponse({ request, response }) { const res = uwsResponseMap.get(request); if (res) { return sendResponseToUwsOpts({ res, response, }); } }, }; } exports.useUWSAdapter = useUWSAdapter; function isUWSResponse(res) { return !!res.onData; } exports.isUWSResponse = isUWSResponse; function getRequestFromUWSRequest({ req, res, fetchAPI }) { let body; const method = req.getMethod(); if (method !== 'get' && method !== 'head') { body = new fetchAPI.ReadableStream({}); const readable = body.readable; res.onAborted(() => { readable.push(null); }); res.onData(function (chunk, isLast) { readable.push(Buffer.from(chunk, 0, chunk.byteLength)); if (isLast) { readable.push(null); } }); } const headers = new fetchAPI.Headers(); req.forEach((key, value) => { headers.set(key, value); }); const url = `http://localhost${req.getUrl()}`; return new fetchAPI.Request(url, { method, headers, body: body, }); } exports.getRequestFromUWSRequest = getRequestFromUWSRequest; async function sendResponseToUwsOpts({ res, response }) { let resAborted = false; res.onAborted(function () { resAborted = true; }); res.cork(() => { res.writeStatus(`${response.status} ${response.statusText}`); }); response.headers.forEach((value, key) => { // content-length causes an error with Node.js's fetch if (key !== 'content-length') { if (key === 'set-cookie') { const setCookies = response.headers.getSetCookie?.(); if (setCookies) { setCookies.forEach(setCookie => { res.cork(() => { res.writeHeader(key, setCookie); }); }); return; } } res.cork(() => { res.writeHeader(key, value); }); } }); if (response.bodyType === 'String' || response.bodyType === 'Uint8Array') { res.cork(() => { res.end(response.bodyInit); }); return; } if (!response.body) { res.end(); return; } for await (const chunk of response.body) { if (resAborted) { return; } res.cork(() => { res.write(chunk); }); } res.cork(() => { res.end(); }); } exports.sendResponseToUwsOpts = sendResponseToUwsOpts;