diff --git a/deps/undici/src/README.md b/deps/undici/src/README.md index 72c32de1346621..476c0280c8f280 100644 --- a/deps/undici/src/README.md +++ b/deps/undici/src/README.md @@ -7,8 +7,12 @@ An HTTP/1.1 client, written from scratch for Node.js. > Undici means eleven in Italian. 1.1 -> 11 -> Eleven -> Undici. It is also a Stranger Things reference. +## How to get involved + Have a question about using Undici? Open a [Q&A Discussion](https://github.com/nodejs/undici/discussions/new) or join our official OpenJS [Slack](https://openjs-foundation.slack.com/archives/C01QF9Q31QD) channel. +Looking to contribute? Start by reading the [contributing guide](./CONTRIBUTING.md) + ## Install ``` diff --git a/deps/undici/src/lib/core/util.js b/deps/undici/src/lib/core/util.js index a62396e23e0297..e7b5d9c1eddea9 100644 --- a/deps/undici/src/lib/core/util.js +++ b/deps/undici/src/lib/core/util.js @@ -246,9 +246,6 @@ function bufferToLowerCasedHeaderName (value) { * @returns {Record} */ function parseHeaders (headers, obj) { - // For H2 support - if (!Array.isArray(headers)) return headers - if (obj === undefined) obj = {} for (let i = 0; i < headers.length; i += 2) { const key = headerNameToString(headers[i]) diff --git a/deps/undici/src/lib/dispatcher/client-h2.js b/deps/undici/src/lib/dispatcher/client-h2.js index d593eae4fca47e..6b48ab9904ecc6 100644 --- a/deps/undici/src/lib/dispatcher/client-h2.js +++ b/deps/undici/src/lib/dispatcher/client-h2.js @@ -54,6 +54,20 @@ const { } } = http2 +function parseH2Headers (headers) { + // set-cookie is always an array. Duplicates are added to the array. + // For duplicate cookie headers, the values are joined together with '; '. + headers = Object.entries(headers).flat(2) + + const result = [] + + for (const header of headers) { + result.push(Buffer.from(header)) + } + + return result +} + async function connectH2 (client, socket) { client[kSocket] = socket @@ -391,7 +405,19 @@ function writeH2 (client, request) { const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers request.onResponseStarted() - if (request.onHeaders(Number(statusCode), realHeaders, stream.resume.bind(stream), '') === false) { + // Due to the stream nature, it is possible we face a race condition + // where the stream has been assigned, but the request has been aborted + // the request remains in-flight and headers hasn't been received yet + // for those scenarios, best effort is to destroy the stream immediately + // as there's no value to keep it open. + if (request.aborted || request.completed) { + const err = new RequestAbortedError() + errorRequest(client, request, err) + util.destroy(stream, err) + return + } + + if (request.onHeaders(Number(statusCode), parseH2Headers(realHeaders), stream.resume.bind(stream), '') === false) { stream.pause() } diff --git a/deps/undici/src/lib/handler/redirect-handler.js b/deps/undici/src/lib/handler/redirect-handler.js index 368ef520d7651a..16a7b2150a9dee 100644 --- a/deps/undici/src/lib/handler/redirect-handler.js +++ b/deps/undici/src/lib/handler/redirect-handler.js @@ -201,9 +201,9 @@ function shouldRemoveHeader (header, removeContent, unknownOrigin) { if (removeContent && util.headerNameToString(header).startsWith('content-')) { return true } - if (unknownOrigin && (header.length === 13 || header.length === 6)) { + if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) { const name = util.headerNameToString(header) - return name === 'authorization' || name === 'cookie' + return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization' } return false } diff --git a/deps/undici/src/lib/mock/pending-interceptors-formatter.js b/deps/undici/src/lib/mock/pending-interceptors-formatter.js index ba6e4ebce1bd3c..ccca951195aa6b 100644 --- a/deps/undici/src/lib/mock/pending-interceptors-formatter.js +++ b/deps/undici/src/lib/mock/pending-interceptors-formatter.js @@ -3,6 +3,9 @@ const { Transform } = require('node:stream') const { Console } = require('node:console') +const PERSISTENT = process.versions.icu ? '✅' : 'Y ' +const NOT_PERSISTENT = process.versions.icu ? '❌' : 'N ' + /** * Gets the output of `console.table(…)` as a string. */ @@ -29,7 +32,7 @@ module.exports = class PendingInterceptorsFormatter { Origin: origin, Path: path, 'Status code': statusCode, - Persistent: persist ? '✅' : '❌', + Persistent: persist ? PERSISTENT : NOT_PERSISTENT, Invocations: timesInvoked, Remaining: persist ? Infinity : times - timesInvoked })) diff --git a/deps/undici/src/lib/web/fetch/data-url.js b/deps/undici/src/lib/web/fetch/data-url.js index ef292011c2c491..ddef36390f3ffd 100644 --- a/deps/undici/src/lib/web/fetch/data-url.js +++ b/deps/undici/src/lib/web/fetch/data-url.js @@ -8,12 +8,12 @@ const encoder = new TextEncoder() * @see https://mimesniff.spec.whatwg.org/#http-token-code-point */ const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/ -const HTTP_WHITESPACE_REGEX = /[\u000A|\u000D|\u0009|\u0020]/ // eslint-disable-line +const HTTP_WHITESPACE_REGEX = /[\u000A\u000D\u0009\u0020]/ // eslint-disable-line const ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g // eslint-disable-line /** * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point */ -const HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/ // eslint-disable-line +const HTTP_QUOTED_STRING_TOKENS = /[\u0009\u0020-\u007E\u0080-\u00FF]/ // eslint-disable-line // https://fetch.spec.whatwg.org/#data-url-processor /** @param {URL} dataURL */ diff --git a/deps/undici/src/lib/web/fetch/headers.js b/deps/undici/src/lib/web/fetch/headers.js index b849b0e356c4e7..2235f125c654ef 100644 --- a/deps/undici/src/lib/web/fetch/headers.js +++ b/deps/undici/src/lib/web/fetch/headers.js @@ -12,7 +12,7 @@ const { } = require('./util') const { webidl } = require('./webidl') const assert = require('node:assert') -const util = require('util') +const util = require('node:util') const kHeadersMap = Symbol('headers map') const kHeadersSortedMap = Symbol('headers map sorted') diff --git a/deps/undici/src/lib/web/fetch/index.js b/deps/undici/src/lib/web/fetch/index.js index d8c20c59bf78fd..58d61585c06899 100644 --- a/deps/undici/src/lib/web/fetch/index.js +++ b/deps/undici/src/lib/web/fetch/index.js @@ -2141,29 +2141,6 @@ async function httpNetworkFetch ( codings = contentEncoding.toLowerCase().split(',').map((x) => x.trim()) } location = headersList.get('location', true) - } else { - const keys = Object.keys(rawHeaders) - for (let i = 0; i < keys.length; ++i) { - // The header names are already in lowercase. - const key = keys[i] - const value = rawHeaders[key] - if (key === 'set-cookie') { - for (let j = 0; j < value.length; ++j) { - headersList.append(key, value[j], true) - } - } else { - headersList.append(key, value, true) - } - } - // For H2, The header names are already in lowercase, - // so we can avoid the `HeadersList#get` call here. - const contentEncoding = rawHeaders['content-encoding'] - if (contentEncoding) { - // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 - // "All content-coding values are case-insensitive..." - codings = contentEncoding.toLowerCase().split(',').map((x) => x.trim()).reverse() - } - location = rawHeaders.location } this.body = new Readable({ read: resume }) diff --git a/deps/undici/src/lib/web/fetch/util.js b/deps/undici/src/lib/web/fetch/util.js index 71bdf1ff112d47..1faf95ccd92341 100644 --- a/deps/undici/src/lib/web/fetch/util.js +++ b/deps/undici/src/lib/web/fetch/util.js @@ -18,6 +18,8 @@ let supportedHashes = [] let crypto try { crypto = require('node:crypto') + const possibleRelevantHashes = ['sha256', 'sha384', 'sha512'] + supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash)) /* c8 ignore next 3 */ } catch { } @@ -615,7 +617,7 @@ function bytesMatch (bytes, metadataList) { // https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options // https://www.w3.org/TR/CSP2/#source-list-syntax // https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1 -const parseHashWithOptions = /(?sha256|sha384|sha512)-(?[A-Za-z0-9+/]+={0,2}(?=\s|$))( +[!-~]*)?/i +const parseHashWithOptions = /(?sha256|sha384|sha512)-((?[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i /** * @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata diff --git a/deps/undici/src/package-lock.json b/deps/undici/src/package-lock.json index 8f9b7ac07122f2..85e47ab6b2cc5c 100644 --- a/deps/undici/src/package-lock.json +++ b/deps/undici/src/package-lock.json @@ -1,19 +1,19 @@ { "name": "undici", - "version": "6.10.2", + "version": "6.11.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "undici", - "version": "6.10.2", + "version": "6.11.1", "license": "MIT", "devDependencies": { "@matteo.collina/tspl": "^0.1.1", "@sinonjs/fake-timers": "^11.1.0", "@types/node": "^18.0.3", "abort-controller": "^3.0.0", - "borp": "^0.9.1", + "borp": "^0.10.0", "c8": "^9.1.0", "cross-env": "^7.0.3", "dns-packet": "^5.4.0", @@ -29,7 +29,7 @@ "proxy": "^2.1.1", "snazzy": "^9.0.0", "standard": "^17.0.0", - "tsd": "^0.30.1", + "tsd": "^0.31.0", "typescript": "^5.0.2", "ws": "^8.11.0" }, @@ -813,9 +813,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "node_modules/@isaacs/cliui": { @@ -1432,9 +1432,9 @@ } }, "node_modules/@tsd/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-CQlfzol0ldaU+ftWuG52vH29uRoKboLinLy84wS8TQOu+m+tWoaUfk4svL4ij2V8M5284KymJBlHUusKj6k34w==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-htCVCSQP58wZcLfQaT7ikW9hSjJN7ntIe0HzAfYpBauI0tYoIM0ow4XEZGFwYN266qEsJoOHhlnkNvz/gLrx4Q==", "dev": true, "engines": { "node": ">=14.17" @@ -1573,9 +1573,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.19.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", - "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", + "version": "18.19.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.28.tgz", + "integrity": "sha512-J5cOGD9n4x3YGgVuaND6khm5x07MMdAKkRyXnjVR6KFhLMNh2yONGiP7Z+4+tBOt5mK+GvDTiacTOVGGpqiecw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -1657,9 +1657,9 @@ } }, "node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "dependencies": { "debug": "^4.3.4" @@ -2188,9 +2188,9 @@ "dev": true }, "node_modules/borp": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/borp/-/borp-0.9.1.tgz", - "integrity": "sha512-vcbbjLjw17kC7hf8vJhum2da37O4c+DTIYusCB1tYGYqwt9fs58I5vKoCECmCIvmteRuQgq3nsYPwl5Gyqggpg==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/borp/-/borp-0.10.0.tgz", + "integrity": "sha512-O5ToZzO0r3K+cH4x/eS0CRO7woLhiJqgufnCSb2tSjZJOe6bLIlxRaC6YQTaorNF9Nvid9HKYmfpPOuJUNKQvw==", "dev": true, "dependencies": { "@reporters/github": "^1.5.4", @@ -2502,9 +2502,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001600", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", - "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", + "version": "1.0.30001605", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001605.tgz", + "integrity": "sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==", "dev": true, "funding": [ { @@ -3158,9 +3158,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.717", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.717.tgz", - "integrity": "sha512-6Fmg8QkkumNOwuZ/5mIbMU9WI3H2fmn5ajcVya64I5Yr5CcNmO7vcLt0Y7c96DCiMO5/9G+4sI2r6eEvdg1F7A==", + "version": "1.4.723", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.723.tgz", + "integrity": "sha512-rxFVtrMGMFROr4qqU6n95rUi9IlfIm+lIAt+hOToy/9r6CDv0XiEcQdC3VP71y1pE5CFTzKV0RvxOGYCPWWHPw==", "dev": true }, "node_modules/emittery": { @@ -3203,9 +3203,9 @@ } }, "node_modules/es-abstract": { - "version": "1.23.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", - "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", @@ -3247,11 +3247,11 @@ "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.9", "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.7", + "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.2", "typed-array-byte-length": "^1.0.1", "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.5", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", "which-typed-array": "^1.1.15" }, @@ -4830,16 +4830,16 @@ } }, "node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", + "jackspeak": "^2.3.6", "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" }, "bin": { "glob": "dist/esm/bin.mjs" @@ -7348,9 +7348,9 @@ } }, "node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -8506,12 +8506,12 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", "dev": true, "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { @@ -10342,12 +10342,12 @@ } }, "node_modules/tsd": { - "version": "0.30.7", - "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.30.7.tgz", - "integrity": "sha512-oTiJ28D6B/KXoU3ww/Eji+xqHJojiuPVMwA12g4KYX1O72N93Nb6P3P3h2OAhhf92Xl8NIhb/xFmBZd5zw/xUw==", + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.31.0.tgz", + "integrity": "sha512-yjBiQ5n8OMv/IZOuhDjBy0ZLCoJ7rky/RxRh5W4sJ0oNNCU/kf6s3puPAkGNi59PptDdkcpUm+RsKSdjR2YbNg==", "dev": true, "dependencies": { - "@tsd/typescript": "~5.3.3", + "@tsd/typescript": "~5.4.3", "eslint-formatter-pretty": "^4.1.0", "globby": "^11.0.1", "jest-diff": "^29.0.3", @@ -10521,9 +10521,9 @@ } }, "node_modules/undici": { - "version": "5.28.3", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz", - "integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==", + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", "dev": true, "dependencies": { "@fastify/busboy": "^2.0.0" diff --git a/deps/undici/src/package.json b/deps/undici/src/package.json index 146ad10a1f6f8b..be389c85c36b78 100644 --- a/deps/undici/src/package.json +++ b/deps/undici/src/package.json @@ -1,6 +1,6 @@ { "name": "undici", - "version": "6.10.2", + "version": "6.11.1", "description": "An HTTP/1.1 client, written from scratch for Node.js", "homepage": "https://undici.nodejs.org", "bugs": { @@ -69,10 +69,13 @@ "lint:fix": "standard --fix | snazzy", "test": "npm run test:javascript && cross-env NODE_V8_COVERAGE= npm run test:typescript", "test:javascript": "node scripts/generate-pem && npm run test:unit && npm run test:node-fetch && npm run test:fetch && npm run test:cookies && npm run test:eventsource && npm run test:wpt && npm run test:websocket && npm run test:node-test && npm run test:jest", + "test:javascript:withoutintl": "node scripts/generate-pem && npm run test:unit && npm run test:node-fetch && npm run test:fetch:nobuild && npm run test:cookies && npm run test:eventsource:nobuild && npm run test:wpt:withoutintl && npm run test:node-test", "test:cookies": "borp -p \"test/cookie/*.js\"", "test:node-fetch": "borp -p \"test/node-fetch/**/*.js\"", - "test:eventsource": "npm run build:node && borp --expose-gc -p \"test/eventsource/*.js\"", - "test:fetch": "npm run build:node && borp --expose-gc -p \"test/fetch/*.js\" && borp -p \"test/webidl/*.js\" && borp -p \"test/busboy/*.js\"", + "test:eventsource": "npm run build:node && npm run test:eventsource:nobuild", + "test:eventsource:nobuild": "borp --expose-gc -p \"test/eventsource/*.js\"", + "test:fetch": "npm run build:node && npm run test:fetch:nobuild", + "test:fetch:nobuild": "borp --expose-gc -p \"test/fetch/*.js\" && borp -p \"test/webidl/*.js\" && borp -p \"test/busboy/*.js\"", "test:jest": "cross-env NODE_V8_COVERAGE= jest", "test:unit": "borp --expose-gc -p \"test/*.js\"", "test:node-test": "borp -p \"test/node-test/**/*.js\"", @@ -81,6 +84,7 @@ "test:typescript": "tsd && tsc --skipLibCheck test/imports/undici-import.ts", "test:websocket": "borp -p \"test/websocket/*.js\"", "test:wpt": "node test/wpt/start-fetch.mjs && node test/wpt/start-FileAPI.mjs && node test/wpt/start-mimesniff.mjs && node test/wpt/start-xhr.mjs && node test/wpt/start-websockets.mjs && node test/wpt/start-cacheStorage.mjs && node test/wpt/start-eventsource.mjs", + "test:wpt:withoutintl": "node test/wpt/start-fetch.mjs && node test/wpt/start-mimesniff.mjs && node test/wpt/start-xhr.mjs && node test/wpt/start-cacheStorage.mjs && node test/wpt/start-eventsource.mjs", "coverage": "npm run coverage:clean && cross-env NODE_V8_COVERAGE=./coverage/tmp npm run test:javascript && npm run coverage:report", "coverage:ci": "npm run coverage:clean && cross-env NODE_V8_COVERAGE=./coverage/tmp npm run test:javascript && npm run coverage:report:ci", "coverage:clean": "node ./scripts/clean-coverage.js", @@ -96,7 +100,7 @@ "@sinonjs/fake-timers": "^11.1.0", "@types/node": "^18.0.3", "abort-controller": "^3.0.0", - "borp": "^0.9.1", + "borp": "^0.10.0", "c8": "^9.1.0", "cross-env": "^7.0.3", "dns-packet": "^5.4.0", @@ -112,7 +116,7 @@ "proxy": "^2.1.1", "snazzy": "^9.0.0", "standard": "^17.0.0", - "tsd": "^0.30.1", + "tsd": "^0.31.0", "typescript": "^5.0.2", "ws": "^8.11.0" }, diff --git a/deps/undici/src/types/diagnostics-channel.d.ts b/deps/undici/src/types/diagnostics-channel.d.ts index 85d44823978df5..a037d1e0b2cea5 100644 --- a/deps/undici/src/types/diagnostics-channel.d.ts +++ b/deps/undici/src/types/diagnostics-channel.d.ts @@ -9,8 +9,7 @@ declare namespace DiagnosticsChannel { completed: boolean; method?: Dispatcher.HttpMethod; path: string; - headers: string; - addHeader(key: string, value: string): Request; + headers: any; } interface Response { statusCode: number; diff --git a/deps/undici/undici.js b/deps/undici/undici.js index 6b4950394adfcb..3dfab0de532e50 100644 --- a/deps/undici/undici.js +++ b/deps/undici/undici.js @@ -816,8 +816,6 @@ var require_util = __commonJS({ } __name(bufferToLowerCasedHeaderName, "bufferToLowerCasedHeaderName"); function parseHeaders(headers, obj) { - if (!Array.isArray(headers)) - return headers; if (obj === void 0) obj = {}; for (let i = 0; i < headers.length; i += 2) { @@ -1302,9 +1300,9 @@ var require_data_url = __commonJS({ var assert = require("node:assert"); var encoder = new TextEncoder(); var HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/; - var HTTP_WHITESPACE_REGEX = /[\u000A|\u000D|\u0009|\u0020]/; + var HTTP_WHITESPACE_REGEX = /[\u000A\u000D\u0009\u0020]/; var ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g; - var HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/; + var HTTP_QUOTED_STRING_TOKENS = /[\u0009\u0020-\u007E\u0080-\u00FF]/; function dataURLProcessor(dataURL) { assert(dataURL.protocol === "data:"); let input = URLSerializer(dataURL, true); @@ -2085,9 +2083,12 @@ var require_util2 = __commonJS({ var assert = require("node:assert"); var { isUint8Array } = require("node:util/types"); var { webidl } = require_webidl(); + var supportedHashes = []; var crypto; try { crypto = require("node:crypto"); + const possibleRelevantHashes = ["sha256", "sha384", "sha512"]; + supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash)); } catch { } function responseURL(response) { @@ -2413,7 +2414,7 @@ var require_util2 = __commonJS({ return false; } __name(bytesMatch, "bytesMatch"); - var parseHashWithOptions = /(?sha256|sha384|sha512)-(?[A-Za-z0-9+/]+={0,2}(?=\s|$))( +[!-~]*)?/i; + var parseHashWithOptions = /(?sha256|sha384|sha512)-((?[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i; function parseMetadata(metadata) { const result = []; let empty = true; @@ -3016,7 +3017,7 @@ var require_headers = __commonJS({ } = require_util2(); var { webidl } = require_webidl(); var assert = require("node:assert"); - var util = require("util"); + var util = require("node:util"); var kHeadersMap = Symbol("headers map"); var kHeadersSortedMap = Symbol("headers map sorted"); function isHTTPWhiteSpaceCharCode(code) { @@ -8159,6 +8160,15 @@ var require_client_h2 = __commonJS({ HTTP2_HEADER_STATUS } } = http2; + function parseH2Headers(headers) { + headers = Object.entries(headers).flat(2); + const result = []; + for (const header of headers) { + result.push(Buffer.from(header)); + } + return result; + } + __name(parseH2Headers, "parseH2Headers"); async function connectH2(client, socket) { client[kSocket] = socket; if (!h2ExperimentalWarned) { @@ -8401,7 +8411,13 @@ var require_client_h2 = __commonJS({ stream.once("response", (headers2) => { const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers2; request.onResponseStarted(); - if (request.onHeaders(Number(statusCode), realHeaders, stream.resume.bind(stream), "") === false) { + if (request.aborted || request.completed) { + const err = new RequestAbortedError(); + errorRequest(client, request, err); + util.destroy(stream, err); + return; + } + if (request.onHeaders(Number(statusCode), parseH2Headers(realHeaders), stream.resume.bind(stream), "") === false) { stream.pause(); } stream.on("data", (chunk) => { @@ -8735,9 +8751,9 @@ var require_redirect_handler = __commonJS({ if (removeContent && util.headerNameToString(header).startsWith("content-")) { return true; } - if (unknownOrigin && (header.length === 13 || header.length === 6)) { + if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) { const name = util.headerNameToString(header); - return name === "authorization" || name === "cookie"; + return name === "authorization" || name === "cookie" || name === "proxy-authorization"; } return false; } @@ -10522,24 +10538,6 @@ var require_fetch = __commonJS({ codings = contentEncoding.toLowerCase().split(",").map((x) => x.trim()); } location = headersList.get("location", true); - } else { - const keys = Object.keys(rawHeaders); - for (let i = 0; i < keys.length; ++i) { - const key = keys[i]; - const value = rawHeaders[key]; - if (key === "set-cookie") { - for (let j = 0; j < value.length; ++j) { - headersList.append(key, value[j], true); - } - } else { - headersList.append(key, value, true); - } - } - const contentEncoding = rawHeaders["content-encoding"]; - if (contentEncoding) { - codings = contentEncoding.toLowerCase().split(",").map((x) => x.trim()).reverse(); - } - location = rawHeaders.location; } this.body = new Readable({ read: resume }); const decoders = []; diff --git a/src/undici_version.h b/src/undici_version.h index b5caecb1f39308..6b89eb5309dc30 100644 --- a/src/undici_version.h +++ b/src/undici_version.h @@ -2,5 +2,5 @@ // Refer to tools/dep_updaters/update-undici.sh #ifndef SRC_UNDICI_VERSION_H_ #define SRC_UNDICI_VERSION_H_ -#define UNDICI_VERSION "6.10.2" +#define UNDICI_VERSION "6.11.1" #endif // SRC_UNDICI_VERSION_H_