Skip to content

Commit 520da34

Browse files
mcollinaRafaelGSS
authored andcommitted
deps: update undici to v6.21.1
Signed-off-by: Matteo Collina <[email protected]> PR-URL: nodejs-private/node-private#662 Reviewed-By: Rafael Gonzaga <[email protected]> CVE-ID: CVE-2025-22150
1 parent 99f2173 commit 520da34

File tree

13 files changed

+503
-10146
lines changed

13 files changed

+503
-10146
lines changed

deps/undici/src/docs/docs/api/Dispatcher.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,57 @@ client.dispatch(
986986
);
987987
```
988988

989+
##### `dns`
990+
991+
The `dns` interceptor enables you to cache DNS lookups for a given duration, per origin.
992+
993+
>It is well suited for scenarios where you want to cache DNS lookups to avoid the overhead of resolving the same domain multiple times
994+
995+
**Options**
996+
- `maxTTL` - The maximum time-to-live (in milliseconds) of the DNS cache. It should be a positive integer. Default: `10000`.
997+
- Set `0` to disable TTL.
998+
- `maxItems` - The maximum number of items to cache. It should be a positive integer. Default: `Infinity`.
999+
- `dualStack` - Whether to resolve both IPv4 and IPv6 addresses. Default: `true`.
1000+
- It will also attempt a happy-eyeballs-like approach to connect to the available addresses in case of a connection failure.
1001+
- `affinity` - Whether to use IPv4 or IPv6 addresses. Default: `4`.
1002+
- It can be either `'4` or `6`.
1003+
- It will only take effect if `dualStack` is `false`.
1004+
- `lookup: (hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException | null, addresses: DNSInterceptorRecord[]) => void) => void` - Custom lookup function. Default: `dns.lookup`.
1005+
- For more info see [dns.lookup](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback).
1006+
- `pick: (origin: URL, records: DNSInterceptorRecords, affinity: 4 | 6) => DNSInterceptorRecord` - Custom pick function. Default: `RoundRobin`.
1007+
- The function should return a single record from the records array.
1008+
- By default a simplified version of Round Robin is used.
1009+
- The `records` property can be mutated to store the state of the balancing algorithm.
1010+
1011+
> The `Dispatcher#options` also gets extended with the options `dns.affinity`, `dns.dualStack`, `dns.lookup` and `dns.pick` which can be used to configure the interceptor at a request-per-request basis.
1012+
1013+
1014+
**DNSInterceptorRecord**
1015+
It represents a DNS record.
1016+
- `family` - (`number`) The IP family of the address. It can be either `4` or `6`.
1017+
- `address` - (`string`) The IP address.
1018+
1019+
**DNSInterceptorOriginRecords**
1020+
It represents a map of DNS IP addresses records for a single origin.
1021+
- `4.ips` - (`DNSInterceptorRecord[] | null`) The IPv4 addresses.
1022+
- `6.ips` - (`DNSInterceptorRecord[] | null`) The IPv6 addresses.
1023+
1024+
**Example - Basic DNS Interceptor**
1025+
1026+
```js
1027+
const { Client, interceptors } = require("undici");
1028+
const { dns } = interceptors;
1029+
1030+
const client = new Agent().compose([
1031+
dns({ ...opts })
1032+
])
1033+
1034+
const response = await client.request({
1035+
origin: `http://localhost:3030`,
1036+
...requestOpts
1037+
})
1038+
```
1039+
9891040
##### `Response Error Interceptor`
9901041

9911042
**Introduction**

deps/undici/src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ module.exports.createRedirectInterceptor = createRedirectInterceptor
4141
module.exports.interceptors = {
4242
redirect: require('./lib/interceptor/redirect'),
4343
retry: require('./lib/interceptor/retry'),
44-
dump: require('./lib/interceptor/dump')
44+
dump: require('./lib/interceptor/dump'),
45+
dns: require('./lib/interceptor/dns')
4546
}
4647

4748
module.exports.buildConnector = buildConnector

deps/undici/src/lib/api/api-request.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class RequestHandler extends AsyncResource {
7373
this.removeAbortListener = util.addAbortListener(this.signal, () => {
7474
this.reason = this.signal.reason ?? new RequestAbortedError()
7575
if (this.res) {
76-
util.destroy(this.res, this.reason)
76+
util.destroy(this.res.on('error', util.nop), this.reason)
7777
} else if (this.abort) {
7878
this.abort(this.reason)
7979
}

deps/undici/src/lib/dispatcher/client-h2.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ const {
3131

3232
const kOpenStreams = Symbol('open streams')
3333

34+
let extractBody
35+
3436
// Experimental
3537
let h2ExperimentalWarned = false
3638

@@ -240,11 +242,12 @@ function onHTTP2GoAway (code) {
240242
util.destroy(this[kSocket], err)
241243

242244
// Fail head of pipeline.
243-
const request = client[kQueue][client[kRunningIdx]]
244-
client[kQueue][client[kRunningIdx]++] = null
245-
util.errorRequest(client, request, err)
246-
247-
client[kPendingIdx] = client[kRunningIdx]
245+
if (client[kRunningIdx] < client[kQueue].length) {
246+
const request = client[kQueue][client[kRunningIdx]]
247+
client[kQueue][client[kRunningIdx]++] = null
248+
util.errorRequest(client, request, err)
249+
client[kPendingIdx] = client[kRunningIdx]
250+
}
248251

249252
assert(client[kRunning] === 0)
250253

@@ -260,7 +263,8 @@ function shouldSendContentLength (method) {
260263

261264
function writeH2 (client, request) {
262265
const session = client[kHTTP2Session]
263-
const { body, method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request
266+
const { method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request
267+
let { body } = request
264268

265269
if (upgrade) {
266270
util.errorRequest(client, request, new Error('Upgrade not supported for H2'))
@@ -381,6 +385,16 @@ function writeH2 (client, request) {
381385

382386
let contentLength = util.bodyLength(body)
383387

388+
if (util.isFormDataLike(body)) {
389+
extractBody ??= require('../web/fetch/body.js').extractBody
390+
391+
const [bodyStream, contentType] = extractBody(body)
392+
headers['content-type'] = contentType
393+
394+
body = bodyStream.stream
395+
contentLength = bodyStream.length
396+
}
397+
384398
if (contentLength == null) {
385399
contentLength = request.contentLength
386400
}

0 commit comments

Comments
 (0)