Read Streams With a Byte Limit
Read an async iterable stream into a string while enforcing a hard byte ceiling and destroying the source as soon as it overflows.
Code
import { Buffer } from "node:buffer";
import { Readable } from "node:stream";
export async function readStreamWithLimit(stream, maxBytes, options = {}) {
if (stream === null || typeof stream !== "object" || typeof stream[Symbol.asyncIterator] !== "function") {
throw new TypeError("stream must be an async iterable readable stream");
}
if (!Number.isInteger(maxBytes) || maxBytes < 1) {
throw new RangeError("maxBytes must be a positive integer");
}
const { encoding = "utf8" } = options;
const chunks = [];
let total = 0;
try {
for await (const chunk of stream) {
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
total += buffer.length;
if (total > maxBytes) {
if (typeof stream.destroy === "function") stream.destroy();
throw new Error(`stream exceeded the ${maxBytes} byte limit`);
}
chunks.push(buffer);
}
} finally {
if (typeof stream.destroy === "function" && !stream.destroyed) stream.destroy();
}
return Buffer.concat(chunks).toString(encoding);
}
const body = Readable.from(["hello ", "world"]);
console.log(await readStreamWithLimit(body, 64));
try {
await readStreamWithLimit(Readable.from(["0123456789"]), 4);
} catch (error) {
console.log(error.message);
}Report a problem with this exampleOpens a pre-filled issue on GitHub.