Skip to content

Commit 517f17b

Browse files
nodejs-github-botdanielleadams
authored andcommittedJun 16, 2022
deps: update undici to 5.5.1
PR-URL: #43412 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: LiviaMedeiros <livia@cirno.name> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent d2a98dc commit 517f17b

16 files changed

+297
-154
lines changed
 

‎deps/undici/src/README.md

+11-16
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,12 @@ Help us improve the test coverage by following instructions at [nodejs/undici/#9
185185
Basic usage example:
186186

187187
```js
188-
import {fetch} from 'undici';
188+
import { fetch } from 'undici';
189189

190-
async function fetchJson() {
191-
const res = await fetch('https://example.com')
192-
const json = await res.json()
193-
console.log(json);
194-
}
190+
191+
const res = await fetch('https://example.com')
192+
const json = await res.json()
193+
console.log(json);
195194
```
196195

197196
You can pass an optional dispatcher to `fetch` as:
@@ -235,24 +234,20 @@ const data = {
235234
},
236235
};
237236

238-
(async () => {
239-
await fetch("https://example.com", { body: data, method: 'POST' });
240-
})();
237+
await fetch("https://example.com", { body: data, method: 'POST' });
241238
```
242239

243240
#### `response.body`
244241

245242
Nodejs has two kinds of streams: [web streams](https://nodejs.org/dist/latest-v16.x/docs/api/webstreams.html), which follow the API of the WHATWG web standard found in browsers, and an older Node-specific [streams API](https://nodejs.org/api/stream.html). `response.body` returns a readable web stream. If you would prefer to work with a Node stream you can convert a web stream using `.fromWeb()`.
246243

247244
```js
248-
import {fetch} from 'undici';
249-
import {Readable} from 'node:stream';
245+
import { fetch } from 'undici';
246+
import { Readable } from 'node:stream';
250247

