@@ -29,5 +29,11 @@ /** | ||
| * | ||
| * Pass {@link BodyLimitOptions.createError | `options.createError`} to throw your | ||
| * own error on overflow (e.g. a framework's native HTTP error) instead of the | ||
| * default {@link createBodyTooLargeError | `413`-style error}. It is used for both | ||
| * the `Content-Length` fast path and the streaming limit, and is forwarded to | ||
| * `clone()` so clones stay limited with the same error. | ||
| * | ||
| * @see https://srvx.h3.dev/guide/body-limit | ||
| */ | ||
| declare function limitRequestBody<T extends Request>(request: T, maxRequestBodySize: number): T; | ||
| declare function limitRequestBody<T extends Request>(request: T, maxRequestBodySize: number, options?: BodyLimitOptions): T; | ||
| /** | ||
@@ -45,5 +51,9 @@ * Wraps a body `ReadableStream` so the total number of bytes read cannot exceed | ||
| * | ||
| * Pass {@link BodyLimitOptions.createError | `options.createError`} to error the | ||
| * stream with your own error on overflow instead of the default | ||
| * {@link createBodyTooLargeError | `413`-style error}. | ||
| * | ||
| * @see https://srvx.h3.dev/guide/body-limit | ||
| */ | ||
| declare function limitBodyStream(stream: ReadableStream<Uint8Array>, maxRequestBodySize: number): ReadableStream<Uint8Array>; | ||
| declare function limitBodyStream(stream: ReadableStream<Uint8Array>, maxRequestBodySize: number, options?: BodyLimitOptions): ReadableStream<Uint8Array>; | ||
| /** | ||
@@ -66,2 +76,20 @@ * The canonical error thrown when a request body exceeds `maxRequestBodySize`. | ||
| /** | ||
| * Factory for the error thrown when a body exceeds `maxRequestBodySize`, injectable | ||
| * via {@link BodyLimitOptions.createError} to override the default. | ||
| * | ||
| * @see https://srvx.h3.dev/guide/body-limit | ||
| */ | ||
| type BodyLimitErrorFactory = (maxRequestBodySize: number) => unknown; | ||
| /** | ||
| * Options for {@link limitRequestBody} and {@link limitBodyStream}. | ||
| * | ||
| * @see https://srvx.h3.dev/guide/body-limit | ||
| */ | ||
| interface BodyLimitOptions { | ||
| /** | ||
| * Factory for the error thrown on overflow. Defaults to {@link createBodyTooLargeError}. | ||
| */ | ||
| createError?: BodyLimitErrorFactory; | ||
| } | ||
| /** | ||
| * Creates the canonical {@link BodyTooLargeError | `413 Payload Too Large` error} | ||
@@ -73,2 +101,2 @@ * used across srvx when a request body exceeds the configured `maxRequestBodySize`. | ||
| declare function createBodyTooLargeError(maxRequestBodySize: number): BodyTooLargeError; | ||
| export { BodyTooLargeError, createBodyTooLargeError, limitBodyStream, limitRequestBody }; | ||
| export { BodyLimitErrorFactory, BodyLimitOptions, BodyTooLargeError, createBodyTooLargeError, limitBodyStream, limitRequestBody }; |
@@ -1,3 +0,4 @@ | ||
| function limitRequestBody(request, maxRequestBodySize) { | ||
| function limitRequestBody(request, maxRequestBodySize, options) { | ||
| if (!request.body) return request; | ||
| const createError = options?.createError ?? createBodyTooLargeError; | ||
| const contentLengthHeader = request.headers.get("content-length"); | ||
@@ -7,5 +8,5 @@ const contentLength = contentLengthHeader && /^\d+$/.test(contentLengthHeader) ? Number(contentLengthHeader) : NaN; | ||
| const overLimit = contentLength > maxRequestBodySize; | ||
| if (overLimit) request.body.cancel(createBodyTooLargeError(maxRequestBodySize)).catch(() => {}); | ||
| if (overLimit) request.body.cancel(createError(maxRequestBodySize)).catch(() => {}); | ||
| let limited; | ||
| const limitedBody = () => limited ??= new Response(overLimit ? erroredStream(createBodyTooLargeError(maxRequestBodySize)) : limitBodyStream(request.body, maxRequestBodySize)); | ||
| const limitedBody = () => limited ??= new Response(overLimit ? erroredStream(createError(maxRequestBodySize)) : limitBodyStream(request.body, maxRequestBodySize, options)); | ||
| return new Proxy(request, { get(target, prop) { | ||
@@ -15,3 +16,3 @@ if (prop === "body") return limitedBody().body; | ||
| if (typeof prop === "string" && bodyReadMethods.has(prop)) return () => limitedBody()[prop](); | ||
| if (prop === "clone") return () => limitRequestBody(target.clone(), maxRequestBodySize); | ||
| if (prop === "clone") return () => limitRequestBody(target.clone(), maxRequestBodySize, options); | ||
| const value = Reflect.get(target, prop, target); | ||
@@ -21,3 +22,4 @@ return typeof value === "function" ? value.bind(target) : value; | ||
| } | ||
| function limitBodyStream(stream, maxRequestBodySize) { | ||
| function limitBodyStream(stream, maxRequestBodySize, options) { | ||
| const createError = options?.createError ?? createBodyTooLargeError; | ||
| const reader = stream.getReader(); | ||
@@ -34,3 +36,3 @@ let size = 0; | ||
| if (size > maxRequestBodySize) { | ||
| const error = createBodyTooLargeError(maxRequestBodySize); | ||
| const error = createError(maxRequestBodySize); | ||
| reader.cancel(error).catch(() => {}); | ||
@@ -37,0 +39,0 @@ controller.error(error); |
+1
-1
@@ -208,3 +208,3 @@ import { bold, cyan, gray, green, magenta, red, url, yellow } from "./_chunks/_utils.mjs"; | ||
| name: "srvx", | ||
| version: "0.12.2", | ||
| version: "0.12.3", | ||
| description: "Universal Server." | ||
@@ -211,0 +211,0 @@ }; |
+1
-1
| { | ||
| "name": "srvx", | ||
| "version": "0.12.3", | ||
| "version": "0.12.4", | ||
| "description": "Universal Server.", | ||
@@ -5,0 +5,0 @@ "homepage": "https://srvx.h3.dev", |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
168044
0.84%3515
0.06%