mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 18:34:02 +00:00
48 lines
1.5 KiB
JavaScript
48 lines
1.5 KiB
JavaScript
/** Read a request body with a hard byte cap; throws { code:'BODY_TOO_LARGE' } past the cap. */
|
|
async function readRequestBodyCapped(req, maxBytes) {
|
|
const chunks = [];
|
|
let total = 0;
|
|
for await (const chunk of req) {
|
|
total += chunk.length;
|
|
if (total > maxBytes) {
|
|
const err = new Error('Request body too large');
|
|
err.code = 'BODY_TOO_LARGE';
|
|
throw err;
|
|
}
|
|
chunks.push(chunk);
|
|
}
|
|
return Buffer.concat(chunks);
|
|
}
|
|
|
|
function readRequestBody(req, maxBytes = 1024 * 1024) {
|
|
return new Promise((resolve, reject) => {
|
|
let total = 0;
|
|
let bodyTooLarge = false;
|
|
const chunks = [];
|
|
req.on('data', (chunk) => {
|
|
// Keep draining after the cap without retaining more bytes. Destroying
|
|
// the request also destroys its socket, so the handler cannot deliver
|
|
// the fixed error response it constructs for BODY_TOO_LARGE.
|
|
if (bodyTooLarge) return;
|
|
total += chunk.length;
|
|
if (total > maxBytes) {
|
|
// Same marker readRequestBodyCapped sets, so a caller can tell an
|
|
// oversized body from a genuine failure without matching on text.
|
|
bodyTooLarge = true;
|
|
chunks.length = 0;
|
|
const error = new Error(`Request body exceeds ${maxBytes} bytes`);
|
|
error.code = 'BODY_TOO_LARGE';
|
|
reject(error);
|
|
return;
|
|
}
|
|
chunks.push(chunk);
|
|
});
|
|
req.on('end', () => {
|
|
if (!bodyTooLarge) resolve(Buffer.concat(chunks).toString('utf8'));
|
|
});
|
|
req.on('error', reject);
|
|
});
|
|
}
|
|
|
|
export { readRequestBodyCapped, readRequestBody };
|