251-
async function fetchStream() {
252-
const response = await fetch('https://example.com')
253-
const readableWebStream = response.body;
254-
const readableNodeStream = Readable.fromWeb(readableWebStream);
255-
}
248+
const response = await fetch('https://example.com')
249+
const readableWebStream = response.body;
250+
const readableNodeStream = Readable.fromWeb(readableWebStream);
256251
```
257252

258253
#### Specification Compliance

‎deps/undici/src/lib/api/api-connect.js

+19-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class ConnectHandler extends AsyncResource {
1515
throw new InvalidArgumentError('invalid callback')
1616
}
1717

18-
const { signal, opaque, responseHeaders } = opts
18+
const { signal, opaque, responseHeaders, httpTunnel } = opts
1919

2020
if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') {
2121
throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget')
@@ -27,6 +27,7 @@ class ConnectHandler extends AsyncResource {
2727
this.responseHeaders = responseHeaders || null
2828
this.callback = callback
2929
this.abort = null
30+
this.httpTunnel = httpTunnel
3031

3132
addSignal(this, signal)
3233
}
@@ -40,8 +41,23 @@ class ConnectHandler extends AsyncResource {
4041
this.context = context
4142
}
4243

43-
onHeaders () {
44-
throw new SocketError('bad connect', null)
44+
onHeaders (statusCode) {
45+
// when httpTunnel headers are allowed
46+
if (this.httpTunnel) {
47+
const { callback, opaque } = this
48+
if (statusCode !== 200) {
49+
if (callback) {
50+
this.callback = null
51+
const err = new RequestAbortedError('Proxy response !== 200 when HTTP Tunneling')
52+
queueMicrotask(() => {
53+
this.runInAsyncScope(callback, null, err, { opaque })
54+
})
55+
}
56+
return 1
57+
}
58+
} else {
59+
throw new SocketError('bad connect', null)
60+
}
4561
}
4662

4763
onUpgrade (statusCode, rawHeaders, socket) {

‎deps/undici/src/lib/core/connect.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) {
2121
timeout = timeout == null ? 10e3 : timeout
2222
maxCachedSessions = maxCachedSessions == null ? 100 : maxCachedSessions
2323

24-
return function connect ({ hostname, host, protocol, port, servername }, callback) {
24+
return function connect ({ hostname, host, protocol, port, servername, httpSocket }, callback) {
2525
let socket
2626
if (protocol === 'https:') {
2727
if (!tls) {
@@ -39,6 +39,7 @@ function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) {
3939
...options,
4040
servername,
4141
session,
42+
socket: httpSocket, // upgrade socket connection
4243
port: port || 443,
4344
host: hostname
4445
})
@@ -65,6 +66,7 @@ function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) {
6566
}
6667
})
6768
} else {
69+
assert(!httpSocket, 'httpSocket can only be sent on TLS update')
6870
socket = net.connect({
6971
highWaterMark: 64 * 1024, // Same as nodejs fs streams.
7072
...options,

‎deps/undici/src/lib/core/request.js

+9-6
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ class Request {
4848
}, handler) {
4949
if (typeof path !== 'string') {
5050
throw new InvalidArgumentError('path must be a string')
51-
} else if (path[0] !== '/' && !(path.startsWith('http://') || path.startsWith('https://'))) {
51+
} else if (
52+
path[0] !== '/' &&
53+
!(path.startsWith('http://') || path.startsWith('https://')) &&
54+
method !== 'CONNECT'
55+
) {
5256
throw new InvalidArgumentError('path must be an absolute URL or start with a slash')
5357
}
5458

@@ -80,13 +84,12 @@ class Request {
8084
this.body = null
8185
} else if (util.isStream(body)) {
8286
this.body = body
83-
} else if (body instanceof DataView) {
84-
// TODO: Why is DataView special?
85-
this.body = body.buffer.byteLength ? Buffer.from(body.buffer) : null
86-
} else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {
87-
this.body = body.byteLength ? Buffer.from(body) : null
8887
} else if (util.isBuffer(body)) {
8988
this.body = body.byteLength ? body : null
89+
} else if (ArrayBuffer.isView(body)) {
90+
this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null
91+
} else if (body instanceof ArrayBuffer) {
92+
this.body = body.byteLength ? Buffer.from(body) : null
9093
} else if (typeof body === 'string') {
9194
this.body = body.length ? Buffer.from(body) : null
9295
} else if (util.isFormDataLike(body) || util.isIterable(body) || util.isBlobLike(body)) {

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const { kBodyUsed } = require('../core/symbols')
99
const assert = require('assert')
1010
const { NotSupportedError } = require('../core/errors')
1111
const { isErrored } = require('../core/util')
12-
const { isUint8Array } = require('util/types')
12+
const { isUint8Array, isArrayBuffer } = require('util/types')
1313

1414
let ReadableStream
1515

@@ -61,7 +61,7 @@ function extractBody (object, keepalive = false) {
6161

6262
// Set Content-Type to `application/x-www-form-urlencoded;charset=UTF-8`.
6363
contentType = 'application/x-www-form-urlencoded;charset=UTF-8'
64-
} else if (object instanceof ArrayBuffer || ArrayBuffer.isView(object)) {
64+
} else if (isArrayBuffer(object) || ArrayBuffer.isView(object)) {
6565
// BufferSource
6666

6767
if (object instanceof DataView) {

‎deps/undici/src/lib/fetch/formdata.js

+54-17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict'
22

3-
const { isBlobLike, isFileLike, toUSVString } = require('./util')
3+
const { isBlobLike, isFileLike, toUSVString, makeIterator } = require('./util')
44
const { kState } = require('./symbols')
55
const { File, FileLike } = require('./file')
66
const { Blob } = require('buffer')
@@ -187,45 +187,68 @@ class FormData {
187187
return this.constructor.name
188188
}
189189

190-
* entries () {
190+
entries () {
191191
if (!(this instanceof FormData)) {
192192
throw new TypeError('Illegal invocation')
193193
}
194194

195-
for (const pair of this) {
196-
yield pair
197-
}
195+
return makeIterator(
196+
makeIterable(this[kState], 'entries'),
197+
'FormData'
198+
)
198199
}
199200

200-
* keys () {
201+
keys () {
201202
if (!(this instanceof FormData)) {
202203
throw new TypeError('Illegal invocation')
203204
}
204205

205-
for (const [key] of this) {
206-
yield key
206+
return makeIterator(
207+
makeIterable(this[kState], 'keys'),
208+
'FormData'
209+
)
210+
}
211+
212+
values () {
213+
if (!(this instanceof FormData)) {
214+
throw new TypeError('Illegal invocation')
207215
}
216+
217+
return makeIterator(
218+
makeIterable(this[kState], 'values'),
219+
'FormData'
220+
)
208221
}
209222

210-
* values () {
223+
/**
224+
* @param {(value: string, key: string, self: FormData) => void} callbackFn
225+
* @param {unknown} thisArg
226+
*/
227+
forEach (callbackFn, thisArg = globalThis) {
211228
if (!(this instanceof FormData)) {
212229
throw new TypeError('Illegal invocation')
213230
}
214231

215-
for (const [, value] of this) {
216-
yield value
232+
if (arguments.length < 1) {
233+
throw new TypeError(
234+
`Failed to execute 'forEach' on 'FormData': 1 argument required, but only ${arguments.length} present.`
235+
)
217236
}
218-
}
219237

220-
* [Symbol.iterator] () {
221-
// The value pairs to iterate over are this’s entry list’s entries with
222-
// the key being the name and the value being the value.
223-
for (const { name, value } of this[kState]) {
224-
yield [name, value]
238+
if (typeof callbackFn !== 'function') {
239+
throw new TypeError(
240+
"Failed to execute 'forEach' on 'FormData': parameter 1 is not of type 'Function'."
241+
)
242+
}
243+
244+
for (const [key, value] of this) {
245+
callbackFn.apply(thisArg, [value, key, this])
225246
}
226247
}
227248
}
228249

250+
FormData.prototype[Symbol.iterator] = FormData.prototype.entries
251+
229252
function makeEntry (name, value, filename) {
230253
// To create an entry for name, value, and optionally a filename, run these
231254
// steps:
@@ -267,4 +290,18 @@ function makeEntry (name, value, filename) {
267290
return entry
268291
}
269292

293+
function * makeIterable (entries, type) {
294+
// The value pairs to iterate over are this’s entry list’s entries
295+
// with the key being the name and the value being the value.
296+
for (const { name, value } of entries) {
297+
if (type === 'entries') {
298+
yield [name, value]
299+
} else if (type === 'values') {
300+
yield value
301+
} else {
302+
yield name
303+
}
304+
}
305+
}
306+
270307
module.exports = { FormData }

‎deps/undici/src/lib/fetch/headers.js

+4-30
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const { validateHeaderName, validateHeaderValue } = require('http')
66
const { kHeadersList } = require('../core/symbols')
77
const { kGuard } = require('./symbols')
88
const { kEnumerableProperty } = require('../core/util')
9+
const { makeIterator } = require('./util')
910

1011
const kHeadersMap = Symbol('headers map')
1112
const kHeadersSortedMap = Symbol('headers map sorted')
@@ -73,33 +74,6 @@ function fill (headers, object) {
7374
}
7475
}
7576

76-
// https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object
77-
const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))
78-
79-
// https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
80-
function makeHeadersIterator (iterator) {
81-
const i = {
82-
next () {
83-
if (Object.getPrototypeOf(this) !== i) {
84-
throw new TypeError(
85-
'\'next\' called on an object that does not implement interface Headers Iterator.'
86-
)
87-
}
88-
89-
return iterator.next()
90-
},
91-
// The class string of an iterator prototype object for a given interface is the
92-
// result of concatenating the identifier of the interface and the string " Iterator".
93-
[Symbol.toStringTag]: 'Headers Iterator'
94-
}
95-
96-
// The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%.
97-
Object.setPrototypeOf(i, esIteratorPrototype)
98-
// esIteratorPrototype needs to be the prototype of i
99-
// which is the prototype of an empty object. Yes, it's confusing.
100-
return Object.setPrototypeOf({}, i)
101-
}
102-
10377
class HeadersList {
10478
constructor (init) {
10579
if (init instanceof HeadersList) {
@@ -306,23 +280,23 @@ class Headers {
306280
throw new TypeError('Illegal invocation')
307281
}
308282

309-
return makeHeadersIterator(this[kHeadersSortedMap].keys())
283+
return makeIterator(this[kHeadersSortedMap].keys(), 'Headers')
310284
}
311285

312286
values () {
313287
if (!(this instanceof Headers)) {
314288
throw new TypeError('Illegal invocation')
315289
}
316290

317-
return makeHeadersIterator(this[kHeadersSortedMap].values())
291+
return makeIterator(this[kHeadersSortedMap].values(), 'Headers')
318292
}
319293

320294
entries () {
321295
if (!(this instanceof Headers)) {
322296
throw new TypeError('Illegal invocation')
323297
}
324298

325-
return makeHeadersIterator(this[kHeadersSortedMap].entries())
299+
return makeIterator(this[kHeadersSortedMap].entries(), 'Headers')
326300
}
327301

328302
/**

‎deps/undici/src/lib/fetch/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,7 @@ async function httpRedirectFetch (fetchParams, response) {
11641164
if (
11651165
([301, 302].includes(actualResponse.status) && request.method === 'POST') ||
11661166
(actualResponse.status === 303 &&
1167-
!['GET', 'HEADER'].includes(request.method))
1167+
!['GET', 'HEAD'].includes(request.method))
11681168
) {
11691169
// then:
11701170
// 1. Set request’s method to `GET` and request’s body to null.

‎deps/undici/src/lib/fetch/util.js

+29-1
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,33 @@ function serializeJavascriptValueToJSONString (value) {
361361
return result
362362
}
363363

364+
// https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object
365+
const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))
366+
367+
// https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
368+
function makeIterator (iterator, name) {
369+
const i = {
370+
next () {
371+
if (Object.getPrototypeOf(this) !== i) {
372+
throw new TypeError(
373+
`'next' called on an object that does not implement interface ${name} Iterator.`
374+
)
375+
}
376+
377+
return iterator.next()
378+
},
379+
// The class string of an iterator prototype object for a given interface is the
380+
// result of concatenating the identifier of the interface and the string " Iterator".
381+
[Symbol.toStringTag]: `${name} Iterator`
382+
}
383+
384+
// The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%.
385+
Object.setPrototypeOf(i, esIteratorPrototype)
386+
// esIteratorPrototype needs to be the prototype of i
387+
// which is the prototype of an empty object. Yes, it's confusing.
388+
return Object.setPrototypeOf({}, i)
389+
}
390+
364391
module.exports = {
365392
isAborted,
366393
isCancelled,
@@ -390,5 +417,6 @@ module.exports = {
390417
isValidReasonPhrase,
391418
sameOrigin,
392419
normalizeMethod,
393-
serializeJavascriptValueToJSONString
420+
serializeJavascriptValueToJSONString,
421+
makeIterator
394422
}

‎deps/undici/src/lib/proxy-agent.js

+70-8
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,90 @@
11
'use strict'
22

33
const { kProxy, kClose, kDestroy } = require('./core/symbols')
4+
const Client = require('./agent')
45
const Agent = require('./agent')
56
const DispatcherBase = require('./dispatcher-base')
67
const { InvalidArgumentError } = require('./core/errors')
8+
const buildConnector = require('./core/connect')
79

810
const kAgent = Symbol('proxy agent')
11+
const kClient = Symbol('proxy client')
12+
const kProxyHeaders = Symbol('proxy headers')
13+
const kRequestTls = Symbol('request tls settings')
14+
const kProxyTls = Symbol('proxy tls settings')
15+
const kConnectEndpoint = Symbol('connect endpoint function')
916

1017
class ProxyAgent extends DispatcherBase {
1118
constructor (opts) {
1219
super(opts)
1320
this[kProxy] = buildProxyOptions(opts)
14-
this[kAgent] = new Agent(opts)
21+
this[kRequestTls] = opts.requestTls
22+
this[kProxyTls] = opts.proxyTls
23+
this[kProxyHeaders] = {}
24+
25+
if (opts.auth) {
26+
this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}`
27+
}
28+
29+
const connect = buildConnector({ ...opts.proxyTls })
30+
this[kConnectEndpoint] = buildConnector({ ...opts.requestTls })
31+
this[kClient] = new Client({ origin: opts.origin, connect })
32+
this[kAgent] = new Agent({ ...opts, connect: this.connectTunnel.bind(this) })
1533
}
1634

