Skip to content

Commit af226d0

Browse files
nodejs-github-botmarco-ippolito
authored andcommitted
deps: update undici to 6.17.0
PR-URL: #53034 Reviewed-By: Matthew Aitken <[email protected]> Reviewed-By: Marco Ippolito <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
1 parent c9c6bf8 commit af226d0

23 files changed

+1597
-505
lines changed

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

+32
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,38 @@ const client = new Client("http://example.com").compose(
952952
);
953953
```
954954

955+
##### `dump`
956+
957+
The `dump` interceptor enables you to dump the response body from a request upon a given limit.
958+
959+
**Options**
960+
- `maxSize` - The maximum size (in bytes) of the response body to dump. If the size of the request's body exceeds this value then the connection will be closed. Default: `1048576`.
961+
962+
> The `Dispatcher#options` also gets extended with the options `dumpMaxSize`, `abortOnDumped`, and `waitForTrailers` which can be used to configure the interceptor at a request-per-request basis.
963+
964+
**Example - Basic Dump Interceptor**
965+
966+
```js
967+
const { Client, interceptors } = require("undici");
968+
const { dump } = interceptors;
969+
970+
const client = new Client("http://example.com").compose(
971+
dump({
972+
maxSize: 1024,
973+
})
974+
);
975+
976+
// or
977+
client.dispatch(
978+
{
979+
path: "/",
980+
method: "GET",
981+
dumpMaxSize: 1024,
982+
},
983+
handler
984+
);
985+
```
986+
955987
## Instance Events
956988

957989
### Event: `'connect'`

