diff --git a/lib/api/readable.js b/lib/api/readable.js index a65a7fcb557..452384a9a11 100644 --- a/lib/api/readable.js +++ b/lib/api/readable.js @@ -14,6 +14,7 @@ const kBody = Symbol('kBody') const kAbort = Symbol('kAbort') const kContentType = Symbol('kContentType') const kContentLength = Symbol('kContentLength') +const kBytesRead = Symbol('kBytesRead') const noop = () => {} @@ -35,9 +36,10 @@ class BodyReadable extends Readable { this[kAbort] = abort this[kConsume] = null + this[kBytesRead] = 0 this[kBody] = null this[kContentType] = contentType - this[kContentLength] = contentLength + this[kContentLength] = Number.isFinite(contentLength) ? contentLength : null // Is stream being consumed through Readable API? // This is an optimization so that we avoid checking @@ -99,6 +101,8 @@ class BodyReadable extends Readable { } push (chunk) { + this[kBytesRead] += chunk ? chunk.length : 0 + if (this[kConsume] && chunk !== null) { consumePush(this[kConsume], chunk) return this[kReading] ? super.push(chunk) : true @@ -151,7 +155,7 @@ class BodyReadable extends Readable { } async dump (opts) { - let limit = Number.isFinite(opts?.limit) ? opts.limit : 128 * 1024 + const limit = Number.isFinite(opts?.limit) ? opts.limit : 128 * 1024 const signal = opts?.signal if (signal != null && (typeof signal !== 'object' || !('aborted' in signal))) { @@ -165,7 +169,7 @@ class BodyReadable extends Readable { } return await new Promise((resolve, reject) => { - if (this[kContentLength] > limit) { + if (this[kContentLength] > limit || this[kBytesRead] > limit) { this.destroy(new AbortError()) } @@ -185,8 +189,7 @@ class BodyReadable extends Readable { }) .on('error', noop) .on('data', function (chunk) { - limit -= chunk.length - if (limit <= 0) { + if (this[kBytesRead] > limit) { this.destroy() } })