1735
dispatch (opts, handler) {
1836
const { host } = new URL(opts.origin)
37+
const headers = buildHeaders(opts.headers)
38+
throwIfProxyAuthIsSent(headers)
1939
return this[kAgent].dispatch(
2040
{
2141
...opts,
22-
origin: this[kProxy].uri,
23-
path: opts.origin + opts.path,
2442
headers: {
25-
...buildHeaders(opts.headers),
43+
...headers,
2644
host
2745
}
2846
},
2947
handler
3048
)
3149
}
3250

51+
async connectTunnel (opts, callback) {
52+
try {
53+
const { socket } = await this[kClient].connect({
54+
origin: this[kProxy].origin,
55+
port: this[kProxy].port,
56+
path: opts.host,
57+
signal: opts.signal,
58+
headers: {
59+
...this[kProxyHeaders],
60+
host: opts.host
61+
},
62+
httpTunnel: true
63+
})
64+
if (opts.protocol !== 'https:') {
65+
callback(null, socket)
66+
return
67+
}
68+
let servername
69+
if (this[kRequestTls]) {
70+
servername = this[kRequestTls].servername
71+
} else {
72+
servername = opts.servername
73+
}
74+
this[kConnectEndpoint]({ ...opts, servername, httpSocket: socket }, callback)
75+
} catch (err) {
76+
callback(err)
77+
}
78+
}
79+
3380
async [kClose] () {
3481
await this[kAgent].close()
82+
await this[kClient].close()
3583
}
3684

