Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deps: update undici to 5.10.0 #44319

Merged
merged 2 commits into from Aug 24, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion deps/undici/src/docs/api/Client.md
Expand Up @@ -18,7 +18,7 @@ Returns: `Client`
### Parameter: `ClientOptions`

* **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.
* **headersTimeout** `number | null` (optional) - Default: `30e3` - The amount of time the parser will wait to receive the complete HTTP headers. Defaults to 30 seconds.
* **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.
* **keepAliveMaxTimeout** `number | null` (optional) - Default: `600e3` - The maximum allowed `keepAliveTimeout` when overridden by *keep-alive* hints from the server. Defaults to 10 minutes.
* **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.
* **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.
Expand Down
2 changes: 1 addition & 1 deletion deps/undici/src/docs/api/Dispatcher.md
Expand Up @@ -199,7 +199,7 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo
* **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.
* **upgrade** `string | null` (optional) - Default: `null` - Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`.
* **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.
* **headersTimeout** `number | null` (optional) - The amount of time the parser will wait to receive the complete HTTP headers. Defaults to 30 seconds.
* **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.
* **throwOnError** `boolean` (optional) - Default: `false` - Whether Undici should throw an error upon receiving a 4xx or 5xx response from the server.

#### Parameter: `DispatchHandler`
Expand Down
17 changes: 15 additions & 2 deletions deps/undici/src/lib/client.js
Expand Up @@ -889,8 +889,10 @@ function onParserTimeout (parser) {

/* istanbul ignore else */
if (timeoutType === TIMEOUT_HEADERS) {
assert(!parser.paused, 'cannot be paused while waiting for headers')
util.destroy(socket, new HeadersTimeoutError())
if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) {
assert(!parser.paused, 'cannot be paused while waiting for headers')
util.destroy(socket, new HeadersTimeoutError())
}
} else if (timeoutType === TIMEOUT_BODY) {
if (!parser.paused) {
util.destroy(socket, new BodyTimeoutError())
Expand Down Expand Up @@ -1641,7 +1643,18 @@ class AsyncWriter {
this.bytesWritten += len

const ret = socket.write(chunk)

request.onBodySent(chunk)

if (!ret) {
if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) {
// istanbul ignore else: only for jest
if (socket[kParser].timeout.refresh) {
socket[kParser].timeout.refresh()
}
}
}

return ret
}

Expand Down
6 changes: 5 additions & 1 deletion deps/undici/src/lib/core/util.js
Expand Up @@ -244,7 +244,11 @@ function parseHeaders (headers, obj = {}) {
const key = headers[i].toString().toLowerCase()
let val = obj[key]
if (!val) {
obj[key] = headers[i + 1].toString()
if (Array.isArray(headers[i + 1])) {
obj[key] = headers[i + 1]
} else {
obj[key] = headers[i + 1].toString()
}
} else {
if (!Array.isArray(val)) {
val = [val]
Expand Down
4 changes: 3 additions & 1 deletion deps/undici/src/lib/fetch/file.js
Expand Up @@ -278,7 +278,9 @@ function processBlobParts (parts, options) {
if (!element.buffer) { // ArrayBuffer
bytes.push(new Uint8Array(element))
} else {
bytes.push(element.buffer)
bytes.push(
new Uint8Array(element.buffer, element.byteOffset, element.byteLength)
)
}
} else if (isBlobLike(element)) {
// 3. If element is a Blob, append the bytes it represents
Expand Down
15 changes: 4 additions & 11 deletions deps/undici/src/lib/fetch/index.js
Expand Up @@ -34,7 +34,8 @@ const {
sameOrigin,
isCancelled,
isAborted,
isErrorLike
isErrorLike,
fullyReadBody
} = require('./util')
const { kState, kHeaders, kGuard, kRealm } = require('./symbols')
const assert = require('assert')
Expand Down Expand Up @@ -738,11 +739,7 @@ async function mainFetch (fetchParams, recursive = false) {
}

// 4. Fully read response’s body given processBody and processBodyError.
try {
processBody(await response.arrayBuffer())
} catch (err) {
processBodyError(err)
}
await fullyReadBody(response.body, processBody, processBodyError)
} else {
// 21. Otherwise, run fetch finale given fetchParams and response.
fetchFinale(fetchParams, response)
Expand Down Expand Up @@ -974,11 +971,7 @@ async function fetchFinale (fetchParams, response) {
} else {
// 4. Otherwise, fully read response’s body given processBody, processBodyError,
// and fetchParams’s task destination.
try {
processBody(await response.body.stream.arrayBuffer())
} catch (err) {
processBodyError(err)
}
await fullyReadBody(response.body, processBody, processBodyError)
}
}
}
Expand Down
55 changes: 53 additions & 2 deletions deps/undici/src/lib/fetch/util.js
Expand Up @@ -4,6 +4,8 @@ const { redirectStatus } = require('./constants')
const { performance } = require('perf_hooks')
const { isBlobLike, toUSVString, ReadableStreamFrom } = require('../core/util')
const assert = require('assert')
const { isUint8Array } = require('util/types')
const { createHash } = require('crypto')

let File

Expand Down Expand Up @@ -340,7 +342,8 @@ function determineRequestsReferrer (request) {
}

function matchRequestIntegrity (request, bytes) {
return false
const [algo, expectedHashValue] = request.integrity.split('-', 2)
return createHash(algo).update(bytes).digest('hex') === expectedHashValue
}

// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request
Expand Down Expand Up @@ -438,6 +441,53 @@ function makeIterator (iterator, name) {
return Object.setPrototypeOf({}, i)
}

/**
* @see https://fetch.spec.whatwg.org/#body-fully-read
*/
async function fullyReadBody (body, processBody, processBodyError) {
// 1. If taskDestination is null, then set taskDestination to
// the result of starting a new parallel queue.

// 2. Let promise be the result of fully reading body as promise
// given body.
try {
/** @type {Uint8Array[]} */
const chunks = []
let length = 0

const reader = body.stream.getReader()

while (true) {
const { done, value } = await reader.read()

if (done === true) {
break
}

// read-loop chunk steps
assert(isUint8Array(value))

chunks.push(value)
length += value.byteLength
}

// 3. Let fulfilledSteps given a byte sequence bytes be to queue
// a fetch task to run processBody given bytes, with
// taskDestination.
const fulfilledSteps = (bytes) => queueMicrotask(() => {
processBody(bytes)
})

fulfilledSteps(Buffer.concat(chunks, length))
} catch (err) {
// 4. Let rejectedSteps be to queue a fetch task to run
// processBodyError, with taskDestination.
queueMicrotask(() => processBodyError(err))
}

// 5. React to promise with fulfilledSteps and rejectedSteps.
}

/**
* Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0.
*/
Expand Down Expand Up @@ -477,5 +527,6 @@ module.exports = {
isValidHeaderName,
isValidHeaderValue,
hasOwn,
isErrorLike
isErrorLike,
fullyReadBody
}
2 changes: 1 addition & 1 deletion deps/undici/src/package.json
@@ -1,6 +1,6 @@
{
"name": "undici",
"version": "5.8.2",
"version": "5.9.1",
"description": "An HTTP/1.1 client, written from scratch for Node.js",
"homepage": "https://undici.nodejs.org",
"bugs": {
Expand Down
66 changes: 49 additions & 17 deletions deps/undici/undici.js
Expand Up @@ -835,7 +835,11 @@ var require_util = __commonJS({
const key = headers[i].toString().toLowerCase();
let val = obj[key];
if (!val) {
obj[key] = headers[i + 1].toString();
if (Array.isArray(headers[i + 1])) {
obj[key] = headers[i + 1];
} else {
obj[key] = headers[i + 1].toString();
}
} else {
if (!Array.isArray(val)) {
val = [val];
Expand Down Expand Up @@ -1537,7 +1541,7 @@ var require_file = __commonJS({
if (!element.buffer) {
bytes.push(new Uint8Array(element));
} else {
bytes.push(element.buffer);
bytes.push(new Uint8Array(element.buffer, element.byteOffset, element.byteLength));
}
} else if (isBlobLike(element)) {
bytes.push(element);
Expand All @@ -1564,6 +1568,8 @@ var require_util2 = __commonJS({
var { performance: performance2 } = require("perf_hooks");
var { isBlobLike, toUSVString, ReadableStreamFrom } = require_util();
var assert = require("assert");
var { isUint8Array } = require("util/types");
var { createHash } = require("crypto");
var File;
var badPorts = [
"1",
Expand Down Expand Up @@ -1804,7 +1810,8 @@ var require_util2 = __commonJS({
return "no-referrer";
}
function matchRequestIntegrity(request, bytes) {
return false;
const [algo, expectedHashValue] = request.integrity.split("-", 2);
return createHash(algo).update(bytes).digest("hex") === expectedHashValue;
}
function tryUpgradeRequestToAPotentiallyTrustworthyURL(request) {
}
Expand Down Expand Up @@ -1854,6 +1861,28 @@ var require_util2 = __commonJS({
Object.setPrototypeOf(i, esIteratorPrototype);
return Object.setPrototypeOf({}, i);
}
async function fullyReadBody(body, processBody, processBodyError) {
try {
const chunks = [];
let length = 0;
const reader = body.stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done === true) {
break;
}
assert(isUint8Array(value));
chunks.push(value);
length += value.byteLength;
}
const fulfilledSteps = (bytes) => queueMicrotask(() => {
processBody(bytes);
});
fulfilledSteps(Buffer.concat(chunks, length));
} catch (err) {
queueMicrotask(() => processBodyError(err));
}
}
var hasOwn = Object.hasOwn || ((dict, key) => Object.prototype.hasOwnProperty.call(dict, key));
module2.exports = {
isAborted,
Expand Down Expand Up @@ -1889,7 +1918,8 @@ var require_util2 = __commonJS({
isValidHeaderName,
isValidHeaderValue,
hasOwn,
isErrorLike
isErrorLike,
fullyReadBody
};
}
});
Expand Down Expand Up @@ -3903,8 +3933,10 @@ var require_client = __commonJS({
function onParserTimeout(parser) {
const { socket, timeoutType, client } = parser;
if (timeoutType === TIMEOUT_HEADERS) {
assert(!parser.paused, "cannot be paused while waiting for headers");
util.destroy(socket, new HeadersTimeoutError());
if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) {
assert(!parser.paused, "cannot be paused while waiting for headers");
util.destroy(socket, new HeadersTimeoutError());
}
} else if (timeoutType === TIMEOUT_BODY) {
if (!parser.paused) {
util.destroy(socket, new BodyTimeoutError());
Expand Down Expand Up @@ -4452,6 +4484,13 @@ ${len.toString(16)}\r
this.bytesWritten += len;
const ret = socket.write(chunk);
request.onBodySent(chunk);
if (!ret) {
if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) {
if (socket[kParser].timeout.refresh) {
socket[kParser].timeout.refresh();
}
}
}
return ret;
}
end() {
Expand Down Expand Up @@ -6228,7 +6267,8 @@ var require_fetch = __commonJS({
sameOrigin,
isCancelled,
isAborted,
isErrorLike
isErrorLike,
fullyReadBody
} = require_util2();
var { kState, kHeaders, kGuard, kRealm } = require_symbols2();
var assert = require("assert");
Expand Down Expand Up @@ -6540,11 +6580,7 @@ var require_fetch = __commonJS({
response.body = safelyExtractBody(bytes)[0];
fetchFinale(fetchParams, response);
};
try {
processBody(await response.arrayBuffer());
} catch (err) {
processBodyError(err);
}
await fullyReadBody(response.body, processBody, processBodyError);
} else {
fetchFinale(fetchParams, response);
}
Expand Down Expand Up @@ -6667,11 +6703,7 @@ var require_fetch = __commonJS({
if (response.body == null) {
queueMicrotask(() => processBody(null));
} else {
try {
processBody(await response.body.stream.arrayBuffer());
} catch (err) {
processBodyError(err);
}
await fullyReadBody(response.body, processBody, processBodyError);
}
}
}
Expand Down