diff --git a/deps/undici/src/index-fetch.js b/deps/undici/src/index-fetch.js index 23ac530600769e..ba31a65f25c184 100644 --- a/deps/undici/src/index-fetch.js +++ b/deps/undici/src/index-fetch.js @@ -2,13 +2,11 @@ const fetchImpl = require('./lib/fetch').fetch -module.exports.fetch = async function fetch (resource, init = undefined) { - try { - return await fetchImpl(resource, init) - } catch (err) { +module.exports.fetch = function fetch (resource, init = undefined) { + return fetchImpl(resource, init).catch((err) => { Error.captureStackTrace(err, this) throw err - } + }) } module.exports.FormData = require('./lib/fetch/formdata').FormData module.exports.Headers = require('./lib/fetch/headers').Headers diff --git a/deps/undici/src/lib/core/request.js b/deps/undici/src/lib/core/request.js index 50be01c0dc8355..43973884f1a3c8 100644 --- a/deps/undici/src/lib/core/request.js +++ b/deps/undici/src/lib/core/request.js @@ -222,6 +222,14 @@ class Request { if (channels.bodySent.hasSubscribers) { channels.bodySent.publish({ request: this }) } + + if (this[kHandler].onRequestSent) { + try { + this[kHandler].onRequestSent() + } catch (err) { + this.onError(err) + } + } } onConnect (abort) { diff --git a/deps/undici/src/lib/fetch/body.js b/deps/undici/src/lib/fetch/body.js index 1d9f17d7e330c6..fd8481b796d847 100644 --- a/deps/undici/src/lib/fetch/body.js +++ b/deps/undici/src/lib/fetch/body.js @@ -26,6 +26,8 @@ let ReadableStream = globalThis.ReadableStream /** @type {globalThis['File']} */ const File = NativeFile ?? UndiciFile +const textEncoder = new TextEncoder() +const textDecoder = new TextDecoder() // https://fetch.spec.whatwg.org/#concept-bodyinit-extract function extractBody (object, keepalive = false) { @@ -49,7 +51,7 @@ function extractBody (object, keepalive = false) { stream = new ReadableStream({ async pull (controller) { controller.enqueue( - typeof source === 'string' ? new TextEncoder().encode(source) : source + typeof source === 'string' ? textEncoder.encode(source) : source ) queueMicrotask(() => readableStreamClose(controller)) }, @@ -119,7 +121,6 @@ function extractBody (object, keepalive = false) { // - That the content-length is calculated in advance. // - And that all parts are pre-encoded and ready to be sent. - const enc = new TextEncoder() const blobParts = [] const rn = new Uint8Array([13, 10]) // '\r\n' length = 0 @@ -127,13 +128,13 @@ function extractBody (object, keepalive = false) { for (const [name, value] of object) { if (typeof value === 'string') { - const chunk = enc.encode(prefix + + const chunk = textEncoder.encode(prefix + `; name="${escape(normalizeLinefeeds(name))}"` + `\r\n\r\n${normalizeLinefeeds(value)}\r\n`) blobParts.push(chunk) length += chunk.byteLength } else { - const chunk = enc.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + + const chunk = textEncoder.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + (value.name ? `; filename="${escape(value.name)}"` : '') + '\r\n' + `Content-Type: ${ value.type || 'application/octet-stream' @@ -147,7 +148,7 @@ function extractBody (object, keepalive = false) { } } - const chunk = enc.encode(`--${boundary}--`) + const chunk = textEncoder.encode(`--${boundary}--`) blobParts.push(chunk) length += chunk.byteLength if (hasUnknownSizeValue) { @@ -443,14 +444,16 @@ function bodyMixinMethods (instance) { let text = '' // application/x-www-form-urlencoded parser will keep the BOM. // https://url.spec.whatwg.org/#concept-urlencoded-parser - const textDecoder = new TextDecoder('utf-8', { ignoreBOM: true }) + // Note that streaming decoder is stateful and cannot be reused + const streamingDecoder = new TextDecoder('utf-8', { ignoreBOM: true }) + for await (const chunk of consumeBody(this[kState].body)) { if (!isUint8Array(chunk)) { throw new TypeError('Expected Uint8Array chunk') } - text += textDecoder.decode(chunk, { stream: true }) + text += streamingDecoder.decode(chunk, { stream: true }) } - text += textDecoder.decode() + text += streamingDecoder.decode() entries = new URLSearchParams(text) } catch (err) { // istanbul ignore next: Unclear when new URLSearchParams can fail on a string. @@ -565,7 +568,7 @@ function utf8DecodeBytes (buffer) { // 3. Process a queue with an instance of UTF-8’s // decoder, ioQueue, output, and "replacement". - const output = new TextDecoder().decode(buffer) + const output = textDecoder.decode(buffer) // 4. Return output. return output diff --git a/deps/undici/src/lib/fetch/constants.js b/deps/undici/src/lib/fetch/constants.js index a5294a994fbc45..218fcbee4da4c7 100644 --- a/deps/undici/src/lib/fetch/constants.js +++ b/deps/undici/src/lib/fetch/constants.js @@ -3,10 +3,12 @@ const { MessageChannel, receiveMessageOnPort } = require('worker_threads') const corsSafeListedMethods = ['GET', 'HEAD', 'POST'] +const corsSafeListedMethodsSet = new Set(corsSafeListedMethods) const nullBodyStatus = [101, 204, 205, 304] const redirectStatus = [301, 302, 303, 307, 308] +const redirectStatusSet = new Set(redirectStatus) // https://fetch.spec.whatwg.org/#block-bad-port const badPorts = [ @@ -18,6 +20,8 @@ const badPorts = [ '10080' ] +const badPortsSet = new Set(badPorts) + // https://w3c.github.io/webappsec-referrer-policy/#referrer-policies const referrerPolicy = [ '', @@ -30,10 +34,12 @@ const referrerPolicy = [ 'strict-origin-when-cross-origin', 'unsafe-url' ] +const referrerPolicySet = new Set(referrerPolicy) const requestRedirect = ['follow', 'manual', 'error'] const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE'] +const safeMethodsSet = new Set(safeMethods) const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors'] @@ -68,6 +74,7 @@ const requestDuplex = [ // http://fetch.spec.whatwg.org/#forbidden-method const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK'] +const forbiddenMethodsSet = new Set(forbiddenMethods) const subresource = [ 'audio', @@ -83,6 +90,7 @@ const subresource = [ 'xslt', '' ] +const subresourceSet = new Set(subresource) /** @type {globalThis['DOMException']} */ const DOMException = globalThis.DOMException ?? (() => { @@ -132,5 +140,12 @@ module.exports = { nullBodyStatus, safeMethods, badPorts, - requestDuplex + requestDuplex, + subresourceSet, + badPortsSet, + redirectStatusSet, + corsSafeListedMethodsSet, + safeMethodsSet, + forbiddenMethodsSet, + referrerPolicySet } diff --git a/deps/undici/src/lib/fetch/file.js b/deps/undici/src/lib/fetch/file.js index 81bb7b2441aaa2..3133d255ecdcdb 100644 --- a/deps/undici/src/lib/fetch/file.js +++ b/deps/undici/src/lib/fetch/file.js @@ -7,6 +7,7 @@ const { isBlobLike } = require('./util') const { webidl } = require('./webidl') const { parseMIMEType, serializeAMimeType } = require('./dataURL') const { kEnumerableProperty } = require('../core/util') +const encoder = new TextEncoder() class File extends Blob { constructor (fileBits, fileName, options = {}) { @@ -280,7 +281,7 @@ function processBlobParts (parts, options) { } // 3. Append the result of UTF-8 encoding s to bytes. - bytes.push(new TextEncoder().encode(s)) + bytes.push(encoder.encode(s)) } else if ( types.isAnyArrayBuffer(element) || types.isTypedArray(element) diff --git a/deps/undici/src/lib/fetch/index.js b/deps/undici/src/lib/fetch/index.js index 5323c30abc8791..298b3ddb27c04c 100644 --- a/deps/undici/src/lib/fetch/index.js +++ b/deps/undici/src/lib/fetch/index.js @@ -46,11 +46,11 @@ const { kState, kHeaders, kGuard, kRealm } = require('./symbols') const assert = require('assert') const { safelyExtractBody } = require('./body') const { - redirectStatus, + redirectStatusSet, nullBodyStatus, - safeMethods, + safeMethodsSet, requestBodyHeader, - subresource, + subresourceSet, DOMException } = require('./constants') const { kHeadersList } = require('../core/symbols') @@ -62,6 +62,7 @@ const { TransformStream } = require('stream/web') const { getGlobalDispatcher } = require('../global') const { webidl } = require('./webidl') const { STATUS_CODES } = require('http') +const GET_OR_HEAD = ['GET', 'HEAD'] /** @type {import('buffer').resolveObjectURL} */ let resolveObjectURL @@ -121,7 +122,7 @@ class Fetch extends EE { } // https://fetch.spec.whatwg.org/#fetch-method -async function fetch (input, init = {}) { +function fetch (input, init = {}) { webidl.argumentLengthCheck(arguments, 1, { header: 'globalThis.fetch' }) // 1. Let p be a new promise. @@ -204,7 +205,7 @@ async function fetch (input, init = {}) { const processResponse = (response) => { // 1. If locallyAborted is true, terminate these substeps. if (locallyAborted) { - return + return Promise.resolve() } // 2. If response’s aborted flag is set, then: @@ -217,7 +218,7 @@ async function fetch (input, init = {}) { // deserializedError. abortFetch(p, request, responseObject, controller.serializedAbortReason) - return + return Promise.resolve() } // 3. If response is a network error, then reject p with a TypeError @@ -226,7 +227,7 @@ async function fetch (input, init = {}) { p.reject( Object.assign(new TypeError('fetch failed'), { cause: response.error }) ) - return + return Promise.resolve() } // 4. Set responseObject to the result of creating a Response object, @@ -509,7 +510,7 @@ function fetching ({ } // 15. If request is a subresource request, then: - if (subresource.includes(request.destination)) { + if (subresourceSet.has(request.destination)) { // TODO } @@ -776,13 +777,13 @@ async function mainFetch (fetchParams, recursive = false) { // https://fetch.spec.whatwg.org/#concept-scheme-fetch // given a fetch params fetchParams -async function schemeFetch (fetchParams) { +function schemeFetch (fetchParams) { // Note: since the connection is destroyed on redirect, which sets fetchParams to a // cancelled state, we do not want this condition to trigger *unless* there have been // no redirects. See https://github.com/nodejs/undici/issues/1776 // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { - return makeAppropriateNetworkError(fetchParams) + return Promise.resolve(makeAppropriateNetworkError(fetchParams)) } // 2. Let request be fetchParams’s request. @@ -798,7 +799,7 @@ async function schemeFetch (fetchParams) { // and body is the empty byte sequence as a body. // Otherwise, return a network error. - return makeNetworkError('about scheme is not supported') + return Promise.resolve(makeNetworkError('about scheme is not supported')) } case 'blob:': { if (!resolveObjectURL) { @@ -811,7 +812,7 @@ async function schemeFetch (fetchParams) { // https://github.com/web-platform-tests/wpt/blob/7b0ebaccc62b566a1965396e5be7bb2bc06f841f/FileAPI/url/resources/fetch-tests.js#L52-L56 // Buffer.resolveObjectURL does not ignore URL queries. if (blobURLEntry.search.length !== 0) { - return makeNetworkError('NetworkError when attempting to fetch resource.') + return Promise.resolve(makeNetworkError('NetworkError when attempting to fetch resource.')) } const blobURLEntryObject = resolveObjectURL(blobURLEntry.toString()) @@ -819,7 +820,7 @@ async function schemeFetch (fetchParams) { // 2. If request’s method is not `GET`, blobURLEntry is null, or blobURLEntry’s // object is not a Blob object, then return a network error. if (request.method !== 'GET' || !isBlobLike(blobURLEntryObject)) { - return makeNetworkError('invalid method') + return Promise.resolve(makeNetworkError('invalid method')) } // 3. Let bodyWithType be the result of safely extracting blobURLEntry’s object. @@ -846,7 +847,7 @@ async function schemeFetch (fetchParams) { response.body = body - return response + return Promise.resolve(response) } case 'data:': { // 1. Let dataURLStruct be the result of running the @@ -857,7 +858,7 @@ async function schemeFetch (fetchParams) { // 2. If dataURLStruct is failure, then return a // network error. if (dataURLStruct === 'failure') { - return makeNetworkError('failed to fetch the data URL') + return Promise.resolve(makeNetworkError('failed to fetch the data URL')) } // 3. Let mimeType be dataURLStruct’s MIME type, serialized. @@ -866,28 +867,28 @@ async function schemeFetch (fetchParams) { // 4. Return a response whose status message is `OK`, // header list is « (`Content-Type`, mimeType) », // and body is dataURLStruct’s body as a body. - return makeResponse({ + return Promise.resolve(makeResponse({ statusText: 'OK', headersList: [ ['content-type', { name: 'Content-Type', value: mimeType }] ], body: safelyExtractBody(dataURLStruct.body)[0] - }) + })) } case 'file:': { // For now, unfortunate as it is, file URLs are left as an exercise for the reader. // When in doubt, return a network error. - return makeNetworkError('not implemented... yet...') + return Promise.resolve(makeNetworkError('not implemented... yet...')) } case 'http:': case 'https:': { // Return the result of running HTTP fetch given fetchParams. - return await httpFetch(fetchParams) + return httpFetch(fetchParams) .catch((err) => makeNetworkError(err)) } default: { - return makeNetworkError('unknown scheme') + return Promise.resolve(makeNetworkError('unknown scheme')) } } } @@ -906,7 +907,7 @@ function finalizeResponse (fetchParams, response) { } // https://fetch.spec.whatwg.org/#fetch-finale -async function fetchFinale (fetchParams, response) { +function fetchFinale (fetchParams, response) { // 1. If response is a network error, then: if (response.type === 'error') { // 1. Set response’s URL list to « fetchParams’s request’s URL list[0] ». @@ -990,8 +991,9 @@ async function fetchFinale (fetchParams, response) { } else { // 4. Otherwise, fully read response’s body given processBody, processBodyError, // and fetchParams’s task destination. - await fullyReadBody(response.body, processBody, processBodyError) + return fullyReadBody(response.body, processBody, processBodyError) } + return Promise.resolve() } } @@ -1062,7 +1064,7 @@ async function httpFetch (fetchParams) { } // 8. If actualResponse’s status is a redirect status, then: - if (redirectStatus.includes(actualResponse.status)) { + if (redirectStatusSet.has(actualResponse.status)) { // 1. If actualResponse’s status is not 303, request’s body is not null, // and the connection uses HTTP/2, then user agents may, and are even // encouraged to, transmit an RST_STREAM frame. @@ -1099,7 +1101,7 @@ async function httpFetch (fetchParams) { } // https://fetch.spec.whatwg.org/#http-redirect-fetch -async function httpRedirectFetch (fetchParams, response) { +function httpRedirectFetch (fetchParams, response) { // 1. Let request be fetchParams’s request. const request = fetchParams.request @@ -1125,18 +1127,18 @@ async function httpRedirectFetch (fetchParams, response) { } } catch (err) { // 5. If locationURL is failure, then return a network error. - return makeNetworkError(err) + return Promise.resolve(makeNetworkError(err)) } // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network // error. if (!urlIsHttpHttpsScheme(locationURL)) { - return makeNetworkError('URL scheme must be a HTTP(S) scheme') + return Promise.resolve(makeNetworkError('URL scheme must be a HTTP(S) scheme')) } // 7. If request’s redirect count is 20, then return a network error. if (request.redirectCount === 20) { - return makeNetworkError('redirect count exceeded') + return Promise.resolve(makeNetworkError('redirect count exceeded')) } // 8. Increase request’s redirect count by 1. @@ -1150,7 +1152,7 @@ async function httpRedirectFetch (fetchParams, response) { (locationURL.username || locationURL.password) && !sameOrigin(request, locationURL) ) { - return makeNetworkError('cross origin not allowed for request mode "cors"') + return Promise.resolve(makeNetworkError('cross origin not allowed for request mode "cors"')) } // 10. If request’s response tainting is "cors" and locationURL includes @@ -1159,9 +1161,9 @@ async function httpRedirectFetch (fetchParams, response) { request.responseTainting === 'cors' && (locationURL.username || locationURL.password) ) { - return makeNetworkError( + return Promise.resolve(makeNetworkError( 'URL cannot contain credentials for request mode "cors"' - ) + )) } // 11. If actualResponse’s status is not 303, request’s body is non-null, @@ -1171,7 +1173,7 @@ async function httpRedirectFetch (fetchParams, response) { request.body != null && request.body.source == null ) { - return makeNetworkError() + return Promise.resolve(makeNetworkError()) } // 12. If one of the following is true @@ -1180,7 +1182,7 @@ async function httpRedirectFetch (fetchParams, response) { if ( ([301, 302].includes(actualResponse.status) && request.method === 'POST') || (actualResponse.status === 303 && - !['GET', 'HEAD'].includes(request.method)) + !GET_OR_HEAD.includes(request.method)) ) { // then: // 1. Set request’s method to `GET` and request’s body to null. @@ -1464,7 +1466,7 @@ async function httpNetworkOrCacheFetch ( // responses in httpCache, as per the "Invalidation" chapter of HTTP // Caching, and set storedResponse to null. [HTTP-CACHING] if ( - !safeMethods.includes(httpRequest.method) && + !safeMethodsSet.has(httpRequest.method) && forwardResponse.status >= 200 && forwardResponse.status <= 399 ) { @@ -2024,7 +2026,7 @@ async function httpNetworkFetch ( const willFollow = request.redirect === 'follow' && location && - redirectStatus.includes(status) + redirectStatusSet.has(status) // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) { diff --git a/deps/undici/src/lib/fetch/request.js b/deps/undici/src/lib/fetch/request.js index 912bd5b8c988af..60e654eca112cd 100644 --- a/deps/undici/src/lib/fetch/request.js +++ b/deps/undici/src/lib/fetch/request.js @@ -13,8 +13,8 @@ const { makePolicyContainer } = require('./util') const { - forbiddenMethods, - corsSafeListedMethods, + forbiddenMethodsSet, + corsSafeListedMethodsSet, referrerPolicy, requestRedirect, requestMode, @@ -319,7 +319,7 @@ class Request { throw TypeError(`'${init.method}' is not a valid HTTP method.`) } - if (forbiddenMethods.indexOf(method.toUpperCase()) !== -1) { + if (forbiddenMethodsSet.has(method.toUpperCase())) { throw TypeError(`'${init.method}' HTTP method is unsupported.`) } @@ -404,7 +404,7 @@ class Request { if (mode === 'no-cors') { // 1. If this’s request’s method is not a CORS-safelisted method, // then throw a TypeError. - if (!corsSafeListedMethods.includes(request.method)) { + if (!corsSafeListedMethodsSet.has(request.method)) { throw new TypeError( `'${request.method} is unsupported in no-cors mode.` ) diff --git a/deps/undici/src/lib/fetch/response.js b/deps/undici/src/lib/fetch/response.js index 88deb71a06285e..23cf55c51dc1c5 100644 --- a/deps/undici/src/lib/fetch/response.js +++ b/deps/undici/src/lib/fetch/response.js @@ -14,7 +14,7 @@ const { isomorphicEncode } = require('./util') const { - redirectStatus, + redirectStatusSet, nullBodyStatus, DOMException } = require('./constants') @@ -28,6 +28,7 @@ const assert = require('assert') const { types } = require('util') const ReadableStream = globalThis.ReadableStream || require('stream/web').ReadableStream +const textEncoder = new TextEncoder('utf-8') // https://fetch.spec.whatwg.org/#response-class class Response { @@ -57,7 +58,7 @@ class Response { } // 1. Let bytes the result of running serialize a JavaScript value to JSON bytes on data. - const bytes = new TextEncoder('utf-8').encode( + const bytes = textEncoder.encode( serializeJavascriptValueToJSONString(data) ) @@ -102,7 +103,7 @@ class Response { } // 3. If status is not a redirect status, then throw a RangeError. - if (!redirectStatus.includes(status)) { + if (!redirectStatusSet.has(status)) { throw new RangeError('Invalid status code ' + status) } diff --git a/deps/undici/src/lib/fetch/util.js b/deps/undici/src/lib/fetch/util.js index fcbba84bc9a8b0..033fa206aedc3e 100644 --- a/deps/undici/src/lib/fetch/util.js +++ b/deps/undici/src/lib/fetch/util.js @@ -1,6 +1,6 @@ 'use strict' -const { redirectStatus, badPorts, referrerPolicy: referrerPolicyTokens } = require('./constants') +const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = require('./constants') const { getGlobalOrigin } = require('./global') const { performance } = require('perf_hooks') const { isBlobLike, toUSVString, ReadableStreamFrom } = require('../core/util') @@ -29,7 +29,7 @@ function responseURL (response) { // https://fetch.spec.whatwg.org/#concept-response-location-url function responseLocationURL (response, requestFragment) { // 1. If response’s status is not a redirect status, then return null. - if (!redirectStatus.includes(response.status)) { + if (!redirectStatusSet.has(response.status)) { return null } @@ -64,7 +64,7 @@ function requestBadPort (request) { // 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port, // then return blocked. - if (urlIsHttpHttpsScheme(url) && badPorts.includes(url.port)) { + if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { return 'blocked' } @@ -206,7 +206,7 @@ function setRequestReferrerPolicyOnRedirect (request, actualResponse) { // The left-most policy is the fallback. for (let i = policyHeader.length; i !== 0; i--) { const token = policyHeader[i - 1].trim() - if (referrerPolicyTokens.includes(token)) { + if (referrerPolicyTokens.has(token)) { policy = token break } diff --git a/deps/undici/src/package-lock.json b/deps/undici/src/package-lock.json index eb929e548c2d86..d6f048345a665b 100644 --- a/deps/undici/src/package-lock.json +++ b/deps/undici/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "undici", - "version": "5.26.4", + "version": "5.27.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "undici", - "version": "5.26.4", + "version": "5.27.0", "license": "MIT", "dependencies": { "@fastify/busboy": "^2.0.0" @@ -795,9 +795,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", - "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -1634,10 +1634,22 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.18.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.6.tgz", - "integrity": "sha512-wf3Vz+jCmOQ2HV1YUJuCWdL64adYxumkrxtc+H1VUQlnQI04+5HtH+qZCOE21lBE7gIrt+CwX2Wv8Acrw5Ak6w==", - "dev": true + "version": "18.18.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.7.tgz", + "integrity": "sha512-bw+lEsxis6eqJYW8Ql6+yTqkE6RuFtsQPSe5JxXbqYRFQEER5aJA9a5UH9igqDWm3X4iLHIKOHlnAXLM4mi7uQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.8.tgz", + "integrity": "sha512-vGXshY9vim9CJjrpcS5raqSjEfKlJcWy2HNdgUasR66fAnVEYarrf1ULV4nfvpC1nZq/moA9qyqBcu83x+Jlrg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/normalize-package-data": { "version": "2.4.3", @@ -1691,9 +1703,9 @@ } }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1712,12 +1724,12 @@ } }, "node_modules/acquerello": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/acquerello/-/acquerello-1.0.12.tgz", - "integrity": "sha512-6yCYGUNctkYqF7DLmm0D/CxlRmM/OrzyuHOU+mbaO6VRxHmRg4EV0phvyBexRt6jTyDtEQIb09YFiwu5LExXsA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/acquerello/-/acquerello-1.1.2.tgz", + "integrity": "sha512-V/ynq+ekRAls3iWOQMxA8G9pi40aTL9mheHHxA8x8oowZVjY7bROD99t+TSOKKp3BviACYOsNMlL+b+8jZ7ImQ==", "dev": true, "engines": { - "node": ">=14.15.0" + "node": ">= 18.18.0" } }, "node_modules/agent-base": { @@ -2658,9 +2670,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001551", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001551.tgz", - "integrity": "sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==", + "version": "1.0.30001557", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001557.tgz", + "integrity": "sha512-91oR7hLNUP3gG6MLU+n96em322a8Xzes8wWdBKhLgUoiJsAF5irZnxSUCbc+qUZXNnPCfUwLOi9ZCZpkvjQajw==", "dev": true, "funding": [ { @@ -3125,17 +3137,17 @@ } }, "node_modules/cronometro": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/cronometro/-/cronometro-1.1.5.tgz", - "integrity": "sha512-uotkltVBg4WLAeCgbSsLhqpEyvYTn1J++bYcsq0i/RPNMHkMp4sN/7Hx+0O3UaCqIWJ4AG1dNrzDSkzt69jwQQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cronometro/-/cronometro-1.2.0.tgz", + "integrity": "sha512-QeNGCuvNFimu4IJhZSL4oNopAmxfjRkSqh4rci4PZuNWKLRhqPC0oemw6gdbfgz0evqxOOS3uwtSt2FMR8dDXw==", "dev": true, "dependencies": { - "acquerello": "^1.0.12", + "acquerello": "^1.1.2", "hdr-histogram-js": "^3.0.0", "table": "^6.8.1" }, "engines": { - "node": ">=14.15.0" + "node": ">= 18.18.0" } }, "node_modules/cross-spawn": { @@ -3782,9 +3794,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.563", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.563.tgz", - "integrity": "sha512-dg5gj5qOgfZNkPNeyKBZQAQitIQ/xwfIDmEQJHCbXaD9ebTZxwJXUsDYcBlAvZGZLi+/354l35J1wkmP6CqYaw==", + "version": "1.4.569", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.569.tgz", + "integrity": "sha512-LsrJjZ0IbVy12ApW3gpYpcmHS3iRxH4bkKOW98y1/D+3cvDUWGcbzbsFinfUS8knpcZk/PG/2p/RnkMCYN7PVg==", "dev": true }, "node_modules/emittery": { @@ -4268,26 +4280,26 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", - "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", + "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", "dev": true, "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.findlastindex": "^1.2.2", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", + "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.8.0", - "has": "^1.0.3", - "is-core-module": "^2.13.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.6", - "object.groupby": "^1.0.0", - "object.values": "^1.1.6", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", "semver": "^6.3.1", "tsconfig-paths": "^3.14.2" }, @@ -4910,9 +4922,9 @@ } }, "node_modules/figlet": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.6.0.tgz", - "integrity": "sha512-31EQGhCEITv6+hi2ORRPyn3bulaV9Fl4xOdR169cBzH/n1UqcxsiSB/noo6SJdD7Kfb1Ljit+IgR1USvF/XbdA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.7.0.tgz", + "integrity": "sha512-gO8l3wvqo0V7wEFLXPbkX83b7MVjRrk1oRLfYlZXol8nEpb/ON9pcKLI4qpBv5YtOTfrINtqb7b40iYY2FTWFg==", "dev": true, "bin": { "figlet": "bin/index.js" @@ -5624,15 +5636,6 @@ "node": ">=6" } }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -10764,11 +10767,12 @@ } }, "node_modules/selfsigned": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", - "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "dev": true, "dependencies": { + "@types/node-forge": "^1.3.0", "node-forge": "^1" }, "engines": { @@ -14300,6 +14304,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/unicode-length": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.1.0.tgz", diff --git a/deps/undici/src/package.json b/deps/undici/src/package.json index 31e157de002b20..454271d7b466f4 100644 --- a/deps/undici/src/package.json +++ b/deps/undici/src/package.json @@ -1,6 +1,6 @@ { "name": "undici", - "version": "5.26.4", + "version": "5.27.0", "description": "An HTTP/1.1 client, written from scratch for Node.js", "homepage": "https://undici.nodejs.org", "bugs": { @@ -84,7 +84,7 @@ "test:tdd": "tap test/*.js test/diagnostics-channel/*.js -w", "test:typescript": "node scripts/verifyVersion.js 14 || tsd && tsc --skipLibCheck test/imports/undici-import.ts", "test:websocket": "node scripts/verifyVersion.js 18 || tap test/websocket/*.js", - "test:wpt": "node scripts/verifyVersion 18 || (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 --no-warnings --expose-internals test/wpt/start-websockets.mjs)", + "test:wpt": "node scripts/verifyVersion 18 || (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)", "coverage": "nyc --reporter=text --reporter=html npm run test", "coverage:ci": "nyc --reporter=lcov npm run test", "bench": "PORT=3042 concurrently -k -s first npm:bench:server npm:bench:run", diff --git a/deps/undici/src/types/index.d.ts b/deps/undici/src/types/index.d.ts index c7532d69a073cc..4589845b4a9bd2 100644 --- a/deps/undici/src/types/index.d.ts +++ b/deps/undici/src/types/index.d.ts @@ -53,5 +53,11 @@ declare namespace Undici { var MockAgent: typeof import('./mock-agent').default; var mockErrors: typeof import('./mock-errors').default; var fetch: typeof import('./fetch').fetch; + var Headers: typeof import('./fetch').Headers; + var Response: typeof import('./fetch').Response; + var Request: typeof import('./fetch').Request; + var FormData: typeof import('./formdata').FormData; + var File: typeof import('./file').File; + var FileReader: typeof import('./filereader').FileReader; var caches: typeof import('./cache').caches; } diff --git a/deps/undici/undici.js b/deps/undici/undici.js index 068edd28b16ee5..a5da33fa3b0075 100644 --- a/deps/undici/undici.js +++ b/deps/undici/undici.js @@ -762,8 +762,10 @@ var require_constants = __commonJS({ "use strict"; var { MessageChannel, receiveMessageOnPort } = require("worker_threads"); var corsSafeListedMethods = ["GET", "HEAD", "POST"]; + var corsSafeListedMethodsSet = new Set(corsSafeListedMethods); var nullBodyStatus = [101, 204, 205, 304]; var redirectStatus = [301, 302, 303, 307, 308]; + var redirectStatusSet = new Set(redirectStatus); var badPorts = [ "1", "7", @@ -846,6 +848,7 @@ var require_constants = __commonJS({ "6697", "10080" ]; + var badPortsSet = new Set(badPorts); var referrerPolicy = [ "", "no-referrer", @@ -857,8 +860,10 @@ var require_constants = __commonJS({ "strict-origin-when-cross-origin", "unsafe-url" ]; + var referrerPolicySet = new Set(referrerPolicy); var requestRedirect = ["follow", "manual", "error"]; var safeMethods = ["GET", "HEAD", "OPTIONS", "TRACE"]; + var safeMethodsSet = new Set(safeMethods); var requestMode = ["navigate", "same-origin", "no-cors", "cors"]; var requestCredentials = ["omit", "same-origin", "include"]; var requestCache = [ @@ -884,6 +889,7 @@ var require_constants = __commonJS({ "half" ]; var forbiddenMethods = ["CONNECT", "TRACE", "TRACK"]; + var forbiddenMethodsSet = new Set(forbiddenMethods); var subresource = [ "audio", "audioworklet", @@ -898,6 +904,7 @@ var require_constants = __commonJS({ "xslt", "" ]; + var subresourceSet = new Set(subresource); var DOMException = globalThis.DOMException ?? (() => { try { atob("~"); @@ -936,7 +943,14 @@ var require_constants = __commonJS({ nullBodyStatus, safeMethods, badPorts, - requestDuplex + requestDuplex, + subresourceSet, + badPortsSet, + redirectStatusSet, + corsSafeListedMethodsSet, + safeMethodsSet, + forbiddenMethodsSet, + referrerPolicySet }; } }); @@ -983,7 +997,7 @@ var require_global = __commonJS({ var require_util2 = __commonJS({ "lib/fetch/util.js"(exports2, module2) { "use strict"; - var { redirectStatus, badPorts, referrerPolicy: referrerPolicyTokens } = require_constants(); + var { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = require_constants(); var { getGlobalOrigin } = require_global(); var { performance: performance2 } = require("perf_hooks"); var { isBlobLike, toUSVString, ReadableStreamFrom } = require_util(); @@ -1001,7 +1015,7 @@ var require_util2 = __commonJS({ } __name(responseURL, "responseURL"); function responseLocationURL(response, requestFragment) { - if (!redirectStatus.includes(response.status)) { + if (!redirectStatusSet.has(response.status)) { return null; } let location = response.headersList.get("location"); @@ -1020,7 +1034,7 @@ var require_util2 = __commonJS({ __name(requestCurrentURL, "requestCurrentURL"); function requestBadPort(request) { const url = requestCurrentURL(request); - if (urlIsHttpHttpsScheme(url) && badPorts.includes(url.port)) { + if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { return "blocked"; } return "allowed"; @@ -1083,7 +1097,7 @@ var require_util2 = __commonJS({ if (policyHeader.length > 0) { for (let i = policyHeader.length; i !== 0; i--) { const token = policyHeader[i - 1].trim(); - if (referrerPolicyTokens.includes(token)) { + if (referrerPolicyTokens.has(token)) { policy = token; break; } @@ -4037,6 +4051,7 @@ var require_file = __commonJS({ var { webidl } = require_webidl(); var { parseMIMEType, serializeAMimeType } = require_dataURL(); var { kEnumerableProperty } = require_util(); + var encoder = new TextEncoder(); var File = class _File extends Blob2 { static { __name(this, "File"); @@ -4188,7 +4203,7 @@ var require_file = __commonJS({ if (options.endings === "native") { s = convertLineEndingsNative(s); } - bytes.push(new TextEncoder().encode(s)); + bytes.push(encoder.encode(s)); } else if (types.isAnyArrayBuffer(element) || types.isTypedArray(element)) { if (!element.buffer) { bytes.push(new Uint8Array(element)); @@ -4407,6 +4422,8 @@ var require_body = __commonJS({ var { parseMIMEType, serializeAMimeType } = require_dataURL(); var ReadableStream = globalThis.ReadableStream; var File = NativeFile ?? UndiciFile; + var textEncoder = new TextEncoder(); + var textDecoder = new TextDecoder(); function extractBody(object, keepalive = false) { if (!ReadableStream) { ReadableStream = require("stream/web").ReadableStream; @@ -4420,7 +4437,7 @@ var require_body = __commonJS({ stream = new ReadableStream({ async pull(controller) { controller.enqueue( - typeof source === "string" ? new TextEncoder().encode(source) : source + typeof source === "string" ? textEncoder.encode(source) : source ); queueMicrotask(() => readableStreamClose(controller)); }, @@ -4450,21 +4467,20 @@ var require_body = __commonJS({ Content-Disposition: form-data`; const escape = /* @__PURE__ */ __name((str) => str.replace(/\n/g, "%0A").replace(/\r/g, "%0D").replace(/"/g, "%22"), "escape"); const normalizeLinefeeds = /* @__PURE__ */ __name((value) => value.replace(/\r?\n|\r/g, "\r\n"), "normalizeLinefeeds"); - const enc = new TextEncoder(); const blobParts = []; const rn = new Uint8Array([13, 10]); length = 0; let hasUnknownSizeValue = false; for (const [name, value] of object) { if (typeof value === "string") { - const chunk2 = enc.encode(prefix + `; name="${escape(normalizeLinefeeds(name))}"\r + const chunk2 = textEncoder.encode(prefix + `; name="${escape(normalizeLinefeeds(name))}"\r \r ${normalizeLinefeeds(value)}\r `); blobParts.push(chunk2); length += chunk2.byteLength; } else { - const chunk2 = enc.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + (value.name ? `; filename="${escape(value.name)}"` : "") + `\r + const chunk2 = textEncoder.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + (value.name ? `; filename="${escape(value.name)}"` : "") + `\r Content-Type: ${value.type || "application/octet-stream"}\r \r `); @@ -4476,7 +4492,7 @@ Content-Type: ${value.type || "application/octet-stream"}\r } } } - const chunk = enc.encode(`--${boundary}--`); + const chunk = textEncoder.encode(`--${boundary}--`); blobParts.push(chunk); length += chunk.byteLength; if (hasUnknownSizeValue) { @@ -4671,14 +4687,14 @@ Content-Type: ${value.type || "application/octet-stream"}\r let entries; try { let text = ""; - const textDecoder = new TextDecoder("utf-8", { ignoreBOM: true }); + const streamingDecoder = new TextDecoder("utf-8", { ignoreBOM: true }); for await (const chunk of consumeBody(this[kState].body)) { if (!isUint8Array(chunk)) { throw new TypeError("Expected Uint8Array chunk"); } - text += textDecoder.decode(chunk, { stream: true }); + text += streamingDecoder.decode(chunk, { stream: true }); } - text += textDecoder.decode(); + text += streamingDecoder.decode(); entries = new URLSearchParams(text); } catch (err) { throw Object.assign(new TypeError(), { cause: err }); @@ -4739,7 +4755,7 @@ Content-Type: ${value.type || "application/octet-stream"}\r if (buffer[0] === 239 && buffer[1] === 187 && buffer[2] === 191) { buffer = buffer.subarray(3); } - const output = new TextDecoder().decode(buffer); + const output = textDecoder.decode(buffer); return output; } __name(utf8DecodeBytes, "utf8DecodeBytes"); @@ -4783,7 +4799,7 @@ var require_response = __commonJS({ isomorphicEncode } = require_util2(); var { - redirectStatus, + redirectStatusSet, nullBodyStatus, DOMException } = require_constants(); @@ -4796,6 +4812,7 @@ var require_response = __commonJS({ var assert = require("assert"); var { types } = require("util"); var ReadableStream = globalThis.ReadableStream || require("stream/web").ReadableStream; + var textEncoder = new TextEncoder("utf-8"); var Response = class _Response { static { __name(this, "Response"); @@ -4817,7 +4834,7 @@ var require_response = __commonJS({ if (init !== null) { init = webidl.converters.ResponseInit(init); } - const bytes = new TextEncoder("utf-8").encode( + const bytes = textEncoder.encode( serializeJavascriptValueToJSONString(data) ); const body = extractBody(bytes); @@ -4843,7 +4860,7 @@ var require_response = __commonJS({ cause: err }); } - if (!redirectStatus.includes(status)) { + if (!redirectStatusSet.has(status)) { throw new RangeError("Invalid status code " + status); } const responseObject = new _Response(); @@ -5216,8 +5233,8 @@ var require_request = __commonJS({ makePolicyContainer } = require_util2(); var { - forbiddenMethods, - corsSafeListedMethods, + forbiddenMethodsSet, + corsSafeListedMethodsSet, referrerPolicy, requestRedirect, requestMode, @@ -5410,7 +5427,7 @@ var require_request = __commonJS({ if (!isValidHTTPToken(init.method)) { throw TypeError(`'${init.method}' is not a valid HTTP method.`); } - if (forbiddenMethods.indexOf(method.toUpperCase()) !== -1) { + if (forbiddenMethodsSet.has(method.toUpperCase())) { throw TypeError(`'${init.method}' HTTP method is unsupported.`); } method = normalizeMethod(init.method); @@ -5457,7 +5474,7 @@ var require_request = __commonJS({ this[kHeaders][kGuard] = "request"; this[kHeaders][kRealm] = this[kRealm]; if (mode === "no-cors") { - if (!corsSafeListedMethods.includes(request.method)) { + if (!corsSafeListedMethodsSet.has(request.method)) { throw new TypeError( `'${request.method} is unsupported in no-cors mode.` ); @@ -6544,6 +6561,13 @@ var require_request2 = __commonJS({ if (channels.bodySent.hasSubscribers) { channels.bodySent.publish({ request: this }); } + if (this[kHandler].onRequestSent) { + try { + this[kHandler].onRequestSent(); + } catch (err) { + this.onError(err); + } + } } onConnect(abort) { assert(!this.aborted); @@ -9448,11 +9472,11 @@ var require_fetch = __commonJS({ var assert = require("assert"); var { safelyExtractBody } = require_body(); var { - redirectStatus, + redirectStatusSet, nullBodyStatus, - safeMethods, + safeMethodsSet, requestBodyHeader, - subresource, + subresourceSet, DOMException } = require_constants(); var { kHeadersList } = require_symbols(); @@ -9464,6 +9488,7 @@ var require_fetch = __commonJS({ var { getGlobalDispatcher } = require_global2(); var { webidl } = require_webidl(); var { STATUS_CODES } = require("http"); + var GET_OR_HEAD = ["GET", "HEAD"]; var resolveObjectURL; var ReadableStream = globalThis.ReadableStream; var Fetch = class extends EE { @@ -9500,7 +9525,7 @@ var require_fetch = __commonJS({ this.emit("terminated", error); } }; - async function fetch2(input, init = {}) { + function fetch2(input, init = {}) { webidl.argumentLengthCheck(arguments, 1, { header: "globalThis.fetch" }); const p = createDeferredPromise(); let requestObject; @@ -9535,17 +9560,17 @@ var require_fetch = __commonJS({ const handleFetchDone = /* @__PURE__ */ __name((response) => finalizeAndReportTiming(response, "fetch"), "handleFetchDone"); const processResponse = /* @__PURE__ */ __name((response) => { if (locallyAborted) { - return; + return Promise.resolve(); } if (response.aborted) { abortFetch(p, request, responseObject, controller.serializedAbortReason); - return; + return Promise.resolve(); } if (response.type === "error") { p.reject( Object.assign(new TypeError("fetch failed"), { cause: response.error }) ); - return; + return Promise.resolve(); } responseObject = new Response(); responseObject[kState] = response; @@ -9689,7 +9714,7 @@ var require_fetch = __commonJS({ } if (request.priority === null) { } - if (subresource.includes(request.destination)) { + if (subresourceSet.has(request.destination)) { } mainFetch(fetchParams).catch((err) => { fetchParams.controller.terminate(err); @@ -9795,15 +9820,15 @@ var require_fetch = __commonJS({ } } __name(mainFetch, "mainFetch"); - async function schemeFetch(fetchParams) { + function schemeFetch(fetchParams) { if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { - return makeAppropriateNetworkError(fetchParams); + return Promise.resolve(makeAppropriateNetworkError(fetchParams)); } const { request } = fetchParams; const { protocol: scheme } = requestCurrentURL(request); switch (scheme) { case "about:": { - return makeNetworkError("about scheme is not supported"); + return Promise.resolve(makeNetworkError("about scheme is not supported")); } case "blob:": { if (!resolveObjectURL) { @@ -9811,11 +9836,11 @@ var require_fetch = __commonJS({ } const blobURLEntry = requestCurrentURL(request); if (blobURLEntry.search.length !== 0) { - return makeNetworkError("NetworkError when attempting to fetch resource."); + return Promise.resolve(makeNetworkError("NetworkError when attempting to fetch resource.")); } const blobURLEntryObject = resolveObjectURL(blobURLEntry.toString()); if (request.method !== "GET" || !isBlobLike(blobURLEntryObject)) { - return makeNetworkError("invalid method"); + return Promise.resolve(makeNetworkError("invalid method")); } const bodyWithType = safelyExtractBody(blobURLEntryObject); const body = bodyWithType[0]; @@ -9829,32 +9854,32 @@ var require_fetch = __commonJS({ ] }); response.body = body; - return response; + return Promise.resolve(response); } case "data:": { const currentURL = requestCurrentURL(request); const dataURLStruct = dataURLProcessor(currentURL); if (dataURLStruct === "failure") { - return makeNetworkError("failed to fetch the data URL"); + return Promise.resolve(makeNetworkError("failed to fetch the data URL")); } const mimeType = serializeAMimeType(dataURLStruct.mimeType); - return makeResponse({ + return Promise.resolve(makeResponse({ statusText: "OK", headersList: [ ["content-type", { name: "Content-Type", value: mimeType }] ], body: safelyExtractBody(dataURLStruct.body)[0] - }); + })); } case "file:": { - return makeNetworkError("not implemented... yet..."); + return Promise.resolve(makeNetworkError("not implemented... yet...")); } case "http:": case "https:": { - return await httpFetch(fetchParams).catch((err) => makeNetworkError(err)); + return httpFetch(fetchParams).catch((err) => makeNetworkError(err)); } default: { - return makeNetworkError("unknown scheme"); + return Promise.resolve(makeNetworkError("unknown scheme")); } } } @@ -9866,7 +9891,7 @@ var require_fetch = __commonJS({ } } __name(finalizeResponse, "finalizeResponse"); - async function fetchFinale(fetchParams, response) { + function fetchFinale(fetchParams, response) { if (response.type === "error") { response.urlList = [fetchParams.request.urlList[0]]; response.timingInfo = createOpaqueTimingInfo({ @@ -9910,8 +9935,9 @@ var require_fetch = __commonJS({ if (response.body == null) { queueMicrotask(() => processBody(null)); } else { - await fullyReadBody(response.body, processBody, processBodyError); + return fullyReadBody(response.body, processBody, processBodyError); } + return Promise.resolve(); } } __name(fetchFinale, "fetchFinale"); @@ -9942,7 +9968,7 @@ var require_fetch = __commonJS({ ) === "blocked") { return makeNetworkError("blocked"); } - if (redirectStatus.includes(actualResponse.status)) { + if (redirectStatusSet.has(actualResponse.status)) { if (request.redirect !== "manual") { fetchParams.controller.connection.destroy(); } @@ -9960,7 +9986,7 @@ var require_fetch = __commonJS({ return response; } __name(httpFetch, "httpFetch"); - async function httpRedirectFetch(fetchParams, response) { + function httpRedirectFetch(fetchParams, response) { const request = fetchParams.request; const actualResponse = response.internalResponse ? response.internalResponse : response; let locationURL; @@ -9973,27 +9999,27 @@ var require_fetch = __commonJS({ return response; } } catch (err) { - return makeNetworkError(err); + return Promise.resolve(makeNetworkError(err)); } if (!urlIsHttpHttpsScheme(locationURL)) { - return makeNetworkError("URL scheme must be a HTTP(S) scheme"); + return Promise.resolve(makeNetworkError("URL scheme must be a HTTP(S) scheme")); } if (request.redirectCount === 20) { - return makeNetworkError("redirect count exceeded"); + return Promise.resolve(makeNetworkError("redirect count exceeded")); } request.redirectCount += 1; if (request.mode === "cors" && (locationURL.username || locationURL.password) && !sameOrigin(request, locationURL)) { - return makeNetworkError('cross origin not allowed for request mode "cors"'); + return Promise.resolve(makeNetworkError('cross origin not allowed for request mode "cors"')); } if (request.responseTainting === "cors" && (locationURL.username || locationURL.password)) { - return makeNetworkError( + return Promise.resolve(makeNetworkError( 'URL cannot contain credentials for request mode "cors"' - ); + )); } if (actualResponse.status !== 303 && request.body != null && request.body.source == null) { - return makeNetworkError(); + return Promise.resolve(makeNetworkError()); } - if ([301, 302].includes(actualResponse.status) && request.method === "POST" || actualResponse.status === 303 && !["GET", "HEAD"].includes(request.method)) { + if ([301, 302].includes(actualResponse.status) && request.method === "POST" || actualResponse.status === 303 && !GET_OR_HEAD.includes(request.method)) { request.method = "GET"; request.body = null; for (const headerName of requestBodyHeader) { @@ -10097,7 +10123,7 @@ var require_fetch = __commonJS({ includeCredentials, isNewConnectionFetch ); - if (!safeMethods.includes(httpRequest.method) && forwardResponse.status >= 200 && forwardResponse.status <= 399) { + if (!safeMethodsSet.has(httpRequest.method) && forwardResponse.status >= 200 && forwardResponse.status <= 399) { } if (revalidatingFlag && forwardResponse.status === 304) { } @@ -10363,7 +10389,7 @@ var require_fetch = __commonJS({ } this.body = new Readable({ read: resume }); const decoders = []; - const willFollow = request.redirect === "follow" && location && redirectStatus.includes(status); + const willFollow = request.redirect === "follow" && location && redirectStatusSet.has(status); if (request.method !== "HEAD" && request.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { for (const coding of codings) { if (coding === "x-gzip" || coding === "gzip") { @@ -11723,13 +11749,11 @@ var require_websocket = __commonJS({ // index-fetch.js var fetchImpl = require_fetch().fetch; -module.exports.fetch = /* @__PURE__ */ __name(async function fetch(resource, init = void 0) { - try { - return await fetchImpl(resource, init); - } catch (err) { +module.exports.fetch = /* @__PURE__ */ __name(function fetch(resource, init = void 0) { + return fetchImpl(resource, init).catch((err) => { Error.captureStackTrace(err, this); throw err; - } + }); }, "fetch"); module.exports.FormData = require_formdata().FormData; module.exports.Headers = require_headers().Headers; diff --git a/doc/contributing/maintaining/maintaining-dependencies.md b/doc/contributing/maintaining/maintaining-dependencies.md index 4960f907141f79..94e88014a57e14 100644 --- a/doc/contributing/maintaining/maintaining-dependencies.md +++ b/doc/contributing/maintaining/maintaining-dependencies.md @@ -28,7 +28,7 @@ This a list of all the dependencies: * [openssl 3.0.8][] * [postject 1.0.0-alpha.6][] * [simdutf 3.2.18][] -* [undici 5.26.4][] +* [undici 5.27.0][] * [uvwasi 0.0.19][] * [V8 11.8.172.12][] * [zlib 1.2.13.1-motley-fef5869][] @@ -291,7 +291,7 @@ The [postject](https://github.com/nodejs/postject) dependency is used for the The [simdutf](https://github.com/simdutf/simdutf) dependency is a C++ library for fast UTF-8 decoding and encoding. -### undici 5.26.4 +### undici 5.27.0 The [undici](https://github.com/nodejs/undici) dependency is an HTTP/1.1 client, written from scratch for Node.js.. @@ -345,7 +345,7 @@ performance improvements not currently available in standard zlib. [openssl 3.0.8]: #openssl-308 [postject 1.0.0-alpha.6]: #postject-100-alpha6 [simdutf 3.2.18]: #simdutf-3218 -[undici 5.26.4]: #undici-5264 +[undici 5.27.0]: #undici-5270 [update-openssl-action]: ../../../.github/workflows/update-openssl.yml [uvwasi 0.0.19]: #uvwasi-0019 [v8 11.8.172.12]: #v8-11817212 diff --git a/src/undici_version.h b/src/undici_version.h index a18545b5072461..930c2318ec80bd 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 "5.26.4" +#define UNDICI_VERSION "5.27.0" #endif // SRC_UNDICI_VERSION_H_