3785
async [kDestroy] () {
3886
await this[kAgent].destroy()
87+
await this[kClient].destroy()
3988
}
4089
}
4190

@@ -48,10 +97,7 @@ function buildProxyOptions (opts) {
4897
throw new InvalidArgumentError('Proxy opts.uri is mandatory')
4998
}
5099

51-
return {
52-
uri: opts.uri,
53-
protocol: opts.protocol || 'https'
54-
}
100+
return new URL(opts.uri)
55101
}
56102

57103
/**
@@ -75,4 +121,20 @@ function buildHeaders (headers) {
75121
return headers
76122
}
77123

124+
/**
125+
* @param {Record<string, string>} headers
126+
*
127+
* Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers
128+
* Nevertheless, it was changed and to avoid a security vulnerability by end users
129+
* this check was created.
130+
* It should be removed in the next major version for performance reasons
131+
*/
132+
function throwIfProxyAuthIsSent (headers) {
133+
const existProxyAuth = headers && Object.keys(headers)
134+
.find((key) => key.toLowerCase() === 'proxy-authorization')
135+
if (existProxyAuth) {
136+
throw new InvalidArgumentError('Proxy-Authorization should be sent in ProxyAgent constructor')
137+
}
138+
}
139+
78140
module.exports = ProxyAgent

