Skip to content

Commit 159bd2a

Browse files
deps: update undici to 8.5.0
1 parent 2fb168f commit 159bd2a

42 files changed

Lines changed: 933 additions & 253 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
# Getting Started
2+
3+
## Installation
4+
5+
```bash
6+
npm install undici
7+
```
8+
9+
## Fetch
10+
11+
The quickest way to get started is with `fetch`, which follows the
12+
[Fetch Standard](https://fetch.spec.whatwg.org/) and works the same way as
13+
the browser API:
14+
15+
```js
16+
import { fetch } from 'undici'
17+
18+
const res = await fetch('https://example.com')
19+
const data = await res.json()
20+
console.log(data)
21+
```
22+
23+
### Using the Request object
24+
25+
undici also exports a `Request` class that follows the Fetch Standard:
26+
27+
```js
28+
import { fetch, Request } from 'undici'
29+
30+
const req = new Request('https://example.com', {
31+
method: 'POST',
32+
headers: { 'content-type': 'application/json' },
33+
body: JSON.stringify({ hello: 'world' })
34+
})
35+
const res = await fetch(req)
36+
console.log(res.status)
37+
```
38+
39+
### Streaming the response
40+
41+
`res.body` is a web `ReadableStream`. Use `pipeline` from
42+
`node:stream/promises` to stream it to a file:
43+
44+
```js
45+
import { fetch } from 'undici'
46+
import { pipeline } from 'node:stream/promises'
47+
import { createWriteStream } from 'node:fs'
48+
49+
const res = await fetch('https://example.com/large-file.zip')
50+
await pipeline(res.body, createWriteStream('./file.zip'))
51+
```
52+
53+
> Always consume or cancel the response body. In Node.js, garbage collection
54+
> is not aggressive enough to release connections promptly, so leaving a body
55+
> unread can cause connection leaks and stalled requests. See
56+
> [Specification Compliance - Garbage Collection](/docs/#garbage-collection)
57+
> for details.
58+
59+
For more on `fetch`, see [API Reference: Fetch](/docs/docs/api/Fetch.md).
60+
61+
## Dispatchers: Connection reuse and pooling
62+
63+
By default, `fetch`, `request`, `stream`, and `pipeline` create a new connection
64+
for each call. For applications that make many requests to the same origin,
65+
this is wasteful. undici provides **dispatchers** that manage connections
66+
internally.
67+
68+
### `Agent` — for requests to multiple origins
69+
70+
`Agent` is the most general-purpose dispatcher. It pools connections per-origin
71+
and is the recommended default for most applications. Use it with
72+
`setGlobalDispatcher` to affect all undici calls globally:
73+
74+
```js
75+
import { Agent, setGlobalDispatcher, fetch } from 'undici'
76+
77+
const agent = new Agent({
78+
keepAliveTimeout: 30_000,
79+
keepAliveMaxTimeout: 600_000
80+
})
81+
setGlobalDispatcher(agent)
82+
83+
// All subsequent fetch/request/stream/pipeline calls reuse connections
84+
const res = await fetch('https://api.example.com/data')
85+
```
86+
87+
You can also pass a dispatcher per-request:
88+
89+
```js
90+
await fetch('https://api.example.com/data', { dispatcher: agent })
91+
```
92+
93+
### `Pool` — for requests to a single origin
94+
95+
`Pool` manages a fixed set of connections to one origin. It gives you explicit
96+
control over concurrency:
97+
98+
```js
99+
import { Pool, request } from 'undici'
100+
101+
const pool = new Pool('https://api.example.com', { connections: 10 })
102+
103+
const { body } = await request('https://api.example.com/data', {
104+
dispatcher: pool
105+
})
106+
const data = await body.json()
107+
108+
pool.close()
109+
```
110+
111+
### `Client` — for a single connection
112+
113+
`Client` maps to a single TCP connection. It supports pipelining (sending
114+
multiple requests before responses arrive):
115+
116+
```js
117+
import { Client } from 'undici'
118+
119+
const client = new Client('https://api.example.com', {
120+
pipelining: 5
121+
})
122+
123+
const { body } = await client.request({ path: '/', method: 'GET' })
124+
await body.dump()
125+
126+
client.close()
127+
```
128+
129+
For more on dispatcher options and lifecycle, see:
130+
- [API Reference: Agent](/docs/docs/api/Agent.md)
131+
- [API Reference: Pool](/docs/docs/api/Pool.md)
132+
- [API Reference: Client](/docs/docs/api/Client.md)
133+
134+
## Timeouts
135+
136+
undici applies timeouts at two levels:
137+
138+
- **`headersTimeout`** — time to wait for response headers (default: 300s).
139+
- **`bodyTimeout`** — time between consecutive body chunks (default: 300s).
140+
141+
Set these on the dispatcher or per-request:
142+
143+
```js
144+
import { Agent, setGlobalDispatcher } from 'undici'
145+
146+
const agent = new Agent({
147+
headersTimeout: 5_000,
148+
bodyTimeout: 30_000
149+
})
150+
151+
setGlobalDispatcher(agent)
152+
```
153+
154+
Timeout errors are thrown as `HeadersTimeoutError` and `BodyTimeoutError`.
155+
See [API Reference: Errors](/docs/docs/api/Errors.md) for the full list.
156+
157+
## Error handling
158+
159+
undici exposes structured errors via `error.code`:
160+
161+
```js
162+
import { request, errors } from 'undici'
163+
164+
try {
165+
const { body } = await request('https://example.com')
166+
await body.json()
167+
} catch (err) {
168+
switch (err.code) {
169+
case 'UND_ERR_CONNECT_TIMEOUT':
170+
console.error('Connection timed out')
171+
break
172+
case 'UND_ERR_HEADERS_TIMEOUT':
173+
console.error('Headers timed out')
174+
break
175+
case 'UND_ERR_BODY_TIMEOUT':
176+
console.error('Body timed out')
177+
break
178+
case 'UND_ERR_ABORTED':
179+
console.error('Request was aborted')
180+
break
181+
default:
182+
console.error(err)
183+
}
184+
}
185+
```
186+
187+
### Aborting requests
188+
189+
```js
190+
import { request } from 'undici'
191+
192+
const ac = new AbortController()
193+
194+
setTimeout(() => ac.abort(), 1000)
195+
196+
try {
197+
const { body } = await request('https://example.com', {
198+
signal: ac.signal
199+
})
200+
await body.dump()
201+
} catch (err) {
202+
console.error(err.code) // UND_ERR_ABORTED
203+
}
204+
```
205+
206+
## Common patterns
207+
208+
### Proxies
209+
210+
Use `ProxyAgent` for HTTP(S) proxies, or `EnvHttpProxyAgent` to pick up
211+
proxy settings from environment variables:
212+
213+
```js
214+
import { ProxyAgent, setGlobalDispatcher } from 'undici'
215+
216+
const proxy = new ProxyAgent('http://proxy.internal:8080')
217+
setGlobalDispatcher(proxy)
218+
```
219+
220+
See [Best Practices: Proxy](/docs/docs/best-practices/proxy.md) and
221+
[API Reference: ProxyAgent](/docs/docs/api/ProxyAgent.md).
222+
223+
### Mocking in tests
224+
225+
```js
226+
import { MockAgent, setGlobalDispatcher, request } from 'undici'
227+
228+
const mockAgent = new MockAgent()
229+
setGlobalDispatcher(mockAgent)
230+
231+
const mockPool = mockAgent.get('https://api.example.com')
232+
mockPool.intercept({ path: '/users' }).reply(200, [{ id: 1 }])
233+
234+
const { body } = await request('https://api.example.com/users')
235+
console.log(await body.json())
236+
```
237+
238+
See [Best Practices: Mocking Request](/docs/docs/best-practices/mocking-request.md)
239+
and [API Reference: MockAgent](/docs/docs/api/MockAgent.md).
240+
241+
### Testing with undici
242+
243+
For test suites, set short keep-alive timeouts to avoid slow teardowns:
244+
245+
```js
246+
import { Agent, setGlobalDispatcher } from 'undici'
247+
248+
const agent = new Agent({
249+
keepAliveTimeout: 10,
250+
keepAliveMaxTimeout: 10
251+
})
252+
setGlobalDispatcher(agent)
253+
```
254+
255+
See [Best Practices: Writing Tests](/docs/docs/best-practices/writing-tests.md).
256+
257+
### Customizing the global fetch
258+
259+
You can override Node.js's built-in globals with `install()`:
260+
261+
```js
262+
import { install } from 'undici'
263+
264+
install()
265+
266+
// Global fetch, Headers, Response, Request, and FormData
267+
// now come from undici, not the Node.js bundle
268+
const res = await fetch('https://example.com')
269+
```
270+
271+
See [API Reference: Global Installation](/docs/docs/api/GlobalInstallation.md).
272+
273+
## Further reading
274+
275+
- [Undici vs. Built-in Fetch](/docs/docs/best-practices/undici-vs-builtin-fetch.md)
276+
when to install undici vs using Node.js built-in fetch
277+
- [API Reference](/docs/docs/api/Dispatcher.md) — full dispatcher API documentation
278+
- [Examples](/docs/examples/) — runnable code examples

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Implements [Client.closed](/docs/docs/api/Client.md#clientclosed)
3434

3535
Implements [Client.destroyed](/docs/docs/api/Client.md#clientdestroyed)
3636

37-
### `Pool.stats`
37+
### `BalancedPool.stats`
3838

3939
Returns [`PoolStats`](/docs/docs/api/PoolStats.md) instance for this pool.
4040

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Returns: `Client`
2525
* **maxHeaderSize** `number | null` (optional) - Default: `--max-http-header-size` or `16384` - The maximum length of request headers in bytes. Defaults to Node.js' --max-http-header-size or 16KiB.
2626
* **maxResponseSize** `number | null` (optional) - Default: `-1` - The maximum length of response body in bytes. Set to `-1` to disable.
2727
* **webSocket** `WebSocketOptions` (optional) - WebSocket-specific configuration options.
28+
* **maxFragments** `number` (optional) - Default: `131072` - Maximum number of fragments in a message. Set to 0 to disable the limit.
2829
* **maxPayloadSize** `number` (optional) - Default: `134217728` (128 MB) - Maximum allowed payload size in bytes for WebSocket messages. Applied to uncompressed messages, compressed frame payloads, and decompressed (permessage-deflate) messages. Set to 0 to disable the limit.
2930
* **pipelining** `number | null` (optional) - Default: `1` - The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Carefully consider your workload and environment before enabling concurrent requests as pipelining may reduce performance if used incorrectly. Pipelining is sensitive to network stack settings as well as head of line blocking caused by e.g. long running requests. Set to `0` to disable keep-alive connections. This option has no effect once HTTP/2 is negotiated — see `maxConcurrentStreams` for the h2 dispatch ceiling.
3031
* **connect** `ConnectOptions | Function | null` (optional) - Default: `null` - Configures how undici establishes TCP/TLS connections. Accepts two forms:

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* **path** `string` (optional)
1111
* **secure** `boolean` (optional)
1212
* **httpOnly** `boolean` (optional)
13-
* **sameSite** `'String'|'Lax'|'None'` (optional)
13+
* **sameSite** `'Strict'|'Lax'|'None'` (optional)
1414
* **unparsed** `string[]` (optional) Left over attributes that weren't parsed.
1515

1616
## `deleteCookie(headers, name[, attributes])`
@@ -80,6 +80,33 @@ Arguments:
8080

8181
Returns: `Cookie[]`
8282

83+
## `parseCookie(cookie)`
84+
85+
Parses a single `Set-Cookie` header value into a `Cookie` object.
86+
87+
```js
88+
import { parseCookie } from 'undici'
89+
90+
console.log(parseCookie('undici=getSetCookies; Secure; SameSite=Lax'))
91+
// {
92+
// name: 'undici',
93+
// value: 'getSetCookies',
94+
// secure: true,
95+
// sameSite: 'Lax'
96+
// }
97+
```
98+
99+
Notes:
100+
101+
* The cookie value is returned as it appears in the header. Percent-encoded sequences such as `%20` or `%0D%0A` are **not** decoded.
102+
* `sameSite` is only set for exact case-insensitive matches of `Strict`, `Lax`, or `None`.
103+
104+
Arguments:
105+
106+
* **cookie** `string`
107+
108+
Returns: `Cookie | null`
109+
83110
## `setCookie(headers, cookie)`
84111

85112
Appends a cookie to the `Set-Cookie` header.

0 commit comments

Comments
 (0)