kequapp
Version:
DEPRECATED: renamed to @kequtech/arbor
72 lines (71 loc) • 2.59 kB
JavaScript
import zlib from 'node:zlib';
import { Ex } from "../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 function createGetBody(req) {
let _body;
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 } };
}