‎deps/undici/src/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "undici",
3-
"version": "5.4.0",
3+
"version": "5.5.1",
44
"description": "An HTTP/1.1 client, written from scratch for Node.js",
55
"homepage": "https://undici.nodejs.org",
66
"bugs": {

‎deps/undici/src/types/connector.d.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
import { URL } from 'url'
2-
import { TLSSocket, TlsOptions } from 'tls'
3-
import { Socket } from 'net'
1+
import {TLSSocket, ConnectionOptions} from 'tls'
2+
import {IpcNetConnectOpts, Socket, TcpNetConnectOpts} from 'net'
43

54
export = buildConnector
65
declare function buildConnector (options?: buildConnector.BuildOptions): typeof buildConnector.connector
76

87
declare namespace buildConnector {
9-
export interface BuildOptions extends TlsOptions {
8+
export type BuildOptions = (ConnectionOptions | TcpNetConnectOpts | IpcNetConnectOpts) & {
109
maxCachedSessions?: number | null;
1110
socketPath?: string | null;
1211
timeout?: number | null;
13-
servername?: string | null;
12+
port?: number;
1413
}
1514

1615
export interface Options {

‎deps/undici/src/types/fetch.d.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,21 @@ export interface BodyMixin {
3838
readonly text: () => Promise<string>
3939
}
4040

41-
export interface HeadersIterator<T, TReturn = any, TNext = undefined> {
41+
export interface SpecIterator<T, TReturn = any, TNext = undefined> {
4242
next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
4343
}
4444

45-
export interface HeadersIterableIterator<T> extends HeadersIterator<T> {
46-
[Symbol.iterator](): HeadersIterableIterator<T>;
45+
export interface SpecIterableIterator<T> extends SpecIterator<T> {
46+
[Symbol.iterator](): SpecIterableIterator<T>;
4747
}
4848

49-
export interface HeadersIterable<T> {
50-
[Symbol.iterator](): HeadersIterator<T>;
49+
export interface SpecIterable<T> {
50+
[Symbol.iterator](): SpecIterator<T>;
5151
}
5252

5353
export type HeadersInit = string[][] | Record<string, string | ReadonlyArray<string>> | Headers
5454

55-
export declare class Headers implements HeadersIterable<[string, string]> {
55+
export declare class Headers implements SpecIterable<[string, string]> {
5656
constructor (init?: HeadersInit)
5757
readonly append: (name: string, value: string) => void
5858
readonly delete: (name: string) => void
@@ -64,10 +64,10 @@ export declare class Headers implements HeadersIterable<[string, string]> {
6464
thisArg?: unknown
6565
) => void
6666

67-
readonly keys: () => HeadersIterableIterator<string>
68-
readonly values: () => HeadersIterableIterator<string>
69-
readonly entries: () => HeadersIterableIterator<[string, string]>
70-
readonly [Symbol.iterator]: () => HeadersIterator<[string, string]>
67+
readonly keys: () => SpecIterableIterator<string>
68+
readonly values: () => SpecIterableIterator<string>
69+
readonly entries: () => SpecIterableIterator<[string, string]>
70+
readonly [Symbol.iterator]: () => SpecIterator<[string, string]>
7171
}
7272

7373
export type RequestCache =

‎deps/undici/src/types/formdata.d.ts

+15-11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/// <reference types="node" />
33

44
import { File } from './file'
5+
import { SpecIterator, SpecIterableIterator } from './fetch'
56

67
/**
78
* A `string` or `File` that represents a single value from a set of `FormData` key-value pairs.
@@ -73,32 +74,35 @@ export declare class FormData {
7374
delete(name: string): void
7475

7576
/**
76-
* Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all keys contained in this `FormData` object.
77-
* Each key is a `string`.
77+
* Executes given callback function for each field of the FormData instance
7878
*/
79-
keys(): Generator<string>
79+
forEach: (
80+
callbackfn: (value: FormDataEntryValue, key: string, iterable: FormData) => void,
81+
thisArg?: unknown
82+
) => void
8083

8184
/**
82-
* Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through the `FormData` key/value pairs.
83-
* The key of each pair is a string; the value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).
85+
* Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all keys contained in this `FormData` object.
86+
* Each key is a `string`.
8487
*/
85-
entries(): Generator<[string, FormDataEntryValue]>
88+
keys: () => SpecIterableIterator<string>
8689

8790
/**
8891
* Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all values contained in this object `FormData` object.
8992
* Each value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).
9093
*/
91-
values(): Generator<FormDataEntryValue>
94+
values: () => SpecIterableIterator<FormDataEntryValue>
9295

9396
/**
94-
* An alias for FormData#entries()
97+
* Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through the `FormData` key/value pairs.
98+
* The key of each pair is a string; the value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).
9599
*/
96-
[Symbol.iterator](): Generator<[string, FormDataEntryValue], void>
100+
entries: () => SpecIterableIterator<[string, FormDataEntryValue]>
97101

98102
/**
99-
* Executes given callback function for each field of the FormData instance
103+
* An alias for FormData#entries()
100104
*/
101-
forEach(callback: (value: FormDataEntryValue, key: string, formData: FormData) => void, thisArg?: unknown): void
105+
[Symbol.iterator]: () => SpecIterableIterator<[string, FormDataEntryValue]>
102106

103107
readonly [Symbol.toStringTag]: string
104108
}

‎deps/undici/src/types/proxy-agent.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { TlsOptions } from 'tls'
12
import Agent = require('./agent')
23
import Dispatcher = require('./dispatcher')
34

@@ -13,5 +14,8 @@ declare class ProxyAgent extends Dispatcher {
1314
declare namespace ProxyAgent {
1415
export interface Options extends Agent.Options {
1516
uri: string;
17+
auth?: string;
18+
requestTls?: TlsOptions & { servername?: string };
19+
proxyTls?: TlsOptions & { servername?: string };
1620
}
1721
}

‎deps/undici/undici.js

+61-42
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,20 @@ var require_util2 = __commonJS({
14151415
assert(typeof result === "string");
14161416
return result;
14171417
}
1418+
var esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));
1419+
function makeIterator(iterator, name) {
1420+
const i = {
1421+
next() {
1422+
if (Object.getPrototypeOf(this) !== i) {
1423+
throw new TypeError(`'next' called on an object that does not implement interface ${name} Iterator.`);
1424+
}
1425+
return iterator.next();
1426+
},
1427+
[Symbol.toStringTag]: `${name} Iterator`
1428+
};
1429+
Object.setPrototypeOf(i, esIteratorPrototype);
1430+
return Object.setPrototypeOf({}, i);
1431+
}
14181432
module2.exports = {
14191433
isAborted,
14201434
isCancelled,
@@ -1444,7 +1458,8 @@ var require_util2 = __commonJS({
14441458
isValidReasonPhrase,
14451459
sameOrigin,
14461460
normalizeMethod,
1447-
serializeJavascriptValueToJSONString
1461+
serializeJavascriptValueToJSONString,
1462+
makeIterator
14481463
};
14491464
}
14501465
});
@@ -1453,7 +1468,7 @@ var require_util2 = __commonJS({
14531468
var require_formdata = __commonJS({
14541469
"lib/fetch/formdata.js"(exports2, module2) {
14551470
"use strict";
1456-
var { isBlobLike, isFileLike, toUSVString } = require_util2();
1471+
var { isBlobLike, isFileLike, toUSVString, makeIterator } = require_util2();
14571472
var { kState } = require_symbols2();
14581473
var { File, FileLike } = require_file();
14591474
var { Blob } = require("buffer");
@@ -1558,38 +1573,42 @@ var require_formdata = __commonJS({
15581573
get [Symbol.toStringTag]() {
15591574
return this.constructor.name;
15601575
}
1561-
*entries() {
1576+
entries() {
15621577
if (!(this instanceof _FormData)) {
15631578
throw new TypeError("Illegal invocation");
15641579
}
1565-
for (const pair of this) {
1566-
yield pair;
1567-
}
1580+
return makeIterator(makeIterable(this[kState], "entries"), "FormData");
15681581
}
1569-
*keys() {
1582+
keys() {
15701583
if (!(this instanceof _FormData)) {
15711584
throw new TypeError("Illegal invocation");
15721585
}
1573-
for (const [key] of this) {
1574-
yield key;
1586+
return makeIterator(makeIterable(this[kState], "keys"), "FormData");
1587+
}
1588+
values() {
1589+
if (!(this instanceof _FormData)) {
1590+
throw new TypeError("Illegal invocation");
15751591
}
1592+
return makeIterator(makeIterable(this[kState], "values"), "FormData");
15761593
}
1577-
*values() {
1594+
forEach(callbackFn, thisArg = globalThis) {
15781595
if (!(this instanceof _FormData)) {
15791596
throw new TypeError("Illegal invocation");
15801597
}
1581-
for (const [, value] of this) {
1582-
yield value;
1598+
if (arguments.length < 1) {
1599+
throw new TypeError(`Failed to execute 'forEach' on 'FormData': 1 argument required, but only ${arguments.length} present.`);
15831600
}
1584-
}
1585-
*[Symbol.iterator]() {
1586-
for (const { name, value } of this[kState]) {
1587-
yield [name, value];
1601+
if (typeof callbackFn !== "function") {
1602+
throw new TypeError("Failed to execute 'forEach' on 'FormData': parameter 1 is not of type 'Function'.");
1603+
}
1604+
for (const [key, value] of this) {
1605+
callbackFn.apply(thisArg, [value, key, this]);
15881606
}
15891607
}
15901608
};
15911609
var FormData = _FormData;
15921610
__publicField(FormData, "name", "FormData");
1611+
FormData.prototype[Symbol.iterator] = FormData.prototype.entries;
15931612
function makeEntry(name, value, filename) {
15941613
const entry = {
15951614
name: null,
@@ -1605,6 +1624,17 @@ var require_formdata = __commonJS({
16051624
entry.value = value;
16061625
return entry;
16071626
}
1627+
function* makeIterable(entries, type) {
1628+
for (const { name, value } of entries) {
1629+
if (type === "entries") {
1630+
yield [name, value];
1631+
} else if (type === "values") {
1632+
yield value;
1633+
} else {
1634+
yield name;
1635+
}
1636+
}
1637+
}
16081638
module2.exports = { FormData };
16091639
}
16101640
});
@@ -1622,7 +1652,7 @@ var require_body = __commonJS({
16221652
var assert = require("assert");
16231653
var { NotSupportedError } = require_errors();
16241654
var { isErrored } = require_util();
1625-
var { isUint8Array } = require("util/types");
1655+
var { isUint8Array, isArrayBuffer } = require("util/types");
16261656
var ReadableStream;
16271657
async function* blobGen(blob) {
16281658
if (blob.stream) {
@@ -1644,7 +1674,7 @@ var require_body = __commonJS({
16441674
} else if (object instanceof URLSearchParams) {
16451675
source = object.toString();
16461676
contentType = "application/x-www-form-urlencoded;charset=UTF-8";
1647-
} else if (object instanceof ArrayBuffer || ArrayBuffer.isView(object)) {
1677+
} else if (isArrayBuffer(object) || ArrayBuffer.isView(object)) {
16481678
if (object instanceof DataView) {
16491679
object = object.buffer;
16501680
}
@@ -1880,7 +1910,7 @@ var require_request = __commonJS({
18801910
}, handler) {
18811911
if (typeof path !== "string") {
18821912
throw new InvalidArgumentError("path must be a string");
1883-
} else if (path[0] !== "/" && !(path.startsWith("http://") || path.startsWith("https://"))) {
1913+
} else if (path[0] !== "/" && !(path.startsWith("http://") || path.startsWith("https://")) && method !== "CONNECT") {
18841914
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
18851915
}
18861916
if (typeof method !== "string") {
@@ -1903,12 +1933,12 @@ var require_request = __commonJS({
19031933
this.body = null;
19041934
} else if (util.isStream(body)) {
19051935
this.body = body;
1906-
} else if (body instanceof DataView) {
1907-
this.body = body.buffer.byteLength ? Buffer.from(body.buffer) : null;
1908-
} else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {
1909-
this.body = body.byteLength ? Buffer.from(body) : null;
19101936
} else if (util.isBuffer(body)) {
19111937
this.body = body.byteLength ? body : null;
1938+
} else if (ArrayBuffer.isView(body)) {
1939+
this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null;
1940+
} else if (body instanceof ArrayBuffer) {
1941+
this.body = body.byteLength ? Buffer.from(body) : null;
19121942
} else if (typeof body === "string") {
19131943
this.body = body.length ? Buffer.from(body) : null;
19141944
} else if (util.isFormDataLike(body) || util.isIterable(body) || util.isBlobLike(body)) {
@@ -2221,7 +2251,7 @@ var require_connect = __commonJS({
22212251
const sessionCache = /* @__PURE__ */ new Map();
22222252
timeout = timeout == null ? 1e4 : timeout;
22232253
maxCachedSessions = maxCachedSessions == null ? 100 : maxCachedSessions;
2224-
return function connect({ hostname, host, protocol, port, servername }, callback) {
2254+
return function connect({ hostname, host, protocol, port, servername, httpSocket }, callback) {
22252255
let socket;
22262256
if (protocol === "https:") {
22272257
if (!tls) {
@@ -2236,6 +2266,7 @@ var require_connect = __commonJS({
22362266
...options,
22372267
servername,
22382268
session,
2269+
socket: httpSocket,
22392270
port: port || 443,
22402271
host: hostname
22412272
});
@@ -2254,6 +2285,7 @@ var require_connect = __commonJS({
22542285
}
22552286
});
22562287
} else {
2288+
assert(!httpSocket, "httpSocket can only be sent on TLS update");
22572289
socket = net.connect({
22582290
highWaterMark: 64 * 1024,
22592291
...options,
@@ -4205,6 +4237,7 @@ var require_headers = __commonJS({
42054237
var { kHeadersList } = require_symbols();
42064238
var { kGuard } = require_symbols2();
42074239
var { kEnumerableProperty } = require_util();
4240+
var { makeIterator } = require_util2();
42084241
var kHeadersMap = Symbol("headers map");
42094242
var kHeadersSortedMap = Symbol("headers map sorted");
42104243
function normalizeAndValidateHeaderName(name) {
@@ -4248,20 +4281,6 @@ var require_headers = __commonJS({
42484281
throw TypeError();
42494282
}
42504283
}
4251-
var esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));
4252-
function makeHeadersIterator(iterator) {
4253-
const i = {
4254-
next() {
4255-
if (Object.getPrototypeOf(this) !== i) {
4256-
throw new TypeError("'next' called on an object that does not implement interface Headers Iterator.");
4257-
}
4258-
return iterator.next();
4259-
},
4260-
[Symbol.toStringTag]: "Headers Iterator"
4261-
};
4262-
Object.setPrototypeOf(i, esIteratorPrototype);
4263-
return Object.setPrototypeOf({}, i);
4264-
}
42654284
var HeadersList = class {
42664285
constructor(init) {
42674286
if (init instanceof HeadersList) {
@@ -4396,19 +4415,19 @@ var require_headers = __commonJS({
43964415
if (!(this instanceof Headers)) {
43974416
throw new TypeError("Illegal invocation");
43984417
}
4399-
return makeHeadersIterator(this[kHeadersSortedMap].keys());
4418+
return makeIterator(this[kHeadersSortedMap].keys(), "Headers");
44004419
}
44014420
values() {
44024421
if (!(this instanceof Headers)) {
44034422
throw new TypeError("Illegal invocation");
44044423
}
4405-
return makeHeadersIterator(this[kHeadersSortedMap].values());
4424+
return makeIterator(this[kHeadersSortedMap].values(), "Headers");
44064425
}
44074426
entries() {
44084427
if (!(this instanceof Headers)) {
44094428
throw new TypeError("Illegal invocation");
44104429
}
4411-
return makeHeadersIterator(this[kHeadersSortedMap].entries());
4430+
return makeIterator(this[kHeadersSortedMap].entries(), "Headers");
44124431
}
44134432
forEach(callbackFn, thisArg = globalThis) {
44144433
if (!(this instanceof Headers)) {
@@ -5950,7 +5969,7 @@ var require_fetch = __commonJS({
59505969
if (actualResponse.status !== 303 && request.body != null && request.body.source == null) {
59515970
return makeNetworkError();
59525971
}
5953-
if ([301, 302].includes(actualResponse.status) && request.method === "POST" || actualResponse.status === 303 && !["GET", "HEADER"].includes(request.method)) {
5972+
if ([301, 302].includes(actualResponse.status) && request.method === "POST" || actualResponse.status === 303 && !["GET", "HEAD"].includes(request.method)) {
59545973
request.method = "GET";
59555974
request.body = null;
59565975
for (const headerName of requestBodyHeader) {

0 commit comments

Comments
 (0)
Please sign in to comment.