Return clean 413 on oversize instead of aborting connection

This commit is contained in:
2026-07-06 12:06:43 +02:00
parent 71f7ef1371
commit 2f8fb2a6d3
+14 -11
View File
@@ -43,30 +43,33 @@ function sendJson(res, status, obj) {
} }
// Read the whole request body, enforcing MAX_BYTES. // Read the whole request body, enforcing MAX_BYTES.
// On overflow we stop buffering and drain the rest of the stream so we can
// still send a clean 413 JSON response (destroying the socket => 502 at proxy).
function readBody(req, limit) { function readBody(req, limit) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const chunks = []; const chunks = [];
let total = 0; let total = 0;
let aborted = false; let over = false;
req.on('data', (chunk) => { req.on('data', (chunk) => {
if (aborted) return;
total += chunk.length; total += chunk.length;
if (over) return;
if (total > limit) { if (total > limit) {
aborted = true; over = true;
const err = new Error('too large'); chunks.length = 0;
err.statusCode = 413;
req.destroy();
reject(err);
return; return;
} }
chunks.push(chunk); chunks.push(chunk);
}); });
req.on('end', () => { req.on('end', () => {
if (!aborted) resolve(Buffer.concat(chunks)); if (over) {
}); const err = new Error('too large');
req.on('error', (err) => { err.statusCode = 413;
if (!aborted) reject(err); reject(err);
return;
}
resolve(Buffer.concat(chunks));
}); });
req.on('error', (err) => reject(err));
}); });
} }