Repository navigation
feat: Support streaming request bodies - #131
Merged
Merged
Conversation
Handlers implementing StreamingRequestHandler receive the request body unread as an InputStream, decoded lazily under the existing size cap, or raw via StreamingRequestHandler.raw(...). Parameters, security and body presence are still checked before the handler runs. Also: Content-Type media ranges (type/*, */*) and a missing Content-Type are matched against requestBody.content; Request.headers() lists all headers; Builder.maxConcurrentStreamingRequests(...) caps concurrent streaming requests with a 503 + Retry-After.
Builder.maxDecompressedStreamingRequestBytes(long) caps the decoded size of a body read by a StreamingRequestHandler with any positive long, so decoded streams are no longer held to the 2 GiB that bounds a buffered body. Unset, it defaults to maxDecompressedRequestBytes.
Javadoc and README now name maxDecompressedStreamingRequestBytes where streamed bodies are concerned. Adds an IT holding a streaming extra route to the streaming cap, with the setters in reverse order.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Request bodies were always buffered in memory (
readAllBytes). This adds opt-in streaming, so a handler can take large uploads without holding them in memory.StreamingRequestHandler— a handler implementing it gets the body unread viarequest.bodyStream(). TheContent-Encoding(gzip built in) is decoded lazily under a size cap;StreamingRequestHandler.raw(...)skips decoding and hands over the bytes as sent.bytes()/parsed()/asPojo()throw on a streaming request.Content-TypematchingrequestBody.content. The body schema is not validated (it can't be without buffering).Builder.maxConcurrentStreamingRequests(n[, retryAfter])— optional server-wide cap; excess streaming requests get503problem+json withRetry-After. The slot is taken after security and the peek, so slow or unauthenticated clients never hold one. Buffered requests are not counted. After-response hooks see the 503.Builder.maxDecompressedStreamingRequestBytes(long)— a separate cap on the decoded size of a streamed body; any positivelong, so past the 2 GiB that bounds buffered bodies (maxDecompressedRequestBytes, held in abyte[]). Defaults tomaxDecompressedRequestBytes.Content-Typematching (both paths): media rangestype/*and*/*inrequestBody.content; a missingContent-Typeis treated asapplication/jsonif declared, elseapplication/octet-stream(RFC 9110 §8.3).Request.headers()— all request headers, case-insensitive.extraRoutewith aStreamingRequestHandler) are supported and share the concurrency cap.requestBodyfails at boot.Additive only; existing handlers behave as before. One 400 detail string for a missing
Content-Typenow namesapplication/octet-streamwhen JSON isn't declared.Design and plan:
docs/superpowers/specs/2026-10-08-streaming-request-bodies-design.md,docs/superpowers/plans/2026-10-08-streaming-request-bodies.md. README has a new "Streaming request bodies" section.Known limits (documented)
Expect: 100-continueare answered100by the JDK before filters run, so a shed client may still send its body.Test plan
mvn verify— 758 unit + 128 IT green (incl. 36 inStreamingRequestBodyIT: 8 MiB past the cap, gzip, 413/400/415, separate streaming cap, validation, security, cap +Retry-After, slot release on failures, stalled clients holding no slot)