undici 4.11.2 → 4.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/docs/api/Dispatcher.md +1 -1
- package/docs/best-practices/mocking-request.md +2 -2
- package/docs/best-practices/proxy.md +1 -1
- package/lib/api/readable.js +2 -2
- package/lib/balanced-pool.js +5 -5
- package/lib/client.js +1 -1
- package/lib/core/util.js +26 -7
- package/lib/fetch/body.js +3 -13
- package/lib/fetch/constants.js +1 -0
- package/lib/fetch/file.js +1 -0
- package/lib/fetch/index.js +194 -213
- package/lib/fetch/request.js +62 -14
- package/lib/fetch/response.js +3 -2
- package/lib/fetch/symbols.js +1 -2
- package/lib/fetch/util.js +40 -9
- package/lib/mock/mock-utils.js +5 -1
- package/lib/pool-base.js +5 -9
- package/lib/pool.js +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -203,13 +203,13 @@ not support or does not fully implement.
|
|
|
203
203
|
* https://fetch.spec.whatwg.org/#garbage-collection
|
|
204
204
|
|
|
205
205
|
The [Fetch Standard](https://fetch.spec.whatwg.org) allows users to skip consuming the response body by relying on
|
|
206
|
-
[garbage collection](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management#garbage_collection) to release connection resources. Undici does the same.
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
206
|
+
[garbage collection](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management#garbage_collection) to release connection resources. Undici does not do the same. Therefore, it is important to always either consume or cancel the response body.
|
|
207
|
+
|
|
208
|
+
Garbage collection in Node is less aggressive and deterministic
|
|
209
|
+
(due to the lack of clear idle periods that browser have through the rendering refresh rate)
|
|
210
|
+
which means that leaving the release of connection resources to the garbage collector can lead
|
|
211
|
+
to excessive connection usage, reduced performance (due to less connection re-use), and even
|
|
212
|
+
stalls or deadlocks when running out of connections.
|
|
213
213
|
|
|
214
214
|
```js
|
|
215
215
|
// Do
|
|
@@ -289,7 +289,7 @@ pipeline requests, without checking whether the connection is persistent.
|
|
|
289
289
|
Hence, automatic fallback to HTTP/1.0 or HTTP/1.1 without pipelining is
|
|
290
290
|
not supported.
|
|
291
291
|
|
|
292
|
-
Undici will immediately pipeline when retrying requests
|
|
292
|
+
Undici will immediately pipeline when retrying requests after a failed
|
|
293
293
|
connection. However, Undici will not retry the first remaining requests in
|
|
294
294
|
the prior pipeline and instead error the corresponding callback/promise/stream.
|
|
295
295
|
|
package/docs/api/Dispatcher.md
CHANGED
|
@@ -571,7 +571,7 @@ try {
|
|
|
571
571
|
|
|
572
572
|
A faster version of `Dispatcher.request`. This method expects the second argument `factory` to return a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable) stream which the response will be written to. This improves performance by avoiding creating an intermediate [`stream.Readable`](https://nodejs.org/api/stream.html#stream_readable_streams) stream when the user expects to directly pipe the response body to a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable) stream.
|
|
573
573
|
|
|
574
|
-
As demonstrated in [Example 1 - Basic GET stream request](#example-1
|
|
574
|
+
As demonstrated in [Example 1 - Basic GET stream request](#example-1-basic-get-stream-request), it is recommended to use the `option.opaque` property to avoid creating a closure for the `factory` method. This pattern works well with Node.js Web Frameworks such as [Fastify](https://fastify.io). See [Example 2 - Stream to Fastify Response](#example-2-stream-to-fastify-response) for more details.
|
|
575
575
|
|
|
576
576
|
Arguments:
|
|
577
577
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Mocking Request
|
|
2
2
|
|
|
3
|
-
Undici have its own mocking [utility](
|
|
3
|
+
Undici have its own mocking [utility](../api/MockAgent.md). It allow us to intercept undici HTTP request and return mocked value instead. It can be useful for testing purposes.
|
|
4
4
|
|
|
5
5
|
Example:
|
|
6
6
|
|
|
@@ -70,7 +70,7 @@ const badRequest = await bankTransfer('1234567890', '100')
|
|
|
70
70
|
assert.deepEqual(badRequest, { message: 'bank account not found' })
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
Explore other MockAgent functionality [here](
|
|
73
|
+
Explore other MockAgent functionality [here](../api/MockAgent.md)
|
|
74
74
|
|
|
75
75
|
## Debug Mock Value
|
|
76
76
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Connecting through a proxy is possible by:
|
|
4
4
|
|
|
5
|
-
- Using [AgentProxy](
|
|
5
|
+
- Using [AgentProxy](../api/ProxyAgent.md).
|
|
6
6
|
- Configuring `Client` or `Pool` constructor.
|
|
7
7
|
|
|
8
8
|
The proxy url should be passed to the `Client` or `Pool` constructor, while the upstream server url
|
package/lib/api/readable.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
'use strict'
|
|
4
4
|
|
|
5
5
|
const assert = require('assert')
|
|
6
|
-
const { Readable
|
|
6
|
+
const { Readable } = require('stream')
|
|
7
7
|
const { RequestAbortedError, NotSupportedError } = require('../core/errors')
|
|
8
8
|
const util = require('../core/util')
|
|
9
9
|
const { ReadableStreamFrom, toUSVString } = require('../core/util')
|
|
@@ -144,7 +144,7 @@ module.exports = class BodyReadable extends Readable {
|
|
|
144
144
|
return this[kBody]
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
async dump(opts) {
|
|
147
|
+
async dump (opts) {
|
|
148
148
|
let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144
|
|
149
149
|
try {
|
|
150
150
|
for await (const chunk of this) {
|
package/lib/balanced-pool.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
|
-
BalancedPoolMissingUpstreamError
|
|
4
|
+
BalancedPoolMissingUpstreamError
|
|
5
5
|
} = require('./core/errors')
|
|
6
6
|
const {
|
|
7
7
|
PoolBase,
|
|
@@ -9,8 +9,8 @@ const {
|
|
|
9
9
|
kNeedDrain,
|
|
10
10
|
kAddClient,
|
|
11
11
|
kRemoveClient,
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
kGetDispatcher
|
|
13
|
+
} = require('./pool-base')
|
|
14
14
|
const Pool = require('./pool')
|
|
15
15
|
const { kUrl } = require('./core/symbols')
|
|
16
16
|
|
|
@@ -65,7 +65,7 @@ class BalancedPool extends PoolBase {
|
|
|
65
65
|
.map((p) => p[kUrl].origin)
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
[
|
|
68
|
+
[kGetDispatcher] () {
|
|
69
69
|
// We validate that pools is greater than 0,
|
|
70
70
|
// otherwise we would have to wait until an upstream
|
|
71
71
|
// is added, which might never happen.
|
|
@@ -73,7 +73,7 @@ class BalancedPool extends PoolBase {
|
|
|
73
73
|
throw new BalancedPoolMissingUpstreamError()
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
const dispatcher = this[kClients].find(dispatcher => (
|
|
77
77
|
!dispatcher[kNeedDrain] &&
|
|
78
78
|
dispatcher.closed !== true &&
|
|
79
79
|
dispatcher.destroyed !== true
|
package/lib/client.js
CHANGED
package/lib/core/util.js
CHANGED
|
@@ -150,7 +150,7 @@ function isDestroyed (stream) {
|
|
|
150
150
|
return !stream || !!(stream.destroyed || stream[kDestroyed])
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
function
|
|
153
|
+
function isReadableAborted (stream) {
|
|
154
154
|
const state = stream && stream._readableState
|
|
155
155
|
return isDestroyed(stream) && state && !state.endEmitted
|
|
156
156
|
}
|
|
@@ -244,15 +244,32 @@ function validateHandler (handler, method, upgrade) {
|
|
|
244
244
|
// A body is disturbed if it has been read from and it cannot
|
|
245
245
|
// be re-used without losing state or data.
|
|
246
246
|
function isDisturbed (body) {
|
|
247
|
-
const state = body && body._readableState
|
|
248
247
|
return !!(body && (
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
248
|
+
stream.isDisturbed
|
|
249
|
+
? stream.isDisturbed(body) || body[kBodyUsed] // TODO (fix): Why is body[kBodyUsed] needed?
|
|
250
|
+
: body[kBodyUsed] ||
|
|
251
|
+
body.readableDidRead ||
|
|
252
|
+
(body._readableState && body._readableState.dataEmitted) ||
|
|
253
|
+
isReadableAborted(body)
|
|
253
254
|
))
|
|
254
255
|
}
|
|
255
256
|
|
|
257
|
+
function isErrored (body) {
|
|
258
|
+
return !!(body && (
|
|
259
|
+
stream.isErrored
|
|
260
|
+
? stream.isErrored(body)
|
|
261
|
+
: /state: 'errored'/.test(nodeUtil.inspect(body)
|
|
262
|
+
)))
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function isReadable (body) {
|
|
266
|
+
return !!(body && (
|
|
267
|
+
stream.isReadable
|
|
268
|
+
? stream.isReadable(body)
|
|
269
|
+
: /state: 'readable'/.test(nodeUtil.inspect(body)
|
|
270
|
+
)))
|
|
271
|
+
}
|
|
272
|
+
|
|
256
273
|
function getSocketInfo (socket) {
|
|
257
274
|
return {
|
|
258
275
|
localAddress: socket.localAddress,
|
|
@@ -310,8 +327,10 @@ module.exports = {
|
|
|
310
327
|
kEnumerableProperty,
|
|
311
328
|
nop,
|
|
312
329
|
isDisturbed,
|
|
330
|
+
isErrored,
|
|
331
|
+
isReadable,
|
|
313
332
|
toUSVString: nodeUtil.toUSVString || ((val) => `${val}`),
|
|
314
|
-
|
|
333
|
+
isReadableAborted,
|
|
315
334
|
isBlobLike,
|
|
316
335
|
parseOrigin,
|
|
317
336
|
parseURL,
|
package/lib/fetch/body.js
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
const util = require('../core/util')
|
|
4
4
|
const { ReadableStreamFrom, toUSVString, isBlobLike } = require('./util')
|
|
5
5
|
const { FormData } = require('./formdata')
|
|
6
|
-
const { kState
|
|
6
|
+
const { kState } = require('./symbols')
|
|
7
7
|
const { Blob } = require('buffer')
|
|
8
8
|
const { kBodyUsed } = require('../core/symbols')
|
|
9
9
|
const assert = require('assert')
|
|
10
10
|
const nodeUtil = require('util')
|
|
11
11
|
const { NotSupportedError } = require('../core/errors')
|
|
12
|
+
const { isErrored } = require('../core/util')
|
|
12
13
|
|
|
13
14
|
let ReadableStream
|
|
14
15
|
|
|
@@ -187,7 +188,7 @@ function extractBody (object, keepalive = false) {
|
|
|
187
188
|
// Whenever one or more bytes are available and stream is not errored,
|
|
188
189
|
// enqueue a Uint8Array wrapping an ArrayBuffer containing the available
|
|
189
190
|
// bytes into stream.
|
|
190
|
-
if (
|
|
191
|
+
if (!isErrored(stream)) {
|
|
191
192
|
controller.enqueue(new Uint8Array(value))
|
|
192
193
|
}
|
|
193
194
|
}
|
|
@@ -268,10 +269,6 @@ const methods = {
|
|
|
268
269
|
if (this[kState].body) {
|
|
269
270
|
const stream = this[kState].body.stream
|
|
270
271
|
|
|
271
|
-
if (stream[kError]) {
|
|
272
|
-
throw stream[kError]
|
|
273
|
-
}
|
|
274
|
-
|
|
275
272
|
if (util.isDisturbed(stream)) {
|
|
276
273
|
throw new TypeError('disturbed')
|
|
277
274
|
}
|
|
@@ -352,19 +349,12 @@ const properties = {
|
|
|
352
349
|
}
|
|
353
350
|
}
|
|
354
351
|
|
|
355
|
-
function cancelBody (body, reason) {
|
|
356
|
-
if (body.stream && !/state: 'errored'/.test(nodeUtil.inspect(body.stream))) {
|
|
357
|
-
body.stream.cancel(reason)
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
352
|
function mixinBody (prototype) {
|
|
362
353
|
Object.assign(prototype, methods)
|
|
363
354
|
Object.defineProperties(prototype, properties)
|
|
364
355
|
}
|
|
365
356
|
|
|
366
357
|
module.exports = {
|
|
367
|
-
cancelBody,
|
|
368
358
|
extractBody,
|
|
369
359
|
safelyExtractBody,
|
|
370
360
|
cloneBody,
|
package/lib/fetch/constants.js
CHANGED