UNPKG

kequapp

Version:

A minimal, zero-magic Node web framework built on native APIs

76 lines (75 loc) 2.7 kB
import zlib from 'node:zlib'; import Ex from "../built-in/tools/ex.js"; import createParseBody, { parseJson, parseUrlEncoded, } from "./create-parse-body.js"; import parseMultipart from "./multipart/parse-multipart.js"; import splitMultipart from "./multipart/split-multipart.js"; import normalizeBody from "./normalize-body.js"; import streamReader from "./stream-reader.js"; const parseBody = createParseBody({ 'application/x-www-form-urlencoded': parseUrlEncoded, 'application/json': parseJson, }); export default function createGetBody(req) { let _body; // biome-ignore lint/suspicious/noExplicitAny: simplicity return async (options = {}) => { if (_body === undefined) { _body = { headers: { 'content-type': req.headers['content-type'] ?? '', 'content-disposition': req.headers['content-disposition'] ?? '', }, data: await streamReader(getStream(req), getMaxPayloadSize(options)), }; } const isMultipartRequest = _body.headers['content-type'].startsWith('multipart/'); if (options.raw === true) { if (options.multipart === true) { return isMultipartRequest ? splitMultipart(_body) : [clone(_body)]; } return _body.data; } if (isMultipartRequest) { const [result, files] = parseMultipart(splitMultipart(_body)); const body = normalizeBody(result, options); if (options.multipart === true) return [body, files]; return body; } else { const result = parseBody(_body); const body = normalizeBody(result, options); if (options.multipart === true) return [body, []]; return body; } }; } function getStream(req) { const encoding = (req.headers['content-encoding'] ?? 'identity').toLowerCase(); switch (encoding) { case 'br': return req.pipe(zlib.createBrotliDecompress()); case 'gzip': return req.pipe(zlib.createGunzip()); case 'deflate': return req.pipe(zlib.createInflate()); case 'identity': return req; } throw Ex.UnsupportedMediaType(`Unsupported encoding: ${encoding}`, { encoding, }); } function getMaxPayloadSize(options) { if (typeof options.maxPayloadSize === 'number' && options.maxPayloadSize > 0) { return options.maxPayloadSize; } return 1e6; } function clone(body) { return { ...body, headers: { ...body.headers } }; }