deps: update undici to 5.20.0

PR-URL: https://github.com/nodejs/node/pull/46711
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
This commit is contained in:
Node.js GitHub Bot 2023-02-18 13:30:11 +01:00 committed by GitHub
parent 132c383b18
commit 41a1bccf43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 95 additions and 60 deletions

View File

@ -405,6 +405,18 @@ implementations in Deno and Cloudflare Workers.
Refs: https://fetch.spec.whatwg.org/#atomic-http-redirect-handling Refs: https://fetch.spec.whatwg.org/#atomic-http-redirect-handling
## Workarounds
### Network address family autoselection.
If you experience problem when connecting to a remote server that is resolved by your DNS servers to a IPv6 (AAAA record)
first, there are chances that your local router or ISP might have problem connecting to IPv6 networks. In that case
undici will throw an error with code `UND_ERR_CONNECT_TIMEOUT`.
If the target server resolves to both a IPv6 and IPv4 (A records) address and you are using a compatible Node version
(18.3.0 and above), you can fix the problem by providing the `autoSelectFamily` option (support by both `undici.request`
and `undici.Agent`) which will enable the family autoselection algorithm when establishing the connection.
## Collaborators ## Collaborators
* [__Daniele Belardi__](https://github.com/dnlup), <https://www.npmjs.com/~dnlup> * [__Daniele Belardi__](https://github.com/dnlup), <https://www.npmjs.com/~dnlup>

View File

@ -17,8 +17,8 @@ Returns: `Client`
### Parameter: `ClientOptions` ### Parameter: `ClientOptions`
* **bodyTimeout** `number | null` (optional) - Default: `30e3` - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 30 seconds. * **bodyTimeout** `number | null` (optional) - Default: `300e3` - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 300 seconds.
* **headersTimeout** `number | null` (optional) - Default: `30e3` - The amount of time the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 30 seconds. * **headersTimeout** `number | null` (optional) - Default: `300e3` - The amount of time the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 300 seconds.
* **keepAliveMaxTimeout** `number | null` (optional) - Default: `600e3` - The maximum allowed `keepAliveTimeout` when overridden by *keep-alive* hints from the server. Defaults to 10 minutes. * **keepAliveMaxTimeout** `number | null` (optional) - Default: `600e3` - The maximum allowed `keepAliveTimeout` when overridden by *keep-alive* hints from the server. Defaults to 10 minutes.
* **keepAliveTimeout** `number | null` (optional) - Default: `4e3` - The timeout after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details. Defaults to 4 seconds. * **keepAliveTimeout** `number | null` (optional) - Default: `4e3` - The timeout after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details. Defaults to 4 seconds.
* **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `1e3` - A number subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 1 second. * **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `1e3` - A number subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 1 second.
@ -28,6 +28,8 @@ Returns: `Client`
* **connect** `ConnectOptions | Function | null` (optional) - Default: `null`. * **connect** `ConnectOptions | Function | null` (optional) - Default: `null`.
* **strictContentLength** `Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body. * **strictContentLength** `Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body.
* **interceptors** `{ Client: DispatchInterceptor[] }` - Default: `[RedirectInterceptor]` - A list of interceptors that are applied to the dispatch method. Additional logic can be applied (such as, but not limited to: 302 status code handling, authentication, cookies, compression and caching). Note that the behavior of interceptors is Experimental and might change at any given time. * **interceptors** `{ Client: DispatchInterceptor[] }` - Default: `[RedirectInterceptor]` - A list of interceptors that are applied to the dispatch method. Additional logic can be applied (such as, but not limited to: 302 status code handling, authentication, cookies, compression and caching). Note that the behavior of interceptors is Experimental and might change at any given time.
* **autoSelectFamily**: `boolean` (optional) - Default: depends on local Node version, on Node 18.13.0 and above is `false`. Enables a family autodetection algorithm that loosely implements section 5 of [RFC 8305](https://tools.ietf.org/html/rfc8305#section-5). See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details. This option is ignored if not supported by the current Node version.
* **autoSelectFamilyAttemptTimeout**: `number` - Default: depends on local Node version, on Node 18.13.0 and above is `250`. The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details.
#### Parameter: `ConnectOptions` #### Parameter: `ConnectOptions`

View File

@ -74,7 +74,7 @@ Returns: `void | Promise<ConnectData>` - Only returns a `Promise` if no `callbac
#### Parameter: `ConnectData` #### Parameter: `ConnectData`
* **statusCode** `number` * **statusCode** `number`
* **headers** `Record<string, string | string[]>` * **headers** `Record<string, string | string[] | undefined>`
* **socket** `stream.Duplex` * **socket** `stream.Duplex`
* **opaque** `unknown` * **opaque** `unknown`
@ -199,8 +199,8 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo
* **idempotent** `boolean` (optional) - Default: `true` if `method` is `'HEAD'` or `'GET'` - Whether the requests can be safely retried or not. If `false` the request won't be sent until all preceding requests in the pipeline has completed. * **idempotent** `boolean` (optional) - Default: `true` if `method` is `'HEAD'` or `'GET'` - Whether the requests can be safely retried or not. If `false` the request won't be sent until all preceding requests in the pipeline has completed.
* **blocking** `boolean` (optional) - Default: `false` - Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received. * **blocking** `boolean` (optional) - Default: `false` - Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received.
* **upgrade** `string | null` (optional) - Default: `null` - Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`. * **upgrade** `string | null` (optional) - Default: `null` - Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`.
* **bodyTimeout** `number | null` (optional) - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 30 seconds. * **bodyTimeout** `number | null` (optional) - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 300 seconds.
* **headersTimeout** `number | null` (optional) - The amount of time the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 30 seconds. * **headersTimeout** `number | null` (optional) - The amount of time the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 300 seconds.
* **throwOnError** `boolean` (optional) - Default: `false` - Whether Undici should throw an error upon receiving a 4xx or 5xx response from the server. * **throwOnError** `boolean` (optional) - Default: `false` - Whether Undici should throw an error upon receiving a 4xx or 5xx response from the server.
#### Parameter: `DispatchHandler` #### Parameter: `DispatchHandler`
@ -383,7 +383,7 @@ Extends: [`RequestOptions`](#parameter-requestoptions)
#### Parameter: PipelineHandlerData #### Parameter: PipelineHandlerData
* **statusCode** `number` * **statusCode** `number`
* **headers** `Record<string, string | string[]>` * **headers** `Record<string, string | string[] | undefined>`
* **opaque** `unknown` * **opaque** `unknown`
* **body** `stream.Readable` * **body** `stream.Readable`
* **context** `object` * **context** `object`
@ -644,7 +644,7 @@ Returns: `void | Promise<StreamData>` - Only returns a `Promise` if no `callback
#### Parameter: `StreamFactoryData` #### Parameter: `StreamFactoryData`
* **statusCode** `number` * **statusCode** `number`
* **headers** `Record<string, string | string[]>` * **headers** `Record<string, string | string[] | undefined>`
* **opaque** `unknown` * **opaque** `unknown`
* **onInfo** `({statusCode: number, headers: Record<string, string | string[]>}) => void | null` (optional) - Default: `null` - Callback collecting all the info headers (HTTP 100-199) received. * **onInfo** `({statusCode: number, headers: Record<string, string | string[]>}) => void | null` (optional) - Default: `null` - Callback collecting all the info headers (HTTP 100-199) received.
@ -853,9 +853,9 @@ Emitted when dispatcher is no longer busy.
## Parameter: `UndiciHeaders` ## Parameter: `UndiciHeaders`
* `Record<string, string | string[]> | string[] | null` * `Record<string, string | string[] | undefined> | string[] | null`
Header arguments such as `options.headers` in [`Client.dispatch`](Client.md#clientdispatchoptions-handlers) can be specified in two forms; either as an object specified by the `Record<string, string | string[]>` (`IncomingHttpHeaders`) type, or an array of strings. An array representation of a header list must have an even length or an `InvalidArgumentError` will be thrown. Header arguments such as `options.headers` in [`Client.dispatch`](Client.md#clientdispatchoptions-handlers) can be specified in two forms; either as an object specified by the `Record<string, string | string[] | undefined>` (`IncomingHttpHeaders`) type, or an array of strings. An array representation of a header list must have an even length or an `InvalidArgumentError` will be thrown.
Keys are lowercase and values are not modified. Keys are lowercase and values are not modified.

View File

@ -20,10 +20,6 @@ const DecoratorHandler = require('./lib/handler/DecoratorHandler')
const RedirectHandler = require('./lib/handler/RedirectHandler') const RedirectHandler = require('./lib/handler/RedirectHandler')
const createRedirectInterceptor = require('./lib/interceptor/redirectInterceptor') const createRedirectInterceptor = require('./lib/interceptor/redirectInterceptor')
const nodeVersion = process.versions.node.split('.')
const nodeMajor = Number(nodeVersion[0])
const nodeMinor = Number(nodeVersion[1])
let hasCrypto let hasCrypto
try { try {
require('crypto') require('crypto')
@ -100,7 +96,7 @@ function makeDispatcher (fn) {
module.exports.setGlobalDispatcher = setGlobalDispatcher module.exports.setGlobalDispatcher = setGlobalDispatcher
module.exports.getGlobalDispatcher = getGlobalDispatcher module.exports.getGlobalDispatcher = getGlobalDispatcher
if (nodeMajor > 16 || (nodeMajor === 16 && nodeMinor >= 8)) { if (util.nodeMajor > 16 || (util.nodeMajor === 16 && util.nodeMinor >= 8)) {
let fetchImpl = null let fetchImpl = null
module.exports.fetch = async function fetch (resource) { module.exports.fetch = async function fetch (resource) {
if (!fetchImpl) { if (!fetchImpl) {
@ -127,7 +123,7 @@ if (nodeMajor > 16 || (nodeMajor === 16 && nodeMinor >= 8)) {
module.exports.getGlobalOrigin = getGlobalOrigin module.exports.getGlobalOrigin = getGlobalOrigin
} }
if (nodeMajor >= 16) { if (util.nodeMajor >= 16) {
const { deleteCookie, getCookies, getSetCookies, setCookie } = require('./lib/cookies') const { deleteCookie, getCookies, getSetCookies, setCookie } = require('./lib/cookies')
module.exports.deleteCookie = deleteCookie module.exports.deleteCookie = deleteCookie
@ -141,7 +137,7 @@ if (nodeMajor >= 16) {
module.exports.serializeAMimeType = serializeAMimeType module.exports.serializeAMimeType = serializeAMimeType
} }
if (nodeMajor >= 18 && hasCrypto) { if (util.nodeMajor >= 18 && hasCrypto) {
const { WebSocket } = require('./lib/websocket/websocket') const { WebSocket } = require('./lib/websocket/websocket')
module.exports.WebSocket = WebSocket module.exports.WebSocket = WebSocket

View File

@ -109,7 +109,9 @@ class Client extends DispatcherBase {
connect, connect,
maxRequestsPerClient, maxRequestsPerClient,
localAddress, localAddress,
maxResponseSize maxResponseSize,
autoSelectFamily,
autoSelectFamilyAttemptTimeout
} = {}) { } = {}) {
super() super()
@ -185,12 +187,20 @@ class Client extends DispatcherBase {
throw new InvalidArgumentError('maxResponseSize must be a positive number') throw new InvalidArgumentError('maxResponseSize must be a positive number')
} }
if (
autoSelectFamilyAttemptTimeout != null &&
(!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1)
) {
throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number')
}
if (typeof connect !== 'function') { if (typeof connect !== 'function') {
connect = buildConnector({ connect = buildConnector({
...tls, ...tls,
maxCachedSessions, maxCachedSessions,
socketPath, socketPath,
timeout: connectTimeout, timeout: connectTimeout,
...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined),
...connect ...connect
}) })
} }
@ -212,8 +222,8 @@ class Client extends DispatcherBase {
this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming
this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming
this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n` this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n`
this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 30e3 this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3
this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 30e3 this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3
this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength
this[kMaxRedirections] = maxRedirections this[kMaxRedirections] = maxRedirections
this[kMaxRequests] = maxRequestsPerClient this[kMaxRequests] = maxRequestsPerClient

View File

@ -2,7 +2,7 @@
const { maxNameValuePairSize, maxAttributeValueSize } = require('./constants') const { maxNameValuePairSize, maxAttributeValueSize } = require('./constants')
const { isCTLExcludingHtab } = require('./util') const { isCTLExcludingHtab } = require('./util')
const { collectASequenceOfCodePoints } = require('../fetch/dataURL') const { collectASequenceOfCodePointsFast } = require('../fetch/dataURL')
const assert = require('assert') const assert = require('assert')
/** /**
@ -32,7 +32,7 @@ function parseSetCookie (header) {
// (including the %x3B (";") in question). // (including the %x3B (";") in question).
const position = { position: 0 } const position = { position: 0 }
nameValuePair = collectASequenceOfCodePoints((char) => char !== ';', header, position) nameValuePair = collectASequenceOfCodePointsFast(';', header, position)
unparsedAttributes = header.slice(position.position) unparsedAttributes = header.slice(position.position)
} else { } else {
// Otherwise: // Otherwise:
@ -54,8 +54,8 @@ function parseSetCookie (header) {
// empty) value string consists of the characters after the first // empty) value string consists of the characters after the first
// %x3D ("=") character. // %x3D ("=") character.
const position = { position: 0 } const position = { position: 0 }
name = collectASequenceOfCodePoints( name = collectASequenceOfCodePointsFast(
(char) => char !== '=', '=',
nameValuePair, nameValuePair,
position position
) )
@ -106,8 +106,8 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
if (unparsedAttributes.includes(';')) { if (unparsedAttributes.includes(';')) {
// 1. Consume the characters of the unparsed-attributes up to, but // 1. Consume the characters of the unparsed-attributes up to, but
// not including, the first %x3B (";") character. // not including, the first %x3B (";") character.
cookieAv = collectASequenceOfCodePoints( cookieAv = collectASequenceOfCodePointsFast(
(char) => char !== ';', ';',
unparsedAttributes, unparsedAttributes,
{ position: 0 } { position: 0 }
) )
@ -134,8 +134,8 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
// character. // character.
const position = { position: 0 } const position = { position: 0 }
attributeName = collectASequenceOfCodePoints( attributeName = collectASequenceOfCodePointsFast(
(char) => char !== '=', '=',
cookieAv, cookieAv,
position position
) )

View File

@ -34,10 +34,6 @@ const channels = {}
let extractBody let extractBody
const nodeVersion = process.versions.node.split('.')
const nodeMajor = Number(nodeVersion[0])
const nodeMinor = Number(nodeVersion[1])
try { try {
const diagnosticsChannel = require('diagnostics_channel') const diagnosticsChannel = require('diagnostics_channel')
channels.create = diagnosticsChannel.channel('undici:request:create') channels.create = diagnosticsChannel.channel('undici:request:create')
@ -172,7 +168,7 @@ class Request {
} }
if (util.isFormDataLike(this.body)) { if (util.isFormDataLike(this.body)) {
if (nodeMajor < 16 || (nodeMajor === 16 && nodeMinor < 8)) { if (util.nodeMajor < 16 || (util.nodeMajor === 16 && util.nodeMinor < 8)) {
throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.8 and newer.') throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.8 and newer.')
} }

View File

@ -10,6 +10,8 @@ const { Blob } = require('buffer')
const nodeUtil = require('util') const nodeUtil = require('util')
const { stringify } = require('querystring') const { stringify } = require('querystring')
const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v))
function nop () {} function nop () {}
function isStream (obj) { function isStream (obj) {
@ -420,5 +422,8 @@ module.exports = {
validateHandler, validateHandler,
getSocketInfo, getSocketInfo,
isFormDataLike, isFormDataLike,
buildURL buildURL,
nodeMajor,
nodeMinor,
nodeHasAutoSelectFamily: nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 13)
} }

View File

@ -556,6 +556,7 @@ module.exports = {
dataURLProcessor, dataURLProcessor,
URLSerializer, URLSerializer,
collectASequenceOfCodePoints, collectASequenceOfCodePoints,
collectASequenceOfCodePointsFast,
stringPercentDecode, stringPercentDecode,
parseMIMEType, parseMIMEType,
collectAnHTTPQuotedString, collectAnHTTPQuotedString,

View File

@ -75,6 +75,7 @@ class HeadersList {
if (init instanceof HeadersList) { if (init instanceof HeadersList) {
this[kHeadersMap] = new Map(init[kHeadersMap]) this[kHeadersMap] = new Map(init[kHeadersMap])
this[kHeadersSortedMap] = init[kHeadersSortedMap] this[kHeadersSortedMap] = init[kHeadersSortedMap]
this.cookies = init.cookies
} else { } else {
this[kHeadersMap] = new Map(init) this[kHeadersMap] = new Map(init)
this[kHeadersSortedMap] = null this[kHeadersSortedMap] = null

View File

@ -53,7 +53,7 @@ const {
const { kHeadersList } = require('../core/symbols') const { kHeadersList } = require('../core/symbols')
const EE = require('events') const EE = require('events')
const { Readable, pipeline } = require('stream') const { Readable, pipeline } = require('stream')
const { isErrored, isReadable } = require('../core/util') const { isErrored, isReadable, nodeMajor, nodeMinor } = require('../core/util')
const { dataURLProcessor, serializeAMimeType } = require('./dataURL') const { dataURLProcessor, serializeAMimeType } = require('./dataURL')
const { TransformStream } = require('stream/web') const { TransformStream } = require('stream/web')
const { getGlobalDispatcher } = require('../global') const { getGlobalDispatcher } = require('../global')
@ -64,10 +64,6 @@ const { STATUS_CODES } = require('http')
let resolveObjectURL let resolveObjectURL
let ReadableStream = globalThis.ReadableStream let ReadableStream = globalThis.ReadableStream
const nodeVersion = process.versions.node.split('.')
const nodeMajor = Number(nodeVersion[0])
const nodeMinor = Number(nodeVersion[1])
class Fetch extends EE { class Fetch extends EE {
constructor (dispatcher) { constructor (dispatcher) {
super() super()

View File

@ -32,6 +32,8 @@ class Pool extends PoolBase {
tls, tls,
maxCachedSessions, maxCachedSessions,
socketPath, socketPath,
autoSelectFamily,
autoSelectFamilyAttemptTimeout,
...options ...options
} = {}) { } = {}) {
super() super()
@ -54,6 +56,7 @@ class Pool extends PoolBase {
maxCachedSessions, maxCachedSessions,
socketPath, socketPath,
timeout: connectTimeout == null ? 10e3 : connectTimeout, timeout: connectTimeout == null ? 10e3 : connectTimeout,
...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined),
...connect ...connect
}) })
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "undici", "name": "undici",
"version": "5.19.1", "version": "5.20.0",
"description": "An HTTP/1.1 client, written from scratch for Node.js", "description": "An HTTP/1.1 client, written from scratch for Node.js",
"homepage": "https://undici.nodejs.org", "homepage": "https://undici.nodejs.org",
"bugs": { "bugs": {
@ -78,6 +78,7 @@
"concurrently": "^7.1.0", "concurrently": "^7.1.0",
"cronometro": "^1.0.5", "cronometro": "^1.0.5",
"delay": "^5.0.0", "delay": "^5.0.0",
"dns-packet": "^5.4.0",
"docsify-cli": "^4.4.3", "docsify-cli": "^4.4.3",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"formdata-node": "^4.3.1", "formdata-node": "^4.3.1",
@ -91,14 +92,13 @@
"pre-commit": "^1.2.2", "pre-commit": "^1.2.2",
"proxy": "^1.0.2", "proxy": "^1.0.2",
"proxyquire": "^2.1.3", "proxyquire": "^2.1.3",
"semver": "^7.3.5",
"sinon": "^15.0.0", "sinon": "^15.0.0",
"snazzy": "^9.0.0", "snazzy": "^9.0.0",
"standard": "^17.0.0", "standard": "^17.0.0",
"table": "^6.8.0", "table": "^6.8.0",
"tap": "^16.1.0", "tap": "^16.1.0",
"tsd": "^0.25.0", "tsd": "^0.25.0",
"typescript": "^4.8.4", "typescript": "^4.9.5",
"wait-on": "^6.0.0", "wait-on": "^6.0.0",
"ws": "^8.11.0" "ws": "^8.11.0"
}, },

View File

@ -31,9 +31,9 @@ declare namespace Client {
connect?: buildConnector.BuildOptions | buildConnector.connector | null; connect?: buildConnector.BuildOptions | buildConnector.connector | null;
/** The maximum length of request headers in bytes. Default: `16384` (16KiB). */ /** The maximum length of request headers in bytes. Default: `16384` (16KiB). */
maxHeaderSize?: number | null; maxHeaderSize?: number | null;
/** The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Default: `30e3` milliseconds (30s). */ /** The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Default: `300e3` milliseconds (300s). */
bodyTimeout?: number | null; bodyTimeout?: number | null;
/** The amount of time the parser will wait to receive the complete HTTP headers (Node 14 and above only). Default: `30e3` milliseconds (30s). */ /** The amount of time the parser will wait to receive the complete HTTP headers (Node 14 and above only). Default: `300e3` milliseconds (300s). */
headersTimeout?: number | null; headersTimeout?: number | null;
/** If `true`, an error is thrown when the request content-length header doesn't match the length of the request body. Default: `true`. */ /** If `true`, an error is thrown when the request content-length header doesn't match the length of the request body. Default: `true`. */
strictContentLength?: boolean; strictContentLength?: boolean;
@ -43,6 +43,10 @@ declare namespace Client {
maxRequestsPerClient?: number; maxRequestsPerClient?: number;
/** Max response body size in bytes, -1 is disabled */ /** Max response body size in bytes, -1 is disabled */
maxResponseSize?: number | null; maxResponseSize?: number | null;
/** Enables a family autodetection algorithm that loosely implements section 5 of RFC 8305. */
autoSelectFamily?: boolean;
/** The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. */
autoSelectFamilyAttemptTimeout?: number;
interceptors?: {Client: readonly DispatchInterceptor[] | undefined} interceptors?: {Client: readonly DispatchInterceptor[] | undefined}
} }

View File

@ -109,9 +109,9 @@ declare namespace Dispatcher {
blocking?: boolean; blocking?: boolean;
/** Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`. Default: `method === 'CONNECT' || null`. */ /** Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`. Default: `method === 'CONNECT' || null`. */
upgrade?: boolean | string | null; upgrade?: boolean | string | null;
/** The amount of time the parser will wait to receive the complete HTTP headers. Defaults to 30 seconds. */ /** The amount of time the parser will wait to receive the complete HTTP headers. Defaults to 300 seconds. */
headersTimeout?: number | null; headersTimeout?: number | null;
/** The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use 0 to disable it entirely. Defaults to 30 seconds. */ /** The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use 0 to disable it entirely. Defaults to 300 seconds. */
bodyTimeout?: number | null; bodyTimeout?: number | null;
/** Whether the request should stablish a keep-alive or not. Default `false` */ /** Whether the request should stablish a keep-alive or not. Default `false` */
reset?: boolean; reset?: boolean;

View File

@ -1,4 +1,4 @@
/** /**
* The header type declaration of `undici`. * The header type declaration of `undici`.
*/ */
export type IncomingHttpHeaders = Record<string, string | string[]>; export type IncomingHttpHeaders = Record<string, string | string[] | undefined>;

33
deps/undici/undici.js vendored
View File

@ -296,6 +296,7 @@ var require_util = __commonJS({
var { Blob } = require("buffer"); var { Blob } = require("buffer");
var nodeUtil = require("util"); var nodeUtil = require("util");
var { stringify } = require("querystring"); var { stringify } = require("querystring");
var [nodeMajor, nodeMinor] = process.versions.node.split(".").map((v) => Number(v));
function nop() { function nop() {
} }
function isStream(obj) { function isStream(obj) {
@ -580,7 +581,10 @@ var require_util = __commonJS({
validateHandler, validateHandler,
getSocketInfo, getSocketInfo,
isFormDataLike, isFormDataLike,
buildURL buildURL,
nodeMajor,
nodeMinor,
nodeHasAutoSelectFamily: nodeMajor > 18 || nodeMajor === 18 && nodeMinor >= 13
}; };
} }
}); });
@ -1653,6 +1657,7 @@ var require_headers = __commonJS({
if (init instanceof HeadersList) { if (init instanceof HeadersList) {
this[kHeadersMap] = new Map(init[kHeadersMap]); this[kHeadersMap] = new Map(init[kHeadersMap]);
this[kHeadersSortedMap] = init[kHeadersSortedMap]; this[kHeadersSortedMap] = init[kHeadersSortedMap];
this.cookies = init.cookies;
} else { } else {
this[kHeadersMap] = new Map(init); this[kHeadersMap] = new Map(init);
this[kHeadersSortedMap] = null; this[kHeadersSortedMap] = null;
@ -5817,6 +5822,7 @@ var require_dataURL = __commonJS({
dataURLProcessor, dataURLProcessor,
URLSerializer, URLSerializer,
collectASequenceOfCodePoints, collectASequenceOfCodePoints,
collectASequenceOfCodePointsFast,
stringPercentDecode, stringPercentDecode,
parseMIMEType, parseMIMEType,
collectAnHTTPQuotedString, collectAnHTTPQuotedString,
@ -7978,9 +7984,6 @@ var require_request2 = __commonJS({
var kHandler = Symbol("handler"); var kHandler = Symbol("handler");
var channels = {}; var channels = {};
var extractBody; var extractBody;
var nodeVersion = process.versions.node.split(".");
var nodeMajor = Number(nodeVersion[0]);
var nodeMinor = Number(nodeVersion[1]);
try { try {
const diagnosticsChannel = require("diagnostics_channel"); const diagnosticsChannel = require("diagnostics_channel");
channels.create = diagnosticsChannel.channel("undici:request:create"); channels.create = diagnosticsChannel.channel("undici:request:create");
@ -8084,7 +8087,7 @@ var require_request2 = __commonJS({
throw new InvalidArgumentError("headers must be an object or an array"); throw new InvalidArgumentError("headers must be an object or an array");
} }
if (util.isFormDataLike(this.body)) { if (util.isFormDataLike(this.body)) {
if (nodeMajor < 16 || nodeMajor === 16 && nodeMinor < 8) { if (util.nodeMajor < 16 || util.nodeMajor === 16 && util.nodeMinor < 8) {
throw new InvalidArgumentError("Form-Data bodies are only supported in node v16.8 and newer."); throw new InvalidArgumentError("Form-Data bodies are only supported in node v16.8 and newer.");
} }
if (!extractBody) { if (!extractBody) {
@ -9002,7 +9005,9 @@ var require_client = __commonJS({
connect: connect2, connect: connect2,
maxRequestsPerClient, maxRequestsPerClient,
localAddress, localAddress,
maxResponseSize maxResponseSize,
autoSelectFamily,
autoSelectFamilyAttemptTimeout
} = {}) { } = {}) {
super(); super();
if (keepAlive !== void 0) { if (keepAlive !== void 0) {
@ -9059,12 +9064,16 @@ var require_client = __commonJS({
if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) { if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) {
throw new InvalidArgumentError("maxResponseSize must be a positive number"); throw new InvalidArgumentError("maxResponseSize must be a positive number");
} }
if (autoSelectFamilyAttemptTimeout != null && (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1)) {
throw new InvalidArgumentError("autoSelectFamilyAttemptTimeout must be a positive number");
}
if (typeof connect2 !== "function") { if (typeof connect2 !== "function") {
connect2 = buildConnector({ connect2 = buildConnector({
...tls, ...tls,
maxCachedSessions, maxCachedSessions,
socketPath, socketPath,
timeout: connectTimeout, timeout: connectTimeout,
...util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : void 0,
...connect2 ...connect2
}); });
} }
@ -9084,8 +9093,8 @@ var require_client = __commonJS({
this[kNeedDrain] = 0; this[kNeedDrain] = 0;
this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ""}\r this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ""}\r
`; `;
this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 3e4; this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 3e5;
this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 3e4; this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 3e5;
this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength; this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength;
this[kMaxRedirections] = maxRedirections; this[kMaxRedirections] = maxRedirections;
this[kMaxRequests] = maxRequestsPerClient; this[kMaxRequests] = maxRequestsPerClient;
@ -10251,6 +10260,8 @@ var require_pool = __commonJS({
tls, tls,
maxCachedSessions, maxCachedSessions,
socketPath, socketPath,
autoSelectFamily,
autoSelectFamilyAttemptTimeout,
...options ...options
} = {}) { } = {}) {
super(); super();
@ -10269,6 +10280,7 @@ var require_pool = __commonJS({
maxCachedSessions, maxCachedSessions,
socketPath, socketPath,
timeout: connectTimeout == null ? 1e4 : connectTimeout, timeout: connectTimeout == null ? 1e4 : connectTimeout,
...util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : void 0,
...connect ...connect
}); });
} }
@ -10496,7 +10508,7 @@ var require_fetch = __commonJS({
var { kHeadersList } = require_symbols(); var { kHeadersList } = require_symbols();
var EE = require("events"); var EE = require("events");
var { Readable, pipeline } = require("stream"); var { Readable, pipeline } = require("stream");
var { isErrored, isReadable } = require_util(); var { isErrored, isReadable, nodeMajor, nodeMinor } = require_util();
var { dataURLProcessor, serializeAMimeType } = require_dataURL(); var { dataURLProcessor, serializeAMimeType } = require_dataURL();
var { TransformStream } = require("stream/web"); var { TransformStream } = require("stream/web");
var { getGlobalDispatcher } = require_global2(); var { getGlobalDispatcher } = require_global2();
@ -10504,9 +10516,6 @@ var require_fetch = __commonJS({
var { STATUS_CODES } = require("http"); var { STATUS_CODES } = require("http");
var resolveObjectURL; var resolveObjectURL;
var ReadableStream = globalThis.ReadableStream; var ReadableStream = globalThis.ReadableStream;
var nodeVersion = process.versions.node.split(".");
var nodeMajor = Number(nodeVersion[0]);
var nodeMinor = Number(nodeVersion[1]);
var Fetch = class extends EE { var Fetch = class extends EE {
constructor(dispatcher) { constructor(dispatcher) {
super(); super();

View File

@ -2,5 +2,5 @@
// Refer to tools/update-undici.sh // Refer to tools/update-undici.sh
#ifndef SRC_UNDICI_VERSION_H_ #ifndef SRC_UNDICI_VERSION_H_
#define SRC_UNDICI_VERSION_H_ #define SRC_UNDICI_VERSION_H_
#define UNDICI_VERSION "5.19.1" #define UNDICI_VERSION "5.20.0"
#endif // SRC_UNDICI_VERSION_H_ #endif // SRC_UNDICI_VERSION_H_