kequapp
Version:
A minimal, zero-magic Node web framework built on native APIs
76 lines (75 loc) • 2.7 kB
JavaScript
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 } };
}