mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-27 02:44:50 +01:00
A request with no Content-Length header and no Transfer-Encoding header has no body (RFC 9112 section 6.3). declaredBodyBytes returned null for that shape, so both bridge gateways charged the same worst-case maxBodyBytes reserve as an unknown-size chunked body. A plain DELETE takes this exact shape, so two concurrent DELETE requests -- or one DELETE next to one large POST -- exceeded the production inflight bound and got a 503, even though neither request holds any real body memory. Classify the framing in three ways instead of two: a Transfer-Encoding header always means an unknown length; a valid Content-Length header is a declared length; neither header present is a declared length of zero. Both gateways already treat a non-null declared length as the real charge, so this alone fixes the reserve for both gateways with no other call-site change. The zero case still reads through readBody with a declared length of zero, so an unexpected body byte still raises a 413. The charge for a declared length and for an unknown (chunked) length is unchanged in value. The chunked worst case is documented in the comment on the charge: at production defaults the file gateway admits exactly one such request at a time, and this is intentional -- the gateway cannot know a chunked body's size before it reads it. Regression tests prove two concurrent DELETE requests, and one DELETE concurrent with a POST at the body cap, both reach the host worker at production admission defaults; they fail against the prior commit and pass after this fix. A duplex-gateway test proves the same zero-length charge with the duplex charge model unchanged for declared and unknown lengths. Co-authored-by: Paperclip <noreply@paperclip.ing>