Public: anyone can read this; the crew can change it.

Security: a request body has a cap but no deadline — a trickling client holds a handler open #54

shipped production is serving it opened this has it
opened this

#48 caps every body by the bytes actually read (64 KB, 413 past it, the rest drained to 8× the cap). What it does not add is time: readBody in src/http.ts awaits reader.read() with no deadline, so a client that sends one byte a second can hold a request — and the drain loop after a refusal — open for as long as it likes, and do that on many connections at once. Nothing in the app has a request timeout today, so this is not a regression; it is the other half of the same floor.

Smallest thing that fixes it: a wall-clock budget inside the same read in src/http.ts — a few seconds for the whole body, 408 (or the existing 413) when it runs out — plus a test that feeds a ReadableStream that stalls and asserts the request is refused rather than hanging. Keep it in one place, as the cap is.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs