Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 517f17b

Browse filesBrowse files
nodejs-github-botdanielleadams
authored andcommitted
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
Copy full SHA for 517f17b

File tree

Expand file treeCollapse file tree

16 files changed

+297
-154
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

16 files changed

+297
-154
lines changed
Open diff view settings
Collapse file

‎deps/undici/src/README.md‎

Copy file name to clipboardExpand all lines: deps/undici/src/README.md
+11-16Lines changed: 11 additions & 16 deletions
  • Display the source diff
  • Display the rich diff
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
Collapse file

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

Copy file name to clipboardExpand all lines: deps/undici/src/lib/api/api-connect.js
+19-3Lines changed: 19 additions & 3 deletions
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) {
Collapse file

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

Copy file name to clipboardExpand all lines: deps/undici/src/lib/core/connect.js
+3-1Lines changed: 3 additions & 1 deletion
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,
Collapse file

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

Copy file name to clipboardExpand all lines: deps/undici/src/lib/core/request.js
+9-6Lines changed: 9 additions & 6 deletions
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)) {
Collapse file

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

Copy file name to clipboardExpand all lines: deps/undici/src/lib/fetch/body.js
+2-2Lines changed: 2 additions & 2 deletions
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) {
Collapse file

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

Copy file name to clipboardExpand all lines: deps/undici/src/lib/fetch/formdata.js
+54-17Lines changed: 54 additions & 17 deletions
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 }
Collapse file

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

Copy file name to clipboardExpand all lines: deps/undici/src/lib/fetch/headers.js
+4-30Lines changed: 4 additions & 30 deletions
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
/**
Collapse file

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

Copy file name to clipboardExpand all lines: deps/undici/src/lib/fetch/index.js
+1-1Lines changed: 1 addition & 1 deletion
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.
Collapse file

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

Copy file name to clipboardExpand all lines: deps/undici/src/lib/fetch/util.js
+29-1Lines changed: 29 additions & 1 deletion
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
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.