From 8473c7fea42cdfd540f4b01317a17ac5f54126ae Mon Sep 17 00:00:00 2001 From: Kevin Stillhammer Date: Tue, 11 Aug 2026 11:27:16 +0200 Subject: [PATCH] chore(deps): roll up Dependabot updates (#994) ## Summary Roll up the remaining net changes from the open Dependabot updates: - release-drafter/release-drafter 7.7.0 (#990) - github/codeql-action 4.37.4 (#987, #988, #989) - zizmorcore/zizmor-action 0.6.1 (#986) - @actions/cache 6.2.0 (#975) - @biomejs/biome 2.5.4 (#974) - undici 8.7.0 (#973) The Jest 30.4.2 (#905) and @renovatebot/pep440 5.0.0 (#907) updates are already present on main and require no additional changes. This also updates the Biome schema, applies the formatter changes from Biome 2.5.4, and regenerates the published bundles. ## Testing - `npm run all` - `actionlint` - `git diff --check` Refs: pi-session 019ff01b-f917-73c1-950e-2966956f263c --- .github/workflows/codeql-analysis.yml | 6 +- .github/workflows/release-drafter.yml | 2 +- .github/workflows/test.yml | 2 +- __tests__/download/checksum/checksum.test.ts | 12 +- __tests__/utils/inputs.test.ts | 31 +- __tests__/version/requirements-file.test.ts | 11 +- biome.json | 2 +- dist/save-cache/index.cjs | 21 +- dist/setup/index.cjs | 997 ++++++++++++++----- dist/update-known-checksums/index.cjs | 936 +++++++++++++---- package-lock.json | 170 ++-- package.json | 6 +- 12 files changed, 1623 insertions(+), 573 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 00008df..0f94267 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -47,7 +47,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 + uses: github/codeql-action/init@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 with: languages: ${{ matrix.language }} source-root: src @@ -59,7 +59,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 + uses: github/codeql-action/autobuild@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -73,4 +73,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 + uses: github/codeql-action/analyze@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index a1a21c2..862b5e6 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -19,7 +19,7 @@ jobs: pull-requests: read steps: - name: 🚀 Run Release Drafter - uses: release-drafter/release-drafter@4d75298e00d9e34c483e5ff8c68d0ea1c1940c1e # v7.5.1 + uses: release-drafter/release-drafter@34d80673e067bdc0c24568d3af899c216adcfaa9 # v7.7.0 with: commitish: ${{ github.sha }} env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4afab0b..9286ea2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,7 +27,7 @@ jobs: - name: Actionlint uses: eifinger/actionlint-action@1fc89649be682d16ec5cf65ea16e269eb88d3982 # v1.10.2 - name: Run zizmor - uses: zizmorcore/zizmor-action@6599ee8b7a49aef6a770f63d261d214911a7ce02 # v0.6.0 + uses: zizmorcore/zizmor-action@6fc4b006235f201fdab3722e17240ab420d580e5 # v0.6.1 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version-file: .nvmrc diff --git a/__tests__/download/checksum/checksum.test.ts b/__tests__/download/checksum/checksum.test.ts index 7d8e086..8b56d0f 100644 --- a/__tests__/download/checksum/checksum.test.ts +++ b/__tests__/download/checksum/checksum.test.ts @@ -40,9 +40,9 @@ it.each([ known: false, version: "0.0.15", }, -])("isknownVersion should return $known for version $version", ({ - version, - known, -}) => { - expect(isknownVersion(version)).toBe(known); -}); +])( + "isknownVersion should return $known for version $version", + ({ version, known }) => { + expect(isknownVersion(version)).toBe(known); + }, +); diff --git a/__tests__/utils/inputs.test.ts b/__tests__/utils/inputs.test.ts index 47706e8..8d45e88 100644 --- a/__tests__/utils/inputs.test.ts +++ b/__tests__/utils/inputs.test.ts @@ -100,24 +100,23 @@ describe("loadInputs", () => { expect(inputs.resolutionStrategy).toBe("highest"); }); - it.each([ - "pull_request_target", - "workflow_run", - "release", - ])("disables automatic caching for the %s event", (eventName) => { - mockInputs["working-directory"] = "/workspace"; - mockInputs["enable-cache"] = "auto"; - process.env.RUNNER_ENVIRONMENT = "github-hosted"; - process.env.RUNNER_TEMP = "/runner-temp"; - process.env.GITHUB_EVENT_NAME = eventName; + it.each(["pull_request_target", "workflow_run", "release"])( + "disables automatic caching for the %s event", + (eventName) => { + mockInputs["working-directory"] = "/workspace"; + mockInputs["enable-cache"] = "auto"; + process.env.RUNNER_ENVIRONMENT = "github-hosted"; + process.env.RUNNER_TEMP = "/runner-temp"; + process.env.GITHUB_EVENT_NAME = eventName; - const inputs = loadInputs(); + const inputs = loadInputs(); - expect(inputs.enableCache).toBe(false); - expect(mockInfo).toHaveBeenCalledWith( - `Caching is disabled for the ${eventName} event`, - ); - }); + expect(inputs.enableCache).toBe(false); + expect(mockInfo).toHaveBeenCalledWith( + `Caching is disabled for the ${eventName} event`, + ); + }, + ); it("disables automatic caching for tag pushes", () => { mockInputs["working-directory"] = "/workspace"; diff --git a/__tests__/version/requirements-file.test.ts b/__tests__/version/requirements-file.test.ts index d356511..5ff0277 100644 --- a/__tests__/version/requirements-file.test.ts +++ b/__tests__/version/requirements-file.test.ts @@ -15,15 +15,18 @@ test("ignores dependencies starting with uv", async () => { test.each([ ["without space before marker", "uv==0.11.20; sys_platform != 'emscripten'"], ["with space before marker", "uv==0.11.20 ; sys_platform != 'emscripten'"], -])("strips PEP 508 markers from pyproject dependency groups %s", (_, dependency) => { - const parsedVersion = getUvVersionFromPyprojectContent(`[dependency-groups] +])( + "strips PEP 508 markers from pyproject dependency groups %s", + (_, dependency) => { + const parsedVersion = getUvVersionFromPyprojectContent(`[dependency-groups] test = [ "${dependency}", ] `); - expect(parsedVersion).toBe("==0.11.20"); -}); + expect(parsedVersion).toBe("==0.11.20"); + }, +); test("strips PEP 508 markers from requirements dependencies", () => { const parsedVersion = getUvVersionFromRequirementsText( diff --git a/biome.json b/biome.json index 60481cb..f5dd9b6 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.5.1/schema.json", + "$schema": "https://biomejs.dev/schemas/2.5.4/schema.json", "assist": { "actions": { "source": { diff --git a/dist/save-cache/index.cjs b/dist/save-cache/index.cjs index 9ad6c06..1517e5f 100644 --- a/dist/save-cache/index.cjs +++ b/dist/save-cache/index.cjs @@ -22691,7 +22691,7 @@ var require_package = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "6.1.0", + version: "6.2.0", description: "Actions cache lib", keywords: [ "github", @@ -60156,6 +60156,15 @@ function getCacheServiceVersion() { return "v1"; return process.env["ACTIONS_CACHE_SERVICE_V2"] ? "v2" : "v1"; } +var KNOWN_CACHE_MODES = ["none", "read", "write", "write-only"]; +function getCacheMode() { + return (process.env["ACTIONS_CACHE_MODE"] || "").trim().toLowerCase(); +} +function isCacheWritable(mode) { + if (!KNOWN_CACHE_MODES.includes(mode)) + return true; + return mode === "write" || mode === "write-only"; +} function getCacheServiceURL() { const version3 = getCacheServiceVersion(); switch (version3) { @@ -61445,6 +61454,12 @@ function saveCache2(paths_1, key_1, options_1) { debug(`Cache service version: ${cacheServiceVersion}`); checkPaths(paths); checkKey(key); + const cacheMode = getCacheMode(); + if (!isCacheWritable(cacheMode)) { + info(`Cache save skipped: the effective cache-mode '${cacheMode}' does not permit writes.`); + debug(`Skipped save for paths [${paths.join(", ")}] with key '${key}'.`); + return -1; + } switch (cacheServiceVersion) { case "v2": return yield saveCacheV2(paths, key, options, enableCrossOsArchive); @@ -61502,8 +61517,6 @@ function saveCacheV1(paths_1, key_1, options_1) { const typedError = error2; if (typedError.name === ValidationError.name) { throw error2; - } else if (typedError.name === CacheWriteDeniedError.name) { - warning(`Failed to save: ${typedError.message}`); } else if (typedError.name === ReserveCacheError.name) { info(`Failed to save: ${typedError.message}`); } else { @@ -61591,8 +61604,6 @@ function saveCacheV2(paths_1, key_1, options_1) { const typedError = error2; if (typedError.name === ValidationError.name) { throw error2; - } else if (typedError.name === CacheWriteDeniedError.name) { - warning(`Failed to save: ${typedError.message}`); } else if (typedError.name === ReserveCacheError.name) { info(`Failed to save: ${typedError.message}`); } else if (typedError.name === FinalizeCacheError.name) { diff --git a/dist/setup/index.cjs b/dist/setup/index.cjs index f1201e6..487f4f7 100644 --- a/dist/setup/index.cjs +++ b/dist/setup/index.cjs @@ -22690,7 +22690,7 @@ var require_package = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "6.1.0", + version: "6.2.0", description: "Actions cache lib", keywords: [ "github", @@ -29572,6 +29572,22 @@ var require_errors2 = __commonJS({ return true; } }; + var kProxyConnectionError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_PRX_CONN"); + var ProxyConnectionError = class extends UndiciError { + constructor(cause, message, options = {}) { + super(message, { cause, ...options }); + this.name = "ProxyConnectionError"; + this.message = message || "Proxy Connection failed"; + this.code = "UND_ERR_PRX_CONN"; + this.cause = cause; + } + static [Symbol.hasInstance](instance) { + return instance && instance[kProxyConnectionError] === true; + } + get [kProxyConnectionError]() { + return true; + } + }; var kMaxOriginsReachedError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_MAX_ORIGINS_REACHED"); var MaxOriginsReachedError = class extends UndiciError { constructor(message) { @@ -29633,6 +29649,7 @@ var require_errors2 = __commonJS({ RequestRetryError, ResponseError, SecureProxyConnectionError, + ProxyConnectionError, MaxOriginsReachedError, Socks5ProxyError, MessageSizeExceededError @@ -30278,9 +30295,8 @@ var require_util9 = __commonJS({ 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"; } function addAbortListener(signal, listener) { - if (signal instanceof AbortSignal) { - const disposable = addAbortListenerNative(signal, listener); - return () => disposable[Symbol.dispose](); + if (!signal || "aborted" in signal) { + return addAbortListenerNative(signal, listener)[Symbol.dispose]; } if (typeof signal.addEventListener === "function") { signal.addEventListener("abort", listener, { once: true }); @@ -30584,7 +30600,8 @@ var require_util9 = __commonJS({ var rangeHeaderRegex = /^bytes (\d+)-(\d+)\/(\d+|\*)?$/; function parseRangeHeader(range2) { if (range2 == null || range2 === "") return { start: 0, end: null, size: null }; - const m = range2 ? range2.match(rangeHeaderRegex) : null; + if (!range2) return null; + const m = rangeHeaderRegex.exec(range2); return m ? { start: parseInt(m[1]), end: m[2] ? parseInt(m[2]) : null, @@ -30658,7 +30675,18 @@ var require_util9 = __commonJS({ message += ` timeout: ${opts.timeout}ms)`; destroy2(socket, new ConnectTimeoutError(message)); } + var lastUrlString = null; + var lastProtocol = null; function getProtocolFromUrlString(urlString) { + if (urlString === lastUrlString) { + return lastProtocol; + } + const protocol = getProtocolFromUrlStringSlow(urlString); + lastUrlString = urlString; + lastProtocol = protocol; + return protocol; + } + function getProtocolFromUrlStringSlow(urlString) { if (urlString[0] === "h" && urlString[1] === "t" && urlString[2] === "t" && urlString[3] === "p") { switch (urlString[4]) { case ":": @@ -30671,8 +30699,10 @@ var require_util9 = __commonJS({ } return urlString.slice(0, urlString.indexOf(":") + 1); } - var kEnumerableProperty = /* @__PURE__ */ Object.create(null); - kEnumerableProperty.enumerable = true; + var kEnumerableProperty = { + __proto__: null, + enumerable: true + }; var normalizedMethodRecordsBase = { delete: "DELETE", DELETE: "DELETE", @@ -30685,7 +30715,9 @@ var require_util9 = __commonJS({ post: "POST", POST: "POST", put: "PUT", - PUT: "PUT" + PUT: "PUT", + query: "QUERY", + QUERY: "QUERY" }; var normalizedMethodRecords = { ...normalizedMethodRecordsBase, @@ -31176,7 +31208,7 @@ var require_request3 = __commonJS({ this.path = query ? serializePathWithQuery(path17, query) : path17; this.origin = origin; this.protocol = getProtocolFromUrlString(origin); - this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent; + this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" || method === "QUERY" : idempotent; this.blocking = blocking ?? this.method !== "HEAD"; this.reset = reset == null ? null : reset; this.host = null; @@ -31502,6 +31534,7 @@ var require_dispatcher_base2 = __commonJS({ */ get webSocketOptions() { return { + maxFragments: this[kWebSocketOptions].maxFragments ?? 131072, maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 // 128 MB default }; @@ -31626,7 +31659,7 @@ var require_connect2 = __commonJS({ var net = require("node:net"); var assert4 = require("node:assert"); var util7 = require_util9(); - var { InvalidArgumentError } = require_errors2(); + var { InvalidArgumentError, ConnectTimeoutError } = require_errors2(); var tls; var SessionCache = class WeakSessionCache { constructor(maxCachedSessions) { @@ -31668,7 +31701,7 @@ var require_connect2 = __commonJS({ this._sessionRegistry.register(session, sessionKey); } }; - function buildConnector({ allowH2, useH2c, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) { + function buildConnector({ allowH2, preferH2, useH2c, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) { if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { throw new InvalidArgumentError("maxCachedSessions must be a positive integer or zero"); } @@ -31694,7 +31727,7 @@ var require_connect2 = __commonJS({ servername, session, localAddress, - ALPNProtocols: allowH2 ? ["http/1.1", "h2"] : ["http/1.1"], + ALPNProtocols: allowH2 ? preferH2 ? ["h2", "http/1.1"] : ["http/1.1", "h2"] : ["http/1.1"], socket: httpSocket, // upgrade socket connection port, @@ -31735,12 +31768,27 @@ var require_connect2 = __commonJS({ if (callback) { const cb = callback; callback = null; - cb(err); + cb(maybeNormalizeConnectError(err, this, { timeout, hostname, port })); } }); return socket; }; } + function maybeNormalizeConnectError(err, socket, opts) { + if (err instanceof AggregateError && (err.code === "ETIMEDOUT" || err.errors.some((e) => e != null && e.code === "ETIMEDOUT"))) { + let message = "Connect Timeout Error"; + if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) { + message += ` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(", ")},`; + } else { + message += ` (attempted address: ${opts.hostname}:${opts.port},`; + } + message += ` timeout: ${opts.timeout}ms)`; + const wrapped = new ConnectTimeoutError(message); + wrapped.cause = err; + return wrapped; + } + return err; + } module2.exports = buildConnector; } }); @@ -32547,7 +32595,7 @@ var require_constants10 = __commonJS({ ); var safeMethods = ( /** @type {const} */ - ["GET", "HEAD", "OPTIONS", "TRACE"] + ["GET", "HEAD", "OPTIONS", "TRACE", "QUERY"] ); var safeMethodsSet = new Set(safeMethods); var requestMode = ( @@ -34269,7 +34317,7 @@ var require_util10 = __commonJS({ if (rangeEndValue === null && rangeStartValue === null) { return "failure"; } - if (rangeStartValue > rangeEndValue) { + if (rangeStartValue !== null && rangeEndValue !== null && rangeStartValue > rangeEndValue) { return "failure"; } return { rangeStartValue, rangeEndValue }; @@ -35259,6 +35307,29 @@ Content-Type: ${value.type || "application/octet-stream"}\r return consumeBody(this, (bytes) => { return new Uint8Array(bytes); }, instance, getInternalState); + }, + textStream() { + const this_ = getInternalState(this); + if (bodyUnusable(this_)) { + throw new TypeError("Body is unusable: Body has already been read"); + } + if (this_.body == null) { + let controller; + const emptyStream = new ReadableStream({ + start: (c) => { + controller = c; + }, + pull: () => Promise.resolve(), + cancel: () => Promise.resolve() + }, { + size: () => 1 + }); + controller.close(); + return emptyStream; + } + const stream4 = this_.body.stream; + const decoder = new TextDecoderStream("UTF-8"); + return stream4.pipeThrough(decoder); } }; return methods; @@ -35373,6 +35444,9 @@ var require_client_h12 = __commonJS({ var EMPTY_BUF = Buffer.alloc(0); var FastBuffer = Buffer[Symbol.species]; var removeAllListeners = util7.removeAllListeners; + var kIdleSocketValidation = /* @__PURE__ */ Symbol("kIdleSocketValidation"); + var kIdleSocketValidationTimeout = /* @__PURE__ */ Symbol("kIdleSocketValidationTimeout"); + var kSocketUsed = /* @__PURE__ */ Symbol("kSocketUsed"); var extractBody; function lazyllhttp() { const llhttpWasmData = process.env.JEST_WORKER_ID ? require_llhttp_wasm2() : void 0; @@ -35613,8 +35687,20 @@ var require_client_h12 = __commonJS({ finish() { assert4(currentParser === null); assert4(this.ptr != null); - assert4(!this.paused); const { llhttp } = this; + if (this.paused) { + let data; + do { + llhttp.llhttp_resume(this.ptr); + this.paused = false; + data = this.socket.read() || EMPTY_BUF; + this.execute(data); + } while (this.paused && data.length > 0); + if (this.paused) { + llhttp.llhttp_resume(this.ptr); + this.paused = false; + } + } let ret; try { currentParser = this; @@ -35671,6 +35757,10 @@ var require_client_h12 = __commonJS({ if (socket.destroyed) { return -1; } + if (client[kRunning] === 0) { + util7.destroy(socket, new SocketError("bad response", util7.getSocketInfo(socket))); + return -1; + } const request = client[kQueue][client[kRunningIdx]]; if (!request) { return -1; @@ -35778,6 +35868,10 @@ var require_client_h12 = __commonJS({ if (socket.destroyed) { return -1; } + if (client[kRunning] === 0) { + util7.destroy(socket, new SocketError("bad response", util7.getSocketInfo(socket))); + return -1; + } const request = client[kQueue][client[kRunningIdx]]; if (!request) { return -1; @@ -35911,6 +36005,7 @@ var require_client_h12 = __commonJS({ } request.onResponseEnd(headers); client[kQueue][client[kRunningIdx]++] = null; + socket[kSocketUsed] = client[kPending] === 0; if (socket[kWriting]) { assert4(client[kRunning] === 0); util7.destroy(socket, new InformationalError("reset")); @@ -35964,6 +36059,9 @@ var require_client_h12 = __commonJS({ socket[kWriting] = false; socket[kReset] = false; socket[kBlocking] = false; + socket[kIdleSocketValidation] = 0; + socket[kIdleSocketValidationTimeout] = null; + socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); util7.addListener(socket, "error", onHttpSocketError); util7.addListener(socket, "readable", onHttpSocketReadable); @@ -36003,7 +36101,7 @@ var require_client_h12 = __commonJS({ * @returns {boolean} */ busy(request) { - if (socket[kWriting] || socket[kReset] || socket[kBlocking]) { + if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) { return true; } if (request) { @@ -36051,6 +36149,7 @@ var require_client_h12 = __commonJS({ } function onHttpSocketClose() { const parser = this[kParser]; + clearIdleSocketValidation(this); if (parser) { if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { this[kError] = parser.finish() || this[kError]; @@ -36082,6 +36181,24 @@ var require_client_h12 = __commonJS({ function onSocketClose() { this[kClosed] = true; } + function clearIdleSocketValidation(socket) { + if (socket[kIdleSocketValidationTimeout]) { + clearTimeout(socket[kIdleSocketValidationTimeout]); + socket[kIdleSocketValidationTimeout] = null; + } + socket[kIdleSocketValidation] = 0; + } + function scheduleIdleSocketValidation(client, socket) { + socket[kIdleSocketValidation] = 1; + socket[kIdleSocketValidationTimeout] = setTimeout(() => { + 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]; if (socket && !socket.destroyed) { @@ -36094,6 +36211,29 @@ var require_client_h12 = __commonJS({ socket.ref(); socket[kNoRef] = false; } + if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) { + if (socket[kIdleSocketValidation] === 0) { + scheduleIdleSocketValidation(client, socket); + socket[kParser].readMore(); + if (socket.destroyed) { + return; + } + return; + } + if (socket[kIdleSocketValidation] === 1) { + socket[kParser].readMore(); + if (socket.destroyed) { + return; + } + return; + } + } + if (client[kRunning] === 0) { + socket[kParser].readMore(); + if (socket.destroyed) { + return; + } + } if (client[kSize] === 0) { if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) { socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE); @@ -36146,6 +36286,7 @@ var require_client_h12 = __commonJS({ process.emitWarning(new RequestContentLengthMismatchError()); } const socket = client[kSocket]; + clearIdleSocketValidation(socket); const abort = (err) => { if (request.aborted || request.completed) { return; @@ -36537,7 +36678,9 @@ var require_client_h22 = __commonJS({ RequestAbortedError, SocketError, InformationalError, - InvalidArgumentError + InvalidArgumentError, + HeadersTimeoutError, + BodyTimeoutError } = require_errors2(); var { kUrl, @@ -36562,6 +36705,8 @@ var require_client_h22 = __commonJS({ kSize, kHTTPContext, kClosed, + kKeepAliveDefaultTimeout, + kHeadersTimeout, kBodyTimeout, kEnableConnectProtocol, kRemoteSettings, @@ -36599,6 +36744,25 @@ var require_client_h22 = __commonJS({ function getGoAwayError(session, errorCode) { return session[kError] || (errorCode === NGHTTP2_NO_ERROR ? new InformationalError(`HTTP/2: "GOAWAY" frame received with code ${errorCode}`) : new SocketError(`HTTP/2: "GOAWAY" frame received with code ${errorCode}`, util7.getSocketInfo(session[kSocket]))); } + function resetHttp2Session(session, err) { + const client = session[kClient]; + const socket = session[kSocket]; + if (client[kHTTP2Session] === session) { + client[kSocket] = null; + client[kHTTPContext] = null; + client[kHTTP2Session] = null; + } + if (socket != null && socket[kError] == null) { + socket[kError] = err; + } + if (!session.closed && !session.destroyed) { + try { + session.destroy(err); + } catch { + } + } + util7.destroy(socket, err); + } function getGoAwayPendingIdx(client, lastStreamID) { const maxAcceptedStreamID = Number.isInteger(lastStreamID) ? lastStreamID : Number.MAX_SAFE_INTEGER; for (let i = client[kRunningIdx]; i < client[kPendingIdx]; i++) { @@ -36632,13 +36796,31 @@ var require_client_h22 = __commonJS({ detachRequestFromStream(request); cleanup?.(stream4); } + function requeueUnsentRequest(client, request) { + client[kQueue].splice(client[kPendingIdx] + 1, 0, request); + } + function completeRequest(client, request, resetPendingIdx = false) { + const queue = client[kQueue]; + const runningIdx = client[kRunningIdx]; + if (runningIdx < client[kPendingIdx] && queue[runningIdx] === request) { + client[kRunningIdx] = runningIdx + 1; + return; + } + const index = queue.indexOf(request, runningIdx); + if (index === -1 || index >= client[kPendingIdx]) { + return; + } + queue.splice(index, 1); + client[kPendingIdx]--; + if (resetPendingIdx && client[kPendingIdx] < client[kRunningIdx]) { + client[kPendingIdx] = client[kRunningIdx]; + } + } function canRetryRequestAfterGoAway(request) { const { body: body2 } = request; return body2 == null || util7.isBuffer(body2) || util7.isBlobLike(body2); } - function closeRequestStream(request, code = NGHTTP2_REFUSED_STREAM) { - const stream4 = request[kRequestStream]; - clearRequestStream(request); + function closeStream(stream4, code = NGHTTP2_REFUSED_STREAM) { if (stream4 != null && !stream4.destroyed && !stream4.closed) { try { stream4.close(code); @@ -36646,6 +36828,11 @@ var require_client_h22 = __commonJS({ } } } + function detachRequestStreamForClose(request) { + const stream4 = request[kRequestStream]; + clearRequestStream(request); + return stream4; + } function connectH2(client, socket) { client[kSocket] = socket; const http2InitialWindowSize = client[kHTTP2InitialWindowSize]; @@ -36664,6 +36851,12 @@ var require_client_h22 = __commonJS({ session[kClient] = client; session[kSocket] = socket; session[kHTTP2SessionState] = { + idleTimeout: null, + // Sockets start out ref'd. Session ref/unref proxies to the socket, so a + // single cached flag lets us skip redundant uv ref/unref calls, provided + // every ref/unref of the session or its socket goes through + // refH2Session/unrefH2Session. + refed: true, ping: { interval: client[kPingInterval] === 0 ? null : setInterval(onHttp2SendPing, client[kPingInterval], session).unref() } @@ -36680,7 +36873,7 @@ var require_client_h22 = __commonJS({ util7.addListener(session, "goaway", onHttp2SessionGoAway); util7.addListener(session, "close", onHttp2SessionClose); util7.addListener(session, "remoteSettings", onHttp2RemoteSettings); - session.unref(); + unrefH2Session(session); client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util7.addListener(socket, "error", onHttp2SocketError); @@ -36734,7 +36927,6 @@ var require_client_h22 = __commonJS({ } if (request != null) { if (client[kRunning] > 0) { - if (request.idempotent === false) return true; if ((request.upgrade === "websocket" || request.method === "CONNECT") && session[kRemoteSettings] === false) return true; if (util7.bodyLength(request.body) !== 0 && (util7.isStream(request.body) || util7.isAsyncIterable(request.body) || util7.isFormDataLike(request.body))) return true; } else { @@ -36745,18 +36937,69 @@ var require_client_h22 = __commonJS({ } }; } + function refH2Session(session) { + const state3 = session[kHTTP2SessionState]; + if (state3.refed === false) { + state3.refed = true; + session.ref(); + } + } + function unrefH2Session(session) { + const state3 = session[kHTTP2SessionState]; + if (state3.refed === true) { + state3.refed = false; + session.unref(); + } + } function resumeH2(client) { const socket = client[kSocket]; + const session = client[kHTTP2Session]; if (socket?.destroyed === false) { if (client[kSize] === 0 || client[kMaxConcurrentStreams] === 0) { - socket.unref(); - client[kHTTP2Session].unref(); + unrefH2Session(session); } else { - socket.ref(); - client[kHTTP2Session].ref(); + refH2Session(session); + } + if (client[kSize] === 0 && session[kOpenStreams] === 0) { + setHttp2IdleTimeout(session); + } else { + clearHttp2IdleTimeout(session); } } } + function clearHttp2IdleTimeout(session) { + const state3 = session[kHTTP2SessionState]; + if (state3?.idleTimeout != null) { + clearTimeout(state3.idleTimeout); + state3.idleTimeout = null; + } + } + function setHttp2IdleTimeout(session) { + const client = session[kClient]; + if (client[kHTTP2Session] !== session || session.closed || session.destroyed) { + return; + } + if (session[kOpenStreams] !== 0 || client[kSize] !== 0) { + clearHttp2IdleTimeout(session); + return; + } + const state3 = session[kHTTP2SessionState]; + if (state3.idleTimeout == null) { + state3.idleTimeout = setTimeout(onHttp2SessionIdleTimeout, client[kKeepAliveDefaultTimeout], session).unref(); + } + } + function onHttp2SessionIdleTimeout(session) { + const client = session[kClient]; + const socket = session[kSocket]; + const state3 = session[kHTTP2SessionState]; + state3.idleTimeout = null; + if (client[kHTTP2Session] !== session || session[kOpenStreams] !== 0 || client[kSize] !== 0 || session.closed || session.destroyed) { + return; + } + const err = new InformationalError("socket idle timeout"); + socket[kError] = err; + util7.destroy(socket, err); + } function applyConnectionWindowSize(connectionWindowSize) { try { if (typeof this.setLocalWindowSize === "function") { @@ -36800,10 +37043,16 @@ var require_client_h22 = __commonJS({ function onHttp2SessionError(err) { assert4(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; + if (this[kReceivedGoAway]) { + return; + } this[kClient][kOnError](err); } function onHttp2FrameError(type, code, id) { if (id === 0) { + if (this[kReceivedGoAway]) { + return; + } const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`); this[kSocket][kError] = err; this[kClient][kOnError](err); @@ -36824,10 +37073,11 @@ var require_client_h22 = __commonJS({ const previousPendingIdx = client[kPendingIdx]; const pendingIdx = getGoAwayPendingIdx(client, lastStreamID); const retriableRequests = []; + const streamsToClose = []; for (let i = pendingIdx; i < previousPendingIdx; i++) { const request = client[kQueue][i]; if (request != null) { - closeRequestStream(request); + streamsToClose.push(detachRequestStreamForClose(request)); if (canRetryRequestAfterGoAway(request)) { retriableRequests.push(request); } else { @@ -36835,6 +37085,9 @@ var require_client_h22 = __commonJS({ } } } + for (let i = 0; i < streamsToClose.length; i++) { + closeStream(streamsToClose[i]); + } if (pendingIdx !== previousPendingIdx) { const remainingPendingRequests = client[kQueue].slice(previousPendingIdx); client[kQueue].length = pendingIdx; @@ -36845,6 +37098,7 @@ var require_client_h22 = __commonJS({ client[kHTTPContext] = null; client[kHTTP2Session] = null; } + clearHttp2IdleTimeout(this); if (!this.closed && !this.destroyed) { this.close(); } @@ -36860,6 +37114,7 @@ var require_client_h22 = __commonJS({ client[kHTTPContext] = null; client[kHTTP2Session] = null; } + clearHttp2IdleTimeout(this); if (state3.ping.interval != null) { clearInterval(state3.ping.interval); state3.ping.interval = null; @@ -36869,7 +37124,9 @@ var require_client_h22 = __commonJS({ const requests = client[kQueue].splice(client[kRunningIdx]); for (let i = 0; i < requests.length; i++) { const request = requests[i]; - util7.errorRequest(client, request, err); + if (request != null) { + util7.errorRequest(client, request, err); + } } } } @@ -36896,6 +37153,9 @@ var require_client_h22 = __commonJS({ function onHttp2SocketError(err) { assert4(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; + if (this[kHTTP2Session]?.[kReceivedGoAway]) { + return; + } this[kClient][kOnError](err); } function onHttp2SocketEnd() { @@ -36911,7 +37171,8 @@ var require_client_h22 = __commonJS({ stream4[kHTTP2Session] = null; session[kOpenStreams] -= 1; if (session[kOpenStreams] === 0) { - session.unref(); + unrefH2Session(session); + setHttp2IdleTimeout(session); } } function onUpgradeStreamClose() { @@ -36922,8 +37183,14 @@ var require_client_h22 = __commonJS({ closeStreamSession(this); } function onRequestStreamClose() { - this.off("data", onData); - this.off("error", noop); + const state3 = this[kRequestStreamState]; + if (state3) { + releaseRequestStream(this); + if (state3.pendingEnd && !state3.request.aborted && !state3.request.completed) { + state3.request.onResponseEnd(state3.trailers || {}); + finalizeRequest(state3); + } + } closeStreamSession(this); this[kRequestStreamState] = null; } @@ -37002,7 +37269,7 @@ var require_client_h22 = __commonJS({ } function onUpgradeStreamTimeout() { const state3 = this[kRequestStreamState]; - failUpgradeStream(state3, new InformationalError(`HTTP/2: "stream timeout after ${state3.requestTimeout}"`)); + failUpgradeStream(state3, new InformationalError(`HTTP/2: "stream timeout after ${state3.headersTimeout}"`)); } function onUpgradeResponse(headers, _flags) { const stream4 = this; @@ -37017,10 +37284,10 @@ var require_client_h22 = __commonJS({ } removeUpgradeStreamListeners(stream4); detachRequestFromStream(request); - state3.finalizeRequest(); + finalizeRequest(state3); } function setupUpgradeStream(stream4, state3) { - const { request, requestTimeout, session } = state3; + const { request, headersTimeout, session } = state3; stream4[kHTTP2Stream] = true; stream4[kHTTP2Session] = session; stream4[kRequestStreamState] = state3; @@ -37031,33 +37298,67 @@ var require_client_h22 = __commonJS({ stream4.once("end", onUpgradeStreamEnd); stream4.on("timeout", onUpgradeStreamTimeout); stream4.once("close", onUpgradeStreamClose); + clearHttp2IdleTimeout(session); ++session[kOpenStreams]; - stream4.setTimeout(requestTimeout); + stream4.setTimeout(headersTimeout); + } + function finalizeRequest(state3, resetPendingIdx = false) { + if (state3.requestFinalized) { + return; + } + state3.requestFinalized = true; + completeRequest(state3.client, state3.request, resetPendingIdx); + state3.client[kResume](); + } + function openStream(client, request, session, abort, headers, options) { + try { + return session.request(headers, options); + } catch (err) { + if (err?.code === "ERR_HTTP2_INVALID_SESSION" || err?.code === "ERR_HTTP2_GOAWAY_SESSION") { + const wrappedErr2 = new SocketError(err.message, util7.getSocketInfo(session[kSocket])); + wrappedErr2.cause = err; + session[kError] = wrappedErr2; + resetHttp2Session(session, wrappedErr2); + requeueUnsentRequest(client, request); + return null; + } + const wrappedErr = new InformationalError(err.message, { cause: err }); + session[kError] = wrappedErr; + session[kSocket][kError] = wrappedErr; + session.destroy(wrappedErr); + util7.destroy(session[kSocket], wrappedErr); + abort(wrappedErr); + return null; + } } function writeH2(client, request) { - const requestTimeout = request.bodyTimeout ?? client[kBodyTimeout]; + const headersTimeout = request.headersTimeout ?? client[kHeadersTimeout]; + const bodyTimeout = request.bodyTimeout ?? client[kBodyTimeout]; const session = client[kHTTP2Session]; const { method, path: path17, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request; - let { body: body2 } = request; if (upgrade != null && upgrade !== "websocket") { util7.errorRequest(client, request, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`)); return false; } const headers = buildRequestHeaders(reqHeaders); - let stream4 = null; headers[HTTP2_HEADER_AUTHORITY] = host || client[kHostAuthority]; headers[HTTP2_HEADER_METHOD] = method; - let requestFinalized = false; - const finalizeRequest = (resetPendingIdx = false) => { - if (requestFinalized) { - return; - } - requestFinalized = true; - client[kQueue][client[kRunningIdx]++] = null; - if (resetPendingIdx) { - client[kPendingIdx] = client[kRunningIdx]; - } - client[kResume](); + const state3 = { + abort: null, + body: request.body, + client, + contentLength: null, + expectsPayload: false, + request, + headersTimeout, + bodyTimeout, + requestFinalized: false, + responseReceived: false, + bodySent: false, + pendingEnd: false, + trailers: null, + session, + stream: null }; const abort = (err, resetPendingIdx = false) => { if (request.aborted || request.completed) { @@ -37065,30 +37366,22 @@ var require_client_h22 = __commonJS({ } err = err || new RequestAbortedError(); util7.errorRequest(client, request, err); - if (stream4 != null) { + if (state3.stream != null) { clearRequestStream(request); - stream4.close(); + const stream5 = state3.stream; + stream5.close(); + setImmediate(() => { + if (!stream5.destroyed) { + util7.destroy(stream5); + } + }); client[kOnError](err); - finalizeRequest(resetPendingIdx); - } - util7.destroy(body2, err); - }; - const requestStream = (headers2, options) => { - try { - return session.request(headers2, options); - } catch (err) { - if (err?.code !== "ERR_HTTP2_INVALID_CONNECTION_HEADERS") { - throw err; - } - const wrappedErr = new InformationalError(err.message, { cause: err }); - session[kError] = wrappedErr; - session[kSocket][kError] = wrappedErr; - session.destroy(wrappedErr); - util7.destroy(session[kSocket], wrappedErr); - abort(wrappedErr); - return null; + finalizeRequest(state3, resetPendingIdx); } + util7.destroy(state3.body, err); }; + state3.abort = abort; + let stream4 = null; try { request.onRequestStart(abort, null); } catch (err) { @@ -37098,20 +37391,11 @@ var require_client_h22 = __commonJS({ return false; } if (upgrade || method === "CONNECT") { - session.ref(); - const upgradeState = { - abort, - finalizeRequest, - request, - requestTimeout, - responseReceived: false, - session, - stream: null - }; + refH2Session(session); if (upgrade === "websocket") { if (session[kEnableConnectProtocol] === false) { util7.errorRequest(client, request, new InformationalError("HTTP/2: Extended CONNECT protocol not supported by server")); - session.unref(); + unrefH2Session(session); return false; } headers[HTTP2_HEADER_METHOD] = "CONNECT"; @@ -37122,25 +37406,26 @@ var require_client_h22 = __commonJS({ } else { headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https"; } - stream4 = requestStream(headers, { endStream: false, signal }); + stream4 = openStream(client, request, session, abort, headers, { endStream: false, signal }); if (stream4 == null) { - session.unref(); + unrefH2Session(session); return false; } - setupUpgradeStream(stream4, upgradeState); + setupUpgradeStream(stream4, state3); return true; } - stream4 = requestStream(headers, { endStream: false, signal }); + stream4 = openStream(client, request, session, abort, headers, { endStream: false, signal }); if (stream4 == null) { - session.unref(); + unrefH2Session(session); return false; } - setupUpgradeStream(stream4, upgradeState); + setupUpgradeStream(stream4, state3); return true; } headers[HTTP2_HEADER_PATH] = path17; headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https"; const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH"; + let body2 = state3.body; if (body2 && typeof body2.read === "function") { body2.read(0); } @@ -37169,7 +37454,7 @@ var require_client_h22 = __commonJS({ assert4(body2 || contentLength2 === 0, "no body must not have content length"); headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength2}`; } - session.ref(); + refH2Session(session); if (channels.sendHeaders.hasSubscribers) { let header = ""; for (const key in headers) { @@ -37179,45 +37464,39 @@ var require_client_h22 = __commonJS({ channels.sendHeaders.publish({ request, headers: header, socket: session[kSocket] }); } const shouldEndStream = body2 === null || contentLength2 === 0; - const state3 = { - abort, - body: body2, - client, - contentLength: contentLength2, - expectsPayload, - finalizeRequest, - request, - requestTimeout, - responseReceived: false, - session, - stream: null - }; + state3.body = body2; + state3.contentLength = contentLength2; + state3.expectsPayload = expectsPayload; if (expectContinue) { headers[HTTP2_HEADER_EXPECT] = "100-continue"; } - stream4 = requestStream(headers, { endStream: shouldEndStream, signal }); + stream4 = openStream(client, request, session, abort, headers, { endStream: shouldEndStream, signal }); if (stream4 == null) { return false; } stream4[kHTTP2Stream] = true; stream4[kRequestStreamState] = state3; state3.stream = stream4; - bindRequestToStream(request, stream4, null); + clearHttp2IdleTimeout(session); ++session[kOpenStreams]; - stream4.setTimeout(requestTimeout); + if (headersTimeout) { + stream4.setTimeout(headersTimeout); + } stream4[kHTTP2Session] = session; - stream4.once("close", onRequestStreamClose); + stream4.on("close", onRequestStreamClose); bindRequestToStream(request, stream4, releaseRequestStream); if (expectContinue) { stream4.once("continue", writeBodyH2); } - stream4.once("response", onResponse); - stream4.once("end", onEnd); - stream4.once("error", onError); - stream4.once("frameError", onFrameError); + stream4.on("response", onResponse); + stream4.on("end", onEnd); + stream4.on("error", onError); + stream4.on("frameError", onFrameError); stream4.on("aborted", onAborted); - stream4.on("timeout", onTimeout); - stream4.once("trailers", onTrailers); + if (headersTimeout || bodyTimeout) { + stream4.on("timeout", onTimeout); + } + stream4.on("trailers", onTrailers); if (!expectContinue) { writeBodyH2.call(stream4); } @@ -37247,14 +37526,18 @@ var require_client_h22 = __commonJS({ if (request[kRequestStream] === stream4) { detachRequestFromStream(request); } - removeRequestStreamListeners(stream4); if (!stream4.destroyed && !stream4.closed) { + removeRequestStreamListeners(stream4); stream4.once("error", noop); } } function onData(chunk) { const stream4 = this; - const { request } = stream4[kRequestStreamState]; + const state3 = stream4[kRequestStreamState]; + if (state3 == null) { + return; + } + const { request } = state3; if (request.aborted || request.completed) { return; } @@ -37265,13 +37548,23 @@ var require_client_h22 = __commonJS({ function onResponse(headers) { const stream4 = this; const state3 = stream4[kRequestStreamState]; + if (state3 == null) { + return; + } const { request } = state3; stream4.off("response", onResponse); + if (state3.body != null && !state3.bodySent && !stream4.writableEnded) { + stream4.removeListener("continue", writeBodyH2); + stream4.end(); + } const statusCode = headers[HTTP2_HEADER_STATUS]; delete headers[HTTP2_HEADER_STATUS]; request.onResponseStarted(); state3.responseReceived = true; - if (request.aborted) { + if (state3.headersTimeout || state3.bodyTimeout) { + stream4.setTimeout(state3.bodyTimeout); + } + if (request.aborted || request.completed) { releaseRequestStream(stream4); return; } @@ -37283,14 +37576,15 @@ var require_client_h22 = __commonJS({ function onEnd() { const stream4 = this; const state3 = stream4[kRequestStreamState]; + if (state3 == null) { + return; + } const { request } = state3; stream4.off("end", onEnd); - releaseRequestStream(stream4); if (state3.responseReceived) { if (!request.aborted && !request.completed) { - request.onResponseEnd({}); + state3.pendingEnd = true; } - state3.finalizeRequest(); } else { state3.abort(new InformationalError("HTTP/2: stream half-closed (remote)"), true); } @@ -37298,15 +37592,19 @@ var require_client_h22 = __commonJS({ function onError(err) { const stream4 = this; const state3 = stream4[kRequestStreamState]; + if (state3 == null) { + return; + } stream4.off("error", onError); - releaseRequestStream(stream4); state3.abort(err); } function onFrameError(type, code) { const stream4 = this; const state3 = stream4[kRequestStreamState]; + if (state3 == null) { + return; + } stream4.off("frameError", onFrameError); - releaseRequestStream(stream4); state3.abort(new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`)); } function onAborted() { @@ -37315,25 +37613,31 @@ var require_client_h22 = __commonJS({ function onTimeout() { const stream4 = this; const state3 = stream4[kRequestStreamState]; - releaseRequestStream(stream4); - const err = new InformationalError(`HTTP/2: "stream timeout after ${state3.requestTimeout}"`); + if (state3 == null) { + return; + } + stream4.off("timeout", onTimeout); + const err = state3.responseReceived ? new BodyTimeoutError(`HTTP/2: "stream timeout after ${state3.bodyTimeout}"`) : new HeadersTimeoutError(`HTTP/2: "headers timeout after ${state3.headersTimeout}"`); state3.abort(err); } function onTrailers(trailers) { const stream4 = this; const state3 = stream4[kRequestStreamState]; + if (state3 == null) { + return; + } const { request } = state3; stream4.off("trailers", onTrailers); + stream4.off("data", onData); if (request.aborted || request.completed) { return; } - releaseRequestStream(stream4); - request.onResponseEnd(trailers); - state3.finalizeRequest(); + state3.trailers = trailers; } function writeBodyH2() { const stream4 = this; const state3 = stream4[kRequestStreamState]; + state3.bodySent = true; const { abort, body: body2, client, contentLength: contentLength2, expectsPayload, request } = state3; if (!body2 || contentLength2 === 0) { writeBuffer( @@ -37589,6 +37893,12 @@ var require_client2 = __commonJS({ function getPipelining(client) { return client[kPipelining] ?? client[kHTTPContext]?.defaultPipelining ?? 1; } + function getMaxConcurrent(client) { + if (client[kHTTPContext]?.version === "h2") { + return client[kMaxConcurrentStreams]; + } + return getPipelining(client); + } var Client = class extends DispatcherBase { /** * @@ -37779,8 +38089,9 @@ var require_client2 = __commonJS({ return !!this[kHTTPContext] && !this[kConnecting] && !this[kHTTPContext].destroyed; } get [kBusy]() { + const allowsMux = this[kHTTPContext]?.version === "h2"; return Boolean( - this[kHTTPContext]?.busy(null) || this[kSize] >= (getPipelining(this) || 1) || this[kPending] > 0 + this[kHTTPContext]?.busy(null) || this[kSize] >= (getMaxConcurrent(this) || 1) || this[kPending] > 0 && !allowsMux ); } [kConnect](cb) { @@ -37816,7 +38127,9 @@ var require_client2 = __commonJS({ const requests = this[kQueue].splice(this[kPendingIdx]); for (let i = 0; i < requests.length; i++) { const request = requests[i]; - util7.errorRequest(this, request, err); + if (request != null) { + util7.errorRequest(this, request, err); + } } const callback = () => { if (this[kClosedResolve]) { @@ -37841,7 +38154,9 @@ var require_client2 = __commonJS({ const requests = client[kQueue].splice(client[kRunningIdx]); for (let i = 0; i < requests.length; i++) { const request = requests[i]; - util7.errorRequest(client, request, err); + if (request != null) { + util7.errorRequest(client, request, err); + } } assert4(client[kSize] === 0); } @@ -37949,9 +38264,13 @@ var require_client2 = __commonJS({ }); } if (err.code === "ERR_TLS_CERT_ALTNAME_INVALID") { - assert4(client[kRunning] === 0); + const running = client[kQueue].splice(client[kRunningIdx], client[kRunning]); + client[kPendingIdx] = client[kRunningIdx]; + for (let i = 0; i < running.length; i++) { + util7.errorRequest(client, running[i], err); + } while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { - const request = client[kQueue][client[kPendingIdx]++]; + const request = client[kQueue].splice(client[kPendingIdx], 1)[0]; util7.errorRequest(client, request, err); } } else { @@ -38004,7 +38323,7 @@ var require_client2 = __commonJS({ if (client[kPending] === 0) { return; } - if (client[kRunning] >= (getPipelining(client) || 1)) { + if (client[kRunning] >= (getMaxConcurrent(client) || 1)) { return; } const request = client[kQueue][client[kPendingIdx]]; @@ -39446,6 +39765,7 @@ var require_socks5_proxy_agent = __commonJS({ var kProxyProtocol = /* @__PURE__ */ Symbol("proxy protocol"); var kPools = /* @__PURE__ */ Symbol("pools"); var kConnector = /* @__PURE__ */ Symbol("connector"); + var kRequestTls = /* @__PURE__ */ Symbol("request tls settings"); var experimentalWarningEmitted = false; var Socks5ProxyAgent = class extends DispatcherBase { constructor(proxyUrl, options = {}) { @@ -39467,6 +39787,7 @@ var require_socks5_proxy_agent = __commonJS({ this[kProxyUrl] = url2; this[kProxyHeaders] = options.headers || {}; this[kProxyProtocol] = options.proxyTls ? "https:" : "http:"; + this[kRequestTls] = options.requestTls; this[kProxyAuth] = { username: options.username || (url2.username ? decodeURIComponent(url2.username) : null), password: options.password || (url2.password ? decodeURIComponent(url2.password) : null) @@ -39574,9 +39895,9 @@ var require_socks5_proxy_agent = __commonJS({ } debug3("upgrading to TLS"); finalSocket = tls.connect({ + ...this[kRequestTls], socket, - servername: targetHost, - ...connectOpts.tls || {} + servername: this[kRequestTls]?.servername || targetHost }); const tlsReady = Promise.withResolvers(); finalSocket.once("secureConnect", tlsReady.resolve); @@ -39635,7 +39956,7 @@ var require_proxy_agent2 = __commonJS({ var Agent3 = require_agent2(); var Pool = require_pool2(); var DispatcherBase = require_dispatcher_base2(); - var { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError } = require_errors2(); + var { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError, ProxyConnectionError } = require_errors2(); var buildConnector = require_connect2(); var Client = require_client2(); var { channels } = require_diagnostics2(); @@ -39663,14 +39984,19 @@ var require_proxy_agent2 = __commonJS({ } return new Pool(origin, opts); } + function shouldProxyTunnel(requestProtocol, proxyTunnel) { + return proxyTunnel === true || requestProtocol !== "http:"; + } var Http1ProxyWrapper = class extends DispatcherBase { #client; - constructor(proxyUrl, { headers = {}, connect, factory }) { + #proxyServername; + constructor(proxyUrl, { headers = {}, connect, factory, proxyServername }) { if (!proxyUrl) { throw new InvalidArgumentError("Proxy URL is mandatory"); } super(); this[kProxyHeaders] = headers; + this.#proxyServername = proxyServername; if (factory) { this.#client = factory(proxyUrl, { connect }); } else { @@ -39699,6 +40025,9 @@ var require_proxy_agent2 = __commonJS({ headers.host = host; } opts.headers = { ...this[kProxyHeaders], ...headers }; + if (this.#proxyServername != null) { + opts.servername = this.#proxyServername; + } return this.#client[kDispatch](opts, handler); } [kClose]() { @@ -39717,7 +40046,7 @@ var require_proxy_agent2 = __commonJS({ if (typeof clientFactory !== "function") { throw new InvalidArgumentError("Proxy opts.clientFactory must be a function."); } - const { proxyTunnel = true, connectTimeout } = opts; + const { proxyTunnel, connectTimeout } = opts; super(); const url2 = this.#getUrl(opts); const { href, origin, port, protocol, username, password, hostname: proxyHostname } = url2; @@ -39738,6 +40067,7 @@ var require_proxy_agent2 = __commonJS({ this[kProxyHeaders]["proxy-authorization"] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:`).toString("base64")}`; } const connect = buildConnector({ timeout: connectTimeout, ...opts.proxyTls }); + const connectHTTP1 = buildConnector({ timeout: connectTimeout, ...opts.proxyTls, allowH2: false }); this[kConnectEndpoint] = buildConnector({ timeout: connectTimeout, ...opts.requestTls }); this[kConnectEndpointHTTP1] = buildConnector({ timeout: connectTimeout, ...opts.requestTls, allowH2: false }); const agentFactory = opts.factory || defaultAgentFactory; @@ -39750,14 +40080,23 @@ var require_proxy_agent2 = __commonJS({ factory: agentFactory, username: opts.username || username, password: opts.password || password, - proxyTls: opts.proxyTls + proxyTls: opts.proxyTls, + requestTls: opts.requestTls }); } - if (!this[kTunnelProxy] && protocol2 === "http:" && this[kProxy].protocol === "http:") { + if (!shouldProxyTunnel(protocol2, this[kTunnelProxy])) { + const forwardConnect = this[kProxy].protocol === "https:" ? (opts2, cb) => connectHTTP1(opts2, (err, socket) => { + if (err && err.code === "ERR_TLS_CERT_ALTNAME_INVALID") { + cb(new SecureProxyConnectionError(err)); + } else { + cb(err, socket); + } + }) : connectHTTP1; return new Http1ProxyWrapper(this[kProxy].uri, { headers: this[kProxyHeaders], - connect, - factory: agentFactory + connect: forwardConnect, + factory: agentFactory, + proxyServername: this[kProxy].protocol === "https:" ? this[kProxyTls]?.servername || proxyHostname : void 0 }); } return agentFactory(origin2, options); @@ -39819,6 +40158,8 @@ var require_proxy_agent2 = __commonJS({ } catch (err) { if (err.code === "ERR_TLS_CERT_ALTNAME_INVALID") { callback(new SecureProxyConnectionError(err)); + } else if (err.code === "UND_ERR_SOCKET") { + callback(new ProxyConnectionError(err)); } else { callback(err); } @@ -40038,6 +40379,35 @@ var require_retry_handler2 = __commonJS({ const retryTime = new Date(retryAfter).getTime(); return isNaN(retryTime) ? 0 : retryTime - Date.now(); } + var RetryController = class { + constructor() { + this.target = null; + } + pause() { + this.target?.pause(); + } + resume() { + this.target?.resume(); + } + abort(reason) { + this.target?.abort(reason); + } + get paused() { + return this.target?.paused ?? false; + } + get aborted() { + return this.target?.aborted ?? false; + } + get reason() { + return this.target?.reason ?? null; + } + get rawHeaders() { + return this.target?.rawHeaders ?? null; + } + get rawTrailers() { + return this.target?.rawTrailers ?? null; + } + }; var RetryHandler = class _RetryHandler { constructor(opts, { dispatch, handler }) { const { retryOptions, ...dispatchOpts } = opts; @@ -40070,7 +40440,7 @@ var require_retry_handler2 = __commonJS({ timeoutFactor: timeoutFactor ?? 2, maxRetries: maxRetries ?? 5, // What errors we should retry - methods: methods ?? ["GET", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE"], + methods: methods ?? ["GET", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "QUERY"], // Indicates which errors to retry statusCodes: statusCodes ?? [500, 502, 503, 504, 429], // List of errors to retry @@ -40094,12 +40464,13 @@ var require_retry_handler2 = __commonJS({ this.etag = null; this.statusCode = null; this.headers = null; + this.controllerProxy = new RetryController(); } onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err) { if (this.retryOpts.throwOnError) { if (this.retryOpts.statusCodes.includes(statusCode) === false) { this.headersSent = true; - this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage); + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); } else { this.error = err; } @@ -40107,13 +40478,13 @@ var require_retry_handler2 = __commonJS({ } if (isDisturbed(this.opts.body)) { this.headersSent = true; - this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage); + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); return; } function shouldRetry(passedErr) { if (passedErr) { this.headersSent = true; - this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage); + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); controller.resume(); return; } @@ -40131,12 +40502,13 @@ var require_retry_handler2 = __commonJS({ ); } onRequestStart(controller, context3) { + this.controllerProxy.target = controller; if (!this.headersSent) { - this.handler.onRequestStart?.(controller, context3); + this.handler.onRequestStart?.(this.controllerProxy, context3); } } - onRequestUpgrade(controller, statusCode, headers, socket) { - this.handler.onRequestUpgrade?.(controller, statusCode, headers, socket); + onRequestUpgrade(_controller, statusCode, headers, socket) { + this.handler.onRequestUpgrade?.(this.controllerProxy, statusCode, headers, socket); } static [kRetryHandlerDefaultRetry](err, { state: state3, opts }, cb) { const { statusCode, code, headers } = err; @@ -40221,7 +40593,7 @@ var require_retry_handler2 = __commonJS({ if (range2 == null) { this.headersSent = true; this.handler.onResponseStart?.( - controller, + this.controllerProxy, statusCode, headers, statusMessage @@ -40253,7 +40625,7 @@ var require_retry_handler2 = __commonJS({ } this.headersSent = true; this.handler.onResponseStart?.( - controller, + this.controllerProxy, statusCode, headers, statusMessage @@ -40265,14 +40637,14 @@ var require_retry_handler2 = __commonJS({ }); } } - onResponseData(controller, chunk) { + onResponseData(_controller, chunk) { if (this.error) { return; } this.start += chunk.length; - this.handler.onResponseData?.(controller, chunk); + this.handler.onResponseData?.(this.controllerProxy, chunk); } - onResponseEnd(controller, trailers) { + onResponseEnd(_controller, trailers) { if (this.error && this.retryOpts.throwOnError) { throw this.error; } @@ -40286,11 +40658,11 @@ var require_retry_handler2 = __commonJS({ } } this.retryCount = 0; - return this.handler.onResponseEnd?.(controller, trailers); + return this.handler.onResponseEnd?.(this.controllerProxy, trailers); } - this.retry(controller); + this.retry(); } - retry(controller) { + retry() { if (this.start !== 0) { const headers = { range: `bytes=${this.start}-${this.end ?? ""}` }; if (this.etag != null) { @@ -40308,20 +40680,20 @@ var require_retry_handler2 = __commonJS({ this.retryCountCheckpoint = this.retryCount; this.dispatch(this.opts, this); } catch (err) { - this.handler.onResponseError?.(controller, err); + this.handler.onResponseError?.(this.controllerProxy, err); } } onResponseError(controller, err) { if (controller?.aborted || isDisturbed(this.opts.body)) { - this.handler.onResponseError?.(controller, err); + this.handler.onResponseError?.(this.controllerProxy, err); return; } function shouldRetry(returnedErr) { if (!returnedErr) { - this.retry(controller); + this.retry(); return; } - this.handler?.onResponseError?.(controller, returnedErr); + this.handler?.onResponseError?.(this.controllerProxy, returnedErr); } if (this.retryCount - this.retryCountCheckpoint > 0) { this.retryCount = this.retryCountCheckpoint + (this.retryCount - this.retryCountCheckpoint); @@ -40438,6 +40810,7 @@ var require_readable2 = __commonJS({ var kContentLength = /* @__PURE__ */ Symbol("kContentLength"); var kUsed = /* @__PURE__ */ Symbol("kUsed"); var kBytesRead = /* @__PURE__ */ Symbol("kBytesRead"); + var kPreservedBuffer = /* @__PURE__ */ Symbol("kPreservedBuffer"); var noop = () => { }; var BodyReadable = class extends Readable6 { @@ -40676,7 +41049,22 @@ var require_readable2 = __commonJS({ */ setEncoding(encoding) { if (Buffer.isEncoding(encoding)) { - this._readableState.encoding = encoding; + const state3 = this._readableState; + const buffer3 = state3.buffer; + if (buffer3 && state3.length > 0) { + const bufferIndex = state3.bufferIndex ?? 0; + const preserved = []; + const source = typeof buffer3.slice === "function" ? buffer3.slice(bufferIndex) : buffer3; + for (const data of source) { + if (Buffer.isBuffer(data)) { + preserved.push(data); + } + } + if (preserved.length > 0) { + this[kPreservedBuffer] = (this[kPreservedBuffer] || []).concat(preserved); + } + } + super.setEncoding(encoding); } return this; } @@ -40726,7 +41114,13 @@ var require_readable2 = __commonJS({ return; } const { _readableState: state3 } = consume2.stream; - if (state3.bufferIndex) { + const preserved = consume2.stream[kPreservedBuffer]; + if (preserved && preserved.length > 0) { + for (const chunk of preserved) { + consumePush(consume2, chunk); + } + consume2.stream[kPreservedBuffer] = null; + } else if (state3.bufferIndex) { const start = state3.bufferIndex; const end = state3.buffer.length; for (let n = start; n < end; n++) { @@ -40797,6 +41191,9 @@ var require_readable2 = __commonJS({ } } function consumePush(consume2, chunk) { + if (consume2.body === null) { + return; + } consume2.length += chunk.length; consume2.body.push(chunk); } @@ -40883,7 +41280,9 @@ var require_api_request2 = __commonJS({ this.removeAbortListener = util7.addAbortListener(signal, () => { this.reason = signal.reason ?? new RequestAbortedError(); if (this.res) { - util7.destroy(this.res.on("error", noop), this.reason); + const res = this.res; + this.res = null; + util7.destroy(res.on("error", noop), this.reason); } else if (this.abort) { this.abort(this.reason); } @@ -42402,7 +42801,7 @@ var require_mock_call_history = __commonJS({ return finalOptions; } function makeFilterCalls(parameterName) { - return (parameterValue, logs) => { + return (parameterValue, logs = this.logs) => { if (typeof parameterValue === "string" || parameterValue == null) { return logs.filter((log2) => { return log2[parameterName] === parameterValue; @@ -43620,7 +44019,11 @@ var require_snapshot_agent = __commonJS({ * @returns {Promise} */ async close() { - await this[kSnapshotRecorder].close(); + if (this[kSnapshotMode] === "playback") { + this[kSnapshotRecorder].destroy(); + } else { + await this[kSnapshotRecorder].close(); + } await this[kRealAgent]?.close(); await super.close(); } @@ -43767,9 +44170,11 @@ var require_redirect_handler2 = __commonJS({ } this.dispatch = dispatch; this.location = null; - const { maxRedirections: _, ...cleanOpts } = opts; + const { maxRedirections: _, stripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect, ...cleanOpts } = opts; this.opts = cleanOpts; this.opts.body = util7.wrapRequestBody(this.opts.body); + this.stripHeadersOnRedirect = normalizeStripHeaders(stripHeadersOnRedirect, "stripHeadersOnRedirect"); + this.stripHeadersOnCrossOriginRedirect = normalizeStripHeaders(stripHeadersOnCrossOriginRedirect, "stripHeadersOnCrossOriginRedirect"); this.maxRedirections = maxRedirections; this.handler = handler; this.history = []; @@ -43814,7 +44219,7 @@ var require_redirect_handler2 = __commonJS({ throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. 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, statusCode === 303, this.opts.origin !== origin); + this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect); this.opts.path = path17; this.opts.origin = origin; this.opts.query = null; @@ -43836,31 +44241,50 @@ var require_redirect_handler2 = __commonJS({ this.handler.onResponseError?.(controller, error2); } }; - function shouldRemoveHeader(header, removeContent, unknownOrigin) { - if (header.length === 4) { - return util7.headerNameToString(header) === "host"; - } - if (removeContent && util7.headerNameToString(header).startsWith("content-")) { + function shouldRemoveHeader(header, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin) { + const name = util7.headerNameToString(header); + if (name === "host") { return true; } - if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) { - const name = util7.headerNameToString(header); + if (stripHeaders?.has(name) || unknownOrigin && stripHeadersOnCrossOrigin?.has(name)) { + return true; + } + if (removeContent && name.startsWith("content-")) { + return true; + } + if (unknownOrigin) { return name === "authorization" || name === "cookie" || name === "proxy-authorization"; } return false; } - function cleanRequestHeaders(headers, removeContent, unknownOrigin) { + function normalizeStripHeaders(headers, optionName) { + if (headers == null) { + return null; + } + if (!Array.isArray(headers)) { + throw new InvalidArgumentError(`${optionName} must be an array`); + } + const normalized = /* @__PURE__ */ new Set(); + for (const header of headers) { + if (typeof header !== "string") { + throw new InvalidArgumentError(`${optionName} must contain header names`); + } + normalized.add(util7.headerNameToString(header)); + } + return normalized; + } + function cleanRequestHeaders(headers, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin) { const ret = []; if (Array.isArray(headers)) { for (let i = 0; i < headers.length; i += 2) { - if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { + if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin)) { ret.push(headers[i], headers[i + 1]); } } } else if (headers && typeof headers === "object") { const entries = util7.hasSafeIterator(headers) ? headers : Object.entries(headers); for (const [key, value] of entries) { - if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { + if (!shouldRemoveHeader(key, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin)) { ret.push(key, value); } } @@ -43878,14 +44302,14 @@ var require_redirect2 = __commonJS({ "node_modules/undici/lib/interceptor/redirect.js"(exports2, module2) { "use strict"; var RedirectHandler = require_redirect_handler2(); - function createRedirectInterceptor({ maxRedirections: defaultMaxRedirections, throwOnMaxRedirect: defaultThrowOnMaxRedirect } = {}) { + function createRedirectInterceptor({ maxRedirections: defaultMaxRedirections, throwOnMaxRedirect: defaultThrowOnMaxRedirect, stripHeadersOnRedirect: defaultStripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect: defaultStripHeadersOnCrossOriginRedirect } = {}) { return (dispatch) => { return function Intercept(opts, handler) { - const { maxRedirections = defaultMaxRedirections, throwOnMaxRedirect = defaultThrowOnMaxRedirect, ...rest } = opts; + const { maxRedirections = defaultMaxRedirections, throwOnMaxRedirect = defaultThrowOnMaxRedirect, stripHeadersOnRedirect = defaultStripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect = defaultStripHeadersOnCrossOriginRedirect, ...rest } = opts; if (maxRedirections == null || maxRedirections === 0) { return dispatch(opts, handler); } - const dispatchOpts = { ...rest, throwOnMaxRedirect }; + const dispatchOpts = { ...rest, throwOnMaxRedirect, stripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect }; const redirectHandler = new RedirectHandler(dispatch, maxRedirections, dispatchOpts, handler); return dispatch(dispatchOpts, redirectHandler); }; @@ -44496,6 +44920,9 @@ var require_dns2 = __commonJS({ const instance = new DNSInstance(opts); return (dispatch) => { return function dnsInterceptor(origDispatchOpts, handler) { + if (origDispatchOpts.origin == null) { + return dispatch(origDispatchOpts, handler); + } const origin = origDispatchOpts.origin.constructor === URL ? origDispatchOpts.origin : new URL(origDispatchOpts.origin); if (isIP(origin.hostname) !== 0) { return dispatch(origDispatchOpts, handler); @@ -44681,6 +45108,9 @@ var require_cache2 = __commonJS({ lastHeader = lastHeader.substring(0, lastHeader.length - 1); headers[headers.length - 1] = lastHeader; } + for (let j = 0; j < headers.length; j++) { + headers[j] = headers[j].trim(); + } if (key in output) { output[key] = output[key].concat(headers); } else { @@ -44688,10 +45118,11 @@ var require_cache2 = __commonJS({ } } } else { + const fieldName = value.trim(); if (key in output) { - output[key] = output[key].concat(value); + output[key] = output[key].concat(fieldName); } else { - output[key] = [value]; + output[key] = [fieldName]; } } break; @@ -48279,6 +48710,12 @@ var require_request4 = __commonJS({ /** @type {Headers} */ #headers; #state; + /** + * Removes the `abort` listener that makes this request's signal follow the + * passed signal. `null` when no such listener was registered. + * @type {(() => void) | null} + */ + #abortCleanup = null; // https://fetch.spec.whatwg.org/#dom-request constructor(input, init = void 0) { webidl.util.markAsUncloneable(this); @@ -48476,8 +48913,13 @@ var require_request4 = __commonJS({ if (abortSignalHasEventHandlerLeakWarning && getMaxListeners(signal) === defaultMaxListeners) { setMaxListeners(1500, signal); } - util7.addAbortListener(signal, abort); + const removeAbortListener = util7.addAbortListener(signal, abort); requestFinalizer.register(ac, { signal, abort }, abort); + this.#abortCleanup = () => { + requestFinalizer.unregister(abort); + removeAbortListener(); + this.#abortCleanup = null; + }; } } this.#headers = new Headers2(kConstruct); @@ -48756,14 +49198,23 @@ var require_request4 = __commonJS({ static setRequestState(request, newState) { request.#state = newState; } + /** + * 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 } = Request; + 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); function makeRequest(init) { return { @@ -48786,6 +49237,7 @@ var require_request4 = __commonJS({ referrerPolicy: init.referrerPolicy ?? "", mode: init.mode ?? "no-cors", useCORSPreflightFlag: init.useCORSPreflightFlag ?? false, + // TODO: is this credentials mode? https://fetch.spec.whatwg.org/#concept-request-credentials-mode credentials: init.credentials ?? "same-origin", useCredentials: init.useCredentials ?? false, cache: init.cache ?? "default", @@ -48957,7 +49409,8 @@ var require_request4 = __commonJS({ fromInnerRequest, cloneRequest, getRequestDispatcher, - getRequestState + getRequestState, + removeRequestAbortListener }; } }); @@ -49114,7 +49567,7 @@ var require_fetch2 = __commonJS({ getResponseState } = require_response2(); var { HeadersList } = require_headers2(); - var { Request, cloneRequest, getRequestDispatcher, getRequestState } = require_request4(); + var { Request, cloneRequest, getRequestDispatcher, getRequestState, removeRequestAbortListener } = require_request4(); var zlib2 = require("node:zlib"); var { makePolicyContainer, @@ -49251,7 +49704,7 @@ var require_fetch2 = __commonJS({ let responseObject = null; let locallyAborted = false; let controller = null; - addAbortListener( + const removeAbortListener = addAbortListener( requestObject.signal, () => { locallyAborted = true; @@ -49261,16 +49714,22 @@ var require_fetch2 = __commonJS({ abortFetch(p, request, realResponse, requestObject.signal.reason, controller.controller); } ); + const cleanupAbortListeners = () => { + removeAbortListener(); + removeRequestAbortListener(requestObject); + }; const processResponse = (response) => { if (locallyAborted) { return; } if (response.aborted) { abortFetch(p, request, responseObject, controller.serializedAbortReason, controller.controller); + cleanupAbortListeners(); return; } if (response.type === "error") { p.reject(new TypeError("fetch failed", { cause: response.error })); + cleanupAbortListeners(); return; } responseObject = new WeakRef(fromInnerResponse(response, "immutable")); @@ -49279,7 +49738,10 @@ var require_fetch2 = __commonJS({ }; controller = fetching({ request, - processResponseEndOfBody: handleFetchDone, + processResponseEndOfBody: (response) => { + handleFetchDone(response); + cleanupAbortListeners(); + }, processResponse, dispatcher: getRequestDispatcher(requestObject), // undici @@ -49778,7 +50240,12 @@ var require_fetch2 = __commonJS({ httpFetchParams = fetchParams; httpRequest = request; } else { - httpRequest = cloneRequest(request); + if (request.body?.source != null) { + httpRequest = cloneRequest(request); + } else { + httpRequest = cloneRequest({ ...request, body: null }); + httpRequest.body = request.body; + } httpFetchParams = { ...fetchParams }; httpFetchParams.request = httpRequest; } @@ -49823,7 +50290,7 @@ var require_fetch2 = __commonJS({ } if (!httpRequest.headersList.contains("accept-encoding", true)) { if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { - httpRequest.headersList.append("accept-encoding", "br, gzip, deflate", true); + httpRequest.headersList.append("accept-encoding", "br, gzip, deflate, zstd", true); } else { httpRequest.headersList.append("accept-encoding", "gzip, deflate", true); } @@ -51001,7 +51468,7 @@ var require_util12 = __commonJS({ for (let i = 0; i < path17.length; ++i) { const code = path17.charCodeAt(i); if (code < 32 || // exclude CTLs (0-31) - code === 127 || // DEL + code > 126 || // exclude non-ascii and DEL code === 59) { throw new Error("Invalid cookie path"); } @@ -51114,7 +51581,6 @@ var require_parse4 = __commonJS({ var { maxNameValuePairSize, maxAttributeValueSize } = require_constants11(); var { isCTLExcludingHtab } = require_util12(); var assert4 = require("node:assert"); - var { unescape: qsUnescape } = require("node:querystring"); function parseSetCookie(header) { if (isCTLExcludingHtab(header)) { return null; @@ -51148,7 +51614,7 @@ var require_parse4 = __commonJS({ } return { name, - value: qsUnescape(value), + value, ...parseUnparsedAttributes(unparsedAttributes) }; } @@ -51191,7 +51657,9 @@ var require_parse4 = __commonJS({ const attributeNameLowercase = attributeName.toLowerCase(); if (attributeNameLowercase === "expires") { const expiryTime = new Date(attributeValue); - cookieAttributeList.expires = expiryTime; + 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] !== "-") { @@ -51222,18 +51690,14 @@ var require_parse4 = __commonJS({ } else if (attributeNameLowercase === "httponly") { cookieAttributeList.httpOnly = true; } else if (attributeNameLowercase === "samesite") { - let enforcement = "Default"; const attributeValueLowercase = attributeValue.toLowerCase(); - if (attributeValueLowercase.includes("none")) { - enforcement = "None"; + if (attributeValueLowercase === "none") { + cookieAttributeList.sameSite = "None"; + } else if (attributeValueLowercase === "strict") { + cookieAttributeList.sameSite = "Strict"; + } else if (attributeValueLowercase === "lax") { + cookieAttributeList.sameSite = "Lax"; } - if (attributeValueLowercase.includes("strict")) { - enforcement = "Strict"; - } - if (attributeValueLowercase.includes("lax")) { - enforcement = "Lax"; - } - cookieAttributeList.sameSite = enforcement; } else { cookieAttributeList.unparsed ??= []; cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`); @@ -52253,6 +52717,8 @@ var require_receiver2 = __commonJS({ /** @type {import('./websocket').Handler} */ #handler; /** @type {number} */ + #maxFragments; + /** @type {number} */ #maxPayloadSize; /** * @param {import('./websocket').Handler} handler @@ -52263,6 +52729,7 @@ var require_receiver2 = __commonJS({ super(); this.#handler = handler; this.#extensions = extensions == null ? /* @__PURE__ */ new Map() : extensions; + this.#maxFragments = options.maxFragments ?? 0; this.#maxPayloadSize = options.maxPayloadSize ?? 0; if (this.#extensions.has("permessage-deflate")) { this.#extensions.set("permessage-deflate", new PerMessageDeflate(extensions, options)); @@ -52279,7 +52746,7 @@ var require_receiver2 = __commonJS({ this.run(callback); } #validatePayloadLength() { - if (this.#maxPayloadSize > 0 && !isControlFrame(this.#info.opcode) && this.#info.payloadLength > this.#maxPayloadSize) { + if (this.#maxPayloadSize > 0 && !isControlFrame(this.#info.opcode) && this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize) { failWebsocketConnection(this.#handler, 1009, "Payload size exceeds maximum allowed size"); return false; } @@ -52396,7 +52863,9 @@ var require_receiver2 = __commonJS({ this.#state = parserStates.INFO; } else { if (!this.#info.compressed) { - this.writeFragments(body2); + if (!this.writeFragments(body2)) { + return; + } if (!this.#info.fragmented && this.#info.fin) { websocketMessageReceived(this.#handler, this.#info.binaryType, this.consumeFragments()); } @@ -52411,7 +52880,9 @@ var require_receiver2 = __commonJS({ failWebsocketConnection(this.#handler, code, error2.message); return; } - this.writeFragments(data); + if (!this.writeFragments(data)) { + return; + } if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) { failWebsocketConnection(this.#handler, 1009, new MessageSizeExceededError().message); return; @@ -52476,8 +52947,13 @@ var require_receiver2 = __commonJS({ } } writeFragments(fragment) { + if (this.#maxFragments > 0 && this.#fragments.length === this.#maxFragments) { + failWebsocketConnection(this.#handler, 1008, "Too many message fragments"); + return false; + } this.#fragmentsBytes += fragment.length; this.#fragments.push(fragment); + return true; } consumeFragments() { const fragments = this.#fragments; @@ -52944,8 +53420,10 @@ var require_websocket2 = __commonJS({ */ #onConnectionEstablished(response, parsedExtensions) { this.#handler.socket = response.socket; + const maxFragments = this.#handler.controller.dispatcher?.webSocketOptions?.maxFragments; const maxPayloadSize = this.#handler.controller.dispatcher?.webSocketOptions?.maxPayloadSize; const parser = new ByteParser(this.#handler, parsedExtensions, { + maxFragments, maxPayloadSize }); parser.on("drain", () => this.#handler.onParserDrain()); @@ -53391,7 +53869,12 @@ var require_websocketstream = __commonJS({ /** @type {import('../websocket').Handler['onConnectionEstablished']} */ #onConnectionEstablished(response, parsedExtensions) { this.#handler.socket = response.socket; - const parser = new ByteParser(this.#handler, parsedExtensions); + const maxFragments = this.#handler.controller.dispatcher?.webSocketOptions?.maxFragments; + const maxPayloadSize = this.#handler.controller.dispatcher?.webSocketOptions?.maxPayloadSize; + const parser = new ByteParser(this.#handler, parsedExtensions, { + maxFragments, + maxPayloadSize + }); parser.on("drain", () => this.#handler.onParserDrain()); parser.on("error", (err) => this.#handler.onParserError(err)); this.#parser = parser; @@ -53531,6 +54014,7 @@ var require_websocketstream = __commonJS({ var require_util14 = __commonJS({ "node_modules/undici/lib/web/eventsource/util.js"(exports2, module2) { "use strict"; + var { makeRequest } = require_request4(); function isValidLastEventId(value) { return value.indexOf("\0") === -1; } @@ -53541,9 +54025,27 @@ var require_util14 = __commonJS({ } return true; } + function createPotentialCORSRequest(url2, destination, corsAttributeState, sameOriginFallback) { + let mode = corsAttributeState === "no cors" ? "no-cors" : "cors"; + if (sameOriginFallback && mode === "no-cors") { + mode = "same-origin"; + } + let credentialsMode = "include"; + if (corsAttributeState === "anonymous") { + credentialsMode = "same-origin"; + } + return makeRequest({ + urlList: [url2], + destination, + mode, + credentials: credentialsMode, + useURLCredentials: true + }); + } module2.exports = { isValidLastEventId, - isASCIINumber + isASCIINumber, + createPotentialCORSRequest }; } }); @@ -53895,7 +54397,6 @@ var require_eventsource2 = __commonJS({ "use strict"; var { pipeline: pipeline4 } = require("node:stream"); var { fetching } = require_fetch2(); - var { makeRequest } = require_request4(); var { webidl } = require_webidl2(); var { EventSourceStream } = require_eventsource_stream2(); var { parseMIMEType } = require_data_url2(); @@ -53903,6 +54404,7 @@ var require_eventsource2 = __commonJS({ var { isNetworkError } = require_response2(); var { kEnumerableProperty } = require_util9(); var { environmentSettingsObject } = require_util10(); + var { createPotentialCORSRequest } = require_util14(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -53967,20 +54469,12 @@ var require_eventsource2 = __commonJS({ corsAttributeState = USE_CREDENTIALS; this.#withCredentials = true; } - const initRequest = { - redirect: "follow", - keepalive: true, - // @see https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes - mode: "cors", - credentials: corsAttributeState === "anonymous" ? "same-origin" : "omit", - referrer: "no-referrer" - }; - initRequest.client = environmentSettingsObject.settingsObject; - initRequest.headersList = [["accept", { name: "accept", value: "text/event-stream" }]]; - initRequest.cache = "no-store"; - initRequest.initiator = "other"; - initRequest.urlList = [new URL(this.#url)]; - this.#request = makeRequest(initRequest); + const request = createPotentialCORSRequest(urlRecord, "", corsAttributeState); + request.client = environmentSettingsObject.settingsObject; + request.headersList.set("Accept", "text/event-stream"); + request.cache = "no-store"; + request.initiator = "other"; + this.#request = request; this.#connect(); } /** @@ -58352,6 +58846,7 @@ var SystemTarPathOnWindows = `${process.env["SYSTEMDRIVE"]}\\Windows\\System32\\ var TarFilename = "cache.tar"; var ManifestFilename = "manifest.txt"; var CacheFileSizeLimit = 10 * Math.pow(1024, 3); +var CacheReadDeniedMessagePrefix = "cache read denied:"; // node_modules/@actions/cache/lib/internal/cacheUtils.js var __awaiter10 = function(thisArg, _arguments, P, generator) { @@ -89009,6 +89504,15 @@ function getCacheServiceVersion() { return "v1"; return process.env["ACTIONS_CACHE_SERVICE_V2"] ? "v2" : "v1"; } +var KNOWN_CACHE_MODES = ["none", "read", "write", "write-only"]; +function getCacheMode() { + return (process.env["ACTIONS_CACHE_MODE"] || "").trim().toLowerCase(); +} +function isCacheReadable(mode) { + if (!KNOWN_CACHE_MODES.includes(mode)) + return true; + return mode === "read" || mode === "write"; +} function getCacheServiceURL() { const version3 = getCacheServiceVersion(); switch (version3) { @@ -89082,6 +89586,7 @@ function createHttpClient() { } function getCacheEntry(keys, paths, options) { return __awaiter13(this, void 0, void 0, function* () { + var _a; const httpClient = createHttpClient(); const version3 = getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod, options === null || options === void 0 ? void 0 : options.enableCrossOsArchive); const resource = `cache?keys=${encodeURIComponent(keys.join(","))}&version=${version3}`; @@ -89095,6 +89600,10 @@ function getCacheEntry(keys, paths, options) { return null; } if (!isSuccessStatusCode(response.statusCode)) { + const errorMessage = (_a = response.error) === null || _a === void 0 ? void 0 : _a.message; + if (errorMessage === null || errorMessage === void 0 ? void 0 : errorMessage.includes(CacheReadDeniedMessagePrefix)) { + throw new Error(errorMessage); + } throw new Error(`Cache service responded with ${response.statusCode}`); } const cacheResult = response.result; @@ -90223,6 +90732,14 @@ var ValidationError = class _ValidationError extends Error { Object.setPrototypeOf(this, _ValidationError.prototype); } }; +var CACHE_READ_DENIED_PREFIX = CacheReadDeniedMessagePrefix; +var CacheReadDeniedError = class _CacheReadDeniedError extends Error { + constructor(message) { + super(message); + this.name = "CacheReadDeniedError"; + Object.setPrototypeOf(this, _CacheReadDeniedError.prototype); + } +}; function checkPaths(paths) { if (!paths || paths.length === 0) { throw new ValidationError(`Path Validation Error: At least one directory or file path is required`); @@ -90242,6 +90759,12 @@ function restoreCache(paths_1, primaryKey_1, restoreKeys_1, options_1) { const cacheServiceVersion = getCacheServiceVersion(); debug(`Cache service version: ${cacheServiceVersion}`); checkPaths(paths); + const cacheMode = getCacheMode(); + if (!isCacheReadable(cacheMode)) { + info(`Cache restore skipped: the effective cache-mode '${cacheMode}' does not permit reads.`); + debug(`Skipped restore for paths [${paths.join(", ")}] with primary key '${primaryKey}'.`); + return void 0; + } switch (cacheServiceVersion) { case "v2": return yield restoreCacheV2(paths, primaryKey, restoreKeys, options, enableCrossOsArchive); @@ -90253,6 +90776,7 @@ function restoreCache(paths_1, primaryKey_1, restoreKeys_1, options_1) { } function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter16(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { + var _a; restoreKeys = restoreKeys || []; const keys = [primaryKey, ...restoreKeys]; debug("Resolved Keys:"); @@ -90266,10 +90790,19 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) { const compressionMethod = yield getCompressionMethod(); let archivePath = ""; try { - const cacheEntry = yield getCacheEntry(keys, paths, { - compressionMethod, - enableCrossOsArchive - }); + let cacheEntry; + try { + cacheEntry = yield getCacheEntry(keys, paths, { + compressionMethod, + enableCrossOsArchive + }); + } catch (error2) { + const errorMessage = (_a = error2 === null || error2 === void 0 ? void 0 : error2.message) !== null && _a !== void 0 ? _a : ""; + if (errorMessage.includes(CACHE_READ_DENIED_PREFIX)) { + throw new CacheReadDeniedError(errorMessage); + } + throw error2; + } if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) { return void 0; } @@ -90311,6 +90844,7 @@ function restoreCacheV1(paths_1, primaryKey_1, restoreKeys_1, options_1) { } function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter16(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { + var _a; options = Object.assign(Object.assign({}, options), { useAzureSdk: true }); restoreKeys = restoreKeys || []; const keys = [primaryKey, ...restoreKeys]; @@ -90331,7 +90865,16 @@ function restoreCacheV2(paths_1, primaryKey_1, restoreKeys_1, options_1) { restoreKeys, version: getCacheVersion(paths, compressionMethod, enableCrossOsArchive) }; - const response = yield twirpClient.GetCacheEntryDownloadURL(request); + let response; + try { + response = yield twirpClient.GetCacheEntryDownloadURL(request); + } catch (error2) { + const errorMessage = (_a = error2 === null || error2 === void 0 ? void 0 : error2.message) !== null && _a !== void 0 ? _a : ""; + if (errorMessage.includes(CACHE_READ_DENIED_PREFIX)) { + throw new CacheReadDeniedError(errorMessage); + } + throw error2; + } if (!response.ok) { debug(`Cache not found for version ${request.version} of keys: ${keys.join(", ")}`); return void 0; diff --git a/dist/update-known-checksums/index.cjs b/dist/update-known-checksums/index.cjs index 72b9bab..30d8db2 100644 --- a/dist/update-known-checksums/index.cjs +++ b/dist/update-known-checksums/index.cjs @@ -20394,6 +20394,22 @@ var require_errors2 = __commonJS({ return true; } }; + var kProxyConnectionError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_PRX_CONN"); + var ProxyConnectionError = class extends UndiciError { + constructor(cause, message, options = {}) { + super(message, { cause, ...options }); + this.name = "ProxyConnectionError"; + this.message = message || "Proxy Connection failed"; + this.code = "UND_ERR_PRX_CONN"; + this.cause = cause; + } + static [Symbol.hasInstance](instance) { + return instance && instance[kProxyConnectionError] === true; + } + get [kProxyConnectionError]() { + return true; + } + }; var kMaxOriginsReachedError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_MAX_ORIGINS_REACHED"); var MaxOriginsReachedError = class extends UndiciError { constructor(message) { @@ -20455,6 +20471,7 @@ var require_errors2 = __commonJS({ RequestRetryError, ResponseError, SecureProxyConnectionError, + ProxyConnectionError, MaxOriginsReachedError, Socks5ProxyError, MessageSizeExceededError @@ -21100,9 +21117,8 @@ var require_util9 = __commonJS({ 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"; } function addAbortListener(signal, listener) { - if (signal instanceof AbortSignal) { - const disposable = addAbortListenerNative(signal, listener); - return () => disposable[Symbol.dispose](); + if (!signal || "aborted" in signal) { + return addAbortListenerNative(signal, listener)[Symbol.dispose]; } if (typeof signal.addEventListener === "function") { signal.addEventListener("abort", listener, { once: true }); @@ -21406,7 +21422,8 @@ var require_util9 = __commonJS({ var rangeHeaderRegex = /^bytes (\d+)-(\d+)\/(\d+|\*)?$/; function parseRangeHeader(range) { if (range == null || range === "") return { start: 0, end: null, size: null }; - const m = range ? range.match(rangeHeaderRegex) : null; + if (!range) return null; + const m = rangeHeaderRegex.exec(range); return m ? { start: parseInt(m[1]), end: m[2] ? parseInt(m[2]) : null, @@ -21480,7 +21497,18 @@ var require_util9 = __commonJS({ message += ` timeout: ${opts.timeout}ms)`; destroy(socket, new ConnectTimeoutError(message)); } + var lastUrlString = null; + var lastProtocol = null; function getProtocolFromUrlString(urlString) { + if (urlString === lastUrlString) { + return lastProtocol; + } + const protocol = getProtocolFromUrlStringSlow(urlString); + lastUrlString = urlString; + lastProtocol = protocol; + return protocol; + } + function getProtocolFromUrlStringSlow(urlString) { if (urlString[0] === "h" && urlString[1] === "t" && urlString[2] === "t" && urlString[3] === "p") { switch (urlString[4]) { case ":": @@ -21493,8 +21521,10 @@ var require_util9 = __commonJS({ } return urlString.slice(0, urlString.indexOf(":") + 1); } - var kEnumerableProperty = /* @__PURE__ */ Object.create(null); - kEnumerableProperty.enumerable = true; + var kEnumerableProperty = { + __proto__: null, + enumerable: true + }; var normalizedMethodRecordsBase = { delete: "DELETE", DELETE: "DELETE", @@ -21507,7 +21537,9 @@ var require_util9 = __commonJS({ post: "POST", POST: "POST", put: "PUT", - PUT: "PUT" + PUT: "PUT", + query: "QUERY", + QUERY: "QUERY" }; var normalizedMethodRecords = { ...normalizedMethodRecordsBase, @@ -21998,7 +22030,7 @@ var require_request3 = __commonJS({ this.path = query ? serializePathWithQuery(path, query) : path; this.origin = origin; this.protocol = getProtocolFromUrlString(origin); - this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent; + this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" || method === "QUERY" : idempotent; this.blocking = blocking ?? this.method !== "HEAD"; this.reset = reset == null ? null : reset; this.host = null; @@ -22324,6 +22356,7 @@ var require_dispatcher_base2 = __commonJS({ */ get webSocketOptions() { return { + maxFragments: this[kWebSocketOptions].maxFragments ?? 131072, maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 // 128 MB default }; @@ -22448,7 +22481,7 @@ var require_connect2 = __commonJS({ var net = require("node:net"); var assert = require("node:assert"); var util = require_util9(); - var { InvalidArgumentError } = require_errors2(); + var { InvalidArgumentError, ConnectTimeoutError } = require_errors2(); var tls; var SessionCache = class WeakSessionCache { constructor(maxCachedSessions) { @@ -22490,7 +22523,7 @@ var require_connect2 = __commonJS({ this._sessionRegistry.register(session, sessionKey); } }; - function buildConnector({ allowH2, useH2c, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) { + function buildConnector({ allowH2, preferH2, useH2c, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) { if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { throw new InvalidArgumentError("maxCachedSessions must be a positive integer or zero"); } @@ -22516,7 +22549,7 @@ var require_connect2 = __commonJS({ servername, session, localAddress, - ALPNProtocols: allowH2 ? ["http/1.1", "h2"] : ["http/1.1"], + ALPNProtocols: allowH2 ? preferH2 ? ["h2", "http/1.1"] : ["http/1.1", "h2"] : ["http/1.1"], socket: httpSocket, // upgrade socket connection port, @@ -22557,12 +22590,27 @@ var require_connect2 = __commonJS({ if (callback) { const cb = callback; callback = null; - cb(err); + cb(maybeNormalizeConnectError(err, this, { timeout, hostname, port })); } }); return socket; }; } + function maybeNormalizeConnectError(err, socket, opts) { + if (err instanceof AggregateError && (err.code === "ETIMEDOUT" || err.errors.some((e) => e != null && e.code === "ETIMEDOUT"))) { + let message = "Connect Timeout Error"; + if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) { + message += ` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(", ")},`; + } else { + message += ` (attempted address: ${opts.hostname}:${opts.port},`; + } + message += ` timeout: ${opts.timeout}ms)`; + const wrapped = new ConnectTimeoutError(message); + wrapped.cause = err; + return wrapped; + } + return err; + } module2.exports = buildConnector; } }); @@ -23369,7 +23417,7 @@ var require_constants8 = __commonJS({ ); var safeMethods = ( /** @type {const} */ - ["GET", "HEAD", "OPTIONS", "TRACE"] + ["GET", "HEAD", "OPTIONS", "TRACE", "QUERY"] ); var safeMethodsSet = new Set(safeMethods); var requestMode = ( @@ -25091,7 +25139,7 @@ var require_util10 = __commonJS({ if (rangeEndValue === null && rangeStartValue === null) { return "failure"; } - if (rangeStartValue > rangeEndValue) { + if (rangeStartValue !== null && rangeEndValue !== null && rangeStartValue > rangeEndValue) { return "failure"; } return { rangeStartValue, rangeEndValue }; @@ -26081,6 +26129,29 @@ Content-Type: ${value.type || "application/octet-stream"}\r return consumeBody(this, (bytes) => { return new Uint8Array(bytes); }, instance, getInternalState); + }, + textStream() { + const this_ = getInternalState(this); + if (bodyUnusable(this_)) { + throw new TypeError("Body is unusable: Body has already been read"); + } + if (this_.body == null) { + let controller; + const emptyStream = new ReadableStream({ + start: (c) => { + controller = c; + }, + pull: () => Promise.resolve(), + cancel: () => Promise.resolve() + }, { + size: () => 1 + }); + controller.close(); + return emptyStream; + } + const stream = this_.body.stream; + const decoder = new TextDecoderStream("UTF-8"); + return stream.pipeThrough(decoder); } }; return methods; @@ -26195,6 +26266,9 @@ var require_client_h12 = __commonJS({ var EMPTY_BUF = Buffer.alloc(0); var FastBuffer = Buffer[Symbol.species]; var removeAllListeners = util.removeAllListeners; + var kIdleSocketValidation = /* @__PURE__ */ Symbol("kIdleSocketValidation"); + var kIdleSocketValidationTimeout = /* @__PURE__ */ Symbol("kIdleSocketValidationTimeout"); + var kSocketUsed = /* @__PURE__ */ Symbol("kSocketUsed"); var extractBody; function lazyllhttp() { const llhttpWasmData = process.env.JEST_WORKER_ID ? require_llhttp_wasm2() : void 0; @@ -26435,8 +26509,20 @@ var require_client_h12 = __commonJS({ finish() { assert(currentParser === null); assert(this.ptr != null); - assert(!this.paused); const { llhttp } = this; + if (this.paused) { + let data; + do { + llhttp.llhttp_resume(this.ptr); + this.paused = false; + data = this.socket.read() || EMPTY_BUF; + this.execute(data); + } while (this.paused && data.length > 0); + if (this.paused) { + llhttp.llhttp_resume(this.ptr); + this.paused = false; + } + } let ret; try { currentParser = this; @@ -26493,6 +26579,10 @@ var require_client_h12 = __commonJS({ if (socket.destroyed) { return -1; } + if (client[kRunning] === 0) { + util.destroy(socket, new SocketError("bad response", util.getSocketInfo(socket))); + return -1; + } const request = client[kQueue][client[kRunningIdx]]; if (!request) { return -1; @@ -26600,6 +26690,10 @@ var require_client_h12 = __commonJS({ if (socket.destroyed) { return -1; } + if (client[kRunning] === 0) { + util.destroy(socket, new SocketError("bad response", util.getSocketInfo(socket))); + return -1; + } const request = client[kQueue][client[kRunningIdx]]; if (!request) { return -1; @@ -26733,6 +26827,7 @@ var require_client_h12 = __commonJS({ } request.onResponseEnd(headers); client[kQueue][client[kRunningIdx]++] = null; + socket[kSocketUsed] = client[kPending] === 0; if (socket[kWriting]) { assert(client[kRunning] === 0); util.destroy(socket, new InformationalError("reset")); @@ -26786,6 +26881,9 @@ var require_client_h12 = __commonJS({ socket[kWriting] = false; socket[kReset] = false; socket[kBlocking] = false; + socket[kIdleSocketValidation] = 0; + socket[kIdleSocketValidationTimeout] = null; + socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); util.addListener(socket, "error", onHttpSocketError); util.addListener(socket, "readable", onHttpSocketReadable); @@ -26825,7 +26923,7 @@ var require_client_h12 = __commonJS({ * @returns {boolean} */ busy(request) { - if (socket[kWriting] || socket[kReset] || socket[kBlocking]) { + if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) { return true; } if (request) { @@ -26873,6 +26971,7 @@ var require_client_h12 = __commonJS({ } function onHttpSocketClose() { const parser = this[kParser]; + clearIdleSocketValidation(this); if (parser) { if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { this[kError] = parser.finish() || this[kError]; @@ -26904,6 +27003,24 @@ var require_client_h12 = __commonJS({ function onSocketClose() { this[kClosed] = true; } + function clearIdleSocketValidation(socket) { + if (socket[kIdleSocketValidationTimeout]) { + clearTimeout(socket[kIdleSocketValidationTimeout]); + socket[kIdleSocketValidationTimeout] = null; + } + socket[kIdleSocketValidation] = 0; + } + function scheduleIdleSocketValidation(client, socket) { + socket[kIdleSocketValidation] = 1; + socket[kIdleSocketValidationTimeout] = setTimeout(() => { + 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]; if (socket && !socket.destroyed) { @@ -26916,6 +27033,29 @@ var require_client_h12 = __commonJS({ socket.ref(); socket[kNoRef] = false; } + if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) { + if (socket[kIdleSocketValidation] === 0) { + scheduleIdleSocketValidation(client, socket); + socket[kParser].readMore(); + if (socket.destroyed) { + return; + } + return; + } + if (socket[kIdleSocketValidation] === 1) { + socket[kParser].readMore(); + if (socket.destroyed) { + return; + } + return; + } + } + if (client[kRunning] === 0) { + socket[kParser].readMore(); + if (socket.destroyed) { + return; + } + } if (client[kSize] === 0) { if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) { socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE); @@ -26968,6 +27108,7 @@ var require_client_h12 = __commonJS({ process.emitWarning(new RequestContentLengthMismatchError()); } const socket = client[kSocket]; + clearIdleSocketValidation(socket); const abort = (err) => { if (request.aborted || request.completed) { return; @@ -27359,7 +27500,9 @@ var require_client_h22 = __commonJS({ RequestAbortedError, SocketError, InformationalError, - InvalidArgumentError + InvalidArgumentError, + HeadersTimeoutError, + BodyTimeoutError } = require_errors2(); var { kUrl, @@ -27384,6 +27527,8 @@ var require_client_h22 = __commonJS({ kSize, kHTTPContext, kClosed, + kKeepAliveDefaultTimeout, + kHeadersTimeout, kBodyTimeout, kEnableConnectProtocol, kRemoteSettings, @@ -27421,6 +27566,25 @@ var require_client_h22 = __commonJS({ function getGoAwayError(session, errorCode) { return session[kError] || (errorCode === NGHTTP2_NO_ERROR ? new InformationalError(`HTTP/2: "GOAWAY" frame received with code ${errorCode}`) : new SocketError(`HTTP/2: "GOAWAY" frame received with code ${errorCode}`, util.getSocketInfo(session[kSocket]))); } + function resetHttp2Session(session, err) { + const client = session[kClient]; + const socket = session[kSocket]; + if (client[kHTTP2Session] === session) { + client[kSocket] = null; + client[kHTTPContext] = null; + client[kHTTP2Session] = null; + } + if (socket != null && socket[kError] == null) { + socket[kError] = err; + } + if (!session.closed && !session.destroyed) { + try { + session.destroy(err); + } catch { + } + } + util.destroy(socket, err); + } function getGoAwayPendingIdx(client, lastStreamID) { const maxAcceptedStreamID = Number.isInteger(lastStreamID) ? lastStreamID : Number.MAX_SAFE_INTEGER; for (let i = client[kRunningIdx]; i < client[kPendingIdx]; i++) { @@ -27454,13 +27618,31 @@ var require_client_h22 = __commonJS({ detachRequestFromStream(request); cleanup?.(stream); } + function requeueUnsentRequest(client, request) { + client[kQueue].splice(client[kPendingIdx] + 1, 0, request); + } + function completeRequest(client, request, resetPendingIdx = false) { + const queue = client[kQueue]; + const runningIdx = client[kRunningIdx]; + if (runningIdx < client[kPendingIdx] && queue[runningIdx] === request) { + client[kRunningIdx] = runningIdx + 1; + return; + } + const index = queue.indexOf(request, runningIdx); + if (index === -1 || index >= client[kPendingIdx]) { + return; + } + queue.splice(index, 1); + client[kPendingIdx]--; + if (resetPendingIdx && client[kPendingIdx] < client[kRunningIdx]) { + client[kPendingIdx] = client[kRunningIdx]; + } + } function canRetryRequestAfterGoAway(request) { const { body } = request; return body == null || util.isBuffer(body) || util.isBlobLike(body); } - function closeRequestStream(request, code = NGHTTP2_REFUSED_STREAM) { - const stream = request[kRequestStream]; - clearRequestStream(request); + function closeStream(stream, code = NGHTTP2_REFUSED_STREAM) { if (stream != null && !stream.destroyed && !stream.closed) { try { stream.close(code); @@ -27468,6 +27650,11 @@ var require_client_h22 = __commonJS({ } } } + function detachRequestStreamForClose(request) { + const stream = request[kRequestStream]; + clearRequestStream(request); + return stream; + } function connectH2(client, socket) { client[kSocket] = socket; const http2InitialWindowSize = client[kHTTP2InitialWindowSize]; @@ -27486,6 +27673,12 @@ var require_client_h22 = __commonJS({ session[kClient] = client; session[kSocket] = socket; session[kHTTP2SessionState] = { + idleTimeout: null, + // Sockets start out ref'd. Session ref/unref proxies to the socket, so a + // single cached flag lets us skip redundant uv ref/unref calls, provided + // every ref/unref of the session or its socket goes through + // refH2Session/unrefH2Session. + refed: true, ping: { interval: client[kPingInterval] === 0 ? null : setInterval(onHttp2SendPing, client[kPingInterval], session).unref() } @@ -27502,7 +27695,7 @@ var require_client_h22 = __commonJS({ util.addListener(session, "goaway", onHttp2SessionGoAway); util.addListener(session, "close", onHttp2SessionClose); util.addListener(session, "remoteSettings", onHttp2RemoteSettings); - session.unref(); + unrefH2Session(session); client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", onHttp2SocketError); @@ -27556,7 +27749,6 @@ var require_client_h22 = __commonJS({ } if (request != null) { if (client[kRunning] > 0) { - if (request.idempotent === false) return true; if ((request.upgrade === "websocket" || request.method === "CONNECT") && session[kRemoteSettings] === false) return true; if (util.bodyLength(request.body) !== 0 && (util.isStream(request.body) || util.isAsyncIterable(request.body) || util.isFormDataLike(request.body))) return true; } else { @@ -27567,18 +27759,69 @@ var require_client_h22 = __commonJS({ } }; } + function refH2Session(session) { + const state = session[kHTTP2SessionState]; + if (state.refed === false) { + state.refed = true; + session.ref(); + } + } + function unrefH2Session(session) { + const state = session[kHTTP2SessionState]; + if (state.refed === true) { + state.refed = false; + session.unref(); + } + } function resumeH2(client) { const socket = client[kSocket]; + const session = client[kHTTP2Session]; if (socket?.destroyed === false) { if (client[kSize] === 0 || client[kMaxConcurrentStreams] === 0) { - socket.unref(); - client[kHTTP2Session].unref(); + unrefH2Session(session); } else { - socket.ref(); - client[kHTTP2Session].ref(); + refH2Session(session); + } + if (client[kSize] === 0 && session[kOpenStreams] === 0) { + setHttp2IdleTimeout(session); + } else { + clearHttp2IdleTimeout(session); } } } + function clearHttp2IdleTimeout(session) { + const state = session[kHTTP2SessionState]; + if (state?.idleTimeout != null) { + clearTimeout(state.idleTimeout); + state.idleTimeout = null; + } + } + function setHttp2IdleTimeout(session) { + const client = session[kClient]; + if (client[kHTTP2Session] !== session || session.closed || session.destroyed) { + return; + } + if (session[kOpenStreams] !== 0 || client[kSize] !== 0) { + clearHttp2IdleTimeout(session); + return; + } + const state = session[kHTTP2SessionState]; + if (state.idleTimeout == null) { + state.idleTimeout = setTimeout(onHttp2SessionIdleTimeout, client[kKeepAliveDefaultTimeout], session).unref(); + } + } + function onHttp2SessionIdleTimeout(session) { + const client = session[kClient]; + const socket = session[kSocket]; + const state = session[kHTTP2SessionState]; + state.idleTimeout = null; + if (client[kHTTP2Session] !== session || session[kOpenStreams] !== 0 || client[kSize] !== 0 || session.closed || session.destroyed) { + return; + } + const err = new InformationalError("socket idle timeout"); + socket[kError] = err; + util.destroy(socket, err); + } function applyConnectionWindowSize(connectionWindowSize) { try { if (typeof this.setLocalWindowSize === "function") { @@ -27622,10 +27865,16 @@ var require_client_h22 = __commonJS({ function onHttp2SessionError(err) { assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; + if (this[kReceivedGoAway]) { + return; + } this[kClient][kOnError](err); } function onHttp2FrameError(type, code, id) { if (id === 0) { + if (this[kReceivedGoAway]) { + return; + } const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`); this[kSocket][kError] = err; this[kClient][kOnError](err); @@ -27646,10 +27895,11 @@ var require_client_h22 = __commonJS({ const previousPendingIdx = client[kPendingIdx]; const pendingIdx = getGoAwayPendingIdx(client, lastStreamID); const retriableRequests = []; + const streamsToClose = []; for (let i = pendingIdx; i < previousPendingIdx; i++) { const request = client[kQueue][i]; if (request != null) { - closeRequestStream(request); + streamsToClose.push(detachRequestStreamForClose(request)); if (canRetryRequestAfterGoAway(request)) { retriableRequests.push(request); } else { @@ -27657,6 +27907,9 @@ var require_client_h22 = __commonJS({ } } } + for (let i = 0; i < streamsToClose.length; i++) { + closeStream(streamsToClose[i]); + } if (pendingIdx !== previousPendingIdx) { const remainingPendingRequests = client[kQueue].slice(previousPendingIdx); client[kQueue].length = pendingIdx; @@ -27667,6 +27920,7 @@ var require_client_h22 = __commonJS({ client[kHTTPContext] = null; client[kHTTP2Session] = null; } + clearHttp2IdleTimeout(this); if (!this.closed && !this.destroyed) { this.close(); } @@ -27682,6 +27936,7 @@ var require_client_h22 = __commonJS({ client[kHTTPContext] = null; client[kHTTP2Session] = null; } + clearHttp2IdleTimeout(this); if (state.ping.interval != null) { clearInterval(state.ping.interval); state.ping.interval = null; @@ -27691,7 +27946,9 @@ var require_client_h22 = __commonJS({ const requests = client[kQueue].splice(client[kRunningIdx]); for (let i = 0; i < requests.length; i++) { const request = requests[i]; - util.errorRequest(client, request, err); + if (request != null) { + util.errorRequest(client, request, err); + } } } } @@ -27718,6 +27975,9 @@ var require_client_h22 = __commonJS({ function onHttp2SocketError(err) { assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; + if (this[kHTTP2Session]?.[kReceivedGoAway]) { + return; + } this[kClient][kOnError](err); } function onHttp2SocketEnd() { @@ -27733,7 +27993,8 @@ var require_client_h22 = __commonJS({ stream[kHTTP2Session] = null; session[kOpenStreams] -= 1; if (session[kOpenStreams] === 0) { - session.unref(); + unrefH2Session(session); + setHttp2IdleTimeout(session); } } function onUpgradeStreamClose() { @@ -27744,8 +28005,14 @@ var require_client_h22 = __commonJS({ closeStreamSession(this); } function onRequestStreamClose() { - this.off("data", onData); - this.off("error", noop); + const state = this[kRequestStreamState]; + if (state) { + releaseRequestStream(this); + if (state.pendingEnd && !state.request.aborted && !state.request.completed) { + state.request.onResponseEnd(state.trailers || {}); + finalizeRequest(state); + } + } closeStreamSession(this); this[kRequestStreamState] = null; } @@ -27824,7 +28091,7 @@ var require_client_h22 = __commonJS({ } function onUpgradeStreamTimeout() { const state = this[kRequestStreamState]; - failUpgradeStream(state, new InformationalError(`HTTP/2: "stream timeout after ${state.requestTimeout}"`)); + failUpgradeStream(state, new InformationalError(`HTTP/2: "stream timeout after ${state.headersTimeout}"`)); } function onUpgradeResponse(headers, _flags) { const stream = this; @@ -27839,10 +28106,10 @@ var require_client_h22 = __commonJS({ } removeUpgradeStreamListeners(stream); detachRequestFromStream(request); - state.finalizeRequest(); + finalizeRequest(state); } function setupUpgradeStream(stream, state) { - const { request, requestTimeout, session } = state; + const { request, headersTimeout, session } = state; stream[kHTTP2Stream] = true; stream[kHTTP2Session] = session; stream[kRequestStreamState] = state; @@ -27853,33 +28120,67 @@ var require_client_h22 = __commonJS({ stream.once("end", onUpgradeStreamEnd); stream.on("timeout", onUpgradeStreamTimeout); stream.once("close", onUpgradeStreamClose); + clearHttp2IdleTimeout(session); ++session[kOpenStreams]; - stream.setTimeout(requestTimeout); + stream.setTimeout(headersTimeout); + } + function finalizeRequest(state, resetPendingIdx = false) { + if (state.requestFinalized) { + return; + } + state.requestFinalized = true; + completeRequest(state.client, state.request, resetPendingIdx); + state.client[kResume](); + } + function openStream(client, request, session, abort, headers, options) { + try { + return session.request(headers, options); + } catch (err) { + if (err?.code === "ERR_HTTP2_INVALID_SESSION" || err?.code === "ERR_HTTP2_GOAWAY_SESSION") { + const wrappedErr2 = new SocketError(err.message, util.getSocketInfo(session[kSocket])); + wrappedErr2.cause = err; + session[kError] = wrappedErr2; + resetHttp2Session(session, wrappedErr2); + requeueUnsentRequest(client, request); + return null; + } + const wrappedErr = new InformationalError(err.message, { cause: err }); + session[kError] = wrappedErr; + session[kSocket][kError] = wrappedErr; + session.destroy(wrappedErr); + util.destroy(session[kSocket], wrappedErr); + abort(wrappedErr); + return null; + } } function writeH2(client, request) { - const requestTimeout = request.bodyTimeout ?? client[kBodyTimeout]; + const headersTimeout = request.headersTimeout ?? client[kHeadersTimeout]; + const bodyTimeout = request.bodyTimeout ?? client[kBodyTimeout]; const session = client[kHTTP2Session]; const { method, path, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request; - let { body } = request; if (upgrade != null && upgrade !== "websocket") { util.errorRequest(client, request, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`)); return false; } const headers = buildRequestHeaders(reqHeaders); - let stream = null; headers[HTTP2_HEADER_AUTHORITY] = host || client[kHostAuthority]; headers[HTTP2_HEADER_METHOD] = method; - let requestFinalized = false; - const finalizeRequest = (resetPendingIdx = false) => { - if (requestFinalized) { - return; - } - requestFinalized = true; - client[kQueue][client[kRunningIdx]++] = null; - if (resetPendingIdx) { - client[kPendingIdx] = client[kRunningIdx]; - } - client[kResume](); + const state = { + abort: null, + body: request.body, + client, + contentLength: null, + expectsPayload: false, + request, + headersTimeout, + bodyTimeout, + requestFinalized: false, + responseReceived: false, + bodySent: false, + pendingEnd: false, + trailers: null, + session, + stream: null }; const abort = (err, resetPendingIdx = false) => { if (request.aborted || request.completed) { @@ -27887,30 +28188,22 @@ var require_client_h22 = __commonJS({ } err = err || new RequestAbortedError(); util.errorRequest(client, request, err); - if (stream != null) { + if (state.stream != null) { clearRequestStream(request); - stream.close(); + const stream2 = state.stream; + stream2.close(); + setImmediate(() => { + if (!stream2.destroyed) { + util.destroy(stream2); + } + }); client[kOnError](err); - finalizeRequest(resetPendingIdx); - } - util.destroy(body, err); - }; - const requestStream = (headers2, options) => { - try { - return session.request(headers2, options); - } catch (err) { - if (err?.code !== "ERR_HTTP2_INVALID_CONNECTION_HEADERS") { - throw err; - } - const wrappedErr = new InformationalError(err.message, { cause: err }); - session[kError] = wrappedErr; - session[kSocket][kError] = wrappedErr; - session.destroy(wrappedErr); - util.destroy(session[kSocket], wrappedErr); - abort(wrappedErr); - return null; + finalizeRequest(state, resetPendingIdx); } + util.destroy(state.body, err); }; + state.abort = abort; + let stream = null; try { request.onRequestStart(abort, null); } catch (err) { @@ -27920,20 +28213,11 @@ var require_client_h22 = __commonJS({ return false; } if (upgrade || method === "CONNECT") { - session.ref(); - const upgradeState = { - abort, - finalizeRequest, - request, - requestTimeout, - responseReceived: false, - session, - stream: null - }; + refH2Session(session); if (upgrade === "websocket") { if (session[kEnableConnectProtocol] === false) { util.errorRequest(client, request, new InformationalError("HTTP/2: Extended CONNECT protocol not supported by server")); - session.unref(); + unrefH2Session(session); return false; } headers[HTTP2_HEADER_METHOD] = "CONNECT"; @@ -27944,25 +28228,26 @@ var require_client_h22 = __commonJS({ } else { headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https"; } - stream = requestStream(headers, { endStream: false, signal }); + stream = openStream(client, request, session, abort, headers, { endStream: false, signal }); if (stream == null) { - session.unref(); + unrefH2Session(session); return false; } - setupUpgradeStream(stream, upgradeState); + setupUpgradeStream(stream, state); return true; } - stream = requestStream(headers, { endStream: false, signal }); + stream = openStream(client, request, session, abort, headers, { endStream: false, signal }); if (stream == null) { - session.unref(); + unrefH2Session(session); return false; } - setupUpgradeStream(stream, upgradeState); + setupUpgradeStream(stream, state); return true; } headers[HTTP2_HEADER_PATH] = path; headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https"; const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH"; + let body = state.body; if (body && typeof body.read === "function") { body.read(0); } @@ -27991,7 +28276,7 @@ var require_client_h22 = __commonJS({ assert(body || contentLength === 0, "no body must not have content length"); headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}`; } - session.ref(); + refH2Session(session); if (channels.sendHeaders.hasSubscribers) { let header = ""; for (const key in headers) { @@ -28001,45 +28286,39 @@ var require_client_h22 = __commonJS({ channels.sendHeaders.publish({ request, headers: header, socket: session[kSocket] }); } const shouldEndStream = body === null || contentLength === 0; - const state = { - abort, - body, - client, - contentLength, - expectsPayload, - finalizeRequest, - request, - requestTimeout, - responseReceived: false, - session, - stream: null - }; + state.body = body; + state.contentLength = contentLength; + state.expectsPayload = expectsPayload; if (expectContinue) { headers[HTTP2_HEADER_EXPECT] = "100-continue"; } - stream = requestStream(headers, { endStream: shouldEndStream, signal }); + stream = openStream(client, request, session, abort, headers, { endStream: shouldEndStream, signal }); if (stream == null) { return false; } stream[kHTTP2Stream] = true; stream[kRequestStreamState] = state; state.stream = stream; - bindRequestToStream(request, stream, null); + clearHttp2IdleTimeout(session); ++session[kOpenStreams]; - stream.setTimeout(requestTimeout); + if (headersTimeout) { + stream.setTimeout(headersTimeout); + } stream[kHTTP2Session] = session; - stream.once("close", onRequestStreamClose); + stream.on("close", onRequestStreamClose); bindRequestToStream(request, stream, releaseRequestStream); if (expectContinue) { stream.once("continue", writeBodyH2); } - stream.once("response", onResponse); - stream.once("end", onEnd); - stream.once("error", onError); - stream.once("frameError", onFrameError); + stream.on("response", onResponse); + stream.on("end", onEnd); + stream.on("error", onError); + stream.on("frameError", onFrameError); stream.on("aborted", onAborted); - stream.on("timeout", onTimeout); - stream.once("trailers", onTrailers); + if (headersTimeout || bodyTimeout) { + stream.on("timeout", onTimeout); + } + stream.on("trailers", onTrailers); if (!expectContinue) { writeBodyH2.call(stream); } @@ -28069,14 +28348,18 @@ var require_client_h22 = __commonJS({ if (request[kRequestStream] === stream) { detachRequestFromStream(request); } - removeRequestStreamListeners(stream); if (!stream.destroyed && !stream.closed) { + removeRequestStreamListeners(stream); stream.once("error", noop); } } function onData(chunk) { const stream = this; - const { request } = stream[kRequestStreamState]; + const state = stream[kRequestStreamState]; + if (state == null) { + return; + } + const { request } = state; if (request.aborted || request.completed) { return; } @@ -28087,13 +28370,23 @@ var require_client_h22 = __commonJS({ function onResponse(headers) { const stream = this; const state = stream[kRequestStreamState]; + if (state == null) { + return; + } const { request } = state; stream.off("response", onResponse); + if (state.body != null && !state.bodySent && !stream.writableEnded) { + stream.removeListener("continue", writeBodyH2); + stream.end(); + } const statusCode = headers[HTTP2_HEADER_STATUS]; delete headers[HTTP2_HEADER_STATUS]; request.onResponseStarted(); state.responseReceived = true; - if (request.aborted) { + if (state.headersTimeout || state.bodyTimeout) { + stream.setTimeout(state.bodyTimeout); + } + if (request.aborted || request.completed) { releaseRequestStream(stream); return; } @@ -28105,14 +28398,15 @@ var require_client_h22 = __commonJS({ function onEnd() { const stream = this; const state = stream[kRequestStreamState]; + if (state == null) { + return; + } const { request } = state; stream.off("end", onEnd); - releaseRequestStream(stream); if (state.responseReceived) { if (!request.aborted && !request.completed) { - request.onResponseEnd({}); + state.pendingEnd = true; } - state.finalizeRequest(); } else { state.abort(new InformationalError("HTTP/2: stream half-closed (remote)"), true); } @@ -28120,15 +28414,19 @@ var require_client_h22 = __commonJS({ function onError(err) { const stream = this; const state = stream[kRequestStreamState]; + if (state == null) { + return; + } stream.off("error", onError); - releaseRequestStream(stream); state.abort(err); } function onFrameError(type, code) { const stream = this; const state = stream[kRequestStreamState]; + if (state == null) { + return; + } stream.off("frameError", onFrameError); - releaseRequestStream(stream); state.abort(new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`)); } function onAborted() { @@ -28137,25 +28435,31 @@ var require_client_h22 = __commonJS({ function onTimeout() { const stream = this; const state = stream[kRequestStreamState]; - releaseRequestStream(stream); - const err = new InformationalError(`HTTP/2: "stream timeout after ${state.requestTimeout}"`); + if (state == null) { + return; + } + stream.off("timeout", onTimeout); + const err = state.responseReceived ? new BodyTimeoutError(`HTTP/2: "stream timeout after ${state.bodyTimeout}"`) : new HeadersTimeoutError(`HTTP/2: "headers timeout after ${state.headersTimeout}"`); state.abort(err); } function onTrailers(trailers) { const stream = this; const state = stream[kRequestStreamState]; + if (state == null) { + return; + } const { request } = state; stream.off("trailers", onTrailers); + stream.off("data", onData); if (request.aborted || request.completed) { return; } - releaseRequestStream(stream); - request.onResponseEnd(trailers); - state.finalizeRequest(); + state.trailers = trailers; } function writeBodyH2() { const stream = this; const state = stream[kRequestStreamState]; + state.bodySent = true; const { abort, body, client, contentLength, expectsPayload, request } = state; if (!body || contentLength === 0) { writeBuffer( @@ -28411,6 +28715,12 @@ var require_client2 = __commonJS({ function getPipelining(client) { return client[kPipelining] ?? client[kHTTPContext]?.defaultPipelining ?? 1; } + function getMaxConcurrent(client) { + if (client[kHTTPContext]?.version === "h2") { + return client[kMaxConcurrentStreams]; + } + return getPipelining(client); + } var Client = class extends DispatcherBase { /** * @@ -28601,8 +28911,9 @@ var require_client2 = __commonJS({ return !!this[kHTTPContext] && !this[kConnecting] && !this[kHTTPContext].destroyed; } get [kBusy]() { + const allowsMux = this[kHTTPContext]?.version === "h2"; return Boolean( - this[kHTTPContext]?.busy(null) || this[kSize] >= (getPipelining(this) || 1) || this[kPending] > 0 + this[kHTTPContext]?.busy(null) || this[kSize] >= (getMaxConcurrent(this) || 1) || this[kPending] > 0 && !allowsMux ); } [kConnect](cb) { @@ -28638,7 +28949,9 @@ var require_client2 = __commonJS({ const requests = this[kQueue].splice(this[kPendingIdx]); for (let i = 0; i < requests.length; i++) { const request = requests[i]; - util.errorRequest(this, request, err); + if (request != null) { + util.errorRequest(this, request, err); + } } const callback = () => { if (this[kClosedResolve]) { @@ -28663,7 +28976,9 @@ var require_client2 = __commonJS({ const requests = client[kQueue].splice(client[kRunningIdx]); for (let i = 0; i < requests.length; i++) { const request = requests[i]; - util.errorRequest(client, request, err); + if (request != null) { + util.errorRequest(client, request, err); + } } assert(client[kSize] === 0); } @@ -28771,9 +29086,13 @@ var require_client2 = __commonJS({ }); } if (err.code === "ERR_TLS_CERT_ALTNAME_INVALID") { - assert(client[kRunning] === 0); + const running = client[kQueue].splice(client[kRunningIdx], client[kRunning]); + client[kPendingIdx] = client[kRunningIdx]; + for (let i = 0; i < running.length; i++) { + util.errorRequest(client, running[i], err); + } while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { - const request = client[kQueue][client[kPendingIdx]++]; + const request = client[kQueue].splice(client[kPendingIdx], 1)[0]; util.errorRequest(client, request, err); } } else { @@ -28826,7 +29145,7 @@ var require_client2 = __commonJS({ if (client[kPending] === 0) { return; } - if (client[kRunning] >= (getPipelining(client) || 1)) { + if (client[kRunning] >= (getMaxConcurrent(client) || 1)) { return; } const request = client[kQueue][client[kPendingIdx]]; @@ -30268,6 +30587,7 @@ var require_socks5_proxy_agent = __commonJS({ var kProxyProtocol = /* @__PURE__ */ Symbol("proxy protocol"); var kPools = /* @__PURE__ */ Symbol("pools"); var kConnector = /* @__PURE__ */ Symbol("connector"); + var kRequestTls = /* @__PURE__ */ Symbol("request tls settings"); var experimentalWarningEmitted = false; var Socks5ProxyAgent = class extends DispatcherBase { constructor(proxyUrl, options = {}) { @@ -30289,6 +30609,7 @@ var require_socks5_proxy_agent = __commonJS({ this[kProxyUrl] = url; this[kProxyHeaders] = options.headers || {}; this[kProxyProtocol] = options.proxyTls ? "https:" : "http:"; + this[kRequestTls] = options.requestTls; this[kProxyAuth] = { username: options.username || (url.username ? decodeURIComponent(url.username) : null), password: options.password || (url.password ? decodeURIComponent(url.password) : null) @@ -30396,9 +30717,9 @@ var require_socks5_proxy_agent = __commonJS({ } debug2("upgrading to TLS"); finalSocket = tls.connect({ + ...this[kRequestTls], socket, - servername: targetHost, - ...connectOpts.tls || {} + servername: this[kRequestTls]?.servername || targetHost }); const tlsReady = Promise.withResolvers(); finalSocket.once("secureConnect", tlsReady.resolve); @@ -30457,7 +30778,7 @@ var require_proxy_agent2 = __commonJS({ var Agent = require_agent2(); var Pool = require_pool2(); var DispatcherBase = require_dispatcher_base2(); - var { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError } = require_errors2(); + var { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError, ProxyConnectionError } = require_errors2(); var buildConnector = require_connect2(); var Client = require_client2(); var { channels } = require_diagnostics2(); @@ -30485,14 +30806,19 @@ var require_proxy_agent2 = __commonJS({ } return new Pool(origin, opts); } + function shouldProxyTunnel(requestProtocol, proxyTunnel) { + return proxyTunnel === true || requestProtocol !== "http:"; + } var Http1ProxyWrapper = class extends DispatcherBase { #client; - constructor(proxyUrl, { headers = {}, connect, factory }) { + #proxyServername; + constructor(proxyUrl, { headers = {}, connect, factory, proxyServername }) { if (!proxyUrl) { throw new InvalidArgumentError("Proxy URL is mandatory"); } super(); this[kProxyHeaders] = headers; + this.#proxyServername = proxyServername; if (factory) { this.#client = factory(proxyUrl, { connect }); } else { @@ -30521,6 +30847,9 @@ var require_proxy_agent2 = __commonJS({ headers.host = host; } opts.headers = { ...this[kProxyHeaders], ...headers }; + if (this.#proxyServername != null) { + opts.servername = this.#proxyServername; + } return this.#client[kDispatch](opts, handler); } [kClose]() { @@ -30539,7 +30868,7 @@ var require_proxy_agent2 = __commonJS({ if (typeof clientFactory !== "function") { throw new InvalidArgumentError("Proxy opts.clientFactory must be a function."); } - const { proxyTunnel = true, connectTimeout } = opts; + const { proxyTunnel, connectTimeout } = opts; super(); const url = this.#getUrl(opts); const { href, origin, port, protocol, username, password, hostname: proxyHostname } = url; @@ -30560,6 +30889,7 @@ var require_proxy_agent2 = __commonJS({ this[kProxyHeaders]["proxy-authorization"] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:`).toString("base64")}`; } const connect = buildConnector({ timeout: connectTimeout, ...opts.proxyTls }); + const connectHTTP1 = buildConnector({ timeout: connectTimeout, ...opts.proxyTls, allowH2: false }); this[kConnectEndpoint] = buildConnector({ timeout: connectTimeout, ...opts.requestTls }); this[kConnectEndpointHTTP1] = buildConnector({ timeout: connectTimeout, ...opts.requestTls, allowH2: false }); const agentFactory = opts.factory || defaultAgentFactory; @@ -30572,14 +30902,23 @@ var require_proxy_agent2 = __commonJS({ factory: agentFactory, username: opts.username || username, password: opts.password || password, - proxyTls: opts.proxyTls + proxyTls: opts.proxyTls, + requestTls: opts.requestTls }); } - if (!this[kTunnelProxy] && protocol2 === "http:" && this[kProxy].protocol === "http:") { + if (!shouldProxyTunnel(protocol2, this[kTunnelProxy])) { + const forwardConnect = this[kProxy].protocol === "https:" ? (opts2, cb) => connectHTTP1(opts2, (err, socket) => { + if (err && err.code === "ERR_TLS_CERT_ALTNAME_INVALID") { + cb(new SecureProxyConnectionError(err)); + } else { + cb(err, socket); + } + }) : connectHTTP1; return new Http1ProxyWrapper(this[kProxy].uri, { headers: this[kProxyHeaders], - connect, - factory: agentFactory + connect: forwardConnect, + factory: agentFactory, + proxyServername: this[kProxy].protocol === "https:" ? this[kProxyTls]?.servername || proxyHostname : void 0 }); } return agentFactory(origin2, options); @@ -30641,6 +30980,8 @@ var require_proxy_agent2 = __commonJS({ } catch (err) { if (err.code === "ERR_TLS_CERT_ALTNAME_INVALID") { callback(new SecureProxyConnectionError(err)); + } else if (err.code === "UND_ERR_SOCKET") { + callback(new ProxyConnectionError(err)); } else { callback(err); } @@ -30860,6 +31201,35 @@ var require_retry_handler2 = __commonJS({ const retryTime = new Date(retryAfter).getTime(); return isNaN(retryTime) ? 0 : retryTime - Date.now(); } + var RetryController = class { + constructor() { + this.target = null; + } + pause() { + this.target?.pause(); + } + resume() { + this.target?.resume(); + } + abort(reason) { + this.target?.abort(reason); + } + get paused() { + return this.target?.paused ?? false; + } + get aborted() { + return this.target?.aborted ?? false; + } + get reason() { + return this.target?.reason ?? null; + } + get rawHeaders() { + return this.target?.rawHeaders ?? null; + } + get rawTrailers() { + return this.target?.rawTrailers ?? null; + } + }; var RetryHandler = class _RetryHandler { constructor(opts, { dispatch, handler }) { const { retryOptions, ...dispatchOpts } = opts; @@ -30892,7 +31262,7 @@ var require_retry_handler2 = __commonJS({ timeoutFactor: timeoutFactor ?? 2, maxRetries: maxRetries ?? 5, // What errors we should retry - methods: methods ?? ["GET", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE"], + methods: methods ?? ["GET", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "QUERY"], // Indicates which errors to retry statusCodes: statusCodes ?? [500, 502, 503, 504, 429], // List of errors to retry @@ -30916,12 +31286,13 @@ var require_retry_handler2 = __commonJS({ this.etag = null; this.statusCode = null; this.headers = null; + this.controllerProxy = new RetryController(); } onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err) { if (this.retryOpts.throwOnError) { if (this.retryOpts.statusCodes.includes(statusCode) === false) { this.headersSent = true; - this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage); + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); } else { this.error = err; } @@ -30929,13 +31300,13 @@ var require_retry_handler2 = __commonJS({ } if (isDisturbed(this.opts.body)) { this.headersSent = true; - this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage); + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); return; } function shouldRetry(passedErr) { if (passedErr) { this.headersSent = true; - this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage); + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage); controller.resume(); return; } @@ -30953,12 +31324,13 @@ var require_retry_handler2 = __commonJS({ ); } onRequestStart(controller, context) { + this.controllerProxy.target = controller; if (!this.headersSent) { - this.handler.onRequestStart?.(controller, context); + this.handler.onRequestStart?.(this.controllerProxy, context); } } - onRequestUpgrade(controller, statusCode, headers, socket) { - this.handler.onRequestUpgrade?.(controller, statusCode, headers, socket); + onRequestUpgrade(_controller, statusCode, headers, socket) { + this.handler.onRequestUpgrade?.(this.controllerProxy, statusCode, headers, socket); } static [kRetryHandlerDefaultRetry](err, { state, opts }, cb) { const { statusCode, code, headers } = err; @@ -31043,7 +31415,7 @@ var require_retry_handler2 = __commonJS({ if (range == null) { this.headersSent = true; this.handler.onResponseStart?.( - controller, + this.controllerProxy, statusCode, headers, statusMessage @@ -31075,7 +31447,7 @@ var require_retry_handler2 = __commonJS({ } this.headersSent = true; this.handler.onResponseStart?.( - controller, + this.controllerProxy, statusCode, headers, statusMessage @@ -31087,14 +31459,14 @@ var require_retry_handler2 = __commonJS({ }); } } - onResponseData(controller, chunk) { + onResponseData(_controller, chunk) { if (this.error) { return; } this.start += chunk.length; - this.handler.onResponseData?.(controller, chunk); + this.handler.onResponseData?.(this.controllerProxy, chunk); } - onResponseEnd(controller, trailers) { + onResponseEnd(_controller, trailers) { if (this.error && this.retryOpts.throwOnError) { throw this.error; } @@ -31108,11 +31480,11 @@ var require_retry_handler2 = __commonJS({ } } this.retryCount = 0; - return this.handler.onResponseEnd?.(controller, trailers); + return this.handler.onResponseEnd?.(this.controllerProxy, trailers); } - this.retry(controller); + this.retry(); } - retry(controller) { + retry() { if (this.start !== 0) { const headers = { range: `bytes=${this.start}-${this.end ?? ""}` }; if (this.etag != null) { @@ -31130,20 +31502,20 @@ var require_retry_handler2 = __commonJS({ this.retryCountCheckpoint = this.retryCount; this.dispatch(this.opts, this); } catch (err) { - this.handler.onResponseError?.(controller, err); + this.handler.onResponseError?.(this.controllerProxy, err); } } onResponseError(controller, err) { if (controller?.aborted || isDisturbed(this.opts.body)) { - this.handler.onResponseError?.(controller, err); + this.handler.onResponseError?.(this.controllerProxy, err); return; } function shouldRetry(returnedErr) { if (!returnedErr) { - this.retry(controller); + this.retry(); return; } - this.handler?.onResponseError?.(controller, returnedErr); + this.handler?.onResponseError?.(this.controllerProxy, returnedErr); } if (this.retryCount - this.retryCountCheckpoint > 0) { this.retryCount = this.retryCountCheckpoint + (this.retryCount - this.retryCountCheckpoint); @@ -31260,6 +31632,7 @@ var require_readable2 = __commonJS({ var kContentLength = /* @__PURE__ */ Symbol("kContentLength"); var kUsed = /* @__PURE__ */ Symbol("kUsed"); var kBytesRead = /* @__PURE__ */ Symbol("kBytesRead"); + var kPreservedBuffer = /* @__PURE__ */ Symbol("kPreservedBuffer"); var noop = () => { }; var BodyReadable = class extends Readable2 { @@ -31498,7 +31871,22 @@ var require_readable2 = __commonJS({ */ setEncoding(encoding) { if (Buffer.isEncoding(encoding)) { - this._readableState.encoding = encoding; + const state = this._readableState; + const buffer = state.buffer; + if (buffer && state.length > 0) { + const bufferIndex = state.bufferIndex ?? 0; + const preserved = []; + const source = typeof buffer.slice === "function" ? buffer.slice(bufferIndex) : buffer; + for (const data of source) { + if (Buffer.isBuffer(data)) { + preserved.push(data); + } + } + if (preserved.length > 0) { + this[kPreservedBuffer] = (this[kPreservedBuffer] || []).concat(preserved); + } + } + super.setEncoding(encoding); } return this; } @@ -31548,7 +31936,13 @@ var require_readable2 = __commonJS({ return; } const { _readableState: state } = consume2.stream; - if (state.bufferIndex) { + const preserved = consume2.stream[kPreservedBuffer]; + if (preserved && preserved.length > 0) { + for (const chunk of preserved) { + consumePush(consume2, chunk); + } + consume2.stream[kPreservedBuffer] = null; + } else if (state.bufferIndex) { const start = state.bufferIndex; const end = state.buffer.length; for (let n = start; n < end; n++) { @@ -31619,6 +32013,9 @@ var require_readable2 = __commonJS({ } } function consumePush(consume2, chunk) { + if (consume2.body === null) { + return; + } consume2.length += chunk.length; consume2.body.push(chunk); } @@ -31705,7 +32102,9 @@ var require_api_request2 = __commonJS({ this.removeAbortListener = util.addAbortListener(signal, () => { this.reason = signal.reason ?? new RequestAbortedError(); if (this.res) { - util.destroy(this.res.on("error", noop), this.reason); + const res = this.res; + this.res = null; + util.destroy(res.on("error", noop), this.reason); } else if (this.abort) { this.abort(this.reason); } @@ -33224,7 +33623,7 @@ var require_mock_call_history = __commonJS({ return finalOptions; } function makeFilterCalls(parameterName) { - return (parameterValue, logs) => { + return (parameterValue, logs = this.logs) => { if (typeof parameterValue === "string" || parameterValue == null) { return logs.filter((log) => { return log[parameterName] === parameterValue; @@ -34442,7 +34841,11 @@ var require_snapshot_agent = __commonJS({ * @returns {Promise} */ async close() { - await this[kSnapshotRecorder].close(); + if (this[kSnapshotMode] === "playback") { + this[kSnapshotRecorder].destroy(); + } else { + await this[kSnapshotRecorder].close(); + } await this[kRealAgent]?.close(); await super.close(); } @@ -34589,9 +34992,11 @@ var require_redirect_handler2 = __commonJS({ } this.dispatch = dispatch; this.location = null; - const { maxRedirections: _, ...cleanOpts } = opts; + const { maxRedirections: _, stripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect, ...cleanOpts } = opts; this.opts = cleanOpts; this.opts.body = util.wrapRequestBody(this.opts.body); + this.stripHeadersOnRedirect = normalizeStripHeaders(stripHeadersOnRedirect, "stripHeadersOnRedirect"); + this.stripHeadersOnCrossOriginRedirect = normalizeStripHeaders(stripHeadersOnCrossOriginRedirect, "stripHeadersOnCrossOriginRedirect"); this.maxRedirections = maxRedirections; this.handler = handler; this.history = []; @@ -34636,7 +35041,7 @@ var require_redirect_handler2 = __commonJS({ throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. 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, statusCode === 303, this.opts.origin !== origin); + this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect); this.opts.path = path; this.opts.origin = origin; this.opts.query = null; @@ -34658,31 +35063,50 @@ var require_redirect_handler2 = __commonJS({ this.handler.onResponseError?.(controller, error2); } }; - function shouldRemoveHeader(header, removeContent, unknownOrigin) { - if (header.length === 4) { - return util.headerNameToString(header) === "host"; - } - if (removeContent && util.headerNameToString(header).startsWith("content-")) { + function shouldRemoveHeader(header, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin) { + const name = util.headerNameToString(header); + if (name === "host") { return true; } - if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) { - const name = util.headerNameToString(header); + if (stripHeaders?.has(name) || unknownOrigin && stripHeadersOnCrossOrigin?.has(name)) { + return true; + } + if (removeContent && name.startsWith("content-")) { + return true; + } + if (unknownOrigin) { return name === "authorization" || name === "cookie" || name === "proxy-authorization"; } return false; } - function cleanRequestHeaders(headers, removeContent, unknownOrigin) { + function normalizeStripHeaders(headers, optionName) { + if (headers == null) { + return null; + } + if (!Array.isArray(headers)) { + throw new InvalidArgumentError(`${optionName} must be an array`); + } + const normalized = /* @__PURE__ */ new Set(); + for (const header of headers) { + if (typeof header !== "string") { + throw new InvalidArgumentError(`${optionName} must contain header names`); + } + normalized.add(util.headerNameToString(header)); + } + return normalized; + } + function cleanRequestHeaders(headers, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin) { const ret = []; if (Array.isArray(headers)) { for (let i = 0; i < headers.length; i += 2) { - if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { + if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin)) { ret.push(headers[i], headers[i + 1]); } } } else if (headers && typeof headers === "object") { const entries = util.hasSafeIterator(headers) ? headers : Object.entries(headers); for (const [key, value] of entries) { - if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { + if (!shouldRemoveHeader(key, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin)) { ret.push(key, value); } } @@ -34700,14 +35124,14 @@ var require_redirect2 = __commonJS({ "node_modules/undici/lib/interceptor/redirect.js"(exports2, module2) { "use strict"; var RedirectHandler = require_redirect_handler2(); - function createRedirectInterceptor({ maxRedirections: defaultMaxRedirections, throwOnMaxRedirect: defaultThrowOnMaxRedirect } = {}) { + function createRedirectInterceptor({ maxRedirections: defaultMaxRedirections, throwOnMaxRedirect: defaultThrowOnMaxRedirect, stripHeadersOnRedirect: defaultStripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect: defaultStripHeadersOnCrossOriginRedirect } = {}) { return (dispatch) => { return function Intercept(opts, handler) { - const { maxRedirections = defaultMaxRedirections, throwOnMaxRedirect = defaultThrowOnMaxRedirect, ...rest } = opts; + const { maxRedirections = defaultMaxRedirections, throwOnMaxRedirect = defaultThrowOnMaxRedirect, stripHeadersOnRedirect = defaultStripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect = defaultStripHeadersOnCrossOriginRedirect, ...rest } = opts; if (maxRedirections == null || maxRedirections === 0) { return dispatch(opts, handler); } - const dispatchOpts = { ...rest, throwOnMaxRedirect }; + const dispatchOpts = { ...rest, throwOnMaxRedirect, stripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect }; const redirectHandler = new RedirectHandler(dispatch, maxRedirections, dispatchOpts, handler); return dispatch(dispatchOpts, redirectHandler); }; @@ -35318,6 +35742,9 @@ var require_dns2 = __commonJS({ const instance = new DNSInstance(opts); return (dispatch) => { return function dnsInterceptor(origDispatchOpts, handler) { + if (origDispatchOpts.origin == null) { + return dispatch(origDispatchOpts, handler); + } const origin = origDispatchOpts.origin.constructor === URL ? origDispatchOpts.origin : new URL(origDispatchOpts.origin); if (isIP(origin.hostname) !== 0) { return dispatch(origDispatchOpts, handler); @@ -35503,6 +35930,9 @@ var require_cache2 = __commonJS({ lastHeader = lastHeader.substring(0, lastHeader.length - 1); headers[headers.length - 1] = lastHeader; } + for (let j = 0; j < headers.length; j++) { + headers[j] = headers[j].trim(); + } if (key in output) { output[key] = output[key].concat(headers); } else { @@ -35510,10 +35940,11 @@ var require_cache2 = __commonJS({ } } } else { + const fieldName = value.trim(); if (key in output) { - output[key] = output[key].concat(value); + output[key] = output[key].concat(fieldName); } else { - output[key] = [value]; + output[key] = [fieldName]; } } break; @@ -39101,6 +39532,12 @@ var require_request4 = __commonJS({ /** @type {Headers} */ #headers; #state; + /** + * Removes the `abort` listener that makes this request's signal follow the + * passed signal. `null` when no such listener was registered. + * @type {(() => void) | null} + */ + #abortCleanup = null; // https://fetch.spec.whatwg.org/#dom-request constructor(input, init = void 0) { webidl.util.markAsUncloneable(this); @@ -39298,8 +39735,13 @@ var require_request4 = __commonJS({ if (abortSignalHasEventHandlerLeakWarning && getMaxListeners(signal) === defaultMaxListeners) { setMaxListeners(1500, signal); } - util.addAbortListener(signal, abort); + const removeAbortListener = util.addAbortListener(signal, abort); requestFinalizer.register(ac, { signal, abort }, abort); + this.#abortCleanup = () => { + requestFinalizer.unregister(abort); + removeAbortListener(); + this.#abortCleanup = null; + }; } } this.#headers = new Headers2(kConstruct); @@ -39578,14 +40020,23 @@ var require_request4 = __commonJS({ static setRequestState(request, newState) { request.#state = newState; } + /** + * 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 } = Request; + 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); function makeRequest(init) { return { @@ -39608,6 +40059,7 @@ var require_request4 = __commonJS({ referrerPolicy: init.referrerPolicy ?? "", mode: init.mode ?? "no-cors", useCORSPreflightFlag: init.useCORSPreflightFlag ?? false, + // TODO: is this credentials mode? https://fetch.spec.whatwg.org/#concept-request-credentials-mode credentials: init.credentials ?? "same-origin", useCredentials: init.useCredentials ?? false, cache: init.cache ?? "default", @@ -39779,7 +40231,8 @@ var require_request4 = __commonJS({ fromInnerRequest, cloneRequest, getRequestDispatcher, - getRequestState + getRequestState, + removeRequestAbortListener }; } }); @@ -39936,7 +40389,7 @@ var require_fetch2 = __commonJS({ getResponseState } = require_response2(); var { HeadersList } = require_headers2(); - var { Request, cloneRequest, getRequestDispatcher, getRequestState } = require_request4(); + var { Request, cloneRequest, getRequestDispatcher, getRequestState, removeRequestAbortListener } = require_request4(); var zlib = require("node:zlib"); var { makePolicyContainer, @@ -40073,7 +40526,7 @@ var require_fetch2 = __commonJS({ let responseObject = null; let locallyAborted = false; let controller = null; - addAbortListener( + const removeAbortListener = addAbortListener( requestObject.signal, () => { locallyAborted = true; @@ -40083,16 +40536,22 @@ var require_fetch2 = __commonJS({ abortFetch(p, request, realResponse, requestObject.signal.reason, controller.controller); } ); + const cleanupAbortListeners = () => { + removeAbortListener(); + removeRequestAbortListener(requestObject); + }; const processResponse = (response) => { if (locallyAborted) { return; } if (response.aborted) { abortFetch(p, request, responseObject, controller.serializedAbortReason, controller.controller); + cleanupAbortListeners(); return; } if (response.type === "error") { p.reject(new TypeError("fetch failed", { cause: response.error })); + cleanupAbortListeners(); return; } responseObject = new WeakRef(fromInnerResponse(response, "immutable")); @@ -40101,7 +40560,10 @@ var require_fetch2 = __commonJS({ }; controller = fetching({ request, - processResponseEndOfBody: handleFetchDone, + processResponseEndOfBody: (response) => { + handleFetchDone(response); + cleanupAbortListeners(); + }, processResponse, dispatcher: getRequestDispatcher(requestObject), // undici @@ -40600,7 +41062,12 @@ var require_fetch2 = __commonJS({ httpFetchParams = fetchParams; httpRequest = request; } else { - httpRequest = cloneRequest(request); + if (request.body?.source != null) { + httpRequest = cloneRequest(request); + } else { + httpRequest = cloneRequest({ ...request, body: null }); + httpRequest.body = request.body; + } httpFetchParams = { ...fetchParams }; httpFetchParams.request = httpRequest; } @@ -40645,7 +41112,7 @@ var require_fetch2 = __commonJS({ } if (!httpRequest.headersList.contains("accept-encoding", true)) { if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { - httpRequest.headersList.append("accept-encoding", "br, gzip, deflate", true); + httpRequest.headersList.append("accept-encoding", "br, gzip, deflate, zstd", true); } else { httpRequest.headersList.append("accept-encoding", "gzip, deflate", true); } @@ -41823,7 +42290,7 @@ var require_util12 = __commonJS({ for (let i = 0; i < path.length; ++i) { const code = path.charCodeAt(i); if (code < 32 || // exclude CTLs (0-31) - code === 127 || // DEL + code > 126 || // exclude non-ascii and DEL code === 59) { throw new Error("Invalid cookie path"); } @@ -41936,7 +42403,6 @@ var require_parse2 = __commonJS({ var { maxNameValuePairSize, maxAttributeValueSize } = require_constants9(); var { isCTLExcludingHtab } = require_util12(); var assert = require("node:assert"); - var { unescape: qsUnescape } = require("node:querystring"); function parseSetCookie(header) { if (isCTLExcludingHtab(header)) { return null; @@ -41970,7 +42436,7 @@ var require_parse2 = __commonJS({ } return { name, - value: qsUnescape(value), + value, ...parseUnparsedAttributes(unparsedAttributes) }; } @@ -42013,7 +42479,9 @@ var require_parse2 = __commonJS({ const attributeNameLowercase = attributeName.toLowerCase(); if (attributeNameLowercase === "expires") { const expiryTime = new Date(attributeValue); - cookieAttributeList.expires = expiryTime; + 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] !== "-") { @@ -42044,18 +42512,14 @@ var require_parse2 = __commonJS({ } else if (attributeNameLowercase === "httponly") { cookieAttributeList.httpOnly = true; } else if (attributeNameLowercase === "samesite") { - let enforcement = "Default"; const attributeValueLowercase = attributeValue.toLowerCase(); - if (attributeValueLowercase.includes("none")) { - enforcement = "None"; + if (attributeValueLowercase === "none") { + cookieAttributeList.sameSite = "None"; + } else if (attributeValueLowercase === "strict") { + cookieAttributeList.sameSite = "Strict"; + } else if (attributeValueLowercase === "lax") { + cookieAttributeList.sameSite = "Lax"; } - if (attributeValueLowercase.includes("strict")) { - enforcement = "Strict"; - } - if (attributeValueLowercase.includes("lax")) { - enforcement = "Lax"; - } - cookieAttributeList.sameSite = enforcement; } else { cookieAttributeList.unparsed ??= []; cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`); @@ -43075,6 +43539,8 @@ var require_receiver2 = __commonJS({ /** @type {import('./websocket').Handler} */ #handler; /** @type {number} */ + #maxFragments; + /** @type {number} */ #maxPayloadSize; /** * @param {import('./websocket').Handler} handler @@ -43085,6 +43551,7 @@ var require_receiver2 = __commonJS({ super(); this.#handler = handler; this.#extensions = extensions == null ? /* @__PURE__ */ new Map() : extensions; + this.#maxFragments = options.maxFragments ?? 0; this.#maxPayloadSize = options.maxPayloadSize ?? 0; if (this.#extensions.has("permessage-deflate")) { this.#extensions.set("permessage-deflate", new PerMessageDeflate(extensions, options)); @@ -43101,7 +43568,7 @@ var require_receiver2 = __commonJS({ this.run(callback); } #validatePayloadLength() { - if (this.#maxPayloadSize > 0 && !isControlFrame(this.#info.opcode) && this.#info.payloadLength > this.#maxPayloadSize) { + if (this.#maxPayloadSize > 0 && !isControlFrame(this.#info.opcode) && this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize) { failWebsocketConnection(this.#handler, 1009, "Payload size exceeds maximum allowed size"); return false; } @@ -43218,7 +43685,9 @@ var require_receiver2 = __commonJS({ this.#state = parserStates.INFO; } else { if (!this.#info.compressed) { - this.writeFragments(body); + if (!this.writeFragments(body)) { + return; + } if (!this.#info.fragmented && this.#info.fin) { websocketMessageReceived(this.#handler, this.#info.binaryType, this.consumeFragments()); } @@ -43233,7 +43702,9 @@ var require_receiver2 = __commonJS({ failWebsocketConnection(this.#handler, code, error2.message); return; } - this.writeFragments(data); + if (!this.writeFragments(data)) { + return; + } if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) { failWebsocketConnection(this.#handler, 1009, new MessageSizeExceededError().message); return; @@ -43298,8 +43769,13 @@ var require_receiver2 = __commonJS({ } } writeFragments(fragment) { + if (this.#maxFragments > 0 && this.#fragments.length === this.#maxFragments) { + failWebsocketConnection(this.#handler, 1008, "Too many message fragments"); + return false; + } this.#fragmentsBytes += fragment.length; this.#fragments.push(fragment); + return true; } consumeFragments() { const fragments = this.#fragments; @@ -43766,8 +44242,10 @@ var require_websocket2 = __commonJS({ */ #onConnectionEstablished(response, parsedExtensions) { this.#handler.socket = response.socket; + const maxFragments = this.#handler.controller.dispatcher?.webSocketOptions?.maxFragments; const maxPayloadSize = this.#handler.controller.dispatcher?.webSocketOptions?.maxPayloadSize; const parser = new ByteParser(this.#handler, parsedExtensions, { + maxFragments, maxPayloadSize }); parser.on("drain", () => this.#handler.onParserDrain()); @@ -44213,7 +44691,12 @@ var require_websocketstream = __commonJS({ /** @type {import('../websocket').Handler['onConnectionEstablished']} */ #onConnectionEstablished(response, parsedExtensions) { this.#handler.socket = response.socket; - const parser = new ByteParser(this.#handler, parsedExtensions); + const maxFragments = this.#handler.controller.dispatcher?.webSocketOptions?.maxFragments; + const maxPayloadSize = this.#handler.controller.dispatcher?.webSocketOptions?.maxPayloadSize; + const parser = new ByteParser(this.#handler, parsedExtensions, { + maxFragments, + maxPayloadSize + }); parser.on("drain", () => this.#handler.onParserDrain()); parser.on("error", (err) => this.#handler.onParserError(err)); this.#parser = parser; @@ -44353,6 +44836,7 @@ var require_websocketstream = __commonJS({ var require_util14 = __commonJS({ "node_modules/undici/lib/web/eventsource/util.js"(exports2, module2) { "use strict"; + var { makeRequest } = require_request4(); function isValidLastEventId(value) { return value.indexOf("\0") === -1; } @@ -44363,9 +44847,27 @@ var require_util14 = __commonJS({ } return true; } + function createPotentialCORSRequest(url, destination, corsAttributeState, sameOriginFallback) { + let mode = corsAttributeState === "no cors" ? "no-cors" : "cors"; + if (sameOriginFallback && mode === "no-cors") { + mode = "same-origin"; + } + let credentialsMode = "include"; + if (corsAttributeState === "anonymous") { + credentialsMode = "same-origin"; + } + return makeRequest({ + urlList: [url], + destination, + mode, + credentials: credentialsMode, + useURLCredentials: true + }); + } module2.exports = { isValidLastEventId, - isASCIINumber + isASCIINumber, + createPotentialCORSRequest }; } }); @@ -44717,7 +45219,6 @@ var require_eventsource2 = __commonJS({ "use strict"; var { pipeline } = require("node:stream"); var { fetching } = require_fetch2(); - var { makeRequest } = require_request4(); var { webidl } = require_webidl2(); var { EventSourceStream } = require_eventsource_stream2(); var { parseMIMEType } = require_data_url2(); @@ -44725,6 +45226,7 @@ var require_eventsource2 = __commonJS({ var { isNetworkError } = require_response2(); var { kEnumerableProperty } = require_util9(); var { environmentSettingsObject } = require_util10(); + var { createPotentialCORSRequest } = require_util14(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -44789,20 +45291,12 @@ var require_eventsource2 = __commonJS({ corsAttributeState = USE_CREDENTIALS; this.#withCredentials = true; } - const initRequest = { - redirect: "follow", - keepalive: true, - // @see https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes - mode: "cors", - credentials: corsAttributeState === "anonymous" ? "same-origin" : "omit", - referrer: "no-referrer" - }; - initRequest.client = environmentSettingsObject.settingsObject; - initRequest.headersList = [["accept", { name: "accept", value: "text/event-stream" }]]; - initRequest.cache = "no-store"; - initRequest.initiator = "other"; - initRequest.urlList = [new URL(this.#url)]; - this.#request = makeRequest(initRequest); + const request = createPotentialCORSRequest(urlRecord, "", corsAttributeState); + request.client = environmentSettingsObject.settingsObject; + request.headersList.set("Accept", "text/event-stream"); + request.cache = "no-store"; + request.initiator = "other"; + this.#request = request; this.#connect(); } /** diff --git a/package-lock.json b/package-lock.json index 7ecbd6a..5ebc14e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@actions/cache": "^6.1.0", + "@actions/cache": "^6.2.0", "@actions/core": "^3.0.0", "@actions/exec": "^3.0.0", "@actions/glob": "^0.6.1", @@ -17,10 +17,10 @@ "@actions/tool-cache": "^4.0.0", "@renovatebot/pep440": "^5.0.0", "smol-toml": "^1.7.0", - "undici": "^8.3.0" + "undici": "^8.7.0" }, "devDependencies": { - "@biomejs/biome": "^2.5.1", + "@biomejs/biome": "^2.5.4", "@types/js-yaml": "^4.0.9", "@types/node": "^26.1.1", "@types/semver": "^7.7.1", @@ -33,9 +33,9 @@ } }, "node_modules/@actions/cache": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-6.1.0.tgz", - "integrity": "sha512-LVqybSbzhBp2uAETOQ3HnVjXA4AcjavgMH+LCr+cjgO+PZfciv/1QAgoW+esXBaAhvDid+vXeV70GGJpAh4V5Q==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-6.2.0.tgz", + "integrity": "sha512-Nv0xWRmbxfDbAn/70flO/F6tj2Nv4XTYMAsQHiDFSojCDfso/Zni+fRKa14ToI9hnmOW/rQcY1WYb6wsM7Pgwg==", "license": "MIT", "dependencies": { "@actions/core": "^3.0.1", @@ -863,9 +863,9 @@ "license": "MIT" }, "node_modules/@biomejs/biome": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.1.tgz", - "integrity": "sha512-IXWLCxKmae+rI7LOHS1B3EbVisQ6GRAWbhN9msa6KjNCyFWrvKZWR4oUdinaNssrV852OrSHuSPa95h1GPJc7Q==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.4.tgz", + "integrity": "sha512-xy5FNE5kQJKyK5MR1gJy6ztXYx4WBAbYGlK04lMEgmyPRWKybY9NFwiG9yo0XdzOU8Xvhj41u034J1ywfoWfMw==", "dev": true, "license": "MIT OR Apache-2.0", "bin": { @@ -879,20 +879,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "2.5.1", - "@biomejs/cli-darwin-x64": "2.5.1", - "@biomejs/cli-linux-arm64": "2.5.1", - "@biomejs/cli-linux-arm64-musl": "2.5.1", - "@biomejs/cli-linux-x64": "2.5.1", - "@biomejs/cli-linux-x64-musl": "2.5.1", - "@biomejs/cli-win32-arm64": "2.5.1", - "@biomejs/cli-win32-x64": "2.5.1" + "@biomejs/cli-darwin-arm64": "2.5.4", + "@biomejs/cli-darwin-x64": "2.5.4", + "@biomejs/cli-linux-arm64": "2.5.4", + "@biomejs/cli-linux-arm64-musl": "2.5.4", + "@biomejs/cli-linux-x64": "2.5.4", + "@biomejs/cli-linux-x64-musl": "2.5.4", + "@biomejs/cli-win32-arm64": "2.5.4", + "@biomejs/cli-win32-x64": "2.5.4" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-npqDzvqv7vFaWRiNN1Te71siRgPaqS9MpqgYCdP/CrUbkJ7ApezaeaKjueKHRN/JH/6lRjJQAHi8acQDCAz22w==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.4.tgz", + "integrity": "sha512-4o3NFRobXHynkgcFVrlZsoDAFtF2ldlEGN8sORSws5ZQqyY4PXnPUIylu4ksfyHuwkfvDREuWh3JK+niRwGq3w==", "cpu": [ "arm64" ], @@ -907,9 +907,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.1.tgz", - "integrity": "sha512-RgwTqPAM8g2tn1j+b5oRjF/DbSBX8a4gwojtuG9XuhfK7GgomvZ9+T+tqjXiVbjLEeGJOoL6VEk8mvRTVeSybw==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.4.tgz", + "integrity": "sha512-D32P5HkU2Y6PySuC/WsVDTOgsDwVFmujzhhhOQjajtATpVWFDXuVd3oRbsWNSEA+aaFzyzZm22szsyydBYlSyQ==", "cpu": [ "x64" ], @@ -924,9 +924,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.1.tgz", - "integrity": "sha512-yhV35CzZh38VyMvTEXi3JTjxZBs++oCKK9KG8vB6VI5+uvQvZNR3BFWEKKzuOmx9DJJj7sQpZ4LQJcmbGTs3+Q==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.4.tgz", + "integrity": "sha512-pSEfW7B8kTsXUjUxC1xVVK+y85Ht3C5XxZ9gclmC7/3Ku9Vqz8jmI7k0p/BNIjQ6t4sFERI2sFeH73ybiZl6YQ==", "cpu": [ "arm64" ], @@ -941,9 +941,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-WMcvMLgByyTqVxGlq918NBBYliq9FRR9GAQVETHb+VjGVqXCZFfHlZHC1FX4ibuYY/Hg6TJE3rHU0xVrdJXNRw==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.4.tgz", + "integrity": "sha512-Rpm5/AT1m+DlJmUoYvS4/vXc+0tXJPJ2NQz25TGPyHVF5JrWy75PE0GH6kVxsKtQDuCH4OgzquZq0R4kj/wCVg==", "cpu": [ "arm64" ], @@ -958,9 +958,9 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.1.tgz", - "integrity": "sha512-J/7uHSX7NfoYDI7HijAkd8lnQIOrRb2W7j3X+tw4R+N5ExvXGsyXFiGdQcfcxfOmNQmZVSQOCDk757fwpzqQcg==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.4.tgz", + "integrity": "sha512-FNxojWJkL7EajAuzBgoLe0T2G0y112M4lBrDIFl/DomFTx8yqenYOIdsRLNXvOvBBofE8hJi85LjzLmBDpY7/Q==", "cpu": [ "x64" ], @@ -975,9 +975,9 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-ANTowtlLmPYm5yeMckWY8Xzb9Ix+JJP3tgHR/n6xRj1VWyIzzWtfRfih9hv9VmClwadpBvZduISZIbBsIlYG3A==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.4.tgz", + "integrity": "sha512-aby/PohmmgbShcHqFsZVzG8H6D98+P+A6xRWRrQcLW1pCjabcov5UUlke4UqNQBYTkDQav+jB4zyyDDeKB2GaA==", "cpu": [ "x64" ], @@ -992,9 +992,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.1.tgz", - "integrity": "sha512-zgXnKNgWPC4iPF7Y1lR3STUeCUuZRpD6IiOrC7TZTlh0Lx6FiVUT05myuMQHQ9D+1cc7uyMldi4forE6lp0ivQ==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.4.tgz", + "integrity": "sha512-emoXexPZIPAZkz2RKmA95WJUqK3I5MJNYtwEbL5ESciRzhmFMMyekDhNG8hpeOaK+ZGRDxAU4wvGuA5IHQ0h0w==", "cpu": [ "arm64" ], @@ -1009,9 +1009,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.1.tgz", - "integrity": "sha512-6uxpR9hvaglANkZemeSiN/FhYgkGasrEGn267eXIWvjrjJ2LhDlk251IhjVJq6MXzkV2/bcXwLwSroLyPtqRZg==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.4.tgz", + "integrity": "sha512-U1jaluLw1qQc2Tx7/CeSoL9N5XcqIH+GWjpUAy1ouB5nVjSCMNO+NNHdY3RAs8zxNurLWAdj6pehQdCA2zyU+Q==", "cpu": [ "x64" ], @@ -5436,9 +5436,9 @@ } }, "node_modules/undici": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-8.3.0.tgz", - "integrity": "sha512-TkUDgb6tl7KOGZ+7e8E3d2FYgUQgF6z5YypqjWmixVQSQERFcVrVg0ySADm2LVLRh5ljAaHTCR5Fmz3Q34rB7Q==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.7.0.tgz", + "integrity": "sha512-N7iQtfyLhIMOFgQubvmLV26svHpO0bqKnAiWotTQCVKCmWrcGbBotPuW1x+xwYZ2VHdSTVUfPQQnlEt1/LouTQ==", "license": "MIT", "engines": { "node": ">=22.19.0" @@ -5789,9 +5789,9 @@ }, "dependencies": { "@actions/cache": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-6.1.0.tgz", - "integrity": "sha512-LVqybSbzhBp2uAETOQ3HnVjXA4AcjavgMH+LCr+cjgO+PZfciv/1QAgoW+esXBaAhvDid+vXeV70GGJpAh4V5Q==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-6.2.0.tgz", + "integrity": "sha512-Nv0xWRmbxfDbAn/70flO/F6tj2Nv4XTYMAsQHiDFSojCDfso/Zni+fRKa14ToI9hnmOW/rQcY1WYb6wsM7Pgwg==", "requires": { "@actions/core": "^3.0.1", "@actions/exec": "^3.0.0", @@ -6377,74 +6377,74 @@ "dev": true }, "@biomejs/biome": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.1.tgz", - "integrity": "sha512-IXWLCxKmae+rI7LOHS1B3EbVisQ6GRAWbhN9msa6KjNCyFWrvKZWR4oUdinaNssrV852OrSHuSPa95h1GPJc7Q==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.4.tgz", + "integrity": "sha512-xy5FNE5kQJKyK5MR1gJy6ztXYx4WBAbYGlK04lMEgmyPRWKybY9NFwiG9yo0XdzOU8Xvhj41u034J1ywfoWfMw==", "dev": true, "requires": { - "@biomejs/cli-darwin-arm64": "2.5.1", - "@biomejs/cli-darwin-x64": "2.5.1", - "@biomejs/cli-linux-arm64": "2.5.1", - "@biomejs/cli-linux-arm64-musl": "2.5.1", - "@biomejs/cli-linux-x64": "2.5.1", - "@biomejs/cli-linux-x64-musl": "2.5.1", - "@biomejs/cli-win32-arm64": "2.5.1", - "@biomejs/cli-win32-x64": "2.5.1" + "@biomejs/cli-darwin-arm64": "2.5.4", + "@biomejs/cli-darwin-x64": "2.5.4", + "@biomejs/cli-linux-arm64": "2.5.4", + "@biomejs/cli-linux-arm64-musl": "2.5.4", + "@biomejs/cli-linux-x64": "2.5.4", + "@biomejs/cli-linux-x64-musl": "2.5.4", + "@biomejs/cli-win32-arm64": "2.5.4", + "@biomejs/cli-win32-x64": "2.5.4" } }, "@biomejs/cli-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-npqDzvqv7vFaWRiNN1Te71siRgPaqS9MpqgYCdP/CrUbkJ7ApezaeaKjueKHRN/JH/6lRjJQAHi8acQDCAz22w==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.4.tgz", + "integrity": "sha512-4o3NFRobXHynkgcFVrlZsoDAFtF2ldlEGN8sORSws5ZQqyY4PXnPUIylu4ksfyHuwkfvDREuWh3JK+niRwGq3w==", "dev": true, "optional": true }, "@biomejs/cli-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.1.tgz", - "integrity": "sha512-RgwTqPAM8g2tn1j+b5oRjF/DbSBX8a4gwojtuG9XuhfK7GgomvZ9+T+tqjXiVbjLEeGJOoL6VEk8mvRTVeSybw==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.4.tgz", + "integrity": "sha512-D32P5HkU2Y6PySuC/WsVDTOgsDwVFmujzhhhOQjajtATpVWFDXuVd3oRbsWNSEA+aaFzyzZm22szsyydBYlSyQ==", "dev": true, "optional": true }, "@biomejs/cli-linux-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.1.tgz", - "integrity": "sha512-yhV35CzZh38VyMvTEXi3JTjxZBs++oCKK9KG8vB6VI5+uvQvZNR3BFWEKKzuOmx9DJJj7sQpZ4LQJcmbGTs3+Q==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.4.tgz", + "integrity": "sha512-pSEfW7B8kTsXUjUxC1xVVK+y85Ht3C5XxZ9gclmC7/3Ku9Vqz8jmI7k0p/BNIjQ6t4sFERI2sFeH73ybiZl6YQ==", "dev": true, "optional": true }, "@biomejs/cli-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-WMcvMLgByyTqVxGlq918NBBYliq9FRR9GAQVETHb+VjGVqXCZFfHlZHC1FX4ibuYY/Hg6TJE3rHU0xVrdJXNRw==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.4.tgz", + "integrity": "sha512-Rpm5/AT1m+DlJmUoYvS4/vXc+0tXJPJ2NQz25TGPyHVF5JrWy75PE0GH6kVxsKtQDuCH4OgzquZq0R4kj/wCVg==", "dev": true, "optional": true }, "@biomejs/cli-linux-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.1.tgz", - "integrity": "sha512-J/7uHSX7NfoYDI7HijAkd8lnQIOrRb2W7j3X+tw4R+N5ExvXGsyXFiGdQcfcxfOmNQmZVSQOCDk757fwpzqQcg==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.4.tgz", + "integrity": "sha512-FNxojWJkL7EajAuzBgoLe0T2G0y112M4lBrDIFl/DomFTx8yqenYOIdsRLNXvOvBBofE8hJi85LjzLmBDpY7/Q==", "dev": true, "optional": true }, "@biomejs/cli-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-ANTowtlLmPYm5yeMckWY8Xzb9Ix+JJP3tgHR/n6xRj1VWyIzzWtfRfih9hv9VmClwadpBvZduISZIbBsIlYG3A==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.4.tgz", + "integrity": "sha512-aby/PohmmgbShcHqFsZVzG8H6D98+P+A6xRWRrQcLW1pCjabcov5UUlke4UqNQBYTkDQav+jB4zyyDDeKB2GaA==", "dev": true, "optional": true }, "@biomejs/cli-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.1.tgz", - "integrity": "sha512-zgXnKNgWPC4iPF7Y1lR3STUeCUuZRpD6IiOrC7TZTlh0Lx6FiVUT05myuMQHQ9D+1cc7uyMldi4forE6lp0ivQ==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.4.tgz", + "integrity": "sha512-emoXexPZIPAZkz2RKmA95WJUqK3I5MJNYtwEbL5ESciRzhmFMMyekDhNG8hpeOaK+ZGRDxAU4wvGuA5IHQ0h0w==", "dev": true, "optional": true }, "@biomejs/cli-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.1.tgz", - "integrity": "sha512-6uxpR9hvaglANkZemeSiN/FhYgkGasrEGn267eXIWvjrjJ2LhDlk251IhjVJq6MXzkV2/bcXwLwSroLyPtqRZg==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.4.tgz", + "integrity": "sha512-U1jaluLw1qQc2Tx7/CeSoL9N5XcqIH+GWjpUAy1ouB5nVjSCMNO+NNHdY3RAs8zxNurLWAdj6pehQdCA2zyU+Q==", "dev": true, "optional": true }, @@ -9303,9 +9303,9 @@ "optional": true }, "undici": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-8.3.0.tgz", - "integrity": "sha512-TkUDgb6tl7KOGZ+7e8E3d2FYgUQgF6z5YypqjWmixVQSQERFcVrVg0ySADm2LVLRh5ljAaHTCR5Fmz3Q34rB7Q==" + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.7.0.tgz", + "integrity": "sha512-N7iQtfyLhIMOFgQubvmLV26svHpO0bqKnAiWotTQCVKCmWrcGbBotPuW1x+xwYZ2VHdSTVUfPQQnlEt1/LouTQ==" }, "undici-types": { "version": "8.3.0", diff --git a/package.json b/package.json index 90858bb..b270a32 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "author": "@eifinger", "license": "MIT", "dependencies": { - "@actions/cache": "^6.1.0", + "@actions/cache": "^6.2.0", "@actions/core": "^3.0.0", "@actions/exec": "^3.0.0", "@actions/glob": "^0.6.1", @@ -36,10 +36,10 @@ "@actions/tool-cache": "^4.0.0", "@renovatebot/pep440": "^5.0.0", "smol-toml": "^1.7.0", - "undici": "^8.3.0" + "undici": "^8.7.0" }, "devDependencies": { - "@biomejs/biome": "^2.5.1", + "@biomejs/biome": "^2.5.4", "@types/js-yaml": "^4.0.9", "@types/node": "^26.1.1", "@types/semver": "^7.7.1",