fix(infra): cap request body timeouts

This commit is contained in:
Peter Steinberger
2026-05-29 17:48:32 -04:00
parent 1dbde826f2
commit 7cd93f8e5c
2 changed files with 21 additions and 3 deletions
+14
View File
@@ -1,6 +1,7 @@
import { EventEmitter } from "node:events";
import type { IncomingMessage } from "node:http";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js";
import { createMockServerResponse } from "../test-utils/mock-http-response.js";
import {
installRequestBodyLimitGuard,
@@ -8,6 +9,7 @@ import {
type RequestBodyLimitErrorCode,
readJsonBodyWithLimit,
readRequestBodyWithLimit,
testApi,
} from "./http-body.js";
type MockIncomingMessage = IncomingMessage & {
@@ -254,6 +256,18 @@ describe("http body limits", () => {
expect(req["__unhandledDestroyError"]).toBeUndefined();
});
it("does not overflow oversized request body timeouts into immediate failures", async () => {
expect(
testApi.resolveRequestBodyLimitValues({
maxBytes: 128,
timeoutMs: Number.MAX_SAFE_INTEGER,
}),
).toEqual({
maxBytes: 128,
timeoutMs: MAX_TIMER_TIMEOUT_MS,
});
});
it("guard clamps invalid maxBytes to one byte", async () => {
const { res } = await expectGuardPayloadTooLarge({
chunks: ["ab"],
+7 -3
View File
@@ -1,5 +1,6 @@
import type { IncomingMessage, ServerResponse } from "node:http";
import { clearTimeout as clearNodeTimeout, setTimeout as setNodeTimeout } from "node:timers";
import { resolveTimerTimeoutMs } from "../shared/number-coercion.js";
import { formatErrorMessage } from "./errors.js";
import { parseStrictNonNegativeInteger } from "./parse-finite-number.js";
@@ -101,12 +102,15 @@ function resolveRequestBodyLimitValues(options: {
? Math.max(1, Math.floor(options.maxBytes))
: 1;
const timeoutMs =
typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs)
? Math.max(1, Math.floor(options.timeoutMs))
: DEFAULT_WEBHOOK_BODY_TIMEOUT_MS;
options.timeoutMs === undefined
? DEFAULT_WEBHOOK_BODY_TIMEOUT_MS
: resolveTimerTimeoutMs(options.timeoutMs, DEFAULT_WEBHOOK_BODY_TIMEOUT_MS);
return { maxBytes, timeoutMs };
}
export const testApi = { resolveRequestBodyLimitValues };
export { testApi as __test__ };
function advanceRequestBodyChunk(
chunk: Buffer | string,
totalBytes: number,