undici 5.8.2 → 5.9.0
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/docs/api/Client.md +1 -1
- package/docs/api/Dispatcher.md +1 -1
- package/lib/client.js +15 -2
- package/lib/core/util.js +5 -1
- package/lib/fetch/file.js +3 -1
- package/lib/fetch/index.js +4 -11
- package/lib/fetch/util.js +53 -2
- package/package.json +1 -1
package/docs/api/Client.md
CHANGED
|
@@ -18,7 +18,7 @@ Returns: `Client`
|
|
|
18
18
|
### Parameter: `ClientOptions`
|
|
19
19
|
|
|
20
20
|
* **bodyTimeout** `number | null` (optional) - Default: `30e3` - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 30 seconds.
|
|
21
|
-
* **headersTimeout** `number | null` (optional) - Default: `30e3` - The amount of time the parser will wait to receive the complete HTTP headers. Defaults to 30 seconds.
|
|
21
|
+
* **headersTimeout** `number | null` (optional) - Default: `30e3` - The amount of time the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 30 seconds.
|
|
22
22
|
* **keepAliveMaxTimeout** `number | null` (optional) - Default: `600e3` - The maximum allowed `keepAliveTimeout` when overridden by *keep-alive* hints from the server. Defaults to 10 minutes.
|
|
23
23
|
* **keepAliveTimeout** `number | null` (optional) - Default: `4e3` - The timeout after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details. Defaults to 4 seconds.
|
|
24
24
|
* **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `1e3` - A number subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 1 second.
|
package/docs/api/Dispatcher.md
CHANGED
|
@@ -199,7 +199,7 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo
|
|
|
199
199
|
* **blocking** `boolean` (optional) - Default: `false` - Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received.
|
|
200
200
|
* **upgrade** `string | null` (optional) - Default: `null` - Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`.
|
|
201
201
|
* **bodyTimeout** `number | null` (optional) - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 30 seconds.
|
|
202
|
-
* **headersTimeout** `number | null` (optional) - The amount of time the parser will wait to receive the complete HTTP headers. Defaults to 30 seconds.
|
|
202
|
+
* **headersTimeout** `number | null` (optional) - The amount of time the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 30 seconds.
|
|
203
203
|
* **throwOnError** `boolean` (optional) - Default: `false` - Whether Undici should throw an error upon receiving a 4xx or 5xx response from the server.
|
|
204
204
|
|
|
205
205
|
#### Parameter: `DispatchHandler`
|
package/lib/client.js
CHANGED
|
@@ -889,8 +889,10 @@ function onParserTimeout (parser) {
|
|
|
889
889
|
|
|
890
890
|
/* istanbul ignore else */
|
|
891
891
|
if (timeoutType === TIMEOUT_HEADERS) {
|
|
892
|
-
|
|
893
|
-
|
|
892
|
+
if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) {
|
|
893
|
+
assert(!parser.paused, 'cannot be paused while waiting for headers')
|
|
894
|
+
util.destroy(socket, new HeadersTimeoutError())
|
|
895
|
+
}
|
|
894
896
|
} else if (timeoutType === TIMEOUT_BODY) {
|
|
895
897
|
if (!parser.paused) {
|
|
896
898
|
util.destroy(socket, new BodyTimeoutError())
|
|
@@ -1641,7 +1643,18 @@ class AsyncWriter {
|
|
|
1641
1643
|
this.bytesWritten += len
|
|
1642
1644
|
|
|
1643
1645
|
const ret = socket.write(chunk)
|
|
1646
|
+
|
|
1644
1647
|
request.onBodySent(chunk)
|
|
1648
|
+
|
|
1649
|
+
if (!ret) {
|
|
1650
|
+
if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) {
|
|
1651
|
+
// istanbul ignore else: only for jest
|
|
1652
|
+
if (socket[kParser].timeout.refresh) {
|
|
1653
|
+
socket[kParser].timeout.refresh()
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1645
1658
|
return ret
|
|
1646
1659
|
}
|
|
1647
1660
|
|
package/lib/core/util.js
CHANGED
|
@@ -244,7 +244,11 @@ function parseHeaders (headers, obj = {}) {
|
|
|
244
244
|
const key = headers[i].toString().toLowerCase()
|
|
245
245
|
let val = obj[key]
|
|
246
246
|
if (!val) {
|
|
247
|
-
|
|
247
|
+
if (Array.isArray(headers[i + 1])) {
|
|
248
|
+
obj[key] = headers[i + 1]
|
|
249
|
+
} else {
|
|
250
|
+
obj[key] = headers[i + 1].toString()
|
|
251
|
+
}
|
|
248
252
|
} else {
|
|
249
253
|
if (!Array.isArray(val)) {
|
|
250
254
|
val = [val]
|
package/lib/fetch/file.js
CHANGED
|
@@ -278,7 +278,9 @@ function processBlobParts (parts, options) {
|
|
|
278
278
|
if (!element.buffer) { // ArrayBuffer
|
|
279
279
|
bytes.push(new Uint8Array(element))
|
|
280
280
|
} else {
|
|
281
|
-
bytes.push(
|
|
281
|
+
bytes.push(
|
|
282
|
+
new Uint8Array(element.buffer, element.byteOffset, element.byteLength)
|
|
283
|
+
)
|
|
282
284
|
}
|
|
283
285
|
} else if (isBlobLike(element)) {
|
|
284
286
|
// 3. If element is a Blob, append the bytes it represents
|
package/lib/fetch/index.js
CHANGED
|
@@ -34,7 +34,8 @@ const {
|
|
|
34
34
|
sameOrigin,
|
|
35
35
|
isCancelled,
|
|
36
36
|
isAborted,
|
|
37
|
-
isErrorLike
|
|
37
|
+
isErrorLike,
|
|
38
|
+
fullyReadBody
|
|
38
39
|
} = require('./util')
|
|
39
40
|
const { kState, kHeaders, kGuard, kRealm } = require('./symbols')
|
|
40
41
|
const assert = require('assert')
|
|
@@ -738,11 +739,7 @@ async function mainFetch (fetchParams, recursive = false) {
|
|
|
738
739
|
}
|
|
739
740
|
|
|
740
741
|
// 4. Fully read response’s body given processBody and processBodyError.
|
|
741
|
-
|
|
742
|
-
processBody(await response.arrayBuffer())
|
|
743
|
-
} catch (err) {
|
|
744
|
-
processBodyError(err)
|
|
745
|
-
}
|
|
742
|
+
await fullyReadBody(response.body, processBody, processBodyError)
|
|
746
743
|
} else {
|
|
747
744
|
// 21. Otherwise, run fetch finale given fetchParams and response.
|
|
748
745
|
fetchFinale(fetchParams, response)
|
|
@@ -974,11 +971,7 @@ async function fetchFinale (fetchParams, response) {
|
|
|
974
971
|
} else {
|
|
975
972
|
// 4. Otherwise, fully read response’s body given processBody, processBodyError,
|
|
976
973
|
// and fetchParams’s task destination.
|
|
977
|
-
|
|
978
|
-
processBody(await response.body.stream.arrayBuffer())
|
|
979
|
-
} catch (err) {
|
|
980
|
-
processBodyError(err)
|
|
981
|
-
}
|
|
974
|
+
await fullyReadBody(response.body, processBody, processBodyError)
|
|
982
975
|
}
|
|
983
976
|
}
|
|
984
977
|
}
|
package/lib/fetch/util.js
CHANGED
|
@@ -4,6 +4,8 @@ const { redirectStatus } = require('./constants')
|
|
|
4
4
|
const { performance } = require('perf_hooks')
|
|
5
5
|
const { isBlobLike, toUSVString, ReadableStreamFrom } = require('../core/util')
|
|
6
6
|
const assert = require('assert')
|
|
7
|
+
const { isUint8Array } = require('util/types')
|
|
8
|
+
const { createHash } = require('crypto')
|
|
7
9
|
|
|
8
10
|
let File
|
|
9
11
|
|
|
@@ -340,7 +342,8 @@ function determineRequestsReferrer (request) {
|
|
|
340
342
|
}
|
|
341
343
|
|
|
342
344
|
function matchRequestIntegrity (request, bytes) {
|
|
343
|
-
|
|
345
|
+
const [algo, expectedHashValue] = request.integrity.split('-', 2)
|
|
346
|
+
return createHash(algo).update(bytes).digest('hex') === expectedHashValue
|
|
344
347
|
}
|
|
345
348
|
|
|
346
349
|
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request
|
|
@@ -438,6 +441,53 @@ function makeIterator (iterator, name) {
|
|
|
438
441
|
return Object.setPrototypeOf({}, i)
|
|
439
442
|
}
|
|
440
443
|
|
|
444
|
+
/**
|
|
445
|
+
* @see https://fetch.spec.whatwg.org/#body-fully-read
|
|
446
|
+
*/
|
|
447
|
+
async function fullyReadBody (body, processBody, processBodyError) {
|
|
448
|
+
// 1. If taskDestination is null, then set taskDestination to
|
|
449
|
+
// the result of starting a new parallel queue.
|
|
450
|
+
|
|
451
|
+
// 2. Let promise be the result of fully reading body as promise
|
|
452
|
+
// given body.
|
|
453
|
+
try {
|
|
454
|
+
/** @type {Uint8Array[]} */
|
|
455
|
+
const chunks = []
|
|
456
|
+
let length = 0
|
|
457
|
+
|
|
458
|
+
const reader = body.stream.getReader()
|
|
459
|
+
|
|
460
|
+
while (true) {
|
|
461
|
+
const { done, value } = await reader.read()
|
|
462
|
+
|
|
463
|
+
if (done === true) {
|
|
464
|
+
break
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// read-loop chunk steps
|
|
468
|
+
assert(isUint8Array(value))
|
|
469
|
+
|
|
470
|
+
chunks.push(value)
|
|
471
|
+
length += value.byteLength
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// 3. Let fulfilledSteps given a byte sequence bytes be to queue
|
|
475
|
+
// a fetch task to run processBody given bytes, with
|
|
476
|
+
// taskDestination.
|
|
477
|
+
const fulfilledSteps = (bytes) => queueMicrotask(() => {
|
|
478
|
+
processBody(bytes)
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
fulfilledSteps(Buffer.concat(chunks, length))
|
|
482
|
+
} catch (err) {
|
|
483
|
+
// 4. Let rejectedSteps be to queue a fetch task to run
|
|
484
|
+
// processBodyError, with taskDestination.
|
|
485
|
+
queueMicrotask(() => processBodyError(err))
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// 5. React to promise with fulfilledSteps and rejectedSteps.
|
|
489
|
+
}
|
|
490
|
+
|
|
441
491
|
/**
|
|
442
492
|
* Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0.
|
|
443
493
|
*/
|
|
@@ -477,5 +527,6 @@ module.exports = {
|
|
|
477
527
|
isValidHeaderName,
|
|
478
528
|
isValidHeaderValue,
|
|
479
529
|
hasOwn,
|
|
480
|
-
isErrorLike
|
|
530
|
+
isErrorLike,
|
|
531
|
+
fullyReadBody
|
|
481
532
|
}
|