Sign In

srvx

Package Overview
Dependencies
Maintainers
1
Versions
84
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

srvx - npm Package Compare versions

Comparing version
0.12.2
to
0.12.3
+42
-33
dist/body-limit.d.mts
/**
* The canonical error thrown when a request body exceeds `maxRequestBodySize`.
* Returns a request whose body is size-limited to `maxRequestBodySize`.
*
* It carries a stable, documented shape so any layer can map it to an HTTP
* `413 Payload Too Large` response without string matching.
* If the request has no body it is returned unchanged; otherwise it is wrapped
* in a `Proxy` that routes every body read (`body` / `text` / `json` /
* `formData` / `arrayBuffer` / `blob` / `bytes` / `bodyUsed`) through a single
* lazily-created size-limited stream and passes everything else through to the
* original request. Used for runtimes that have no native body-size option (e.g.
* Deno) and exported so downstream layers can apply per-handler limits.
*
* @see https://srvx.h3.dev/guide/body-limit
*/
interface BodyTooLargeError extends Error {
/** Stable machine-readable code. */
code: "ERR_BODY_TOO_LARGE";
/** HTTP status to respond with. */
statusCode: 413;
/** Alias of {@link statusCode}. */
status: 413;
}
/**
* Creates the canonical {@link BodyTooLargeError | `413 Payload Too Large` error}
* used across srvx when a request body exceeds the configured `maxRequestBodySize`.
* Proxy-wrapping (rather than rebuilding via `new Request(request, …)`) is
* deliberate: it preserves the exact object handed in — including srvx's
* `ServerRequest` augmentation (`runtime`, `waitUntil`, `ip`, `context`, …) —
* and works on the Node adapter's `ServerRequest`. The returned
* value is the same type as the input, so `limitRequestBody(req)` on a
* `ServerRequest` yields a `ServerRequest`.
*
* When the request declares a `Content-Length` that already exceeds the limit,
* the body is rejected early: the original body is cancelled without being read
* and the returned request's body errors immediately with the
* {@link createBodyTooLargeError | `413`-style error}. `Content-Length` is only
* a fast path — it may be absent (chunked transfer encoding) or understated, so
* the streaming limit is always enforced regardless. A request that overstates
* its `Content-Length` is rejected on the declared length (a malformed request,
* matching how e.g. Bun and nginx enforce limits). The error still surfaces when
* the body is consumed (`request.text()` / `.json()` / `.arrayBuffer()` /
* `.body`), matching the streamed-limit behaviour.
*
* @see https://srvx.h3.dev/guide/body-limit
*/
declare function createBodyTooLargeError(maxRequestBodySize: number): BodyTooLargeError;
declare function limitRequestBody<T extends Request>(request: T, maxRequestBodySize: number): T;
/**

@@ -40,23 +48,24 @@ * Wraps a body `ReadableStream` so the total number of bytes read cannot exceed

/**
* Returns a `Request` whose body is size-limited to `maxRequestBodySize`.
* The canonical error thrown when a request body exceeds `maxRequestBodySize`.
*
* If the request has no body it is returned unchanged; otherwise it is rebuilt
* with a size-limited body stream (method, url, headers and signal are
* preserved). Used for runtimes that expose a native `Request` but no body-size
* option (e.g. Deno).
* It carries a stable, documented shape so any layer can map it to an HTTP
* `413 Payload Too Large` response without string matching.
*
* When the request declares a `Content-Length` that already exceeds the limit,
* the body is rejected early: the original body is cancelled without being read
* and the returned request's body errors immediately with the
* {@link createBodyTooLargeError | `413`-style error}. `Content-Length` is only
* a fast path — it may be absent (chunked transfer encoding) or understated, so
* the streaming limit is always enforced regardless. A request that overstates
* its `Content-Length` is rejected on the declared length (a malformed request,
* matching how e.g. Bun and nginx enforce limits). The error still surfaces when
* the body is consumed (`request.text()` / `.json()` / `.arrayBuffer()` /
* `.body`), matching the streamed-limit behaviour.
* @see https://srvx.h3.dev/guide/body-limit
*/
interface BodyTooLargeError extends Error {
/** Stable machine-readable code. */
code: "ERR_BODY_TOO_LARGE";
/** HTTP status to respond with. */
statusCode: 413;
/** Alias of {@link statusCode}. */
status: 413;
}
/**
* Creates the canonical {@link BodyTooLargeError | `413 Payload Too Large` error}
* used across srvx when a request body exceeds the configured `maxRequestBodySize`.
*
* @see https://srvx.h3.dev/guide/body-limit
*/
declare function limitRequestBody(request: Request, maxRequestBodySize: number): Request;
declare function createBodyTooLargeError(maxRequestBodySize: number): BodyTooLargeError;
export { BodyTooLargeError, createBodyTooLargeError, limitBodyStream, limitRequestBody };

