fix: parseBody uses byte-accurate size check and returns 413

- Track bytes with Buffer.byteLength instead of string code units
- Return 413 Payload Too Large instead of generic 500
- Custom PayloadTooLargeError class for handler discrimination

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mert Koseoglu
2026-03-19 21:28:17 +03:00
parent 08a9c26ed2
commit 0e9258c300
+25 -8
View File
@@ -1311,15 +1311,24 @@ function createServer(options: ServerOptions = {}) {
return server;
}
class PayloadTooLargeError extends Error {
constructor() {
super("Body too large");
this.name = "PayloadTooLargeError";
}
}
async function parseBody(req: NextApiRequest): Promise<unknown> {
const MAX_BODY_SIZE = 1024 * 1024; // 1MB
return new Promise((resolve, reject) => {
let body = "";
req.on("data", (chunk) => {
let bytesReceived = 0;
req.on("data", (chunk: Buffer | string) => {
bytesReceived += Buffer.isBuffer(chunk) ? chunk.length : Buffer.byteLength(chunk);
body += chunk;
if (body.length > MAX_BODY_SIZE) {
if (bytesReceived > MAX_BODY_SIZE) {
req.destroy();
reject(new Error("Body too large"));
reject(new PayloadTooLargeError());
return;
}
});
@@ -1457,11 +1466,19 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
} catch (error) {
console.error("MCP error:", error);
if (!res.headersSent) {
res.status(500).json({
jsonrpc: "2.0",
error: { code: -32603, message: "Internal server error" },
id: null,
});
if (error instanceof PayloadTooLargeError) {
res.status(413).json({
jsonrpc: "2.0",
error: { code: -32600, message: "Payload too large. Maximum body size is 1MB." },
id: null,
});
} else {
res.status(500).json({
jsonrpc: "2.0",
error: { code: -32603, message: "Internal server error" },
id: null,
});
}
}
}
}