Skip to content

Commit 10a4c47

Browse files
nodejs-github-botRafaelGSS
authored andcommitted
deps: update undici to 5.19.1
PR-URL: #46634 Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
1 parent b10fc75 commit 10a4c47

File tree

12 files changed

+167
-32
lines changed

12 files changed

+167
-32
lines changed

deps/undici/src/docs/api/MockPool.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ Returns: `MockInterceptor` corresponding to the input options.
6363

6464
We can define the behaviour of an intercepted request with the following options.
6565

66-
* **reply** `(statusCode: number, replyData: string | Buffer | object | MockInterceptor.MockResponseDataHandler, responseOptions?: MockResponseOptions) => MockScope` - define a reply for a matching request. You can define this as a callback to read incoming request data. Default for `responseOptions` is `{}`.
66+
* **reply** `(statusCode: number, replyData: string | Buffer | object | MockInterceptor.MockResponseDataHandler, responseOptions?: MockResponseOptions) => MockScope` - define a reply for a matching request. You can define the replyData as a callback to read incoming request data. Default for `responseOptions` is `{}`.
67+
* **reply** `(callback: MockInterceptor.MockReplyOptionsCallback) => MockScope` - define a reply for a matching request, allowing dynamic mocking of all reply options rather than just the data.
6768
* **replyWithError** `(error: Error) => MockScope` - define an error for a matching request to throw.
6869
* **defaultReplyHeaders** `(headers: Record<string, string>) => MockInterceptor` - define default headers to be included in subsequent replies. These are in addition to headers on a specific reply.
6970
* **defaultReplyTrailers** `(trailers: Record<string, string>) => MockInterceptor` - define default trailers to be included in subsequent replies. These are in addition to trailers on a specific reply.

deps/undici/src/lib/cookies/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ function getSetCookies (headers) {
8383
return []
8484
}
8585

86-
return cookies.map((pair) => parseSetCookie(pair[1]))
86+
// In older versions of undici, cookies is a list of name:value.
87+
return cookies.map((pair) => parseSetCookie(Array.isArray(pair) ? pair[1] : pair))
8788
}
8889

8990
/**

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

+3
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ function processHeader (request, key, val) {
304304
key.length === 4 &&
305305
key.toLowerCase() === 'host'
306306
) {
307+
if (headerCharRegex.exec(val) !== null) {
308+
throw new InvalidArgumentError(`invalid ${key} header`)
309+
}
307310
// Consumed by Client
308311
request.host = val
309312
} else if (

deps/undici/src/lib/core/util.js

+20-3
Original file line numberDiff line numberDiff line change
@@ -213,25 +213,42 @@ function parseHeaders (headers, obj = {}) {
213213
for (let i = 0; i < headers.length; i += 2) {
214214
const key = headers[i].toString().toLowerCase()
215215
let val = obj[key]
216+
217+
const encoding = key.length === 19 && key === 'content-disposition'
218+
? 'latin1'
219+
: 'utf8'
220+
216221
if (!val) {
217222
if (Array.isArray(headers[i + 1])) {
218223
obj[key] = headers[i + 1]
219224
} else {
220-
obj[key] = headers[i + 1].toString()
225+
obj[key] = headers[i + 1].toString(encoding)
221226
}
222227
} else {
223228
if (!Array.isArray(val)) {
224229
val = [val]
225230
obj[key] = val
226231
}
227-
val.push(headers[i + 1].toString())
232+
val.push(headers[i + 1].toString(encoding))
228233
}
229234
}
230235
return obj
231236
}
232237

233238
function parseRawHeaders (headers) {
234-
return headers.map(header => header.toString())
239+
const ret = []
240+
for (let n = 0; n < headers.length; n += 2) {
241+
const key = headers[n + 0].toString()
242+
243+
const encoding = key.length === 19 && key.toLowerCase() === 'content-disposition'
244+
? 'latin1'
245+
: 'utf8'
246+
247+
const val = headers[n + 1].toString(encoding)
248+
249+
ret.push(key, val)
250+
}
251+
return ret
235252
}
236253

237254
function isBuffer (buffer) {

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

+71-12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const {
1111
isValidHeaderValue
1212
} = require('./util')
1313
const { webidl } = require('./webidl')
14+
const assert = require('assert')
1415

1516
const kHeadersMap = Symbol('headers map')
1617
const kHeadersSortedMap = Symbol('headers map sorted')
@@ -23,10 +24,12 @@ function headerValueNormalize (potentialValue) {
2324
// To normalize a byte sequence potentialValue, remove
2425
// any leading and trailing HTTP whitespace bytes from
2526
// potentialValue.
26-
return potentialValue.replace(
27-
/^[\r\n\t ]+|[\r\n\t ]+$/g,
28-
''
29-
)
27+
28+
// Trimming the end with `.replace()` and a RegExp is typically subject to
29+
// ReDoS. This is safer and faster.
30+
let i = potentialValue.length
31+
while (/[\r\n\t ]/.test(potentialValue.charAt(--i)));
32+
return potentialValue.slice(0, i + 1).replace(/^[\r\n\t ]+/, '')
3033
}
3134

3235
function fill (headers, object) {
@@ -115,7 +118,7 @@ class HeadersList {
115118

116119
if (lowercaseName === 'set-cookie') {
117120
this.cookies ??= []
118-
this.cookies.push([name, value])
121+
this.cookies.push(value)
119122
}
120123
}
121124

@@ -125,7 +128,7 @@ class HeadersList {
125128
const lowercaseName = name.toLowerCase()
126129

127130
if (lowercaseName === 'set-cookie') {
128-
this.cookies = [[name, value]]
131+
this.cookies = [value]
129132
}
130133

131134
// 1. If list contains name, then set the value of
@@ -383,18 +386,74 @@ class Headers {
383386
return this[kHeadersList].set(name, value)
384387
}
385388

389+
// https://fetch.spec.whatwg.org/#dom-headers-getsetcookie
390+
getSetCookie () {
391+
webidl.brandCheck(this, Headers)
392+
393+
// 1. If this’s header list does not contain `Set-Cookie`, then return « ».
394+
// 2. Return the values of all headers in this’s header list whose name is
395+
// a byte-case-insensitive match for `Set-Cookie`, in order.
396+
397+
const list = this[kHeadersList].cookies
398+
399+
if (list) {
400+
return [...list]
401+
}
402+
403+
return []
404+
}
405+
406+
// https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine
386407
get [kHeadersSortedMap] () {
387-
if (!this[kHeadersList][kHeadersSortedMap]) {
388-
this[kHeadersList][kHeadersSortedMap] = new Map([...this[kHeadersList]].sort((a, b) => a[0] < b[0] ? -1 : 1))
408+
if (this[kHeadersList][kHeadersSortedMap]) {
409+
return this[kHeadersList][kHeadersSortedMap]
389410
}
390-
return this[kHeadersList][kHeadersSortedMap]
411+
412+
// 1. Let headers be an empty list of headers with the key being the name
413+
// and value the value.
414+
const headers = []
415+
416+
// 2. Let names be the result of convert header names to a sorted-lowercase
417+
// set with all the names of the headers in list.
418+
const names = [...this[kHeadersList]].sort((a, b) => a[0] < b[0] ? -1 : 1)
419+
const cookies = this[kHeadersList].cookies
420+
421+
// 3. For each name of names:
422+
for (const [name, value] of names) {
423+
// 1. If name is `set-cookie`, then:
424+
if (name === 'set-cookie') {
425+
// 1. Let values be a list of all values of headers in list whose name
426+
// is a byte-case-insensitive match for name, in order.
427+
428+
// 2. For each value of values:
429+
// 1. Append (name, value) to headers.
430+
for (const value of cookies) {
431+
headers.push([name, value])
432+
}
433+
} else {
434+
// 2. Otherwise:
435+
436+
// 1. Let value be the result of getting name from list.
437+
438+
// 2. Assert: value is non-null.
439+
assert(value !== null)
440+
441+
// 3. Append (name, value) to headers.
442+
headers.push([name, value])
443+
}
444+
}
445+
446+
this[kHeadersList][kHeadersSortedMap] = headers
447+
448+
// 4. Return headers.
449+
return headers
391450
}
392451

393452
keys () {
394453
webidl.brandCheck(this, Headers)
395454

396455
return makeIterator(
397-
() => [...this[kHeadersSortedMap].entries()],
456+
() => [...this[kHeadersSortedMap].values()],
398457
'Headers',
399458
'key'
400459
)
@@ -404,7 +463,7 @@ class Headers {
404463
webidl.brandCheck(this, Headers)
405464

406465
return makeIterator(
407-
() => [...this[kHeadersSortedMap].entries()],
466+
() => [...this[kHeadersSortedMap].values()],
408467
'Headers',
409468
'value'
410469
)
@@ -414,7 +473,7 @@ class Headers {
414473
webidl.brandCheck(this, Headers)
415474

416475
return makeIterator(
417-
() => [...this[kHeadersSortedMap].entries()],
476+
() => [...this[kHeadersSortedMap].values()],
418477
'Headers',
419478
'key+value'
420479
)

deps/undici/src/lib/fetch/request.js

+6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const { getGlobalOrigin } = require('./global')
2828
const { URLSerializer } = require('./dataURL')
2929
const { kHeadersList } = require('../core/symbols')
3030
const assert = require('assert')
31+
const { setMaxListeners, getEventListeners, defaultMaxListeners } = require('events')
3132

3233
let TransformStream = globalThis.TransformStream
3334

@@ -352,6 +353,11 @@ class Request {
352353
const abort = function () {
353354
acRef.deref()?.abort(this.reason)
354355
}
356+
357+
if (getEventListeners(signal, 'abort').length >= defaultMaxListeners) {
358+
setMaxListeners(100, signal)
359+
}
360+
355361
signal.addEventListener('abort', abort, { once: true })
356362
requestFinalizer.register(this, { signal, abort })
357363
}

deps/undici/src/lib/mock/mock-utils.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,11 @@ function buildKey (opts) {
188188
}
189189

190190
function generateKeyValues (data) {
191-
return Object.entries(data).reduce((keyValuePairs, [key, value]) => [...keyValuePairs, key, value], [])
191+
return Object.entries(data).reduce((keyValuePairs, [key, value]) => [
192+
...keyValuePairs,
193+
Buffer.from(`${key}`),
194+
Array.isArray(value) ? value.map(x => Buffer.from(`${x}`)) : Buffer.from(`${value}`)
195+
], [])
192196
}
193197

194198
/**

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.18.0",
3+
"version": "5.19.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

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ declare namespace buildConnector {
1010
socketPath?: string | null;
1111
timeout?: number | null;
1212
port?: number;
13+
keepAlive?: boolean | null;
14+
keepAliveInitialDelay?: number | null;
1315
}
1416

1517
export interface Options {

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

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export declare class Headers implements SpecIterable<[string, string]> {
5959
readonly get: (name: string) => string | null
6060
readonly has: (name: string) => boolean
6161
readonly set: (name: string, value: string) => void
62+
readonly getSetCookie: () => string[]
6263
readonly forEach: (
6364
callbackfn: (value: string, key: string, iterable: Headers) => void,
6465
thisArg?: unknown

0 commit comments

Comments
 (0)