Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v21.x backport] deps: update undici to 6.6.2 #51768

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 18 additions & 33 deletions deps/undici/src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,23 @@ npm i undici
## Benchmarks

The benchmark is a simple `hello world` [example](benchmarks/benchmark.js) using a
number of unix sockets (connections) with a pipelining depth of 10 running on Node 20.6.0.

### Connections 1


| Tests | Samples | Result | Tolerance | Difference with slowest |
|---------------------|---------|---------------|-----------|-------------------------|
| http - no keepalive | 15 | 5.32 req/sec | ± 2.61 % | - |
| http - keepalive | 10 | 5.35 req/sec | ± 2.47 % | + 0.44 % |
| undici - fetch | 15 | 41.85 req/sec | ± 2.49 % | + 686.04 % |
| undici - pipeline | 40 | 50.36 req/sec | ± 2.77 % | + 845.92 % |
| undici - stream | 15 | 60.58 req/sec | ± 2.75 % | + 1037.72 % |
| undici - request | 10 | 61.19 req/sec | ± 2.60 % | + 1049.24 % |
| undici - dispatch | 20 | 64.84 req/sec | ± 2.81 % | + 1117.81 % |


### Connections 50

| Tests | Samples | Result | Tolerance | Difference with slowest |
|---------------------|---------|------------------|-----------|-------------------------|
| undici - fetch | 30 | 2107.19 req/sec | ± 2.69 % | - |
| http - no keepalive | 10 | 2698.90 req/sec | ± 2.68 % | + 28.08 % |
| http - keepalive | 10 | 4639.49 req/sec | ± 2.55 % | + 120.17 % |
| undici - pipeline | 40 | 6123.33 req/sec | ± 2.97 % | + 190.59 % |
| undici - stream | 50 | 9426.51 req/sec | ± 2.92 % | + 347.35 % |
| undici - request | 10 | 10162.88 req/sec | ± 2.13 % | + 382.29 % |
| undici - dispatch | 50 | 11191.11 req/sec | ± 2.98 % | + 431.09 % |
50 TCP connections with a pipelining depth of 10 running on Node 20.10.0.

```
│ Tests │ Samples │ Result │ Tolerance │ Difference with slowest │
|─────────────────────|─────────|─────────────────|───────────|─────────────────────────|
│ got │ 45 │ 1661.71 req/sec │ ± 2.93 % │ - │
│ node-fetch │ 20 │ 2164.81 req/sec │ ± 2.63 % │ + 30.28 % │
│ undici - fetch │ 35 │ 2274.27 req/sec │ ± 2.70 % │ + 36.86 % │
│ http - no keepalive │ 15 │ 2376.04 req/sec │ ± 2.99 % │ + 42.99 % │
│ axios │ 25 │ 2612.93 req/sec │ ± 2.89 % │ + 57.24 % │
│ request │ 40 │ 2712.19 req/sec │ ± 2.92 % │ + 63.22 % │
│ http - keepalive │ 45 │ 4393.25 req/sec │ ± 2.86 % │ + 164.38 % │
│ undici - pipeline │ 45 │ 5484.69 req/sec │ ± 2.87 % │ + 230.06 % │
│ undici - request │ 55 │ 7773.98 req/sec │ ± 2.93 % │ + 367.83 % │
│ undici - stream │ 70 │ 8425.96 req/sec │ ± 2.91 % │ + 407.07 % │
│ undici - dispatch │ 50 │ 9488.99 req/sec │ ± 2.85 % │ + 471.04 % │
```

## Quick Start

