File undici_5.8.1.patch of Package nodejs16.26207
From d09bc5402de5a9478b22ff63756f9358b0b3e1d9 Mon Sep 17 00:00:00 2001
From: "Node.js GitHub Bot" <github-bot@iojs.org>
Date: Mon, 8 Aug 2022 04:41:22 -0400
Subject: [PATCH] deps: update undici to 5.8.1
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
PR-URL: https://github.com/nodejs/node/pull/44158
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Feng Yu <F3n67u@outlook.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
---
.../docs/best-practices/mocking-request.md | 18 ++--
deps/undici/src/lib/core/connect.js | 33 +++++--
deps/undici/src/lib/fetch/body.js | 13 ++-
deps/undici/src/lib/fetch/dataURL.js | 2 +-
deps/undici/src/lib/fetch/index.js | 18 ++--
deps/undici/src/lib/fetch/request.js | 10 +--
deps/undici/src/lib/fetch/response.js | 15 ++--
deps/undici/src/lib/fetch/util.js | 10 ++-
deps/undici/src/lib/fetch/webidl.js | 5 +-
deps/undici/src/lib/mock/mock-utils.js | 29 +++++--
deps/undici/src/package.json | 3 +-
deps/undici/src/types/mock-interceptor.d.ts | 2 +-
deps/undici/src/types/pool-stats.d.ts | 19 +++++
deps/undici/src/types/pool.d.ts | 4 +
deps/undici/undici.js | 85 ++++++++++++++-----
15 files changed, 195 insertions(+), 71 deletions(-)
create mode 100644 deps/undici/src/types/pool-stats.d.ts
diff --git a/deps/undici/src/docs/best-practices/mocking-request.md b/deps/undici/src/docs/best-practices/mocking-request.md
index b98a450a32e2..695439274449 100644
--- a/deps/undici/src/docs/best-practices/mocking-request.md
+++ b/deps/undici/src/docs/best-practices/mocking-request.md
@@ -1,6 +1,6 @@
# Mocking Request
-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.
+Undici has its own mocking [utility](../api/MockAgent.md). It allow us to intercept undici HTTP requests and return mocked values instead. It can be useful for testing purposes.
Example:
@@ -8,7 +8,7 @@ Example:
// bank.mjs
import { request } from 'undici'
-export async function bankTransfer(recepient, amount) {
+export async function bankTransfer(recipient, amount) {
const { body } = await request('http://localhost:3000/bank-transfer',
{
method: 'POST',
@@ -16,7 +16,7 @@ export async function bankTransfer(recepient, amount) {
'X-TOKEN-SECRET': 'SuperSecretToken',
},
body: JSON.stringify({
- recepient,
+ recipient,
amount
})
}
@@ -48,7 +48,7 @@ mockPool.intercept({
'X-TOKEN-SECRET': 'SuperSecretToken',
},
body: JSON.stringify({
- recepient: '1234567890',
+ recipient: '1234567890',
amount: '100'
})
}).reply(200, {
@@ -77,7 +77,7 @@ Explore other MockAgent functionality [here](../api/MockAgent.md)
## Debug Mock Value
-When the interceptor we wrote are not the same undici will automatically call real HTTP request. To debug our mock value use `mockAgent.disableNetConnect()`
+When the interceptor and the request options are not the same, undici will automatically make a real HTTP request. To prevent real requests from being made, use `mockAgent.disableNetConnect()`:
```js
const mockAgent = new MockAgent();
@@ -89,7 +89,7 @@ mockAgent.disableNetConnect()
const mockPool = mockAgent.get('http://localhost:3000');
mockPool.intercept({
- path: '/bank-tanfer',
+ path: '/bank-transfer',
method: 'POST',
}).reply(200, {
message: 'transaction processed'
@@ -103,7 +103,7 @@ const badRequest = await bankTransfer('1234567890', '100')
## Reply with data based on request
-If the mocked response needs to be dynamically derived from the request parameters, you can provide a function instead of an object to `reply`
+If the mocked response needs to be dynamically derived from the request parameters, you can provide a function instead of an object to `reply`:
```js
mockPool.intercept({
@@ -113,7 +113,7 @@ mockPool.intercept({
'X-TOKEN-SECRET': 'SuperSecretToken',
},
body: JSON.stringify({
- recepient: '1234567890',
+ recipient: '1234567890',
amount: '100'
})
}).reply(200, (opts) => {
@@ -129,7 +129,7 @@ in this case opts will be
{
method: 'POST',
headers: { 'X-TOKEN-SECRET': 'SuperSecretToken' },
- body: '{"recepient":"1234567890","amount":"100"}',
+ body: '{"recipient":"1234567890","amount":"100"}',
origin: 'http://localhost:3000',
path: '/bank-transfer'
}
diff --git a/deps/undici/src/lib/core/connect.js b/deps/undici/src/lib/core/connect.js
index 57667a1314af..e9b456f88319 100644
--- a/deps/undici/src/lib/core/connect.js
+++ b/deps/undici/src/lib/core/connect.js
@@ -75,14 +75,12 @@ function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) {
})
}
- const timeoutId = timeout
- ? setTimeout(onConnectTimeout, timeout, socket)
- : null
+ const cancelTimeout = setupTimeout(() => onConnectTimeout(socket), timeout)
socket
.setNoDelay(true)
.once(protocol === 'https:' ? 'secureConnect' : 'connect', function () {
- clearTimeout(timeoutId)
+ cancelTimeout()
if (callback) {
const cb = callback
@@ -91,7 +89,7 @@ function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) {
}
})
.on('error', function (err) {
- clearTimeout(timeoutId)
+ cancelTimeout()
if (callback) {
const cb = callback
@@ -104,6 +102,31 @@ function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) {
}
}
+function setupTimeout (onConnectTimeout, timeout) {
+ if (!timeout) {
+ return () => {}
+ }
+
+ let s1 = null
+ let s2 = null
+ const timeoutId = setTimeout(() => {
+ // setImmediate is added to make sure that we priotorise socket error events over timeouts
+ s1 = setImmediate(() => {
+ if (process.platform === 'win32') {
+ // Windows needs an extra setImmediate probably due to implementation differences in the socket logic
+ s2 = setImmediate(() => onConnectTimeout())
+ } else {
+ onConnectTimeout()
+ }
+ })
+ }, timeout)
+ return () => {
+ clearTimeout(timeoutId)
+ clearImmediate(s1)
+ clearImmediate(s2)
+ }
+}
+
function onConnectTimeout (socket) {
util.destroy(socket, new ConnectTimeoutError())
}
diff --git a/deps/undici/src/lib/fetch/body.js b/deps/undici/src/lib/fetch/body.js
index 2a9f1c83d888..08d22310a38d 100644
--- a/deps/undici/src/lib/fetch/body.js
+++ b/deps/undici/src/lib/fetch/body.js
@@ -404,7 +404,18 @@ function bodyMixinMethods (instance) {
// 1. Let entries be the result of parsing bytes.
let entries
try {
- entries = new URLSearchParams(await this.text())
+ let text = ''
+ // application/x-www-form-urlencoded parser will keep the BOM.
+ // https://url.spec.whatwg.org/#concept-urlencoded-parser
+ const textDecoder = new TextDecoder('utf-8', { ignoreBOM: true })
+ for await (const chunk of consumeBody(this[kState].body)) {
+ if (!isUint8Array(chunk)) {
+ throw new TypeError('Expected Uint8Array chunk')
+ }
+ text += textDecoder.decode(chunk, { stream: true })
+ }
+ text += textDecoder.decode()
+ entries = new URLSearchParams(text)
} catch (err) {
// istanbul ignore next: Unclear when new URLSearchParams can fail on a string.
// 2. If entries is failure, then throw a TypeError.
diff --git a/deps/undici/src/lib/fetch/dataURL.js b/deps/undici/src/lib/fetch/dataURL.js
index 5eb0a514aed2..cad44853e165 100644
--- a/deps/undici/src/lib/fetch/dataURL.js
+++ b/deps/undici/src/lib/fetch/dataURL.js
@@ -255,7 +255,7 @@ function percentDecode (input) {
}
// 3. Return output.
- return Uint8Array.of(...output)
+ return Uint8Array.from(output)
}
// https://mimesniff.spec.whatwg.org/#parse-a-mime-type
diff --git a/deps/undici/src/lib/fetch/index.js b/deps/undici/src/lib/fetch/index.js
index cf91a5d378e9..f9b09547edbc 100644
--- a/deps/undici/src/lib/fetch/index.js
+++ b/deps/undici/src/lib/fetch/index.js
@@ -33,7 +33,8 @@ const {
isBlobLike,
sameOrigin,
isCancelled,
- isAborted
+ isAborted,
+ isErrorLike
} = require('./util')
const { kState, kHeaders, kGuard, kRealm } = require('./symbols')
const assert = require('assert')
@@ -1854,7 +1855,7 @@ async function httpNetworkFetch (
timingInfo.decodedBodySize += bytes?.byteLength ?? 0
// 6. If bytes is failure, then terminate fetchParams’s controller.
- if (bytes instanceof Error) {
+ if (isErrorLike(bytes)) {
fetchParams.controller.terminate(bytes)
return
}
@@ -1894,7 +1895,7 @@ async function httpNetworkFetch (
// 3. Otherwise, if stream is readable, error stream with a TypeError.
if (isReadable(stream)) {
fetchParams.controller.controller.error(new TypeError('terminated', {
- cause: reason instanceof Error ? reason : undefined
+ cause: isErrorLike(reason) ? reason : undefined
}))
}
}
@@ -1942,14 +1943,17 @@ async function httpNetworkFetch (
}
let codings = []
+ let location = ''
const headers = new Headers()
for (let n = 0; n < headersList.length; n += 2) {
- const key = headersList[n + 0].toString()
- const val = headersList[n + 1].toString()
+ const key = headersList[n + 0].toString('latin1')
+ const val = headersList[n + 1].toString('latin1')
if (key.toLowerCase() === 'content-encoding') {
codings = val.split(',').map((x) => x.trim())
+ } else if (key.toLowerCase() === 'location') {
+ location = val
}
headers.append(key, val)
@@ -1960,7 +1964,7 @@ async function httpNetworkFetch (
const decoders = []
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
- if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status)) {
+ if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !(request.redirect === 'follow' && location)) {
for (const coding of codings) {
if (/(x-)?gzip/.test(coding)) {
decoders.push(zlib.createGunzip())
@@ -1980,7 +1984,7 @@ async function httpNetworkFetch (
statusText,
headersList: headers[kHeadersList],
body: decoders.length
- ? pipeline(this.body, ...decoders, () => {})
+ ? pipeline(this.body, ...decoders, () => { })
: this.body.on('error', () => {})
})
diff --git a/deps/undici/src/lib/fetch/request.js b/deps/undici/src/lib/fetch/request.js
index 7e1b3d8eb1d0..7fda8d90b28b 100644
--- a/deps/undici/src/lib/fetch/request.js
+++ b/deps/undici/src/lib/fetch/request.js
@@ -367,9 +367,9 @@ class Request {
}
if (signal.aborted) {
- ac.abort()
+ ac.abort(signal.reason)
} else {
- const abort = () => ac.abort()
+ const abort = () => ac.abort(signal.reason)
signal.addEventListener('abort', abort, { once: true })
requestFinalizer.register(this, { signal, abort })
}
@@ -726,12 +726,12 @@ class Request {
// 4. Make clonedRequestObject’s signal follow this’s signal.
const ac = new AbortController()
if (this.signal.aborted) {
- ac.abort()
+ ac.abort(this.signal.reason)
} else {
this.signal.addEventListener(
'abort',
- function () {
- ac.abort()
+ () => {
+ ac.abort(this.signal.reason)
},
{ once: true }
)
diff --git a/deps/undici/src/lib/fetch/response.js b/deps/undici/src/lib/fetch/response.js
index 4649a5da9070..526259478d40 100644
--- a/deps/undici/src/lib/fetch/response.js
+++ b/deps/undici/src/lib/fetch/response.js
@@ -10,7 +10,8 @@ const {
isCancelled,
isAborted,
isBlobLike,
- serializeJavascriptValueToJSONString
+ serializeJavascriptValueToJSONString,
+ isErrorLike
} = require('./util')
const {
redirectStatus,
@@ -347,15 +348,15 @@ function makeResponse (init) {
}
function makeNetworkError (reason) {
+ const isError = isErrorLike(reason)
return makeResponse({
type: 'error',
status: 0,
- error:
- reason instanceof Error
- ? reason
- : new Error(reason ? String(reason) : reason, {
- cause: reason instanceof Error ? reason : undefined
- }),
+ error: isError
+ ? reason
+ : new Error(reason ? String(reason) : reason, {
+ cause: isError ? reason : undefined
+ }),
aborted: reason && reason.name === 'AbortError'
})
}
diff --git a/deps/undici/src/lib/fetch/util.js b/deps/undici/src/lib/fetch/util.js
index 17c68162980f..9806e331871c 100644
--- a/deps/undici/src/lib/fetch/util.js
+++ b/deps/undici/src/lib/fetch/util.js
@@ -82,6 +82,13 @@ function isFileLike (object) {
)
}
+function isErrorLike (object) {
+ return object instanceof Error || (
+ object?.constructor?.name === 'Error' ||
+ object?.constructor?.name === 'DOMException'
+ )
+}
+
// Check whether |statusText| is a ByteString and
// matches the Reason-Phrase token production.
// RFC 2616: https://tools.ietf.org/html/rfc2616
@@ -469,5 +476,6 @@ module.exports = {
makeIterator,
isValidHeaderName,
isValidHeaderValue,
- hasOwn
+ hasOwn,
+ isErrorLike
}
diff --git a/deps/undici/src/lib/fetch/webidl.js b/deps/undici/src/lib/fetch/webidl.js
index f9a780ccaa74..293199e8f9b4 100644
--- a/deps/undici/src/lib/fetch/webidl.js
+++ b/deps/undici/src/lib/fetch/webidl.js
@@ -388,8 +388,9 @@ webidl.converters.DOMString = function (V, opts = {}) {
return String(V)
}
+// Check for 0 or more characters outside of the latin1 range.
// eslint-disable-next-line no-control-regex
-const isNotLatin1 = /[^\u0000-\u00ff]/
+const isLatin1 = /^[\u0000-\u00ff]{0,}$/
// https://webidl.spec.whatwg.org/#es-ByteString
webidl.converters.ByteString = function (V) {
@@ -399,7 +400,7 @@ webidl.converters.ByteString = function (V) {
// 2. If the value of any element of x is greater than
// 255, then throw a TypeError.
- if (isNotLatin1.test(x)) {
+ if (!isLatin1.test(x)) {
throw new TypeError('Argument is not a ByteString')
}
diff --git a/deps/undici/src/lib/mock/mock-utils.js b/deps/undici/src/lib/mock/mock-utils.js
index 80052223f8fb..7e115f83b4d5 100644
--- a/deps/undici/src/lib/mock/mock-utils.js
+++ b/deps/undici/src/lib/mock/mock-utils.js
@@ -38,7 +38,7 @@ function lowerCaseEntries (headers) {
function getHeaderByName (headers, key) {
if (Array.isArray(headers)) {
for (let i = 0; i < headers.length; i += 2) {
- if (headers[i] === key) {
+ if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) {
return headers[i + 1]
}
}
@@ -47,19 +47,24 @@ function getHeaderByName (headers, key) {
} else if (typeof headers.get === 'function') {
return headers.get(key)
} else {
- return headers[key]
+ return lowerCaseEntries(headers)[key.toLocaleLowerCase()]
}
}
+/** @param {string[]} headers */
+function buildHeadersFromArray (headers) { // fetch HeadersList
+ const clone = headers.slice()
+ const entries = []
+ for (let index = 0; index < clone.length; index += 2) {
+ entries.push([clone[index], clone[index + 1]])
+ }
+ return Object.fromEntries(entries)
+}
+
function matchHeaders (mockDispatch, headers) {
if (typeof mockDispatch.headers === 'function') {
if (Array.isArray(headers)) { // fetch HeadersList
- const clone = headers.slice()
- const entries = []
- for (let index = 0; index < clone.length; index += 2) {
- entries.push([clone[index], clone[index + 1]])
- }
- headers = Object.fromEntries(entries)
+ headers = buildHeadersFromArray(headers)
}
return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {})
}
@@ -284,7 +289,13 @@ function mockDispatch (opts, handler) {
}
function handleReply (mockDispatches) {
- const responseData = getResponseData(typeof data === 'function' ? data(opts) : data)
+ // fetch's HeadersList is a 1D string array
+ const optsHeaders = Array.isArray(opts.headers)
+ ? buildHeadersFromArray(opts.headers)
+ : opts.headers
+ const responseData = getResponseData(
+ typeof data === 'function' ? data({ ...opts, headers: optsHeaders }) : data
+ )
const responseHeaders = generateKeyValues(headers)
const responseTrailers = generateKeyValues(trailers)
diff --git a/deps/undici/src/package.json b/deps/undici/src/package.json
index 1fde040055fa..4ac0eb8863d1 100644
--- a/deps/undici/src/package.json
+++ b/deps/undici/src/package.json
@@ -1,6 +1,6 @@
{
"name": "undici",
- "version": "5.8.0",
+ "version": "5.8.1",
"description": "An HTTP/1.1 client, written from scratch for Node.js",
"homepage": "https://undici.nodejs.org",
"bugs": {
@@ -67,6 +67,7 @@
"@sinonjs/fake-timers": "^9.1.2",
"@types/node": "^17.0.29",
"abort-controller": "^3.0.0",
+ "atomic-sleep": "^1.0.0",
"busboy": "^1.6.0",
"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
diff --git a/deps/undici/src/types/mock-interceptor.d.ts b/deps/undici/src/types/mock-interceptor.d.ts
index 8812960573f3..87eedcd40605 100644
--- a/deps/undici/src/types/mock-interceptor.d.ts
+++ b/deps/undici/src/types/mock-interceptor.d.ts
@@ -74,7 +74,7 @@ declare namespace MockInterceptor {
origin: string;
method: string;
body?: BodyInit | Dispatcher.DispatchOptions['body'];
- headers: Headers;
+ headers: Headers | Record<string, string>;
maxRedirections: number;
}
diff --git a/deps/undici/src/types/pool-stats.d.ts b/deps/undici/src/types/pool-stats.d.ts
new file mode 100644
index 000000000000..807e68f1b81d
--- /dev/null
+++ b/deps/undici/src/types/pool-stats.d.ts
@@ -0,0 +1,19 @@
+import Pool = require("./pool")
+
+export = PoolStats
+
+declare class PoolStats {
+ constructor(pool: Pool);
+ /** Number of open socket connections in this pool. */
+ connected: number;
+ /** Number of open socket connections in this pool that do not have an active request. */
+ free: number;
+ /** Number of pending requests across all clients in this pool. */
+ pending: number;
+ /** Number of queued requests across all clients in this pool. */
+ queued: number;
+ /** Number of currently active requests across all clients in this pool. */
+ running: number;
+ /** Number of active, pending, or queued requests across all clients in this pool. */
+ size: number;
+}
diff --git a/deps/undici/src/types/pool.d.ts b/deps/undici/src/types/pool.d.ts
index 82aeb376cd23..af7fb94a9a68 100644
--- a/deps/undici/src/types/pool.d.ts
+++ b/deps/undici/src/types/pool.d.ts
@@ -1,5 +1,6 @@
import Client = require('./client')
import Dispatcher = require('./dispatcher')
+import TPoolStats = require('./pool-stats')
import { URL } from 'url'
export = Pool
@@ -10,9 +11,12 @@ declare class Pool extends Dispatcher {
closed: boolean;
/** `true` after `pool.destroyed()` has been called or `pool.close()` has been called and the pool shutdown has completed. */
destroyed: boolean;
+ /** Aggregate stats for a Pool. */
+ readonly stats: TPoolStats;
}
declare namespace Pool {
+ export type PoolStats = TPoolStats;
export interface Options extends Client.Options {
/** Default: `(origin, opts) => new Client(origin, opts)`. */
factory?(origin: URL, opts: object): Dispatcher;
diff --git a/deps/undici/undici.js b/deps/undici/undici.js
index f59f177536a3..123b51b4d306 100644
--- a/deps/undici/undici.js
+++ b/deps/undici/undici.js
@@ -1281,10 +1281,10 @@ var require_webidl = __commonJS({
}
return String(V);
};
- var isNotLatin1 = /[^\u0000-\u00ff]/;
+ var isLatin1 = /^[\u0000-\u00ff]{0,}$/;
webidl.converters.ByteString = function(V) {
const x = webidl.converters.DOMString(V);
- if (isNotLatin1.test(x)) {
+ if (!isLatin1.test(x)) {
throw new TypeError("Argument is not a ByteString");
}
return x;
@@ -1671,6 +1671,9 @@ var require_util2 = __commonJS({
}
return object instanceof File || object && (typeof object.stream === "function" || typeof object.arrayBuffer === "function") && /^(File)$/.test(object[Symbol.toStringTag]);
}
+ function isErrorLike(object) {
+ return object instanceof Error || (object?.constructor?.name === "Error" || object?.constructor?.name === "DOMException");
+ }
function isValidReasonPhrase(statusText) {
for (let i = 0; i < statusText.length; ++i) {
const c = statusText.charCodeAt(i);
@@ -1877,7 +1880,8 @@ var require_util2 = __commonJS({
makeIterator,
isValidHeaderName,
isValidHeaderValue,
- hasOwn
+ hasOwn,
+ isErrorLike
};
}
});
@@ -2300,7 +2304,16 @@ Content-Type: ${value.type || "application/octet-stream"}\r
} else if (/application\/x-www-form-urlencoded/.test(contentType)) {
let entries;
try {
- entries = new URLSearchParams(await this.text());
+ let text = "";
+ const textDecoder = new TextDecoder("utf-8", { ignoreBOM: true });
+ for await (const chunk of consumeBody(this[kState].body)) {
+ if (!isUint8Array(chunk)) {
+ throw new TypeError("Expected Uint8Array chunk");
+ }
+ text += textDecoder.decode(chunk, { stream: true });
+ }
+ text += textDecoder.decode();
+ entries = new URLSearchParams(text);
} catch (err) {
throw Object.assign(new TypeError(), { cause: err });
}
@@ -2792,16 +2805,16 @@ var require_connect = __commonJS({
host: hostname
});
}
- const timeoutId = timeout ? setTimeout(onConnectTimeout, timeout, socket) : null;
+ const cancelTimeout = setupTimeout(() => onConnectTimeout(socket), timeout);
socket.setNoDelay(true).once(protocol === "https:" ? "secureConnect" : "connect", function() {
- clearTimeout(timeoutId);
+ cancelTimeout();
if (callback) {
const cb = callback;
callback = null;
cb(null, this);
}
}).on("error", function(err) {
- clearTimeout(timeoutId);
+ cancelTimeout();
if (callback) {
const cb = callback;
callback = null;
@@ -2811,6 +2824,28 @@ var require_connect = __commonJS({
return socket;
};
}
+ function setupTimeout(onConnectTimeout2, timeout) {
+ if (!timeout) {
+ return () => {
+ };
+ }
+ let s1 = null;
+ let s2 = null;
+ const timeoutId = setTimeout(() => {
+ s1 = setImmediate(() => {
+ if (process.platform === "win32") {
+ s2 = setImmediate(() => onConnectTimeout2());
+ } else {
+ onConnectTimeout2();
+ }
+ });
+ }, timeout);
+ return () => {
+ clearTimeout(timeoutId);
+ clearImmediate(s1);
+ clearImmediate(s2);
+ };
+ }
function onConnectTimeout(socket) {
util.destroy(socket, new ConnectTimeoutError());
}
@@ -5047,7 +5082,8 @@ var require_response = __commonJS({
isCancelled,
isAborted,
isBlobLike,
- serializeJavascriptValueToJSONString
+ serializeJavascriptValueToJSONString,
+ isErrorLike
} = require_util2();
var {
redirectStatus,
@@ -5245,11 +5281,12 @@ var require_response = __commonJS({
};
}
function makeNetworkError(reason) {
+ const isError = isErrorLike(reason);
return makeResponse({
type: "error",
status: 0,
- error: reason instanceof Error ? reason : new Error(reason ? String(reason) : reason, {
- cause: reason instanceof Error ? reason : void 0
+ error: isError ? reason : new Error(reason ? String(reason) : reason, {
+ cause: isError ? reason : void 0
}),
aborted: reason && reason.name === "AbortError"
});
@@ -5586,9 +5623,9 @@ var require_request2 = __commonJS({
throw new TypeError("Failed to construct 'Request': member signal is not of type AbortSignal.");
}
if (signal.aborted) {
- ac.abort();
+ ac.abort(signal.reason);
} else {
- const abort = () => ac.abort();
+ const abort = () => ac.abort(signal.reason);
signal.addEventListener("abort", abort, { once: true });
requestFinalizer.register(this, { signal, abort });
}
@@ -5767,10 +5804,10 @@ var require_request2 = __commonJS({
clonedRequestObject[kHeaders][kRealm] = this[kHeaders][kRealm];
const ac = new AbortController();
if (this.signal.aborted) {
- ac.abort();
+ ac.abort(this.signal.reason);
} else {
- this.signal.addEventListener("abort", function() {
- ac.abort();
+ this.signal.addEventListener("abort", () => {
+ ac.abort(this.signal.reason);
}, { once: true });
}
clonedRequestObject[kSignal] = ac.signal;
@@ -6035,7 +6072,7 @@ var require_dataURL = __commonJS({
i += 2;
}
}
- return Uint8Array.of(...output);
+ return Uint8Array.from(output);
}
function parseMIMEType(input) {
input = input.trim();
@@ -6182,7 +6219,8 @@ var require_fetch = __commonJS({
isBlobLike,
sameOrigin,
isCancelled,
- isAborted
+ isAborted,
+ isErrorLike
} = require_util2();
var { kState, kHeaders, kGuard, kRealm } = require_symbols2();
var assert = require("assert");
@@ -6945,7 +6983,7 @@ var require_fetch = __commonJS({
return;
}
timingInfo.decodedBodySize += bytes?.byteLength ?? 0;
- if (bytes instanceof Error) {
+ if (isErrorLike(bytes)) {
fetchParams.controller.terminate(bytes);
return;
}
@@ -6968,7 +7006,7 @@ var require_fetch = __commonJS({
} else {
if (isReadable(stream)) {
fetchParams.controller.controller.error(new TypeError("terminated", {
- cause: reason instanceof Error ? reason : void 0
+ cause: isErrorLike(reason) ? reason : void 0
}));
}
}
@@ -7003,18 +7041,21 @@ var require_fetch = __commonJS({
return;
}
let codings = [];
+ let location = "";
const headers = new Headers();
for (let n = 0; n < headersList.length; n += 2) {
- const key = headersList[n + 0].toString();
- const val = headersList[n + 1].toString();
+ const key = headersList[n + 0].toString("latin1");
+ const val = headersList[n + 1].toString("latin1");
if (key.toLowerCase() === "content-encoding") {
codings = val.split(",").map((x) => x.trim());
+ } else if (key.toLowerCase() === "location") {
+ location = val;
}
headers.append(key, val);
}
this.body = new Readable({ read: resume });
const decoders = [];
- if (request.method !== "HEAD" && request.method !== "CONNECT" && !nullBodyStatus.includes(status)) {
+ if (request.method !== "HEAD" && request.method !== "CONNECT" && !nullBodyStatus.includes(status) && !(request.redirect === "follow" && location)) {
for (const coding of codings) {
if (/(x-)?gzip/.test(coding)) {
decoders.push(zlib.createGunzip());