From 74357cf360fdefa63124d02bce22cc6f3388433f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 05:01:26 +0000 Subject: [PATCH 1/4] fix: apply audit fixes --- dist/save-cache/index.cjs | 606 +++++++++++++++++++++++++++----------- 1 file changed, 436 insertions(+), 170 deletions(-) diff --git a/dist/save-cache/index.cjs b/dist/save-cache/index.cjs index 4126e4d..a72053e 100644 --- a/dist/save-cache/index.cjs +++ b/dist/save-cache/index.cjs @@ -1859,10 +1859,66 @@ var require_request = __commonJS({ return false; } } - onUpgrade(statusCode, headers, socket) { + /** + * @param {number|null} statusCode + * @param {Buffer[]|null} headers + * @param {import('node:stream').Duplex} socket + * @param {string} [statusText] + */ + onUpgrade(statusCode, headers, socket, statusText = "") { + this.onFinally(); assert4(!this.aborted); assert4(!this.completed); - return this[kHandler].onUpgrade(statusCode, headers, socket); + if (statusCode !== null) { + this.#publishUpgradeHeaders(statusCode, headers, statusText); + } + const result = this[kHandler].onUpgrade(statusCode, headers, socket); + if (!this.aborted) { + this.completed = true; + if (statusCode !== null) { + this.#publishUpgradeTrailers(); + } + } + return result; + } + /** + * @param {number} statusCode + * @param {import('node:http2').IncomingHttpHeaders} headers + * @param {(headers: import('node:http2').IncomingHttpHeaders) => Buffer[]} parseHeaders + * @param {string} [statusText] + */ + onUpgradeResponse(statusCode, headers, parseHeaders, statusText = "") { + assert4(!this.aborted); + assert4(this.completed); + if (channels.headers.hasSubscribers) { + this.#publishUpgradeHeaders(statusCode, parseHeaders(headers), statusText); + } + this.#publishUpgradeTrailers(); + } + /** + * @param {Error} error + */ + onUpgradeError(error2) { + assert4(!this.aborted); + assert4(this.completed); + if (channels.error.hasSubscribers) { + channels.error.publish({ request: this, error: error2 }); + } + } + /** + * @param {number} statusCode + * @param {Buffer[]} headers + * @param {string} statusText + */ + #publishUpgradeHeaders(statusCode, headers, statusText) { + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }); + } + } + #publishUpgradeTrailers() { + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers: [] }); + } } onComplete(trailers) { this.onFinally(); @@ -6005,7 +6061,7 @@ var require_client_h1 = __commonJS({ } } onUpgrade(head) { - const { upgrade, client, socket, headers, statusCode } = this; + const { upgrade, client, socket, headers, statusCode, statusText } = this; assert4(upgrade); assert4(client[kSocket] === socket); assert4(!socket.destroyed); @@ -6030,9 +6086,10 @@ var require_client_h1 = __commonJS({ client[kQueue][client[kRunningIdx]++] = null; client.emit("disconnect", client[kUrl], [client], new InformationalError("upgrade")); try { - request.onUpgrade(statusCode, headers, socket); - } catch (err) { - util7.destroy(socket, err); + request.onUpgrade(statusCode, headers, socket, statusText); + } catch (error2) { + util7.errorRequest(client, request, error2); + util7.destroy(socket, error2); } client[kResume](); } @@ -6324,21 +6381,20 @@ var require_client_h1 = __commonJS({ } function clearIdleSocketValidation(socket) { if (socket[kIdleSocketValidationTimeout]) { - clearTimeout(socket[kIdleSocketValidationTimeout]); + clearImmediate(socket[kIdleSocketValidationTimeout]); socket[kIdleSocketValidationTimeout] = null; } socket[kIdleSocketValidation] = 0; } function scheduleIdleSocketValidation(client, socket) { socket[kIdleSocketValidation] = 1; - socket[kIdleSocketValidationTimeout] = setTimeout(() => { + socket[kIdleSocketValidationTimeout] = setImmediate(() => { socket[kIdleSocketValidationTimeout] = null; socket[kIdleSocketValidation] = 2; if (client[kSocket] === socket && !socket.destroyed) { client[kResume](); } - }, 0); - socket[kIdleSocketValidationTimeout].unref?.(); + }); } function resumeH1(client) { const socket = client[kSocket]; @@ -6436,11 +6492,17 @@ var require_client_h1 = __commonJS({ } const socket = client[kSocket]; clearIdleSocketValidation(socket); - const abort = (err) => { - if (request.aborted || request.completed) { + const abort = (error2) => { + if (request.aborted) { return; } - util7.errorRequest(client, request, err || new RequestAbortedError()); + if (request.completed) { + if (request.upgrade || request.method === "CONNECT") { + util7.destroy(socket, new InformationalError("aborted")); + } + return; + } + util7.errorRequest(client, request, error2 || new RequestAbortedError()); util7.destroy(body2); util7.destroy(socket, new InformationalError("aborted")); }; @@ -6796,6 +6858,7 @@ var require_client_h2 = __commonJS({ "node_modules/@actions/http-client/node_modules/undici/lib/dispatcher/client-h2.js"(exports2, module2) { "use strict"; var assert4 = require("node:assert"); + var { errorMonitor } = require("node:events"); var { pipeline } = require("node:stream"); var util7 = require_util(); var { @@ -6856,6 +6919,10 @@ var require_client_h2 = __commonJS({ } return result; } + function parseH2ResponseHeaders(headers) { + const { [HTTP2_HEADER_STATUS]: _statusCode, ...realHeaders } = headers; + return parseH2Headers(realHeaders); + } async function connectH2(client, socket) { client[kSocket] = socket; if (!h2ExperimentalWarned) { @@ -7019,16 +7086,22 @@ var require_client_h2 = __commonJS({ const { hostname, port } = client[kUrl]; headers[HTTP2_HEADER_AUTHORITY] = host || `${hostname}${port ? `:${port}` : ""}`; headers[HTTP2_HEADER_METHOD] = method; - const abort = (err) => { - if (request.aborted || request.completed) { + const abort = (error2) => { + if (request.aborted) { return; } - err = err || new RequestAbortedError(); - util7.errorRequest(client, request, err); + if (request.completed) { + if (method === "CONNECT" && stream4 != null) { + util7.destroy(stream4, error2 || new RequestAbortedError()); + } + return; + } + error2 = error2 || new RequestAbortedError(); + util7.errorRequest(client, request, error2); if (stream4 != null) { - util7.destroy(stream4, err); + util7.destroy(stream4, error2); } - util7.destroy(body2, err); + util7.destroy(body2, error2); client[kQueue][client[kRunningIdx]++] = null; client[kResume](); }; @@ -7043,18 +7116,42 @@ var require_client_h2 = __commonJS({ if (method === "CONNECT") { session.ref(); stream4 = session.request(headers, { endStream: false, signal }); - if (stream4.id && !stream4.pending) { - request.onUpgrade(null, null, stream4); - ++session[kOpenStreams]; - client[kQueue][client[kRunningIdx]++] = null; - } else { - stream4.once("ready", () => { + let upgradeResponseFinished = false; + const onResponse = (headers2) => { + upgradeResponseFinished = true; + stream4.off(errorMonitor, onUpgradeError); + request.onUpgradeResponse(Number(headers2[HTTP2_HEADER_STATUS]), headers2, parseH2ResponseHeaders); + }; + const onUpgradeError = (error2) => { + upgradeResponseFinished = true; + stream4.off("response", onResponse); + request.onUpgradeError(error2); + }; + const onReady = () => { + try { request.onUpgrade(null, null, stream4); - ++session[kOpenStreams]; - client[kQueue][client[kRunningIdx]++] = null; - }); - } + } catch (error2) { + stream4.off("response", onResponse); + abort(error2); + return; + } + if (request.aborted) { + return; + } + stream4.off("error", abort); + stream4.once(errorMonitor, onUpgradeError); + client[kQueue][client[kRunningIdx]++] = null; + }; + stream4.once("response", onResponse); + stream4.once("error", abort); + ++session[kOpenStreams]; + onReady(); stream4.once("close", () => { + if (!upgradeResponseFinished && request.completed) { + stream4.off("response", onResponse); + stream4.off(errorMonitor, onUpgradeError); + request.onUpgradeError(new InformationalError(`HTTP/2: "stream error" received - code ${stream4.rstCode}`)); + } session[kOpenStreams] -= 1; if (session[kOpenStreams] === 0) session.unref(); }); @@ -9037,6 +9134,7 @@ var require_retry_handler = __commonJS({ this.end = null; this.etag = null; this.resume = null; + this.headersSent = false; this.handler.onConnect((reason) => { this.aborted = true; if (this.abort) { @@ -9046,6 +9144,17 @@ var require_retry_handler = __commonJS({ } }); } + checkpointResponseEnd(headers, resume) { + if (this.end == null && this.opts.method !== "HEAD") { + const contentLength2 = headers["content-length"]; + this.end = contentLength2 != null ? Number(contentLength2) - 1 : null; + assert4( + this.end == null || Number.isFinite(this.end), + "invalid content-length" + ); + } + this.resume = this.end != null ? resume : null; + } onRequestSent() { if (this.handler.onRequestSent) { this.handler.onRequestSent(); @@ -9107,7 +9216,9 @@ var require_retry_handler = __commonJS({ const headers = parseHeaders(rawHeaders); this.retryCount += 1; if (statusCode >= 300) { - if (this.retryOpts.statusCodes.includes(statusCode) === false) { + if (!this.headersSent && this.retryOpts.statusCodes.includes(statusCode) === false) { + this.headersSent = true; + this.checkpointResponseEnd(headers, resume); return this.handler.onHeaders( statusCode, rawHeaders, @@ -9162,8 +9273,15 @@ var require_retry_handler = __commonJS({ return false; } const { start, size, end = size - 1 } = contentRange; - assert4(this.start === start, "content-range mismatch"); - assert4(this.end == null || this.end === end, "content-range mismatch"); + if (this.start !== start || this.end != null && this.end !== end) { + this.abort( + new RequestRetryError("Content-Range mismatch", statusCode, { + headers, + data: { count: this.retryCount } + }) + ); + return false; + } this.resume = resume; return true; } @@ -9171,6 +9289,7 @@ var require_retry_handler = __commonJS({ if (statusCode === 206) { const range3 = parseRangeHeader(headers["content-range"]); if (range3 == null) { + this.headersSent = true; return this.handler.onHeaders( statusCode, rawHeaders, @@ -9202,6 +9321,7 @@ var require_retry_handler = __commonJS({ "invalid content-length" ); this.resume = resume; + this.headersSent = true; this.etag = headers.etag != null ? headers.etag : null; if (this.etag != null && this.etag.startsWith("W/")) { this.etag = null; @@ -9229,7 +9349,7 @@ var require_retry_handler = __commonJS({ return this.handler.onComplete(rawTrailers); } onError(err) { - if (this.aborted || isDisturbed(this.opts.body)) { + if (this.aborted || isDisturbed(this.opts.body) || this.headersSent && this.resume == null) { return this.handler.onError(err); } if (this.retryCount - this.retryCountCheckpoint > 0) { @@ -17115,7 +17235,7 @@ var require_connection = __commonJS({ const secProtocol = response.headersList.get("Sec-WebSocket-Protocol"); if (secProtocol !== null) { const requestProtocols = getDecodeSplit("sec-websocket-protocol", request.headersList); - if (!requestProtocols.includes(secProtocol)) { + if (requestProtocols === null || !requestProtocols.includes(secProtocol)) { failWebsocketConnection(ws, "Protocol was not set in the opening handshake."); return; } @@ -17263,6 +17383,7 @@ var require_permessage_deflate = __commonJS({ if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) { callback(new MessageSizeExceededError()); this.#inflate.removeAllListeners(); + this.#inflate.destroy(); this.#inflate = null; return; } @@ -18174,6 +18295,40 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var DATA = Buffer.from("data"); + var EVENT = Buffer.from("event"); + var ID2 = Buffer.from("id"); + var RETRY = Buffer.from("retry"); + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { + return false; + } + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { + return false; + } + } + return true; + } + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { + return false; + } + } + return true; + } + function isFieldName(line, length, field) { + if (length !== field.length) { + return false; + } + for (let i = 0; i < length; i++) { + if (line[i] !== field[i]) { + return false; + } + } + return true; + } var EventSourceStream = class extends Transform2 { /** * @type {eventSourceSettings} @@ -18193,10 +18348,13 @@ var require_eventsource_stream = __commonJS({ */ eventEndCheck = false; /** - * @type {Buffer} + * @type {Buffer[]} */ - buffer = null; + chunks = []; + chunkIndex = 0; pos = 0; + lineChunkIndex = 0; + linePos = 0; event = { data: void 0, event: void 0, @@ -18227,63 +18385,30 @@ var require_eventsource_stream = __commonJS({ callback(); return; } - if (this.buffer) { - this.buffer = Buffer.concat([this.buffer, chunk]); - } else { - this.buffer = chunk; - } + this.chunks.push(chunk); if (this.checkBOM) { - switch (this.buffer.length) { - case 1: - if (this.buffer[0] === BOM[0]) { - callback(); - return; - } - this.checkBOM = false; - callback(); - return; - case 2: - if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1]) { - callback(); - return; - } - this.checkBOM = false; - break; - case 3: - if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) { - this.buffer = Buffer.alloc(0); - this.checkBOM = false; - callback(); - return; - } - this.checkBOM = false; - break; - default: - if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) { - this.buffer = this.buffer.subarray(3); - } - this.checkBOM = false; - break; + if (this.handleBOM()) { + callback(); + return; } } - while (this.pos < this.buffer.length) { + while (this.hasCurrentByte()) { + const byte = this.currentByte(); if (this.eventEndCheck) { if (this.crlfCheck) { - if (this.buffer[this.pos] === LF) { - this.buffer = this.buffer.subarray(this.pos + 1); - this.pos = 0; + if (byte === LF) { this.crlfCheck = false; + this.consumeCurrentByte(); continue; } this.crlfCheck = false; } - if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { - if (this.buffer[this.pos] === CR) { + if (byte === LF || byte === CR) { + if (byte === CR) { this.crlfCheck = true; } - this.buffer = this.buffer.subarray(this.pos + 1); - this.pos = 0; - if (this.event.data !== void 0 || this.event.event || this.event.id || this.event.retry) { + this.consumeCurrentByte(); + if (this.hasPendingEvent()) { this.processEvent(this.event); } this.clearEvent(); @@ -18292,17 +18417,16 @@ var require_eventsource_stream = __commonJS({ this.eventEndCheck = false; continue; } - if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { - if (this.buffer[this.pos] === CR) { + if (byte === LF || byte === CR) { + if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.buffer.subarray(0, this.pos), this.event); - this.buffer = this.buffer.subarray(this.pos + 1); - this.pos = 0; + this.parseLine(this.readLine(), this.event); + this.consumeCurrentByte(); this.eventEndCheck = true; continue; } - this.pos++; + this.advanceCursor(); } callback(); } @@ -18318,43 +18442,42 @@ var require_eventsource_stream = __commonJS({ if (colonPosition === 0) { return; } - let field = ""; - let value = ""; + let fieldLength = line.length; + let valueStart = line.length; if (colonPosition !== -1) { - field = line.subarray(0, colonPosition).toString("utf8"); - let valueStart = colonPosition + 1; + fieldLength = colonPosition; + valueStart = colonPosition + 1; if (line[valueStart] === SPACE) { ++valueStart; } - value = line.subarray(valueStart).toString("utf8"); - } else { - field = line.toString("utf8"); - value = ""; } - switch (field) { - case "data": - if (event[field] === void 0) { - event[field] = value; - } else { - event[field] += ` + if (isFieldName(line, fieldLength, DATA)) { + const value = line.toString("utf8", valueStart); + if (event.data === void 0) { + event.data = value; + } else { + event.data += ` ${value}`; - } - break; - case "retry": - if (isASCIINumber(value)) { - event[field] = value; - } - break; - case "id": - if (isValidLastEventId(value)) { - event[field] = value; - } - break; - case "event": - if (value.length > 0) { - event[field] = value; - } - break; + } + return; + } + if (isFieldName(line, fieldLength, RETRY)) { + if (isASCIINumberBytes(line, valueStart)) { + event.retry = line.toString("utf8", valueStart); + } + return; + } + if (isFieldName(line, fieldLength, ID2)) { + if (isValidLastEventIdBytes(line, valueStart)) { + event.id = line.toString("utf8", valueStart); + } + return; + } + if (isFieldName(line, fieldLength, EVENT)) { + const value = line.toString("utf8", valueStart); + if (value.length > 0) { + event.event = value; + } } } /** @@ -18379,12 +18502,120 @@ ${value}`; } } clearEvent() { - this.event = { - data: void 0, - event: void 0, - id: void 0, - retry: void 0 - }; + this.event.data = void 0; + this.event.event = void 0; + this.event.id = void 0; + this.event.retry = void 0; + } + hasPendingEvent() { + return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; + } + hasCurrentByte() { + return this.chunkIndex < this.chunks.length && this.pos < this.chunks[this.chunkIndex].length; + } + currentByte() { + return this.chunks[this.chunkIndex][this.pos]; + } + consumeCurrentByte() { + this.advanceCursor(); + this.syncLineStartToCursor(); + } + advanceCursor() { + this.pos++; + while (this.chunkIndex < this.chunks.length && this.pos >= this.chunks[this.chunkIndex].length) { + this.chunkIndex++; + this.pos = 0; + } + } + syncLineStartToCursor() { + this.lineChunkIndex = this.chunkIndex; + this.linePos = this.pos; + this.dropConsumedChunks(); + } + dropConsumedChunks() { + while (this.lineChunkIndex > 0) { + this.chunks.shift(); + this.lineChunkIndex--; + this.chunkIndex--; + } + if (this.chunkIndex === this.chunks.length) { + this.chunks.length = 0; + this.chunkIndex = 0; + this.pos = 0; + this.lineChunkIndex = 0; + this.linePos = 0; + } + } + readLine() { + if (this.lineChunkIndex === this.chunkIndex) { + return this.chunks[this.chunkIndex].subarray(this.linePos, this.pos); + } + const chunks = []; + let length = 0; + for (let i = this.lineChunkIndex; i <= this.chunkIndex; i++) { + const chunk = this.chunks[i]; + const start = i === this.lineChunkIndex ? this.linePos : 0; + const end = i === this.chunkIndex ? this.pos : chunk.length; + const slice = chunk.subarray(start, end); + length += slice.length; + chunks.push(slice); + } + return Buffer.concat(chunks, length); + } + peekBufferedByte(offset) { + let chunkIndex = this.lineChunkIndex; + let pos = this.linePos; + while (chunkIndex < this.chunks.length) { + const chunk = this.chunks[chunkIndex]; + const remaining = chunk.length - pos; + if (offset < remaining) { + return chunk[pos + offset]; + } + offset -= remaining; + chunkIndex++; + pos = 0; + } + } + discardLeadingBytes(count) { + while (count > 0 && this.lineChunkIndex < this.chunks.length) { + const chunk = this.chunks[this.lineChunkIndex]; + const remaining = chunk.length - this.linePos; + if (count < remaining) { + this.linePos += count; + count = 0; + } else { + count -= remaining; + this.lineChunkIndex++; + this.linePos = 0; + } + } + this.chunkIndex = this.lineChunkIndex; + this.pos = this.linePos; + this.dropConsumedChunks(); + } + handleBOM() { + const first = this.peekBufferedByte(0); + const second = this.peekBufferedByte(1); + const third = this.peekBufferedByte(2); + if (second === void 0) { + if (first === BOM[0]) { + return true; + } + this.checkBOM = false; + return true; + } + if (third === void 0) { + if (first === BOM[0] && second === BOM[1]) { + return true; + } + this.checkBOM = false; + return false; + } + if (first === BOM[0] && second === BOM[1] && third === BOM[2]) { + this.discardLeadingBytes(3); + } + this.checkBOM = false; + return !this.hasCurrentByte(); } }; module2.exports = { @@ -18918,6 +19149,8 @@ var require_brace_expansion = __commonJS({ var escPeriod2 = "\0PERIOD" + Math.random() + "\0"; var EXPANSION_MAX2 = 1e5; var EXPANSION_MAX_LENGTH2 = 4e6; + var EXPANSION_MAX_DEPTH2 = 1e3; + var EXPANSION_MAX_REWRITES2 = 1e3; function numeric2(str) { return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0); } @@ -18927,25 +19160,36 @@ var require_brace_expansion = __commonJS({ function unescapeBraces2(str) { return str.split(escSlash2).join("\\").split(escOpen2).join("{").split(escClose2).join("}").split(escComma2).join(",").split(escPeriod2).join("."); } + function pushAll2(target, items) { + for (var i = 0; i < items.length; i++) { + target.push(items[i]); + } + } function parseCommaParts2(str) { - if (!str) - return [""]; var parts = []; - var m = balanced2("{", "}", str); - if (!m) - return str.split(","); - var pre = m.pre; - var body2 = m.body; - var post = m.post; - var p = pre.split(","); - p[p.length - 1] += "{" + body2 + "}"; - var postParts = parseCommaParts2(post); - if (post.length) { - p[p.length - 1] += postParts.shift(); - p.push.apply(p, postParts); - } - parts.push.apply(parts, p); - return parts; + var carry = ""; + for (; ; ) { + var m = balanced2("{", "}", str); + if (!m) { + var tail = str.split(","); + tail[0] = carry + tail[0]; + pushAll2(parts, tail); + return parts; + } + var pre = m.pre; + var body2 = m.body; + var post = m.post; + var p = pre.split(","); + p[0] = carry + p[0]; + p[p.length - 1] += "{" + body2 + "}"; + if (!post.length) { + pushAll2(parts, p); + return parts; + } + carry = p.pop(); + pushAll2(parts, p); + str = post; + } } function expandTop(str, options) { if (!str) @@ -18953,10 +19197,12 @@ var require_brace_expansion = __commonJS({ options = options || {}; var max = options.max == null ? EXPANSION_MAX2 : options.max; var maxLength = options.maxLength == null ? EXPANSION_MAX_LENGTH2 : options.maxLength; + var maxDepth = options.maxDepth == null ? EXPANSION_MAX_DEPTH2 : options.maxDepth; + var maxRewrites = options.maxRewrites == null ? EXPANSION_MAX_REWRITES2 : options.maxRewrites; if (str.substr(0, 2) === "{}") { str = "\\{\\}" + str.substr(2); } - return expand2(escapeBraces2(str), max, maxLength, true).map(unescapeBraces2); + return expand2(escapeBraces2(str), max, maxLength, maxDepth, 0, maxRewrites, true).map(unescapeBraces2); } function embrace2(str) { return "{" + str + "}"; @@ -19031,9 +19277,13 @@ var require_brace_expansion = __commonJS({ } return N; } - function expand2(str, max, maxLength, isTop) { + function expand2(str, max, maxLength, maxDepth, depth, maxRewrites, isTop) { + if (depth > maxDepth) { + return [str]; + } var acc = [""]; var accBase = [0]; + var rewrites = 0; var dropEmpties = false; var firstGroup = true; var nextBase; @@ -19051,7 +19301,8 @@ var require_brace_expansion = __commonJS({ var isSequence = isNumericSequence || isAlphaSequence; var isOptions = m.body.indexOf(",") >= 0; if (!isSequence && !isOptions) { - if (m.post.match(/,(?!,).*\}/)) { + if (rewrites < maxRewrites && m.post.match(/,(?!,).*\}/)) { + rewrites++; str = m.pre + "{" + m.body + escClose2 + m.post; isTop = true; firstGroup = true; @@ -19083,7 +19334,7 @@ var require_brace_expansion = __commonJS({ } else { var n = parseCommaParts2(m.body); if (n.length === 1 && n[0] !== void 0) { - n = expand2(n[0], max, maxLength, false).map(embrace2); + n = expand2(n[0], max, maxLength, maxDepth, depth + 1, maxRewrites, false).map(embrace2); if (n.length === 1) { nextBase = []; acc = combine2( @@ -19111,7 +19362,7 @@ var require_brace_expansion = __commonJS({ values = []; var valuesLength = 0; outer: for (var j = 0; j < n.length; j++) { - var expanded = expand2(n[j], max, maxLength, false); + var expanded = expand2(n[j], max, maxLength, maxDepth, depth + 1, maxRewrites, false); for (var k = 0; k < expanded.length; k++) { var v = expanded[k]; if (dropsEmpties && !v) continue; @@ -75520,6 +75771,8 @@ var commaPattern = /\\,/g; var periodPattern = /\\\./g; var EXPANSION_MAX = 1e5; var EXPANSION_MAX_LENGTH = 4e6; +var EXPANSION_MAX_DEPTH = 1e3; +var EXPANSION_MAX_REWRITES = 1e3; function numeric(str) { return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0); } @@ -75529,36 +75782,44 @@ function escapeBraces(str) { function unescapeBraces(str) { return str.replace(escSlashPattern, "\\").replace(escOpenPattern, "{").replace(escClosePattern, "}").replace(escCommaPattern, ",").replace(escPeriodPattern, "."); } -function parseCommaParts(str) { - if (!str) { - return [""]; +function pushAll(target, items) { + for (let i = 0; i < items.length; i++) { + target.push(items[i]); } +} +function parseCommaParts(str) { const parts = []; - const m = balanced("{", "}", str); - if (!m) { - return str.split(","); - } - const { pre, body: body2, post } = m; - const p = pre.split(","); - p[p.length - 1] += "{" + body2 + "}"; - const postParts = parseCommaParts(post); - if (post.length) { - ; - p[p.length - 1] += postParts.shift(); - p.push.apply(p, postParts); - } - parts.push.apply(parts, p); - return parts; + let carry = ""; + for (; ; ) { + const m = balanced("{", "}", str); + if (!m) { + const tail = str.split(","); + tail[0] = carry + tail[0]; + pushAll(parts, tail); + return parts; + } + const { pre, body: body2, post } = m; + const p = pre.split(","); + p[0] = carry + p[0]; + p[p.length - 1] += "{" + body2 + "}"; + if (!post.length) { + pushAll(parts, p); + return parts; + } + carry = p.pop(); + pushAll(parts, p); + str = post; + } } function expand(str, options = {}) { if (!str) { return []; } - const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH } = options; + const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH, maxDepth = EXPANSION_MAX_DEPTH, maxRewrites = EXPANSION_MAX_REWRITES } = options; if (str.slice(0, 2) === "{}") { str = "\\{\\}" + str.slice(2); } - return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces); + return expand_(escapeBraces(str), max, maxLength, maxDepth, 0, maxRewrites, true).map(unescapeBraces); } function embrace(str) { return "{" + str + "}"; @@ -75636,8 +75897,12 @@ function expandSequence(body2, isAlphaSequence, max, maxLength) { } return N; } -function expand_(str, max, maxLength, isTop) { +function expand_(str, max, maxLength, maxDepth, depth, maxRewrites, isTop) { + if (depth > maxDepth) { + return [str]; + } let acc = [""]; + let rewrites = 0; let dropEmpties = false; let firstGroup = true; for (; ; ) { @@ -75659,7 +75924,8 @@ function expand_(str, max, maxLength, isTop) { const isSequence = isNumericSequence || isAlphaSequence; const isOptions = m.body.indexOf(",") >= 0; if (!isSequence && !isOptions) { - if (m.post.match(/,(?!,).*\}/)) { + if (rewrites < maxRewrites && m.post.match(/,(?!,).*\}/)) { + rewrites++; str = m.pre + "{" + m.body + escClose + m.post; isTop = true; continue; @@ -75676,7 +75942,7 @@ function expand_(str, max, maxLength, isTop) { } else { let n = parseCommaParts(m.body); if (n.length === 1 && n[0] !== void 0) { - n = expand_(n[0], max, maxLength, false).map(embrace); + n = expand_(n[0], max, maxLength, maxDepth, depth + 1, maxRewrites, false).map(embrace); if (n.length === 1) { acc = combine(acc, pre + n[0], [""], max, maxLength, dropEmpties && !m.post.length); if (!m.post.length) @@ -75694,7 +75960,7 @@ function expand_(str, max, maxLength, isTop) { values = []; let valuesLength = 0; outer: for (let j = 0; j < n.length; j++) { - const expanded = expand_(n[j], max, maxLength, false); + const expanded = expand_(n[j], max, maxLength, maxDepth, depth + 1, maxRewrites, false); for (let k = 0; k < expanded.length; k++) { const v = expanded[k]; if (dropsEmpties && !v) From 83fb30c57173f4d6f75f4db0fa459761aec12dd5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 05:01:28 +0000 Subject: [PATCH 2/4] fix: apply audit fixes --- dist/setup/index.cjs | 2825 +++++++++++++++++++++++++++++------------- 1 file changed, 1945 insertions(+), 880 deletions(-) diff --git a/dist/setup/index.cjs b/dist/setup/index.cjs index e5108b6..640e9e3 100644 --- a/dist/setup/index.cjs +++ b/dist/setup/index.cjs @@ -1858,10 +1858,66 @@ var require_request = __commonJS({ return false; } } - onUpgrade(statusCode, headers, socket) { + /** + * @param {number|null} statusCode + * @param {Buffer[]|null} headers + * @param {import('node:stream').Duplex} socket + * @param {string} [statusText] + */ + onUpgrade(statusCode, headers, socket, statusText = "") { + this.onFinally(); assert4(!this.aborted); assert4(!this.completed); - return this[kHandler].onUpgrade(statusCode, headers, socket); + if (statusCode !== null) { + this.#publishUpgradeHeaders(statusCode, headers, statusText); + } + const result = this[kHandler].onUpgrade(statusCode, headers, socket); + if (!this.aborted) { + this.completed = true; + if (statusCode !== null) { + this.#publishUpgradeTrailers(); + } + } + return result; + } + /** + * @param {number} statusCode + * @param {import('node:http2').IncomingHttpHeaders} headers + * @param {(headers: import('node:http2').IncomingHttpHeaders) => Buffer[]} parseHeaders + * @param {string} [statusText] + */ + onUpgradeResponse(statusCode, headers, parseHeaders, statusText = "") { + assert4(!this.aborted); + assert4(this.completed); + if (channels.headers.hasSubscribers) { + this.#publishUpgradeHeaders(statusCode, parseHeaders(headers), statusText); + } + this.#publishUpgradeTrailers(); + } + /** + * @param {Error} error + */ + onUpgradeError(error2) { + assert4(!this.aborted); + assert4(this.completed); + if (channels.error.hasSubscribers) { + channels.error.publish({ request: this, error: error2 }); + } + } + /** + * @param {number} statusCode + * @param {Buffer[]} headers + * @param {string} statusText + */ + #publishUpgradeHeaders(statusCode, headers, statusText) { + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }); + } + } + #publishUpgradeTrailers() { + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers: [] }); + } } onComplete(trailers) { this.onFinally(); @@ -6004,7 +6060,7 @@ var require_client_h1 = __commonJS({ } } onUpgrade(head) { - const { upgrade, client, socket, headers, statusCode } = this; + const { upgrade, client, socket, headers, statusCode, statusText } = this; assert4(upgrade); assert4(client[kSocket] === socket); assert4(!socket.destroyed); @@ -6029,9 +6085,10 @@ var require_client_h1 = __commonJS({ client[kQueue][client[kRunningIdx]++] = null; client.emit("disconnect", client[kUrl], [client], new InformationalError("upgrade")); try { - request.onUpgrade(statusCode, headers, socket); - } catch (err) { - util10.destroy(socket, err); + request.onUpgrade(statusCode, headers, socket, statusText); + } catch (error2) { + util10.errorRequest(client, request, error2); + util10.destroy(socket, error2); } client[kResume](); } @@ -6323,21 +6380,20 @@ var require_client_h1 = __commonJS({ } function clearIdleSocketValidation(socket) { if (socket[kIdleSocketValidationTimeout]) { - clearTimeout(socket[kIdleSocketValidationTimeout]); + clearImmediate(socket[kIdleSocketValidationTimeout]); socket[kIdleSocketValidationTimeout] = null; } socket[kIdleSocketValidation] = 0; } function scheduleIdleSocketValidation(client, socket) { socket[kIdleSocketValidation] = 1; - socket[kIdleSocketValidationTimeout] = setTimeout(() => { + socket[kIdleSocketValidationTimeout] = setImmediate(() => { socket[kIdleSocketValidationTimeout] = null; socket[kIdleSocketValidation] = 2; if (client[kSocket] === socket && !socket.destroyed) { client[kResume](); } - }, 0); - socket[kIdleSocketValidationTimeout].unref?.(); + }); } function resumeH1(client) { const socket = client[kSocket]; @@ -6435,11 +6491,17 @@ var require_client_h1 = __commonJS({ } const socket = client[kSocket]; clearIdleSocketValidation(socket); - const abort = (err) => { - if (request.aborted || request.completed) { + const abort = (error2) => { + if (request.aborted) { return; } - util10.errorRequest(client, request, err || new RequestAbortedError()); + if (request.completed) { + if (request.upgrade || request.method === "CONNECT") { + util10.destroy(socket, new InformationalError("aborted")); + } + return; + } + util10.errorRequest(client, request, error2 || new RequestAbortedError()); util10.destroy(body2); util10.destroy(socket, new InformationalError("aborted")); }; @@ -6795,6 +6857,7 @@ var require_client_h2 = __commonJS({ "node_modules/@actions/http-client/node_modules/undici/lib/dispatcher/client-h2.js"(exports2, module2) { "use strict"; var assert4 = require("node:assert"); + var { errorMonitor } = require("node:events"); var { pipeline: pipeline4 } = require("node:stream"); var util10 = require_util(); var { @@ -6855,6 +6918,10 @@ var require_client_h2 = __commonJS({ } return result; } + function parseH2ResponseHeaders(headers) { + const { [HTTP2_HEADER_STATUS]: _statusCode, ...realHeaders } = headers; + return parseH2Headers(realHeaders); + } async function connectH2(client, socket) { client[kSocket] = socket; if (!h2ExperimentalWarned) { @@ -7018,16 +7085,22 @@ var require_client_h2 = __commonJS({ const { hostname, port } = client[kUrl]; headers[HTTP2_HEADER_AUTHORITY] = host || `${hostname}${port ? `:${port}` : ""}`; headers[HTTP2_HEADER_METHOD] = method; - const abort = (err) => { - if (request.aborted || request.completed) { + const abort = (error2) => { + if (request.aborted) { return; } - err = err || new RequestAbortedError(); - util10.errorRequest(client, request, err); + if (request.completed) { + if (method === "CONNECT" && stream7 != null) { + util10.destroy(stream7, error2 || new RequestAbortedError()); + } + return; + } + error2 = error2 || new RequestAbortedError(); + util10.errorRequest(client, request, error2); if (stream7 != null) { - util10.destroy(stream7, err); + util10.destroy(stream7, error2); } - util10.destroy(body2, err); + util10.destroy(body2, error2); client[kQueue][client[kRunningIdx]++] = null; client[kResume](); }; @@ -7042,18 +7115,42 @@ var require_client_h2 = __commonJS({ if (method === "CONNECT") { session.ref(); stream7 = session.request(headers, { endStream: false, signal }); - if (stream7.id && !stream7.pending) { - request.onUpgrade(null, null, stream7); - ++session[kOpenStreams]; - client[kQueue][client[kRunningIdx]++] = null; - } else { - stream7.once("ready", () => { + let upgradeResponseFinished = false; + const onResponse = (headers2) => { + upgradeResponseFinished = true; + stream7.off(errorMonitor, onUpgradeError); + request.onUpgradeResponse(Number(headers2[HTTP2_HEADER_STATUS]), headers2, parseH2ResponseHeaders); + }; + const onUpgradeError = (error2) => { + upgradeResponseFinished = true; + stream7.off("response", onResponse); + request.onUpgradeError(error2); + }; + const onReady = () => { + try { request.onUpgrade(null, null, stream7); - ++session[kOpenStreams]; - client[kQueue][client[kRunningIdx]++] = null; - }); - } + } catch (error2) { + stream7.off("response", onResponse); + abort(error2); + return; + } + if (request.aborted) { + return; + } + stream7.off("error", abort); + stream7.once(errorMonitor, onUpgradeError); + client[kQueue][client[kRunningIdx]++] = null; + }; + stream7.once("response", onResponse); + stream7.once("error", abort); + ++session[kOpenStreams]; + onReady(); stream7.once("close", () => { + if (!upgradeResponseFinished && request.completed) { + stream7.off("response", onResponse); + stream7.off(errorMonitor, onUpgradeError); + request.onUpgradeError(new InformationalError(`HTTP/2: "stream error" received - code ${stream7.rstCode}`)); + } session[kOpenStreams] -= 1; if (session[kOpenStreams] === 0) session.unref(); }); @@ -9036,6 +9133,7 @@ var require_retry_handler = __commonJS({ this.end = null; this.etag = null; this.resume = null; + this.headersSent = false; this.handler.onConnect((reason) => { this.aborted = true; if (this.abort) { @@ -9045,6 +9143,17 @@ var require_retry_handler = __commonJS({ } }); } + checkpointResponseEnd(headers, resume) { + if (this.end == null && this.opts.method !== "HEAD") { + const contentLength2 = headers["content-length"]; + this.end = contentLength2 != null ? Number(contentLength2) - 1 : null; + assert4( + this.end == null || Number.isFinite(this.end), + "invalid content-length" + ); + } + this.resume = this.end != null ? resume : null; + } onRequestSent() { if (this.handler.onRequestSent) { this.handler.onRequestSent(); @@ -9106,7 +9215,9 @@ var require_retry_handler = __commonJS({ const headers = parseHeaders(rawHeaders); this.retryCount += 1; if (statusCode >= 300) { - if (this.retryOpts.statusCodes.includes(statusCode) === false) { + if (!this.headersSent && this.retryOpts.statusCodes.includes(statusCode) === false) { + this.headersSent = true; + this.checkpointResponseEnd(headers, resume); return this.handler.onHeaders( statusCode, rawHeaders, @@ -9161,8 +9272,15 @@ var require_retry_handler = __commonJS({ return false; } const { start, size, end = size - 1 } = contentRange; - assert4(this.start === start, "content-range mismatch"); - assert4(this.end == null || this.end === end, "content-range mismatch"); + if (this.start !== start || this.end != null && this.end !== end) { + this.abort( + new RequestRetryError("Content-Range mismatch", statusCode, { + headers, + data: { count: this.retryCount } + }) + ); + return false; + } this.resume = resume; return true; } @@ -9170,6 +9288,7 @@ var require_retry_handler = __commonJS({ if (statusCode === 206) { const range3 = parseRangeHeader(headers["content-range"]); if (range3 == null) { + this.headersSent = true; return this.handler.onHeaders( statusCode, rawHeaders, @@ -9201,6 +9320,7 @@ var require_retry_handler = __commonJS({ "invalid content-length" ); this.resume = resume; + this.headersSent = true; this.etag = headers.etag != null ? headers.etag : null; if (this.etag != null && this.etag.startsWith("W/")) { this.etag = null; @@ -9228,7 +9348,7 @@ var require_retry_handler = __commonJS({ return this.handler.onComplete(rawTrailers); } onError(err) { - if (this.aborted || isDisturbed(this.opts.body)) { + if (this.aborted || isDisturbed(this.opts.body) || this.headersSent && this.resume == null) { return this.handler.onError(err); } if (this.retryCount - this.retryCountCheckpoint > 0) { @@ -17114,7 +17234,7 @@ var require_connection = __commonJS({ const secProtocol = response.headersList.get("Sec-WebSocket-Protocol"); if (secProtocol !== null) { const requestProtocols = getDecodeSplit("sec-websocket-protocol", request.headersList); - if (!requestProtocols.includes(secProtocol)) { + if (requestProtocols === null || !requestProtocols.includes(secProtocol)) { failWebsocketConnection(ws, "Protocol was not set in the opening handshake."); return; } @@ -17262,6 +17382,7 @@ var require_permessage_deflate = __commonJS({ if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) { callback(new MessageSizeExceededError()); this.#inflate.removeAllListeners(); + this.#inflate.destroy(); this.#inflate = null; return; } @@ -18173,6 +18294,40 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var DATA = Buffer.from("data"); + var EVENT = Buffer.from("event"); + var ID2 = Buffer.from("id"); + var RETRY = Buffer.from("retry"); + function isASCIINumberBytes(buffer3, start) { + if (start >= buffer3.length) { + return false; + } + for (let i = start; i < buffer3.length; i++) { + if (buffer3[i] < 48 || buffer3[i] > 57) { + return false; + } + } + return true; + } + function isValidLastEventIdBytes(buffer3, start) { + for (let i = start; i < buffer3.length; i++) { + if (buffer3[i] === 0) { + return false; + } + } + return true; + } + function isFieldName(line, length, field) { + if (length !== field.length) { + return false; + } + for (let i = 0; i < length; i++) { + if (line[i] !== field[i]) { + return false; + } + } + return true; + } var EventSourceStream = class extends Transform2 { /** * @type {eventSourceSettings} @@ -18192,10 +18347,13 @@ var require_eventsource_stream = __commonJS({ */ eventEndCheck = false; /** - * @type {Buffer} + * @type {Buffer[]} */ - buffer = null; + chunks = []; + chunkIndex = 0; pos = 0; + lineChunkIndex = 0; + linePos = 0; event = { data: void 0, event: void 0, @@ -18226,63 +18384,30 @@ var require_eventsource_stream = __commonJS({ callback(); return; } - if (this.buffer) { - this.buffer = Buffer.concat([this.buffer, chunk]); - } else { - this.buffer = chunk; - } + this.chunks.push(chunk); if (this.checkBOM) { - switch (this.buffer.length) { - case 1: - if (this.buffer[0] === BOM[0]) { - callback(); - return; - } - this.checkBOM = false; - callback(); - return; - case 2: - if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1]) { - callback(); - return; - } - this.checkBOM = false; - break; - case 3: - if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) { - this.buffer = Buffer.alloc(0); - this.checkBOM = false; - callback(); - return; - } - this.checkBOM = false; - break; - default: - if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) { - this.buffer = this.buffer.subarray(3); - } - this.checkBOM = false; - break; + if (this.handleBOM()) { + callback(); + return; } } - while (this.pos < this.buffer.length) { + while (this.hasCurrentByte()) { + const byte = this.currentByte(); if (this.eventEndCheck) { if (this.crlfCheck) { - if (this.buffer[this.pos] === LF) { - this.buffer = this.buffer.subarray(this.pos + 1); - this.pos = 0; + if (byte === LF) { this.crlfCheck = false; + this.consumeCurrentByte(); continue; } this.crlfCheck = false; } - if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { - if (this.buffer[this.pos] === CR) { + if (byte === LF || byte === CR) { + if (byte === CR) { this.crlfCheck = true; } - this.buffer = this.buffer.subarray(this.pos + 1); - this.pos = 0; - if (this.event.data !== void 0 || this.event.event || this.event.id || this.event.retry) { + this.consumeCurrentByte(); + if (this.hasPendingEvent()) { this.processEvent(this.event); } this.clearEvent(); @@ -18291,17 +18416,16 @@ var require_eventsource_stream = __commonJS({ this.eventEndCheck = false; continue; } - if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { - if (this.buffer[this.pos] === CR) { + if (byte === LF || byte === CR) { + if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.buffer.subarray(0, this.pos), this.event); - this.buffer = this.buffer.subarray(this.pos + 1); - this.pos = 0; + this.parseLine(this.readLine(), this.event); + this.consumeCurrentByte(); this.eventEndCheck = true; continue; } - this.pos++; + this.advanceCursor(); } callback(); } @@ -18317,43 +18441,42 @@ var require_eventsource_stream = __commonJS({ if (colonPosition === 0) { return; } - let field = ""; - let value = ""; + let fieldLength = line.length; + let valueStart = line.length; if (colonPosition !== -1) { - field = line.subarray(0, colonPosition).toString("utf8"); - let valueStart = colonPosition + 1; + fieldLength = colonPosition; + valueStart = colonPosition + 1; if (line[valueStart] === SPACE) { ++valueStart; } - value = line.subarray(valueStart).toString("utf8"); - } else { - field = line.toString("utf8"); - value = ""; } - switch (field) { - case "data": - if (event[field] === void 0) { - event[field] = value; - } else { - event[field] += ` + if (isFieldName(line, fieldLength, DATA)) { + const value = line.toString("utf8", valueStart); + if (event.data === void 0) { + event.data = value; + } else { + event.data += ` ${value}`; - } - break; - case "retry": - if (isASCIINumber(value)) { - event[field] = value; - } - break; - case "id": - if (isValidLastEventId(value)) { - event[field] = value; - } - break; - case "event": - if (value.length > 0) { - event[field] = value; - } - break; + } + return; + } + if (isFieldName(line, fieldLength, RETRY)) { + if (isASCIINumberBytes(line, valueStart)) { + event.retry = line.toString("utf8", valueStart); + } + return; + } + if (isFieldName(line, fieldLength, ID2)) { + if (isValidLastEventIdBytes(line, valueStart)) { + event.id = line.toString("utf8", valueStart); + } + return; + } + if (isFieldName(line, fieldLength, EVENT)) { + const value = line.toString("utf8", valueStart); + if (value.length > 0) { + event.event = value; + } } } /** @@ -18378,12 +18501,120 @@ ${value}`; } } clearEvent() { - this.event = { - data: void 0, - event: void 0, - id: void 0, - retry: void 0 - }; + this.event.data = void 0; + this.event.event = void 0; + this.event.id = void 0; + this.event.retry = void 0; + } + hasPendingEvent() { + return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; + } + hasCurrentByte() { + return this.chunkIndex < this.chunks.length && this.pos < this.chunks[this.chunkIndex].length; + } + currentByte() { + return this.chunks[this.chunkIndex][this.pos]; + } + consumeCurrentByte() { + this.advanceCursor(); + this.syncLineStartToCursor(); + } + advanceCursor() { + this.pos++; + while (this.chunkIndex < this.chunks.length && this.pos >= this.chunks[this.chunkIndex].length) { + this.chunkIndex++; + this.pos = 0; + } + } + syncLineStartToCursor() { + this.lineChunkIndex = this.chunkIndex; + this.linePos = this.pos; + this.dropConsumedChunks(); + } + dropConsumedChunks() { + while (this.lineChunkIndex > 0) { + this.chunks.shift(); + this.lineChunkIndex--; + this.chunkIndex--; + } + if (this.chunkIndex === this.chunks.length) { + this.chunks.length = 0; + this.chunkIndex = 0; + this.pos = 0; + this.lineChunkIndex = 0; + this.linePos = 0; + } + } + readLine() { + if (this.lineChunkIndex === this.chunkIndex) { + return this.chunks[this.chunkIndex].subarray(this.linePos, this.pos); + } + const chunks = []; + let length = 0; + for (let i = this.lineChunkIndex; i <= this.chunkIndex; i++) { + const chunk = this.chunks[i]; + const start = i === this.lineChunkIndex ? this.linePos : 0; + const end = i === this.chunkIndex ? this.pos : chunk.length; + const slice = chunk.subarray(start, end); + length += slice.length; + chunks.push(slice); + } + return Buffer.concat(chunks, length); + } + peekBufferedByte(offset) { + let chunkIndex = this.lineChunkIndex; + let pos = this.linePos; + while (chunkIndex < this.chunks.length) { + const chunk = this.chunks[chunkIndex]; + const remaining = chunk.length - pos; + if (offset < remaining) { + return chunk[pos + offset]; + } + offset -= remaining; + chunkIndex++; + pos = 0; + } + } + discardLeadingBytes(count) { + while (count > 0 && this.lineChunkIndex < this.chunks.length) { + const chunk = this.chunks[this.lineChunkIndex]; + const remaining = chunk.length - this.linePos; + if (count < remaining) { + this.linePos += count; + count = 0; + } else { + count -= remaining; + this.lineChunkIndex++; + this.linePos = 0; + } + } + this.chunkIndex = this.lineChunkIndex; + this.pos = this.linePos; + this.dropConsumedChunks(); + } + handleBOM() { + const first = this.peekBufferedByte(0); + const second = this.peekBufferedByte(1); + const third = this.peekBufferedByte(2); + if (second === void 0) { + if (first === BOM[0]) { + return true; + } + this.checkBOM = false; + return true; + } + if (third === void 0) { + if (first === BOM[0] && second === BOM[1]) { + return true; + } + this.checkBOM = false; + return false; + } + if (first === BOM[0] && second === BOM[1] && third === BOM[2]) { + this.discardLeadingBytes(3); + } + this.checkBOM = false; + return !this.hasCurrentByte(); } }; module2.exports = { @@ -18917,6 +19148,8 @@ var require_brace_expansion = __commonJS({ var escPeriod2 = "\0PERIOD" + Math.random() + "\0"; var EXPANSION_MAX2 = 1e5; var EXPANSION_MAX_LENGTH2 = 4e6; + var EXPANSION_MAX_DEPTH2 = 1e3; + var EXPANSION_MAX_REWRITES2 = 1e3; function numeric2(str) { return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0); } @@ -18926,25 +19159,36 @@ var require_brace_expansion = __commonJS({ function unescapeBraces2(str) { return str.split(escSlash2).join("\\").split(escOpen2).join("{").split(escClose2).join("}").split(escComma2).join(",").split(escPeriod2).join("."); } + function pushAll2(target, items) { + for (var i = 0; i < items.length; i++) { + target.push(items[i]); + } + } function parseCommaParts2(str) { - if (!str) - return [""]; var parts = []; - var m = balanced2("{", "}", str); - if (!m) - return str.split(","); - var pre = m.pre; - var body2 = m.body; - var post = m.post; - var p = pre.split(","); - p[p.length - 1] += "{" + body2 + "}"; - var postParts = parseCommaParts2(post); - if (post.length) { - p[p.length - 1] += postParts.shift(); - p.push.apply(p, postParts); - } - parts.push.apply(parts, p); - return parts; + var carry = ""; + for (; ; ) { + var m = balanced2("{", "}", str); + if (!m) { + var tail = str.split(","); + tail[0] = carry + tail[0]; + pushAll2(parts, tail); + return parts; + } + var pre = m.pre; + var body2 = m.body; + var post = m.post; + var p = pre.split(","); + p[0] = carry + p[0]; + p[p.length - 1] += "{" + body2 + "}"; + if (!post.length) { + pushAll2(parts, p); + return parts; + } + carry = p.pop(); + pushAll2(parts, p); + str = post; + } } function expandTop(str, options) { if (!str) @@ -18952,10 +19196,12 @@ var require_brace_expansion = __commonJS({ options = options || {}; var max = options.max == null ? EXPANSION_MAX2 : options.max; var maxLength = options.maxLength == null ? EXPANSION_MAX_LENGTH2 : options.maxLength; + var maxDepth = options.maxDepth == null ? EXPANSION_MAX_DEPTH2 : options.maxDepth; + var maxRewrites = options.maxRewrites == null ? EXPANSION_MAX_REWRITES2 : options.maxRewrites; if (str.substr(0, 2) === "{}") { str = "\\{\\}" + str.substr(2); } - return expand2(escapeBraces2(str), max, maxLength, true).map(unescapeBraces2); + return expand2(escapeBraces2(str), max, maxLength, maxDepth, 0, maxRewrites, true).map(unescapeBraces2); } function embrace2(str) { return "{" + str + "}"; @@ -19030,9 +19276,13 @@ var require_brace_expansion = __commonJS({ } return N; } - function expand2(str, max, maxLength, isTop) { + function expand2(str, max, maxLength, maxDepth, depth, maxRewrites, isTop) { + if (depth > maxDepth) { + return [str]; + } var acc = [""]; var accBase = [0]; + var rewrites = 0; var dropEmpties = false; var firstGroup = true; var nextBase; @@ -19050,7 +19300,8 @@ var require_brace_expansion = __commonJS({ var isSequence = isNumericSequence || isAlphaSequence; var isOptions = m.body.indexOf(",") >= 0; if (!isSequence && !isOptions) { - if (m.post.match(/,(?!,).*\}/)) { + if (rewrites < maxRewrites && m.post.match(/,(?!,).*\}/)) { + rewrites++; str = m.pre + "{" + m.body + escClose2 + m.post; isTop = true; firstGroup = true; @@ -19082,7 +19333,7 @@ var require_brace_expansion = __commonJS({ } else { var n = parseCommaParts2(m.body); if (n.length === 1 && n[0] !== void 0) { - n = expand2(n[0], max, maxLength, false).map(embrace2); + n = expand2(n[0], max, maxLength, maxDepth, depth + 1, maxRewrites, false).map(embrace2); if (n.length === 1) { nextBase = []; acc = combine2( @@ -19110,7 +19361,7 @@ var require_brace_expansion = __commonJS({ values = []; var valuesLength = 0; outer: for (var j = 0; j < n.length; j++) { - var expanded = expand2(n[j], max, maxLength, false); + var expanded = expand2(n[j], max, maxLength, maxDepth, depth + 1, maxRewrites, false); for (var k = 0; k < expanded.length; k++) { var v = expanded[k]; if (dropsEmpties && !v) continue; @@ -29363,6 +29614,8 @@ var require_symbols6 = __commonJS({ kDestroy: /* @__PURE__ */ Symbol("destroy"), kDispatch: /* @__PURE__ */ Symbol("dispatch"), kUrl: /* @__PURE__ */ Symbol("url"), + kRequestOrigin: /* @__PURE__ */ Symbol("request origin"), + kOriginless: /* @__PURE__ */ Symbol("originless"), kWriting: /* @__PURE__ */ Symbol("writing"), kResuming: /* @__PURE__ */ Symbol("resuming"), kQueue: /* @__PURE__ */ Symbol("queue"), @@ -30697,37 +30950,6 @@ var require_util9 = __commonJS({ bytesRead: socket.bytesRead }; } - function ReadableStreamFrom(iterable) { - let iterator2; - return new ReadableStream( - { - start() { - iterator2 = iterable[Symbol.asyncIterator](); - }, - pull(controller) { - return iterator2.next().then(({ done, value }) => { - if (done) { - return queueMicrotask(() => { - controller.close(); - controller.byobRequest?.respond(0); - }); - } else { - const buf = Buffer.isBuffer(value) ? value : Buffer.from(value); - if (buf.byteLength) { - return controller.enqueue(new Uint8Array(buf)); - } else { - return this.pull(controller); - } - } - }); - }, - cancel() { - return iterator2.return(); - }, - type: "bytes" - } - ); - } function isFormDataLike(object) { return object && typeof object === "object" && typeof object.append === "function" && typeof object.delete === "function" && typeof object.get === "function" && typeof object.getAll === "function" && typeof object.has === "function" && typeof object.set === "function" && object[Symbol.toStringTag] === "FormData"; } @@ -31188,7 +31410,6 @@ var require_util9 = __commonJS({ destroy: destroy2, bodyLength, deepClone, - ReadableStreamFrom, isBuffer: isBuffer2, assertRequestHandler, getSocketInfo, @@ -31757,15 +31978,32 @@ var require_request3 = __commonJS({ return false; } } - onRequestUpgrade(statusCode, headers, socket) { + /** + * @param {number} statusCode + * @param {Buffer[]|string[]|import('../../types/header.d.ts').IncomingHttpHeaders} headers + * @param {import('node:stream').Duplex} socket + * @param {string} [statusText] + */ + onRequestUpgrade(statusCode, headers, socket, statusText = "") { + this.onFinally(); assert4(!this.aborted); assert4(!this.completed); + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }); + } const controller = this[kController]; if (controller) { controller.rawHeaders = headers; } const parsedHeaders = Array.isArray(headers) ? parseHeaders(headers) : headers; - return this[kHandler].onRequestUpgrade?.(controller, statusCode, parsedHeaders, socket); + const result = this[kHandler].onRequestUpgrade?.(controller, statusCode, parsedHeaders, socket); + if (!this.aborted) { + this.completed = true; + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers: [] }); + } + } + return result; } onResponseEnd(trailers) { this.onFinally(); @@ -31909,6 +32147,7 @@ var require_dispatcher2 = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher.js"(exports2, module2) { "use strict"; var EventEmitter5 = require("node:events"); + var { kOriginless, kUrl } = require_symbols6(); var Dispatcher = class extends EventEmitter5 { dispatch() { throw new Error("not implemented"); @@ -31921,6 +32160,7 @@ var require_dispatcher2 = __commonJS({ } compose(...args) { const interceptors = Array.isArray(args[0]) ? args[0] : args; + const interceptorOrigin = this[kOriginless] === true ? null : this[kUrl]?.origin; let dispatch = this.dispatch.bind(this); for (const interceptor of interceptors) { if (interceptor == null) { @@ -31929,11 +32169,19 @@ var require_dispatcher2 = __commonJS({ if (typeof interceptor !== "function") { throw new TypeError(`invalid interceptor, expected function received ${typeof interceptor}`); } - dispatch = interceptor(dispatch); + dispatch = interceptor(dispatch, interceptorOrigin); if (dispatch == null || typeof dispatch !== "function" || dispatch.length !== 2) { throw new TypeError("invalid interceptor"); } } + const originalDispatch = dispatch; + const self2 = this; + dispatch = function(opts, handler) { + if (opts && typeof opts === "object" && !opts.origin && self2[kUrl]) { + opts = Object.assign({}, opts, { origin: self2[kUrl].origin }); + } + return originalDispatch(opts, handler); + }; return new Proxy(this, { get: (target, key) => key === "dispatch" ? dispatch : target[key] }); @@ -31947,6 +32195,7 @@ var require_dispatcher2 = __commonJS({ var require_dispatcher_base2 = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports2, module2) { "use strict"; + var buffer3 = require("node:buffer"); var Dispatcher = require_dispatcher2(); var { ClientDestroyedError, @@ -31957,6 +32206,7 @@ var require_dispatcher_base2 = __commonJS({ var kOnDestroyed = /* @__PURE__ */ Symbol("onDestroyed"); var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { /** @type {boolean} */ [kDestroyed] = false; @@ -31972,9 +32222,10 @@ var require_dispatcher_base2 = __commonJS({ constructor(opts) { super(); this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } /** - * @returns {import('../../types/dispatcher').WebSocketOptions} + * @returns {import('../../types/client').Client.WebSocketOptions} */ get webSocketOptions() { return { @@ -31983,6 +32234,14 @@ var require_dispatcher_base2 = __commonJS({ // 128 MB default }; } + /** + * @returns {import('../../types/client').Client.EventSourceOptions} + */ + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer3.kStringMaxLength + }; + } /** @returns {boolean} */ get destroyed() { return this[kDestroyed]; @@ -33272,6 +33531,10 @@ var require_infra = __commonJS({ assert4(!invalidIsomorphicEncodeValueRegex.test(input)); return input; } + var nonASCIIRegex = /[^\x00-\x7F]/; + function asciiLowercase(str) { + return nonASCIIRegex.test(str) ? str.replace(/[A-Z]+/g, (upper) => upper.toLowerCase()) : str.toLowerCase(); + } function parseJSONFromBytes(bytes) { return JSON.parse(utf8DecodeBytes(bytes)); } @@ -33285,7 +33548,7 @@ var require_infra = __commonJS({ while (lead < str.length && predicate(str.charCodeAt(lead))) lead++; } if (trailing) { - while (trail > 0 && predicate(str.charCodeAt(trail))) trail--; + while (trail >= lead && predicate(str.charCodeAt(trail))) trail--; } return lead === 0 && trail === str.length - 1 ? str : str.slice(lead, trail + 1); } @@ -33298,6 +33561,7 @@ var require_infra = __commonJS({ return result; } module2.exports = { + asciiLowercase, collectASequenceOfCodePoints, collectASequenceOfCodePointsFast, forgivingBase64, @@ -33317,9 +33581,9 @@ var require_data_url2 = __commonJS({ "node_modules/undici/lib/web/fetch/data-url.js"(exports2, module2) { "use strict"; var assert4 = require("node:assert"); - var { forgivingBase64, collectASequenceOfCodePoints, collectASequenceOfCodePointsFast, isomorphicDecode, removeASCIIWhitespace, removeChars } = require_infra(); + var { asciiLowercase, forgivingBase64, collectASequenceOfCodePoints, collectASequenceOfCodePointsFast, isomorphicDecode, removeASCIIWhitespace, removeChars } = require_infra(); var encoder = new TextEncoder(); - var HTTP_TOKEN_CODEPOINTS = /^[-!#$%&'*+.^_|~A-Za-z0-9]+$/u; + var HTTP_TOKEN_CODEPOINTS = /^[-!#$%&'*+.^_`|~A-Za-z0-9]+$/u; var HTTP_WHITESPACE_REGEX = /[\u000A\u000D\u0009\u0020]/u; var HTTP_QUOTED_STRING_TOKENS = /^[\u0009\u0020-\u007E\u0080-\u00FF]+$/u; function dataURLProcessor(dataURL) { @@ -33340,7 +33604,7 @@ var require_data_url2 = __commonJS({ position.position++; const encodedBody = input.slice(mimeTypeLength + 1); let body2 = stringPercentDecode(encodedBody); - if (/;(?:\u0020*)base64$/ui.test(mimeType)) { + if (/;\u0020*[Bb][Aa][Ss][Ee]64$/u.test(mimeType)) { const stringBody = isomorphicDecode(body2); body2 = forgivingBase64(stringBody); if (body2 === "failure") { @@ -33427,8 +33691,8 @@ var require_data_url2 = __commonJS({ if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { return "failure"; } - const typeLowercase = type.toLowerCase(); - const subtypeLowercase = subtype.toLowerCase(); + const typeLowercase = asciiLowercase(type); + const subtypeLowercase = asciiLowercase(subtype); const mimeType = { type: typeLowercase, subtype: subtypeLowercase, @@ -33450,7 +33714,7 @@ var require_data_url2 = __commonJS({ input, position ); - parameterName = parameterName.toLowerCase(); + parameterName = asciiLowercase(parameterName); if (position.position < input.length) { if (input[position.position] === ";") { continue; @@ -33630,23 +33894,13 @@ var require_webidl2 = __commonJS({ message: `"${context3.value}" is an invalid ${context3.type}.` }); }; - webidl.brandCheck = function(V, I) { - if (!FunctionPrototypeSymbolHasInstance(I, V)) { + webidl.brandCheck = function(V, is) { + if (!is(V)) { const err = new TypeError("Illegal invocation"); err.code = "ERR_INVALID_THIS"; throw err; } }; - webidl.brandCheckMultiple = function(List) { - const prototypes = List.map((c) => webidl.util.MakeTypeAssertion(c)); - return (V) => { - if (prototypes.every((typeCheck) => !typeCheck(V))) { - const err = new TypeError("Illegal invocation"); - err.code = "ERR_INVALID_THIS"; - throw err; - } - }; - }; webidl.argumentLengthCheck = function({ length }, min, ctx) { if (length < min) { throw webidl.errors.exception({ @@ -34202,7 +34456,7 @@ var require_util10 = __commonJS({ var { getGlobalOrigin } = require_global3(); var { collectAnHTTPQuotedString, parseMIMEType } = require_data_url2(); var { performance: performance2 } = require("node:perf_hooks"); - var { ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = require_util9(); + var { isValidHTTPToken, normalizedMethodRecordsBase } = require_util9(); var assert4 = require("node:assert"); var { isUint8Array } = require("node:util/types"); var { webidl } = require_webidl2(); @@ -34299,6 +34553,9 @@ var require_util10 = __commonJS({ return "success"; } function appendFetchMetadata(httpRequest) { + if (!isURLPotentiallyTrustworthy(requestCurrentURL(httpRequest))) { + return; + } let header = null; header = httpRequest.mode; httpRequest.headersList.set("sec-fetch-mode", header, true); @@ -34595,7 +34852,7 @@ var require_util10 = __commonJS({ return new FastIterableIterator(target, kind); }; } - function iteratorMixin(name, object, kInternalIterator, keyIndex = 0, valueIndex = 1) { + function iteratorMixin(name, object, kInternalIterator, keyIndex = 0, valueIndex = 1, brandCheck) { const makeIterator = createIterator(name, kInternalIterator, keyIndex, valueIndex); const properties = { keys: { @@ -34603,7 +34860,7 @@ var require_util10 = __commonJS({ enumerable: true, configurable: true, value: function keys() { - webidl.brandCheck(this, object); + webidl.brandCheck(this, brandCheck); return makeIterator(this, "key"); } }, @@ -34612,7 +34869,7 @@ var require_util10 = __commonJS({ enumerable: true, configurable: true, value: function values() { - webidl.brandCheck(this, object); + webidl.brandCheck(this, brandCheck); return makeIterator(this, "value"); } }, @@ -34621,7 +34878,7 @@ var require_util10 = __commonJS({ enumerable: true, configurable: true, value: function entries() { - webidl.brandCheck(this, object); + webidl.brandCheck(this, brandCheck); return makeIterator(this, "key+value"); } }, @@ -34630,7 +34887,7 @@ var require_util10 = __commonJS({ enumerable: true, configurable: true, value: function forEach2(callbackfn, thisArg = globalThis) { - webidl.brandCheck(this, object); + webidl.brandCheck(this, brandCheck); webidl.argumentLengthCheck(arguments, 1, `${name}.forEach`); if (typeof callbackfn !== "function") { throw new TypeError( @@ -34911,7 +35168,6 @@ var require_util10 = __commonJS({ isAborted, isCancelled, isValidEncodedURL, - ReadableStreamFrom, tryUpgradeRequestToAPotentiallyTrustworthyURL, clampAndCoarsenConnectionTimingInfo, coarsenedSharedCurrentTime, @@ -35044,7 +35300,10 @@ var require_formdata2 = __commonJS({ var nodeUtil = require("node:util"); var { runtimeFeatures } = require_runtime_features(); var random = runtimeFeatures.has("crypto") ? require("node:crypto").randomInt : (max) => Math.floor(Math.random() * max); - var FormData3 = class _FormData { + var getFormDataState; + var setFormDataState; + var getFormDataBoundary; + var FormData3 = class { #state = []; #boundary = null; constructor(form = void 0) { @@ -35058,7 +35317,7 @@ var require_formdata2 = __commonJS({ } } append(name, value, filename = void 0) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix2 = "FormData.append"; webidl.argumentLengthCheck(arguments, 2, prefix2); name = webidl.converters.USVString(name); @@ -35074,14 +35333,14 @@ var require_formdata2 = __commonJS({ this.#state.push(entry); } delete(name) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix2 = "FormData.delete"; webidl.argumentLengthCheck(arguments, 1, prefix2); name = webidl.converters.USVString(name); this.#state = this.#state.filter((entry) => entry.name !== name); } get(name) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix2 = "FormData.get"; webidl.argumentLengthCheck(arguments, 1, prefix2); name = webidl.converters.USVString(name); @@ -35092,21 +35351,21 @@ var require_formdata2 = __commonJS({ return this.#state[idx].value; } getAll(name) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix2 = "FormData.getAll"; webidl.argumentLengthCheck(arguments, 1, prefix2); name = webidl.converters.USVString(name); return this.#state.filter((entry) => entry.name === name).map((entry) => entry.value); } has(name) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix2 = "FormData.has"; webidl.argumentLengthCheck(arguments, 1, prefix2); name = webidl.converters.USVString(name); return this.#state.findIndex((entry) => entry.name === name) !== -1; } set(name, value, filename = void 0) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix2 = "FormData.set"; webidl.argumentLengthCheck(arguments, 2, prefix2); name = webidl.converters.USVString(name); @@ -35148,34 +35407,20 @@ var require_formdata2 = __commonJS({ const output = nodeUtil.formatWithOptions(options, state3); return `FormData ${output.slice(output.indexOf("]") + 2)}`; } - /** - * @param {FormData} formData - */ - static getFormDataState(formData) { - return formData.#state; - } - /** - * @param {FormData} formData - * @param {any[]} newState - */ - static setFormDataState(formData, newState) { - formData.#state = newState; - } - /** - * @param {FormData} formData - * @returns {string | null} - */ - static getFormDataBoundary(formData) { - const boundary = formData.#boundary; - if (boundary != null) return boundary; - return formData.#boundary = `----formdata-undici-0${`${random(1e11)}`.padStart(11, "0")}`; + static { + getFormDataState = (formData) => formData.#state; + setFormDataState = (formData, newState) => { + formData.#state = newState; + }; + getFormDataBoundary = (formData) => { + return formData.#boundary ??= `----formdata-undici-0${`${random(1e11)}`.padStart(11, "0")}`; + }; + webidl.is.FormData = (arg) => { + return arg != null && typeof arg === "object" && #state in arg; + }; } }; - var { getFormDataState, setFormDataState, getFormDataBoundary } = FormData3; - Reflect.deleteProperty(FormData3, "getFormDataState"); - Reflect.deleteProperty(FormData3, "setFormDataState"); - Reflect.deleteProperty(FormData3, "getFormDataBoundary"); - iteratorMixin("FormData", FormData3, getFormDataState, "name", "value"); + iteratorMixin("FormData", FormData3, getFormDataState, "name", "value", webidl.is.FormData); Object.defineProperties(FormData3.prototype, { append: kEnumerableProperty, delete: kEnumerableProperty, @@ -35204,7 +35449,6 @@ var require_formdata2 = __commonJS({ } return { name, value }; } - webidl.is.FormData = webidl.util.MakeTypeAssertion(FormData3); module2.exports = { FormData: FormData3, makeEntry, setFormDataState, getFormDataBoundary }; } }); @@ -35545,7 +35789,6 @@ var require_body2 = __commonJS({ "use strict"; var util10 = require_util9(); var { - ReadableStreamFrom, readableStreamClose, fullyReadBody, extractMimeType @@ -35665,7 +35908,14 @@ Content-Type: ${value.type || "application/octet-stream"}\r "Response body object should not be disturbed or locked" ); } - stream7 = webidl.is.ReadableStream(object) ? object : ReadableStreamFrom(object); + stream7 = webidl.is.ReadableStream(object) ? object : ReadableStream.from(object).pipeThrough(new TransformStream({ + transform(chunk, controller2) { + const bytes = isUint8Array(chunk) ? chunk : Buffer.from(chunk); + if (bytes.byteLength) { + controller2.enqueue(bytes); + } + } + })); } if (typeof source === "string" || isUint8Array(source)) { action5 = () => { @@ -35710,7 +35960,7 @@ Content-Type: ${value.type || "application/octet-stream"}\r source: body2.source }; } - function bodyMixinMethods(instance, getInternalState) { + function bodyMixinMethods(brandCheck, getInternalState) { const methods = { blob() { return consumeBody(this, (bytes) => { @@ -35721,18 +35971,18 @@ Content-Type: ${value.type || "application/octet-stream"}\r mimeType = serializeAMimeType(mimeType); } return new Blob([bytes], { type: mimeType }); - }, instance, getInternalState); + }, brandCheck, getInternalState); }, arrayBuffer() { return consumeBody(this, (bytes) => { return new Uint8Array(bytes).buffer; - }, instance, getInternalState); + }, brandCheck, getInternalState); }, text() { - return consumeBody(this, utf8DecodeBytes, instance, getInternalState); + return consumeBody(this, utf8DecodeBytes, brandCheck, getInternalState); }, json() { - return consumeBody(this, parseJSONFromBytes, instance, getInternalState); + return consumeBody(this, parseJSONFromBytes, brandCheck, getInternalState); }, formData() { return consumeBody(this, (value) => { @@ -35758,12 +36008,12 @@ Content-Type: ${value.type || "application/octet-stream"}\r throw new TypeError( 'Content-Type was not one of "multipart/form-data" or "application/x-www-form-urlencoded".' ); - }, instance, getInternalState); + }, brandCheck, getInternalState); }, bytes() { return consumeBody(this, (bytes) => { return new Uint8Array(bytes); - }, instance, getInternalState); + }, brandCheck, getInternalState); }, textStream() { const this_ = getInternalState(this); @@ -35791,12 +36041,12 @@ Content-Type: ${value.type || "application/octet-stream"}\r }; return methods; } - function mixinBody(prototype2, getInternalState) { - Object.assign(prototype2.prototype, bodyMixinMethods(prototype2, getInternalState)); + function mixinBody(prototype2, getInternalState, brandCheck) { + Object.assign(prototype2.prototype, bodyMixinMethods(brandCheck, getInternalState)); } - function consumeBody(object, convertBytesToJSValue, instance, getInternalState) { + function consumeBody(object, convertBytesToJSValue, brandCheck, getInternalState) { try { - webidl.brandCheck(object, instance); + webidl.brandCheck(object, brandCheck); } catch (e) { return Promise.reject(e); } @@ -35910,7 +36160,13 @@ var require_client_h12 = __commonJS({ function lazyllhttp() { const llhttpWasmData = process.env.JEST_WORKER_ID ? require_llhttp_wasm2() : void 0; let mod; - let useWasmSIMD = process.arch !== "ppc64"; + let useWasmSIMD = true; + if (process.arch === "ppc64") { + const [major2, minor2] = process.versions.node.split(".").map((n) => parseInt(n, 10)); + if (major2 < 24 || major2 === 24 && minor2 < 12) { + useWasmSIMD = false; + } + } if (process.env.UNDICI_NO_WASM_SIMD === "1") { useWasmSIMD = false; } else if (process.env.UNDICI_NO_WASM_SIMD === "0") { @@ -36285,7 +36541,7 @@ var require_client_h12 = __commonJS({ * @param {Buffer} head */ onUpgrade(head) { - const { upgrade, client, socket, headers, statusCode } = this; + const { upgrade, client, socket, headers, statusCode, statusText } = this; assert4(upgrade); assert4(client[kSocket] === socket); assert4(!socket.destroyed); @@ -36310,8 +36566,9 @@ var require_client_h12 = __commonJS({ client[kQueue][client[kRunningIdx]++] = null; client.emit("disconnect", client[kUrl], [client], new InformationalError("upgrade")); try { - request.onRequestUpgrade(statusCode, headers, socket); + request.onRequestUpgrade(statusCode, headers, socket, statusText); } catch (err) { + util10.errorRequest(client, request, err); util10.destroy(socket, err); } client[kResume](); @@ -36642,21 +36899,20 @@ var require_client_h12 = __commonJS({ } function clearIdleSocketValidation(socket) { if (socket[kIdleSocketValidationTimeout]) { - clearTimeout(socket[kIdleSocketValidationTimeout]); + clearImmediate(socket[kIdleSocketValidationTimeout]); socket[kIdleSocketValidationTimeout] = null; } socket[kIdleSocketValidation] = 0; } function scheduleIdleSocketValidation(client, socket) { socket[kIdleSocketValidation] = 1; - socket[kIdleSocketValidationTimeout] = setTimeout(() => { + socket[kIdleSocketValidationTimeout] = setImmediate(() => { socket[kIdleSocketValidationTimeout] = null; socket[kIdleSocketValidation] = 2; if (client[kSocket] === socket && !socket.destroyed) { client[kResume](); } - }, 0); - socket[kIdleSocketValidationTimeout].unref?.(); + }); } function resumeH1(client) { const socket = client[kSocket]; @@ -37158,12 +37414,14 @@ var require_client_h22 = __commonJS({ var util10 = require_util9(); var { RequestContentLengthMismatchError, + ResponseContentLengthMismatchError, RequestAbortedError, SocketError, InformationalError, InvalidArgumentError, HeadersTimeoutError, - BodyTimeoutError + BodyTimeoutError, + ResponseExceededMaxSizeError } = require_errors2(); var { kUrl, @@ -37192,7 +37450,8 @@ var require_client_h22 = __commonJS({ kRemoteSettings, kHTTP2Stream, kHTTP2SessionState, - kHTTP2Options + kHTTP2Options, + kMaxResponseSize } = require_symbols6(); var { channels } = require_diagnostics2(); var kOpenStreams = /* @__PURE__ */ Symbol("open streams"); @@ -37305,6 +37564,10 @@ var require_client_h22 = __commonJS({ const { body: body2 } = request; return body2 == null || util10.isBuffer(body2) || util10.isBlobLike(body2); } + function hasResponseStarted(request) { + const state3 = request[kRequestStream]?.[kRequestStreamState]; + return state3?.responseReceived === true; + } function registerGoAwayRefusal(request) { const attempts = (request[kGoAwayReplayAttempts] ?? 0) + 1; request[kGoAwayReplayAttempts] = attempts; @@ -37461,7 +37724,7 @@ var require_client_h22 = __commonJS({ const socket = client[kSocket]; const session = client[kHTTP2Session]; if (socket?.destroyed === false) { - if (client[kSize] === 0 || client[kMaxConcurrentStreams] === 0) { + if (session[kOpenStreams] === 0 && client[kSize] === 0) { unrefH2Session(session); } else { refH2Session(session); @@ -37618,8 +37881,9 @@ var require_client_h22 = __commonJS({ for (let i = pendingIdx; i < previousPendingIdx; i++) { const request = client[kQueue][i]; if (request != null) { + const responseStarted = hasResponseStarted(request); streamsToClose.push(detachRequestStreamForClose(request)); - if (canReplayRequest(request) && registerGoAwayRefusal(request)) { + if (!responseStarted && canReplayRequest(request) && registerGoAwayRefusal(request)) { retriableRequests.push(request); } else { util10.errorRequest(client, request, err); @@ -37711,9 +37975,10 @@ var require_client_h22 = __commonJS({ } function closeStreamSession(stream7) { const session = stream7[kHTTP2Session]; + const client = session[kClient]; stream7[kHTTP2Session] = null; session[kOpenStreams] -= 1; - if (session[kOpenStreams] === 0) { + if (session[kOpenStreams] === 0 && (client[kSize] === 0 || session[kReceivedGoAway])) { unrefH2Session(session); setHttp2IdleTimeout(session); } @@ -37828,8 +38093,13 @@ var require_client_h22 = __commonJS({ state3.responseReceived = true; const statusCode = headers[HTTP2_HEADER_STATUS]; delete headers[HTTP2_HEADER_STATUS]; - request.onRequestUpgrade(statusCode, headers, stream7); - if (request.aborted || request.completed) { + try { + request.onRequestUpgrade(statusCode, headers, stream7); + } catch (err) { + state3.abort(err); + return; + } + if (request.aborted) { return; } removeUpgradeStreamListeners(stream7); @@ -37896,13 +38166,16 @@ var require_client_h22 = __commonJS({ const state3 = { abort: null, body: request.body, + bytesRead: 0, client, contentLength: null, expectsPayload: false, + maxResponseSize: client[kMaxResponseSize], request, headersTimeout, bodyTimeout, requestFinalized: false, + responseContentLength: null, responseReceived: false, bodySent: false, pendingEnd: false, @@ -38037,6 +38310,7 @@ var require_client_h22 = __commonJS({ stream7.once("continue", writeBodyH2); } stream7.on("response", onResponse); + stream7.on("headers", onInterimResponse); stream7.on("end", onEnd); stream7.on("error", onError); stream7.on("frameError", onFrameError); @@ -38054,6 +38328,7 @@ var require_client_h22 = __commonJS({ stream7.off("error", noop2); stream7.off("continue", writeBodyH2); stream7.off("response", onResponse); + stream7.off("headers", onInterimResponse); stream7.off("end", onEnd); stream7.off("error", onError); stream7.off("frameError", onFrameError); @@ -38085,14 +38360,37 @@ var require_client_h22 = __commonJS({ if (state3 == null) { return; } - const { request } = state3; + const { request, maxResponseSize, responseContentLength } = state3; if (request.aborted || request.completed) { return; } + if (responseContentLength != null && state3.bytesRead + chunk.length > responseContentLength) { + state3.abort(new ResponseContentLengthMismatchError()); + return; + } + if (maxResponseSize > -1 && state3.bytesRead + chunk.length > maxResponseSize) { + state3.abort(new ResponseExceededMaxSizeError()); + return; + } + state3.bytesRead += chunk.length; if (request.onResponseData(chunk) === false) { stream7.pause(); } } + function onInterimResponse(headers) { + const stream7 = this; + const state3 = stream7[kRequestStreamState]; + if (state3 == null) { + return; + } + const { request } = state3; + if (request.aborted || request.completed) { + return; + } + const statusCode = headers[HTTP2_HEADER_STATUS]; + delete headers[HTTP2_HEADER_STATUS]; + request.onResponseStart(Number(statusCode), headers, noop2, ""); + } function onResponse(headers) { const stream7 = this; const state3 = stream7[kRequestStreamState]; @@ -38105,10 +38403,14 @@ var require_client_h22 = __commonJS({ stream7.removeListener("continue", writeBodyH2); stream7.end(); } - const statusCode = headers[HTTP2_HEADER_STATUS]; + const statusCode = Number(headers[HTTP2_HEADER_STATUS]); delete headers[HTTP2_HEADER_STATUS]; request.onResponseStarted(); state3.responseReceived = true; + if (request.method !== "HEAD" && statusCode !== 304) { + const contentLength2 = headers[HTTP2_HEADER_CONTENT_LENGTH]; + state3.responseContentLength = contentLength2 == null ? null : Number(contentLength2); + } if (state3.headersTimeout || state3.bodyTimeout) { stream7.setTimeout(state3.bodyTimeout); } @@ -38116,7 +38418,7 @@ var require_client_h22 = __commonJS({ releaseRequestStream(stream7); return; } - if (request.onResponseStart(Number(statusCode), headers, stream7.resume.bind(stream7), "") === false) { + if (request.onResponseStart(statusCode, headers, stream7.resume.bind(stream7), "") === false) { stream7.pause(); } stream7.on("data", onData); @@ -38131,6 +38433,10 @@ var require_client_h22 = __commonJS({ stream7.off("end", onEnd); if (state3.responseReceived) { if (!request.aborted && !request.completed) { + if (state3.responseContentLength != null && state3.bytesRead !== state3.responseContentLength) { + state3.abort(new ResponseContentLengthMismatchError()); + return; + } state3.pendingEnd = true; completeRequestStream.call(stream7); } @@ -38159,6 +38465,9 @@ var require_client_h22 = __commonJS({ return; } stream7.off("error", onError); + if (state3.responseContentLength != null && state3.bytesRead !== state3.responseContentLength) { + err = new ResponseContentLengthMismatchError(); + } if (typeof stream7.rstCode === "number" && stream7.rstCode !== NGHTTP2_NO_ERROR) { err.http2ErrorCode = stream7.rstCode; } @@ -38512,7 +38821,8 @@ var require_client2 = __commonJS({ connectionWindowSize, pingInterval, webSocket, - h2Options + h2Options, + eventSource } = {}) { if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); @@ -38583,7 +38893,7 @@ var require_client2 = __commonJS({ if (h2Options.settings?.initialWindowSize != null && (!Number.isInteger(h2Options.settings.initialWindowSize) || h2Options.settings.initialWindowSize < 1)) { throw new InvalidArgumentError("h2Options.settings.initialWindowSize must be a positive integer, greater than 0"); } - if (h2Options.maxConcurrentStreams != null && (!Number.isInteger(h2Options.connectionWindowSize) || h2Options.maxConcurrentStreams < 1)) { + if (h2Options.maxConcurrentStreams != null && (!Number.isInteger(h2Options.maxConcurrentStreams) || h2Options.maxConcurrentStreams < 1)) { throw new InvalidArgumentError("h2Options.maxConcurrentStreams must be a positive integer, greater than 0"); } if (h2Options.connectionWindowSize != null && (!Number.isInteger(h2Options.connectionWindowSize) || h2Options.connectionWindowSize < 1)) { @@ -38615,7 +38925,7 @@ var require_client2 = __commonJS({ } } } - super({ webSocket }); + super({ webSocket, eventSource }); if (typeof connect2 !== "function") { connect2 = buildConnector({ ...tls, @@ -38942,6 +39252,10 @@ var require_client2 = __commonJS({ if (request === null) { return; } + if (request.aborted) { + client[kQueue].splice(client[kPendingIdx], 1); + continue; + } if (client[kUrl].protocol === "https:" && client[kServerName] !== request.servername) { if (client[kRunning] > 0) { return; @@ -39064,6 +39378,9 @@ var require_pool_base2 = __commonJS({ var kOnConnect = /* @__PURE__ */ Symbol("onConnect"); var kOnDisconnect = /* @__PURE__ */ Symbol("onDisconnect"); var kOnConnectionError = /* @__PURE__ */ Symbol("onConnectionError"); + var kOnClientBusy = /* @__PURE__ */ Symbol("on client busy"); + var kOnClientDrain = /* @__PURE__ */ Symbol("on client drain"); + var kDrainQueue = /* @__PURE__ */ Symbol("drain queue"); var kGetDispatcher = /* @__PURE__ */ Symbol("get dispatcher"); var kHasDispatcher = /* @__PURE__ */ Symbol("has dispatcher"); var kAddClient = /* @__PURE__ */ Symbol("add client"); @@ -39074,8 +39391,12 @@ var require_pool_base2 = __commonJS({ [kClients] = []; [kNeedDrain] = false; [kOnDrain](client, origin2, targets) { + if (client.closed || client.destroyed) { + return; + } const queue = this[kQueue]; let needDrain = false; + this[kOnClientDrain](client); while (!needDrain) { const item = queue.shift(); if (!item) { @@ -39085,6 +39406,9 @@ var require_pool_base2 = __commonJS({ needDrain = !client.dispatch(item.opts, item.handler); } client[kNeedDrain] = needDrain; + if (needDrain) { + this[kOnClientBusy](client); + } if (!needDrain && this[kNeedDrain]) { this[kNeedDrain] = false; this.emit("drain", origin2, [this, ...targets]); @@ -39100,6 +39424,45 @@ var require_pool_base2 = __commonJS({ return Promise.all(closeAll).then(this[kClosedResolve]); } } + [kOnClientBusy]() { + } + [kOnClientDrain]() { + } + [kDrainQueue](origin2, targets) { + const queue = this[kQueue]; + let hasDispatcher = true; + while (!queue.isEmpty()) { + const dispatcher = this[kGetDispatcher](); + if (!dispatcher) { + hasDispatcher = false; + break; + } + const item = queue.shift(); + this[kQueued]--; + if (!dispatcher.dispatch(item.opts, item.handler)) { + dispatcher[kNeedDrain] = true; + this[kOnClientBusy](dispatcher); + hasDispatcher = this[kHasDispatcher](); + if (!hasDispatcher) { + break; + } + } + } + if (hasDispatcher && this[kNeedDrain]) { + this[kNeedDrain] = false; + this.emit("drain", origin2, [this, ...targets]); + } + if (this[kClosedResolve] && queue.isEmpty()) { + const closeAll = []; + for (let i = 0; i < this[kClients].length; i++) { + const client = this[kClients][i]; + if (!client.destroyed) { + closeAll.push(client.close()); + } + } + return Promise.all(closeAll).then(this[kClosedResolve]); + } + } [kOnConnect] = (origin2, targets) => { this.emit("connect", origin2, [this, ...targets]); }; @@ -39188,6 +39551,7 @@ var require_pool_base2 = __commonJS({ this[kQueued]++; } else if (!dispatcher.dispatch(opts, handler)) { dispatcher[kNeedDrain] = true; + this[kOnClientBusy](dispatcher); this[kNeedDrain] = !this[kHasDispatcher](); } return !this[kNeedDrain]; @@ -39206,7 +39570,7 @@ var require_pool_base2 = __commonJS({ this[kClients].push(client); if (this[kNeedDrain]) { queueMicrotask(() => { - if (this[kNeedDrain]) { + if (this[kNeedDrain] && !client[kNeedDrain]) { this[kOnDrain](client, client[kUrl], [client, this]); } }); @@ -39229,6 +39593,9 @@ var require_pool_base2 = __commonJS({ kNeedDrain, kAddClient, kRemoveClient, + kDrainQueue, + kOnClientBusy, + kOnClientDrain, kGetDispatcher, kHasDispatcher }; @@ -39244,6 +39611,9 @@ var require_pool2 = __commonJS({ kClients, kNeedDrain, kAddClient, + kDrainQueue, + kOnClientBusy, + kOnClientDrain, kGetDispatcher, kHasDispatcher, kRemoveClient @@ -39253,14 +39623,27 @@ var require_pool2 = __commonJS({ InvalidArgumentError } = require_errors2(); var util10 = require_util9(); - var { kUrl } = require_symbols6(); + var { kConnecting, kHTTPContext, kUrl } = require_symbols6(); var buildConnector = require_connect2(); var kOptions = /* @__PURE__ */ Symbol("options"); var kConnections = /* @__PURE__ */ Symbol("connections"); var kFactory = /* @__PURE__ */ Symbol("factory"); + var kProtocol = /* @__PURE__ */ Symbol("protocol"); + var kProtocolProbe = /* @__PURE__ */ Symbol("protocol probe"); function defaultFactory(origin2, opts) { return new Client(origin2, opts); } + function shouldCreateProtocolProbe(pool, dispatcher) { + return dispatcher instanceof Client && pool[kProtocol] !== "h1" && (pool[kOptions].useH2c === true || pool[kUrl].protocol === "https:" && pool[kOptions].allowH2 !== false); + } + function createClient(pool) { + const dispatcher = pool[kFactory](pool[kUrl], pool[kOptions]); + if (shouldCreateProtocolProbe(pool, dispatcher)) { + pool[kProtocolProbe] = dispatcher; + } + pool[kAddClient](dispatcher); + return dispatcher; + } var Pool = class extends PoolBase { constructor(origin2, { connections, @@ -39303,22 +39686,58 @@ var require_pool2 = __commonJS({ this[kUrl] = util10.parseOrigin(origin2); this[kOptions] = { ...util10.deepClone(options), connect, allowH2, useH2c, clientTtl, socketPath }; this[kFactory] = factory2; + this[kProtocol] = null; + this[kProtocolProbe] = null; this.on("connect", (origin3, targets) => { if (clientTtl != null && clientTtl > 0) { for (const target of targets) { Object.assign(target, { ttl: Date.now() }); } } + const client = targets[targets.length - 1]; + if (client instanceof Client) { + this[kProtocol] = client[kHTTPContext]?.version; + } + if (client === this[kProtocolProbe]) { + if (this[kProtocol] !== "h2") { + this[kProtocolProbe] = null; + this[kDrainQueue](origin3, targets.slice(1)); + } + } }); - this.on("connectionError", (origin3, targets, error2) => { + this.on("disconnect", (origin3, targets) => { + if (targets.includes(this[kProtocolProbe])) { + this[kProtocolProbe] = null; + this[kDrainQueue](origin3, targets.slice(1)); + } + }); + this.on("connectionError", (origin3, targets) => { + let resumeQueued = false; for (const target of targets) { + if (target === this[kProtocolProbe]) { + this[kProtocolProbe] = null; + resumeQueued = true; + } const idx = this[kClients].indexOf(target); if (idx !== -1) { this[kClients].splice(idx, 1); } } + if (resumeQueued) { + this[kDrainQueue](origin3, targets.slice(1)); + } }); } + [kOnClientBusy](client) { + if (this[kProtocolProbe] === null && client[kConnecting] && shouldCreateProtocolProbe(this, client)) { + this[kProtocolProbe] = client; + } + } + [kOnClientDrain](client) { + if (client === this[kProtocolProbe]) { + this[kProtocolProbe] = null; + } + } [kGetDispatcher]() { const clientTtlOption = this[kOptions].clientTtl; for (let i = 0; i < this[kClients].length; i++) { @@ -39330,10 +39749,11 @@ var require_pool2 = __commonJS({ return client; } } + if (this[kProtocolProbe] !== null) { + return; + } if (!this[kConnections] || this[kClients].length < this[kConnections]) { - const dispatcher = this[kFactory](this[kUrl], this[kOptions]); - this[kAddClient](dispatcher); - return dispatcher; + return createClient(this); } } [kHasDispatcher]() { @@ -39347,9 +39767,11 @@ var require_pool2 = __commonJS({ return true; } } + if (this[kProtocolProbe] !== null) { + return false; + } if (!this[kConnections] || this[kClients].length < this[kConnections]) { - const dispatcher = this[kFactory](this[kUrl], this[kOptions]); - this[kAddClient](dispatcher); + createClient(this); return true; } return false; @@ -39376,7 +39798,7 @@ var require_balanced_pool2 = __commonJS({ kGetDispatcher } = require_pool_base2(); var Pool = require_pool2(); - var { kUrl } = require_symbols6(); + var { kOriginless, kUrl } = require_symbols6(); var util10 = require_util9(); var kFactory = /* @__PURE__ */ Symbol("factory"); var kOptions = /* @__PURE__ */ Symbol("options"); @@ -39399,12 +39821,15 @@ var require_balanced_pool2 = __commonJS({ return new Pool(origin2, opts); } var BalancedPool = class extends PoolBase { - constructor(upstreams = [], { factory: factory2 = defaultFactory, ...opts } = {}) { + constructor(upstreams = [], { factory: factory2 = defaultFactory, connect, tls, ...opts } = {}) { if (typeof factory2 !== "function") { throw new InvalidArgumentError("factory must be a function."); } - super(); - this[kOptions] = { ...util10.deepClone(opts) }; + super(opts); + this[kOriginless] = true; + if (connect && typeof connect !== "function") connect = { ...connect }; + if (tls && typeof tls !== "function") tls = { ...tls }; + this[kOptions] = { ...util10.deepClone(opts), connect, tls }; this[kIndex] = -1; this[kCurrentWeight] = 0; this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100; @@ -39566,7 +39991,7 @@ var require_round_robin_pool = __commonJS({ ...connect }); } - super(); + super(options); this[kConnections] = connections || null; this[kUrl] = util10.parseOrigin(origin2); this[kOptions] = { ...util10.deepClone(options), connect, allowH2, clientTtl, socketPath }; @@ -39646,7 +40071,7 @@ var require_agent2 = __commonJS({ "node_modules/undici/lib/dispatcher/agent.js"(exports2, module2) { "use strict"; var { InvalidArgumentError, MaxOriginsReachedError } = require_errors2(); - var { kBusy, kClients, kConnected, kRunning, kClose, kDestroy, kDispatch, kUrl } = require_symbols6(); + var { kBusy, kClients, kConnected, kRunning, kPending, kClose, kDestroy, kDispatch, kUrl } = require_symbols6(); var DispatcherBase = require_dispatcher_base2(); var Pool = require_pool2(); var Client = require_client2(); @@ -39719,7 +40144,7 @@ var require_agent2 = __commonJS({ if (this[kClients].get(key) !== dispatcher) { return; } - if (dispatcher[kConnected] > 0 || dispatcher[kBusy]) { + if (dispatcher[kConnected] > 0 || dispatcher[kBusy] || dispatcher[kPending] > 0) { return; } this[kClients].delete(key); @@ -39786,6 +40211,7 @@ var require_dispatcher1_wrapper = __commonJS({ var Dispatcher = require_dispatcher2(); var { InvalidArgumentError } = require_errors2(); var { toRawHeaders } = require_util9(); + var { kOriginless, kUrl } = require_symbols6(); var LegacyHandlerWrapper = class { #handler; constructor(handler) { @@ -39837,6 +40263,8 @@ var require_dispatcher1_wrapper = __commonJS({ throw new InvalidArgumentError("Argument dispatcher must implement dispatch"); } this.#dispatcher = dispatcher; + this[kUrl] = dispatcher[kUrl]; + this[kOriginless] = dispatcher[kOriginless]; } static wrapHandler(handler) { if (!handler || typeof handler !== "object") { @@ -40365,24 +40793,33 @@ var require_socks5_proxy_agent = __commonJS({ var { URL: URL3 } = require("node:url"); var tls; var DispatcherBase = require_dispatcher_base2(); - var { InvalidArgumentError } = require_errors2(); + var { ConnectTimeoutError, InvalidArgumentError } = require_errors2(); var { Socks5Client, STATES } = require_socks5_client(); var { kBusy, kConnected, kDispatch, kClose, kDestroy } = require_symbols6(); var Pool = require_pool2(); var buildConnector = require_connect2(); + var { setupConnectTimeout } = require_util9(); var { debuglog } = require("node:util"); var debug3 = debuglog("undici:socks5-proxy"); + var DEFAULT_SOCKS5_CONNECT_TIMEOUT = 5e3; var kProxyUrl = /* @__PURE__ */ Symbol("proxy url"); var kProxyHeaders = /* @__PURE__ */ Symbol("proxy headers"); var kProxyAuth = /* @__PURE__ */ Symbol("proxy auth"); var kProxyProtocol = /* @__PURE__ */ Symbol("proxy protocol"); var kPools = /* @__PURE__ */ Symbol("pools"); var kConnector = /* @__PURE__ */ Symbol("connector"); + var kConnectTimeout = /* @__PURE__ */ Symbol("connect timeout"); var kRequestTls = /* @__PURE__ */ Symbol("request tls settings"); + var kRequestTlsTimeout = /* @__PURE__ */ Symbol("request tls timeout"); + function createConnectTimeoutError(hostname, port, timeout) { + return new ConnectTimeoutError( + `Connect Timeout Error (attempted address: ${hostname}:${port}, timeout: ${timeout}ms)` + ); + } var experimentalWarningEmitted = false; var Socks5ProxyAgent = class extends DispatcherBase { constructor(proxyUrl, options = {}) { - super(); + super(options); if (!experimentalWarningEmitted) { process.emitWarning( "SOCKS5 proxy support is experimental and subject to change", @@ -40400,13 +40837,29 @@ var require_socks5_proxy_agent = __commonJS({ this[kProxyUrl] = url3; this[kProxyHeaders] = options.headers || {}; this[kProxyProtocol] = options.proxyTls ? "https:" : "http:"; - this[kRequestTls] = options.requestTls; + const connectTimeout = options.connectTimeout ?? DEFAULT_SOCKS5_CONNECT_TIMEOUT; + if (!Number.isFinite(connectTimeout) || connectTimeout < 0) { + throw new InvalidArgumentError("invalid connectTimeout"); + } + this[kConnectTimeout] = connectTimeout; + const { timeout, ...requestTls } = options.requestTls || {}; + const requestTlsTimeout = timeout ?? connectTimeout; + if (!Number.isFinite(requestTlsTimeout) || requestTlsTimeout < 0) { + throw new InvalidArgumentError("invalid requestTls.timeout"); + } + this[kRequestTls] = requestTls; + this[kRequestTlsTimeout] = requestTlsTimeout; this[kProxyAuth] = { username: options.username || (url3.username ? decodeURIComponent(url3.username) : null), password: options.password || (url3.password ? decodeURIComponent(url3.password) : null) }; + const proxyTlsTimeout = options.proxyTls?.timeout ?? connectTimeout; + if (!Number.isFinite(proxyTlsTimeout) || proxyTlsTimeout < 0) { + throw new InvalidArgumentError("invalid proxyTls.timeout"); + } this[kConnector] = options.connect || buildConnector({ ...options.proxyTls, + timeout: proxyTlsTimeout, servername: options.proxyTls?.servername || url3.hostname }); this[kPools] = /* @__PURE__ */ new Map(); @@ -40439,17 +40892,24 @@ var require_socks5_proxy_agent = __commonJS({ }); await socks5Client.handshake(); const authenticationReady = Promise.withResolvers(); - const authenticationTimeout = setTimeout(() => { - authenticationReady.reject(new Error("SOCKS5 authentication timeout")); - }, 5e3); - const onAuthenticated = () => { + const authenticationTimeout = this[kConnectTimeout] === 0 ? null : setTimeout(() => { + cleanupAuthenticationListeners(); + socks5Client.destroy(); + authenticationReady.reject( + createConnectTimeoutError(proxyHost, proxyPort, this[kConnectTimeout]) + ); + }, this[kConnectTimeout]); + const cleanupAuthenticationListeners = () => { clearTimeout(authenticationTimeout); + socks5Client.removeListener("authenticated", onAuthenticated); socks5Client.removeListener("error", onAuthenticationError); + }; + const onAuthenticated = () => { + cleanupAuthenticationListeners(); authenticationReady.resolve(); }; const onAuthenticationError = (err) => { - clearTimeout(authenticationTimeout); - socks5Client.removeListener("authenticated", onAuthenticated); + cleanupAuthenticationListeners(); authenticationReady.reject(err); }; if (socks5Client.state === STATES.AUTHENTICATED) { @@ -40462,18 +40922,25 @@ var require_socks5_proxy_agent = __commonJS({ await authenticationReady.promise; await socks5Client.connect(targetHost, targetPort); const connectionReady = Promise.withResolvers(); - const connectionTimeout = setTimeout(() => { - connectionReady.reject(new Error("SOCKS5 connection timeout")); - }, 5e3); - const onConnected = (info3) => { - debug3("SOCKS5 tunnel established to", targetHost, targetPort, "via", info3); + const connectionTimeout = this[kConnectTimeout] === 0 ? null : setTimeout(() => { + cleanupConnectionListeners(); + socks5Client.destroy(); + connectionReady.reject( + createConnectTimeoutError(targetHost, targetPort, this[kConnectTimeout]) + ); + }, this[kConnectTimeout]); + const cleanupConnectionListeners = () => { clearTimeout(connectionTimeout); + socks5Client.removeListener("connected", onConnected); socks5Client.removeListener("error", onConnectionError); + }; + const onConnected = (info3) => { + debug3("SOCKS5 tunnel established to", targetHost, targetPort, "via", info3); + cleanupConnectionListeners(); connectionReady.resolve(); }; const onConnectionError = (err) => { - clearTimeout(connectionTimeout); - socks5Client.removeListener("connected", onConnected); + cleanupConnectionListeners(); connectionReady.reject(err); }; socks5Client.once("connected", onConnected); @@ -40513,8 +40980,26 @@ var require_socks5_proxy_agent = __commonJS({ servername: this[kRequestTls]?.servername || targetHost }); const tlsReady = Promise.withResolvers(); - finalSocket.once("secureConnect", tlsReady.resolve); - finalSocket.once("error", tlsReady.reject); + const cleanupTlsListeners = () => { + queueMicrotask(clearTlsTimeout); + finalSocket.removeListener("secureConnect", onSecureConnect); + finalSocket.removeListener("error", onTlsError); + }; + const onSecureConnect = () => { + cleanupTlsListeners(); + tlsReady.resolve(); + }; + const onTlsError = (err) => { + cleanupTlsListeners(); + tlsReady.reject(err); + }; + const clearTlsTimeout = setupConnectTimeout(new WeakRef(finalSocket), { + timeout: this[kRequestTlsTimeout], + hostname: targetHost, + port: targetPort + }); + finalSocket.once("secureConnect", onSecureConnect); + finalSocket.once("error", onTlsError); await tlsReady.promise; } callback(null, finalSocket); @@ -40585,6 +41070,7 @@ var require_proxy_agent2 = __commonJS({ var Client = require_client2(); var { channels } = require_diagnostics2(); var Socks5ProxyAgent = require_socks5_proxy_agent(); + var { hasSafeIterator } = require_util9(); var kAgent = /* @__PURE__ */ Symbol("proxy agent"); var kClient = /* @__PURE__ */ Symbol("proxy client"); var kProxyHeaders = /* @__PURE__ */ Symbol("proxy headers"); @@ -40671,7 +41157,7 @@ var require_proxy_agent2 = __commonJS({ throw new InvalidArgumentError("Proxy opts.clientFactory must be a function."); } const { proxyTunnel, connectTimeout } = opts; - super(); + super(opts); const url3 = this.#getUrl(opts); const { href, origin: origin2, port, protocol, username, password, hostname: proxyHostname } = url3; this[kProxy] = { uri: href, protocol }; @@ -40704,6 +41190,7 @@ var require_proxy_agent2 = __commonJS({ factory: agentFactory, username: opts.username || username, password: opts.password || password, + connectTimeout, proxyTls: opts.proxyTls, requestTls: opts.requestTls }); @@ -40845,6 +41332,25 @@ var require_proxy_agent2 = __commonJS({ } return headersPair; } + if (headers && typeof headers === "object" && hasSafeIterator(headers)) { + const headersPair = {}; + for (const [key, value] of headers) { + if (!Object.hasOwn(headersPair, key)) { + headersPair[key] = value; + continue; + } + const previous = headersPair[key]; + const values = []; + if (previous !== void 0) { + values.push(...Array.isArray(previous) ? previous : [previous]); + } + if (value !== void 0) { + values.push(...Array.isArray(value) ? value : [value]); + } + headersPair[key] = values.length > 1 ? values : values[0]; + } + return headersPair; + } return headers; } function throwIfProxyAuthIsSent(headers) { @@ -40881,7 +41387,7 @@ var require_env_http_proxy_agent2 = __commonJS({ #noProxyEntries = null; #opts = null; constructor(opts = {}) { - super(); + super(opts); this.#opts = opts; const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts; this[kNoProxyAgent] = new Agent3(agentOpts); @@ -40921,6 +41427,9 @@ var require_env_http_proxy_agent2 = __commonJS({ #getProxyAgentForUrl(url3) { let { protocol, host: hostname, port } = url3; hostname = hostname.replace(/:\d*$/, "").replace(/^\[(.+)\]$/, "$1").toLowerCase(); + if (hostname.length > 1 && hostname.charCodeAt(hostname.length - 1) === 46) { + hostname = hostname.slice(0, -1); + } port = Number.parseInt(port, 10) || DEFAULT_PORTS3[protocol] || 0; if (!this.#shouldProxy(hostname, port)) { return this[kNoProxyAgent]; @@ -40937,15 +41446,18 @@ var require_env_http_proxy_agent2 = __commonJS({ if (this.#noProxyEntries.length === 0) { return true; } - if (this.#noProxyValue === "*") { - return false; - } for (let i = 0; i < this.#noProxyEntries.length; i++) { const entry = this.#noProxyEntries[i]; + if (entry.hostname === "*") { + if (entry.port && entry.port !== port) { + continue; + } + return false; + } if (entry.port && entry.port !== port) { continue; } - if (hostname === entry.hostname) { + if (!entry.wildcard && hostname === entry.hostname) { return false; } if (hostname.slice(-(entry.hostname.length + 1)) === `.${entry.hostname}`) { @@ -40975,10 +41487,12 @@ var require_env_http_proxy_agent2 = __commonJS({ hostname = parsed ? parsed[1] : unbracketed; port = parsed ? Number.parseInt(parsed[2], 10) : 0; } + const wildcard = entry.charCodeAt(0) === 42; noProxyEntries.push({ - // strip leading dot or asterisk with dot - hostname: hostname.replace(/^\*?\./, "").toLowerCase(), - port + // strip leading dot or asterisk with dot, and any trailing dot + hostname: hostname.replace(/^\*?\./, "").replace(/^(.+)\.$/, "$1").toLowerCase(), + port, + wildcard }); } this.#noProxyValue = noProxyValue; @@ -41004,7 +41518,7 @@ var require_retry_handler2 = __commonJS({ "use strict"; var assert4 = require("node:assert"); var { kRetryHandlerDefaultRetry } = require_symbols6(); - var { RequestRetryError } = require_errors2(); + var { RequestRetryError, RequestAbortedError } = require_errors2(); var { isDisturbed, parseRangeHeader, @@ -41032,32 +41546,57 @@ var require_retry_handler2 = __commonJS({ } } var RetryController = class { - constructor() { - this.target = null; + #onAbort; + #paused = false; + #target = null; + constructor(onAbort) { + this.#onAbort = onAbort; + } + set target(target) { + this.#target = target; + if (this.#paused) { + target?.pause(); + } + } + get target() { + return this.#target; } pause() { - this.target?.pause(); + this.#paused = true; + this.#target?.pause(); } resume() { - this.target?.resume(); + this.#paused = false; + this.#target?.resume(); } abort(reason) { - this.target?.abort(reason); + this.#target?.abort(reason); + this.#onAbort(reason); } get paused() { - return this.target?.paused ?? false; + return this.#paused || (this.#target?.paused ?? false); } get aborted() { - return this.target?.aborted ?? false; + return this.#target?.aborted ?? false; } get reason() { - return this.target?.reason ?? null; + return this.#target?.reason ?? null; } get rawHeaders() { - return this.target?.rawHeaders ?? null; + return this.#target?.rawHeaders ?? null; + } + set rawHeaders(value) { + if (this.#target) { + this.#target.rawHeaders = value; + } } get rawTrailers() { - return this.target?.rawTrailers ?? null; + return this.#target?.rawTrailers ?? null; + } + set rawTrailers(value) { + if (this.#target) { + this.#target.rawTrailers = value; + } } }; var RetryHandler = class _RetryHandler { @@ -41116,13 +41655,24 @@ var require_retry_handler2 = __commonJS({ this.etag = null; this.statusCode = null; this.headers = null; - this.controllerProxy = new RetryController(); + this.controllerProxy = new RetryController((reason) => this.#onAbort(reason)); + this.retryPending = false; + this.retryTimer = null; + this.pendingResponseData = null; + this.pendingResponseTrailers = null; + this.pendingResponseEnded = false; + this.aborted = false; } onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err) { if (this.retryOpts.throwOnError) { if (this.retryOpts.statusCodes.includes(statusCode) === false) { - this.headersSent = true; - this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); + if (this.headersSent) { + this.handler.onResponseError?.(this.controllerProxy, err); + } else { + this.headersSent = true; + this.checkpointResponseEnd(headers); + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); + } } else { this.error = err; } @@ -41130,28 +41680,71 @@ var require_retry_handler2 = __commonJS({ } if (isDisturbed(this.opts.body)) { this.headersSent = true; + this.checkpointResponseEnd(headers); this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); return; } function shouldRetry(passedErr) { + if (this.aborted) { + return; + } + this.retryPending = false; + this.retryTimer = null; + const pendingData = this.pendingResponseData; + const pendingTrailers = this.pendingResponseTrailers; + const pendingEnd = this.pendingResponseEnded; + this.pendingResponseData = null; + this.pendingResponseTrailers = null; + this.pendingResponseEnded = false; if (passedErr) { - this.headersSent = true; - this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); + if (this.headersSent) { + this.handler.onResponseError?.(this.controllerProxy, passedErr); + } else { + this.headersSent = true; + this.checkpointResponseEnd(headers); + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); + controller.resume(); + if (pendingEnd) { + for (const chunk of pendingData) { + this.onResponseData(controller, chunk); + } + this.onResponseEnd(controller, pendingTrailers); + } + return; + } controller.resume(); return; } this.error = err; controller.resume(); + if (pendingEnd) { + this.onResponseEnd(controller, pendingTrailers); + } } controller.pause(); - this.retryOpts.retry( + this.retryPending = true; + this.pendingResponseData = []; + this.pendingResponseTrailers = null; + this.pendingResponseEnded = false; + this.retryTimer = this.retryOpts.retry( err, { state: { counter: this.retryCount }, opts: { retryOptions: this.retryOpts, ...this.opts } }, shouldRetry.bind(this) - ); + ) ?? null; + } + checkpointResponseEnd(headers) { + if (this.end == null && this.opts.method !== "HEAD") { + const contentLength2 = headers["content-length"]; + this.end = contentLength2 != null ? Number(contentLength2) - 1 : null; + assert4( + this.end == null || Number.isFinite(this.end), + "invalid content-length" + ); + this.resume = this.end != null; + } } onRequestStart(controller, context3) { this.controllerProxy.target = controller; @@ -41159,6 +41752,12 @@ var require_retry_handler2 = __commonJS({ this.handler.onRequestStart?.(this.controllerProxy, context3); } } + onBodySent(chunk) { + this.handler.onBodySent?.(chunk); + } + onRequestSent() { + this.handler.onRequestSent?.(); + } onRequestUpgrade(_controller, statusCode, headers, socket) { this.handler.onRequestUpgrade?.(this.controllerProxy, statusCode, headers, socket); } @@ -41172,7 +41771,8 @@ var require_retry_handler2 = __commonJS({ timeoutFactor, statusCodes, errorCodes, - methods + methods, + retryAfter } = retryOptions; const { counter } = state3; if (code && code !== "UND_ERR_REQ_RETRY" && !errorCodes.includes(code)) { @@ -41191,13 +41791,13 @@ var require_retry_handler2 = __commonJS({ cb(err); return; } - let retryAfterHeader = headers?.["retry-after"]; + let retryAfterHeader = retryAfter === false ? void 0 : headers?.["retry-after"]; if (retryAfterHeader) { retryAfterHeader = Number(retryAfterHeader); retryAfterHeader = Number.isNaN(retryAfterHeader) ? calculateRetryAfterHeader(headers["retry-after"]) : retryAfterHeader * 1e3; } const retryTimeout = retryAfterHeader === 0 ? 0 : retryAfterHeader > 0 ? Math.min(retryAfterHeader, maxTimeout) : Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout); - setTimeout(() => cb(null), retryTimeout); + return setTimeout(() => cb(null), retryTimeout); } onResponseStart(controller, statusCode, headers, statusMessage) { if (statusCode < 200) { @@ -41208,16 +41808,6 @@ var require_retry_handler2 = __commonJS({ this.retryCount += 1; this.statusCode = statusCode; this.headers = headers; - if (statusCode >= 300) { - const err = new RequestRetryError("Request failed", statusCode, { - headers, - data: { - count: this.retryCount - } - }); - this.onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err); - return; - } if (this.headersSent) { if (statusCode !== 206 && (this.start > 0 || statusCode !== 200)) { throw new RequestRetryError("server does not support the range header and the payload was partially consumed", statusCode, { @@ -41240,8 +41830,22 @@ var require_retry_handler2 = __commonJS({ } validatePartialResponseContentLength(headers, contentRange, statusCode, this.retryCount); const { start, size, end = size ? size - 1 : null } = contentRange; - assert4(this.start === start, "content-range mismatch"); - assert4(this.end == null || this.end === end, "content-range mismatch"); + if (this.start !== start || this.end != null && this.end !== end) { + throw new RequestRetryError("Content-Range mismatch", statusCode, { + headers, + data: { count: this.retryCount } + }); + } + return; + } + if (statusCode >= 300) { + const err = new RequestRetryError("Request failed", statusCode, { + headers, + data: { + count: this.retryCount + } + }); + this.onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err); return; } if (this.end == null) { @@ -41296,6 +41900,10 @@ var require_retry_handler2 = __commonJS({ } } onResponseData(_controller, chunk) { + if (this.pendingResponseData !== null) { + this.pendingResponseData.push(chunk); + return; + } if (this.error) { return; } @@ -41303,6 +41911,11 @@ var require_retry_handler2 = __commonJS({ this.handler.onResponseData?.(this.controllerProxy, chunk); } onResponseEnd(_controller, trailers) { + if (this.pendingResponseData !== null) { + this.pendingResponseTrailers = trailers; + this.pendingResponseEnded = true; + return; + } if (this.error && this.retryOpts.throwOnError) { throw this.error; } @@ -41342,11 +41955,19 @@ var require_retry_handler2 = __commonJS({ } } onResponseError(controller, err) { - if (controller?.aborted || isDisturbed(this.opts.body)) { + if (this.aborted) { + return; + } + if (controller?.aborted || isDisturbed(this.opts.body) || this.headersSent && !this.resume) { this.handler.onResponseError?.(this.controllerProxy, err); return; } function shouldRetry(returnedErr) { + if (this.aborted) { + return; + } + this.retryPending = false; + this.retryTimer = null; if (!returnedErr) { this.retry(); return; @@ -41358,14 +41979,28 @@ var require_retry_handler2 = __commonJS({ } else { this.retryCount += 1; } - this.retryOpts.retry( + this.retryPending = true; + this.retryTimer = this.retryOpts.retry( err, { state: { counter: this.retryCount }, opts: { retryOptions: this.retryOpts, ...this.opts } }, shouldRetry.bind(this) - ); + ) ?? null; + } + #onAbort(reason) { + if (!this.retryPending) { + return; + } + this.aborted = true; + this.retryPending = false; + clearTimeout(this.retryTimer); + this.retryTimer = null; + this.pendingResponseData = null; + this.pendingResponseTrailers = null; + this.pendingResponseEnded = false; + this.handler.onResponseError?.(this.controllerProxy, reason ?? new RequestAbortedError()); } }; module2.exports = RetryHandler; @@ -41378,6 +42013,7 @@ var require_retry_agent2 = __commonJS({ "use strict"; var Dispatcher = require_dispatcher2(); var RetryHandler = require_retry_handler2(); + var { kOriginless, kUrl } = require_symbols6(); var RetryAgent = class extends Dispatcher { #agent = null; #options = null; @@ -41385,6 +42021,8 @@ var require_retry_agent2 = __commonJS({ super(options); this.#agent = agent; this.#options = options; + this[kUrl] = agent[kUrl]; + this[kOriginless] = agent[kOriginless]; } dispatch(opts, handler) { const retry2 = new RetryHandler({ @@ -41459,7 +42097,6 @@ var require_readable2 = __commonJS({ var { Readable: Readable7 } = require("node:stream"); var { RequestAbortedError, NotSupportedError, InvalidArgumentError, AbortError: AbortError3 } = require_errors2(); var util10 = require_util9(); - var { ReadableStreamFrom } = require_util9(); var kConsume = /* @__PURE__ */ Symbol("kConsume"); var kReading = /* @__PURE__ */ Symbol("kReading"); var kBody = /* @__PURE__ */ Symbol("kBody"); @@ -41646,7 +42283,7 @@ var require_readable2 = __commonJS({ */ get body() { if (!this[kBody]) { - this[kBody] = ReadableStreamFrom(this); + this[kBody] = ReadableStream.from(this); if (this[kConsume]) { this[kBody].getReader(); assert4(this[kBody].locked); @@ -43056,8 +43693,7 @@ var require_mock_utils2 = __commonJS({ handler.onResponseError(null, new InvalidArgumentError("reply options callback must return an object")); return; } - mockDispatch2.data = { ...responseDefaults, ...resolvedData }; - dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler); + dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler, { ...responseDefaults, ...resolvedData }); }, (error2) => { handler.onResponseError(null, error2); @@ -43068,12 +43704,13 @@ var require_mock_utils2 = __commonJS({ if (callbackResult == null || typeof callbackResult !== "object") { throw new InvalidArgumentError("reply options callback must return an object"); } - mockDispatch2.data = { ...responseDefaults, ...callbackResult }; + return dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler, { ...responseDefaults, ...callbackResult }); } return dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler); } - function dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler) { - const { data: response, delay: delay4 } = mockDispatch2; + function dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler, resolvedResponse) { + const { data: responseData, delay: delay4 } = mockDispatch2; + const response = resolvedResponse ?? responseData; if (response.error !== null) { deleteMockDispatch(mockDispatches, key); handler.onResponseError(null, response.error); @@ -43147,8 +43784,7 @@ var require_mock_utils2 = __commonJS({ handler.onResponseError(null, new InvalidArgumentError("reply options callback must return an object")); return; } - mockDispatch2.data = { ...responseDefaults, ...resolvedData }; - handleReply(dispatches, mockDispatch2.data); + handleReply(dispatches, { ...responseDefaults, ...resolvedData }); }, (err) => { handler.onResponseError(null, err); @@ -43159,8 +43795,7 @@ var require_mock_utils2 = __commonJS({ if (callbackResult == null || typeof callbackResult !== "object") { throw new InvalidArgumentError("reply options callback must return an object"); } - mockDispatch2.data = { ...responseDefaults, ...callbackResult }; - handleReply(dispatches, mockDispatch2.data); + handleReply(dispatches, { ...responseDefaults, ...callbackResult }); return; } if (typeof delay4 === "number" && delay4 > 0) { @@ -43185,13 +43820,13 @@ var require_mock_utils2 = __commonJS({ if (aborted) { return; } - const responseData = getResponseData(body2); + const responseData2 = getResponseData(body2); const responseHeaders = generateKeyValues(headers ?? {}); const responseTrailers = generateKeyValues(trailers ?? {}); controller.rawHeaders = responseHeaders; controller.rawTrailers = responseTrailers; handler.onResponseStart?.(controller, statusCode, parseHeaders(responseHeaders), getStatusText(statusCode)); - handler.onResponseData?.(controller, Buffer.from(responseData)); + handler.onResponseData?.(controller, Buffer.from(responseData2)); handler.onResponseEnd?.(controller, parseHeaders(responseTrailers)); deleteMockDispatch(mockDispatches2, key); } @@ -43954,10 +44589,18 @@ var require_mock_agent2 = __commonJS({ } dispatch(opts, handler) { opts.origin = normalizeOrigin(opts.origin); - this.get(opts.origin); + const mockDispatcher = this.get(opts.origin); this[kMockAgentAddCallHistoryLog](opts); const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters]; const dispatchOpts = { ...opts }; + if (dispatchOpts.allowH2 === false) { + const http1OnlyKey = `${dispatchOpts.origin}#http1-only`; + if (!this[kClients].has(http1OnlyKey)) { + const http1OnlyDispatcher = this[kFactory](dispatchOpts.origin); + http1OnlyDispatcher[kDispatches] = mockDispatcher[kDispatches]; + this[kMockAgentSet](http1OnlyKey, http1OnlyDispatcher); + } + } if (acceptNonStandardSearchParameters && dispatchOpts.path) { const [path18, searchParams] = dispatchOpts.path.split("?"); const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters); @@ -44971,7 +45614,11 @@ var require_decorator_handler2 = __commonJS({ /** * @deprecated */ - onBodySent() { + onBodySent(...args) { + return this.#handler.onBodySent?.(...args); + } + onRequestSent(...args) { + return this.#handler.onRequestSent?.(...args); } }; } @@ -44984,6 +45631,7 @@ var require_redirect_handler2 = __commonJS({ var util10 = require_util9(); var assert4 = require("node:assert"); var { InvalidArgumentError } = require_errors2(); + var { kRequestOrigin } = require_symbols6(); var redirectableStatusCodes = [300, 301, 302, 303, 307, 308]; var noop2 = () => { }; @@ -45016,10 +45664,20 @@ var require_redirect_handler2 = __commonJS({ onRequestStart(controller, context3) { this.handler.onRequestStart?.(controller, { ...context3, history: this.history }); } + onBodySent(chunk) { + this.handler.onBodySent?.(chunk); + } + onRequestSent() { + this.handler.onRequestSent?.(); + } onRequestUpgrade(controller, statusCode, headers, socket) { this.handler.onRequestUpgrade?.(controller, statusCode, headers, socket); } onResponseStart(controller, statusCode, headers, statusMessage) { + if (statusCode < 200) { + this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage); + return; + } if (this.opts.throwOnMaxRedirect && this.history.length >= this.maxRedirections) { throw new Error("max redirects"); } @@ -45040,14 +45698,16 @@ var require_redirect_handler2 = __commonJS({ this.opts.body = null; } this.location = this.history.length >= this.maxRedirections || util10.isDisturbed(this.opts.body) || redirectableStatusCodes.indexOf(statusCode) === -1 ? null : headers.location; - if (this.opts.origin) { - this.history.push(new URL(this.opts.path, this.opts.origin)); + const requestOrigin = this.opts[kRequestOrigin] === void 0 ? this.opts.origin : this.opts[kRequestOrigin]; + if (requestOrigin) { + this.history.push(new URL(this.opts.path, requestOrigin)); } if (!this.location) { this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage); return; } - const { origin: origin2, pathname, search } = util10.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))); + const baseUrl = requestOrigin ? new URL(this.opts.path, requestOrigin) : void 0; + const { origin: origin2, pathname, search } = util10.parseURL(new URL(this.location, baseUrl)); const path18 = search ? `${pathname}${search}` : pathname; const redirectUrlString = `${origin2}${path18}`; for (const historyUrl of this.history) { @@ -45055,9 +45715,10 @@ var require_redirect_handler2 = __commonJS({ throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin2}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`); } } - this.opts.headers = cleanRequestHeaders(this.opts.headers, removeContentHeaders, this.opts.origin !== origin2, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect); + this.opts.headers = cleanRequestHeaders(this.opts.headers, removeContentHeaders, requestOrigin !== origin2, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect); this.opts.path = path18; this.opts.origin = origin2; + this.opts[kRequestOrigin] = origin2; this.opts.query = null; } onResponseData(controller, chunk) { @@ -45271,7 +45932,6 @@ var require_dump2 = __commonJS({ #maxSize = 1024 * 1024; #dumped = false; #size = 0; - #controller = null; aborted = false; reason = false; constructor({ maxSize: maxSize2, signal }, handler) { @@ -45287,7 +45947,6 @@ var require_dump2 = __commonJS({ } onRequestStart(controller, context3) { controller.abort = this.#abort.bind(this); - this.#controller = controller; return super.onRequestStart(controller, context3); } onResponseStart(controller, statusCode, headers, statusMessage) { @@ -45303,33 +45962,26 @@ var require_dump2 = __commonJS({ return super.onResponseStart(controller, statusCode, headers, statusMessage); } onResponseError(controller, err) { - if (this.#dumped) { - return; - } - err = this.#controller?.reason ?? err; - super.onResponseError(controller, err); + super.onResponseError(controller, this.aborted === true ? this.reason : err); } onResponseData(controller, chunk) { this.#size = this.#size + chunk.length; - if (this.#size >= this.#maxSize) { + if (this.#size > this.#maxSize) { + throw new RequestAbortedError( + `Response size (${this.#size}) larger than maxSize (${this.#maxSize})` + ); + } + if (this.#size === this.#maxSize) { this.#dumped = true; - if (this.aborted === true) { - super.onResponseError(controller, this.reason); - } else { - super.onResponseEnd(controller, {}); - } } return true; } onResponseEnd(controller, trailers) { - if (this.#dumped) { - return; - } - if (this.#controller.aborted === true) { + if (this.aborted === true) { super.onResponseError(controller, this.reason); return; } - super.onResponseEnd(controller, trailers); + super.onResponseEnd(controller, this.#dumped ? {} : trailers); } }; function createDumpInterceptor({ maxSize: defaultMaxSize } = { @@ -45355,6 +46007,7 @@ var require_dns2 = __commonJS({ var { lookup } = require("node:dns"); var DecoratorHandler = require_decorator_handler2(); var { InvalidArgumentError, InformationalError } = require_errors2(); + var { kRequestOrigin } = require_symbols6(); var maxInt = Math.pow(2, 31) - 1; function hasSafeIterator(headers) { const prototype2 = Object.getPrototypeOf(headers); @@ -45694,6 +46347,7 @@ var require_dns2 = __commonJS({ const dispatchOpts = { ...this.#opts, origin: `${this.#origin.protocol}//${ip.family === 6 ? `[${ip.address}]` : ip.address}${port}`, + [kRequestOrigin]: this.#opts[kRequestOrigin] === void 0 ? this.#origin : this.#opts[kRequestOrigin], headers: withHostHeader(this.#origin.host, this.#opts.headers) }; this.#dispatch(dispatchOpts, this); @@ -45772,6 +46426,7 @@ var require_dns2 = __commonJS({ servername: origin2.hostname, // For SNI on TLS origin: newOrigin.origin, + [kRequestOrigin]: origDispatchOpts[kRequestOrigin] === void 0 ? origin2 : origDispatchOpts[kRequestOrigin], headers: withHostHeader(origin2.host, origDispatchOpts.headers) }; dispatch( @@ -45800,6 +46455,7 @@ var require_cache2 = __commonJS({ isValidHTTPToken } = require_util9(); var { serializePathWithQuery } = require_util9(); + var { kRequestOrigin } = require_symbols6(); var MAX_DELTA_SECONDS = 2147483647; var RESTRICTIVE_DIRECTIVE_NAMES = ["no-store", "private", "no-cache"]; var kInvalidCacheControlDirectives = /* @__PURE__ */ Symbol("invalid cache-control directives"); @@ -45911,14 +46567,39 @@ var require_cache2 = __commonJS({ return tokenOnlyKey; } } - function makeCacheKey(opts) { - const origin2 = opts.origin ? opts.origin.toString() : ""; + function getRequestOrigin(opts) { + const origin2 = opts[kRequestOrigin] === void 0 ? opts.origin : opts[kRequestOrigin]; + return typeof origin2 === "string" || origin2 instanceof URL ? origin2 : null; + } + function getInterceptorOrigin(opts, interceptorOrigin) { + const requestOrigin = getRequestOrigin(opts); + if (interceptorOrigin === void 0) { + return requestOrigin; + } + if (interceptorOrigin === null) { + return null; + } + if (requestOrigin) { + try { + if (new URL(requestOrigin).origin !== interceptorOrigin) { + return null; + } + } catch { + return interceptorOrigin; + } + } + return interceptorOrigin; + } + function makeCacheKey(opts, origin2 = getRequestOrigin(opts)) { + if (!origin2) { + throw new Error("opts.origin is undefined"); + } let fullPath = opts.path || "/"; if (opts.query && !pathHasQueryOrFragment(fullPath)) { fullPath = serializePathWithQuery(fullPath, opts.query); } return { - origin: origin2, + origin: origin2.toString(), method: opts.method, path: fullPath, headers: opts.headers @@ -46293,6 +46974,8 @@ var require_cache2 = __commonJS({ return JSON.stringify([cacheKey.origin, cacheKey.method, cacheKey.path, headers]); } module2.exports = { + getInterceptorOrigin, + getRequestOrigin, makeCacheKey, normalizeHeaders, assertCacheKey, @@ -46959,6 +47642,12 @@ var require_cache_handler = __commonJS({ this.#writeStream = void 0; this.#handler.onRequestStart?.(controller, context3); } + onBodySent(chunk) { + this.#handler.onBodySent?.(chunk); + } + onRequestSent() { + this.#handler.onRequestSent?.(); + } onRequestUpgrade(controller, statusCode, headers, socket) { this.#handler.onRequestUpgrade?.(controller, statusCode, headers, socket); } @@ -46981,6 +47670,11 @@ var require_cache_handler = __commonJS({ return downstreamOnHeaders(); } const cacheControlHeader = resHeaders["cache-control"]; + const cacheControlDirectives = cacheControlHeader ? parseCacheControlHeader(cacheControlHeader) : {}; + if (revalidationResponseDisallowsCachedReuse(this.#cacheType, resHeaders, cacheControlDirectives)) { + deleteCachedValue(this.#store, this.#cacheKey); + return downstreamOnHeaders(); + } const heuristicallyCacheable = resHeaders["last-modified"] && arrayIncludes(HEURISTICALLY_CACHEABLE_STATUS_CODES, statusCode); if (!cacheControlHeader && !resHeaders["expires"] && !heuristicallyCacheable && !this.#cacheByDefault) { if (statusCode === 304 && resHeaders.vary && isInvalidOrWildcardVaryHeader(resHeaders.vary)) { @@ -46988,8 +47682,7 @@ var require_cache_handler = __commonJS({ } return downstreamOnHeaders(); } - const cacheControlDirectives = cacheControlHeader ? parseCacheControlHeader(cacheControlHeader) : {}; - if (!canCacheResponse(this.#cacheType, statusCode, resHeaders, cacheControlDirectives, this.#cacheKey.headers)) { + if (!canCacheResponse(this.#cacheType, this.#cacheKey.method, statusCode, resHeaders, cacheControlDirectives, this.#cacheKey.headers)) { if (statusCode === 304 && (cacheControlHeader || revalidationResponseDisallowsCachedReuse(this.#cacheType, resHeaders, cacheControlDirectives))) { deleteCachedValue(this.#store, this.#cacheKey); } @@ -47154,9 +47847,12 @@ var require_cache_handler = __commonJS({ } } function revalidationResponseDisallowsCachedReuse(cacheType, resHeaders, cacheControlDirectives) { - return cacheControlDirectives["no-store"] === true || cacheType === "shared" && cacheControlDirectives.private === true || (resHeaders.vary ? isInvalidOrWildcardVaryHeader(resHeaders.vary) : false); + return cacheControlDirectives["no-store"] === true || cacheType === "shared" && (cacheControlDirectives.private === true || Object.hasOwn(resHeaders, "set-cookie")) || (resHeaders.vary ? isInvalidOrWildcardVaryHeader(resHeaders.vary) : false); } - function canCacheResponse(cacheType, statusCode, resHeaders, cacheControlDirectives, reqHeaders) { + function canCacheResponse(cacheType, method, statusCode, resHeaders, cacheControlDirectives, reqHeaders) { + if (!arrayIncludes(util10.safeHTTPMethods, method)) { + return false; + } if (statusCode < 200 || arrayIncludes(NOT_UNDERSTOOD_STATUS_CODES, statusCode)) { return false; } @@ -47167,7 +47863,7 @@ var require_cache_handler = __commonJS({ if (cacheControlDirectives["no-store"]) { return false; } - if (cacheType === "shared" && cacheControlDirectives.private === true) { + if (cacheType === "shared" && (cacheControlDirectives.private === true || Object.hasOwn(resHeaders, "set-cookie"))) { return false; } if (resHeaders.vary && hasVaryStar(resHeaders.vary)) { @@ -47402,7 +48098,7 @@ var require_memory_cache_store = __commonJS({ return this.#size >= this.#maxSize || this.#count >= this.#maxCount; } /** - * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} req + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key * @returns {import('../../types/cache-interceptor.d.ts').default.GetResult | undefined} */ get(key) { @@ -47475,7 +48171,7 @@ var require_memory_cache_store = __commonJS({ store.#hasEmittedMaxSizeEvent = true; } for (const [key2, entries2] of store.#entries) { - for (const entry2 of entries2.splice(0, entries2.length / 2)) { + for (const entry2 of entries2.splice(0, Math.ceil(entries2.length / 2))) { store.#size -= entry2.size; store.#count -= 1; } @@ -47652,7 +48348,16 @@ var require_cache3 = __commonJS({ var CacheHandler = require_cache_handler(); var MemoryCacheStore = require_memory_cache_store(); var CacheRevalidationHandler = require_cache_revalidation_handler(); - var { assertCacheStore, assertCacheMethods, makeCacheKey, normalizeHeaders, parseCacheControlHeader, isInvalidOrWildcardVaryHeader } = require_cache2(); + var { + assertCacheStore, + assertCacheMethods, + getInterceptorOrigin, + makeCacheKey, + normalizeHeaders, + parseCacheControlHeader, + isInvalidOrWildcardVaryHeader, + parseVaryHeader + } = require_cache2(); var { AbortError: AbortError3 } = require_errors2(); var { parseHttpDate } = require_date(); function assertCacheOrigins(origins, name) { @@ -47718,7 +48423,7 @@ var require_cache3 = __commonJS({ result.cacheControlDirectives?.["s-maxage"] !== void 0); } function revalidationResponseDisallowsCachedReuse(cacheType, headers) { - if (headers.vary && isInvalidOrWildcardVaryHeader(headers.vary)) { + if (headers.vary && isInvalidOrWildcardVaryHeader(headers.vary) || cacheType === "shared" && Object.hasOwn(headers, "set-cookie")) { return true; } const cacheControl = headers["cache-control"]; @@ -47731,6 +48436,17 @@ var require_cache3 = __commonJS({ function revalidationResponseUpdatesCacheControl(headers) { return headers["cache-control"] !== void 0; } + function revalidationResponseAddsVary(result, varyDirectives) { + if (!varyDirectives) { + return false; + } + for (const key in varyDirectives) { + if (result.vary == null || !Object.hasOwn(result.vary, key)) { + return true; + } + } + return false; + } function deleteCachedValue(store, cacheKey) { try { store.delete(cacheKey)?.catch?.(nop); @@ -47826,6 +48542,7 @@ var require_cache3 = __commonJS({ const stream7 = util10.isStream(result.body) ? result.body : Readable7.from(result.body ?? []); assert4(!stream7.destroyed, "stream should not be destroyed"); assert4(!stream7.readableDidRead, "stream should not be readableDidRead"); + let aborted = false; const controller = { rawHeaders: [], rawTrailers: [], @@ -47839,12 +48556,13 @@ var require_cache3 = __commonJS({ return stream7.isPaused(); }, get aborted() { - return stream7.destroyed; + return aborted; }, get reason() { return stream7.errored; }, abort(reason) { + aborted = true; stream7.destroy(reason ?? new AbortError3()); } }; @@ -47883,6 +48601,13 @@ var require_cache3 = __commonJS({ if (!result) { return handleUncachedResponse(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl); } + if (globalOpts.type === "shared" && Object.hasOwn(result.headers, "set-cookie")) { + if (util10.isStream(result.body)) { + result.body.on("error", nop).destroy(); + } + deleteCachedValue(globalOpts.store, cacheKey); + return handleUncachedResponse(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl); + } const now = Date.now(); if (now > result.deleteAt) { return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler)); @@ -47949,6 +48674,12 @@ var require_cache3 = __commonJS({ } if (revalidationResponseUpdatesCacheControl(headers2)) { deleteCachedValue(globalOpts.store, cacheKey); + } else if (revalidationResponseAddsVary(result, headers2.vary ? parseVaryHeader(headers2.vary, opts.headers) : void 0)) { + if (util10.isStream(result.body)) { + result.body.on("error", nop).destroy(); + } + deleteCachedValue(globalOpts.store, cacheKey); + return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler)); } } sendCachedValue(handler, opts, result, age, context3, stale); @@ -47999,25 +48730,23 @@ var require_cache3 = __commonJS({ safeMethodsToNotCache.push(method); } } - return (dispatch) => { + return (dispatch, interceptorOrigin) => { return (opts2, handler) => { - if (arrayIncludes(safeMethodsToNotCache, opts2.method)) { + const requestOrigin = getInterceptorOrigin(opts2, interceptorOrigin); + if (!requestOrigin || arrayIncludes(safeMethodsToNotCache, opts2.method)) { return dispatch(opts2, handler); } if (origins !== void 0) { - if (!opts2.origin) { - return dispatch(opts2, handler); - } - const requestOrigin = opts2.origin.toString().toLowerCase(); + const normalizedRequestOrigin = requestOrigin.toString().toLowerCase(); let isAllowed = false; for (let i = 0; i < origins.length; i++) { const allowed = origins[i]; if (typeof allowed === "string") { - if (allowed.toLowerCase() === requestOrigin) { + if (allowed.toLowerCase() === normalizedRequestOrigin) { isAllowed = true; break; } - } else if (allowed.test(requestOrigin)) { + } else if (allowed.test(normalizedRequestOrigin)) { isAllowed = true; break; } @@ -48034,7 +48763,10 @@ var require_cache3 = __commonJS({ if (reqCacheControl?.["no-store"]) { return dispatch(opts2, handler); } - const cacheKey = makeCacheKey(opts2); + const cacheKey = makeCacheKey(opts2, requestOrigin); + if (!arrayIncludes(util10.safeHTTPMethods, opts2.method)) { + return dispatch(opts2, new CacheHandler(globalOpts, cacheKey, handler)); + } const result = store.get(cacheKey); if (result && typeof result.then === "function") { return result.then((result2) => handleResult( @@ -48068,9 +48800,66 @@ var require_decompress = __commonJS({ "node_modules/undici/lib/interceptor/decompress.js"(exports2, module2) { "use strict"; var { createInflate, createGunzip, createBrotliDecompress, createZstdDecompress } = require("node:zlib"); - var { pipeline: pipeline4 } = require("node:stream"); + var { pipeline: pipeline4, Transform: TransformStream2 } = require("node:stream"); + var { InvalidArgumentError, ResponseExceededMaxSizeError } = require_errors2(); var DecoratorHandler = require_decorator_handler2(); + var DecompressController = class { + #onPause; + #onResume; + #onAbort; + #paused = false; + constructor(onPause, onResume, onAbort) { + this.#onPause = onPause; + this.#onResume = onResume; + this.#onAbort = onAbort; + this.target = null; + } + pause() { + if (this.#paused) { + return; + } + this.#paused = true; + this.#onPause(); + } + resume() { + if (!this.#paused) { + return; + } + this.#paused = false; + this.#onResume(); + } + abort(reason) { + this.target?.abort(reason); + this.#onAbort(reason); + } + get paused() { + return this.#paused; + } + get aborted() { + return this.target?.aborted ?? false; + } + get reason() { + return this.target?.reason ?? null; + } + get rawHeaders() { + return this.target?.rawHeaders ?? null; + } + set rawHeaders(value) { + if (this.target) { + this.target.rawHeaders = value; + } + } + get rawTrailers() { + return this.target?.rawTrailers ?? null; + } + set rawTrailers(value) { + if (this.target) { + this.target.rawTrailers = value; + } + } + }; var supportedEncodings = { + __proto__: null, gzip: createGunzip, "x-gzip": createGunzip, br: createBrotliDecompress, @@ -48083,6 +48872,23 @@ var require_decompress = __commonJS({ /** @type {const} */ [204, 304] ); + var defaultMaxSize = 0; + function createMaxSizeLimiter(maxSize2) { + let size = 0; + return new TransformStream2({ + transform(chunk, _encoding, callback) { + const decompressedSize = size + chunk.length; + if (decompressedSize > maxSize2) { + callback(new ResponseExceededMaxSizeError( + `Decompressed response size (${decompressedSize}) exceeded maxSize (${maxSize2})` + )); + return; + } + size = decompressedSize; + callback(null, chunk); + } + }); + } var warningEmitted = ( /** @type {boolean} */ false @@ -48096,10 +48902,122 @@ var require_decompress = __commonJS({ #skipStatusCodes; /** @type {boolean} */ #skipErrorResponses; - constructor(handler, { skipStatusCodes = defaultSkipStatusCodes, skipErrorResponses = true } = {}) { + /** @type {number} */ + #maxSize; + /** @type {number} */ + #decompressedSize = 0; + /** @type {boolean} */ + #terminated = false; + /** @type {boolean} */ + #inputEnded = false; + /** @type {boolean} */ + #inputBackpressured = false; + /** @type {boolean} */ + #upstreamPaused = false; + /** @type {boolean} */ + #draining = false; + /** @type {boolean} */ + #drainRequested = false; + /** @type {boolean} */ + #completionPending = false; + /** @type {DecompressorStream | undefined} */ + #finalDecompressor; + /** @type {DecompressController} */ + #controller; + constructor(handler, { skipStatusCodes = defaultSkipStatusCodes, skipErrorResponses = true, maxSize: maxSize2 = defaultMaxSize } = {}) { + if (!Number.isSafeInteger(maxSize2) || maxSize2 < 0) { + throw new InvalidArgumentError("maxSize must be a non-negative integer"); + } super(handler); this.#skipStatusCodes = skipStatusCodes; this.#skipErrorResponses = skipErrorResponses; + this.#maxSize = maxSize2; + this.#controller = new DecompressController( + () => this.#onDownstreamPause(), + () => this.#onDownstreamResume(), + (reason) => { + if (this.#inputEnded && !this.#terminated) { + this.onResponseError(this.#controller, reason); + } + } + ); + } + #onDownstreamPause() { + this.#pauseUpstream(); + } + #onDownstreamResume() { + const drainWasDeferred = this.#draining; + this.#drainOutput(); + if (!drainWasDeferred) { + this.#resumeUpstreamIfNeeded(); + this.#finishIfReady(); + } + } + #pauseUpstream() { + if (!this.#upstreamPaused && !this.#terminated) { + this.#upstreamPaused = true; + this.#controller.target?.pause(); + } + } + #resumeUpstreamIfNeeded() { + if (this.#upstreamPaused && !this.#controller.paused && !this.#inputBackpressured) { + this.#upstreamPaused = false; + if (!this.#inputEnded) { + this.#controller.target?.resume(); + } + } + } + #drainOutput() { + if (this.#terminated || this.#controller.paused || !this.#finalDecompressor) { + return; + } + if (this.#draining) { + this.#drainRequested = true; + return; + } + this.#draining = true; + try { + do { + this.#drainRequested = false; + let chunk; + while (!this.#terminated && !this.#controller.paused && (chunk = this.#finalDecompressor.read()) !== null) { + if (this.#maxSize > 0) { + const decompressedSize = this.#decompressedSize + chunk.length; + if (decompressedSize > this.#maxSize) { + this.#fail(new ResponseExceededMaxSizeError( + `Decompressed response size (${decompressedSize}) exceeded maxSize (${this.#maxSize})` + )); + return; + } + this.#decompressedSize = decompressedSize; + } + const result = super.onResponseData(this.#controller, chunk); + if (result === false && !this.#controller.paused) { + this.#controller.pause(); + } + } + } while (this.#drainRequested && !this.#terminated && !this.#controller.paused); + } finally { + this.#draining = false; + } + this.#resumeUpstreamIfNeeded(); + this.#finishIfReady(); + } + #finishIfReady() { + if (this.#terminated || !this.#completionPending || this.#controller.paused || this.#draining) { + return; + } + this.#terminated = true; + this.#cleanupDecompressors(); + super.onResponseEnd(this.#controller, this.#trailers); + } + #onDecompressionEnd() { + if (this.#terminated) { + return; + } + this.#completionPending = true; + this.#drainOutput(); + this.#finishIfReady(); } /** * Determines if decompression should be skipped based on encoding and status code @@ -48117,7 +49035,7 @@ var require_decompress = __commonJS({ * Creates a chain of decompressors for multiple content encodings * * @param {string} encodings - Comma-separated list of content encodings - * @returns {Array} - Array of decompressor streams + * @returns {Array} - Array of decompressor and limiting streams * @throws {Error} - If the number of content-encodings exceeds the maximum allowed */ #createDecompressionChain(encodings) { @@ -48136,54 +49054,81 @@ var require_decompress = __commonJS({ } decompressors.push(supportedEncodings[encoding]()); } - return decompressors; + if (decompressors.length < 2) { + return decompressors; + } + const streams = []; + for (let i = 0; i < decompressors.length; i++) { + streams.push(decompressors[i]); + if (i < decompressors.length - 1 && this.#maxSize > 0) { + streams.push(createMaxSizeLimiter(this.#maxSize)); + } + } + return streams; + } + /** + * Stops decompression and reports an error. + * @param {Error} error - The decompression error + * @returns {void} + */ + #fail(error2) { + if (this.#terminated) { + return; + } + if (this.#inputEnded) { + this.onResponseError(this.#controller, error2); + } else { + this.#controller.abort(error2); + } } /** - * Sets up event handlers for a decompressor stream using readable events + * Sets up event handlers for the final decompressor stream. * @param {DecompressorStream} decompressor - The decompressor stream - * @param {Controller} controller - The controller to coordinate with * @returns {void} */ - #setupDecompressorEvents(decompressor, controller) { - decompressor.on("readable", () => { - let chunk; - while ((chunk = decompressor.read()) !== null) { - const result = super.onResponseData(controller, chunk); - if (result === false) { - break; - } - } - }); - decompressor.on("error", (error2) => { - super.onResponseError(controller, error2); - }); + #setupDecompressorEvents(decompressor) { + this.#finalDecompressor = decompressor; + decompressor.on("readable", () => this.#drainOutput()); + decompressor.on("error", (error2) => this.#fail(error2)); } /** * Sets up event handling for a single decompressor - * @param {Controller} controller - The controller to handle events * @returns {void} */ - #setupSingleDecompressor(controller) { + #setupSingleDecompressor() { const decompressor = this.#decompressors[0]; - this.#setupDecompressorEvents(decompressor, controller); - decompressor.on("end", () => { - super.onResponseEnd(controller, this.#trailers); - }); + this.#setupDecompressorEvents(decompressor); + decompressor.on("end", () => this.#onDecompressionEnd()); } /** * Sets up event handling for multiple chained decompressors using pipeline - * @param {Controller} controller - The controller to handle events * @returns {void} */ - #setupMultipleDecompressors(controller) { + #setupMultipleDecompressors() { const lastDecompressor = this.#decompressors[this.#decompressors.length - 1]; - this.#setupDecompressorEvents(lastDecompressor, controller); + this.#setupDecompressorEvents(lastDecompressor); pipeline4(this.#decompressors, (err) => { + if (this.#terminated) { + return; + } if (err) { - super.onResponseError(controller, err); + this.#fail(err); + return; + } + this.#onDecompressionEnd(); + }); + } + #setupInputBackpressure() { + const decompressor = this.#decompressors[0]; + decompressor.on("drain", () => { + if (this.#terminated) { return; } - super.onResponseEnd(controller, this.#trailers); + this.#inputBackpressured = false; + if (!this.#controller.paused) { + this.#drainOutput(); + this.#resumeUpstreamIfNeeded(); + } }); } /** @@ -48192,6 +49137,14 @@ var require_decompress = __commonJS({ */ #cleanupDecompressors() { this.#decompressors.length = 0; + this.#finalDecompressor = void 0; + } + onRequestStart(controller, context3) { + this.#controller.target = controller; + return super.onRequestStart(this.#controller, context3); + } + onRequestUpgrade(controller, statusCode, headers, socket) { + return super.onRequestUpgrade(this.#controller, statusCode, headers, socket); } /** * @param {Controller} controller @@ -48201,19 +49154,20 @@ var require_decompress = __commonJS({ * @returns {void} */ onResponseStart(controller, statusCode, headers, statusMessage) { - const contentEncoding = headers["content-encoding"]; + const rawContentEncoding = headers["content-encoding"]; + const contentEncoding = Array.isArray(rawContentEncoding) ? rawContentEncoding.join(",") : rawContentEncoding; if (this.#shouldSkipDecompression(contentEncoding, statusCode)) { - return super.onResponseStart(controller, statusCode, headers, statusMessage); + return super.onResponseStart(this.#controller, statusCode, headers, statusMessage); } const decompressors = this.#createDecompressionChain(contentEncoding.toLowerCase()); if (decompressors.length === 0) { this.#cleanupDecompressors(); - return super.onResponseStart(controller, statusCode, headers, statusMessage); + return super.onResponseStart(this.#controller, statusCode, headers, statusMessage); } this.#decompressors = decompressors; const { "content-encoding": _, "content-length": __, ...newHeaders } = headers; - if (controller?.rawHeaders) { - const rawHeaders = controller.rawHeaders; + if (this.#controller.rawHeaders) { + const rawHeaders = this.#controller.rawHeaders; if (Array.isArray(rawHeaders)) { const filteredHeaders = []; for (let i = 0; i < rawHeaders.length; i += 2) { @@ -48225,7 +49179,7 @@ var require_decompress = __commonJS({ } filteredHeaders.push(rawHeaders[i], rawHeaders[i + 1]); } - controller.rawHeaders = filteredHeaders; + rawHeaders.splice(0, rawHeaders.length, ...filteredHeaders); } else if (typeof rawHeaders === "object") { for (const name of Object.keys(rawHeaders)) { const lowerName = name.toLowerCase(); @@ -48235,12 +49189,13 @@ var require_decompress = __commonJS({ } } } + this.#setupInputBackpressure(); if (this.#decompressors.length === 1) { - this.#setupSingleDecompressor(controller); + this.#setupSingleDecompressor(); } else { - this.#setupMultipleDecompressors(controller); + this.#setupMultipleDecompressors(); } - return super.onResponseStart(controller, statusCode, newHeaders, statusMessage); + return super.onResponseStart(this.#controller, statusCode, newHeaders, statusMessage); } /** * @param {Controller} controller @@ -48249,10 +49204,13 @@ var require_decompress = __commonJS({ */ onResponseData(controller, chunk) { if (this.#decompressors.length > 0) { - this.#decompressors[0].write(chunk); + if (!this.#decompressors[0].write(chunk)) { + this.#inputBackpressured = true; + this.#pauseUpstream(); + } return; } - super.onResponseData(controller, chunk); + return super.onResponseData(this.#controller, chunk); } /** * @param {Controller} controller @@ -48261,12 +49219,12 @@ var require_decompress = __commonJS({ */ onResponseEnd(controller, trailers) { if (this.#decompressors.length > 0) { + this.#inputEnded = true; this.#trailers = trailers; this.#decompressors[0].end(); - this.#cleanupDecompressors(); return; } - super.onResponseEnd(controller, trailers); + return super.onResponseEnd(this.#controller, trailers); } /** * @param {Controller} controller @@ -48274,13 +49232,15 @@ var require_decompress = __commonJS({ * @returns {void} */ onResponseError(controller, err) { - if (this.#decompressors.length > 0) { - for (const decompressor of this.#decompressors) { - decompressor.destroy(err); - } - this.#cleanupDecompressors(); + if (this.#terminated) { + return; } - super.onResponseError(controller, err); + this.#terminated = true; + for (const decompressor of this.#decompressors) { + decompressor.destroy(); + } + this.#cleanupDecompressors(); + super.onResponseError(this.#controller, err); } }; function createDecompressInterceptor(options = {}) { @@ -48496,8 +49456,9 @@ var require_deduplication_handler = __commonJS({ if (this.#aborted || this.#completed) { return; } - this.#completed = true; + this.#cleanup(); this.#primaryHandler.onResponseEnd?.(controller, trailers); + this.#completed = true; for (const waitingHandler of this.#waitingHandlers) { if (waitingHandler.done || waitingHandler.controller.aborted) { waitingHandler.done = true; @@ -48508,18 +49469,18 @@ var require_deduplication_handler = __commonJS({ waitingHandler.done = true; continue; } - if (waitingHandler.controller.paused && waitingHandler.bufferedChunks.length > 0) { + if (waitingHandler.controller.paused) { waitingHandler.pendingTrailers = trailers; continue; } try { waitingHandler.handler.onResponseEnd?.(waitingHandler.controller, trailers); - } catch { + } catch (err) { + this.#errorWaitingHandler(waitingHandler, err); } waitingHandler.done = true; } this.#pruneDoneWaitingHandlers(); - this.#onComplete?.(); } /** * @param {import('../../types/dispatcher.d.ts').default.DispatchController} controller @@ -48531,12 +49492,17 @@ var require_deduplication_handler = __commonJS({ } this.#aborted = true; this.#completed = true; + this.#cleanup(); this.#primaryHandler.onResponseError?.(controller, err); for (const waitingHandler of this.#waitingHandlers) { this.#errorWaitingHandler(waitingHandler, err); } this.#waitingHandlers = []; - this.#onComplete?.(); + } + #cleanup() { + const onComplete = this.#onComplete; + this.#onComplete = null; + onComplete?.(); } /** * @param {DispatchHandler} handler @@ -48566,7 +49532,8 @@ var require_deduplication_handler = __commonJS({ if (this.#completed && waitingHandler.pendingTrailers && waitingHandler.bufferedChunks.length === 0 && !state3.paused && !state3.aborted) { try { waitingHandler.handler.onResponseEnd?.(waitingHandler.controller, waitingHandler.pendingTrailers); - } catch { + } catch (err) { + this.#errorWaitingHandler(waitingHandler, err); } waitingHandler.pendingTrailers = null; waitingHandler.done = true; @@ -48588,12 +49555,19 @@ var require_deduplication_handler = __commonJS({ return state3.reason; }, abort: (reason) => { + if (state3.aborted) { + return; + } state3.aborted = true; state3.reason = reason ?? null; waitingHandler.done = true; waitingHandler.pendingTrailers = null; waitingHandler.bufferedChunks = []; waitingHandler.bufferedBytes = 0; + try { + handler.onResponseError?.(waitingHandler.controller, state3.reason ?? new RequestAbortedError()); + } catch { + } } }; return waitingHandler; @@ -48614,7 +49588,7 @@ var require_deduplication_handler = __commonJS({ waitingHandler.bufferedBytes += bufferedChunk.length; if (waitingHandler.bufferedBytes > this.#maxBufferSize) { const err = new RequestAbortedError(`Deduplicated waiting handler exceeded maxBufferSize (${this.#maxBufferSize} bytes) while paused`); - this.#errorWaitingHandler(waitingHandler, err); + waitingHandler.controller.abort(err); } } /** @@ -48651,7 +49625,6 @@ var require_deduplication_handler = __commonJS({ waitingHandler.bufferedChunks = []; waitingHandler.bufferedBytes = 0; try { - waitingHandler.controller.abort(err); waitingHandler.handler.onResponseError?.(waitingHandler.controller, err); } catch { } @@ -48671,7 +49644,7 @@ var require_deduplicate = __commonJS({ var diagnosticsChannel = require("node:diagnostics_channel"); var util10 = require_util9(); var DeduplicationHandler = require_deduplication_handler(); - var { normalizeHeaders, makeCacheKey, makeDeduplicationKey } = require_cache2(); + var { getInterceptorOrigin, normalizeHeaders, makeCacheKey, makeDeduplicationKey } = require_cache2(); var pendingRequestsChannel = diagnosticsChannel.channel("undici:request:pending-requests"); module2.exports = (opts = {}) => { const { @@ -48703,9 +49676,10 @@ var require_deduplicate = __commonJS({ const skipHeaderNamesSet = new Set(skipHeaderNames.map((name) => name.toLowerCase())); const excludeHeaderNamesSet = new Set(excludeHeaderNames.map((name) => name.toLowerCase())); const pendingRequests = /* @__PURE__ */ new Map(); - return (dispatch) => { + return (dispatch, interceptorOrigin) => { return (opts2, handler) => { - if (opts2.upgrade || methods.includes(opts2.method) === false) { + const requestOrigin = getInterceptorOrigin(opts2, interceptorOrigin); + if (!requestOrigin || opts2.upgrade || methods.includes(opts2.method) === false) { return dispatch(opts2, handler); } opts2 = { @@ -48719,7 +49693,7 @@ var require_deduplicate = __commonJS({ } } } - const cacheKey = makeCacheKey(opts2); + const cacheKey = makeCacheKey(opts2, requestOrigin); const dedupeKey = makeDeduplicationKey(cacheKey, excludeHeaderNamesSet); const pendingHandler = pendingRequests.get(dedupeKey); if (pendingHandler) { @@ -49380,7 +50354,11 @@ var require_headers2 = __commonJS({ } } }; - var Headers2 = class _Headers { + var getHeadersGuard; + var setHeadersGuard; + var getHeadersList; + var setHeadersList; + var Headers2 = class { #guard; /** * @type {HeadersList} @@ -49404,7 +50382,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-append append(name, value) { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); webidl.argumentLengthCheck(arguments, 2, "Headers.append"); const prefix2 = "Headers.append"; name = webidl.converters.ByteString(name, prefix2, "name"); @@ -49413,7 +50391,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-delete delete(name) { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); webidl.argumentLengthCheck(arguments, 1, "Headers.delete"); const prefix2 = "Headers.delete"; name = webidl.converters.ByteString(name, prefix2, "name"); @@ -49434,7 +50412,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-get get(name) { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); webidl.argumentLengthCheck(arguments, 1, "Headers.get"); const prefix2 = "Headers.get"; name = webidl.converters.ByteString(name, prefix2, "name"); @@ -49449,7 +50427,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-has has(name) { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); webidl.argumentLengthCheck(arguments, 1, "Headers.has"); const prefix2 = "Headers.has"; name = webidl.converters.ByteString(name, prefix2, "name"); @@ -49464,7 +50442,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-set set(name, value) { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); webidl.argumentLengthCheck(arguments, 2, "Headers.set"); const prefix2 = "Headers.set"; name = webidl.converters.ByteString(name, prefix2, "name"); @@ -49490,7 +50468,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie getSetCookie() { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); const list = this.#headersList.cookies; if (list) { return [...list]; @@ -49501,32 +50479,21 @@ var require_headers2 = __commonJS({ options.depth ??= depth; return `Headers ${util10.formatWithOptions(options, this.#headersList.entries)}`; } - static getHeadersGuard(o) { - return o.#guard; - } - static setHeadersGuard(o, guard) { - o.#guard = guard; - } - /** - * @param {Headers} o - */ - static getHeadersList(o) { - return o.#headersList; - } - /** - * @param {Headers} target - * @param {HeadersList} list - */ - static setHeadersList(target, list) { - target.#headersList = list; + static { + getHeadersGuard = (headers) => headers.#guard; + setHeadersGuard = (headers, guard) => { + headers.#guard = guard; + }; + getHeadersList = (headers) => headers.#headersList; + setHeadersList = (target, list) => { + target.#headersList = list; + }; + webidl.is.Headers = (arg) => { + return arg != null && typeof arg === "object" && #guard in arg; + }; } }; - var { getHeadersGuard, setHeadersGuard, getHeadersList, setHeadersList } = Headers2; - Reflect.deleteProperty(Headers2, "getHeadersGuard"); - Reflect.deleteProperty(Headers2, "setHeadersGuard"); - Reflect.deleteProperty(Headers2, "getHeadersList"); - Reflect.deleteProperty(Headers2, "setHeadersList"); - iteratorMixin("Headers", Headers2, headersListSortAndCombine, 0, 1); + iteratorMixin("Headers", Headers2, headersListSortAndCombine, 0, 1, webidl.is.Headers); Object.defineProperties(Headers2.prototype, { append: kEnumerableProperty, delete: kEnumerableProperty, @@ -49602,7 +50569,11 @@ var require_response2 = __commonJS({ var assert4 = require("node:assert"); var { isomorphicEncode, serializeJavascriptValueToJSONString } = require_infra(); var textEncoder2 = new TextEncoder("utf-8"); - var Response = class _Response { + var getResponseHeaders2; + var setResponseHeaders; + var getResponseState; + var setResponseState; + var Response = class { /** @type {Headers} */ #headers; #state; @@ -49666,12 +50637,12 @@ var require_response2 = __commonJS({ } // Returns response’s type, e.g., "cors". get type() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.type; } // Returns response’s URL, if it has one; otherwise the empty string. get url() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); const urlList = this.#state.urlList; const url3 = urlList[urlList.length - 1] ?? null; if (url3 === null) { @@ -49681,40 +50652,40 @@ var require_response2 = __commonJS({ } // Returns whether response was obtained through a redirect. get redirected() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.urlList.length > 1; } // Returns response’s status. get status() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.status; } // Returns whether response’s status is an ok status. get ok() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.status >= 200 && this.#state.status <= 299; } // Returns response’s status message. get statusText() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.statusText; } // Returns response’s headers as Headers. get headers() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#headers; } get body() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.body ? this.#state.body.stream : null; } get bodyUsed() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return !!this.#state.body && util10.isDisturbed(this.#state.body.stream); } // Returns a clone of response. clone() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); if (bodyUnusable(this.#state)) { throw webidl.errors.exception({ header: "Response.clone", @@ -49745,39 +50716,25 @@ var require_response2 = __commonJS({ }; return `Response ${nodeUtil.formatWithOptions(options, properties)}`; } - /** - * @param {Response} response - */ - static getResponseHeaders(response) { - return response.#headers; - } - /** - * @param {Response} response - * @param {Headers} newHeaders - */ - static setResponseHeaders(response, newHeaders) { - response.#headers = newHeaders; - } - /** - * @param {Response} response - */ - static getResponseState(response) { - return response.#state; - } - /** - * @param {Response} response - * @param {any} newState - */ - static setResponseState(response, newState) { - response.#state = newState; + static { + getResponseHeaders2 = (response) => { + return response.#headers; + }; + setResponseHeaders = (response, newHeaders) => { + response.#headers = newHeaders; + }; + getResponseState = (response) => { + return response.#state; + }; + setResponseState = (response, newState) => { + response.#state = newState; + }; + webidl.is.Response = (arg) => { + return arg != null && typeof arg === "object" && #state in arg; + }; } }; - var { getResponseHeaders: getResponseHeaders2, setResponseHeaders, getResponseState, setResponseState } = Response; - Reflect.deleteProperty(Response, "getResponseHeaders"); - Reflect.deleteProperty(Response, "setResponseHeaders"); - Reflect.deleteProperty(Response, "getResponseState"); - Reflect.deleteProperty(Response, "setResponseState"); - mixinBody(Response, getResponseState); + mixinBody(Response, getResponseState, webidl.is.Response); Object.defineProperties(Response.prototype, { type: kEnumerableProperty, url: kEnumerableProperty, @@ -49981,7 +50938,6 @@ var require_response2 = __commonJS({ converter: webidl.converters.HeadersInit } ]); - webidl.is.Response = webidl.util.MakeTypeAssertion(Response); module2.exports = { isNetworkError, makeNetworkError, @@ -50061,7 +51017,14 @@ var require_request4 = __commonJS({ } } var patchMethodWarning = false; - var Request = class _Request { + var setRequestSignal; + var getRequestDispatcher; + var setRequestDispatcher; + var setRequestHeaders; + var getRequestState; + var setRequestState; + var removeRequestAbortListener; + var Request = class { /** @type {AbortSignal} */ #signal; /** @type {import('../../dispatcher/dispatcher')} */ @@ -50351,25 +51314,25 @@ var require_request4 = __commonJS({ } // Returns request’s HTTP method, which is "GET" by default. get method() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.method; } // Returns the URL of request as a string. get url() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return URLSerializer(this.#state.url); } // Returns a Headers object consisting of the headers associated with request. // Note that headers added in the network layer by the user agent will not // be accounted for in this object, e.g., the "Host" header. get headers() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#headers; } // Returns the kind of resource requested by request, e.g., "document" // or "script". get destination() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.destination; } // Returns the referrer of request. Its value can be a same-origin URL if @@ -50378,7 +51341,7 @@ var require_request4 = __commonJS({ // during fetching to determine the value of the `Referer` header of the // request being made. get referrer() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); if (this.#state.referrer === "no-referrer") { return ""; } @@ -50391,28 +51354,28 @@ var require_request4 = __commonJS({ // This is used during fetching to compute the value of the request’s // referrer. get referrerPolicy() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.referrerPolicy; } // Returns the mode associated with request, which is a string indicating // whether the request will use CORS, or will be restricted to same-origin // URLs. get mode() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.mode; } // Returns the credentials mode associated with request, // which is a string indicating whether credentials will be sent with the // request always, never, or only when sent to a same-origin URL. get credentials() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.credentials; } // Returns the cache mode associated with request, // which is a string indicating how the request will // interact with the browser’s cache when fetching. get cache() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.cache; } // Returns the redirect mode associated with request, @@ -50420,56 +51383,56 @@ var require_request4 = __commonJS({ // request will be handled during fetching. A request // will follow redirects by default. get redirect() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.redirect; } // Returns request’s subresource integrity metadata, which is a // cryptographic hash of the resource being fetched. Its value // consists of multiple hashes separated by whitespace. [SRI] get integrity() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.integrity; } // Returns a boolean indicating whether or not request can outlive the // global in which it was created. get keepalive() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.keepalive; } // Returns a boolean indicating whether or not request is for a reload // navigation. get isReloadNavigation() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.reloadNavigation; } // Returns a boolean indicating whether or not request is for a history // navigation (a.k.a. back-forward navigation). get isHistoryNavigation() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.historyNavigation; } // Returns the signal associated with request, which is an AbortSignal // object indicating whether or not request has been aborted, and its // abort event handler. get signal() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#signal; } get body() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.body ? this.#state.body.stream : null; } get bodyUsed() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return !!this.#state.body && util10.isDisturbed(this.#state.body.stream); } get duplex() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return "half"; } // Returns a clone of request. clone() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); if (bodyUnusable(this.#state)) { throw new TypeError("unusable"); } @@ -50516,65 +51479,34 @@ var require_request4 = __commonJS({ }; return `Request ${nodeUtil.formatWithOptions(options, properties)}`; } - /** - * @param {Request} request - * @param {AbortSignal} newSignal - */ - static setRequestSignal(request, newSignal) { - request.#signal = newSignal; - return request; - } - /** - * @param {Request} request - */ - static getRequestDispatcher(request) { - return request.#dispatcher; - } - /** - * @param {Request} request - * @param {import('../../dispatcher/dispatcher')} newDispatcher - */ - static setRequestDispatcher(request, newDispatcher) { - request.#dispatcher = newDispatcher; - } - /** - * @param {Request} request - * @param {Headers} newHeaders - */ - static setRequestHeaders(request, newHeaders) { - request.#headers = newHeaders; - } - /** - * @param {Request} request - */ - static getRequestState(request) { - return request.#state; - } - /** - * @param {Request} request - * @param {any} newState - */ - static setRequestState(request, newState) { - request.#state = newState; + static { + setRequestSignal = (request, newSignal) => { + request.#signal = newSignal; + }; + getRequestDispatcher = (request) => { + return request.#dispatcher; + }; + setRequestDispatcher = (request, newDispatcher) => { + request.#dispatcher = newDispatcher; + }; + setRequestHeaders = (request, newHeaders) => { + request.#headers = newHeaders; + }; + getRequestState = (request) => { + return request.#state; + }; + setRequestState = (request, newState) => { + request.#state = newState; + }; + removeRequestAbortListener = (request) => { + request.#abortCleanup?.(); + }; + webidl.is.Request = (arg) => { + return arg != null && typeof arg === "object" && #state in arg; + }; } - /** - * Removes the `abort` listener that makes this request's signal follow the - * signal passed to its constructor, if any. Idempotent. - * @param {Request} request - */ - static removeRequestAbortListener(request) { - request.#abortCleanup?.(); - } - }; - var { setRequestSignal, getRequestDispatcher, setRequestDispatcher, setRequestHeaders, getRequestState, setRequestState, removeRequestAbortListener } = Request; - Reflect.deleteProperty(Request, "setRequestSignal"); - Reflect.deleteProperty(Request, "getRequestDispatcher"); - Reflect.deleteProperty(Request, "setRequestDispatcher"); - Reflect.deleteProperty(Request, "setRequestHeaders"); - Reflect.deleteProperty(Request, "getRequestState"); - Reflect.deleteProperty(Request, "setRequestState"); - Reflect.deleteProperty(Request, "removeRequestAbortListener"); - mixinBody(Request, getRequestState); + }; + mixinBody(Request, getRequestState, webidl.is.Request); function makeRequest(init) { return { method: init.method ?? "GET", @@ -50589,7 +51521,7 @@ var require_request4 = __commonJS({ serviceWorkers: init.serviceWorkers ?? "all", initiator: init.initiator ?? "", destination: init.destination ?? "", - priority: init.priority ?? null, + priority: init.priority ?? "auto", origin: init.origin ?? "client", policyContainer: init.policyContainer ?? "client", referrer: init.referrer ?? "client", @@ -50664,7 +51596,6 @@ var require_request4 = __commonJS({ configurable: true } }); - webidl.is.Request = webidl.util.MakeTypeAssertion(Request); webidl.converters.RequestInfo = function(V) { if (typeof V === "string") { return webidl.converters.USVString(V); @@ -50758,8 +51689,7 @@ var require_request4 = __commonJS({ { key: "priority", converter: webidl.converters.DOMString, - allowedValues: ["high", "low", "auto"], - defaultValue: () => "auto" + allowedValues: ["high", "low", "auto"] } ]); module2.exports = { @@ -50974,6 +51904,7 @@ var require_fetch2 = __commonJS({ var EE = require("node:events"); var { Readable: Readable7, pipeline: pipeline4, finished, isErrored, isReadable } = require("node:stream"); var { addAbortListener, bufferToLowerCasedHeaderName } = require_util9(); + var { SocketError } = require_errors2(); var { dataURLProcessor, serializeAMimeType, minimizeSupportedMimeType } = require_data_url2(); var { getGlobalDispatcher } = require_global4(); var { webidl } = require_webidl2(); @@ -51333,7 +52264,7 @@ var require_fetch2 = __commonJS({ } } function schemeFetch(fetchParams) { - if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { + if (isCancelled(fetchParams)) { return Promise.resolve(makeAppropriateNetworkError(fetchParams)); } const { request } = fetchParams; @@ -51431,11 +52362,11 @@ var require_fetch2 = __commonJS({ } function fetchFinale(fetchParams, response) { let timingInfo = fetchParams.timingInfo; + if (fetchParams.request.destination === "document") { + fetchParams.controller.fullTimingInfo = timingInfo; + } const processResponseEndOfBody = () => { const unsafeEndTime = Date.now(); - if (fetchParams.request.destination === "document") { - fetchParams.controller.fullTimingInfo = timingInfo; - } fetchParams.controller.reportTimingSteps = () => { if (!urlIsHttpHttpsScheme(fetchParams.request.url)) { return; @@ -51484,6 +52415,15 @@ var require_fetch2 = __commonJS({ processResponseEndOfBody(); }); } + if (fetchParams.processResponseConsumeBody != null) { + const processBody = (nullOrBytes) => fetchParams.processResponseConsumeBody(response, nullOrBytes); + const processBodyError = () => fetchParams.processResponseConsumeBody(response, "failure"); + if (internalResponse.body == null) { + queueMicrotask(() => processBody(null)); + } else { + fullyReadBody(internalResponse.body, processBody, processBodyError); + } + } } async function httpFetch(fetchParams) { const request = fetchParams.request; @@ -51514,7 +52454,7 @@ var require_fetch2 = __commonJS({ } if (redirectStatusSet.has(actualResponse.status)) { if (request.redirect !== "manual") { - fetchParams.controller.connection.destroy(void 0, false); + fetchParams.controller.connection.destroy(); } if (request.redirect === "error") { response = makeNetworkError("unexpected redirect"); @@ -51745,12 +52685,10 @@ var require_fetch2 = __commonJS({ fetchParams.controller.connection = { abort: null, destroyed: false, - destroy(err, abort = true) { + destroy(err) { if (!this.destroyed) { this.destroyed = true; - if (abort) { - this.abort?.(err ?? new DOMException("The operation was aborted.", "AbortError")); - } + this.abort?.(err ?? new DOMException("The operation was aborted.", "AbortError")); } } }; @@ -52020,7 +52958,7 @@ var require_fetch2 = __commonJS({ fetchParams.controller.ended = true; this.body?.push(null); }, - onResponseError(_controller, error2) { + onResponseError(controller, error2) { if (this.abort) { fetchParams.controller.off("terminated", this.abort); } @@ -52029,11 +52967,16 @@ var require_fetch2 = __commonJS({ return; } this.body?.destroy(error2); - fetchParams.controller.terminate(error2); + if (!controller?.aborted) { + fetchParams.controller.terminate(error2); + } reject(error2); }, onRequestUpgrade(controller, status, headers, socket) { if (socket.session != null && status !== 200 || socket.session == null && status !== 101) { + if (socket.session != null) { + controller.abort(new SocketError("bad upgrade", null)); + } return false; } const rawHeaders = controller?.rawHeaders ?? []; @@ -52104,7 +53047,7 @@ var require_cache4 = __commonJS({ var { Request, fromInnerRequest, getRequestState } = require_request4(); var { fetching } = require_fetch2(); var { urlIsHttpHttpsScheme, readAllBytes } = require_util10(); - var Cache = class _Cache { + var Cache = class { /** * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list * @type {requestResponseList} @@ -52118,7 +53061,7 @@ var require_cache4 = __commonJS({ this.#relevantRequestResponseList = arguments[1]; } async match(request, options = {}) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix2 = "Cache.match"; webidl.argumentLengthCheck(arguments, 1, prefix2); request = webidl.converters.RequestInfo(request); @@ -52130,14 +53073,14 @@ var require_cache4 = __commonJS({ return p[0]; } async matchAll(request = void 0, options = {}) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix2 = "Cache.matchAll"; if (request !== void 0) request = webidl.converters.RequestInfo(request); options = webidl.converters.CacheQueryOptions(options, prefix2, "options"); return this.#internalMatchAll(request, options); } async add(request) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix2 = "Cache.add"; webidl.argumentLengthCheck(arguments, 1, prefix2); request = webidl.converters.RequestInfo(request); @@ -52146,7 +53089,7 @@ var require_cache4 = __commonJS({ return await responseArrayPromise; } async addAll(requests) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix2 = "Cache.addAll"; webidl.argumentLengthCheck(arguments, 1, prefix2); const responsePromises = []; @@ -52208,7 +53151,10 @@ var require_cache4 = __commonJS({ } } }, - processResponseEndOfBody(response) { + // Possible spec bug. If the body is never read, `processResponseEndOfBody` (which is attached to a TransformStream's flush hook) + // never runs, so this would hang. This hook, on the other hand, always reads the body. + // https://github.com/nodejs/undici/issues/5615 + processResponseConsumeBody(response) { if (response.aborted) { responsePromise.reject(new DOMException("aborted", "AbortError")); return; @@ -52251,7 +53197,7 @@ var require_cache4 = __commonJS({ return cacheJobPromise.promise; } async put(request, response) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix2 = "Cache.put"; webidl.argumentLengthCheck(arguments, 2, prefix2); request = webidl.converters.RequestInfo(request); @@ -52332,7 +53278,7 @@ var require_cache4 = __commonJS({ return cacheJobPromise.promise; } async delete(request, options = {}) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix2 = "Cache.delete"; webidl.argumentLengthCheck(arguments, 1, prefix2); request = webidl.converters.RequestInfo(request); @@ -52378,7 +53324,7 @@ var require_cache4 = __commonJS({ * @returns {Promise} */ async keys(request = void 0, options = {}) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix2 = "Cache.keys"; if (request !== void 0) request = webidl.converters.RequestInfo(request); options = webidl.converters.CacheQueryOptions(options, prefix2, "options"); @@ -52587,6 +53533,11 @@ var require_cache4 = __commonJS({ } return Object.freeze(responseList); } + static { + webidl.is.Cache = (arg) => { + return arg != null && typeof arg === "object" && #relevantRequestResponseList in arg; + }; + } }; Object.defineProperties(Cache.prototype, { [Symbol.toStringTag]: { @@ -52647,7 +53598,7 @@ var require_cachestorage2 = __commonJS({ var { webidl } = require_webidl2(); var { kEnumerableProperty } = require_util9(); var { kConstruct } = require_symbols6(); - var CacheStorage = class _CacheStorage { + var CacheStorage = class { /** * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map * @type {Map} */ async has(cacheName) { - webidl.brandCheck(this, _CacheStorage); + webidl.brandCheck(this, webidl.is.CacheStorage); const prefix2 = "CacheStorage.has"; webidl.argumentLengthCheck(arguments, 1, prefix2); cacheName = webidl.converters.DOMString(cacheName, prefix2, "cacheName"); @@ -52698,7 +53649,7 @@ var require_cachestorage2 = __commonJS({ * @returns {Promise} */ async open(cacheName) { - webidl.brandCheck(this, _CacheStorage); + webidl.brandCheck(this, webidl.is.CacheStorage); const prefix2 = "CacheStorage.open"; webidl.argumentLengthCheck(arguments, 1, prefix2); cacheName = webidl.converters.DOMString(cacheName, prefix2, "cacheName"); @@ -52716,7 +53667,7 @@ var require_cachestorage2 = __commonJS({ * @returns {Promise} */ async delete(cacheName) { - webidl.brandCheck(this, _CacheStorage); + webidl.brandCheck(this, webidl.is.CacheStorage); const prefix2 = "CacheStorage.delete"; webidl.argumentLengthCheck(arguments, 1, prefix2); cacheName = webidl.converters.DOMString(cacheName, prefix2, "cacheName"); @@ -52727,10 +53678,15 @@ var require_cachestorage2 = __commonJS({ * @returns {Promise} */ async keys() { - webidl.brandCheck(this, _CacheStorage); + webidl.brandCheck(this, webidl.is.CacheStorage); const keys = this.#caches.keys(); return [...keys]; } + static { + webidl.is.CacheStorage = (arg) => { + return arg != null && typeof arg === "object" && #caches in arg; + }; + } }; Object.defineProperties(CacheStorage.prototype, { [Symbol.toStringTag]: { @@ -52940,7 +53896,7 @@ var require_util12 = __commonJS({ validateCookiePath(cookie.path); out.push(`Path=${cookie.path}`); } - if (cookie.expires && cookie.expires.toString() !== "Invalid Date") { + if (cookie.expires != null && cookie.expires.toString() !== "Invalid Date") { out.push(`Expires=${toIMFDate(cookie.expires)}`); } if (cookie.sameSite) { @@ -53016,90 +53972,93 @@ var require_parse4 = __commonJS({ }; } function parseUnparsedAttributes(unparsedAttributes, cookieAttributeList = {}) { - if (unparsedAttributes.length === 0) { - return cookieAttributeList; - } - assert4(unparsedAttributes[0] === ";"); - unparsedAttributes = unparsedAttributes.slice(1); - let cookieAv = ""; - if (unparsedAttributes.includes(";")) { - cookieAv = collectASequenceOfCodePointsFast( - ";", - unparsedAttributes, - { position: 0 } - ); - unparsedAttributes = unparsedAttributes.slice(cookieAv.length); - } else { - cookieAv = unparsedAttributes; - unparsedAttributes = ""; - } - let attributeName = ""; - let attributeValue = ""; - if (cookieAv.includes("=")) { - const position = { position: 0 }; - attributeName = collectASequenceOfCodePointsFast( - "=", - cookieAv, - position - ); - attributeValue = cookieAv.slice(position.position + 1); - } else { - attributeName = cookieAv; - } - attributeName = attributeName.trim(); - attributeValue = attributeValue.trim(); - if (attributeValue.length > maxAttributeValueSize) { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); - } - const attributeNameLowercase = attributeName.toLowerCase(); - if (attributeNameLowercase === "expires") { - const expiryTime = new Date(attributeValue); - if (!Number.isNaN(expiryTime.getTime())) { - cookieAttributeList.expires = expiryTime; - } - } else if (attributeNameLowercase === "max-age") { - const charCode = attributeValue.charCodeAt(0); - if ((charCode < 48 || charCode > 57) && attributeValue[0] !== "-") { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); - } - if (!/^\d+$/.test(attributeValue)) { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); + while (true) { + if (unparsedAttributes.length === 0) { + return cookieAttributeList; + } + assert4(unparsedAttributes[0] === ";"); + unparsedAttributes = unparsedAttributes.slice(1); + let cookieAv = ""; + if (unparsedAttributes.includes(";")) { + cookieAv = collectASequenceOfCodePointsFast( + ";", + unparsedAttributes, + { position: 0 } + ); + unparsedAttributes = unparsedAttributes.slice(cookieAv.length); + } else { + cookieAv = unparsedAttributes; + unparsedAttributes = ""; + } + let attributeName = ""; + let attributeValue = ""; + if (cookieAv.includes("=")) { + const position = { position: 0 }; + attributeName = collectASequenceOfCodePointsFast( + "=", + cookieAv, + position + ); + attributeValue = cookieAv.slice(position.position + 1); + } else { + attributeName = cookieAv; } - const deltaSeconds = Number(attributeValue); - cookieAttributeList.maxAge = deltaSeconds; - } else if (attributeNameLowercase === "domain") { - let cookieDomain = attributeValue; - if (cookieDomain[0] === ".") { - cookieDomain = cookieDomain.slice(1); + attributeName = attributeName.trim(); + attributeValue = attributeValue.trim(); + if (attributeValue.length > maxAttributeValueSize) { + continue; } - cookieDomain = cookieDomain.toLowerCase(); - cookieAttributeList.domain = cookieDomain; - } else if (attributeNameLowercase === "path") { - let cookiePath = ""; - if (attributeValue.length === 0 || attributeValue[0] !== "/") { - cookiePath = "/"; + const attributeNameLowercase = attributeName.toLowerCase(); + if (attributeNameLowercase === "expires") { + const expiryTime = new Date(attributeValue); + if (!Number.isNaN(expiryTime.getTime())) { + cookieAttributeList.expires = expiryTime; + } + } else if (attributeNameLowercase === "max-age") { + const charCode = attributeValue.charCodeAt(0); + const startsWithDigit = charCode >= 48 && charCode <= 57; + const startsWithSignedDigit = attributeValue[0] === "-" && attributeValue.length > 1; + if (!startsWithDigit && !startsWithSignedDigit) { + continue; + } + if (/[^\d]/.test(attributeValue.slice(1))) { + continue; + } + const deltaSeconds = Number(attributeValue); + cookieAttributeList.maxAge = deltaSeconds; + } else if (attributeNameLowercase === "domain") { + let cookieDomain = attributeValue; + if (cookieDomain[0] === ".") { + cookieDomain = cookieDomain.slice(1); + } + cookieDomain = cookieDomain.toLowerCase(); + cookieAttributeList.domain = cookieDomain; + } else if (attributeNameLowercase === "path") { + let cookiePath = ""; + if (attributeValue.length === 0 || attributeValue[0] !== "/") { + cookiePath = "/"; + } else { + cookiePath = attributeValue; + } + cookieAttributeList.path = cookiePath; + } else if (attributeNameLowercase === "secure") { + cookieAttributeList.secure = true; + } else if (attributeNameLowercase === "httponly") { + cookieAttributeList.httpOnly = true; + } else if (attributeNameLowercase === "samesite") { + const attributeValueLowercase = attributeValue.toLowerCase(); + if (attributeValueLowercase === "none") { + cookieAttributeList.sameSite = "None"; + } else if (attributeValueLowercase === "strict") { + cookieAttributeList.sameSite = "Strict"; + } else if (attributeValueLowercase === "lax") { + cookieAttributeList.sameSite = "Lax"; + } } else { - cookiePath = attributeValue; + cookieAttributeList.unparsed ??= []; + cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`); } - cookieAttributeList.path = cookiePath; - } else if (attributeNameLowercase === "secure") { - cookieAttributeList.secure = true; - } else if (attributeNameLowercase === "httponly") { - cookieAttributeList.httpOnly = true; - } else if (attributeNameLowercase === "samesite") { - const attributeValueLowercase = attributeValue.toLowerCase(); - if (attributeValueLowercase === "none") { - cookieAttributeList.sameSite = "None"; - } else if (attributeValueLowercase === "strict") { - cookieAttributeList.sameSite = "Strict"; - } else if (attributeValueLowercase === "lax") { - cookieAttributeList.sameSite = "Lax"; - } - } else { - cookieAttributeList.unparsed ??= []; - cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`); } - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); } module2.exports = { parseSetCookie, @@ -53115,13 +54074,21 @@ var require_cookies2 = __commonJS({ var { parseSetCookie } = require_parse4(); var { stringify: stringify3 } = require_util12(); var { webidl } = require_webidl2(); - var { Headers: Headers2 } = require_headers2(); - var brandChecks = webidl.brandCheckMultiple([Headers2, globalThis.Headers].filter(Boolean)); + var globalHeadersBrandCheck = (arg) => webidl.brandCheck(arg, webidl.util.MakeTypeAssertion(globalThis.Headers)); + var undiciHeadersBrandCheck = (arg) => webidl.brandCheck(arg, webidl.is.Headers); + function brandCheckHeaders(arg) { + try { + undiciHeadersBrandCheck(arg); + return; + } catch { + } + globalHeadersBrandCheck(arg); + } function getCookies(headers) { webidl.argumentLengthCheck(arguments, 1, "getCookies"); - brandChecks(headers); + brandCheckHeaders(headers); const cookie = headers.get("cookie"); - const out = {}; + const out = { __proto__: null }; if (!cookie) { return out; } @@ -53132,7 +54099,7 @@ var require_cookies2 = __commonJS({ return out; } function deleteCookie(headers, name, attributes) { - brandChecks(headers); + brandCheckHeaders(headers); const prefix2 = "deleteCookie"; webidl.argumentLengthCheck(arguments, 2, prefix2); name = webidl.converters.DOMString(name, prefix2, "name"); @@ -53146,7 +54113,7 @@ var require_cookies2 = __commonJS({ } function getSetCookies(headers) { webidl.argumentLengthCheck(arguments, 1, "getSetCookies"); - brandChecks(headers); + brandCheckHeaders(headers); const cookies = headers.getSetCookie(); if (!cookies) { return []; @@ -53159,7 +54126,7 @@ var require_cookies2 = __commonJS({ } function setCookie(headers, cookie) { webidl.argumentLengthCheck(arguments, 2, "setCookie"); - brandChecks(headers); + brandCheckHeaders(headers); cookie = webidl.converters.Cookie(cookie); const str = stringify3(cookie); if (str) { @@ -53250,6 +54217,7 @@ var require_events2 = __commonJS({ var { webidl } = require_webidl2(); var { kEnumerableProperty } = require_util9(); var { kConstruct } = require_symbols6(); + var createFastMessageEvent; var MessageEvent = class _MessageEvent extends Event { #eventInit; constructor(type, eventInitDict = {}) { @@ -53267,30 +54235,30 @@ var require_events2 = __commonJS({ webidl.util.markAsUncloneable(this); } get data() { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); return this.#eventInit.data; } get origin() { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); return this.#eventInit.origin; } get lastEventId() { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); return this.#eventInit.lastEventId; } get source() { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); return this.#eventInit.source; } get ports() { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); if (!Object.isFrozen(this.#eventInit.ports)) { Object.freeze(this.#eventInit.ports); } return this.#eventInit.ports; } initMessageEvent(type, bubbles = false, cancelable = false, data = null, origin2 = "", lastEventId = "", source = null, ports = []) { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); webidl.argumentLengthCheck(arguments, 1, "MessageEvent.initMessageEvent"); return new _MessageEvent(type, { bubbles, @@ -53302,20 +54270,23 @@ var require_events2 = __commonJS({ ports }); } - static createFastMessageEvent(type, init) { - const messageEvent = new _MessageEvent(kConstruct, type, init); - messageEvent.#eventInit = init; - messageEvent.#eventInit.data ??= null; - messageEvent.#eventInit.origin ??= ""; - messageEvent.#eventInit.lastEventId ??= ""; - messageEvent.#eventInit.source ??= null; - messageEvent.#eventInit.ports ??= []; - return messageEvent; + static { + createFastMessageEvent = (type, init) => { + const messageEvent = new _MessageEvent(kConstruct, type, init); + messageEvent.#eventInit = init; + messageEvent.#eventInit.data ??= null; + messageEvent.#eventInit.origin ??= ""; + messageEvent.#eventInit.lastEventId ??= ""; + messageEvent.#eventInit.source ??= null; + messageEvent.#eventInit.ports ??= []; + return messageEvent; + }; + webidl.is.MessageEvent = (arg) => { + return arg != null && typeof arg === "object" && #eventInit in arg; + }; } }; - var { createFastMessageEvent } = MessageEvent; - delete MessageEvent.createFastMessageEvent; - var CloseEvent = class _CloseEvent extends Event { + var CloseEvent = class extends Event { #eventInit; constructor(type, eventInitDict = {}) { const prefix2 = "CloseEvent constructor"; @@ -53327,19 +54298,24 @@ var require_events2 = __commonJS({ webidl.util.markAsUncloneable(this); } get wasClean() { - webidl.brandCheck(this, _CloseEvent); + webidl.brandCheck(this, webidl.is.CloseEvent); return this.#eventInit.wasClean; } get code() { - webidl.brandCheck(this, _CloseEvent); + webidl.brandCheck(this, webidl.is.CloseEvent); return this.#eventInit.code; } get reason() { - webidl.brandCheck(this, _CloseEvent); + webidl.brandCheck(this, webidl.is.CloseEvent); return this.#eventInit.reason; } + static { + webidl.is.CloseEvent = (arg) => { + return arg != null && typeof arg === "object" && #eventInit in arg; + }; + } }; - var ErrorEvent = class _ErrorEvent extends Event { + var ErrorEvent = class extends Event { #eventInit; constructor(type, eventInitDict) { const prefix2 = "ErrorEvent constructor"; @@ -53351,25 +54327,30 @@ var require_events2 = __commonJS({ this.#eventInit = eventInitDict; } get message() { - webidl.brandCheck(this, _ErrorEvent); + webidl.brandCheck(this, webidl.is.ErrorEvent); return this.#eventInit.message; } get filename() { - webidl.brandCheck(this, _ErrorEvent); + webidl.brandCheck(this, webidl.is.ErrorEvent); return this.#eventInit.filename; } get lineno() { - webidl.brandCheck(this, _ErrorEvent); + webidl.brandCheck(this, webidl.is.ErrorEvent); return this.#eventInit.lineno; } get colno() { - webidl.brandCheck(this, _ErrorEvent); + webidl.brandCheck(this, webidl.is.ErrorEvent); return this.#eventInit.colno; } get error() { - webidl.brandCheck(this, _ErrorEvent); + webidl.brandCheck(this, webidl.is.ErrorEvent); return this.#eventInit.error; } + static { + webidl.is.ErrorEvent = (arg) => { + return arg != null && typeof arg === "object" && #eventInit in arg; + }; + } }; Object.defineProperties(MessageEvent.prototype, { [Symbol.toStringTag]: { @@ -53892,11 +54873,11 @@ var require_connection2 = __commonJS({ processResponse(response) { if (response.type === "error" || response.status !== 101) { if (response.socket?.session == null) { - failWebsocketConnection(handler, 1002, "Received network error or non-101 status code.", response.error); + failHandshake(handler, response, 1002, "Received network error or non-101 status code.", response.error); return; } if (response.status !== 200) { - failWebsocketConnection(handler, 1002, "Received network error or non-200 status code.", response.error); + failHandshake(handler, response, 1002, "Received network error or non-200 status code.", response.error); return; } } @@ -53905,40 +54886,45 @@ var require_connection2 = __commonJS({ warningEmitted = true; } if (protocols.length !== 0 && !response.headersList.get("Sec-WebSocket-Protocol")) { - failWebsocketConnection(handler, 1002, "Server did not respond with sent protocols."); + failHandshake(handler, response, 1002, "Server did not respond with sent protocols."); return; } if (response.socket.session == null && response.headersList.get("Upgrade")?.toLowerCase() !== "websocket") { - failWebsocketConnection(handler, 1002, 'Server did not set Upgrade header to "websocket".'); + failHandshake(handler, response, 1002, 'Server did not set Upgrade header to "websocket".'); return; } if (response.socket.session == null && response.headersList.get("Connection")?.toLowerCase() !== "upgrade") { - failWebsocketConnection(handler, 1002, 'Server did not set Connection header to "upgrade".'); + failHandshake(handler, response, 1002, 'Server did not set Connection header to "upgrade".'); return; } - const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); - const digest = crypto8.hash("sha1", keyValue + uid, "base64"); - if (secWSAccept !== digest) { - failWebsocketConnection(handler, 1002, "Incorrect hash received in Sec-WebSocket-Accept header."); - return; + if (response.socket.session == null) { + const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); + const digest = crypto8.hash("sha1", keyValue + uid, "base64"); + if (secWSAccept !== digest) { + failHandshake(handler, response, 1002, "Incorrect hash received in Sec-WebSocket-Accept header."); + return; + } } const secExtension = response.headersList.get("Sec-WebSocket-Extensions"); let extensions; if (secExtension !== null) { extensions = parseExtensions(secExtension); if (!extensions.has("permessage-deflate")) { - failWebsocketConnection(handler, 1002, "Sec-WebSocket-Extensions header does not match."); + failHandshake(handler, response, 1002, "Sec-WebSocket-Extensions header does not match."); return; } } const secProtocol = response.headersList.get("Sec-WebSocket-Protocol"); if (secProtocol !== null) { const requestProtocols = getDecodeSplit("sec-websocket-protocol", request.headersList); - if (!requestProtocols.includes(secProtocol)) { - failWebsocketConnection(handler, 1002, "Protocol was not set in the opening handshake."); + if (requestProtocols === null || !requestProtocols.includes(secProtocol)) { + failHandshake(handler, response, 1002, "Protocol was not set in the opening handshake."); return; } } + if (response.socket.session != null) { + response.socket.allowHalfOpen = false; + } response.socket.on("data", handler.onSocketData); response.socket.on("close", handler.onSocketClose); response.socket.on("error", handler.onSocketError); @@ -53981,6 +54967,12 @@ var require_connection2 = __commonJS({ object.readyState = states.CLOSING; } } + function failHandshake(handler, response, code, reason, cause) { + if (response.socket?.session != null && !response.socket.destroyed) { + response.socket.destroy(); + } + failWebsocketConnection(handler, code, reason, cause); + } function failWebsocketConnection(handler, code, reason, cause) { if (isEstablished(handler.readyState)) { closeWebSocketConnection(handler, code, reason, false); @@ -54052,6 +55044,7 @@ var require_permessage_deflate2 = __commonJS({ if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) { callback(new MessageSizeExceededError()); this.#inflate.removeAllListeners(); + this.#inflate.destroy(); this.#inflate = null; return; } @@ -54354,6 +55347,7 @@ var require_receiver2 = __commonJS({ } consumeFragments() { const fragments = this.#fragments; + this.#info.compressed = false; if (fragments.length === 1) { this.#fragmentsBytes = 0; return fragments.shift(); @@ -54557,6 +55551,7 @@ var require_websocket2 = __commonJS({ var { channels } = require_diagnostics2(); var kRef = /* @__PURE__ */ Symbol.for("nodejs.ref"); var kUnref = /* @__PURE__ */ Symbol.for("nodejs.unref"); + var ping; function getSocketAddress(socket) { if (typeof socket?.address === "function") { return socket.address(); @@ -54659,13 +55654,13 @@ var require_websocket2 = __commonJS({ this.#handler.readyState = _WebSocket.CONNECTING; this.#binaryType = "blob"; } + // TODO: remove this [kRef]() { - webidl.brandCheck(this, _WebSocket); this.#refed = true; this.#handler.socket?.ref?.(); } + // TODO: remove this [kUnref]() { - webidl.brandCheck(this, _WebSocket); this.#refed = false; this.#handler.socket?.unref?.(); } @@ -54675,7 +55670,7 @@ var require_websocket2 = __commonJS({ * @param {string|undefined} reason */ close(code = void 0, reason = void 0) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); const prefix2 = "WebSocket.close"; if (code !== void 0) { code = webidl.converters["unsigned short"](code, prefix2, "code", webidl.attributes.Clamp); @@ -54692,7 +55687,7 @@ var require_websocket2 = __commonJS({ * @param {NodeJS.TypedArray|ArrayBuffer|Blob|string} data */ send(data) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); const prefix2 = "WebSocket.send"; webidl.argumentLengthCheck(arguments, 1, prefix2); data = webidl.converters.WebSocketSendData(data, prefix2, "data"); @@ -54726,31 +55721,31 @@ var require_websocket2 = __commonJS({ } } get readyState() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#handler.readyState; } get bufferedAmount() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#bufferedAmount; } get url() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return URLSerializer(this.#url); } get extensions() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#extensions; } get protocol() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#protocol; } get onopen() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#events.open; } set onopen(fn) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); if (this.#events.open) { this.removeEventListener("open", this.#events.open); } @@ -54763,11 +55758,11 @@ var require_websocket2 = __commonJS({ } } get onerror() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#events.error; } set onerror(fn) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); if (this.#events.error) { this.removeEventListener("error", this.#events.error); } @@ -54780,11 +55775,11 @@ var require_websocket2 = __commonJS({ } } get onclose() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#events.close; } set onclose(fn) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); if (this.#events.close) { this.removeEventListener("close", this.#events.close); } @@ -54797,11 +55792,11 @@ var require_websocket2 = __commonJS({ } } get onmessage() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#events.message; } set onmessage(fn) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); if (this.#events.message) { this.removeEventListener("message", this.#events.message); } @@ -54814,11 +55809,11 @@ var require_websocket2 = __commonJS({ } } get binaryType() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#binaryType; } set binaryType(type) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); if (type !== "blob" && type !== "arraybuffer") { this.#binaryType = "blob"; } else { @@ -54928,27 +55923,26 @@ var require_websocket2 = __commonJS({ }); } } - /** - * @param {WebSocket} ws - * @param {Buffer|undefined} buffer - */ - static ping(ws, buffer3) { - if (Buffer.isBuffer(buffer3)) { - if (buffer3.length > 125) { - throw new TypeError("A PING frame cannot have a body larger than 125 bytes."); + static { + ping = (ws, buffer3) => { + if (Buffer.isBuffer(buffer3)) { + if (buffer3.length > 125) { + throw new TypeError("A PING frame cannot have a body larger than 125 bytes."); + } + } else if (buffer3 !== void 0) { + throw new TypeError("Expected buffer payload"); } - } else if (buffer3 !== void 0) { - throw new TypeError("Expected buffer payload"); - } - const readyState = ws.#handler.readyState; - if (isEstablished(readyState) && !isClosing(readyState) && !isClosed(readyState)) { - const frame = new WebsocketFrameSend(buffer3); - ws.#handler.socket.write(frame.createFrame(opcodes.PING)); - } + const readyState = ws.#handler.readyState; + if (isEstablished(readyState) && !isClosing(readyState) && !isClosed(readyState)) { + const frame = new WebsocketFrameSend(buffer3); + ws.#handler.socket.write(frame.createFrame(opcodes.PING)); + } + }; + webidl.is.WebSocket = (arg) => { + return arg != null && typeof arg === "object" && #handler in arg; + }; } }; - var { ping } = WebSocket; - Reflect.deleteProperty(WebSocket, "ping"); WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING; WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN; WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING; @@ -55057,6 +56051,7 @@ var require_websocketerror = __commonJS({ } }); } + var createUnvalidatedWebSocketError; var WebSocketError = class _WebSocketError extends createInheritableDOMException() { #closeCode; #reason; @@ -55083,20 +56078,18 @@ var require_websocketerror = __commonJS({ get reason() { return this.#reason; } - /** - * @param {string} message - * @param {number|null} code - * @param {string} reason - */ - static createUnvalidatedWebSocketError(message, code, reason) { - const error2 = new _WebSocketError(message, kConstruct); - error2.#closeCode = code; - error2.#reason = reason; - return error2; + static { + createUnvalidatedWebSocketError = (message, code, reason) => { + const error2 = new _WebSocketError(message, kConstruct); + error2.#closeCode = code; + error2.#reason = reason; + return error2; + }; + webidl.is.WebSocketError = (arg) => { + return arg != null && typeof arg === "object" && #reason in arg; + }; } }; - var { createUnvalidatedWebSocketError } = WebSocketError; - delete WebSocketError.createUnvalidatedWebSocketError; Object.defineProperties(WebSocketError.prototype, { closeCode: kEnumerableProperty, reason: kEnumerableProperty, @@ -55107,7 +56100,6 @@ var require_websocketerror = __commonJS({ configurable: true } }); - webidl.is.WebSocketError = webidl.util.MakeTypeAssertion(WebSocketError); module2.exports = { WebSocketError, createUnvalidatedWebSocketError }; } }); @@ -55144,9 +56136,9 @@ var require_websocketstream = __commonJS({ #readableStream; /** @type {ReadableStreamDefaultController} */ #readableStreamController; - // Each WebSocketStream object has an associated writable stream , which is a WritableStream . - /** @type {WritableStream} */ - #writableStream; + // Retain the controller so the writable stream can be errored while locked. + /** @type {WritableStreamDefaultController} */ + #writableStreamController; // Each WebSocketStream object has an associated boolean handshake aborted , which is initially false. #handshakeAborted = false; /** @type {import('../websocket').Handler} */ @@ -55168,7 +56160,9 @@ var require_websocketstream = __commonJS({ } this.#handler.socket.destroy(); }, - onSocketClose: () => this.#onSocketClose(), + // When the WebSocket connection is closed for a WebSocketStream stream, possibly cleanly, the user agent must + // queue a global task on the WebSocket task source given stream ’s relevant global object to run the following substeps: + onSocketClose: () => queueMicrotask(() => this.#onSocketClose()), onPing: () => { }, onPong: () => { @@ -55276,6 +56270,8 @@ var require_websocketstream = __commonJS({ this.#handler.socket.write(frame.createFrame(opcode), () => { promise.resolve(void 0); }); + } else { + promise.resolve(void 0); } return promise.promise; } @@ -55292,21 +56288,24 @@ var require_websocketstream = __commonJS({ parser.on("error", (err) => this.#handler.onParserError(err)); this.#parser = parser; this.#handler.readyState = states.OPEN; - const extensions = parsedExtensions ?? ""; + const extensions = response.headersList.get("sec-websocket-extensions") ?? ""; const protocol = response.headersList.get("sec-websocket-protocol") ?? ""; const readable = new ReadableStream({ start: (controller) => { this.#readableStreamController = controller; }, + pull: () => this.#pull(), cancel: (reason) => this.#cancel(reason) }); const writable = new WritableStream({ + start: (controller) => { + this.#writableStreamController = controller; + }, write: (chunk) => this.#write(chunk), close: () => closeWebSocketConnection(this.#handler, null, null), abort: (reason) => this.#closeUsingReason(reason) }); this.#readableStream = readable; - this.#writableStream = writable; this.#openedPromise.resolve({ extensions, protocol, @@ -55331,6 +56330,9 @@ var require_websocketstream = __commonJS({ chunk = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); } this.#readableStreamController.enqueue(chunk); + if (this.#readableStreamController.desiredSize <= 0) { + this.#handler.socket.pause(); + } } /** @type {import('../websocket').Handler['onSocketClose']} */ #onSocketClose() { @@ -55344,15 +56346,13 @@ var require_websocketstream = __commonJS({ } const result = this.#parser?.closingInfo; let code = result?.code ?? 1005; - if (!this.#handler.closeState.has(sentCloseFrameState.SENT) && !this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) { + if (!this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) { code = 1006; } const reason = result?.reason == null ? "" : utf8DecodeBytes(Buffer.from(result.reason)); if (wasClean) { readableStreamClose(this.#readableStreamController); - if (!this.#writableStream.locked) { - this.#writableStream.abort(new DOMException("A closed WebSocketStream cannot be written to", "InvalidStateError")); - } + this.#writableStreamController.error(new DOMException("A closed WebSocketStream cannot be written to", "InvalidStateError")); this.#closedPromise.resolve({ closeCode: code, reason @@ -55360,7 +56360,7 @@ var require_websocketstream = __commonJS({ } else { const error2 = createUnvalidatedWebSocketError("unclean close", code, reason); this.#readableStreamController?.error(error2); - this.#writableStream?.abort(error2); + this.#writableStreamController?.error(error2); this.#closedPromise.reject(error2); } } @@ -55373,6 +56373,10 @@ var require_websocketstream = __commonJS({ } closeWebSocketConnection(this.#handler, code, reasonString); } + // To pull bytes from a WebSocketStream stream , if stream is currently applying backpressure, release backpressure. + #pull() { + this.#handler.socket.resume(); + } // To cancel a WebSocketStream stream given reason , close using reason giving stream and reason . #cancel(reason) { this.#closeUsingReason(reason); @@ -55467,6 +56471,7 @@ var require_util14 = __commonJS({ var require_eventsource_stream2 = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports2, module2) { "use strict"; + var buffer3 = require("node:buffer"); var { Transform: Transform2 } = require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util14(); var BOM = [239, 187, 191]; @@ -55474,24 +56479,25 @@ var require_eventsource_stream2 = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer3.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID2 = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer3, start) { - if (start >= buffer3.length) { + function isASCIINumberBytes(buffer4, start) { + if (start >= buffer4.length) { return false; } - for (let i = start; i < buffer3.length; i++) { - if (buffer3[i] < 48 || buffer3[i] > 57) { + for (let i = start; i < buffer4.length; i++) { + if (buffer4[i] < 48 || buffer4[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer3, start) { - for (let i = start; i < buffer3.length; i++) { - if (buffer3[i] === 0) { + function isValidLastEventIdBytes(buffer4, start) { + for (let i = start; i < buffer4.length; i++) { + if (buffer4[i] === 0) { return false; } } @@ -55508,6 +56514,11 @@ var require_eventsource_stream2 = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform2 { /** * @type {eventSourceSettings} @@ -55534,6 +56545,8 @@ var require_eventsource_stream2 = __commonJS({ pos = 0; lineChunkIndex = 0; linePos = 0; + eventDataSize = 0; + maxEventSize; event = { data: void 0, event: void 0, @@ -55543,6 +56556,7 @@ var require_eventsource_stream2 = __commonJS({ /** * @param {object} options * @param {boolean} [options.readableObjectMode] + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} [options.eventSourceSettings] * @param {(chunk: any, encoding?: BufferEncoding | undefined) => boolean} [options.push] */ @@ -55550,6 +56564,7 @@ var require_eventsource_stream2 = __commonJS({ options.readableObjectMode = true; super(options); this.state = options.eventSourceSettings || {}; + this.maxEventSize = options.maxEventSize ?? defaultMaxEventSize; if (options.push) { this.push = options.push; } @@ -55601,7 +56616,12 @@ var require_eventsource_stream2 = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; @@ -55632,6 +56652,11 @@ var require_eventsource_stream2 = __commonJS({ } } if (isFieldName(line, fieldLength, DATA)) { + const valueBytes = line.length - valueStart; + const eventDataSize = this.eventDataSize + (event.data === void 0 ? 0 : 1) + valueBytes; + if (this.maxEventSize > 0 && eventDataSize > this.maxEventSize) { + throw createMaxEventSizeExceededError(); + } const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -55639,6 +56664,7 @@ var require_eventsource_stream2 = __commonJS({ event.data += ` ${value}`; } + this.eventDataSize = eventDataSize; return; } if (isFieldName(line, fieldLength, RETRY)) { @@ -55686,6 +56712,7 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventDataSize = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -55815,9 +56842,12 @@ var require_eventsource2 = __commonJS({ var { parseMIMEType } = require_data_url2(); var { createFastMessageEvent } = require_events2(); var { isNetworkError } = require_response2(); - var { kEnumerableProperty } = require_util9(); + var { isValidHeaderValue, kEnumerableProperty } = require_util9(); var { environmentSettingsObject } = require_util10(); var { createPotentialCORSRequest } = require_util14(); + var { getGlobalDispatcher } = require_global4(); + var { isomorphicDecode } = require_infra(); + var textEncoder2 = new TextEncoder(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -55825,7 +56855,7 @@ var require_eventsource2 = __commonJS({ var CLOSED = 2; var ANONYMOUS = "anonymous"; var USE_CREDENTIALS = "use-credentials"; - var EventSource = class _EventSource extends EventTarget { + var EventSource = class extends EventTarget { #events = { open: null, error: null, @@ -55897,6 +56927,7 @@ var require_eventsource2 = __commonJS({ * @readonly */ get readyState() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#readyState; } /** @@ -55905,6 +56936,7 @@ var require_eventsource2 = __commonJS({ * @returns {string} */ get url() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#url; } /** @@ -55912,6 +56944,7 @@ var require_eventsource2 = __commonJS({ * instantiated with CORS credentials set (true), or not (false, the default). */ get withCredentials() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#withCredentials; } #connect() { @@ -55951,6 +56984,7 @@ var require_eventsource2 = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -55981,8 +57015,12 @@ var require_eventsource2 = __commonJS({ this.dispatchEvent(new Event("error")); setTimeout(() => { if (this.#readyState !== CONNECTING) return; + this.#request.headersList.delete("last-event-id", true); if (this.#state.lastEventId.length) { - this.#request.headersList.set("last-event-id", this.#state.lastEventId, true); + const lastEventId = isomorphicDecode(textEncoder2.encode(this.#state.lastEventId)); + if (isValidHeaderValue(lastEventId)) { + this.#request.headersList.set("last-event-id", lastEventId, true); + } } this.#connect(); }, this.#state.reconnectionTime)?.unref(); @@ -55992,16 +57030,18 @@ var require_eventsource2 = __commonJS({ * CLOSED. */ close() { - webidl.brandCheck(this, _EventSource); + webidl.brandCheck(this, webidl.is.EventSource); if (this.#readyState === CLOSED) return; this.#readyState = CLOSED; this.#controller.abort(); this.#request = null; } get onopen() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#events.open; } set onopen(fn) { + webidl.brandCheck(this, webidl.is.EventSource); if (this.#events.open) { this.removeEventListener("open", this.#events.open); } @@ -56014,9 +57054,11 @@ var require_eventsource2 = __commonJS({ } } get onmessage() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#events.message; } set onmessage(fn) { + webidl.brandCheck(this, webidl.is.EventSource); if (this.#events.message) { this.removeEventListener("message", this.#events.message); } @@ -56029,9 +57071,11 @@ var require_eventsource2 = __commonJS({ } } get onerror() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#events.error; } set onerror(fn) { + webidl.brandCheck(this, webidl.is.EventSource); if (this.#events.error) { this.removeEventListener("error", this.#events.error); } @@ -56043,6 +57087,11 @@ var require_eventsource2 = __commonJS({ this.#events.error = null; } } + static { + webidl.is.EventSource = (arg) => { + return arg != null && typeof arg === "object" && #events in arg; + }; + } }; var constantsPropertyDescriptors = { CONNECTING: { @@ -56087,7 +57136,8 @@ var require_eventsource2 = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() }, { key: "node", @@ -105118,6 +106168,8 @@ var commaPattern = /\\,/g; var periodPattern = /\\\./g; var EXPANSION_MAX = 1e5; var EXPANSION_MAX_LENGTH = 4e6; +var EXPANSION_MAX_DEPTH = 1e3; +var EXPANSION_MAX_REWRITES = 1e3; function numeric(str) { return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0); } @@ -105127,36 +106179,44 @@ function escapeBraces(str) { function unescapeBraces(str) { return str.replace(escSlashPattern, "\\").replace(escOpenPattern, "{").replace(escClosePattern, "}").replace(escCommaPattern, ",").replace(escPeriodPattern, "."); } -function parseCommaParts(str) { - if (!str) { - return [""]; +function pushAll(target, items) { + for (let i = 0; i < items.length; i++) { + target.push(items[i]); } +} +function parseCommaParts(str) { const parts = []; - const m = balanced("{", "}", str); - if (!m) { - return str.split(","); - } - const { pre, body: body2, post } = m; - const p = pre.split(","); - p[p.length - 1] += "{" + body2 + "}"; - const postParts = parseCommaParts(post); - if (post.length) { - ; - p[p.length - 1] += postParts.shift(); - p.push.apply(p, postParts); - } - parts.push.apply(parts, p); - return parts; + let carry = ""; + for (; ; ) { + const m = balanced("{", "}", str); + if (!m) { + const tail = str.split(","); + tail[0] = carry + tail[0]; + pushAll(parts, tail); + return parts; + } + const { pre, body: body2, post } = m; + const p = pre.split(","); + p[0] = carry + p[0]; + p[p.length - 1] += "{" + body2 + "}"; + if (!post.length) { + pushAll(parts, p); + return parts; + } + carry = p.pop(); + pushAll(parts, p); + str = post; + } } function expand(str, options = {}) { if (!str) { return []; } - const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH } = options; + const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH, maxDepth = EXPANSION_MAX_DEPTH, maxRewrites = EXPANSION_MAX_REWRITES } = options; if (str.slice(0, 2) === "{}") { str = "\\{\\}" + str.slice(2); } - return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces); + return expand_(escapeBraces(str), max, maxLength, maxDepth, 0, maxRewrites, true).map(unescapeBraces); } function embrace(str) { return "{" + str + "}"; @@ -105234,8 +106294,12 @@ function expandSequence(body2, isAlphaSequence, max, maxLength) { } return N; } -function expand_(str, max, maxLength, isTop) { +function expand_(str, max, maxLength, maxDepth, depth, maxRewrites, isTop) { + if (depth > maxDepth) { + return [str]; + } let acc = [""]; + let rewrites = 0; let dropEmpties = false; let firstGroup = true; for (; ; ) { @@ -105257,7 +106321,8 @@ function expand_(str, max, maxLength, isTop) { const isSequence = isNumericSequence || isAlphaSequence; const isOptions = m.body.indexOf(",") >= 0; if (!isSequence && !isOptions) { - if (m.post.match(/,(?!,).*\}/)) { + if (rewrites < maxRewrites && m.post.match(/,(?!,).*\}/)) { + rewrites++; str = m.pre + "{" + m.body + escClose + m.post; isTop = true; continue; @@ -105274,7 +106339,7 @@ function expand_(str, max, maxLength, isTop) { } else { let n = parseCommaParts(m.body); if (n.length === 1 && n[0] !== void 0) { - n = expand_(n[0], max, maxLength, false).map(embrace); + n = expand_(n[0], max, maxLength, maxDepth, depth + 1, maxRewrites, false).map(embrace); if (n.length === 1) { acc = combine(acc, pre + n[0], [""], max, maxLength, dropEmpties && !m.post.length); if (!m.post.length) @@ -105292,7 +106357,7 @@ function expand_(str, max, maxLength, isTop) { values = []; let valuesLength = 0; outer: for (let j = 0; j < n.length; j++) { - const expanded = expand_(n[j], max, maxLength, false); + const expanded = expand_(n[j], max, maxLength, maxDepth, depth + 1, maxRewrites, false); for (let k = 0; k < expanded.length; k++) { const v = expanded[k]; if (dropsEmpties && !v) From 975cfc0086bb4f115825f7057e3fb1f3d9215cb3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 05:01:31 +0000 Subject: [PATCH 3/4] fix: apply audit fixes --- dist/update-known-checksums/index.cjs | 2698 +++++++++++++++++-------- 1 file changed, 1864 insertions(+), 834 deletions(-) diff --git a/dist/update-known-checksums/index.cjs b/dist/update-known-checksums/index.cjs index 750c7be..10862a1 100644 --- a/dist/update-known-checksums/index.cjs +++ b/dist/update-known-checksums/index.cjs @@ -1858,10 +1858,66 @@ var require_request = __commonJS({ return false; } } - onUpgrade(statusCode, headers, socket) { + /** + * @param {number|null} statusCode + * @param {Buffer[]|null} headers + * @param {import('node:stream').Duplex} socket + * @param {string} [statusText] + */ + onUpgrade(statusCode, headers, socket, statusText = "") { + this.onFinally(); assert(!this.aborted); assert(!this.completed); - return this[kHandler].onUpgrade(statusCode, headers, socket); + if (statusCode !== null) { + this.#publishUpgradeHeaders(statusCode, headers, statusText); + } + const result = this[kHandler].onUpgrade(statusCode, headers, socket); + if (!this.aborted) { + this.completed = true; + if (statusCode !== null) { + this.#publishUpgradeTrailers(); + } + } + return result; + } + /** + * @param {number} statusCode + * @param {import('node:http2').IncomingHttpHeaders} headers + * @param {(headers: import('node:http2').IncomingHttpHeaders) => Buffer[]} parseHeaders + * @param {string} [statusText] + */ + onUpgradeResponse(statusCode, headers, parseHeaders, statusText = "") { + assert(!this.aborted); + assert(this.completed); + if (channels.headers.hasSubscribers) { + this.#publishUpgradeHeaders(statusCode, parseHeaders(headers), statusText); + } + this.#publishUpgradeTrailers(); + } + /** + * @param {Error} error + */ + onUpgradeError(error2) { + assert(!this.aborted); + assert(this.completed); + if (channels.error.hasSubscribers) { + channels.error.publish({ request: this, error: error2 }); + } + } + /** + * @param {number} statusCode + * @param {Buffer[]} headers + * @param {string} statusText + */ + #publishUpgradeHeaders(statusCode, headers, statusText) { + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }); + } + } + #publishUpgradeTrailers() { + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers: [] }); + } } onComplete(trailers) { this.onFinally(); @@ -6004,7 +6060,7 @@ var require_client_h1 = __commonJS({ } } onUpgrade(head) { - const { upgrade, client, socket, headers, statusCode } = this; + const { upgrade, client, socket, headers, statusCode, statusText } = this; assert(upgrade); assert(client[kSocket] === socket); assert(!socket.destroyed); @@ -6029,9 +6085,10 @@ var require_client_h1 = __commonJS({ client[kQueue][client[kRunningIdx]++] = null; client.emit("disconnect", client[kUrl], [client], new InformationalError("upgrade")); try { - request.onUpgrade(statusCode, headers, socket); - } catch (err) { - util4.destroy(socket, err); + request.onUpgrade(statusCode, headers, socket, statusText); + } catch (error2) { + util4.errorRequest(client, request, error2); + util4.destroy(socket, error2); } client[kResume](); } @@ -6323,21 +6380,20 @@ var require_client_h1 = __commonJS({ } function clearIdleSocketValidation(socket) { if (socket[kIdleSocketValidationTimeout]) { - clearTimeout(socket[kIdleSocketValidationTimeout]); + clearImmediate(socket[kIdleSocketValidationTimeout]); socket[kIdleSocketValidationTimeout] = null; } socket[kIdleSocketValidation] = 0; } function scheduleIdleSocketValidation(client, socket) { socket[kIdleSocketValidation] = 1; - socket[kIdleSocketValidationTimeout] = setTimeout(() => { + socket[kIdleSocketValidationTimeout] = setImmediate(() => { socket[kIdleSocketValidationTimeout] = null; socket[kIdleSocketValidation] = 2; if (client[kSocket] === socket && !socket.destroyed) { client[kResume](); } - }, 0); - socket[kIdleSocketValidationTimeout].unref?.(); + }); } function resumeH1(client) { const socket = client[kSocket]; @@ -6435,11 +6491,17 @@ var require_client_h1 = __commonJS({ } const socket = client[kSocket]; clearIdleSocketValidation(socket); - const abort = (err) => { - if (request.aborted || request.completed) { + const abort = (error2) => { + if (request.aborted) { return; } - util4.errorRequest(client, request, err || new RequestAbortedError()); + if (request.completed) { + if (request.upgrade || request.method === "CONNECT") { + util4.destroy(socket, new InformationalError("aborted")); + } + return; + } + util4.errorRequest(client, request, error2 || new RequestAbortedError()); util4.destroy(body); util4.destroy(socket, new InformationalError("aborted")); }; @@ -6795,6 +6857,7 @@ var require_client_h2 = __commonJS({ "node_modules/@actions/http-client/node_modules/undici/lib/dispatcher/client-h2.js"(exports2, module2) { "use strict"; var assert = require("node:assert"); + var { errorMonitor } = require("node:events"); var { pipeline } = require("node:stream"); var util4 = require_util(); var { @@ -6855,6 +6918,10 @@ var require_client_h2 = __commonJS({ } return result; } + function parseH2ResponseHeaders(headers) { + const { [HTTP2_HEADER_STATUS]: _statusCode, ...realHeaders } = headers; + return parseH2Headers(realHeaders); + } async function connectH2(client, socket) { client[kSocket] = socket; if (!h2ExperimentalWarned) { @@ -7018,16 +7085,22 @@ var require_client_h2 = __commonJS({ const { hostname, port } = client[kUrl]; headers[HTTP2_HEADER_AUTHORITY] = host || `${hostname}${port ? `:${port}` : ""}`; headers[HTTP2_HEADER_METHOD] = method; - const abort = (err) => { - if (request.aborted || request.completed) { + const abort = (error2) => { + if (request.aborted) { return; } - err = err || new RequestAbortedError(); - util4.errorRequest(client, request, err); + if (request.completed) { + if (method === "CONNECT" && stream4 != null) { + util4.destroy(stream4, error2 || new RequestAbortedError()); + } + return; + } + error2 = error2 || new RequestAbortedError(); + util4.errorRequest(client, request, error2); if (stream4 != null) { - util4.destroy(stream4, err); + util4.destroy(stream4, error2); } - util4.destroy(body, err); + util4.destroy(body, error2); client[kQueue][client[kRunningIdx]++] = null; client[kResume](); }; @@ -7042,18 +7115,42 @@ var require_client_h2 = __commonJS({ if (method === "CONNECT") { session.ref(); stream4 = session.request(headers, { endStream: false, signal }); - if (stream4.id && !stream4.pending) { - request.onUpgrade(null, null, stream4); - ++session[kOpenStreams]; - client[kQueue][client[kRunningIdx]++] = null; - } else { - stream4.once("ready", () => { + let upgradeResponseFinished = false; + const onResponse = (headers2) => { + upgradeResponseFinished = true; + stream4.off(errorMonitor, onUpgradeError); + request.onUpgradeResponse(Number(headers2[HTTP2_HEADER_STATUS]), headers2, parseH2ResponseHeaders); + }; + const onUpgradeError = (error2) => { + upgradeResponseFinished = true; + stream4.off("response", onResponse); + request.onUpgradeError(error2); + }; + const onReady = () => { + try { request.onUpgrade(null, null, stream4); - ++session[kOpenStreams]; - client[kQueue][client[kRunningIdx]++] = null; - }); - } + } catch (error2) { + stream4.off("response", onResponse); + abort(error2); + return; + } + if (request.aborted) { + return; + } + stream4.off("error", abort); + stream4.once(errorMonitor, onUpgradeError); + client[kQueue][client[kRunningIdx]++] = null; + }; + stream4.once("response", onResponse); + stream4.once("error", abort); + ++session[kOpenStreams]; + onReady(); stream4.once("close", () => { + if (!upgradeResponseFinished && request.completed) { + stream4.off("response", onResponse); + stream4.off(errorMonitor, onUpgradeError); + request.onUpgradeError(new InformationalError(`HTTP/2: "stream error" received - code ${stream4.rstCode}`)); + } session[kOpenStreams] -= 1; if (session[kOpenStreams] === 0) session.unref(); }); @@ -9036,6 +9133,7 @@ var require_retry_handler = __commonJS({ this.end = null; this.etag = null; this.resume = null; + this.headersSent = false; this.handler.onConnect((reason) => { this.aborted = true; if (this.abort) { @@ -9045,6 +9143,17 @@ var require_retry_handler = __commonJS({ } }); } + checkpointResponseEnd(headers, resume) { + if (this.end == null && this.opts.method !== "HEAD") { + const contentLength = headers["content-length"]; + this.end = contentLength != null ? Number(contentLength) - 1 : null; + assert( + this.end == null || Number.isFinite(this.end), + "invalid content-length" + ); + } + this.resume = this.end != null ? resume : null; + } onRequestSent() { if (this.handler.onRequestSent) { this.handler.onRequestSent(); @@ -9106,7 +9215,9 @@ var require_retry_handler = __commonJS({ const headers = parseHeaders(rawHeaders); this.retryCount += 1; if (statusCode >= 300) { - if (this.retryOpts.statusCodes.includes(statusCode) === false) { + if (!this.headersSent && this.retryOpts.statusCodes.includes(statusCode) === false) { + this.headersSent = true; + this.checkpointResponseEnd(headers, resume); return this.handler.onHeaders( statusCode, rawHeaders, @@ -9161,8 +9272,15 @@ var require_retry_handler = __commonJS({ return false; } const { start, size, end = size - 1 } = contentRange; - assert(this.start === start, "content-range mismatch"); - assert(this.end == null || this.end === end, "content-range mismatch"); + if (this.start !== start || this.end != null && this.end !== end) { + this.abort( + new RequestRetryError("Content-Range mismatch", statusCode, { + headers, + data: { count: this.retryCount } + }) + ); + return false; + } this.resume = resume; return true; } @@ -9170,6 +9288,7 @@ var require_retry_handler = __commonJS({ if (statusCode === 206) { const range = parseRangeHeader(headers["content-range"]); if (range == null) { + this.headersSent = true; return this.handler.onHeaders( statusCode, rawHeaders, @@ -9201,6 +9320,7 @@ var require_retry_handler = __commonJS({ "invalid content-length" ); this.resume = resume; + this.headersSent = true; this.etag = headers.etag != null ? headers.etag : null; if (this.etag != null && this.etag.startsWith("W/")) { this.etag = null; @@ -9228,7 +9348,7 @@ var require_retry_handler = __commonJS({ return this.handler.onComplete(rawTrailers); } onError(err) { - if (this.aborted || isDisturbed(this.opts.body)) { + if (this.aborted || isDisturbed(this.opts.body) || this.headersSent && this.resume == null) { return this.handler.onError(err); } if (this.retryCount - this.retryCountCheckpoint > 0) { @@ -17114,7 +17234,7 @@ var require_connection = __commonJS({ const secProtocol = response.headersList.get("Sec-WebSocket-Protocol"); if (secProtocol !== null) { const requestProtocols = getDecodeSplit("sec-websocket-protocol", request.headersList); - if (!requestProtocols.includes(secProtocol)) { + if (requestProtocols === null || !requestProtocols.includes(secProtocol)) { failWebsocketConnection(ws, "Protocol was not set in the opening handshake."); return; } @@ -17262,6 +17382,7 @@ var require_permessage_deflate = __commonJS({ if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) { callback(new MessageSizeExceededError()); this.#inflate.removeAllListeners(); + this.#inflate.destroy(); this.#inflate = null; return; } @@ -18173,6 +18294,40 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var DATA = Buffer.from("data"); + var EVENT = Buffer.from("event"); + var ID = Buffer.from("id"); + var RETRY = Buffer.from("retry"); + function isASCIINumberBytes(buffer, start) { + if (start >= buffer.length) { + return false; + } + for (let i = start; i < buffer.length; i++) { + if (buffer[i] < 48 || buffer[i] > 57) { + return false; + } + } + return true; + } + function isValidLastEventIdBytes(buffer, start) { + for (let i = start; i < buffer.length; i++) { + if (buffer[i] === 0) { + return false; + } + } + return true; + } + function isFieldName(line, length, field) { + if (length !== field.length) { + return false; + } + for (let i = 0; i < length; i++) { + if (line[i] !== field[i]) { + return false; + } + } + return true; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18192,10 +18347,13 @@ var require_eventsource_stream = __commonJS({ */ eventEndCheck = false; /** - * @type {Buffer} + * @type {Buffer[]} */ - buffer = null; + chunks = []; + chunkIndex = 0; pos = 0; + lineChunkIndex = 0; + linePos = 0; event = { data: void 0, event: void 0, @@ -18226,63 +18384,30 @@ var require_eventsource_stream = __commonJS({ callback(); return; } - if (this.buffer) { - this.buffer = Buffer.concat([this.buffer, chunk]); - } else { - this.buffer = chunk; - } + this.chunks.push(chunk); if (this.checkBOM) { - switch (this.buffer.length) { - case 1: - if (this.buffer[0] === BOM[0]) { - callback(); - return; - } - this.checkBOM = false; - callback(); - return; - case 2: - if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1]) { - callback(); - return; - } - this.checkBOM = false; - break; - case 3: - if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) { - this.buffer = Buffer.alloc(0); - this.checkBOM = false; - callback(); - return; - } - this.checkBOM = false; - break; - default: - if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) { - this.buffer = this.buffer.subarray(3); - } - this.checkBOM = false; - break; + if (this.handleBOM()) { + callback(); + return; } } - while (this.pos < this.buffer.length) { + while (this.hasCurrentByte()) { + const byte = this.currentByte(); if (this.eventEndCheck) { if (this.crlfCheck) { - if (this.buffer[this.pos] === LF) { - this.buffer = this.buffer.subarray(this.pos + 1); - this.pos = 0; + if (byte === LF) { this.crlfCheck = false; + this.consumeCurrentByte(); continue; } this.crlfCheck = false; } - if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { - if (this.buffer[this.pos] === CR) { + if (byte === LF || byte === CR) { + if (byte === CR) { this.crlfCheck = true; } - this.buffer = this.buffer.subarray(this.pos + 1); - this.pos = 0; - if (this.event.data !== void 0 || this.event.event || this.event.id || this.event.retry) { + this.consumeCurrentByte(); + if (this.hasPendingEvent()) { this.processEvent(this.event); } this.clearEvent(); @@ -18291,17 +18416,16 @@ var require_eventsource_stream = __commonJS({ this.eventEndCheck = false; continue; } - if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { - if (this.buffer[this.pos] === CR) { + if (byte === LF || byte === CR) { + if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.buffer.subarray(0, this.pos), this.event); - this.buffer = this.buffer.subarray(this.pos + 1); - this.pos = 0; + this.parseLine(this.readLine(), this.event); + this.consumeCurrentByte(); this.eventEndCheck = true; continue; } - this.pos++; + this.advanceCursor(); } callback(); } @@ -18317,43 +18441,42 @@ var require_eventsource_stream = __commonJS({ if (colonPosition === 0) { return; } - let field = ""; - let value = ""; + let fieldLength = line.length; + let valueStart = line.length; if (colonPosition !== -1) { - field = line.subarray(0, colonPosition).toString("utf8"); - let valueStart = colonPosition + 1; + fieldLength = colonPosition; + valueStart = colonPosition + 1; if (line[valueStart] === SPACE) { ++valueStart; } - value = line.subarray(valueStart).toString("utf8"); - } else { - field = line.toString("utf8"); - value = ""; } - switch (field) { - case "data": - if (event[field] === void 0) { - event[field] = value; - } else { - event[field] += ` + if (isFieldName(line, fieldLength, DATA)) { + const value = line.toString("utf8", valueStart); + if (event.data === void 0) { + event.data = value; + } else { + event.data += ` ${value}`; - } - break; - case "retry": - if (isASCIINumber(value)) { - event[field] = value; - } - break; - case "id": - if (isValidLastEventId(value)) { - event[field] = value; - } - break; - case "event": - if (value.length > 0) { - event[field] = value; - } - break; + } + return; + } + if (isFieldName(line, fieldLength, RETRY)) { + if (isASCIINumberBytes(line, valueStart)) { + event.retry = line.toString("utf8", valueStart); + } + return; + } + if (isFieldName(line, fieldLength, ID)) { + if (isValidLastEventIdBytes(line, valueStart)) { + event.id = line.toString("utf8", valueStart); + } + return; + } + if (isFieldName(line, fieldLength, EVENT)) { + const value = line.toString("utf8", valueStart); + if (value.length > 0) { + event.event = value; + } } } /** @@ -18378,12 +18501,120 @@ ${value}`; } } clearEvent() { - this.event = { - data: void 0, - event: void 0, - id: void 0, - retry: void 0 - }; + this.event.data = void 0; + this.event.event = void 0; + this.event.id = void 0; + this.event.retry = void 0; + } + hasPendingEvent() { + return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; + } + hasCurrentByte() { + return this.chunkIndex < this.chunks.length && this.pos < this.chunks[this.chunkIndex].length; + } + currentByte() { + return this.chunks[this.chunkIndex][this.pos]; + } + consumeCurrentByte() { + this.advanceCursor(); + this.syncLineStartToCursor(); + } + advanceCursor() { + this.pos++; + while (this.chunkIndex < this.chunks.length && this.pos >= this.chunks[this.chunkIndex].length) { + this.chunkIndex++; + this.pos = 0; + } + } + syncLineStartToCursor() { + this.lineChunkIndex = this.chunkIndex; + this.linePos = this.pos; + this.dropConsumedChunks(); + } + dropConsumedChunks() { + while (this.lineChunkIndex > 0) { + this.chunks.shift(); + this.lineChunkIndex--; + this.chunkIndex--; + } + if (this.chunkIndex === this.chunks.length) { + this.chunks.length = 0; + this.chunkIndex = 0; + this.pos = 0; + this.lineChunkIndex = 0; + this.linePos = 0; + } + } + readLine() { + if (this.lineChunkIndex === this.chunkIndex) { + return this.chunks[this.chunkIndex].subarray(this.linePos, this.pos); + } + const chunks = []; + let length = 0; + for (let i = this.lineChunkIndex; i <= this.chunkIndex; i++) { + const chunk = this.chunks[i]; + const start = i === this.lineChunkIndex ? this.linePos : 0; + const end = i === this.chunkIndex ? this.pos : chunk.length; + const slice = chunk.subarray(start, end); + length += slice.length; + chunks.push(slice); + } + return Buffer.concat(chunks, length); + } + peekBufferedByte(offset) { + let chunkIndex = this.lineChunkIndex; + let pos = this.linePos; + while (chunkIndex < this.chunks.length) { + const chunk = this.chunks[chunkIndex]; + const remaining = chunk.length - pos; + if (offset < remaining) { + return chunk[pos + offset]; + } + offset -= remaining; + chunkIndex++; + pos = 0; + } + } + discardLeadingBytes(count) { + while (count > 0 && this.lineChunkIndex < this.chunks.length) { + const chunk = this.chunks[this.lineChunkIndex]; + const remaining = chunk.length - this.linePos; + if (count < remaining) { + this.linePos += count; + count = 0; + } else { + count -= remaining; + this.lineChunkIndex++; + this.linePos = 0; + } + } + this.chunkIndex = this.lineChunkIndex; + this.pos = this.linePos; + this.dropConsumedChunks(); + } + handleBOM() { + const first = this.peekBufferedByte(0); + const second = this.peekBufferedByte(1); + const third = this.peekBufferedByte(2); + if (second === void 0) { + if (first === BOM[0]) { + return true; + } + this.checkBOM = false; + return true; + } + if (third === void 0) { + if (first === BOM[0] && second === BOM[1]) { + return true; + } + this.checkBOM = false; + return false; + } + if (first === BOM[0] && second === BOM[1] && third === BOM[2]) { + this.discardLeadingBytes(3); + } + this.checkBOM = false; + return !this.hasCurrentByte(); } }; module2.exports = { @@ -19996,6 +20227,8 @@ var require_symbols6 = __commonJS({ kDestroy: /* @__PURE__ */ Symbol("destroy"), kDispatch: /* @__PURE__ */ Symbol("dispatch"), kUrl: /* @__PURE__ */ Symbol("url"), + kRequestOrigin: /* @__PURE__ */ Symbol("request origin"), + kOriginless: /* @__PURE__ */ Symbol("originless"), kWriting: /* @__PURE__ */ Symbol("writing"), kResuming: /* @__PURE__ */ Symbol("resuming"), kQueue: /* @__PURE__ */ Symbol("queue"), @@ -21330,37 +21563,6 @@ var require_util9 = __commonJS({ bytesRead: socket.bytesRead }; } - function ReadableStreamFrom(iterable) { - let iterator2; - return new ReadableStream( - { - start() { - iterator2 = iterable[Symbol.asyncIterator](); - }, - pull(controller) { - return iterator2.next().then(({ done, value }) => { - if (done) { - return queueMicrotask(() => { - controller.close(); - controller.byobRequest?.respond(0); - }); - } else { - const buf = Buffer.isBuffer(value) ? value : Buffer.from(value); - if (buf.byteLength) { - return controller.enqueue(new Uint8Array(buf)); - } else { - return this.pull(controller); - } - } - }); - }, - cancel() { - return iterator2.return(); - }, - type: "bytes" - } - ); - } function isFormDataLike(object) { return object && typeof object === "object" && typeof object.append === "function" && typeof object.delete === "function" && typeof object.get === "function" && typeof object.getAll === "function" && typeof object.has === "function" && typeof object.set === "function" && object[Symbol.toStringTag] === "FormData"; } @@ -21821,7 +22023,6 @@ var require_util9 = __commonJS({ destroy, bodyLength, deepClone, - ReadableStreamFrom, isBuffer: isBuffer2, assertRequestHandler, getSocketInfo, @@ -22390,15 +22591,32 @@ var require_request3 = __commonJS({ return false; } } - onRequestUpgrade(statusCode, headers, socket) { + /** + * @param {number} statusCode + * @param {Buffer[]|string[]|import('../../types/header.d.ts').IncomingHttpHeaders} headers + * @param {import('node:stream').Duplex} socket + * @param {string} [statusText] + */ + onRequestUpgrade(statusCode, headers, socket, statusText = "") { + this.onFinally(); assert(!this.aborted); assert(!this.completed); + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }); + } const controller = this[kController]; if (controller) { controller.rawHeaders = headers; } const parsedHeaders = Array.isArray(headers) ? parseHeaders(headers) : headers; - return this[kHandler].onRequestUpgrade?.(controller, statusCode, parsedHeaders, socket); + const result = this[kHandler].onRequestUpgrade?.(controller, statusCode, parsedHeaders, socket); + if (!this.aborted) { + this.completed = true; + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers: [] }); + } + } + return result; } onResponseEnd(trailers) { this.onFinally(); @@ -22542,6 +22760,7 @@ var require_dispatcher2 = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher.js"(exports2, module2) { "use strict"; var EventEmitter2 = require("node:events"); + var { kOriginless, kUrl } = require_symbols6(); var Dispatcher = class extends EventEmitter2 { dispatch() { throw new Error("not implemented"); @@ -22554,6 +22773,7 @@ var require_dispatcher2 = __commonJS({ } compose(...args) { const interceptors = Array.isArray(args[0]) ? args[0] : args; + const interceptorOrigin = this[kOriginless] === true ? null : this[kUrl]?.origin; let dispatch = this.dispatch.bind(this); for (const interceptor of interceptors) { if (interceptor == null) { @@ -22562,11 +22782,19 @@ var require_dispatcher2 = __commonJS({ if (typeof interceptor !== "function") { throw new TypeError(`invalid interceptor, expected function received ${typeof interceptor}`); } - dispatch = interceptor(dispatch); + dispatch = interceptor(dispatch, interceptorOrigin); if (dispatch == null || typeof dispatch !== "function" || dispatch.length !== 2) { throw new TypeError("invalid interceptor"); } } + const originalDispatch = dispatch; + const self2 = this; + dispatch = function(opts, handler) { + if (opts && typeof opts === "object" && !opts.origin && self2[kUrl]) { + opts = Object.assign({}, opts, { origin: self2[kUrl].origin }); + } + return originalDispatch(opts, handler); + }; return new Proxy(this, { get: (target, key) => key === "dispatch" ? dispatch : target[key] }); @@ -22580,6 +22808,7 @@ var require_dispatcher2 = __commonJS({ var require_dispatcher_base2 = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports2, module2) { "use strict"; + var buffer = require("node:buffer"); var Dispatcher = require_dispatcher2(); var { ClientDestroyedError, @@ -22590,6 +22819,7 @@ var require_dispatcher_base2 = __commonJS({ var kOnDestroyed = /* @__PURE__ */ Symbol("onDestroyed"); var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { /** @type {boolean} */ [kDestroyed] = false; @@ -22605,9 +22835,10 @@ var require_dispatcher_base2 = __commonJS({ constructor(opts) { super(); this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } /** - * @returns {import('../../types/dispatcher').WebSocketOptions} + * @returns {import('../../types/client').Client.WebSocketOptions} */ get webSocketOptions() { return { @@ -22616,6 +22847,14 @@ var require_dispatcher_base2 = __commonJS({ // 128 MB default }; } + /** + * @returns {import('../../types/client').Client.EventSourceOptions} + */ + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } /** @returns {boolean} */ get destroyed() { return this[kDestroyed]; @@ -23905,6 +24144,10 @@ var require_infra = __commonJS({ assert(!invalidIsomorphicEncodeValueRegex.test(input)); return input; } + var nonASCIIRegex = /[^\x00-\x7F]/; + function asciiLowercase(str) { + return nonASCIIRegex.test(str) ? str.replace(/[A-Z]+/g, (upper) => upper.toLowerCase()) : str.toLowerCase(); + } function parseJSONFromBytes(bytes) { return JSON.parse(utf8DecodeBytes(bytes)); } @@ -23918,7 +24161,7 @@ var require_infra = __commonJS({ while (lead < str.length && predicate(str.charCodeAt(lead))) lead++; } if (trailing) { - while (trail > 0 && predicate(str.charCodeAt(trail))) trail--; + while (trail >= lead && predicate(str.charCodeAt(trail))) trail--; } return lead === 0 && trail === str.length - 1 ? str : str.slice(lead, trail + 1); } @@ -23931,6 +24174,7 @@ var require_infra = __commonJS({ return result; } module2.exports = { + asciiLowercase, collectASequenceOfCodePoints, collectASequenceOfCodePointsFast, forgivingBase64, @@ -23950,9 +24194,9 @@ var require_data_url2 = __commonJS({ "node_modules/undici/lib/web/fetch/data-url.js"(exports2, module2) { "use strict"; var assert = require("node:assert"); - var { forgivingBase64, collectASequenceOfCodePoints, collectASequenceOfCodePointsFast, isomorphicDecode, removeASCIIWhitespace, removeChars } = require_infra(); + var { asciiLowercase, forgivingBase64, collectASequenceOfCodePoints, collectASequenceOfCodePointsFast, isomorphicDecode, removeASCIIWhitespace, removeChars } = require_infra(); var encoder = new TextEncoder(); - var HTTP_TOKEN_CODEPOINTS = /^[-!#$%&'*+.^_|~A-Za-z0-9]+$/u; + var HTTP_TOKEN_CODEPOINTS = /^[-!#$%&'*+.^_`|~A-Za-z0-9]+$/u; var HTTP_WHITESPACE_REGEX = /[\u000A\u000D\u0009\u0020]/u; var HTTP_QUOTED_STRING_TOKENS = /^[\u0009\u0020-\u007E\u0080-\u00FF]+$/u; function dataURLProcessor(dataURL) { @@ -23973,7 +24217,7 @@ var require_data_url2 = __commonJS({ position.position++; const encodedBody = input.slice(mimeTypeLength + 1); let body = stringPercentDecode(encodedBody); - if (/;(?:\u0020*)base64$/ui.test(mimeType)) { + if (/;\u0020*[Bb][Aa][Ss][Ee]64$/u.test(mimeType)) { const stringBody = isomorphicDecode(body); body = forgivingBase64(stringBody); if (body === "failure") { @@ -24060,8 +24304,8 @@ var require_data_url2 = __commonJS({ if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { return "failure"; } - const typeLowercase = type.toLowerCase(); - const subtypeLowercase = subtype.toLowerCase(); + const typeLowercase = asciiLowercase(type); + const subtypeLowercase = asciiLowercase(subtype); const mimeType = { type: typeLowercase, subtype: subtypeLowercase, @@ -24083,7 +24327,7 @@ var require_data_url2 = __commonJS({ input, position ); - parameterName = parameterName.toLowerCase(); + parameterName = asciiLowercase(parameterName); if (position.position < input.length) { if (input[position.position] === ";") { continue; @@ -24263,23 +24507,13 @@ var require_webidl2 = __commonJS({ message: `"${context.value}" is an invalid ${context.type}.` }); }; - webidl.brandCheck = function(V, I) { - if (!FunctionPrototypeSymbolHasInstance(I, V)) { + webidl.brandCheck = function(V, is) { + if (!is(V)) { const err = new TypeError("Illegal invocation"); err.code = "ERR_INVALID_THIS"; throw err; } }; - webidl.brandCheckMultiple = function(List) { - const prototypes = List.map((c) => webidl.util.MakeTypeAssertion(c)); - return (V) => { - if (prototypes.every((typeCheck) => !typeCheck(V))) { - const err = new TypeError("Illegal invocation"); - err.code = "ERR_INVALID_THIS"; - throw err; - } - }; - }; webidl.argumentLengthCheck = function({ length }, min, ctx) { if (length < min) { throw webidl.errors.exception({ @@ -24835,7 +25069,7 @@ var require_util10 = __commonJS({ var { getGlobalOrigin } = require_global3(); var { collectAnHTTPQuotedString, parseMIMEType } = require_data_url2(); var { performance: performance2 } = require("node:perf_hooks"); - var { ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = require_util9(); + var { isValidHTTPToken, normalizedMethodRecordsBase } = require_util9(); var assert = require("node:assert"); var { isUint8Array } = require("node:util/types"); var { webidl } = require_webidl2(); @@ -24932,6 +25166,9 @@ var require_util10 = __commonJS({ return "success"; } function appendFetchMetadata(httpRequest) { + if (!isURLPotentiallyTrustworthy(requestCurrentURL(httpRequest))) { + return; + } let header = null; header = httpRequest.mode; httpRequest.headersList.set("sec-fetch-mode", header, true); @@ -25228,7 +25465,7 @@ var require_util10 = __commonJS({ return new FastIterableIterator(target, kind); }; } - function iteratorMixin(name, object, kInternalIterator, keyIndex = 0, valueIndex = 1) { + function iteratorMixin(name, object, kInternalIterator, keyIndex = 0, valueIndex = 1, brandCheck) { const makeIterator = createIterator(name, kInternalIterator, keyIndex, valueIndex); const properties = { keys: { @@ -25236,7 +25473,7 @@ var require_util10 = __commonJS({ enumerable: true, configurable: true, value: function keys() { - webidl.brandCheck(this, object); + webidl.brandCheck(this, brandCheck); return makeIterator(this, "key"); } }, @@ -25245,7 +25482,7 @@ var require_util10 = __commonJS({ enumerable: true, configurable: true, value: function values() { - webidl.brandCheck(this, object); + webidl.brandCheck(this, brandCheck); return makeIterator(this, "value"); } }, @@ -25254,7 +25491,7 @@ var require_util10 = __commonJS({ enumerable: true, configurable: true, value: function entries() { - webidl.brandCheck(this, object); + webidl.brandCheck(this, brandCheck); return makeIterator(this, "key+value"); } }, @@ -25263,7 +25500,7 @@ var require_util10 = __commonJS({ enumerable: true, configurable: true, value: function forEach2(callbackfn, thisArg = globalThis) { - webidl.brandCheck(this, object); + webidl.brandCheck(this, brandCheck); webidl.argumentLengthCheck(arguments, 1, `${name}.forEach`); if (typeof callbackfn !== "function") { throw new TypeError( @@ -25544,7 +25781,6 @@ var require_util10 = __commonJS({ isAborted, isCancelled, isValidEncodedURL, - ReadableStreamFrom, tryUpgradeRequestToAPotentiallyTrustworthyURL, clampAndCoarsenConnectionTimingInfo, coarsenedSharedCurrentTime, @@ -25677,7 +25913,10 @@ var require_formdata2 = __commonJS({ var nodeUtil = require("node:util"); var { runtimeFeatures } = require_runtime_features(); var random = runtimeFeatures.has("crypto") ? require("node:crypto").randomInt : (max) => Math.floor(Math.random() * max); - var FormData3 = class _FormData { + var getFormDataState; + var setFormDataState; + var getFormDataBoundary; + var FormData3 = class { #state = []; #boundary = null; constructor(form = void 0) { @@ -25691,7 +25930,7 @@ var require_formdata2 = __commonJS({ } } append(name, value, filename = void 0) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix = "FormData.append"; webidl.argumentLengthCheck(arguments, 2, prefix); name = webidl.converters.USVString(name); @@ -25707,14 +25946,14 @@ var require_formdata2 = __commonJS({ this.#state.push(entry); } delete(name) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix = "FormData.delete"; webidl.argumentLengthCheck(arguments, 1, prefix); name = webidl.converters.USVString(name); this.#state = this.#state.filter((entry) => entry.name !== name); } get(name) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix = "FormData.get"; webidl.argumentLengthCheck(arguments, 1, prefix); name = webidl.converters.USVString(name); @@ -25725,21 +25964,21 @@ var require_formdata2 = __commonJS({ return this.#state[idx].value; } getAll(name) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix = "FormData.getAll"; webidl.argumentLengthCheck(arguments, 1, prefix); name = webidl.converters.USVString(name); return this.#state.filter((entry) => entry.name === name).map((entry) => entry.value); } has(name) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix = "FormData.has"; webidl.argumentLengthCheck(arguments, 1, prefix); name = webidl.converters.USVString(name); return this.#state.findIndex((entry) => entry.name === name) !== -1; } set(name, value, filename = void 0) { - webidl.brandCheck(this, _FormData); + webidl.brandCheck(this, webidl.is.FormData); const prefix = "FormData.set"; webidl.argumentLengthCheck(arguments, 2, prefix); name = webidl.converters.USVString(name); @@ -25781,34 +26020,20 @@ var require_formdata2 = __commonJS({ const output = nodeUtil.formatWithOptions(options, state); return `FormData ${output.slice(output.indexOf("]") + 2)}`; } - /** - * @param {FormData} formData - */ - static getFormDataState(formData) { - return formData.#state; - } - /** - * @param {FormData} formData - * @param {any[]} newState - */ - static setFormDataState(formData, newState) { - formData.#state = newState; - } - /** - * @param {FormData} formData - * @returns {string | null} - */ - static getFormDataBoundary(formData) { - const boundary = formData.#boundary; - if (boundary != null) return boundary; - return formData.#boundary = `----formdata-undici-0${`${random(1e11)}`.padStart(11, "0")}`; + static { + getFormDataState = (formData) => formData.#state; + setFormDataState = (formData, newState) => { + formData.#state = newState; + }; + getFormDataBoundary = (formData) => { + return formData.#boundary ??= `----formdata-undici-0${`${random(1e11)}`.padStart(11, "0")}`; + }; + webidl.is.FormData = (arg) => { + return arg != null && typeof arg === "object" && #state in arg; + }; } }; - var { getFormDataState, setFormDataState, getFormDataBoundary } = FormData3; - Reflect.deleteProperty(FormData3, "getFormDataState"); - Reflect.deleteProperty(FormData3, "setFormDataState"); - Reflect.deleteProperty(FormData3, "getFormDataBoundary"); - iteratorMixin("FormData", FormData3, getFormDataState, "name", "value"); + iteratorMixin("FormData", FormData3, getFormDataState, "name", "value", webidl.is.FormData); Object.defineProperties(FormData3.prototype, { append: kEnumerableProperty, delete: kEnumerableProperty, @@ -25837,7 +26062,6 @@ var require_formdata2 = __commonJS({ } return { name, value }; } - webidl.is.FormData = webidl.util.MakeTypeAssertion(FormData3); module2.exports = { FormData: FormData3, makeEntry, setFormDataState, getFormDataBoundary }; } }); @@ -26178,7 +26402,6 @@ var require_body2 = __commonJS({ "use strict"; var util4 = require_util9(); var { - ReadableStreamFrom, readableStreamClose, fullyReadBody, extractMimeType @@ -26298,7 +26521,14 @@ Content-Type: ${value.type || "application/octet-stream"}\r "Response body object should not be disturbed or locked" ); } - stream4 = webidl.is.ReadableStream(object) ? object : ReadableStreamFrom(object); + stream4 = webidl.is.ReadableStream(object) ? object : ReadableStream.from(object).pipeThrough(new TransformStream({ + transform(chunk, controller2) { + const bytes = isUint8Array(chunk) ? chunk : Buffer.from(chunk); + if (bytes.byteLength) { + controller2.enqueue(bytes); + } + } + })); } if (typeof source === "string" || isUint8Array(source)) { action = () => { @@ -26343,7 +26573,7 @@ Content-Type: ${value.type || "application/octet-stream"}\r source: body.source }; } - function bodyMixinMethods(instance, getInternalState) { + function bodyMixinMethods(brandCheck, getInternalState) { const methods = { blob() { return consumeBody(this, (bytes) => { @@ -26354,18 +26584,18 @@ Content-Type: ${value.type || "application/octet-stream"}\r mimeType = serializeAMimeType(mimeType); } return new Blob([bytes], { type: mimeType }); - }, instance, getInternalState); + }, brandCheck, getInternalState); }, arrayBuffer() { return consumeBody(this, (bytes) => { return new Uint8Array(bytes).buffer; - }, instance, getInternalState); + }, brandCheck, getInternalState); }, text() { - return consumeBody(this, utf8DecodeBytes, instance, getInternalState); + return consumeBody(this, utf8DecodeBytes, brandCheck, getInternalState); }, json() { - return consumeBody(this, parseJSONFromBytes, instance, getInternalState); + return consumeBody(this, parseJSONFromBytes, brandCheck, getInternalState); }, formData() { return consumeBody(this, (value) => { @@ -26391,12 +26621,12 @@ Content-Type: ${value.type || "application/octet-stream"}\r throw new TypeError( 'Content-Type was not one of "multipart/form-data" or "application/x-www-form-urlencoded".' ); - }, instance, getInternalState); + }, brandCheck, getInternalState); }, bytes() { return consumeBody(this, (bytes) => { return new Uint8Array(bytes); - }, instance, getInternalState); + }, brandCheck, getInternalState); }, textStream() { const this_ = getInternalState(this); @@ -26424,12 +26654,12 @@ Content-Type: ${value.type || "application/octet-stream"}\r }; return methods; } - function mixinBody(prototype2, getInternalState) { - Object.assign(prototype2.prototype, bodyMixinMethods(prototype2, getInternalState)); + function mixinBody(prototype2, getInternalState, brandCheck) { + Object.assign(prototype2.prototype, bodyMixinMethods(brandCheck, getInternalState)); } - function consumeBody(object, convertBytesToJSValue, instance, getInternalState) { + function consumeBody(object, convertBytesToJSValue, brandCheck, getInternalState) { try { - webidl.brandCheck(object, instance); + webidl.brandCheck(object, brandCheck); } catch (e) { return Promise.reject(e); } @@ -26543,7 +26773,13 @@ var require_client_h12 = __commonJS({ function lazyllhttp() { const llhttpWasmData = process.env.JEST_WORKER_ID ? require_llhttp_wasm2() : void 0; let mod; - let useWasmSIMD = process.arch !== "ppc64"; + let useWasmSIMD = true; + if (process.arch === "ppc64") { + const [major, minor] = process.versions.node.split(".").map((n) => parseInt(n, 10)); + if (major < 24 || major === 24 && minor < 12) { + useWasmSIMD = false; + } + } if (process.env.UNDICI_NO_WASM_SIMD === "1") { useWasmSIMD = false; } else if (process.env.UNDICI_NO_WASM_SIMD === "0") { @@ -26918,7 +27154,7 @@ var require_client_h12 = __commonJS({ * @param {Buffer} head */ onUpgrade(head) { - const { upgrade, client, socket, headers, statusCode } = this; + const { upgrade, client, socket, headers, statusCode, statusText } = this; assert(upgrade); assert(client[kSocket] === socket); assert(!socket.destroyed); @@ -26943,8 +27179,9 @@ var require_client_h12 = __commonJS({ client[kQueue][client[kRunningIdx]++] = null; client.emit("disconnect", client[kUrl], [client], new InformationalError("upgrade")); try { - request.onRequestUpgrade(statusCode, headers, socket); + request.onRequestUpgrade(statusCode, headers, socket, statusText); } catch (err) { + util4.errorRequest(client, request, err); util4.destroy(socket, err); } client[kResume](); @@ -27275,21 +27512,20 @@ var require_client_h12 = __commonJS({ } function clearIdleSocketValidation(socket) { if (socket[kIdleSocketValidationTimeout]) { - clearTimeout(socket[kIdleSocketValidationTimeout]); + clearImmediate(socket[kIdleSocketValidationTimeout]); socket[kIdleSocketValidationTimeout] = null; } socket[kIdleSocketValidation] = 0; } function scheduleIdleSocketValidation(client, socket) { socket[kIdleSocketValidation] = 1; - socket[kIdleSocketValidationTimeout] = setTimeout(() => { + socket[kIdleSocketValidationTimeout] = setImmediate(() => { socket[kIdleSocketValidationTimeout] = null; socket[kIdleSocketValidation] = 2; if (client[kSocket] === socket && !socket.destroyed) { client[kResume](); } - }, 0); - socket[kIdleSocketValidationTimeout].unref?.(); + }); } function resumeH1(client) { const socket = client[kSocket]; @@ -27791,12 +28027,14 @@ var require_client_h22 = __commonJS({ var util4 = require_util9(); var { RequestContentLengthMismatchError, + ResponseContentLengthMismatchError, RequestAbortedError, SocketError, InformationalError, InvalidArgumentError, HeadersTimeoutError, - BodyTimeoutError + BodyTimeoutError, + ResponseExceededMaxSizeError } = require_errors2(); var { kUrl, @@ -27825,7 +28063,8 @@ var require_client_h22 = __commonJS({ kRemoteSettings, kHTTP2Stream, kHTTP2SessionState, - kHTTP2Options + kHTTP2Options, + kMaxResponseSize } = require_symbols6(); var { channels } = require_diagnostics2(); var kOpenStreams = /* @__PURE__ */ Symbol("open streams"); @@ -27938,6 +28177,10 @@ var require_client_h22 = __commonJS({ const { body } = request; return body == null || util4.isBuffer(body) || util4.isBlobLike(body); } + function hasResponseStarted(request) { + const state = request[kRequestStream]?.[kRequestStreamState]; + return state?.responseReceived === true; + } function registerGoAwayRefusal(request) { const attempts = (request[kGoAwayReplayAttempts] ?? 0) + 1; request[kGoAwayReplayAttempts] = attempts; @@ -28094,7 +28337,7 @@ var require_client_h22 = __commonJS({ const socket = client[kSocket]; const session = client[kHTTP2Session]; if (socket?.destroyed === false) { - if (client[kSize] === 0 || client[kMaxConcurrentStreams] === 0) { + if (session[kOpenStreams] === 0 && client[kSize] === 0) { unrefH2Session(session); } else { refH2Session(session); @@ -28251,8 +28494,9 @@ var require_client_h22 = __commonJS({ for (let i = pendingIdx; i < previousPendingIdx; i++) { const request = client[kQueue][i]; if (request != null) { + const responseStarted = hasResponseStarted(request); streamsToClose.push(detachRequestStreamForClose(request)); - if (canReplayRequest(request) && registerGoAwayRefusal(request)) { + if (!responseStarted && canReplayRequest(request) && registerGoAwayRefusal(request)) { retriableRequests.push(request); } else { util4.errorRequest(client, request, err); @@ -28344,9 +28588,10 @@ var require_client_h22 = __commonJS({ } function closeStreamSession(stream4) { const session = stream4[kHTTP2Session]; + const client = session[kClient]; stream4[kHTTP2Session] = null; session[kOpenStreams] -= 1; - if (session[kOpenStreams] === 0) { + if (session[kOpenStreams] === 0 && (client[kSize] === 0 || session[kReceivedGoAway])) { unrefH2Session(session); setHttp2IdleTimeout(session); } @@ -28461,8 +28706,13 @@ var require_client_h22 = __commonJS({ state.responseReceived = true; const statusCode = headers[HTTP2_HEADER_STATUS]; delete headers[HTTP2_HEADER_STATUS]; - request.onRequestUpgrade(statusCode, headers, stream4); - if (request.aborted || request.completed) { + try { + request.onRequestUpgrade(statusCode, headers, stream4); + } catch (err) { + state.abort(err); + return; + } + if (request.aborted) { return; } removeUpgradeStreamListeners(stream4); @@ -28529,13 +28779,16 @@ var require_client_h22 = __commonJS({ const state = { abort: null, body: request.body, + bytesRead: 0, client, contentLength: null, expectsPayload: false, + maxResponseSize: client[kMaxResponseSize], request, headersTimeout, bodyTimeout, requestFinalized: false, + responseContentLength: null, responseReceived: false, bodySent: false, pendingEnd: false, @@ -28670,6 +28923,7 @@ var require_client_h22 = __commonJS({ stream4.once("continue", writeBodyH2); } stream4.on("response", onResponse); + stream4.on("headers", onInterimResponse); stream4.on("end", onEnd); stream4.on("error", onError); stream4.on("frameError", onFrameError); @@ -28687,6 +28941,7 @@ var require_client_h22 = __commonJS({ stream4.off("error", noop2); stream4.off("continue", writeBodyH2); stream4.off("response", onResponse); + stream4.off("headers", onInterimResponse); stream4.off("end", onEnd); stream4.off("error", onError); stream4.off("frameError", onFrameError); @@ -28718,14 +28973,37 @@ var require_client_h22 = __commonJS({ if (state == null) { return; } - const { request } = state; + const { request, maxResponseSize, responseContentLength } = state; if (request.aborted || request.completed) { return; } + if (responseContentLength != null && state.bytesRead + chunk.length > responseContentLength) { + state.abort(new ResponseContentLengthMismatchError()); + return; + } + if (maxResponseSize > -1 && state.bytesRead + chunk.length > maxResponseSize) { + state.abort(new ResponseExceededMaxSizeError()); + return; + } + state.bytesRead += chunk.length; if (request.onResponseData(chunk) === false) { stream4.pause(); } } + function onInterimResponse(headers) { + const stream4 = this; + const state = stream4[kRequestStreamState]; + if (state == null) { + return; + } + const { request } = state; + if (request.aborted || request.completed) { + return; + } + const statusCode = headers[HTTP2_HEADER_STATUS]; + delete headers[HTTP2_HEADER_STATUS]; + request.onResponseStart(Number(statusCode), headers, noop2, ""); + } function onResponse(headers) { const stream4 = this; const state = stream4[kRequestStreamState]; @@ -28738,10 +29016,14 @@ var require_client_h22 = __commonJS({ stream4.removeListener("continue", writeBodyH2); stream4.end(); } - const statusCode = headers[HTTP2_HEADER_STATUS]; + const statusCode = Number(headers[HTTP2_HEADER_STATUS]); delete headers[HTTP2_HEADER_STATUS]; request.onResponseStarted(); state.responseReceived = true; + if (request.method !== "HEAD" && statusCode !== 304) { + const contentLength = headers[HTTP2_HEADER_CONTENT_LENGTH]; + state.responseContentLength = contentLength == null ? null : Number(contentLength); + } if (state.headersTimeout || state.bodyTimeout) { stream4.setTimeout(state.bodyTimeout); } @@ -28749,7 +29031,7 @@ var require_client_h22 = __commonJS({ releaseRequestStream(stream4); return; } - if (request.onResponseStart(Number(statusCode), headers, stream4.resume.bind(stream4), "") === false) { + if (request.onResponseStart(statusCode, headers, stream4.resume.bind(stream4), "") === false) { stream4.pause(); } stream4.on("data", onData); @@ -28764,6 +29046,10 @@ var require_client_h22 = __commonJS({ stream4.off("end", onEnd); if (state.responseReceived) { if (!request.aborted && !request.completed) { + if (state.responseContentLength != null && state.bytesRead !== state.responseContentLength) { + state.abort(new ResponseContentLengthMismatchError()); + return; + } state.pendingEnd = true; completeRequestStream.call(stream4); } @@ -28792,6 +29078,9 @@ var require_client_h22 = __commonJS({ return; } stream4.off("error", onError); + if (state.responseContentLength != null && state.bytesRead !== state.responseContentLength) { + err = new ResponseContentLengthMismatchError(); + } if (typeof stream4.rstCode === "number" && stream4.rstCode !== NGHTTP2_NO_ERROR) { err.http2ErrorCode = stream4.rstCode; } @@ -29145,7 +29434,8 @@ var require_client2 = __commonJS({ connectionWindowSize, pingInterval, webSocket, - h2Options + h2Options, + eventSource } = {}) { if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); @@ -29216,7 +29506,7 @@ var require_client2 = __commonJS({ if (h2Options.settings?.initialWindowSize != null && (!Number.isInteger(h2Options.settings.initialWindowSize) || h2Options.settings.initialWindowSize < 1)) { throw new InvalidArgumentError("h2Options.settings.initialWindowSize must be a positive integer, greater than 0"); } - if (h2Options.maxConcurrentStreams != null && (!Number.isInteger(h2Options.connectionWindowSize) || h2Options.maxConcurrentStreams < 1)) { + if (h2Options.maxConcurrentStreams != null && (!Number.isInteger(h2Options.maxConcurrentStreams) || h2Options.maxConcurrentStreams < 1)) { throw new InvalidArgumentError("h2Options.maxConcurrentStreams must be a positive integer, greater than 0"); } if (h2Options.connectionWindowSize != null && (!Number.isInteger(h2Options.connectionWindowSize) || h2Options.connectionWindowSize < 1)) { @@ -29248,7 +29538,7 @@ var require_client2 = __commonJS({ } } } - super({ webSocket }); + super({ webSocket, eventSource }); if (typeof connect2 !== "function") { connect2 = buildConnector({ ...tls, @@ -29575,6 +29865,10 @@ var require_client2 = __commonJS({ if (request === null) { return; } + if (request.aborted) { + client[kQueue].splice(client[kPendingIdx], 1); + continue; + } if (client[kUrl].protocol === "https:" && client[kServerName] !== request.servername) { if (client[kRunning] > 0) { return; @@ -29697,6 +29991,9 @@ var require_pool_base2 = __commonJS({ var kOnConnect = /* @__PURE__ */ Symbol("onConnect"); var kOnDisconnect = /* @__PURE__ */ Symbol("onDisconnect"); var kOnConnectionError = /* @__PURE__ */ Symbol("onConnectionError"); + var kOnClientBusy = /* @__PURE__ */ Symbol("on client busy"); + var kOnClientDrain = /* @__PURE__ */ Symbol("on client drain"); + var kDrainQueue = /* @__PURE__ */ Symbol("drain queue"); var kGetDispatcher = /* @__PURE__ */ Symbol("get dispatcher"); var kHasDispatcher = /* @__PURE__ */ Symbol("has dispatcher"); var kAddClient = /* @__PURE__ */ Symbol("add client"); @@ -29707,8 +30004,12 @@ var require_pool_base2 = __commonJS({ [kClients] = []; [kNeedDrain] = false; [kOnDrain](client, origin2, targets) { + if (client.closed || client.destroyed) { + return; + } const queue = this[kQueue]; let needDrain = false; + this[kOnClientDrain](client); while (!needDrain) { const item = queue.shift(); if (!item) { @@ -29718,6 +30019,9 @@ var require_pool_base2 = __commonJS({ needDrain = !client.dispatch(item.opts, item.handler); } client[kNeedDrain] = needDrain; + if (needDrain) { + this[kOnClientBusy](client); + } if (!needDrain && this[kNeedDrain]) { this[kNeedDrain] = false; this.emit("drain", origin2, [this, ...targets]); @@ -29733,6 +30037,45 @@ var require_pool_base2 = __commonJS({ return Promise.all(closeAll).then(this[kClosedResolve]); } } + [kOnClientBusy]() { + } + [kOnClientDrain]() { + } + [kDrainQueue](origin2, targets) { + const queue = this[kQueue]; + let hasDispatcher = true; + while (!queue.isEmpty()) { + const dispatcher = this[kGetDispatcher](); + if (!dispatcher) { + hasDispatcher = false; + break; + } + const item = queue.shift(); + this[kQueued]--; + if (!dispatcher.dispatch(item.opts, item.handler)) { + dispatcher[kNeedDrain] = true; + this[kOnClientBusy](dispatcher); + hasDispatcher = this[kHasDispatcher](); + if (!hasDispatcher) { + break; + } + } + } + if (hasDispatcher && this[kNeedDrain]) { + this[kNeedDrain] = false; + this.emit("drain", origin2, [this, ...targets]); + } + if (this[kClosedResolve] && queue.isEmpty()) { + const closeAll = []; + for (let i = 0; i < this[kClients].length; i++) { + const client = this[kClients][i]; + if (!client.destroyed) { + closeAll.push(client.close()); + } + } + return Promise.all(closeAll).then(this[kClosedResolve]); + } + } [kOnConnect] = (origin2, targets) => { this.emit("connect", origin2, [this, ...targets]); }; @@ -29821,6 +30164,7 @@ var require_pool_base2 = __commonJS({ this[kQueued]++; } else if (!dispatcher.dispatch(opts, handler)) { dispatcher[kNeedDrain] = true; + this[kOnClientBusy](dispatcher); this[kNeedDrain] = !this[kHasDispatcher](); } return !this[kNeedDrain]; @@ -29839,7 +30183,7 @@ var require_pool_base2 = __commonJS({ this[kClients].push(client); if (this[kNeedDrain]) { queueMicrotask(() => { - if (this[kNeedDrain]) { + if (this[kNeedDrain] && !client[kNeedDrain]) { this[kOnDrain](client, client[kUrl], [client, this]); } }); @@ -29862,6 +30206,9 @@ var require_pool_base2 = __commonJS({ kNeedDrain, kAddClient, kRemoveClient, + kDrainQueue, + kOnClientBusy, + kOnClientDrain, kGetDispatcher, kHasDispatcher }; @@ -29877,6 +30224,9 @@ var require_pool2 = __commonJS({ kClients, kNeedDrain, kAddClient, + kDrainQueue, + kOnClientBusy, + kOnClientDrain, kGetDispatcher, kHasDispatcher, kRemoveClient @@ -29886,14 +30236,27 @@ var require_pool2 = __commonJS({ InvalidArgumentError } = require_errors2(); var util4 = require_util9(); - var { kUrl } = require_symbols6(); + var { kConnecting, kHTTPContext, kUrl } = require_symbols6(); var buildConnector = require_connect2(); var kOptions = /* @__PURE__ */ Symbol("options"); var kConnections = /* @__PURE__ */ Symbol("connections"); var kFactory = /* @__PURE__ */ Symbol("factory"); + var kProtocol = /* @__PURE__ */ Symbol("protocol"); + var kProtocolProbe = /* @__PURE__ */ Symbol("protocol probe"); function defaultFactory(origin2, opts) { return new Client(origin2, opts); } + function shouldCreateProtocolProbe(pool, dispatcher) { + return dispatcher instanceof Client && pool[kProtocol] !== "h1" && (pool[kOptions].useH2c === true || pool[kUrl].protocol === "https:" && pool[kOptions].allowH2 !== false); + } + function createClient(pool) { + const dispatcher = pool[kFactory](pool[kUrl], pool[kOptions]); + if (shouldCreateProtocolProbe(pool, dispatcher)) { + pool[kProtocolProbe] = dispatcher; + } + pool[kAddClient](dispatcher); + return dispatcher; + } var Pool = class extends PoolBase { constructor(origin2, { connections, @@ -29936,22 +30299,58 @@ var require_pool2 = __commonJS({ this[kUrl] = util4.parseOrigin(origin2); this[kOptions] = { ...util4.deepClone(options), connect, allowH2, useH2c, clientTtl, socketPath }; this[kFactory] = factory2; + this[kProtocol] = null; + this[kProtocolProbe] = null; this.on("connect", (origin3, targets) => { if (clientTtl != null && clientTtl > 0) { for (const target of targets) { Object.assign(target, { ttl: Date.now() }); } } + const client = targets[targets.length - 1]; + if (client instanceof Client) { + this[kProtocol] = client[kHTTPContext]?.version; + } + if (client === this[kProtocolProbe]) { + if (this[kProtocol] !== "h2") { + this[kProtocolProbe] = null; + this[kDrainQueue](origin3, targets.slice(1)); + } + } }); - this.on("connectionError", (origin3, targets, error2) => { + this.on("disconnect", (origin3, targets) => { + if (targets.includes(this[kProtocolProbe])) { + this[kProtocolProbe] = null; + this[kDrainQueue](origin3, targets.slice(1)); + } + }); + this.on("connectionError", (origin3, targets) => { + let resumeQueued = false; for (const target of targets) { + if (target === this[kProtocolProbe]) { + this[kProtocolProbe] = null; + resumeQueued = true; + } const idx = this[kClients].indexOf(target); if (idx !== -1) { this[kClients].splice(idx, 1); } } + if (resumeQueued) { + this[kDrainQueue](origin3, targets.slice(1)); + } }); } + [kOnClientBusy](client) { + if (this[kProtocolProbe] === null && client[kConnecting] && shouldCreateProtocolProbe(this, client)) { + this[kProtocolProbe] = client; + } + } + [kOnClientDrain](client) { + if (client === this[kProtocolProbe]) { + this[kProtocolProbe] = null; + } + } [kGetDispatcher]() { const clientTtlOption = this[kOptions].clientTtl; for (let i = 0; i < this[kClients].length; i++) { @@ -29963,10 +30362,11 @@ var require_pool2 = __commonJS({ return client; } } + if (this[kProtocolProbe] !== null) { + return; + } if (!this[kConnections] || this[kClients].length < this[kConnections]) { - const dispatcher = this[kFactory](this[kUrl], this[kOptions]); - this[kAddClient](dispatcher); - return dispatcher; + return createClient(this); } } [kHasDispatcher]() { @@ -29980,9 +30380,11 @@ var require_pool2 = __commonJS({ return true; } } + if (this[kProtocolProbe] !== null) { + return false; + } if (!this[kConnections] || this[kClients].length < this[kConnections]) { - const dispatcher = this[kFactory](this[kUrl], this[kOptions]); - this[kAddClient](dispatcher); + createClient(this); return true; } return false; @@ -30009,7 +30411,7 @@ var require_balanced_pool2 = __commonJS({ kGetDispatcher } = require_pool_base2(); var Pool = require_pool2(); - var { kUrl } = require_symbols6(); + var { kOriginless, kUrl } = require_symbols6(); var util4 = require_util9(); var kFactory = /* @__PURE__ */ Symbol("factory"); var kOptions = /* @__PURE__ */ Symbol("options"); @@ -30032,12 +30434,15 @@ var require_balanced_pool2 = __commonJS({ return new Pool(origin2, opts); } var BalancedPool = class extends PoolBase { - constructor(upstreams = [], { factory: factory2 = defaultFactory, ...opts } = {}) { + constructor(upstreams = [], { factory: factory2 = defaultFactory, connect, tls, ...opts } = {}) { if (typeof factory2 !== "function") { throw new InvalidArgumentError("factory must be a function."); } - super(); - this[kOptions] = { ...util4.deepClone(opts) }; + super(opts); + this[kOriginless] = true; + if (connect && typeof connect !== "function") connect = { ...connect }; + if (tls && typeof tls !== "function") tls = { ...tls }; + this[kOptions] = { ...util4.deepClone(opts), connect, tls }; this[kIndex] = -1; this[kCurrentWeight] = 0; this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100; @@ -30199,7 +30604,7 @@ var require_round_robin_pool = __commonJS({ ...connect }); } - super(); + super(options); this[kConnections] = connections || null; this[kUrl] = util4.parseOrigin(origin2); this[kOptions] = { ...util4.deepClone(options), connect, allowH2, clientTtl, socketPath }; @@ -30279,7 +30684,7 @@ var require_agent2 = __commonJS({ "node_modules/undici/lib/dispatcher/agent.js"(exports2, module2) { "use strict"; var { InvalidArgumentError, MaxOriginsReachedError } = require_errors2(); - var { kBusy, kClients, kConnected, kRunning, kClose, kDestroy, kDispatch, kUrl } = require_symbols6(); + var { kBusy, kClients, kConnected, kRunning, kPending, kClose, kDestroy, kDispatch, kUrl } = require_symbols6(); var DispatcherBase = require_dispatcher_base2(); var Pool = require_pool2(); var Client = require_client2(); @@ -30352,7 +30757,7 @@ var require_agent2 = __commonJS({ if (this[kClients].get(key) !== dispatcher) { return; } - if (dispatcher[kConnected] > 0 || dispatcher[kBusy]) { + if (dispatcher[kConnected] > 0 || dispatcher[kBusy] || dispatcher[kPending] > 0) { return; } this[kClients].delete(key); @@ -30419,6 +30824,7 @@ var require_dispatcher1_wrapper = __commonJS({ var Dispatcher = require_dispatcher2(); var { InvalidArgumentError } = require_errors2(); var { toRawHeaders } = require_util9(); + var { kOriginless, kUrl } = require_symbols6(); var LegacyHandlerWrapper = class { #handler; constructor(handler) { @@ -30470,6 +30876,8 @@ var require_dispatcher1_wrapper = __commonJS({ throw new InvalidArgumentError("Argument dispatcher must implement dispatch"); } this.#dispatcher = dispatcher; + this[kUrl] = dispatcher[kUrl]; + this[kOriginless] = dispatcher[kOriginless]; } static wrapHandler(handler) { if (!handler || typeof handler !== "object") { @@ -30998,24 +31406,33 @@ var require_socks5_proxy_agent = __commonJS({ var { URL: URL2 } = require("node:url"); var tls; var DispatcherBase = require_dispatcher_base2(); - var { InvalidArgumentError } = require_errors2(); + var { ConnectTimeoutError, InvalidArgumentError } = require_errors2(); var { Socks5Client, STATES } = require_socks5_client(); var { kBusy, kConnected, kDispatch, kClose, kDestroy } = require_symbols6(); var Pool = require_pool2(); var buildConnector = require_connect2(); + var { setupConnectTimeout } = require_util9(); var { debuglog } = require("node:util"); var debug2 = debuglog("undici:socks5-proxy"); + var DEFAULT_SOCKS5_CONNECT_TIMEOUT = 5e3; var kProxyUrl = /* @__PURE__ */ Symbol("proxy url"); var kProxyHeaders = /* @__PURE__ */ Symbol("proxy headers"); var kProxyAuth = /* @__PURE__ */ Symbol("proxy auth"); var kProxyProtocol = /* @__PURE__ */ Symbol("proxy protocol"); var kPools = /* @__PURE__ */ Symbol("pools"); var kConnector = /* @__PURE__ */ Symbol("connector"); + var kConnectTimeout = /* @__PURE__ */ Symbol("connect timeout"); var kRequestTls = /* @__PURE__ */ Symbol("request tls settings"); + var kRequestTlsTimeout = /* @__PURE__ */ Symbol("request tls timeout"); + function createConnectTimeoutError(hostname, port, timeout) { + return new ConnectTimeoutError( + `Connect Timeout Error (attempted address: ${hostname}:${port}, timeout: ${timeout}ms)` + ); + } var experimentalWarningEmitted = false; var Socks5ProxyAgent = class extends DispatcherBase { constructor(proxyUrl, options = {}) { - super(); + super(options); if (!experimentalWarningEmitted) { process.emitWarning( "SOCKS5 proxy support is experimental and subject to change", @@ -31033,13 +31450,29 @@ var require_socks5_proxy_agent = __commonJS({ this[kProxyUrl] = url2; this[kProxyHeaders] = options.headers || {}; this[kProxyProtocol] = options.proxyTls ? "https:" : "http:"; - this[kRequestTls] = options.requestTls; + const connectTimeout = options.connectTimeout ?? DEFAULT_SOCKS5_CONNECT_TIMEOUT; + if (!Number.isFinite(connectTimeout) || connectTimeout < 0) { + throw new InvalidArgumentError("invalid connectTimeout"); + } + this[kConnectTimeout] = connectTimeout; + const { timeout, ...requestTls } = options.requestTls || {}; + const requestTlsTimeout = timeout ?? connectTimeout; + if (!Number.isFinite(requestTlsTimeout) || requestTlsTimeout < 0) { + throw new InvalidArgumentError("invalid requestTls.timeout"); + } + this[kRequestTls] = requestTls; + this[kRequestTlsTimeout] = requestTlsTimeout; this[kProxyAuth] = { username: options.username || (url2.username ? decodeURIComponent(url2.username) : null), password: options.password || (url2.password ? decodeURIComponent(url2.password) : null) }; + const proxyTlsTimeout = options.proxyTls?.timeout ?? connectTimeout; + if (!Number.isFinite(proxyTlsTimeout) || proxyTlsTimeout < 0) { + throw new InvalidArgumentError("invalid proxyTls.timeout"); + } this[kConnector] = options.connect || buildConnector({ ...options.proxyTls, + timeout: proxyTlsTimeout, servername: options.proxyTls?.servername || url2.hostname }); this[kPools] = /* @__PURE__ */ new Map(); @@ -31072,17 +31505,24 @@ var require_socks5_proxy_agent = __commonJS({ }); await socks5Client.handshake(); const authenticationReady = Promise.withResolvers(); - const authenticationTimeout = setTimeout(() => { - authenticationReady.reject(new Error("SOCKS5 authentication timeout")); - }, 5e3); - const onAuthenticated = () => { + const authenticationTimeout = this[kConnectTimeout] === 0 ? null : setTimeout(() => { + cleanupAuthenticationListeners(); + socks5Client.destroy(); + authenticationReady.reject( + createConnectTimeoutError(proxyHost, proxyPort, this[kConnectTimeout]) + ); + }, this[kConnectTimeout]); + const cleanupAuthenticationListeners = () => { clearTimeout(authenticationTimeout); + socks5Client.removeListener("authenticated", onAuthenticated); socks5Client.removeListener("error", onAuthenticationError); + }; + const onAuthenticated = () => { + cleanupAuthenticationListeners(); authenticationReady.resolve(); }; const onAuthenticationError = (err) => { - clearTimeout(authenticationTimeout); - socks5Client.removeListener("authenticated", onAuthenticated); + cleanupAuthenticationListeners(); authenticationReady.reject(err); }; if (socks5Client.state === STATES.AUTHENTICATED) { @@ -31095,18 +31535,25 @@ var require_socks5_proxy_agent = __commonJS({ await authenticationReady.promise; await socks5Client.connect(targetHost, targetPort); const connectionReady = Promise.withResolvers(); - const connectionTimeout = setTimeout(() => { - connectionReady.reject(new Error("SOCKS5 connection timeout")); - }, 5e3); - const onConnected = (info3) => { - debug2("SOCKS5 tunnel established to", targetHost, targetPort, "via", info3); + const connectionTimeout = this[kConnectTimeout] === 0 ? null : setTimeout(() => { + cleanupConnectionListeners(); + socks5Client.destroy(); + connectionReady.reject( + createConnectTimeoutError(targetHost, targetPort, this[kConnectTimeout]) + ); + }, this[kConnectTimeout]); + const cleanupConnectionListeners = () => { clearTimeout(connectionTimeout); + socks5Client.removeListener("connected", onConnected); socks5Client.removeListener("error", onConnectionError); + }; + const onConnected = (info3) => { + debug2("SOCKS5 tunnel established to", targetHost, targetPort, "via", info3); + cleanupConnectionListeners(); connectionReady.resolve(); }; const onConnectionError = (err) => { - clearTimeout(connectionTimeout); - socks5Client.removeListener("connected", onConnected); + cleanupConnectionListeners(); connectionReady.reject(err); }; socks5Client.once("connected", onConnected); @@ -31146,8 +31593,26 @@ var require_socks5_proxy_agent = __commonJS({ servername: this[kRequestTls]?.servername || targetHost }); const tlsReady = Promise.withResolvers(); - finalSocket.once("secureConnect", tlsReady.resolve); - finalSocket.once("error", tlsReady.reject); + const cleanupTlsListeners = () => { + queueMicrotask(clearTlsTimeout); + finalSocket.removeListener("secureConnect", onSecureConnect); + finalSocket.removeListener("error", onTlsError); + }; + const onSecureConnect = () => { + cleanupTlsListeners(); + tlsReady.resolve(); + }; + const onTlsError = (err) => { + cleanupTlsListeners(); + tlsReady.reject(err); + }; + const clearTlsTimeout = setupConnectTimeout(new WeakRef(finalSocket), { + timeout: this[kRequestTlsTimeout], + hostname: targetHost, + port: targetPort + }); + finalSocket.once("secureConnect", onSecureConnect); + finalSocket.once("error", onTlsError); await tlsReady.promise; } callback(null, finalSocket); @@ -31218,6 +31683,7 @@ var require_proxy_agent2 = __commonJS({ var Client = require_client2(); var { channels } = require_diagnostics2(); var Socks5ProxyAgent = require_socks5_proxy_agent(); + var { hasSafeIterator } = require_util9(); var kAgent = /* @__PURE__ */ Symbol("proxy agent"); var kClient = /* @__PURE__ */ Symbol("proxy client"); var kProxyHeaders = /* @__PURE__ */ Symbol("proxy headers"); @@ -31304,7 +31770,7 @@ var require_proxy_agent2 = __commonJS({ throw new InvalidArgumentError("Proxy opts.clientFactory must be a function."); } const { proxyTunnel, connectTimeout } = opts; - super(); + super(opts); const url2 = this.#getUrl(opts); const { href, origin: origin2, port, protocol, username, password, hostname: proxyHostname } = url2; this[kProxy] = { uri: href, protocol }; @@ -31337,6 +31803,7 @@ var require_proxy_agent2 = __commonJS({ factory: agentFactory, username: opts.username || username, password: opts.password || password, + connectTimeout, proxyTls: opts.proxyTls, requestTls: opts.requestTls }); @@ -31478,6 +31945,25 @@ var require_proxy_agent2 = __commonJS({ } return headersPair; } + if (headers && typeof headers === "object" && hasSafeIterator(headers)) { + const headersPair = {}; + for (const [key, value] of headers) { + if (!Object.hasOwn(headersPair, key)) { + headersPair[key] = value; + continue; + } + const previous = headersPair[key]; + const values = []; + if (previous !== void 0) { + values.push(...Array.isArray(previous) ? previous : [previous]); + } + if (value !== void 0) { + values.push(...Array.isArray(value) ? value : [value]); + } + headersPair[key] = values.length > 1 ? values : values[0]; + } + return headersPair; + } return headers; } function throwIfProxyAuthIsSent(headers) { @@ -31514,7 +32000,7 @@ var require_env_http_proxy_agent2 = __commonJS({ #noProxyEntries = null; #opts = null; constructor(opts = {}) { - super(); + super(opts); this.#opts = opts; const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts; this[kNoProxyAgent] = new Agent(agentOpts); @@ -31554,6 +32040,9 @@ var require_env_http_proxy_agent2 = __commonJS({ #getProxyAgentForUrl(url2) { let { protocol, host: hostname, port } = url2; hostname = hostname.replace(/:\d*$/, "").replace(/^\[(.+)\]$/, "$1").toLowerCase(); + if (hostname.length > 1 && hostname.charCodeAt(hostname.length - 1) === 46) { + hostname = hostname.slice(0, -1); + } port = Number.parseInt(port, 10) || DEFAULT_PORTS3[protocol] || 0; if (!this.#shouldProxy(hostname, port)) { return this[kNoProxyAgent]; @@ -31570,15 +32059,18 @@ var require_env_http_proxy_agent2 = __commonJS({ if (this.#noProxyEntries.length === 0) { return true; } - if (this.#noProxyValue === "*") { - return false; - } for (let i = 0; i < this.#noProxyEntries.length; i++) { const entry = this.#noProxyEntries[i]; + if (entry.hostname === "*") { + if (entry.port && entry.port !== port) { + continue; + } + return false; + } if (entry.port && entry.port !== port) { continue; } - if (hostname === entry.hostname) { + if (!entry.wildcard && hostname === entry.hostname) { return false; } if (hostname.slice(-(entry.hostname.length + 1)) === `.${entry.hostname}`) { @@ -31608,10 +32100,12 @@ var require_env_http_proxy_agent2 = __commonJS({ hostname = parsed ? parsed[1] : unbracketed; port = parsed ? Number.parseInt(parsed[2], 10) : 0; } + const wildcard = entry.charCodeAt(0) === 42; noProxyEntries.push({ - // strip leading dot or asterisk with dot - hostname: hostname.replace(/^\*?\./, "").toLowerCase(), - port + // strip leading dot or asterisk with dot, and any trailing dot + hostname: hostname.replace(/^\*?\./, "").replace(/^(.+)\.$/, "$1").toLowerCase(), + port, + wildcard }); } this.#noProxyValue = noProxyValue; @@ -31637,7 +32131,7 @@ var require_retry_handler2 = __commonJS({ "use strict"; var assert = require("node:assert"); var { kRetryHandlerDefaultRetry } = require_symbols6(); - var { RequestRetryError } = require_errors2(); + var { RequestRetryError, RequestAbortedError } = require_errors2(); var { isDisturbed, parseRangeHeader, @@ -31665,32 +32159,57 @@ var require_retry_handler2 = __commonJS({ } } var RetryController = class { - constructor() { - this.target = null; + #onAbort; + #paused = false; + #target = null; + constructor(onAbort) { + this.#onAbort = onAbort; + } + set target(target) { + this.#target = target; + if (this.#paused) { + target?.pause(); + } + } + get target() { + return this.#target; } pause() { - this.target?.pause(); + this.#paused = true; + this.#target?.pause(); } resume() { - this.target?.resume(); + this.#paused = false; + this.#target?.resume(); } abort(reason) { - this.target?.abort(reason); + this.#target?.abort(reason); + this.#onAbort(reason); } get paused() { - return this.target?.paused ?? false; + return this.#paused || (this.#target?.paused ?? false); } get aborted() { - return this.target?.aborted ?? false; + return this.#target?.aborted ?? false; } get reason() { - return this.target?.reason ?? null; + return this.#target?.reason ?? null; } get rawHeaders() { - return this.target?.rawHeaders ?? null; + return this.#target?.rawHeaders ?? null; + } + set rawHeaders(value) { + if (this.#target) { + this.#target.rawHeaders = value; + } } get rawTrailers() { - return this.target?.rawTrailers ?? null; + return this.#target?.rawTrailers ?? null; + } + set rawTrailers(value) { + if (this.#target) { + this.#target.rawTrailers = value; + } } }; var RetryHandler = class _RetryHandler { @@ -31749,13 +32268,24 @@ var require_retry_handler2 = __commonJS({ this.etag = null; this.statusCode = null; this.headers = null; - this.controllerProxy = new RetryController(); + this.controllerProxy = new RetryController((reason) => this.#onAbort(reason)); + this.retryPending = false; + this.retryTimer = null; + this.pendingResponseData = null; + this.pendingResponseTrailers = null; + this.pendingResponseEnded = false; + this.aborted = false; } onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err) { if (this.retryOpts.throwOnError) { if (this.retryOpts.statusCodes.includes(statusCode) === false) { - this.headersSent = true; - this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); + if (this.headersSent) { + this.handler.onResponseError?.(this.controllerProxy, err); + } else { + this.headersSent = true; + this.checkpointResponseEnd(headers); + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); + } } else { this.error = err; } @@ -31763,28 +32293,71 @@ var require_retry_handler2 = __commonJS({ } if (isDisturbed(this.opts.body)) { this.headersSent = true; + this.checkpointResponseEnd(headers); this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); return; } function shouldRetry(passedErr) { + if (this.aborted) { + return; + } + this.retryPending = false; + this.retryTimer = null; + const pendingData = this.pendingResponseData; + const pendingTrailers = this.pendingResponseTrailers; + const pendingEnd = this.pendingResponseEnded; + this.pendingResponseData = null; + this.pendingResponseTrailers = null; + this.pendingResponseEnded = false; if (passedErr) { - this.headersSent = true; - this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); + if (this.headersSent) { + this.handler.onResponseError?.(this.controllerProxy, passedErr); + } else { + this.headersSent = true; + this.checkpointResponseEnd(headers); + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); + controller.resume(); + if (pendingEnd) { + for (const chunk of pendingData) { + this.onResponseData(controller, chunk); + } + this.onResponseEnd(controller, pendingTrailers); + } + return; + } controller.resume(); return; } this.error = err; controller.resume(); + if (pendingEnd) { + this.onResponseEnd(controller, pendingTrailers); + } } controller.pause(); - this.retryOpts.retry( + this.retryPending = true; + this.pendingResponseData = []; + this.pendingResponseTrailers = null; + this.pendingResponseEnded = false; + this.retryTimer = this.retryOpts.retry( err, { state: { counter: this.retryCount }, opts: { retryOptions: this.retryOpts, ...this.opts } }, shouldRetry.bind(this) - ); + ) ?? null; + } + checkpointResponseEnd(headers) { + if (this.end == null && this.opts.method !== "HEAD") { + const contentLength = headers["content-length"]; + this.end = contentLength != null ? Number(contentLength) - 1 : null; + assert( + this.end == null || Number.isFinite(this.end), + "invalid content-length" + ); + this.resume = this.end != null; + } } onRequestStart(controller, context) { this.controllerProxy.target = controller; @@ -31792,6 +32365,12 @@ var require_retry_handler2 = __commonJS({ this.handler.onRequestStart?.(this.controllerProxy, context); } } + onBodySent(chunk) { + this.handler.onBodySent?.(chunk); + } + onRequestSent() { + this.handler.onRequestSent?.(); + } onRequestUpgrade(_controller, statusCode, headers, socket) { this.handler.onRequestUpgrade?.(this.controllerProxy, statusCode, headers, socket); } @@ -31805,7 +32384,8 @@ var require_retry_handler2 = __commonJS({ timeoutFactor, statusCodes, errorCodes, - methods + methods, + retryAfter } = retryOptions; const { counter } = state; if (code && code !== "UND_ERR_REQ_RETRY" && !errorCodes.includes(code)) { @@ -31824,13 +32404,13 @@ var require_retry_handler2 = __commonJS({ cb(err); return; } - let retryAfterHeader = headers?.["retry-after"]; + let retryAfterHeader = retryAfter === false ? void 0 : headers?.["retry-after"]; if (retryAfterHeader) { retryAfterHeader = Number(retryAfterHeader); retryAfterHeader = Number.isNaN(retryAfterHeader) ? calculateRetryAfterHeader(headers["retry-after"]) : retryAfterHeader * 1e3; } const retryTimeout = retryAfterHeader === 0 ? 0 : retryAfterHeader > 0 ? Math.min(retryAfterHeader, maxTimeout) : Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout); - setTimeout(() => cb(null), retryTimeout); + return setTimeout(() => cb(null), retryTimeout); } onResponseStart(controller, statusCode, headers, statusMessage) { if (statusCode < 200) { @@ -31841,16 +32421,6 @@ var require_retry_handler2 = __commonJS({ this.retryCount += 1; this.statusCode = statusCode; this.headers = headers; - if (statusCode >= 300) { - const err = new RequestRetryError("Request failed", statusCode, { - headers, - data: { - count: this.retryCount - } - }); - this.onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err); - return; - } if (this.headersSent) { if (statusCode !== 206 && (this.start > 0 || statusCode !== 200)) { throw new RequestRetryError("server does not support the range header and the payload was partially consumed", statusCode, { @@ -31873,8 +32443,22 @@ var require_retry_handler2 = __commonJS({ } validatePartialResponseContentLength(headers, contentRange, statusCode, this.retryCount); const { start, size, end = size ? size - 1 : null } = contentRange; - assert(this.start === start, "content-range mismatch"); - assert(this.end == null || this.end === end, "content-range mismatch"); + if (this.start !== start || this.end != null && this.end !== end) { + throw new RequestRetryError("Content-Range mismatch", statusCode, { + headers, + data: { count: this.retryCount } + }); + } + return; + } + if (statusCode >= 300) { + const err = new RequestRetryError("Request failed", statusCode, { + headers, + data: { + count: this.retryCount + } + }); + this.onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err); return; } if (this.end == null) { @@ -31929,6 +32513,10 @@ var require_retry_handler2 = __commonJS({ } } onResponseData(_controller, chunk) { + if (this.pendingResponseData !== null) { + this.pendingResponseData.push(chunk); + return; + } if (this.error) { return; } @@ -31936,6 +32524,11 @@ var require_retry_handler2 = __commonJS({ this.handler.onResponseData?.(this.controllerProxy, chunk); } onResponseEnd(_controller, trailers) { + if (this.pendingResponseData !== null) { + this.pendingResponseTrailers = trailers; + this.pendingResponseEnded = true; + return; + } if (this.error && this.retryOpts.throwOnError) { throw this.error; } @@ -31975,11 +32568,19 @@ var require_retry_handler2 = __commonJS({ } } onResponseError(controller, err) { - if (controller?.aborted || isDisturbed(this.opts.body)) { + if (this.aborted) { + return; + } + if (controller?.aborted || isDisturbed(this.opts.body) || this.headersSent && !this.resume) { this.handler.onResponseError?.(this.controllerProxy, err); return; } function shouldRetry(returnedErr) { + if (this.aborted) { + return; + } + this.retryPending = false; + this.retryTimer = null; if (!returnedErr) { this.retry(); return; @@ -31991,14 +32592,28 @@ var require_retry_handler2 = __commonJS({ } else { this.retryCount += 1; } - this.retryOpts.retry( + this.retryPending = true; + this.retryTimer = this.retryOpts.retry( err, { state: { counter: this.retryCount }, opts: { retryOptions: this.retryOpts, ...this.opts } }, shouldRetry.bind(this) - ); + ) ?? null; + } + #onAbort(reason) { + if (!this.retryPending) { + return; + } + this.aborted = true; + this.retryPending = false; + clearTimeout(this.retryTimer); + this.retryTimer = null; + this.pendingResponseData = null; + this.pendingResponseTrailers = null; + this.pendingResponseEnded = false; + this.handler.onResponseError?.(this.controllerProxy, reason ?? new RequestAbortedError()); } }; module2.exports = RetryHandler; @@ -32011,6 +32626,7 @@ var require_retry_agent2 = __commonJS({ "use strict"; var Dispatcher = require_dispatcher2(); var RetryHandler = require_retry_handler2(); + var { kOriginless, kUrl } = require_symbols6(); var RetryAgent = class extends Dispatcher { #agent = null; #options = null; @@ -32018,6 +32634,8 @@ var require_retry_agent2 = __commonJS({ super(options); this.#agent = agent; this.#options = options; + this[kUrl] = agent[kUrl]; + this[kOriginless] = agent[kOriginless]; } dispatch(opts, handler) { const retry = new RetryHandler({ @@ -32092,7 +32710,6 @@ var require_readable2 = __commonJS({ var { Readable: Readable3 } = require("node:stream"); var { RequestAbortedError, NotSupportedError, InvalidArgumentError, AbortError } = require_errors2(); var util4 = require_util9(); - var { ReadableStreamFrom } = require_util9(); var kConsume = /* @__PURE__ */ Symbol("kConsume"); var kReading = /* @__PURE__ */ Symbol("kReading"); var kBody = /* @__PURE__ */ Symbol("kBody"); @@ -32279,7 +32896,7 @@ var require_readable2 = __commonJS({ */ get body() { if (!this[kBody]) { - this[kBody] = ReadableStreamFrom(this); + this[kBody] = ReadableStream.from(this); if (this[kConsume]) { this[kBody].getReader(); assert(this[kBody].locked); @@ -33689,8 +34306,7 @@ var require_mock_utils2 = __commonJS({ handler.onResponseError(null, new InvalidArgumentError("reply options callback must return an object")); return; } - mockDispatch2.data = { ...responseDefaults, ...resolvedData }; - dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler); + dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler, { ...responseDefaults, ...resolvedData }); }, (error2) => { handler.onResponseError(null, error2); @@ -33701,12 +34317,13 @@ var require_mock_utils2 = __commonJS({ if (callbackResult == null || typeof callbackResult !== "object") { throw new InvalidArgumentError("reply options callback must return an object"); } - mockDispatch2.data = { ...responseDefaults, ...callbackResult }; + return dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler, { ...responseDefaults, ...callbackResult }); } return dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler); } - function dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler) { - const { data: response, delay } = mockDispatch2; + function dispatchMockReply(mockDispatches, mockDispatch2, key, opts, handler, resolvedResponse) { + const { data: responseData, delay } = mockDispatch2; + const response = resolvedResponse ?? responseData; if (response.error !== null) { deleteMockDispatch(mockDispatches, key); handler.onResponseError(null, response.error); @@ -33780,8 +34397,7 @@ var require_mock_utils2 = __commonJS({ handler.onResponseError(null, new InvalidArgumentError("reply options callback must return an object")); return; } - mockDispatch2.data = { ...responseDefaults, ...resolvedData }; - handleReply(dispatches, mockDispatch2.data); + handleReply(dispatches, { ...responseDefaults, ...resolvedData }); }, (err) => { handler.onResponseError(null, err); @@ -33792,8 +34408,7 @@ var require_mock_utils2 = __commonJS({ if (callbackResult == null || typeof callbackResult !== "object") { throw new InvalidArgumentError("reply options callback must return an object"); } - mockDispatch2.data = { ...responseDefaults, ...callbackResult }; - handleReply(dispatches, mockDispatch2.data); + handleReply(dispatches, { ...responseDefaults, ...callbackResult }); return; } if (typeof delay === "number" && delay > 0) { @@ -33818,13 +34433,13 @@ var require_mock_utils2 = __commonJS({ if (aborted) { return; } - const responseData = getResponseData(body); + const responseData2 = getResponseData(body); const responseHeaders = generateKeyValues(headers ?? {}); const responseTrailers = generateKeyValues(trailers ?? {}); controller.rawHeaders = responseHeaders; controller.rawTrailers = responseTrailers; handler.onResponseStart?.(controller, statusCode, parseHeaders(responseHeaders), getStatusText(statusCode)); - handler.onResponseData?.(controller, Buffer.from(responseData)); + handler.onResponseData?.(controller, Buffer.from(responseData2)); handler.onResponseEnd?.(controller, parseHeaders(responseTrailers)); deleteMockDispatch(mockDispatches2, key); } @@ -34587,10 +35202,18 @@ var require_mock_agent2 = __commonJS({ } dispatch(opts, handler) { opts.origin = normalizeOrigin(opts.origin); - this.get(opts.origin); + const mockDispatcher = this.get(opts.origin); this[kMockAgentAddCallHistoryLog](opts); const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters]; const dispatchOpts = { ...opts }; + if (dispatchOpts.allowH2 === false) { + const http1OnlyKey = `${dispatchOpts.origin}#http1-only`; + if (!this[kClients].has(http1OnlyKey)) { + const http1OnlyDispatcher = this[kFactory](dispatchOpts.origin); + http1OnlyDispatcher[kDispatches] = mockDispatcher[kDispatches]; + this[kMockAgentSet](http1OnlyKey, http1OnlyDispatcher); + } + } if (acceptNonStandardSearchParameters && dispatchOpts.path) { const [path, searchParams] = dispatchOpts.path.split("?"); const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters); @@ -35604,7 +36227,11 @@ var require_decorator_handler2 = __commonJS({ /** * @deprecated */ - onBodySent() { + onBodySent(...args) { + return this.#handler.onBodySent?.(...args); + } + onRequestSent(...args) { + return this.#handler.onRequestSent?.(...args); } }; } @@ -35617,6 +36244,7 @@ var require_redirect_handler2 = __commonJS({ var util4 = require_util9(); var assert = require("node:assert"); var { InvalidArgumentError } = require_errors2(); + var { kRequestOrigin } = require_symbols6(); var redirectableStatusCodes = [300, 301, 302, 303, 307, 308]; var noop2 = () => { }; @@ -35649,10 +36277,20 @@ var require_redirect_handler2 = __commonJS({ onRequestStart(controller, context) { this.handler.onRequestStart?.(controller, { ...context, history: this.history }); } + onBodySent(chunk) { + this.handler.onBodySent?.(chunk); + } + onRequestSent() { + this.handler.onRequestSent?.(); + } onRequestUpgrade(controller, statusCode, headers, socket) { this.handler.onRequestUpgrade?.(controller, statusCode, headers, socket); } onResponseStart(controller, statusCode, headers, statusMessage) { + if (statusCode < 200) { + this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage); + return; + } if (this.opts.throwOnMaxRedirect && this.history.length >= this.maxRedirections) { throw new Error("max redirects"); } @@ -35673,14 +36311,16 @@ var require_redirect_handler2 = __commonJS({ this.opts.body = null; } this.location = this.history.length >= this.maxRedirections || util4.isDisturbed(this.opts.body) || redirectableStatusCodes.indexOf(statusCode) === -1 ? null : headers.location; - if (this.opts.origin) { - this.history.push(new URL(this.opts.path, this.opts.origin)); + const requestOrigin = this.opts[kRequestOrigin] === void 0 ? this.opts.origin : this.opts[kRequestOrigin]; + if (requestOrigin) { + this.history.push(new URL(this.opts.path, requestOrigin)); } if (!this.location) { this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage); return; } - const { origin: origin2, pathname, search } = util4.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))); + const baseUrl = requestOrigin ? new URL(this.opts.path, requestOrigin) : void 0; + const { origin: origin2, pathname, search } = util4.parseURL(new URL(this.location, baseUrl)); const path = search ? `${pathname}${search}` : pathname; const redirectUrlString = `${origin2}${path}`; for (const historyUrl of this.history) { @@ -35688,9 +36328,10 @@ var require_redirect_handler2 = __commonJS({ throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin2}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`); } } - this.opts.headers = cleanRequestHeaders(this.opts.headers, removeContentHeaders, this.opts.origin !== origin2, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect); + this.opts.headers = cleanRequestHeaders(this.opts.headers, removeContentHeaders, requestOrigin !== origin2, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect); this.opts.path = path; this.opts.origin = origin2; + this.opts[kRequestOrigin] = origin2; this.opts.query = null; } onResponseData(controller, chunk) { @@ -35904,7 +36545,6 @@ var require_dump2 = __commonJS({ #maxSize = 1024 * 1024; #dumped = false; #size = 0; - #controller = null; aborted = false; reason = false; constructor({ maxSize, signal }, handler) { @@ -35920,7 +36560,6 @@ var require_dump2 = __commonJS({ } onRequestStart(controller, context) { controller.abort = this.#abort.bind(this); - this.#controller = controller; return super.onRequestStart(controller, context); } onResponseStart(controller, statusCode, headers, statusMessage) { @@ -35936,33 +36575,26 @@ var require_dump2 = __commonJS({ return super.onResponseStart(controller, statusCode, headers, statusMessage); } onResponseError(controller, err) { - if (this.#dumped) { - return; - } - err = this.#controller?.reason ?? err; - super.onResponseError(controller, err); + super.onResponseError(controller, this.aborted === true ? this.reason : err); } onResponseData(controller, chunk) { this.#size = this.#size + chunk.length; - if (this.#size >= this.#maxSize) { + if (this.#size > this.#maxSize) { + throw new RequestAbortedError( + `Response size (${this.#size}) larger than maxSize (${this.#maxSize})` + ); + } + if (this.#size === this.#maxSize) { this.#dumped = true; - if (this.aborted === true) { - super.onResponseError(controller, this.reason); - } else { - super.onResponseEnd(controller, {}); - } } return true; } onResponseEnd(controller, trailers) { - if (this.#dumped) { - return; - } - if (this.#controller.aborted === true) { + if (this.aborted === true) { super.onResponseError(controller, this.reason); return; } - super.onResponseEnd(controller, trailers); + super.onResponseEnd(controller, this.#dumped ? {} : trailers); } }; function createDumpInterceptor({ maxSize: defaultMaxSize } = { @@ -35988,6 +36620,7 @@ var require_dns2 = __commonJS({ var { lookup } = require("node:dns"); var DecoratorHandler = require_decorator_handler2(); var { InvalidArgumentError, InformationalError } = require_errors2(); + var { kRequestOrigin } = require_symbols6(); var maxInt = Math.pow(2, 31) - 1; function hasSafeIterator(headers) { const prototype2 = Object.getPrototypeOf(headers); @@ -36327,6 +36960,7 @@ var require_dns2 = __commonJS({ const dispatchOpts = { ...this.#opts, origin: `${this.#origin.protocol}//${ip.family === 6 ? `[${ip.address}]` : ip.address}${port}`, + [kRequestOrigin]: this.#opts[kRequestOrigin] === void 0 ? this.#origin : this.#opts[kRequestOrigin], headers: withHostHeader(this.#origin.host, this.#opts.headers) }; this.#dispatch(dispatchOpts, this); @@ -36405,6 +37039,7 @@ var require_dns2 = __commonJS({ servername: origin2.hostname, // For SNI on TLS origin: newOrigin.origin, + [kRequestOrigin]: origDispatchOpts[kRequestOrigin] === void 0 ? origin2 : origDispatchOpts[kRequestOrigin], headers: withHostHeader(origin2.host, origDispatchOpts.headers) }; dispatch( @@ -36433,6 +37068,7 @@ var require_cache2 = __commonJS({ isValidHTTPToken } = require_util9(); var { serializePathWithQuery } = require_util9(); + var { kRequestOrigin } = require_symbols6(); var MAX_DELTA_SECONDS = 2147483647; var RESTRICTIVE_DIRECTIVE_NAMES = ["no-store", "private", "no-cache"]; var kInvalidCacheControlDirectives = /* @__PURE__ */ Symbol("invalid cache-control directives"); @@ -36544,14 +37180,39 @@ var require_cache2 = __commonJS({ return tokenOnlyKey; } } - function makeCacheKey(opts) { - const origin2 = opts.origin ? opts.origin.toString() : ""; + function getRequestOrigin(opts) { + const origin2 = opts[kRequestOrigin] === void 0 ? opts.origin : opts[kRequestOrigin]; + return typeof origin2 === "string" || origin2 instanceof URL ? origin2 : null; + } + function getInterceptorOrigin(opts, interceptorOrigin) { + const requestOrigin = getRequestOrigin(opts); + if (interceptorOrigin === void 0) { + return requestOrigin; + } + if (interceptorOrigin === null) { + return null; + } + if (requestOrigin) { + try { + if (new URL(requestOrigin).origin !== interceptorOrigin) { + return null; + } + } catch { + return interceptorOrigin; + } + } + return interceptorOrigin; + } + function makeCacheKey(opts, origin2 = getRequestOrigin(opts)) { + if (!origin2) { + throw new Error("opts.origin is undefined"); + } let fullPath = opts.path || "/"; if (opts.query && !pathHasQueryOrFragment(fullPath)) { fullPath = serializePathWithQuery(fullPath, opts.query); } return { - origin: origin2, + origin: origin2.toString(), method: opts.method, path: fullPath, headers: opts.headers @@ -36926,6 +37587,8 @@ var require_cache2 = __commonJS({ return JSON.stringify([cacheKey.origin, cacheKey.method, cacheKey.path, headers]); } module2.exports = { + getInterceptorOrigin, + getRequestOrigin, makeCacheKey, normalizeHeaders, assertCacheKey, @@ -37592,6 +38255,12 @@ var require_cache_handler = __commonJS({ this.#writeStream = void 0; this.#handler.onRequestStart?.(controller, context); } + onBodySent(chunk) { + this.#handler.onBodySent?.(chunk); + } + onRequestSent() { + this.#handler.onRequestSent?.(); + } onRequestUpgrade(controller, statusCode, headers, socket) { this.#handler.onRequestUpgrade?.(controller, statusCode, headers, socket); } @@ -37614,6 +38283,11 @@ var require_cache_handler = __commonJS({ return downstreamOnHeaders(); } const cacheControlHeader = resHeaders["cache-control"]; + const cacheControlDirectives = cacheControlHeader ? parseCacheControlHeader(cacheControlHeader) : {}; + if (revalidationResponseDisallowsCachedReuse(this.#cacheType, resHeaders, cacheControlDirectives)) { + deleteCachedValue(this.#store, this.#cacheKey); + return downstreamOnHeaders(); + } const heuristicallyCacheable = resHeaders["last-modified"] && arrayIncludes(HEURISTICALLY_CACHEABLE_STATUS_CODES, statusCode); if (!cacheControlHeader && !resHeaders["expires"] && !heuristicallyCacheable && !this.#cacheByDefault) { if (statusCode === 304 && resHeaders.vary && isInvalidOrWildcardVaryHeader(resHeaders.vary)) { @@ -37621,8 +38295,7 @@ var require_cache_handler = __commonJS({ } return downstreamOnHeaders(); } - const cacheControlDirectives = cacheControlHeader ? parseCacheControlHeader(cacheControlHeader) : {}; - if (!canCacheResponse(this.#cacheType, statusCode, resHeaders, cacheControlDirectives, this.#cacheKey.headers)) { + if (!canCacheResponse(this.#cacheType, this.#cacheKey.method, statusCode, resHeaders, cacheControlDirectives, this.#cacheKey.headers)) { if (statusCode === 304 && (cacheControlHeader || revalidationResponseDisallowsCachedReuse(this.#cacheType, resHeaders, cacheControlDirectives))) { deleteCachedValue(this.#store, this.#cacheKey); } @@ -37787,9 +38460,12 @@ var require_cache_handler = __commonJS({ } } function revalidationResponseDisallowsCachedReuse(cacheType, resHeaders, cacheControlDirectives) { - return cacheControlDirectives["no-store"] === true || cacheType === "shared" && cacheControlDirectives.private === true || (resHeaders.vary ? isInvalidOrWildcardVaryHeader(resHeaders.vary) : false); + return cacheControlDirectives["no-store"] === true || cacheType === "shared" && (cacheControlDirectives.private === true || Object.hasOwn(resHeaders, "set-cookie")) || (resHeaders.vary ? isInvalidOrWildcardVaryHeader(resHeaders.vary) : false); } - function canCacheResponse(cacheType, statusCode, resHeaders, cacheControlDirectives, reqHeaders) { + function canCacheResponse(cacheType, method, statusCode, resHeaders, cacheControlDirectives, reqHeaders) { + if (!arrayIncludes(util4.safeHTTPMethods, method)) { + return false; + } if (statusCode < 200 || arrayIncludes(NOT_UNDERSTOOD_STATUS_CODES, statusCode)) { return false; } @@ -37800,7 +38476,7 @@ var require_cache_handler = __commonJS({ if (cacheControlDirectives["no-store"]) { return false; } - if (cacheType === "shared" && cacheControlDirectives.private === true) { + if (cacheType === "shared" && (cacheControlDirectives.private === true || Object.hasOwn(resHeaders, "set-cookie"))) { return false; } if (resHeaders.vary && hasVaryStar(resHeaders.vary)) { @@ -38035,7 +38711,7 @@ var require_memory_cache_store = __commonJS({ return this.#size >= this.#maxSize || this.#count >= this.#maxCount; } /** - * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} req + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key * @returns {import('../../types/cache-interceptor.d.ts').default.GetResult | undefined} */ get(key) { @@ -38108,7 +38784,7 @@ var require_memory_cache_store = __commonJS({ store.#hasEmittedMaxSizeEvent = true; } for (const [key2, entries2] of store.#entries) { - for (const entry2 of entries2.splice(0, entries2.length / 2)) { + for (const entry2 of entries2.splice(0, Math.ceil(entries2.length / 2))) { store.#size -= entry2.size; store.#count -= 1; } @@ -38285,7 +38961,16 @@ var require_cache3 = __commonJS({ var CacheHandler = require_cache_handler(); var MemoryCacheStore = require_memory_cache_store(); var CacheRevalidationHandler = require_cache_revalidation_handler(); - var { assertCacheStore, assertCacheMethods, makeCacheKey, normalizeHeaders, parseCacheControlHeader, isInvalidOrWildcardVaryHeader } = require_cache2(); + var { + assertCacheStore, + assertCacheMethods, + getInterceptorOrigin, + makeCacheKey, + normalizeHeaders, + parseCacheControlHeader, + isInvalidOrWildcardVaryHeader, + parseVaryHeader + } = require_cache2(); var { AbortError } = require_errors2(); var { parseHttpDate } = require_date(); function assertCacheOrigins(origins, name) { @@ -38351,7 +39036,7 @@ var require_cache3 = __commonJS({ result.cacheControlDirectives?.["s-maxage"] !== void 0); } function revalidationResponseDisallowsCachedReuse(cacheType, headers) { - if (headers.vary && isInvalidOrWildcardVaryHeader(headers.vary)) { + if (headers.vary && isInvalidOrWildcardVaryHeader(headers.vary) || cacheType === "shared" && Object.hasOwn(headers, "set-cookie")) { return true; } const cacheControl = headers["cache-control"]; @@ -38364,6 +39049,17 @@ var require_cache3 = __commonJS({ function revalidationResponseUpdatesCacheControl(headers) { return headers["cache-control"] !== void 0; } + function revalidationResponseAddsVary(result, varyDirectives) { + if (!varyDirectives) { + return false; + } + for (const key in varyDirectives) { + if (result.vary == null || !Object.hasOwn(result.vary, key)) { + return true; + } + } + return false; + } function deleteCachedValue(store, cacheKey) { try { store.delete(cacheKey)?.catch?.(nop); @@ -38459,6 +39155,7 @@ var require_cache3 = __commonJS({ const stream4 = util4.isStream(result.body) ? result.body : Readable3.from(result.body ?? []); assert(!stream4.destroyed, "stream should not be destroyed"); assert(!stream4.readableDidRead, "stream should not be readableDidRead"); + let aborted = false; const controller = { rawHeaders: [], rawTrailers: [], @@ -38472,12 +39169,13 @@ var require_cache3 = __commonJS({ return stream4.isPaused(); }, get aborted() { - return stream4.destroyed; + return aborted; }, get reason() { return stream4.errored; }, abort(reason) { + aborted = true; stream4.destroy(reason ?? new AbortError()); } }; @@ -38516,6 +39214,13 @@ var require_cache3 = __commonJS({ if (!result) { return handleUncachedResponse(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl); } + if (globalOpts.type === "shared" && Object.hasOwn(result.headers, "set-cookie")) { + if (util4.isStream(result.body)) { + result.body.on("error", nop).destroy(); + } + deleteCachedValue(globalOpts.store, cacheKey); + return handleUncachedResponse(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl); + } const now = Date.now(); if (now > result.deleteAt) { return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler)); @@ -38582,6 +39287,12 @@ var require_cache3 = __commonJS({ } if (revalidationResponseUpdatesCacheControl(headers2)) { deleteCachedValue(globalOpts.store, cacheKey); + } else if (revalidationResponseAddsVary(result, headers2.vary ? parseVaryHeader(headers2.vary, opts.headers) : void 0)) { + if (util4.isStream(result.body)) { + result.body.on("error", nop).destroy(); + } + deleteCachedValue(globalOpts.store, cacheKey); + return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler)); } } sendCachedValue(handler, opts, result, age, context, stale); @@ -38632,25 +39343,23 @@ var require_cache3 = __commonJS({ safeMethodsToNotCache.push(method); } } - return (dispatch) => { + return (dispatch, interceptorOrigin) => { return (opts2, handler) => { - if (arrayIncludes(safeMethodsToNotCache, opts2.method)) { + const requestOrigin = getInterceptorOrigin(opts2, interceptorOrigin); + if (!requestOrigin || arrayIncludes(safeMethodsToNotCache, opts2.method)) { return dispatch(opts2, handler); } if (origins !== void 0) { - if (!opts2.origin) { - return dispatch(opts2, handler); - } - const requestOrigin = opts2.origin.toString().toLowerCase(); + const normalizedRequestOrigin = requestOrigin.toString().toLowerCase(); let isAllowed = false; for (let i = 0; i < origins.length; i++) { const allowed = origins[i]; if (typeof allowed === "string") { - if (allowed.toLowerCase() === requestOrigin) { + if (allowed.toLowerCase() === normalizedRequestOrigin) { isAllowed = true; break; } - } else if (allowed.test(requestOrigin)) { + } else if (allowed.test(normalizedRequestOrigin)) { isAllowed = true; break; } @@ -38667,7 +39376,10 @@ var require_cache3 = __commonJS({ if (reqCacheControl?.["no-store"]) { return dispatch(opts2, handler); } - const cacheKey = makeCacheKey(opts2); + const cacheKey = makeCacheKey(opts2, requestOrigin); + if (!arrayIncludes(util4.safeHTTPMethods, opts2.method)) { + return dispatch(opts2, new CacheHandler(globalOpts, cacheKey, handler)); + } const result = store.get(cacheKey); if (result && typeof result.then === "function") { return result.then((result2) => handleResult( @@ -38701,9 +39413,66 @@ var require_decompress = __commonJS({ "node_modules/undici/lib/interceptor/decompress.js"(exports2, module2) { "use strict"; var { createInflate, createGunzip, createBrotliDecompress, createZstdDecompress } = require("node:zlib"); - var { pipeline } = require("node:stream"); + var { pipeline, Transform: TransformStream2 } = require("node:stream"); + var { InvalidArgumentError, ResponseExceededMaxSizeError } = require_errors2(); var DecoratorHandler = require_decorator_handler2(); + var DecompressController = class { + #onPause; + #onResume; + #onAbort; + #paused = false; + constructor(onPause, onResume, onAbort) { + this.#onPause = onPause; + this.#onResume = onResume; + this.#onAbort = onAbort; + this.target = null; + } + pause() { + if (this.#paused) { + return; + } + this.#paused = true; + this.#onPause(); + } + resume() { + if (!this.#paused) { + return; + } + this.#paused = false; + this.#onResume(); + } + abort(reason) { + this.target?.abort(reason); + this.#onAbort(reason); + } + get paused() { + return this.#paused; + } + get aborted() { + return this.target?.aborted ?? false; + } + get reason() { + return this.target?.reason ?? null; + } + get rawHeaders() { + return this.target?.rawHeaders ?? null; + } + set rawHeaders(value) { + if (this.target) { + this.target.rawHeaders = value; + } + } + get rawTrailers() { + return this.target?.rawTrailers ?? null; + } + set rawTrailers(value) { + if (this.target) { + this.target.rawTrailers = value; + } + } + }; var supportedEncodings = { + __proto__: null, gzip: createGunzip, "x-gzip": createGunzip, br: createBrotliDecompress, @@ -38716,6 +39485,23 @@ var require_decompress = __commonJS({ /** @type {const} */ [204, 304] ); + var defaultMaxSize = 0; + function createMaxSizeLimiter(maxSize) { + let size = 0; + return new TransformStream2({ + transform(chunk, _encoding, callback) { + const decompressedSize = size + chunk.length; + if (decompressedSize > maxSize) { + callback(new ResponseExceededMaxSizeError( + `Decompressed response size (${decompressedSize}) exceeded maxSize (${maxSize})` + )); + return; + } + size = decompressedSize; + callback(null, chunk); + } + }); + } var warningEmitted = ( /** @type {boolean} */ false @@ -38729,10 +39515,122 @@ var require_decompress = __commonJS({ #skipStatusCodes; /** @type {boolean} */ #skipErrorResponses; - constructor(handler, { skipStatusCodes = defaultSkipStatusCodes, skipErrorResponses = true } = {}) { + /** @type {number} */ + #maxSize; + /** @type {number} */ + #decompressedSize = 0; + /** @type {boolean} */ + #terminated = false; + /** @type {boolean} */ + #inputEnded = false; + /** @type {boolean} */ + #inputBackpressured = false; + /** @type {boolean} */ + #upstreamPaused = false; + /** @type {boolean} */ + #draining = false; + /** @type {boolean} */ + #drainRequested = false; + /** @type {boolean} */ + #completionPending = false; + /** @type {DecompressorStream | undefined} */ + #finalDecompressor; + /** @type {DecompressController} */ + #controller; + constructor(handler, { skipStatusCodes = defaultSkipStatusCodes, skipErrorResponses = true, maxSize = defaultMaxSize } = {}) { + if (!Number.isSafeInteger(maxSize) || maxSize < 0) { + throw new InvalidArgumentError("maxSize must be a non-negative integer"); + } super(handler); this.#skipStatusCodes = skipStatusCodes; this.#skipErrorResponses = skipErrorResponses; + this.#maxSize = maxSize; + this.#controller = new DecompressController( + () => this.#onDownstreamPause(), + () => this.#onDownstreamResume(), + (reason) => { + if (this.#inputEnded && !this.#terminated) { + this.onResponseError(this.#controller, reason); + } + } + ); + } + #onDownstreamPause() { + this.#pauseUpstream(); + } + #onDownstreamResume() { + const drainWasDeferred = this.#draining; + this.#drainOutput(); + if (!drainWasDeferred) { + this.#resumeUpstreamIfNeeded(); + this.#finishIfReady(); + } + } + #pauseUpstream() { + if (!this.#upstreamPaused && !this.#terminated) { + this.#upstreamPaused = true; + this.#controller.target?.pause(); + } + } + #resumeUpstreamIfNeeded() { + if (this.#upstreamPaused && !this.#controller.paused && !this.#inputBackpressured) { + this.#upstreamPaused = false; + if (!this.#inputEnded) { + this.#controller.target?.resume(); + } + } + } + #drainOutput() { + if (this.#terminated || this.#controller.paused || !this.#finalDecompressor) { + return; + } + if (this.#draining) { + this.#drainRequested = true; + return; + } + this.#draining = true; + try { + do { + this.#drainRequested = false; + let chunk; + while (!this.#terminated && !this.#controller.paused && (chunk = this.#finalDecompressor.read()) !== null) { + if (this.#maxSize > 0) { + const decompressedSize = this.#decompressedSize + chunk.length; + if (decompressedSize > this.#maxSize) { + this.#fail(new ResponseExceededMaxSizeError( + `Decompressed response size (${decompressedSize}) exceeded maxSize (${this.#maxSize})` + )); + return; + } + this.#decompressedSize = decompressedSize; + } + const result = super.onResponseData(this.#controller, chunk); + if (result === false && !this.#controller.paused) { + this.#controller.pause(); + } + } + } while (this.#drainRequested && !this.#terminated && !this.#controller.paused); + } finally { + this.#draining = false; + } + this.#resumeUpstreamIfNeeded(); + this.#finishIfReady(); + } + #finishIfReady() { + if (this.#terminated || !this.#completionPending || this.#controller.paused || this.#draining) { + return; + } + this.#terminated = true; + this.#cleanupDecompressors(); + super.onResponseEnd(this.#controller, this.#trailers); + } + #onDecompressionEnd() { + if (this.#terminated) { + return; + } + this.#completionPending = true; + this.#drainOutput(); + this.#finishIfReady(); } /** * Determines if decompression should be skipped based on encoding and status code @@ -38750,7 +39648,7 @@ var require_decompress = __commonJS({ * Creates a chain of decompressors for multiple content encodings * * @param {string} encodings - Comma-separated list of content encodings - * @returns {Array} - Array of decompressor streams + * @returns {Array} - Array of decompressor and limiting streams * @throws {Error} - If the number of content-encodings exceeds the maximum allowed */ #createDecompressionChain(encodings) { @@ -38769,54 +39667,81 @@ var require_decompress = __commonJS({ } decompressors.push(supportedEncodings[encoding]()); } - return decompressors; + if (decompressors.length < 2) { + return decompressors; + } + const streams = []; + for (let i = 0; i < decompressors.length; i++) { + streams.push(decompressors[i]); + if (i < decompressors.length - 1 && this.#maxSize > 0) { + streams.push(createMaxSizeLimiter(this.#maxSize)); + } + } + return streams; + } + /** + * Stops decompression and reports an error. + * @param {Error} error - The decompression error + * @returns {void} + */ + #fail(error2) { + if (this.#terminated) { + return; + } + if (this.#inputEnded) { + this.onResponseError(this.#controller, error2); + } else { + this.#controller.abort(error2); + } } /** - * Sets up event handlers for a decompressor stream using readable events + * Sets up event handlers for the final decompressor stream. * @param {DecompressorStream} decompressor - The decompressor stream - * @param {Controller} controller - The controller to coordinate with * @returns {void} */ - #setupDecompressorEvents(decompressor, controller) { - decompressor.on("readable", () => { - let chunk; - while ((chunk = decompressor.read()) !== null) { - const result = super.onResponseData(controller, chunk); - if (result === false) { - break; - } - } - }); - decompressor.on("error", (error2) => { - super.onResponseError(controller, error2); - }); + #setupDecompressorEvents(decompressor) { + this.#finalDecompressor = decompressor; + decompressor.on("readable", () => this.#drainOutput()); + decompressor.on("error", (error2) => this.#fail(error2)); } /** * Sets up event handling for a single decompressor - * @param {Controller} controller - The controller to handle events * @returns {void} */ - #setupSingleDecompressor(controller) { + #setupSingleDecompressor() { const decompressor = this.#decompressors[0]; - this.#setupDecompressorEvents(decompressor, controller); - decompressor.on("end", () => { - super.onResponseEnd(controller, this.#trailers); - }); + this.#setupDecompressorEvents(decompressor); + decompressor.on("end", () => this.#onDecompressionEnd()); } /** * Sets up event handling for multiple chained decompressors using pipeline - * @param {Controller} controller - The controller to handle events * @returns {void} */ - #setupMultipleDecompressors(controller) { + #setupMultipleDecompressors() { const lastDecompressor = this.#decompressors[this.#decompressors.length - 1]; - this.#setupDecompressorEvents(lastDecompressor, controller); + this.#setupDecompressorEvents(lastDecompressor); pipeline(this.#decompressors, (err) => { + if (this.#terminated) { + return; + } if (err) { - super.onResponseError(controller, err); + this.#fail(err); + return; + } + this.#onDecompressionEnd(); + }); + } + #setupInputBackpressure() { + const decompressor = this.#decompressors[0]; + decompressor.on("drain", () => { + if (this.#terminated) { return; } - super.onResponseEnd(controller, this.#trailers); + this.#inputBackpressured = false; + if (!this.#controller.paused) { + this.#drainOutput(); + this.#resumeUpstreamIfNeeded(); + } }); } /** @@ -38825,6 +39750,14 @@ var require_decompress = __commonJS({ */ #cleanupDecompressors() { this.#decompressors.length = 0; + this.#finalDecompressor = void 0; + } + onRequestStart(controller, context) { + this.#controller.target = controller; + return super.onRequestStart(this.#controller, context); + } + onRequestUpgrade(controller, statusCode, headers, socket) { + return super.onRequestUpgrade(this.#controller, statusCode, headers, socket); } /** * @param {Controller} controller @@ -38834,19 +39767,20 @@ var require_decompress = __commonJS({ * @returns {void} */ onResponseStart(controller, statusCode, headers, statusMessage) { - const contentEncoding = headers["content-encoding"]; + const rawContentEncoding = headers["content-encoding"]; + const contentEncoding = Array.isArray(rawContentEncoding) ? rawContentEncoding.join(",") : rawContentEncoding; if (this.#shouldSkipDecompression(contentEncoding, statusCode)) { - return super.onResponseStart(controller, statusCode, headers, statusMessage); + return super.onResponseStart(this.#controller, statusCode, headers, statusMessage); } const decompressors = this.#createDecompressionChain(contentEncoding.toLowerCase()); if (decompressors.length === 0) { this.#cleanupDecompressors(); - return super.onResponseStart(controller, statusCode, headers, statusMessage); + return super.onResponseStart(this.#controller, statusCode, headers, statusMessage); } this.#decompressors = decompressors; const { "content-encoding": _, "content-length": __, ...newHeaders } = headers; - if (controller?.rawHeaders) { - const rawHeaders = controller.rawHeaders; + if (this.#controller.rawHeaders) { + const rawHeaders = this.#controller.rawHeaders; if (Array.isArray(rawHeaders)) { const filteredHeaders = []; for (let i = 0; i < rawHeaders.length; i += 2) { @@ -38858,7 +39792,7 @@ var require_decompress = __commonJS({ } filteredHeaders.push(rawHeaders[i], rawHeaders[i + 1]); } - controller.rawHeaders = filteredHeaders; + rawHeaders.splice(0, rawHeaders.length, ...filteredHeaders); } else if (typeof rawHeaders === "object") { for (const name of Object.keys(rawHeaders)) { const lowerName = name.toLowerCase(); @@ -38868,12 +39802,13 @@ var require_decompress = __commonJS({ } } } + this.#setupInputBackpressure(); if (this.#decompressors.length === 1) { - this.#setupSingleDecompressor(controller); + this.#setupSingleDecompressor(); } else { - this.#setupMultipleDecompressors(controller); + this.#setupMultipleDecompressors(); } - return super.onResponseStart(controller, statusCode, newHeaders, statusMessage); + return super.onResponseStart(this.#controller, statusCode, newHeaders, statusMessage); } /** * @param {Controller} controller @@ -38882,10 +39817,13 @@ var require_decompress = __commonJS({ */ onResponseData(controller, chunk) { if (this.#decompressors.length > 0) { - this.#decompressors[0].write(chunk); + if (!this.#decompressors[0].write(chunk)) { + this.#inputBackpressured = true; + this.#pauseUpstream(); + } return; } - super.onResponseData(controller, chunk); + return super.onResponseData(this.#controller, chunk); } /** * @param {Controller} controller @@ -38894,12 +39832,12 @@ var require_decompress = __commonJS({ */ onResponseEnd(controller, trailers) { if (this.#decompressors.length > 0) { + this.#inputEnded = true; this.#trailers = trailers; this.#decompressors[0].end(); - this.#cleanupDecompressors(); return; } - super.onResponseEnd(controller, trailers); + return super.onResponseEnd(this.#controller, trailers); } /** * @param {Controller} controller @@ -38907,13 +39845,15 @@ var require_decompress = __commonJS({ * @returns {void} */ onResponseError(controller, err) { - if (this.#decompressors.length > 0) { - for (const decompressor of this.#decompressors) { - decompressor.destroy(err); - } - this.#cleanupDecompressors(); + if (this.#terminated) { + return; } - super.onResponseError(controller, err); + this.#terminated = true; + for (const decompressor of this.#decompressors) { + decompressor.destroy(); + } + this.#cleanupDecompressors(); + super.onResponseError(this.#controller, err); } }; function createDecompressInterceptor(options = {}) { @@ -39129,8 +40069,9 @@ var require_deduplication_handler = __commonJS({ if (this.#aborted || this.#completed) { return; } - this.#completed = true; + this.#cleanup(); this.#primaryHandler.onResponseEnd?.(controller, trailers); + this.#completed = true; for (const waitingHandler of this.#waitingHandlers) { if (waitingHandler.done || waitingHandler.controller.aborted) { waitingHandler.done = true; @@ -39141,18 +40082,18 @@ var require_deduplication_handler = __commonJS({ waitingHandler.done = true; continue; } - if (waitingHandler.controller.paused && waitingHandler.bufferedChunks.length > 0) { + if (waitingHandler.controller.paused) { waitingHandler.pendingTrailers = trailers; continue; } try { waitingHandler.handler.onResponseEnd?.(waitingHandler.controller, trailers); - } catch { + } catch (err) { + this.#errorWaitingHandler(waitingHandler, err); } waitingHandler.done = true; } this.#pruneDoneWaitingHandlers(); - this.#onComplete?.(); } /** * @param {import('../../types/dispatcher.d.ts').default.DispatchController} controller @@ -39164,12 +40105,17 @@ var require_deduplication_handler = __commonJS({ } this.#aborted = true; this.#completed = true; + this.#cleanup(); this.#primaryHandler.onResponseError?.(controller, err); for (const waitingHandler of this.#waitingHandlers) { this.#errorWaitingHandler(waitingHandler, err); } this.#waitingHandlers = []; - this.#onComplete?.(); + } + #cleanup() { + const onComplete = this.#onComplete; + this.#onComplete = null; + onComplete?.(); } /** * @param {DispatchHandler} handler @@ -39199,7 +40145,8 @@ var require_deduplication_handler = __commonJS({ if (this.#completed && waitingHandler.pendingTrailers && waitingHandler.bufferedChunks.length === 0 && !state.paused && !state.aborted) { try { waitingHandler.handler.onResponseEnd?.(waitingHandler.controller, waitingHandler.pendingTrailers); - } catch { + } catch (err) { + this.#errorWaitingHandler(waitingHandler, err); } waitingHandler.pendingTrailers = null; waitingHandler.done = true; @@ -39221,12 +40168,19 @@ var require_deduplication_handler = __commonJS({ return state.reason; }, abort: (reason) => { + if (state.aborted) { + return; + } state.aborted = true; state.reason = reason ?? null; waitingHandler.done = true; waitingHandler.pendingTrailers = null; waitingHandler.bufferedChunks = []; waitingHandler.bufferedBytes = 0; + try { + handler.onResponseError?.(waitingHandler.controller, state.reason ?? new RequestAbortedError()); + } catch { + } } }; return waitingHandler; @@ -39247,7 +40201,7 @@ var require_deduplication_handler = __commonJS({ waitingHandler.bufferedBytes += bufferedChunk.length; if (waitingHandler.bufferedBytes > this.#maxBufferSize) { const err = new RequestAbortedError(`Deduplicated waiting handler exceeded maxBufferSize (${this.#maxBufferSize} bytes) while paused`); - this.#errorWaitingHandler(waitingHandler, err); + waitingHandler.controller.abort(err); } } /** @@ -39284,7 +40238,6 @@ var require_deduplication_handler = __commonJS({ waitingHandler.bufferedChunks = []; waitingHandler.bufferedBytes = 0; try { - waitingHandler.controller.abort(err); waitingHandler.handler.onResponseError?.(waitingHandler.controller, err); } catch { } @@ -39304,7 +40257,7 @@ var require_deduplicate = __commonJS({ var diagnosticsChannel = require("node:diagnostics_channel"); var util4 = require_util9(); var DeduplicationHandler = require_deduplication_handler(); - var { normalizeHeaders, makeCacheKey, makeDeduplicationKey } = require_cache2(); + var { getInterceptorOrigin, normalizeHeaders, makeCacheKey, makeDeduplicationKey } = require_cache2(); var pendingRequestsChannel = diagnosticsChannel.channel("undici:request:pending-requests"); module2.exports = (opts = {}) => { const { @@ -39336,9 +40289,10 @@ var require_deduplicate = __commonJS({ const skipHeaderNamesSet = new Set(skipHeaderNames.map((name) => name.toLowerCase())); const excludeHeaderNamesSet = new Set(excludeHeaderNames.map((name) => name.toLowerCase())); const pendingRequests = /* @__PURE__ */ new Map(); - return (dispatch) => { + return (dispatch, interceptorOrigin) => { return (opts2, handler) => { - if (opts2.upgrade || methods.includes(opts2.method) === false) { + const requestOrigin = getInterceptorOrigin(opts2, interceptorOrigin); + if (!requestOrigin || opts2.upgrade || methods.includes(opts2.method) === false) { return dispatch(opts2, handler); } opts2 = { @@ -39352,7 +40306,7 @@ var require_deduplicate = __commonJS({ } } } - const cacheKey = makeCacheKey(opts2); + const cacheKey = makeCacheKey(opts2, requestOrigin); const dedupeKey = makeDeduplicationKey(cacheKey, excludeHeaderNamesSet); const pendingHandler = pendingRequests.get(dedupeKey); if (pendingHandler) { @@ -40013,7 +40967,11 @@ var require_headers2 = __commonJS({ } } }; - var Headers2 = class _Headers { + var getHeadersGuard; + var setHeadersGuard; + var getHeadersList; + var setHeadersList; + var Headers2 = class { #guard; /** * @type {HeadersList} @@ -40037,7 +40995,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-append append(name, value) { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); webidl.argumentLengthCheck(arguments, 2, "Headers.append"); const prefix = "Headers.append"; name = webidl.converters.ByteString(name, prefix, "name"); @@ -40046,7 +41004,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-delete delete(name) { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); webidl.argumentLengthCheck(arguments, 1, "Headers.delete"); const prefix = "Headers.delete"; name = webidl.converters.ByteString(name, prefix, "name"); @@ -40067,7 +41025,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-get get(name) { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); webidl.argumentLengthCheck(arguments, 1, "Headers.get"); const prefix = "Headers.get"; name = webidl.converters.ByteString(name, prefix, "name"); @@ -40082,7 +41040,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-has has(name) { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); webidl.argumentLengthCheck(arguments, 1, "Headers.has"); const prefix = "Headers.has"; name = webidl.converters.ByteString(name, prefix, "name"); @@ -40097,7 +41055,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-set set(name, value) { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); webidl.argumentLengthCheck(arguments, 2, "Headers.set"); const prefix = "Headers.set"; name = webidl.converters.ByteString(name, prefix, "name"); @@ -40123,7 +41081,7 @@ var require_headers2 = __commonJS({ } // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie getSetCookie() { - webidl.brandCheck(this, _Headers); + webidl.brandCheck(this, webidl.is.Headers); const list = this.#headersList.cookies; if (list) { return [...list]; @@ -40134,32 +41092,21 @@ var require_headers2 = __commonJS({ options.depth ??= depth; return `Headers ${util4.formatWithOptions(options, this.#headersList.entries)}`; } - static getHeadersGuard(o) { - return o.#guard; - } - static setHeadersGuard(o, guard) { - o.#guard = guard; - } - /** - * @param {Headers} o - */ - static getHeadersList(o) { - return o.#headersList; - } - /** - * @param {Headers} target - * @param {HeadersList} list - */ - static setHeadersList(target, list) { - target.#headersList = list; + static { + getHeadersGuard = (headers) => headers.#guard; + setHeadersGuard = (headers, guard) => { + headers.#guard = guard; + }; + getHeadersList = (headers) => headers.#headersList; + setHeadersList = (target, list) => { + target.#headersList = list; + }; + webidl.is.Headers = (arg) => { + return arg != null && typeof arg === "object" && #guard in arg; + }; } }; - var { getHeadersGuard, setHeadersGuard, getHeadersList, setHeadersList } = Headers2; - Reflect.deleteProperty(Headers2, "getHeadersGuard"); - Reflect.deleteProperty(Headers2, "setHeadersGuard"); - Reflect.deleteProperty(Headers2, "getHeadersList"); - Reflect.deleteProperty(Headers2, "setHeadersList"); - iteratorMixin("Headers", Headers2, headersListSortAndCombine, 0, 1); + iteratorMixin("Headers", Headers2, headersListSortAndCombine, 0, 1, webidl.is.Headers); Object.defineProperties(Headers2.prototype, { append: kEnumerableProperty, delete: kEnumerableProperty, @@ -40235,7 +41182,11 @@ var require_response2 = __commonJS({ var assert = require("node:assert"); var { isomorphicEncode, serializeJavascriptValueToJSONString } = require_infra(); var textEncoder2 = new TextEncoder("utf-8"); - var Response = class _Response { + var getResponseHeaders; + var setResponseHeaders; + var getResponseState; + var setResponseState; + var Response = class { /** @type {Headers} */ #headers; #state; @@ -40299,12 +41250,12 @@ var require_response2 = __commonJS({ } // Returns response’s type, e.g., "cors". get type() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.type; } // Returns response’s URL, if it has one; otherwise the empty string. get url() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); const urlList = this.#state.urlList; const url2 = urlList[urlList.length - 1] ?? null; if (url2 === null) { @@ -40314,40 +41265,40 @@ var require_response2 = __commonJS({ } // Returns whether response was obtained through a redirect. get redirected() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.urlList.length > 1; } // Returns response’s status. get status() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.status; } // Returns whether response’s status is an ok status. get ok() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.status >= 200 && this.#state.status <= 299; } // Returns response’s status message. get statusText() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.statusText; } // Returns response’s headers as Headers. get headers() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#headers; } get body() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return this.#state.body ? this.#state.body.stream : null; } get bodyUsed() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); return !!this.#state.body && util4.isDisturbed(this.#state.body.stream); } // Returns a clone of response. clone() { - webidl.brandCheck(this, _Response); + webidl.brandCheck(this, webidl.is.Response); if (bodyUnusable(this.#state)) { throw webidl.errors.exception({ header: "Response.clone", @@ -40378,39 +41329,25 @@ var require_response2 = __commonJS({ }; return `Response ${nodeUtil.formatWithOptions(options, properties)}`; } - /** - * @param {Response} response - */ - static getResponseHeaders(response) { - return response.#headers; - } - /** - * @param {Response} response - * @param {Headers} newHeaders - */ - static setResponseHeaders(response, newHeaders) { - response.#headers = newHeaders; - } - /** - * @param {Response} response - */ - static getResponseState(response) { - return response.#state; - } - /** - * @param {Response} response - * @param {any} newState - */ - static setResponseState(response, newState) { - response.#state = newState; + static { + getResponseHeaders = (response) => { + return response.#headers; + }; + setResponseHeaders = (response, newHeaders) => { + response.#headers = newHeaders; + }; + getResponseState = (response) => { + return response.#state; + }; + setResponseState = (response, newState) => { + response.#state = newState; + }; + webidl.is.Response = (arg) => { + return arg != null && typeof arg === "object" && #state in arg; + }; } }; - var { getResponseHeaders, setResponseHeaders, getResponseState, setResponseState } = Response; - Reflect.deleteProperty(Response, "getResponseHeaders"); - Reflect.deleteProperty(Response, "setResponseHeaders"); - Reflect.deleteProperty(Response, "getResponseState"); - Reflect.deleteProperty(Response, "setResponseState"); - mixinBody(Response, getResponseState); + mixinBody(Response, getResponseState, webidl.is.Response); Object.defineProperties(Response.prototype, { type: kEnumerableProperty, url: kEnumerableProperty, @@ -40614,7 +41551,6 @@ var require_response2 = __commonJS({ converter: webidl.converters.HeadersInit } ]); - webidl.is.Response = webidl.util.MakeTypeAssertion(Response); module2.exports = { isNetworkError, makeNetworkError, @@ -40694,7 +41630,14 @@ var require_request4 = __commonJS({ } } var patchMethodWarning = false; - var Request = class _Request { + var setRequestSignal; + var getRequestDispatcher; + var setRequestDispatcher; + var setRequestHeaders; + var getRequestState; + var setRequestState; + var removeRequestAbortListener; + var Request = class { /** @type {AbortSignal} */ #signal; /** @type {import('../../dispatcher/dispatcher')} */ @@ -40984,25 +41927,25 @@ var require_request4 = __commonJS({ } // Returns request’s HTTP method, which is "GET" by default. get method() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.method; } // Returns the URL of request as a string. get url() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return URLSerializer(this.#state.url); } // Returns a Headers object consisting of the headers associated with request. // Note that headers added in the network layer by the user agent will not // be accounted for in this object, e.g., the "Host" header. get headers() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#headers; } // Returns the kind of resource requested by request, e.g., "document" // or "script". get destination() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.destination; } // Returns the referrer of request. Its value can be a same-origin URL if @@ -41011,7 +41954,7 @@ var require_request4 = __commonJS({ // during fetching to determine the value of the `Referer` header of the // request being made. get referrer() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); if (this.#state.referrer === "no-referrer") { return ""; } @@ -41024,28 +41967,28 @@ var require_request4 = __commonJS({ // This is used during fetching to compute the value of the request’s // referrer. get referrerPolicy() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.referrerPolicy; } // Returns the mode associated with request, which is a string indicating // whether the request will use CORS, or will be restricted to same-origin // URLs. get mode() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.mode; } // Returns the credentials mode associated with request, // which is a string indicating whether credentials will be sent with the // request always, never, or only when sent to a same-origin URL. get credentials() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.credentials; } // Returns the cache mode associated with request, // which is a string indicating how the request will // interact with the browser’s cache when fetching. get cache() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.cache; } // Returns the redirect mode associated with request, @@ -41053,56 +41996,56 @@ var require_request4 = __commonJS({ // request will be handled during fetching. A request // will follow redirects by default. get redirect() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.redirect; } // Returns request’s subresource integrity metadata, which is a // cryptographic hash of the resource being fetched. Its value // consists of multiple hashes separated by whitespace. [SRI] get integrity() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.integrity; } // Returns a boolean indicating whether or not request can outlive the // global in which it was created. get keepalive() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.keepalive; } // Returns a boolean indicating whether or not request is for a reload // navigation. get isReloadNavigation() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.reloadNavigation; } // Returns a boolean indicating whether or not request is for a history // navigation (a.k.a. back-forward navigation). get isHistoryNavigation() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.historyNavigation; } // Returns the signal associated with request, which is an AbortSignal // object indicating whether or not request has been aborted, and its // abort event handler. get signal() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#signal; } get body() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return this.#state.body ? this.#state.body.stream : null; } get bodyUsed() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return !!this.#state.body && util4.isDisturbed(this.#state.body.stream); } get duplex() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); return "half"; } // Returns a clone of request. clone() { - webidl.brandCheck(this, _Request); + webidl.brandCheck(this, webidl.is.Request); if (bodyUnusable(this.#state)) { throw new TypeError("unusable"); } @@ -41149,65 +42092,34 @@ var require_request4 = __commonJS({ }; return `Request ${nodeUtil.formatWithOptions(options, properties)}`; } - /** - * @param {Request} request - * @param {AbortSignal} newSignal - */ - static setRequestSignal(request, newSignal) { - request.#signal = newSignal; - return request; - } - /** - * @param {Request} request - */ - static getRequestDispatcher(request) { - return request.#dispatcher; - } - /** - * @param {Request} request - * @param {import('../../dispatcher/dispatcher')} newDispatcher - */ - static setRequestDispatcher(request, newDispatcher) { - request.#dispatcher = newDispatcher; - } - /** - * @param {Request} request - * @param {Headers} newHeaders - */ - static setRequestHeaders(request, newHeaders) { - request.#headers = newHeaders; - } - /** - * @param {Request} request - */ - static getRequestState(request) { - return request.#state; - } - /** - * @param {Request} request - * @param {any} newState - */ - static setRequestState(request, newState) { - request.#state = newState; + static { + setRequestSignal = (request, newSignal) => { + request.#signal = newSignal; + }; + getRequestDispatcher = (request) => { + return request.#dispatcher; + }; + setRequestDispatcher = (request, newDispatcher) => { + request.#dispatcher = newDispatcher; + }; + setRequestHeaders = (request, newHeaders) => { + request.#headers = newHeaders; + }; + getRequestState = (request) => { + return request.#state; + }; + setRequestState = (request, newState) => { + request.#state = newState; + }; + removeRequestAbortListener = (request) => { + request.#abortCleanup?.(); + }; + webidl.is.Request = (arg) => { + return arg != null && typeof arg === "object" && #state in arg; + }; } - /** - * Removes the `abort` listener that makes this request's signal follow the - * signal passed to its constructor, if any. Idempotent. - * @param {Request} request - */ - static removeRequestAbortListener(request) { - request.#abortCleanup?.(); - } - }; - var { setRequestSignal, getRequestDispatcher, setRequestDispatcher, setRequestHeaders, getRequestState, setRequestState, removeRequestAbortListener } = Request; - Reflect.deleteProperty(Request, "setRequestSignal"); - Reflect.deleteProperty(Request, "getRequestDispatcher"); - Reflect.deleteProperty(Request, "setRequestDispatcher"); - Reflect.deleteProperty(Request, "setRequestHeaders"); - Reflect.deleteProperty(Request, "getRequestState"); - Reflect.deleteProperty(Request, "setRequestState"); - Reflect.deleteProperty(Request, "removeRequestAbortListener"); - mixinBody(Request, getRequestState); + }; + mixinBody(Request, getRequestState, webidl.is.Request); function makeRequest(init) { return { method: init.method ?? "GET", @@ -41222,7 +42134,7 @@ var require_request4 = __commonJS({ serviceWorkers: init.serviceWorkers ?? "all", initiator: init.initiator ?? "", destination: init.destination ?? "", - priority: init.priority ?? null, + priority: init.priority ?? "auto", origin: init.origin ?? "client", policyContainer: init.policyContainer ?? "client", referrer: init.referrer ?? "client", @@ -41297,7 +42209,6 @@ var require_request4 = __commonJS({ configurable: true } }); - webidl.is.Request = webidl.util.MakeTypeAssertion(Request); webidl.converters.RequestInfo = function(V) { if (typeof V === "string") { return webidl.converters.USVString(V); @@ -41391,8 +42302,7 @@ var require_request4 = __commonJS({ { key: "priority", converter: webidl.converters.DOMString, - allowedValues: ["high", "low", "auto"], - defaultValue: () => "auto" + allowedValues: ["high", "low", "auto"] } ]); module2.exports = { @@ -41607,6 +42517,7 @@ var require_fetch2 = __commonJS({ var EE = require("node:events"); var { Readable: Readable3, pipeline, finished, isErrored, isReadable } = require("node:stream"); var { addAbortListener, bufferToLowerCasedHeaderName } = require_util9(); + var { SocketError } = require_errors2(); var { dataURLProcessor, serializeAMimeType, minimizeSupportedMimeType } = require_data_url2(); var { getGlobalDispatcher } = require_global4(); var { webidl } = require_webidl2(); @@ -41966,7 +42877,7 @@ var require_fetch2 = __commonJS({ } } function schemeFetch(fetchParams) { - if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { + if (isCancelled(fetchParams)) { return Promise.resolve(makeAppropriateNetworkError(fetchParams)); } const { request } = fetchParams; @@ -42064,11 +42975,11 @@ var require_fetch2 = __commonJS({ } function fetchFinale(fetchParams, response) { let timingInfo = fetchParams.timingInfo; + if (fetchParams.request.destination === "document") { + fetchParams.controller.fullTimingInfo = timingInfo; + } const processResponseEndOfBody = () => { const unsafeEndTime = Date.now(); - if (fetchParams.request.destination === "document") { - fetchParams.controller.fullTimingInfo = timingInfo; - } fetchParams.controller.reportTimingSteps = () => { if (!urlIsHttpHttpsScheme(fetchParams.request.url)) { return; @@ -42117,6 +43028,15 @@ var require_fetch2 = __commonJS({ processResponseEndOfBody(); }); } + if (fetchParams.processResponseConsumeBody != null) { + const processBody = (nullOrBytes) => fetchParams.processResponseConsumeBody(response, nullOrBytes); + const processBodyError = () => fetchParams.processResponseConsumeBody(response, "failure"); + if (internalResponse.body == null) { + queueMicrotask(() => processBody(null)); + } else { + fullyReadBody(internalResponse.body, processBody, processBodyError); + } + } } async function httpFetch(fetchParams) { const request = fetchParams.request; @@ -42147,7 +43067,7 @@ var require_fetch2 = __commonJS({ } if (redirectStatusSet.has(actualResponse.status)) { if (request.redirect !== "manual") { - fetchParams.controller.connection.destroy(void 0, false); + fetchParams.controller.connection.destroy(); } if (request.redirect === "error") { response = makeNetworkError("unexpected redirect"); @@ -42378,12 +43298,10 @@ var require_fetch2 = __commonJS({ fetchParams.controller.connection = { abort: null, destroyed: false, - destroy(err, abort = true) { + destroy(err) { if (!this.destroyed) { this.destroyed = true; - if (abort) { - this.abort?.(err ?? new DOMException("The operation was aborted.", "AbortError")); - } + this.abort?.(err ?? new DOMException("The operation was aborted.", "AbortError")); } } }; @@ -42653,7 +43571,7 @@ var require_fetch2 = __commonJS({ fetchParams.controller.ended = true; this.body?.push(null); }, - onResponseError(_controller, error2) { + onResponseError(controller, error2) { if (this.abort) { fetchParams.controller.off("terminated", this.abort); } @@ -42662,11 +43580,16 @@ var require_fetch2 = __commonJS({ return; } this.body?.destroy(error2); - fetchParams.controller.terminate(error2); + if (!controller?.aborted) { + fetchParams.controller.terminate(error2); + } reject(error2); }, onRequestUpgrade(controller, status, headers, socket) { if (socket.session != null && status !== 200 || socket.session == null && status !== 101) { + if (socket.session != null) { + controller.abort(new SocketError("bad upgrade", null)); + } return false; } const rawHeaders = controller?.rawHeaders ?? []; @@ -42737,7 +43660,7 @@ var require_cache4 = __commonJS({ var { Request, fromInnerRequest, getRequestState } = require_request4(); var { fetching } = require_fetch2(); var { urlIsHttpHttpsScheme, readAllBytes } = require_util10(); - var Cache = class _Cache { + var Cache = class { /** * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list * @type {requestResponseList} @@ -42751,7 +43674,7 @@ var require_cache4 = __commonJS({ this.#relevantRequestResponseList = arguments[1]; } async match(request, options = {}) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix = "Cache.match"; webidl.argumentLengthCheck(arguments, 1, prefix); request = webidl.converters.RequestInfo(request); @@ -42763,14 +43686,14 @@ var require_cache4 = __commonJS({ return p[0]; } async matchAll(request = void 0, options = {}) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix = "Cache.matchAll"; if (request !== void 0) request = webidl.converters.RequestInfo(request); options = webidl.converters.CacheQueryOptions(options, prefix, "options"); return this.#internalMatchAll(request, options); } async add(request) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix = "Cache.add"; webidl.argumentLengthCheck(arguments, 1, prefix); request = webidl.converters.RequestInfo(request); @@ -42779,7 +43702,7 @@ var require_cache4 = __commonJS({ return await responseArrayPromise; } async addAll(requests) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix = "Cache.addAll"; webidl.argumentLengthCheck(arguments, 1, prefix); const responsePromises = []; @@ -42841,7 +43764,10 @@ var require_cache4 = __commonJS({ } } }, - processResponseEndOfBody(response) { + // Possible spec bug. If the body is never read, `processResponseEndOfBody` (which is attached to a TransformStream's flush hook) + // never runs, so this would hang. This hook, on the other hand, always reads the body. + // https://github.com/nodejs/undici/issues/5615 + processResponseConsumeBody(response) { if (response.aborted) { responsePromise.reject(new DOMException("aborted", "AbortError")); return; @@ -42884,7 +43810,7 @@ var require_cache4 = __commonJS({ return cacheJobPromise.promise; } async put(request, response) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix = "Cache.put"; webidl.argumentLengthCheck(arguments, 2, prefix); request = webidl.converters.RequestInfo(request); @@ -42965,7 +43891,7 @@ var require_cache4 = __commonJS({ return cacheJobPromise.promise; } async delete(request, options = {}) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix = "Cache.delete"; webidl.argumentLengthCheck(arguments, 1, prefix); request = webidl.converters.RequestInfo(request); @@ -43011,7 +43937,7 @@ var require_cache4 = __commonJS({ * @returns {Promise} */ async keys(request = void 0, options = {}) { - webidl.brandCheck(this, _Cache); + webidl.brandCheck(this, webidl.is.Cache); const prefix = "Cache.keys"; if (request !== void 0) request = webidl.converters.RequestInfo(request); options = webidl.converters.CacheQueryOptions(options, prefix, "options"); @@ -43220,6 +44146,11 @@ var require_cache4 = __commonJS({ } return Object.freeze(responseList); } + static { + webidl.is.Cache = (arg) => { + return arg != null && typeof arg === "object" && #relevantRequestResponseList in arg; + }; + } }; Object.defineProperties(Cache.prototype, { [Symbol.toStringTag]: { @@ -43280,7 +44211,7 @@ var require_cachestorage2 = __commonJS({ var { webidl } = require_webidl2(); var { kEnumerableProperty } = require_util9(); var { kConstruct } = require_symbols6(); - var CacheStorage = class _CacheStorage { + var CacheStorage = class { /** * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map * @type {Map} */ async has(cacheName) { - webidl.brandCheck(this, _CacheStorage); + webidl.brandCheck(this, webidl.is.CacheStorage); const prefix = "CacheStorage.has"; webidl.argumentLengthCheck(arguments, 1, prefix); cacheName = webidl.converters.DOMString(cacheName, prefix, "cacheName"); @@ -43331,7 +44262,7 @@ var require_cachestorage2 = __commonJS({ * @returns {Promise} */ async open(cacheName) { - webidl.brandCheck(this, _CacheStorage); + webidl.brandCheck(this, webidl.is.CacheStorage); const prefix = "CacheStorage.open"; webidl.argumentLengthCheck(arguments, 1, prefix); cacheName = webidl.converters.DOMString(cacheName, prefix, "cacheName"); @@ -43349,7 +44280,7 @@ var require_cachestorage2 = __commonJS({ * @returns {Promise} */ async delete(cacheName) { - webidl.brandCheck(this, _CacheStorage); + webidl.brandCheck(this, webidl.is.CacheStorage); const prefix = "CacheStorage.delete"; webidl.argumentLengthCheck(arguments, 1, prefix); cacheName = webidl.converters.DOMString(cacheName, prefix, "cacheName"); @@ -43360,10 +44291,15 @@ var require_cachestorage2 = __commonJS({ * @returns {Promise} */ async keys() { - webidl.brandCheck(this, _CacheStorage); + webidl.brandCheck(this, webidl.is.CacheStorage); const keys = this.#caches.keys(); return [...keys]; } + static { + webidl.is.CacheStorage = (arg) => { + return arg != null && typeof arg === "object" && #caches in arg; + }; + } }; Object.defineProperties(CacheStorage.prototype, { [Symbol.toStringTag]: { @@ -43573,7 +44509,7 @@ var require_util12 = __commonJS({ validateCookiePath(cookie.path); out.push(`Path=${cookie.path}`); } - if (cookie.expires && cookie.expires.toString() !== "Invalid Date") { + if (cookie.expires != null && cookie.expires.toString() !== "Invalid Date") { out.push(`Expires=${toIMFDate(cookie.expires)}`); } if (cookie.sameSite) { @@ -43649,90 +44585,93 @@ var require_parse2 = __commonJS({ }; } function parseUnparsedAttributes(unparsedAttributes, cookieAttributeList = {}) { - if (unparsedAttributes.length === 0) { - return cookieAttributeList; - } - assert(unparsedAttributes[0] === ";"); - unparsedAttributes = unparsedAttributes.slice(1); - let cookieAv = ""; - if (unparsedAttributes.includes(";")) { - cookieAv = collectASequenceOfCodePointsFast( - ";", - unparsedAttributes, - { position: 0 } - ); - unparsedAttributes = unparsedAttributes.slice(cookieAv.length); - } else { - cookieAv = unparsedAttributes; - unparsedAttributes = ""; - } - let attributeName = ""; - let attributeValue = ""; - if (cookieAv.includes("=")) { - const position = { position: 0 }; - attributeName = collectASequenceOfCodePointsFast( - "=", - cookieAv, - position - ); - attributeValue = cookieAv.slice(position.position + 1); - } else { - attributeName = cookieAv; - } - attributeName = attributeName.trim(); - attributeValue = attributeValue.trim(); - if (attributeValue.length > maxAttributeValueSize) { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); - } - const attributeNameLowercase = attributeName.toLowerCase(); - if (attributeNameLowercase === "expires") { - const expiryTime = new Date(attributeValue); - if (!Number.isNaN(expiryTime.getTime())) { - cookieAttributeList.expires = expiryTime; - } - } else if (attributeNameLowercase === "max-age") { - const charCode = attributeValue.charCodeAt(0); - if ((charCode < 48 || charCode > 57) && attributeValue[0] !== "-") { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); - } - if (!/^\d+$/.test(attributeValue)) { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); + while (true) { + if (unparsedAttributes.length === 0) { + return cookieAttributeList; + } + assert(unparsedAttributes[0] === ";"); + unparsedAttributes = unparsedAttributes.slice(1); + let cookieAv = ""; + if (unparsedAttributes.includes(";")) { + cookieAv = collectASequenceOfCodePointsFast( + ";", + unparsedAttributes, + { position: 0 } + ); + unparsedAttributes = unparsedAttributes.slice(cookieAv.length); + } else { + cookieAv = unparsedAttributes; + unparsedAttributes = ""; + } + let attributeName = ""; + let attributeValue = ""; + if (cookieAv.includes("=")) { + const position = { position: 0 }; + attributeName = collectASequenceOfCodePointsFast( + "=", + cookieAv, + position + ); + attributeValue = cookieAv.slice(position.position + 1); + } else { + attributeName = cookieAv; } - const deltaSeconds = Number(attributeValue); - cookieAttributeList.maxAge = deltaSeconds; - } else if (attributeNameLowercase === "domain") { - let cookieDomain = attributeValue; - if (cookieDomain[0] === ".") { - cookieDomain = cookieDomain.slice(1); + attributeName = attributeName.trim(); + attributeValue = attributeValue.trim(); + if (attributeValue.length > maxAttributeValueSize) { + continue; } - cookieDomain = cookieDomain.toLowerCase(); - cookieAttributeList.domain = cookieDomain; - } else if (attributeNameLowercase === "path") { - let cookiePath = ""; - if (attributeValue.length === 0 || attributeValue[0] !== "/") { - cookiePath = "/"; + const attributeNameLowercase = attributeName.toLowerCase(); + if (attributeNameLowercase === "expires") { + const expiryTime = new Date(attributeValue); + if (!Number.isNaN(expiryTime.getTime())) { + cookieAttributeList.expires = expiryTime; + } + } else if (attributeNameLowercase === "max-age") { + const charCode = attributeValue.charCodeAt(0); + const startsWithDigit = charCode >= 48 && charCode <= 57; + const startsWithSignedDigit = attributeValue[0] === "-" && attributeValue.length > 1; + if (!startsWithDigit && !startsWithSignedDigit) { + continue; + } + if (/[^\d]/.test(attributeValue.slice(1))) { + continue; + } + const deltaSeconds = Number(attributeValue); + cookieAttributeList.maxAge = deltaSeconds; + } else if (attributeNameLowercase === "domain") { + let cookieDomain = attributeValue; + if (cookieDomain[0] === ".") { + cookieDomain = cookieDomain.slice(1); + } + cookieDomain = cookieDomain.toLowerCase(); + cookieAttributeList.domain = cookieDomain; + } else if (attributeNameLowercase === "path") { + let cookiePath = ""; + if (attributeValue.length === 0 || attributeValue[0] !== "/") { + cookiePath = "/"; + } else { + cookiePath = attributeValue; + } + cookieAttributeList.path = cookiePath; + } else if (attributeNameLowercase === "secure") { + cookieAttributeList.secure = true; + } else if (attributeNameLowercase === "httponly") { + cookieAttributeList.httpOnly = true; + } else if (attributeNameLowercase === "samesite") { + const attributeValueLowercase = attributeValue.toLowerCase(); + if (attributeValueLowercase === "none") { + cookieAttributeList.sameSite = "None"; + } else if (attributeValueLowercase === "strict") { + cookieAttributeList.sameSite = "Strict"; + } else if (attributeValueLowercase === "lax") { + cookieAttributeList.sameSite = "Lax"; + } } else { - cookiePath = attributeValue; - } - cookieAttributeList.path = cookiePath; - } else if (attributeNameLowercase === "secure") { - cookieAttributeList.secure = true; - } else if (attributeNameLowercase === "httponly") { - cookieAttributeList.httpOnly = true; - } else if (attributeNameLowercase === "samesite") { - const attributeValueLowercase = attributeValue.toLowerCase(); - if (attributeValueLowercase === "none") { - cookieAttributeList.sameSite = "None"; - } else if (attributeValueLowercase === "strict") { - cookieAttributeList.sameSite = "Strict"; - } else if (attributeValueLowercase === "lax") { - cookieAttributeList.sameSite = "Lax"; + cookieAttributeList.unparsed ??= []; + cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`); } - } else { - cookieAttributeList.unparsed ??= []; - cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`); } - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); } module2.exports = { parseSetCookie, @@ -43748,13 +44687,21 @@ var require_cookies2 = __commonJS({ var { parseSetCookie } = require_parse2(); var { stringify } = require_util12(); var { webidl } = require_webidl2(); - var { Headers: Headers2 } = require_headers2(); - var brandChecks = webidl.brandCheckMultiple([Headers2, globalThis.Headers].filter(Boolean)); + var globalHeadersBrandCheck = (arg) => webidl.brandCheck(arg, webidl.util.MakeTypeAssertion(globalThis.Headers)); + var undiciHeadersBrandCheck = (arg) => webidl.brandCheck(arg, webidl.is.Headers); + function brandCheckHeaders(arg) { + try { + undiciHeadersBrandCheck(arg); + return; + } catch { + } + globalHeadersBrandCheck(arg); + } function getCookies(headers) { webidl.argumentLengthCheck(arguments, 1, "getCookies"); - brandChecks(headers); + brandCheckHeaders(headers); const cookie = headers.get("cookie"); - const out = {}; + const out = { __proto__: null }; if (!cookie) { return out; } @@ -43765,7 +44712,7 @@ var require_cookies2 = __commonJS({ return out; } function deleteCookie(headers, name, attributes) { - brandChecks(headers); + brandCheckHeaders(headers); const prefix = "deleteCookie"; webidl.argumentLengthCheck(arguments, 2, prefix); name = webidl.converters.DOMString(name, prefix, "name"); @@ -43779,7 +44726,7 @@ var require_cookies2 = __commonJS({ } function getSetCookies(headers) { webidl.argumentLengthCheck(arguments, 1, "getSetCookies"); - brandChecks(headers); + brandCheckHeaders(headers); const cookies = headers.getSetCookie(); if (!cookies) { return []; @@ -43792,7 +44739,7 @@ var require_cookies2 = __commonJS({ } function setCookie(headers, cookie) { webidl.argumentLengthCheck(arguments, 2, "setCookie"); - brandChecks(headers); + brandCheckHeaders(headers); cookie = webidl.converters.Cookie(cookie); const str = stringify(cookie); if (str) { @@ -43883,6 +44830,7 @@ var require_events2 = __commonJS({ var { webidl } = require_webidl2(); var { kEnumerableProperty } = require_util9(); var { kConstruct } = require_symbols6(); + var createFastMessageEvent; var MessageEvent = class _MessageEvent extends Event { #eventInit; constructor(type, eventInitDict = {}) { @@ -43900,30 +44848,30 @@ var require_events2 = __commonJS({ webidl.util.markAsUncloneable(this); } get data() { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); return this.#eventInit.data; } get origin() { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); return this.#eventInit.origin; } get lastEventId() { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); return this.#eventInit.lastEventId; } get source() { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); return this.#eventInit.source; } get ports() { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); if (!Object.isFrozen(this.#eventInit.ports)) { Object.freeze(this.#eventInit.ports); } return this.#eventInit.ports; } initMessageEvent(type, bubbles = false, cancelable = false, data = null, origin2 = "", lastEventId = "", source = null, ports = []) { - webidl.brandCheck(this, _MessageEvent); + webidl.brandCheck(this, webidl.is.MessageEvent); webidl.argumentLengthCheck(arguments, 1, "MessageEvent.initMessageEvent"); return new _MessageEvent(type, { bubbles, @@ -43935,20 +44883,23 @@ var require_events2 = __commonJS({ ports }); } - static createFastMessageEvent(type, init) { - const messageEvent = new _MessageEvent(kConstruct, type, init); - messageEvent.#eventInit = init; - messageEvent.#eventInit.data ??= null; - messageEvent.#eventInit.origin ??= ""; - messageEvent.#eventInit.lastEventId ??= ""; - messageEvent.#eventInit.source ??= null; - messageEvent.#eventInit.ports ??= []; - return messageEvent; + static { + createFastMessageEvent = (type, init) => { + const messageEvent = new _MessageEvent(kConstruct, type, init); + messageEvent.#eventInit = init; + messageEvent.#eventInit.data ??= null; + messageEvent.#eventInit.origin ??= ""; + messageEvent.#eventInit.lastEventId ??= ""; + messageEvent.#eventInit.source ??= null; + messageEvent.#eventInit.ports ??= []; + return messageEvent; + }; + webidl.is.MessageEvent = (arg) => { + return arg != null && typeof arg === "object" && #eventInit in arg; + }; } }; - var { createFastMessageEvent } = MessageEvent; - delete MessageEvent.createFastMessageEvent; - var CloseEvent = class _CloseEvent extends Event { + var CloseEvent = class extends Event { #eventInit; constructor(type, eventInitDict = {}) { const prefix = "CloseEvent constructor"; @@ -43960,19 +44911,24 @@ var require_events2 = __commonJS({ webidl.util.markAsUncloneable(this); } get wasClean() { - webidl.brandCheck(this, _CloseEvent); + webidl.brandCheck(this, webidl.is.CloseEvent); return this.#eventInit.wasClean; } get code() { - webidl.brandCheck(this, _CloseEvent); + webidl.brandCheck(this, webidl.is.CloseEvent); return this.#eventInit.code; } get reason() { - webidl.brandCheck(this, _CloseEvent); + webidl.brandCheck(this, webidl.is.CloseEvent); return this.#eventInit.reason; } + static { + webidl.is.CloseEvent = (arg) => { + return arg != null && typeof arg === "object" && #eventInit in arg; + }; + } }; - var ErrorEvent = class _ErrorEvent extends Event { + var ErrorEvent = class extends Event { #eventInit; constructor(type, eventInitDict) { const prefix = "ErrorEvent constructor"; @@ -43984,25 +44940,30 @@ var require_events2 = __commonJS({ this.#eventInit = eventInitDict; } get message() { - webidl.brandCheck(this, _ErrorEvent); + webidl.brandCheck(this, webidl.is.ErrorEvent); return this.#eventInit.message; } get filename() { - webidl.brandCheck(this, _ErrorEvent); + webidl.brandCheck(this, webidl.is.ErrorEvent); return this.#eventInit.filename; } get lineno() { - webidl.brandCheck(this, _ErrorEvent); + webidl.brandCheck(this, webidl.is.ErrorEvent); return this.#eventInit.lineno; } get colno() { - webidl.brandCheck(this, _ErrorEvent); + webidl.brandCheck(this, webidl.is.ErrorEvent); return this.#eventInit.colno; } get error() { - webidl.brandCheck(this, _ErrorEvent); + webidl.brandCheck(this, webidl.is.ErrorEvent); return this.#eventInit.error; } + static { + webidl.is.ErrorEvent = (arg) => { + return arg != null && typeof arg === "object" && #eventInit in arg; + }; + } }; Object.defineProperties(MessageEvent.prototype, { [Symbol.toStringTag]: { @@ -44525,11 +45486,11 @@ var require_connection2 = __commonJS({ processResponse(response) { if (response.type === "error" || response.status !== 101) { if (response.socket?.session == null) { - failWebsocketConnection(handler, 1002, "Received network error or non-101 status code.", response.error); + failHandshake(handler, response, 1002, "Received network error or non-101 status code.", response.error); return; } if (response.status !== 200) { - failWebsocketConnection(handler, 1002, "Received network error or non-200 status code.", response.error); + failHandshake(handler, response, 1002, "Received network error or non-200 status code.", response.error); return; } } @@ -44538,40 +45499,45 @@ var require_connection2 = __commonJS({ warningEmitted = true; } if (protocols.length !== 0 && !response.headersList.get("Sec-WebSocket-Protocol")) { - failWebsocketConnection(handler, 1002, "Server did not respond with sent protocols."); + failHandshake(handler, response, 1002, "Server did not respond with sent protocols."); return; } if (response.socket.session == null && response.headersList.get("Upgrade")?.toLowerCase() !== "websocket") { - failWebsocketConnection(handler, 1002, 'Server did not set Upgrade header to "websocket".'); + failHandshake(handler, response, 1002, 'Server did not set Upgrade header to "websocket".'); return; } if (response.socket.session == null && response.headersList.get("Connection")?.toLowerCase() !== "upgrade") { - failWebsocketConnection(handler, 1002, 'Server did not set Connection header to "upgrade".'); + failHandshake(handler, response, 1002, 'Server did not set Connection header to "upgrade".'); return; } - const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); - const digest = crypto3.hash("sha1", keyValue + uid, "base64"); - if (secWSAccept !== digest) { - failWebsocketConnection(handler, 1002, "Incorrect hash received in Sec-WebSocket-Accept header."); - return; + if (response.socket.session == null) { + const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); + const digest = crypto3.hash("sha1", keyValue + uid, "base64"); + if (secWSAccept !== digest) { + failHandshake(handler, response, 1002, "Incorrect hash received in Sec-WebSocket-Accept header."); + return; + } } const secExtension = response.headersList.get("Sec-WebSocket-Extensions"); let extensions; if (secExtension !== null) { extensions = parseExtensions(secExtension); if (!extensions.has("permessage-deflate")) { - failWebsocketConnection(handler, 1002, "Sec-WebSocket-Extensions header does not match."); + failHandshake(handler, response, 1002, "Sec-WebSocket-Extensions header does not match."); return; } } const secProtocol = response.headersList.get("Sec-WebSocket-Protocol"); if (secProtocol !== null) { const requestProtocols = getDecodeSplit("sec-websocket-protocol", request.headersList); - if (!requestProtocols.includes(secProtocol)) { - failWebsocketConnection(handler, 1002, "Protocol was not set in the opening handshake."); + if (requestProtocols === null || !requestProtocols.includes(secProtocol)) { + failHandshake(handler, response, 1002, "Protocol was not set in the opening handshake."); return; } } + if (response.socket.session != null) { + response.socket.allowHalfOpen = false; + } response.socket.on("data", handler.onSocketData); response.socket.on("close", handler.onSocketClose); response.socket.on("error", handler.onSocketError); @@ -44614,6 +45580,12 @@ var require_connection2 = __commonJS({ object.readyState = states.CLOSING; } } + function failHandshake(handler, response, code, reason, cause) { + if (response.socket?.session != null && !response.socket.destroyed) { + response.socket.destroy(); + } + failWebsocketConnection(handler, code, reason, cause); + } function failWebsocketConnection(handler, code, reason, cause) { if (isEstablished(handler.readyState)) { closeWebSocketConnection(handler, code, reason, false); @@ -44685,6 +45657,7 @@ var require_permessage_deflate2 = __commonJS({ if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) { callback(new MessageSizeExceededError()); this.#inflate.removeAllListeners(); + this.#inflate.destroy(); this.#inflate = null; return; } @@ -44987,6 +45960,7 @@ var require_receiver2 = __commonJS({ } consumeFragments() { const fragments = this.#fragments; + this.#info.compressed = false; if (fragments.length === 1) { this.#fragmentsBytes = 0; return fragments.shift(); @@ -45190,6 +46164,7 @@ var require_websocket2 = __commonJS({ var { channels } = require_diagnostics2(); var kRef = /* @__PURE__ */ Symbol.for("nodejs.ref"); var kUnref = /* @__PURE__ */ Symbol.for("nodejs.unref"); + var ping; function getSocketAddress(socket) { if (typeof socket?.address === "function") { return socket.address(); @@ -45292,13 +46267,13 @@ var require_websocket2 = __commonJS({ this.#handler.readyState = _WebSocket.CONNECTING; this.#binaryType = "blob"; } + // TODO: remove this [kRef]() { - webidl.brandCheck(this, _WebSocket); this.#refed = true; this.#handler.socket?.ref?.(); } + // TODO: remove this [kUnref]() { - webidl.brandCheck(this, _WebSocket); this.#refed = false; this.#handler.socket?.unref?.(); } @@ -45308,7 +46283,7 @@ var require_websocket2 = __commonJS({ * @param {string|undefined} reason */ close(code = void 0, reason = void 0) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); const prefix = "WebSocket.close"; if (code !== void 0) { code = webidl.converters["unsigned short"](code, prefix, "code", webidl.attributes.Clamp); @@ -45325,7 +46300,7 @@ var require_websocket2 = __commonJS({ * @param {NodeJS.TypedArray|ArrayBuffer|Blob|string} data */ send(data) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); const prefix = "WebSocket.send"; webidl.argumentLengthCheck(arguments, 1, prefix); data = webidl.converters.WebSocketSendData(data, prefix, "data"); @@ -45359,31 +46334,31 @@ var require_websocket2 = __commonJS({ } } get readyState() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#handler.readyState; } get bufferedAmount() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#bufferedAmount; } get url() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return URLSerializer(this.#url); } get extensions() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#extensions; } get protocol() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#protocol; } get onopen() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#events.open; } set onopen(fn) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); if (this.#events.open) { this.removeEventListener("open", this.#events.open); } @@ -45396,11 +46371,11 @@ var require_websocket2 = __commonJS({ } } get onerror() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#events.error; } set onerror(fn) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); if (this.#events.error) { this.removeEventListener("error", this.#events.error); } @@ -45413,11 +46388,11 @@ var require_websocket2 = __commonJS({ } } get onclose() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#events.close; } set onclose(fn) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); if (this.#events.close) { this.removeEventListener("close", this.#events.close); } @@ -45430,11 +46405,11 @@ var require_websocket2 = __commonJS({ } } get onmessage() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#events.message; } set onmessage(fn) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); if (this.#events.message) { this.removeEventListener("message", this.#events.message); } @@ -45447,11 +46422,11 @@ var require_websocket2 = __commonJS({ } } get binaryType() { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); return this.#binaryType; } set binaryType(type) { - webidl.brandCheck(this, _WebSocket); + webidl.brandCheck(this, webidl.is.WebSocket); if (type !== "blob" && type !== "arraybuffer") { this.#binaryType = "blob"; } else { @@ -45561,27 +46536,26 @@ var require_websocket2 = __commonJS({ }); } } - /** - * @param {WebSocket} ws - * @param {Buffer|undefined} buffer - */ - static ping(ws, buffer) { - if (Buffer.isBuffer(buffer)) { - if (buffer.length > 125) { - throw new TypeError("A PING frame cannot have a body larger than 125 bytes."); + static { + ping = (ws, buffer) => { + if (Buffer.isBuffer(buffer)) { + if (buffer.length > 125) { + throw new TypeError("A PING frame cannot have a body larger than 125 bytes."); + } + } else if (buffer !== void 0) { + throw new TypeError("Expected buffer payload"); } - } else if (buffer !== void 0) { - throw new TypeError("Expected buffer payload"); - } - const readyState = ws.#handler.readyState; - if (isEstablished(readyState) && !isClosing(readyState) && !isClosed(readyState)) { - const frame = new WebsocketFrameSend(buffer); - ws.#handler.socket.write(frame.createFrame(opcodes.PING)); - } + const readyState = ws.#handler.readyState; + if (isEstablished(readyState) && !isClosing(readyState) && !isClosed(readyState)) { + const frame = new WebsocketFrameSend(buffer); + ws.#handler.socket.write(frame.createFrame(opcodes.PING)); + } + }; + webidl.is.WebSocket = (arg) => { + return arg != null && typeof arg === "object" && #handler in arg; + }; } }; - var { ping } = WebSocket; - Reflect.deleteProperty(WebSocket, "ping"); WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING; WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN; WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING; @@ -45690,6 +46664,7 @@ var require_websocketerror = __commonJS({ } }); } + var createUnvalidatedWebSocketError; var WebSocketError = class _WebSocketError extends createInheritableDOMException() { #closeCode; #reason; @@ -45716,20 +46691,18 @@ var require_websocketerror = __commonJS({ get reason() { return this.#reason; } - /** - * @param {string} message - * @param {number|null} code - * @param {string} reason - */ - static createUnvalidatedWebSocketError(message, code, reason) { - const error2 = new _WebSocketError(message, kConstruct); - error2.#closeCode = code; - error2.#reason = reason; - return error2; + static { + createUnvalidatedWebSocketError = (message, code, reason) => { + const error2 = new _WebSocketError(message, kConstruct); + error2.#closeCode = code; + error2.#reason = reason; + return error2; + }; + webidl.is.WebSocketError = (arg) => { + return arg != null && typeof arg === "object" && #reason in arg; + }; } }; - var { createUnvalidatedWebSocketError } = WebSocketError; - delete WebSocketError.createUnvalidatedWebSocketError; Object.defineProperties(WebSocketError.prototype, { closeCode: kEnumerableProperty, reason: kEnumerableProperty, @@ -45740,7 +46713,6 @@ var require_websocketerror = __commonJS({ configurable: true } }); - webidl.is.WebSocketError = webidl.util.MakeTypeAssertion(WebSocketError); module2.exports = { WebSocketError, createUnvalidatedWebSocketError }; } }); @@ -45777,9 +46749,9 @@ var require_websocketstream = __commonJS({ #readableStream; /** @type {ReadableStreamDefaultController} */ #readableStreamController; - // Each WebSocketStream object has an associated writable stream , which is a WritableStream . - /** @type {WritableStream} */ - #writableStream; + // Retain the controller so the writable stream can be errored while locked. + /** @type {WritableStreamDefaultController} */ + #writableStreamController; // Each WebSocketStream object has an associated boolean handshake aborted , which is initially false. #handshakeAborted = false; /** @type {import('../websocket').Handler} */ @@ -45801,7 +46773,9 @@ var require_websocketstream = __commonJS({ } this.#handler.socket.destroy(); }, - onSocketClose: () => this.#onSocketClose(), + // When the WebSocket connection is closed for a WebSocketStream stream, possibly cleanly, the user agent must + // queue a global task on the WebSocket task source given stream ’s relevant global object to run the following substeps: + onSocketClose: () => queueMicrotask(() => this.#onSocketClose()), onPing: () => { }, onPong: () => { @@ -45909,6 +46883,8 @@ var require_websocketstream = __commonJS({ this.#handler.socket.write(frame.createFrame(opcode), () => { promise.resolve(void 0); }); + } else { + promise.resolve(void 0); } return promise.promise; } @@ -45925,21 +46901,24 @@ var require_websocketstream = __commonJS({ parser.on("error", (err) => this.#handler.onParserError(err)); this.#parser = parser; this.#handler.readyState = states.OPEN; - const extensions = parsedExtensions ?? ""; + const extensions = response.headersList.get("sec-websocket-extensions") ?? ""; const protocol = response.headersList.get("sec-websocket-protocol") ?? ""; const readable = new ReadableStream({ start: (controller) => { this.#readableStreamController = controller; }, + pull: () => this.#pull(), cancel: (reason) => this.#cancel(reason) }); const writable = new WritableStream({ + start: (controller) => { + this.#writableStreamController = controller; + }, write: (chunk) => this.#write(chunk), close: () => closeWebSocketConnection(this.#handler, null, null), abort: (reason) => this.#closeUsingReason(reason) }); this.#readableStream = readable; - this.#writableStream = writable; this.#openedPromise.resolve({ extensions, protocol, @@ -45964,6 +46943,9 @@ var require_websocketstream = __commonJS({ chunk = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); } this.#readableStreamController.enqueue(chunk); + if (this.#readableStreamController.desiredSize <= 0) { + this.#handler.socket.pause(); + } } /** @type {import('../websocket').Handler['onSocketClose']} */ #onSocketClose() { @@ -45977,15 +46959,13 @@ var require_websocketstream = __commonJS({ } const result = this.#parser?.closingInfo; let code = result?.code ?? 1005; - if (!this.#handler.closeState.has(sentCloseFrameState.SENT) && !this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) { + if (!this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) { code = 1006; } const reason = result?.reason == null ? "" : utf8DecodeBytes(Buffer.from(result.reason)); if (wasClean) { readableStreamClose(this.#readableStreamController); - if (!this.#writableStream.locked) { - this.#writableStream.abort(new DOMException("A closed WebSocketStream cannot be written to", "InvalidStateError")); - } + this.#writableStreamController.error(new DOMException("A closed WebSocketStream cannot be written to", "InvalidStateError")); this.#closedPromise.resolve({ closeCode: code, reason @@ -45993,7 +46973,7 @@ var require_websocketstream = __commonJS({ } else { const error2 = createUnvalidatedWebSocketError("unclean close", code, reason); this.#readableStreamController?.error(error2); - this.#writableStream?.abort(error2); + this.#writableStreamController?.error(error2); this.#closedPromise.reject(error2); } } @@ -46006,6 +46986,10 @@ var require_websocketstream = __commonJS({ } closeWebSocketConnection(this.#handler, code, reasonString); } + // To pull bytes from a WebSocketStream stream , if stream is currently applying backpressure, release backpressure. + #pull() { + this.#handler.socket.resume(); + } // To cancel a WebSocketStream stream given reason , close using reason giving stream and reason . #cancel(reason) { this.#closeUsingReason(reason); @@ -46100,6 +47084,7 @@ var require_util14 = __commonJS({ var require_eventsource_stream2 = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports2, module2) { "use strict"; + var buffer = require("node:buffer"); var { Transform } = require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util14(); var BOM = [239, 187, 191]; @@ -46107,24 +47092,25 @@ var require_eventsource_stream2 = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -46141,6 +47127,11 @@ var require_eventsource_stream2 = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -46167,6 +47158,8 @@ var require_eventsource_stream2 = __commonJS({ pos = 0; lineChunkIndex = 0; linePos = 0; + eventDataSize = 0; + maxEventSize; event = { data: void 0, event: void 0, @@ -46176,6 +47169,7 @@ var require_eventsource_stream2 = __commonJS({ /** * @param {object} options * @param {boolean} [options.readableObjectMode] + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} [options.eventSourceSettings] * @param {(chunk: any, encoding?: BufferEncoding | undefined) => boolean} [options.push] */ @@ -46183,6 +47177,7 @@ var require_eventsource_stream2 = __commonJS({ options.readableObjectMode = true; super(options); this.state = options.eventSourceSettings || {}; + this.maxEventSize = options.maxEventSize ?? defaultMaxEventSize; if (options.push) { this.push = options.push; } @@ -46234,7 +47229,12 @@ var require_eventsource_stream2 = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; @@ -46265,6 +47265,11 @@ var require_eventsource_stream2 = __commonJS({ } } if (isFieldName(line, fieldLength, DATA)) { + const valueBytes = line.length - valueStart; + const eventDataSize = this.eventDataSize + (event.data === void 0 ? 0 : 1) + valueBytes; + if (this.maxEventSize > 0 && eventDataSize > this.maxEventSize) { + throw createMaxEventSizeExceededError(); + } const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -46272,6 +47277,7 @@ var require_eventsource_stream2 = __commonJS({ event.data += ` ${value}`; } + this.eventDataSize = eventDataSize; return; } if (isFieldName(line, fieldLength, RETRY)) { @@ -46319,6 +47325,7 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventDataSize = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -46448,9 +47455,12 @@ var require_eventsource2 = __commonJS({ var { parseMIMEType } = require_data_url2(); var { createFastMessageEvent } = require_events2(); var { isNetworkError } = require_response2(); - var { kEnumerableProperty } = require_util9(); + var { isValidHeaderValue, kEnumerableProperty } = require_util9(); var { environmentSettingsObject } = require_util10(); var { createPotentialCORSRequest } = require_util14(); + var { getGlobalDispatcher } = require_global4(); + var { isomorphicDecode } = require_infra(); + var textEncoder2 = new TextEncoder(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -46458,7 +47468,7 @@ var require_eventsource2 = __commonJS({ var CLOSED = 2; var ANONYMOUS = "anonymous"; var USE_CREDENTIALS = "use-credentials"; - var EventSource = class _EventSource extends EventTarget { + var EventSource = class extends EventTarget { #events = { open: null, error: null, @@ -46530,6 +47540,7 @@ var require_eventsource2 = __commonJS({ * @readonly */ get readyState() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#readyState; } /** @@ -46538,6 +47549,7 @@ var require_eventsource2 = __commonJS({ * @returns {string} */ get url() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#url; } /** @@ -46545,6 +47557,7 @@ var require_eventsource2 = __commonJS({ * instantiated with CORS credentials set (true), or not (false, the default). */ get withCredentials() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#withCredentials; } #connect() { @@ -46584,6 +47597,7 @@ var require_eventsource2 = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -46614,8 +47628,12 @@ var require_eventsource2 = __commonJS({ this.dispatchEvent(new Event("error")); setTimeout(() => { if (this.#readyState !== CONNECTING) return; + this.#request.headersList.delete("last-event-id", true); if (this.#state.lastEventId.length) { - this.#request.headersList.set("last-event-id", this.#state.lastEventId, true); + const lastEventId = isomorphicDecode(textEncoder2.encode(this.#state.lastEventId)); + if (isValidHeaderValue(lastEventId)) { + this.#request.headersList.set("last-event-id", lastEventId, true); + } } this.#connect(); }, this.#state.reconnectionTime)?.unref(); @@ -46625,16 +47643,18 @@ var require_eventsource2 = __commonJS({ * CLOSED. */ close() { - webidl.brandCheck(this, _EventSource); + webidl.brandCheck(this, webidl.is.EventSource); if (this.#readyState === CLOSED) return; this.#readyState = CLOSED; this.#controller.abort(); this.#request = null; } get onopen() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#events.open; } set onopen(fn) { + webidl.brandCheck(this, webidl.is.EventSource); if (this.#events.open) { this.removeEventListener("open", this.#events.open); } @@ -46647,9 +47667,11 @@ var require_eventsource2 = __commonJS({ } } get onmessage() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#events.message; } set onmessage(fn) { + webidl.brandCheck(this, webidl.is.EventSource); if (this.#events.message) { this.removeEventListener("message", this.#events.message); } @@ -46662,9 +47684,11 @@ var require_eventsource2 = __commonJS({ } } get onerror() { + webidl.brandCheck(this, webidl.is.EventSource); return this.#events.error; } set onerror(fn) { + webidl.brandCheck(this, webidl.is.EventSource); if (this.#events.error) { this.removeEventListener("error", this.#events.error); } @@ -46676,6 +47700,11 @@ var require_eventsource2 = __commonJS({ this.#events.error = null; } } + static { + webidl.is.EventSource = (arg) => { + return arg != null && typeof arg === "object" && #events in arg; + }; + } }; var constantsPropertyDescriptors = { CONNECTING: { @@ -46720,7 +47749,8 @@ var require_eventsource2 = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() }, { key: "node", From ef9d9f84b7f9c409eff306aecfb4c92e6e7277f2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 05:01:34 +0000 Subject: [PATCH 4/4] fix: apply audit fixes --- package-lock.json | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index c96cf36..fac552f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -114,9 +114,9 @@ } }, "node_modules/@actions/glob/node_modules/brace-expansion": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", - "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -151,9 +151,9 @@ } }, "node_modules/@actions/http-client/node_modules/undici": { - "version": "6.28.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.0.tgz", - "integrity": "sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==", + "version": "6.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.0.tgz", + "integrity": "sha512-R+RODBqp6i2pPflGdq+xIOUkl+RNfGgHwoinecKu/JCuf2uO06cOKoDbI2P7Dn6KcswdKwrczbU6IYJ6K8X+wg==", "license": "MIT", "engines": { "node": ">=18.17" @@ -1585,9 +1585,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.1.tgz", - "integrity": "sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz", + "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==", "dev": true, "license": "MIT", "dependencies": { @@ -2867,9 +2867,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", - "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -3768,9 +3768,9 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", - "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz", + "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==", "dev": true, "license": "MIT", "dependencies": { @@ -5890,9 +5890,9 @@ } }, "node_modules/undici": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-8.10.0.tgz", - "integrity": "sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.11.2.tgz", + "integrity": "sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==", "license": "MIT", "engines": { "node": ">=22.19.0"