Skip to content

Commit 89672b1

Browse files
nodejs-github-botmcollina
authored andcommitted
deps: update undici to 8.7.0
1 parent 51dbfd6 commit 89672b1

77 files changed

Lines changed: 10584 additions & 4765 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

deps/undici/src/CONTRIBUTING.md

Lines changed: 153 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* [Building for externally shared node builtins](#external-builds)
1111
* [Benchmarks](#benchmarks)
1212
* [Documentation](#documentation)
13+
* [Reproduction](#reproduction)
1314
* [Developer's Certificate of Origin 1.1](#developers-certificate-of-origin)
1415
* [Moderation Policy](#moderation-policy)
1516

@@ -58,7 +59,7 @@ npm i
5859
> This requires [docker](https://www.docker.com/) installed on your machine.
5960
6061
```bash
61-
npm run build-wasm
62+
npm run build:wasm
6263
```
6364

6465
#### Copy the sources to `undici`
@@ -198,6 +199,157 @@ cd docs && npm i && npm run serve
198199

199200
The documentation will be available at `http://localhost:3000`.
200201

202+
<a id="reproduction"></a>
203+
### Reproduction
204+
205+
When reporting a bug, a high-quality reproduction helps maintainers diagnose and fix the issue quickly. Follow the guidelines below to create a minimal, standalone reproduction script.
206+
207+
#### What Makes a Good Reproduction
208+
209+
- **Standalone**: The script must be self-contained and run without external dependencies beyond `undici` and Node.js built-in modules.
210+
- **Minimal**: Strip everything unrelated to the bug — no production configs, no frameworks, no unnecessary middleware.
211+
- **Reproducible**: Run the script and confirm the bug occurs before submitting.
212+
- **Specific**: Include the exact `undici` API call that triggers the issue (e.g., `Client`, `Pool`, `Agent`, `fetch`, `request`, `stream`, `pipeline`).
213+
- **Run with Node's test runner**: Use `node --test` (Node 20+) or `node test/your-repro.js`.
214+
215+
#### Standalone Server Pattern
216+
217+
Use `createServer` from `node:http` (or `node:https` for TLS-related bugs) to run a local server inside the same script. This avoids external service dependencies and keeps the reproduction fully self-contained.
218+
219+
```javascript
220+
'use strict'
221+
222+
const { test } = require('node:test')
223+
const { createServer } = require('node:http')
224+
const { once } = require('node:events')
225+
const { Client } = require('undici')
226+
227+
// https://github.com/nodejs/undici/issues/XXXX
228+
229+
test('short description of the bug', { timeout: 60000 }, async (t) => {
230+
t.plan(1)
231+
232+
// 1. Start a local HTTP server that reproduces the scenario
233+
const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => {
234+
// Simulate the bug-triggering response
235+
res.statusCode = 200
236+
res.setHeader('content-length', 100)
237+
res.end('hello'.repeat(20))
238+
})
239+
t.after(() => { server.closeAllConnections?.(); server.close() })
240+
241+
server.listen(0)
242+
await once(server, 'listening')
243+
244+
// 2. Create the undici client pointing to the local server
245+
const client = new Client(`http://localhost:${server.address().port}`)
246+
t.after(() => client.close())
247+
248+
// 3. Perform the request that triggers the bug
249+
const { body } = await client.request({ path: '/', method: 'GET' })
250+
251+
let responseBody = ''
252+
for await (const chunk of body) {
253+
responseBody += chunk
254+
}
255+
256+
t.assert.strictEqual(responseBody, 'hello'.repeat(20))
257+
})
258+
```
259+
260+
Save the script as `test/repro-XXXX.js` and run it:
261+
262+
```bash
263+
node --test test/repro-XXXX.js
264+
```
265+
266+
#### Fetch-Based Reproduction
267+
268+
For bugs involving `fetch`, use the same standalone server pattern:
269+
270+
```javascript
271+
'use strict'
272+
273+
const { test } = require('node:test')
274+
const { createServer } = require('node:http')
275+
const { once } = require('node:events')
276+
const { fetch, Agent } = require('undici')
277+
278+
// https://github.com/nodejs/undici/issues/XXXX
279+
280+
test('short description of the fetch bug', { timeout: 60000 }, async (t) => {
281+
t.plan(1)
282+
283+
const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => {
284+
res.statusCode = 200
285+
res.setHeader('content-type', 'application/json')
286+
res.end(JSON.stringify({ ok: true }))
287+
})
288+
t.after(() => server.close())
289+
290+
server.listen(0)
291+
await once(server, 'listening')
292+
293+
const agent = new Agent({ keepAliveTimeout: 1 })
294+
t.after(() => agent.close())
295+
296+
const response = await fetch(`http://localhost:${server.address().port}/`, {
297+
dispatcher: agent
298+
})
299+
300+
await response.body.cancel()
301+
302+
t.assert.strictEqual(response.status, 200)
303+
})
304+
```
305+
306+
#### Using Pool or Agent
307+
308+
For bugs involving connection pooling or agent behavior:
309+
310+
```javascript
311+
'use strict'
312+
313+
const { test } = require('node:test')
314+
const { createServer } = require('node:http')
315+
const { once } = require('node:events')
316+
const { Pool } = require('undici')
317+
318+
// https://github.com/nodejs/undici/issues/XXXX
319+
320+
test('Pool bug reproduction', { timeout: 60000 }, async (t) => {
321+
t.plan(1)
322+
323+
const server = createServer({ joinDuplicateHeaders: true }, (req, res) => {
324+
res.end('ok')
325+
})
326+
t.after(() => server.close())
327+
328+
server.listen(0)
329+
await once(server, 'listening')
330+
331+
const pool = new Pool(`http://localhost:${server.address().port}`)
332+
t.after(() => pool.close())
333+
334+
const data = await pool.request({ path: '/', method: 'GET' })
335+
await data.body.dump()
336+
337+
t.assert.strictEqual(data.statusCode, 200)
338+
})
339+
```
340+
341+
#### Adding the Reproduction to the Repository
342+
343+
If you are submitting a bug fix via a pull request, include a test file `test/issue-XXXX.js` that reproduces the bug and passes with the fix.
344+
345+
#### Checklist for Submitting a Bug Report
346+
347+
1. [ ] Write a standalone reproduction script.
348+
2. [ ] Run it locally to confirm the bug is reproducible.
349+
3. [ ] Attach the script (or a gist link) in the bug report.
350+
4. [ ] Include the exact undici version and Node.js version.
351+
5. [ ] Describe the expected vs. actual behavior.
352+
201353
<a id="developers-certificate-of-origin"></a>
202354
## Developer's Certificate of Origin 1.1
203355

deps/undici/src/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -717,8 +717,9 @@ Refs: https://tools.ietf.org/html/rfc7231#section-5.1.1
717717
#### Pipelining
718718

719719
Undici will only use pipelining if configured with a `pipelining` factor
720-
greater than `1`. Also it is important to pass `blocking: false` to the
721-
request options to properly pipeline requests.
720+
greater than `1`. Only enable pipelining when the remote server is trusted.
721+
Also it is important to pass `blocking: false` to the request options to
722+
properly pipeline requests.
722723

723724
Undici always assumes that connections are persistent and will immediately
724725
pipeline requests, without checking whether the connection is persistent.

deps/undici/src/SECURITY.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,18 @@ lead to a loss of confidentiality, integrity, or availability.
153153
calling `body.formData()` on untrusted responses is considered an application
154154
responsibility, not a vulnerability in undici.
155155

156+
#### HTTP/1.1 keep-alive with untrusted servers
157+
158+
* HTTP/1.1 responses on a reused connection are ordered, but they do not carry a
159+
request identifier. Once a request has been written on a reused connection,
160+
a well-formed response sent by the server is the response to that next request
161+
from the client's point of view. Undici avoids immediate reuse of
162+
non-pipelined HTTP/1.1 connections when callers are already waiting to send
163+
more work, but applications that require per-request connection isolation for
164+
untrusted or user-controlled servers should disable reuse by using
165+
`pipelining: 0` or `maxRequestsPerClient: 1`, or use a protocol with response
166+
correlation such as HTTP/2.
167+
156168
#### Application Misconfiguration
157169

158170
* Issues arising from incorrect or insecure use of undici APIs (such as

0 commit comments

Comments
 (0)