Skip to content

Commit 9c7bc95

Browse files
nodejs-github-botRafaelGSS
authored andcommitted
deps: update undici to 7.4.0
PR-URL: #57236 Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Rafael Gonzaga <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 68bd6b3 commit 9c7bc95

19 files changed

+1580
-294
lines changed

deps/undici/src/MAINTAINERS.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,13 @@ Maintainers are encouraged to use the extensive and detailed list of labels for
3131
* Issues with a low-barrier of entry should be assigned the `good first issue` label.
3232
* Do not use the `invalid` label, instead use `bug` or `Status: wontfix`.
3333
* Duplicate issues should initially be assigned the `duplicate` label.
34+
35+
36+
## Making a Release
37+
38+
1. Go to github actions, then select ["Create Release PR"](https://github.com/nodejs/undici/actions/workflows/release-create-pr.yml).
39+
2. Run the workflow, selecting `main` and indicating if you want a specific version number or a patch/minor/major release
40+
3. Wait for the PR to be created. Approve the PR ([this](https://github.com/nodejs/undici/pull/4021) is a an example).
41+
4. Land the PR, wait for the CI to pass.
42+
5. Got to the ["Release"](https://github.com/nodejs/undici/actions/workflows/release.yml) workflow, you should see a job waiting.
43+
6. If you are one of the [releases](https://github.com/nodejs/undici?tab=readme-ov-file#releasers), then click "review deployments", then select "release" and click "approve and deploy". If you are not a releaser, contact one.

deps/undici/src/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,8 @@ See [Dispatcher.upgrade](./docs/docs/api/Dispatcher.md#dispatcherupgradeoptions-
337337

338338
* dispatcher `Dispatcher`
339339

340-
Sets the global dispatcher used by Common API Methods.
340+
Sets the global dispatcher used by Common API Methods. Global dispatcher is shared among compatible undici modules,
341+
including undici that is bundled internally with node.js.
341342

342343
### `undici.getGlobalDispatcher()`
343344

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo
210210
* **onResponseStart** `(controller: DispatchController, statusCode: number, headers: Record<string, string | string []>, statusMessage?: string) => void` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests.
211211
* **onResponseData** `(controller: DispatchController, chunk: Buffer) => void` - Invoked when response payload data is received. Not required for `upgrade` requests.
212212
* **onResponseEnd** `(controller: DispatchController, trailers: Record<string, string | string[]>) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests.
213-
* **onResponseError** `(error: Error) => void` - Invoked when an error has occurred. May not throw.
213+
* **onResponseError** `(controller: DispatchController, error: Error) => void` - Invoked when an error has occurred. May not throw.
214214

215215
#### Example 1 - Dispatch GET request
216216

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Class: EnvHttpProxyAgent
22

3-
Stability: Experimental.
4-
53
Extends: `undici.Dispatcher`
64

75
EnvHttpProxyAgent automatically reads the proxy configuration from the environment variables `http_proxy`, `https_proxy`, and `no_proxy` and sets up the proxy agents accordingly. When `http_proxy` and `https_proxy` are set, `http_proxy` is used for HTTP requests and `https_proxy` is used for HTTPS requests. If only `http_proxy` is set, `http_proxy` is used for both HTTP and HTTPS requests. If only `https_proxy` is set, it is only used for HTTPS requests.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { errors } from 'undici'
2828
| `ResponseExceededMaxSizeError` | `UND_ERR_RES_EXCEEDED_MAX_SIZE` | response body exceed the max size allowed |
2929
| `SecureProxyConnectionError` | `UND_ERR_PRX_TLS` | tls connection to a proxy failed |
3030

31+
Be aware of the possible difference between the global dispatcher version and the actual undici version you might be using. We recommend to avoid the check `instanceof errors.UndiciError` and seek for the `error.code === '<error_code>'` instead to avoid inconsistencies.
3132
### `SocketError`
3233

3334
The `SocketError` has a `.socket` property which holds socket metadata:

deps/undici/src/index-fetch.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ module.exports.createFastMessageEvent = createFastMessageEvent
2626

2727
module.exports.EventSource = require('./lib/web/eventsource/eventsource').EventSource
2828

29+
const api = require('./lib/api')
30+
const Dispatcher = require('./lib/dispatcher/dispatcher')
31+
Object.assign(Dispatcher.prototype, api)
2932
// Expose the fetch implementation to be enabled in Node.js core via a flag
3033
module.exports.EnvHttpProxyAgent = EnvHttpProxyAgent
3134
module.exports.getGlobalDispatcher = getGlobalDispatcher

deps/undici/src/lib/cache/memory-cache-store.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,13 @@ class MemoryCacheStore {
7979
const entry = this.#entries.get(topLevelKey)?.find((entry) => (
8080
entry.deleteAt > now &&
8181
entry.method === key.method &&
82-
(entry.vary == null || Object.keys(entry.vary).every(headerName => entry.vary[headerName] === key.headers?.[headerName]))
82+
(entry.vary == null || Object.keys(entry.vary).every(headerName => {
83+
if (entry.vary[headerName] === null) {
84+
return key.headers[headerName] === undefined
85+
}
86+
87+
return entry.vary[headerName] === key.headers[headerName]
88+
}))
8389
))
8490

8591
return entry == null

deps/undici/src/lib/cache/sqlite-cache-store.js

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ module.exports = class SqliteCacheStore {
232232
const value = this.#findValue(key)
233233
return value
234234
? {
235-
body: value.body ? Buffer.from(value.body.buffer) : undefined,
235+
body: value.body ? Buffer.from(value.body.buffer, value.body.byteOffset, value.body.byteLength) : undefined,
236236
statusCode: value.statusCode,
237237
statusMessage: value.statusMessage,
238238
headers: value.headers ? JSON.parse(value.headers) : undefined,
@@ -411,10 +411,6 @@ module.exports = class SqliteCacheStore {
411411
let matches = true
412412

413413
if (value.vary) {
414-
if (!headers) {
415-
return undefined
416-
}
417-
418414
const vary = JSON.parse(value.vary)
419415

420416
for (const header in vary) {
@@ -440,18 +436,21 @@ module.exports = class SqliteCacheStore {
440436
* @returns {boolean}
441437
*/
442438
function headerValueEquals (lhs, rhs) {
439+
if (lhs == null && rhs == null) {
440+
return true
441+
}
442+
443+
if ((lhs == null && rhs != null) ||
444+
(lhs != null && rhs == null)) {
445+
return false
446+
}
447+
443448
if (Array.isArray(lhs) && Array.isArray(rhs)) {
444449
if (lhs.length !== rhs.length) {
445450
return false
446451
}
447452

448-
for (let i = 0; i < lhs.length; i++) {
449-
if (rhs.includes(lhs[i])) {
450-
return false
451-
}
452-
}
453-
454-
return true
453+
return lhs.every((x, i) => x === rhs[i])
455454
}
456455

457456
return lhs === rhs

deps/undici/src/lib/dispatcher/env-http-proxy-agent.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ const DEFAULT_PORTS = {
1010
'https:': 443
1111
}
1212

13-
let experimentalWarned = false
14-
1513
class EnvHttpProxyAgent extends DispatcherBase {
1614
#noProxyValue = null
1715
#noProxyEntries = null
@@ -21,13 +19,6 @@ class EnvHttpProxyAgent extends DispatcherBase {
2119
super()
2220
this.#opts = opts
2321

24-
if (!experimentalWarned) {
25-
experimentalWarned = true
26-
process.emitWarning('EnvHttpProxyAgent is experimental, expect them to change at any time.', {
27-
code: 'UNDICI-EHPA'
28-
})
29-
}
30-
3122
const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts
3223

3324
this[kNoProxyAgent] = new Agent(agentOpts)

deps/undici/src/lib/llhttp/wasm_build_env.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
> undici@7.3.0 build:wasm
2+
> undici@7.4.0 build:wasm
33
> node build/wasm.js --docker
44

55
> docker run --rm --platform=linux/x86_64 --user 1001:118 --mount type=bind,source=/home/runner/work/node/node/deps/undici/src/lib/llhttp,target=/home/node/build/lib/llhttp --mount type=bind,source=/home/runner/work/node/node/deps/undici/src/build,target=/home/node/build/build --mount type=bind,source=/home/runner/work/node/node/deps/undici/src/deps,target=/home/node/build/deps -t ghcr.io/nodejs/wasm-builder@sha256:975f391d907e42a75b8c72eb77c782181e941608687d4d8694c3e9df415a0970 node build/wasm.js

deps/undici/src/lib/mock/mock-utils.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,10 @@ function getResponseData (data) {
124124
return data
125125
} else if (typeof data === 'object') {
126126
return JSON.stringify(data)
127-
} else {
127+
} else if (data) {
128128
return data.toString()
129+
} else {
130+
return ''
129131
}
130132
}
131133

deps/undici/src/lib/util/cache.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@ function makeCacheKey (opts) {
2626
if (typeof key !== 'string' || typeof val !== 'string') {
2727
throw new Error('opts.headers is not a valid header map')
2828
}
29-
headers[key] = val
29+
headers[key.toLowerCase()] = val
3030
}
3131
} else if (typeof opts.headers === 'object') {
32-
headers = opts.headers
32+
headers = {}
33+
34+
for (const key of Object.keys(opts.headers)) {
35+
headers[key.toLowerCase()] = opts.headers[key]
36+
}
3337
} else {
3438
throw new Error('opts.headers is not an object')
3539
}
@@ -260,19 +264,16 @@ function parseVaryHeader (varyHeader, headers) {
260264
return headers
261265
}
262266

263-
const output = /** @type {Record<string, string | string[]>} */ ({})
267+
const output = /** @type {Record<string, string | string[] | null>} */ ({})
264268

265269
const varyingHeaders = typeof varyHeader === 'string'
266270
? varyHeader.split(',')
267271
: varyHeader
272+
268273
for (const header of varyingHeaders) {
269274
const trimmedHeader = header.trim().toLowerCase()
270275

271-
if (headers[trimmedHeader]) {
272-
output[trimmedHeader] = headers[trimmedHeader]
273-
} else {
274-
return undefined
275-
}
276+
output[trimmedHeader] = headers[trimmedHeader] ?? null
276277
}
277278

278279
return output

deps/undici/src/lib/web/fetch/body.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ try {
2323
const crypto = require('node:crypto')
2424
random = (max) => crypto.randomInt(0, max)
2525
} catch {
26-
random = (max) => Math.floor(Math.random(max))
26+
random = (max) => Math.floor(Math.random() * max)
2727
}
2828

2929
const textEncoder = new TextEncoder()

deps/undici/src/lib/web/fetch/request.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => {
3737

3838
const dependentControllerMap = new WeakMap()
3939

40+
let abortSignalHasEventHandlerLeakWarning
41+
42+
try {
43+
abortSignalHasEventHandlerLeakWarning = getMaxListeners(new AbortController().signal) > 0
44+
} catch {
45+
abortSignalHasEventHandlerLeakWarning = false
46+
}
47+
4048
function buildAbort (acRef) {
4149
return abort
4250

@@ -424,15 +432,10 @@ class Request {
424432
const acRef = new WeakRef(ac)
425433
const abort = buildAbort(acRef)
426434

427-
// Third-party AbortControllers may not work with these.
428-
// See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619.
429-
try {
430-
// If the max amount of listeners is equal to the default, increase it
431-
// This is only available in node >= v19.9.0
432-
if (typeof getMaxListeners === 'function' && getMaxListeners(signal) === defaultMaxListeners) {
433-
setMaxListeners(1500, signal)
434-
}
435-
} catch {}
435+
// If the max amount of listeners is equal to the default, increase it
436+
if (abortSignalHasEventHandlerLeakWarning && getMaxListeners(signal) === defaultMaxListeners) {
437+
setMaxListeners(1500, signal)
438+
}
436439

437440
util.addAbortListener(signal, abort)
438441
// The third argument must be a registry key to be unregistered.

0 commit comments

Comments
 (0)