/** * Bounded request-body reading - the single source of truth for nifra's body-size cap. A lying or * absent `Content-Length` can't force us to buffer an oversized payload: a declared length over the * cap is rejected *before* buffering, a chunked / length-less body is aborted mid-stream once the * running byte count exceeds the cap, and the fast path re-checks the real byte count after the * read - the declared length is a hint, never the enforcement. Shared by the server's schema path, * `c.boundedBody`, and `verifyWebhook` so they all enforce the same guarantee. */ interface BodySource { readonly headers: Pick; readonly body: ReadableStream | null; arrayBuffer(): Promise; bytes?(): Promise; } /** The pre-cap reader surface a transport-capped request stashes under {@link RAW_BODY_READERS}. */ export interface RawBodyReaders { readonly headers: Pick; readonly body: ReadableStream | null; arrayBuffer(): Promise; /** Runtime-native exact-byte reader, when the request implementation exposes one. */ bytes?(): Promise; json(): Promise; } /** * The raw readers of a transport-capped request (see {@link capTransportBodyReads}), or the source * itself when it was never capped. Framework readers (the schema lane, `c.boundedBody`, * `verifyWebhook`, the idempotency lane) read through this so the transport cap on *direct* user * reads never narrows their own caller-supplied cap - `c.boundedBody(explicitBytes)` must keep * overriding the route cap upward, exactly as before the transport cap existed. */ export declare function rawBodySourceOf(req: T): T; /** * The byte cap a route that declared `bodyLimit: "unlimited"` reads under. It is a real number, not * `Infinity` or a skipped check: every bounded reader keeps its single `> maxBytes` enforcement * point (and its `assertByteLimit` guard) rather than growing an uncapped branch that a future * caller could reach by accident. No HTTP body reaches 2^53-1 bytes, so this is unlimited in fact. */ export declare const UNLIMITED_BODY_BYTES: number; /** Security/resource limits must be finite byte counts. Invalid values otherwise make `> maxBytes` * comparisons fail open (notably for `NaN`) and can re-enable unbounded buffering. */ export declare function assertByteLimit(value: number, name?: string): void; export declare function parseContentLength(value: string): number | undefined; /** The shared streaming byte-cap loop: read until done, or cancel + 413 once over `maxBytes`. * A single-chunk body (the common case for small chunked payloads) returns the runtime's own * chunk directly - no chunk array, no copy-merge. */ export declare function drainCapped(body: ReadableStream, maxBytes: number): Promise<{ ok: true; bytes: Uint8Array; } | { ok: false; status: 413; }>; /** * Read a request body as **bytes**, capped at `maxBytes`. Rejects a `Content-Length` over the cap * before buffering (`413`) and a malformed `Content-Length` (`400`); a chunked / length-less body * falls through to the streaming byte-cap guard. Fast path: a non-chunked request with a * `Content-Length` within the cap is read via native `arrayBuffer()`, then the **real** byte count * is checked against the declared length - a source that delivers more than it declared (a lying * or upstream-decoding adapter) is rejected with `413` even though its header passed the hint. */ export declare function readBoundedBytes(source: BodySource, maxBytes: number): Promise<{ ok: true; bytes: Uint8Array; } | { ok: false; status: 400 | 413; }>; /** Key under which a transport-capped request stashes its {@link RawBodyReaders}. */ export declare const RAW_BODY_READERS: unique symbol; /** Mark a request delivered straight from a runtime HTTP parser. */ export declare function markTrustedBodyFraming(source: object): void; /** True only for the runtime-framed ingress mark. */ export declare function hasTrustedBodyFraming(source: object): boolean; /** * Mark a request source with its route's transport byte cap. Dispatch-time cost is one property * write; nothing is shadowed, wrapped, or read here - the hot path stays untouched. The cap is * applied by {@link applyTransportCap} only when user code actually reaches for the request * (`c.req` / `c.request`), so a route that never direct-reads the body pays nothing. */ export declare function markTransportCap(source: object, maxBytes: number): void; /** * Enforce a marked source's transport byte cap on **direct user reads** of its request * (`c.req.json()`, `c.req.arrayBuffer()`, the raw `body` stream, `clone()`, ...), without swapping * the request's identity and without reading anything eagerly: the direct readers are shadowed with * byte-capped versions on the same object, so `WeakMap` keys, symbol stashes (the transport-codec * lane's pre-decoded body), and hook-observed references all survive. Framework readers bypass the * shadow through {@link rawBodySourceOf} and enforce their own caps - `c.boundedBody(explicit)` * still overrides in either direction. An unmarked source (`bodyLimit: "unlimited"`) is untouched. * * A source that owns its transport bytes directly (Node's lazy source reads the socket itself) * supplies them through `RequestSource.rawBodyReaders`: the capped readers then buffer off the * socket instead of routing every read back through a runtime `Request` the source was still * deferring. The cap is identical either way - the same {@link readBoundedBytes} enforces it. */ export declare function applyTransportCap(source: object, request: Request): void; export {}; //# sourceMappingURL=body.d.ts.map