deps/undici/src/index-fetch.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const fetchImpl = require('./lib/web/fetch').fetch
77
module.exports.fetch = function fetch (resource, init = undefined) {
88
return fetchImpl(resource, init).catch((err) => {
99
if (err && typeof err === 'object') {
10-
Error.captureStackTrace(err, this)
10+
Error.captureStackTrace(err)
1111
}
1212
throw err
1313
})

deps/undici/src/index.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ module.exports.RedirectHandler = RedirectHandler
4040
module.exports.createRedirectInterceptor = createRedirectInterceptor
4141
module.exports.interceptors = {
4242
redirect: require('./lib/interceptor/redirect'),
43-
retry: require('./lib/interceptor/retry')
43+
retry: require('./lib/interceptor/retry'),
44+
dump: require('./lib/interceptor/dump')
4445
}
4546

4647
module.exports.buildConnector = buildConnector
@@ -108,7 +109,7 @@ module.exports.fetch = async function fetch (init, options = undefined) {
108109
return await fetchImpl(init, options)
109110
} catch (err) {
110111
if (err && typeof err === 'object') {
111-
Error.captureStackTrace(err, this)
112+
Error.captureStackTrace(err)
112113
}
113114

114115
throw err

deps/undici/src/lib/core/symbols.js

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ module.exports = {
88
kQueue: Symbol('queue'),
99
kConnect: Symbol('connect'),
1010
kConnecting: Symbol('connecting'),
11-
kHeadersList: Symbol('headers list'),
1211
kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'),
1312
kKeepAliveMaxTimeout: Symbol('max keep alive timeout'),
1413
kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'),

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,7 @@ function writeStream ({ abort, body, client, request, socket, contentLength, hea
11011101
}
11021102
}
11031103

1104-
async function writeBuffer ({ abort, body, client, request, socket, contentLength, header, expectsPayload }) {
1104+
function writeBuffer ({ abort, body, client, request, socket, contentLength, header, expectsPayload }) {
11051105
try {
11061106
if (!body) {
11071107
if (contentLength === 0) {
+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
'use strict'
2+
3+
const util = require('../core/util')
4+
const { InvalidArgumentError, RequestAbortedError } = require('../core/errors')
5+
const DecoratorHandler = require('../handler/decorator-handler')
6+
7+
class DumpHandler extends DecoratorHandler {
8+
#maxSize = 1024 * 1024
9+
#abort = null
10+
#dumped = false
11+
#aborted = false
12+
#size = 0
13+
#reason = null
14+
#handler = null
15+
16+
constructor ({ maxSize }, handler) {
17+
super(handler)
18+
19+
if (maxSize != null && (!Number.isFinite(maxSize) || maxSize < 1)) {
20+
throw new InvalidArgumentError('maxSize must be a number greater than 0')
21+
}
22+
23+
this.#maxSize = maxSize ?? this.#maxSize
24+
this.#handler = handler
25+
}
26+
27+
onConnect (abort) {
28+
this.#abort = abort
29+
30+
this.#handler.onConnect(this.#customAbort.bind(this))
31+
}
32+
33+
#customAbort (reason) {
34+
this.#aborted = true
35+
this.#reason = reason
36+
}
37+
38+
// TODO: will require adjustment after new hooks are out
39+
onHeaders (statusCode, rawHeaders, resume, statusMessage) {
40+
const headers = util.parseHeaders(rawHeaders)
41+
const contentLength = headers['content-length']
42+
43+
if (contentLength != null && contentLength > this.#maxSize) {
44+
throw new RequestAbortedError(
45+
`Response size (${contentLength}) larger than maxSize (${
46+
this.#maxSize
47+
})`
48+
)
49+
}
50+
51+
if (this.#aborted) {
52+
return true
53+
}
54+
55+
return this.#handler.onHeaders(
56+
statusCode,
57+
rawHeaders,
58+
resume,
59+
statusMessage
60+
)
61+
}
62+
63+
onError (err) {
64+
if (this.#dumped) {
65+
return
66+
}
67+
68+
err = this.#reason ?? err
69+
70+
this.#handler.onError(err)
71+
}
72+
73+
onData (chunk) {
74+
this.#size = this.#size + chunk.length
75+
76+
if (this.#size >= this.#maxSize) {
77+
this.#dumped = true
78+
79+
if (this.#aborted) {
80+
this.#handler.onError(this.#reason)
81+
} else {
82+
this.#handler.onComplete([])
83+
}
84+
}
85+
86+
return true
87+
}
88+
89+
onComplete (trailers) {
90+
if (this.#dumped) {
91+
return
92+
}
93+
94+
if (this.#aborted) {
95+
this.#handler.onError(this.reason)
96+
return
97+
}
98+
99+
this.#handler.onComplete(trailers)
100+
}
101+
}
102+
103+
function createDumpInterceptor (
104+
{ maxSize: defaultMaxSize } = {
105+
maxSize: 1024 * 1024
106+
}
107+
) {
108+
return dispatch => {
109+
return function Intercept (opts, handler) {
110+
const { dumpMaxSize = defaultMaxSize } =
111+
opts
112+
113+
const dumpHandler = new DumpHandler(
114+
{ maxSize: dumpMaxSize },
115+
handler
116+
)
117+
118+
return dispatch(opts, dumpHandler)
119+
}
120+
}
121+
}
122+
123+
module.exports = createDumpInterceptor

deps/undici/src/lib/web/cookies/util.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict'
22

33
const assert = require('node:assert')
4-
const { kHeadersList } = require('../../core/symbols')
4+
const { getHeadersList: internalGetHeadersList } = require('../fetch/headers')
55

66
/**
77
* @param {string} value
@@ -278,8 +278,10 @@ function stringify (cookie) {
278278
let kHeadersListNode
279279

280280
function getHeadersList (headers) {
281-
if (headers[kHeadersList]) {
282-
return headers[kHeadersList]
281+
try {
282+
return internalGetHeadersList(headers)
283+
} catch {
284+
// fall-through
283285
}
284286

285287
if (!kHeadersListNode) {

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

+9
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,15 @@ function bodyMixinMethods (instance) {
385385
'Content-Type was not one of "multipart/form-data" or "application/x-www-form-urlencoded".'
386386
)
387387
}, instance, false)
388+
},
389+
390+
bytes () {
391+
// The bytes() method steps are to return the result of running consume body
392+
// with this and the following step given a byte sequence bytes: return the
393+
// result of creating a Uint8Array from bytes in this’s relevant realm.
394+
return consumeBody(this, (bytes) => {
395+
return new Uint8Array(bytes.buffer, 0, bytes.byteLength)
396+
}, instance, true)
388397
}
389398
}
390399

0 commit comments

Comments
 (0)