Expand All @@ -62,9 +51,7 @@ const {
console.log('response received', statusCode)
console.log('headers', headers)

for await (const data of body) {
console.log('data', data)
}
for await (const data of body) { console.log('data', data) }

console.log('trailers', trailers)
```
Expand Down Expand Up @@ -119,7 +106,7 @@ Returns a promise with the result of the `Dispatcher.request` method.

Calls `options.dispatcher.request(options)`.

See [Dispatcher.request](./docs/api/Dispatcher.md#dispatcherrequestoptions-callback) for more details.
See [Dispatcher.request](./docs/api/Dispatcher.md#dispatcherrequestoptions-callback) for more details, and [request examples](./examples/README.md) for examples.

### `undici.stream([url, options, ]factory): Promise`

Expand Down Expand Up @@ -180,8 +167,6 @@ Implements [fetch](https://fetch.spec.whatwg.org/#fetch-method).
* https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
* https://fetch.spec.whatwg.org/#fetch-method

Only supported on Node 16.8+.

Basic usage example:

```js
Expand Down
2 changes: 1 addition & 1 deletion deps/undici/src/docs/api/BalancedPool.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Arguments:

### `BalancedPool.removeUpstream(upstream)`

Removes an upstream that was previously addded.
Removes an upstream that was previously added.

### `BalancedPool.close([callback])`

Expand Down
62 changes: 62 additions & 0 deletions deps/undici/src/docs/api/Debug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Debug

Undici (and subsenquently `fetch` and `websocket`) exposes a debug statement that can be enabled by setting `NODE_DEBUG` within the environment.

The flags availabile are:

## `undici`

This flag enables debug statements for the core undici library.

```sh
NODE_DEBUG=undici node script.js

UNDICI 16241: connecting to nodejs.org using https:h1
UNDICI 16241: connecting to nodejs.org using https:h1
UNDICI 16241: connected to nodejs.org using https:h1
UNDICI 16241: sending request to GET https://nodejs.org//
UNDICI 16241: received response to GET https://nodejs.org// - HTTP 307
UNDICI 16241: connecting to nodejs.org using https:h1
UNDICI 16241: trailers received from GET https://nodejs.org//
UNDICI 16241: connected to nodejs.org using https:h1
UNDICI 16241: sending request to GET https://nodejs.org//en
UNDICI 16241: received response to GET https://nodejs.org//en - HTTP 200
UNDICI 16241: trailers received from GET https://nodejs.org//en
```

## `fetch`

This flag enables debug statements for the `fetch` API.

> **Note**: statements are pretty similar to the ones in the `undici` flag, but scoped to `fetch`

```sh
NODE_DEBUG=fetch node script.js

FETCH 16241: connecting to nodejs.org using https:h1
FETCH 16241: connecting to nodejs.org using https:h1
FETCH 16241: connected to nodejs.org using https:h1
FETCH 16241: sending request to GET https://nodejs.org//
FETCH 16241: received response to GET https://nodejs.org// - HTTP 307
FETCH 16241: connecting to nodejs.org using https:h1
FETCH 16241: trailers received from GET https://nodejs.org//
FETCH 16241: connected to nodejs.org using https:h1
FETCH 16241: sending request to GET https://nodejs.org//en
FETCH 16241: received response to GET https://nodejs.org//en - HTTP 200
FETCH 16241: trailers received from GET https://nodejs.org//en
```

## `websocket`

This flag enables debug statements for the `Websocket` API.

> **Note**: statements can overlap with `UNDICI` ones if `undici` or `fetch` flag has been enabled as well.

```sh
NODE_DEBUG=websocket node script.js

WEBSOCKET 18309: connecting to echo.websocket.org using https:h1
WEBSOCKET 18309: connected to echo.websocket.org using https:h1
WEBSOCKET 18309: sending request to GET https://echo.websocket.org//
WEBSOCKET 18309: connection opened <ip_address>
```
6 changes: 3 additions & 3 deletions deps/undici/src/docs/api/DiagnosticsChannel.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ You can not assume that this event is related to any specific request.
import diagnosticsChannel from 'diagnostics_channel'

diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(({ connectParams, connector }) => {
// const { host, hostname, protocol, port, servername } = connectParams
// const { host, hostname, protocol, port, servername, version } = connectParams
// connector is a function that creates the socket
})
```
Expand All @@ -118,7 +118,7 @@ This message is published after a connection is established.
import diagnosticsChannel from 'diagnostics_channel'

diagnosticsChannel.channel('undici:client:connected').subscribe(({ socket, connectParams, connector }) => {
// const { host, hostname, protocol, port, servername } = connectParams
// const { host, hostname, protocol, port, servername, version } = connectParams
// connector is a function that creates the socket
})
```
Expand All @@ -131,7 +131,7 @@ This message is published if it did not succeed to create new connection
import diagnosticsChannel from 'diagnostics_channel'

diagnosticsChannel.channel('undici:client:connectError').subscribe(({ error, socket, connectParams, connector }) => {
// const { host, hostname, protocol, port, servername } = connectParams
// const { host, hostname, protocol, port, servername, version } = connectParams
// connector is a function that creates the socket
console.log(`Connect failed with ${error.message}`)
})
Expand Down
1 change: 1 addition & 0 deletions deps/undici/src/docs/api/Dispatcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo
* **onConnect** `(abort: () => void, context: object) => void` - Invoked before request is dispatched on socket. May be invoked multiple times when a request is retried when the request at the head of the pipeline fails.
* **onError** `(error: Error) => void` - Invoked when an error has occurred. May not throw.
* **onUpgrade** `(statusCode: number, headers: Buffer[], socket: Duplex) => void` (optional) - Invoked when request is upgraded. Required if `DispatchOptions.upgrade` is defined or `DispatchOptions.method === 'CONNECT'`.
* **onResponseStarted** `() => void` (optional) - Invoked when response is received, before headers have been read.
* **onHeaders** `(statusCode: number, headers: Buffer[], resume: () => void, statusText: string) => boolean` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests.
* **onData** `(chunk: Buffer) => boolean` - Invoked when response payload data is received. Not required for `upgrade` requests.
* **onComplete** `(trailers: Buffer[]) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests.
Expand Down
21 changes: 21 additions & 0 deletions deps/undici/src/docs/api/EventSource.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# EventSource

Undici exposes a WHATWG spec-compliant implementation of [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)
for [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events).

## Instantiating EventSource

Undici exports a EventSource class. You can instantiate the EventSource as
follows:

```mjs
import { EventSource } from 'undici'

const evenSource = new EventSource('http://localhost:3000')
evenSource.onmessage = (event) => {
console.log(event.data)
}
```

More information about the EventSource API can be found on
[MDN](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).
96 changes: 96 additions & 0 deletions deps/undici/src/docs/api/RedirectHandler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Class: RedirectHandler

A class that handles redirection logic for HTTP requests.

## `new RedirectHandler(dispatch, maxRedirections, opts, handler, redirectionLimitReached)`

Arguments:

- **dispatch** `function` - The dispatch function to be called after every retry.
- **maxRedirections** `number` - Maximum number of redirections allowed.
- **opts** `object` - Options for handling redirection.
- **handler** `object` - An object containing handlers for different stages of the request lifecycle.
- **redirectionLimitReached** `boolean` (default: `false`) - A flag that the implementer can provide to enable or disable the feature. If set to `false`, it indicates that the caller doesn't want to use the feature and prefers the old behavior.

Returns: `RedirectHandler`

### Parameters

- **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandlers) => Promise<Dispatch.DispatchResponse>` (required) - Dispatch function to be called after every redirection.
- **maxRedirections** `number` (required) - Maximum number of redirections allowed.
- **opts** `object` (required) - Options for handling redirection.
- **handler** `object` (required) - Handlers for different stages of the request lifecycle.
- **redirectionLimitReached** `boolean` (default: `false`) - A flag that the implementer can provide to enable or disable the feature. If set to `false`, it indicates that the caller doesn't want to use the feature and prefers the old behavior.

### Properties

- **location** `string` - The current redirection location.
- **abort** `function` - The abort function.
- **opts** `object` - The options for handling redirection.
- **maxRedirections** `number` - Maximum number of redirections allowed.
- **handler** `object` - Handlers for different stages of the request lifecycle.
- **history** `Array` - An array representing the history of URLs during redirection.
- **redirectionLimitReached** `boolean` - Indicates whether the redirection limit has been reached.

### Methods

#### `onConnect(abort)`

Called when the connection is established.

Parameters:

- **abort** `function` - The abort function.

#### `onUpgrade(statusCode, headers, socket)`

Called when an upgrade is requested.

Parameters:

- **statusCode** `number` - The HTTP status code.
- **headers** `object` - The headers received in the response.
- **socket** `object` - The socket object.

#### `onError(error)`

Called when an error occurs.

Parameters:

- **error** `Error` - The error that occurred.

#### `onHeaders(statusCode, headers, resume, statusText)`

Called when headers are received.

Parameters:

- **statusCode** `number` - The HTTP status code.
- **headers** `object` - The headers received in the response.
- **resume** `function` - The resume function.
- **statusText** `string` - The status text.

#### `onData(chunk)`

Called when data is received.

Parameters:

- **chunk** `Buffer` - The data chunk received.

#### `onComplete(trailers)`

Called when the request is complete.

Parameters:

- **trailers** `object` - The trailers received.

#### `onBodySent(chunk)`

Called when the request body is sent.

Parameters:

- **chunk** `Buffer` - The chunk of the request body sent.
25 changes: 25 additions & 0 deletions deps/undici/src/docs/api/Util.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Util

Utility API for third-party implementations of the dispatcher API.

## `parseHeaders(headers, [obj])`

Receives a header object and returns the parsed value.

Arguments:

- **headers** `Record<string, string | string[]> | (Buffer | string | (Buffer | string)[])[]` (required) - Header object.

- **obj** `Record<string, string | string[]>` (optional) - Object to specify a proxy object. The parsed value is assigned to this object. But, if **headers** is an object, it is not used.

Returns: `Record<string, string | string[]>` If **headers** is an object, it is **headers**. Otherwise, if **obj** is specified, it is equivalent to **obj**.

## `headerNameToString(value)`

Retrieves a header name and returns its lowercase value.

Arguments:

- **value** `string | Buffer` (required) - Header name.

Returns: `string`
6 changes: 3 additions & 3 deletions deps/undici/src/docs/best-practices/client-certificate.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ The server option `rejectUnauthorized: false` allows us to handle any invalid ce
### Client Certificate Authentication

```js
const { readFileSync } = require('fs')
const { join } = require('path')
const { createServer } = require('https')
const { readFileSync } = require('node:fs')
const { join } = require('node:path')
const { createServer } = require('node:https')
const { Client } = require('undici')

const serverOptions = {
Expand Down
7 changes: 6 additions & 1 deletion deps/undici/src/index-fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ const fetchImpl = require('./lib/fetch').fetch

module.exports.fetch = function fetch (resource, init = undefined) {
return fetchImpl(resource, init).catch((err) => {
Error.captureStackTrace(err, this)
if (typeof err === 'object') {
Error.captureStackTrace(err, this)
}
throw err
})
}
module.exports.FormData = require('./lib/fetch/formdata').FormData
module.exports.Headers = require('./lib/fetch/headers').Headers
module.exports.Response = require('./lib/fetch/response').Response
module.exports.Request = require('./lib/fetch/request').Request

module.exports.WebSocket = require('./lib/websocket/websocket').WebSocket

module.exports.EventSource = require('./lib/eventsource/eventsource').EventSource
Loading