@@ -1,7 +0,18 @@

function createBodyTooLargeError(maxRequestBodySize) {
return Object.assign(/* @__PURE__ */ new Error(`Request body exceeds the maximum allowed size of ${maxRequestBodySize} bytes.`), {
code: "ERR_BODY_TOO_LARGE",
statusCode: 413,
status: 413
});
function limitRequestBody(request, maxRequestBodySize) {
if (!request.body) return request;
const contentLengthHeader = request.headers.get("content-length");
const contentLength = contentLengthHeader && /^\d+$/.test(contentLengthHeader) ? Number(contentLengthHeader) : NaN;
const initiallyUsed = request.bodyUsed;
const overLimit = contentLength > maxRequestBodySize;
if (overLimit) request.body.cancel(createBodyTooLargeError(maxRequestBodySize)).catch(() => {});
let limited;
const limitedBody = () => limited ??= new Response(overLimit ? erroredStream(createBodyTooLargeError(maxRequestBodySize)) : limitBodyStream(request.body, maxRequestBodySize));
return new Proxy(request, { get(target, prop) {
if (prop === "body") return limitedBody().body;
if (prop === "bodyUsed") return initiallyUsed || (limited?.bodyUsed ?? false);
if (typeof prop === "string" && bodyReadMethods.has(prop)) return () => limitedBody()[prop]();
if (prop === "clone") return () => limitRequestBody(target.clone(), maxRequestBodySize);
const value = Reflect.get(target, prop, target);
return typeof value === "function" ? value.bind(target) : value;
} });
}

@@ -32,20 +43,22 @@ function limitBodyStream(stream, maxRequestBodySize) {

}
function limitRequestBody(request, maxRequestBodySize) {
if (!request.body) return request;
const contentLengthHeader = request.headers.get("content-length");
if ((contentLengthHeader && /^\d+$/.test(contentLengthHeader) ? Number(contentLengthHeader) : NaN) > maxRequestBodySize) {
const error = createBodyTooLargeError(maxRequestBodySize);
request.body.cancel(error).catch(() => {});
return new Request(request, {
body: new ReadableStream({ start(controller) {
controller.error(error);
} }),
duplex: "half"
});
}
return new Request(request, {
body: limitBodyStream(request.body, maxRequestBodySize),
duplex: "half"
const bodyReadMethods = /* @__PURE__ */ new Set([
"arrayBuffer",
"blob",
"bytes",
"formData",
"json",
"text"
]);
function createBodyTooLargeError(maxRequestBodySize) {
return Object.assign(/* @__PURE__ */ new Error(`Request body exceeds the maximum allowed size of ${maxRequestBodySize} bytes.`), {
code: "ERR_BODY_TOO_LARGE",
statusCode: 413,
status: 413
});
}
function erroredStream(error) {
return new ReadableStream({ start(controller) {
controller.error(error);
} });
}
export { createBodyTooLargeError, limitBodyStream, limitRequestBody };

@@ -208,3 +208,3 @@ import { bold, cyan, gray, green, magenta, red, url, yellow } from "./_chunks/_utils.mjs";

name: "srvx",
version: "0.12.1",
version: "0.12.2",
description: "Universal Server."

@@ -211,0 +211,0 @@ };

{
"name": "srvx",
"version": "0.12.2",
"version": "0.12.3",
"description": "Universal Server.",

@@ -5,0 +5,0 @@ "homepage": "https://srvx.h3.dev",