Skip to content

Export body-size-limit helpers (limitBodyStream / limitRequestBody) for downstream reuse #279

Description

@pi0x

Request: export the body-size-limit helpers

The pull-based body-limit helpers in src/_body-limit.tslimitBodyStream, limitRequestBody, createBodyTooLargeError — are currently internal (_-prefixed, not in the public exports). They're a clean, runtime-agnostic implementation of streaming body-size enforcement, and downstream projects would benefit from reusing them instead of reimplementing.

Concrete motivation: h3 has bodyLimit() / assertBodySize() as per-handler / per-route utilities (distinct from srvx's server-global maxRequestBodySize). They currently verify size by pre-buffering a req.clone() before the handler runs, which adds latency and buffers up to limit bytes per request. We'd like to switch them to the exact pull-based approach limitRequestBody already implements — but can't import it. See h3js/h3#1498.

Ask

Expose these publicly, e.g. a srvx/body-limit subpath (or from the main entry):

export { limitBodyStream, limitRequestBody, createBodyTooLargeError } from "srvx/body-limit";

Reusing them (rather than mirroring ~30 lines in h3) keeps the error contract identical to srvx's server-level path — { code: "ERR_BODY_TOO_LARGE", statusCode: 413, status: 413 } — so both layers map to the same 413 behavior.

Possible improvements while exposing them

  1. Tighten the stream type. limitBodyStream(stream: ReadableStream, ...)ReadableStream<Uint8Array>, so value.byteLength is type-safe for consumers.
  2. Optional fail-fast on an honest Content-Length. limitRequestBody could reject immediately when a present content-length already exceeds the max, yielding a clean pre-read 413 instead of erroring mid-stream. (Header stays untrusted — it's an early-reject optimization only; the stream limit remains the authoritative check. Skip when transfer-encoding is also present.)
  3. Document the semantics of the exported API: pull-based (preserves backpressure, no read-ahead), enforcement is tied to consumption, and overflow surfaces as a stream error rather than a pre-handler response for unknown-length bodies.
  4. Shared error shape. Consider documenting/exporting the ERR_BODY_TOO_LARGE contract as the canonical body-too-large signal so downstreams (h3, nitro) map it consistently rather than string-matching.

Happy to send a PR if the direction sounds good.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions