Skip to content

Commit 6c8456d

Browse files
nodejs-github-botMoLow
authored andcommitted
deps: update undici to 5.21.1
PR-URL: #47488 Reviewed-By: Debadree Chatterjee <debadree333@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent bd1eb14 commit 6c8456d

12 files changed

Lines changed: 196 additions & 94 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ module.exports = {
4141
kClient: Symbol('client'),
4242
kParser: Symbol('parser'),
4343
kOnDestroyed: Symbol('destroy callbacks'),
44-
kPipelining: Symbol('pipelinig'),
44+
kPipelining: Symbol('pipelining'),
4545
kSocket: Symbol('socket'),
4646
kHostHeader: Symbol('host header'),
4747
kConnector: Symbol('connector'),

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

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,38 +48,38 @@ function parseURL (url) {
4848
url=newURL(url)
4949

5050
if(!/^https?:/.test(url.origin||url.protocol)){
51-
thrownewInvalidArgumentError('invalid protocol')
51+
thrownewInvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.')
5252
}
5353

5454
returnurl
5555
}
5656

5757
if(!url||typeofurl!=='object'){
58-
thrownewInvalidArgumentError('invalid url')
58+
thrownewInvalidArgumentError('Invalid URL: The URL argument must be a non-null object.')
5959
}
6060

6161
if(url.port!=null&&url.port!==''&&!Number.isFinite(parseInt(url.port))){
62-
thrownewInvalidArgumentError('invalid port')
62+
thrownewInvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.')
6363
}
6464

6565
if(url.path!=null&&typeofurl.path!=='string'){
66-
thrownewInvalidArgumentError('invalid path')
66+
thrownewInvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.')
6767
}
6868

6969
if(url.pathname!=null&&typeofurl.pathname!=='string'){
70-
thrownewInvalidArgumentError('invalid pathname')
70+
thrownewInvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.')
7171
}
7272

7373
if(url.hostname!=null&&typeofurl.hostname!=='string'){
74-
thrownewInvalidArgumentError('invalid hostname')
74+
thrownewInvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.')
7575
}
7676

7777
if(url.origin!=null&&typeofurl.origin!=='string'){
78-
thrownewInvalidArgumentError('invalid origin')
78+
thrownewInvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.')
7979
}
8080

8181
if(!/^https?:/.test(url.origin||url.protocol)){
82-
thrownewInvalidArgumentError('invalid protocol')
82+
thrownewInvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.')
8383
}
8484

8585
if(!(urlinstanceofURL)){
@@ -409,6 +409,21 @@ function throwIfAborted (signal) {
409409
}
410410
}
411411

412+
consthasToWellFormed=!!String.prototype.toWellFormed
413+
414+
/**
415+
* @param {string} val
416+
*/
417+
functiontoUSVString(val){
418+
if(hasToWellFormed){
419+
return`${val}`.toWellFormed()
420+
}elseif(nodeUtil.toUSVString){
421+
returnnodeUtil.toUSVString(val)
422+
}
423+
424+
return`${val}`
425+
}
426+
412427
constkEnumerableProperty=Object.create(null)
413428
kEnumerableProperty.enumerable=true
414429

@@ -418,7 +433,7 @@ module.exports = {
418433
isDisturbed,
419434
isErrored,
420435
isReadable,
421-
toUSVString: nodeUtil.toUSVString||((val)=>`${val}`),
436+
toUSVString,
422437
isReadableAborted,
423438
isBlobLike,
424439
parseOrigin,

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,17 @@ const requestCache = [
4848
'only-if-cached'
4949
]
5050

51+
// https://fetch.spec.whatwg.org/#request-body-header-name
5152
constrequestBodyHeader=[
5253
'content-encoding',
5354
'content-language',
5455
'content-location',
55-
'content-type'
56+
'content-type',
57+
// See https://github.com/nodejs/undici/issues/2021
58+
// 'Content-Length' is a forbidden header name, which is typically
59+
// removed in the Headers implementation. However, undici doesn't
60+
// filter out headers, so we add it here.
61+
'content-length'
5662
]
5763

5864
// https://fetch.spec.whatwg.org/#enumdef-requestduplex

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,7 @@ class FormData {
6161

6262
// The delete(name) method steps are to remove all entries whose name
6363
// is name from this’s entry list.
64-
constnext=[]
65-
for(constentryofthis[kState]){
66-
if(entry.name!==name){
67-
next.push(entry)
68-
}
69-
}
70-
71-
this[kState]=next
64+
this[kState]=this[kState].filter(entry=>entry.name!==name)
7265
}
7366

7467
get(name){

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

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ const {
3737
isErrorLike,
3838
fullyReadBody,
3939
readableStreamClose,
40-
isomorphicEncode
40+
isomorphicEncode,
41+
urlIsLocal,
42+
urlIsHttpHttpsScheme,
43+
urlHasHttpsScheme
4144
}=require('./util')
4245
const{ kState, kHeaders, kGuard, kRealm, kHeadersCaseInsensitive }=require('./symbols')
4346
constassert=require('assert')
@@ -272,7 +275,7 @@ function finalizeAndReportTiming (response, initiatorType = 'other') {
272275
letcacheState=response.cacheState
273276

274277
// 6. If originalURL’s scheme is not an HTTP(S) scheme, then return.
275-
if(!/^https?:/.test(originalURL.protocol)){
278+
if(!urlIsHttpHttpsScheme(originalURL)){
276279
return
277280
}
278281

@@ -530,10 +533,7 @@ async function mainFetch (fetchParams, recursive = false) {
530533

531534
// 3. If request’s local-URLs-only flag is set and request’s current URL is
532535
// not local, then set response to a network error.
533-
if(
534-
request.localURLsOnly&&
535-
!/^(about|blob|data):/.test(requestCurrentURL(request).protocol)
536-
){
536+
if(request.localURLsOnly&&!urlIsLocal(requestCurrentURL(request))){
537537
response=makeNetworkError('local URLs only')
538538
}
539539

@@ -623,7 +623,7 @@ async function mainFetch (fetchParams, recursive = false) {
623623
}
624624

625625
// request’s current URL’s scheme is not an HTTP(S) scheme
626-
if(!/^https?:/.test(requestCurrentURL(request).protocol)){
626+
if(!urlIsHttpHttpsScheme(requestCurrentURL(request))){
627627
// Return a network error.
628628
returnmakeNetworkError('URL scheme must be a HTTP(S) scheme')
629629
}
@@ -1130,7 +1130,7 @@ async function httpRedirectFetch (fetchParams, response) {
11301130

11311131
// 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network
11321132
// error.
1133-
if(!/^https?:/.test(locationURL.protocol)){
1133+
if(!urlIsHttpHttpsScheme(locationURL)){
11341134
returnmakeNetworkError('URL scheme must be a HTTP(S) scheme')
11351135
}
11361136

@@ -1205,7 +1205,7 @@ async function httpRedirectFetch (fetchParams, response) {
12051205
// 14. If request’s body is non-null, then set request’s body to the first return
12061206
// value of safely extracting request’s body’s source.
12071207
if(request.body!=null){
1208-
assert(request.body.source)
1208+
assert(request.body.source!=null)
12091209
request.body=safelyExtractBody(request.body.source)[0]
12101210
}
12111211

@@ -1399,7 +1399,7 @@ async function httpNetworkOrCacheFetch (
13991399
// header if httpRequest’s header list contains that header’s name.
14001400
// TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129
14011401
if(!httpRequest.headersList.contains('accept-encoding')){
1402-
if(/^https:/.test(requestCurrentURL(httpRequest).protocol)){
1402+
if(urlHasHttpsScheme(requestCurrentURL(httpRequest))){
14031403
httpRequest.headersList.append('accept-encoding','br, gzip, deflate')
14041404
}else{
14051405
httpRequest.headersList.append('accept-encoding','gzip, deflate')
@@ -1845,6 +1845,7 @@ async function httpNetworkFetch (
18451845
// 4. Set bytes to the result of handling content codings given
18461846
// codings and bytes.
18471847
letbytes
1848+
letisFailure
18481849
try{
18491850
const{ done, value }=awaitfetchParams.controller.next()
18501851

@@ -1859,6 +1860,10 @@ async function httpNetworkFetch (
18591860
bytes=undefined
18601861
}else{
18611862
bytes=err
1863+
1864+
// err may be propagated from the result of calling readablestream.cancel,
1865+
// which might not be an error. https://github.com/nodejs/undici/issues/2009
1866+
isFailure=true
18621867
}
18631868
}
18641869

@@ -1878,7 +1883,7 @@ async function httpNetworkFetch (
18781883
timingInfo.decodedBodySize+=bytes?.byteLength??0
18791884

18801885
// 6. If bytes is failure, then terminate fetchParams’s controller.
1881-
if(isErrorLike(bytes)){
1886+
if(isFailure){
18821887
fetchParams.controller.terminate(bytes)
18831888
return
18841889
}
@@ -1979,7 +1984,9 @@ async function httpNetworkFetch (
19791984
constval=headersList[n+1].toString('latin1')
19801985

19811986
if(key.toLowerCase()==='content-encoding'){
1982-
codings=val.split(',').map((x)=>x.trim())
1987+
// https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1
1988+
// "All content-coding values are case-insensitive..."
1989+
codings=val.toLowerCase().split(',').map((x)=>x.trim())
19831990
}elseif(key.toLowerCase()==='location'){
19841991
location=val
19851992
}
@@ -1998,9 +2005,10 @@ async function httpNetworkFetch (
19982005
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
19992006
if(request.method!=='HEAD'&&request.method!=='CONNECT'&&!nullBodyStatus.includes(status)&&!willFollow){
20002007
for(constcodingofcodings){
2001-
if(/(x-)?gzip/.test(coding)){
2008+
// https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2
2009+
if(coding==='x-gzip'||coding==='gzip'){
20022010
decoders.push(zlib.createGunzip())
2003-
}elseif(/(x-)?deflate/.test(coding)){
2011+
}elseif(coding==='deflate'){
20042012
decoders.push(zlib.createInflate())
20052013
}elseif(coding==='br'){
20062014
decoders.push(zlib.createBrotliDecompress())

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

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const { setMaxListeners, getEventListeners, defaultMaxListeners } = require('eve
3434
letTransformStream=globalThis.TransformStream
3535

3636
constkInit=Symbol('init')
37+
constkAbortController=Symbol('abortController')
3738

3839
constrequestFinalizer=newFinalizationRegistry(({ signal, abort })=>{
3940
signal.removeEventListener('abort',abort)
@@ -128,12 +129,12 @@ class Request {
128129
}
129130

130131
// 10. If init["window"] exists and is non-null, then throw a TypeError.
131-
if(init.window!==undefined&&init.window!=null){
132+
if(init.window!=null){
132133
thrownewTypeError(`'window' option '${window}' must be null`)
133134
}
134135

135136
// 11. If init["window"] exists, then set window to "no-window".
136-
if(init.window!==undefined){
137+
if('window'ininit){
137138
window='no-window'
138139
}
139140

@@ -354,20 +355,30 @@ class Request {
354355
if(signal.aborted){
355356
ac.abort(signal.reason)
356357
}else{
358+
// Keep a strong ref to ac while request object
359+
// is alive. This is needed to prevent AbortController
360+
// from being prematurely garbage collected.
361+
// See, https://github.com/nodejs/undici/issues/1926.
362+
this[kAbortController]=ac
363+
364+
constacRef=newWeakRef(ac)
357365
constabort=function(){
358-
ac.abort(this.reason)
366+
constac=acRef.deref()
367+
if(ac!==undefined){
368+
ac.abort(this.reason)
369+
}
359370
}
360371

361372
// Third-party AbortControllers may not work with these.
362-
// See https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619
373+
// See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619.
363374
try{
364375
if(getEventListeners(signal,'abort').length>=defaultMaxListeners){
365376
setMaxListeners(100,signal)
366377
}
367378
}catch{}
368379

369380
signal.addEventListener('abort',abort,{once: true})
370-
requestFinalizer.register(this,{ signal, abort })
381+
requestFinalizer.register(ac,{ signal, abort })
371382
}
372383
}
373384

@@ -427,7 +438,7 @@ class Request {
427438
// non-null, and request’s method is `GET` or `HEAD`, then throw a
428439
// TypeError.
429440
if(
430-
((init.body!==undefined&&init.body!=null)||inputBody!=null)&&
441+
(init.body!=null||inputBody!=null)&&
431442
(request.method==='GET'||request.method==='HEAD')
432443
){
433444
thrownewTypeError('Request with GET/HEAD method cannot have body.')
@@ -437,7 +448,7 @@ class Request {
437448
letinitBody=null
438449

439450
// 36. If init["body"] exists and is non-null, then:
440-
if(init.body!==undefined&&init.body!=null){
451+
if(init.body!=null){
441452
// 1. Let Content-Type be null.
442453
// 2. Set initBody and Content-Type to the result of extracting
443454
// init["body"], with keepalive set to request’s keepalive.

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,7 @@ function makeNetworkError (reason) {
348348
status: 0,
349349
error: isError
350350
? reason
351-
: newError(reason ? String(reason) : reason,{
352-
cause: isError ? reason : undefined
353-
}),
351+
: newError(reason ? String(reason) : reason),
354352
aborted: reason&&reason.name==='AbortError'
355353
})
356354
}

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

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ function requestBadPort (request) {
6464

6565
// 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port,
6666
// then return blocked.
67-
if(/^https?:/.test(url.protocol)&&badPorts.includes(url.port)){
67+
if(urlIsHttpHttpsScheme(url)&&badPorts.includes(url.port)){
6868
return'blocked'
6969
}
7070

@@ -285,7 +285,7 @@ function appendRequestOriginHeader (request) {
285285
case'strict-origin':
286286
case'strict-origin-when-cross-origin':
287287
// If request’s origin is a tuple origin, its scheme is "https", and request’s current URL’s scheme is not "https", then set serializedOrigin to `null`.
288-
if(/^https:/.test(request.origin)&&!/^https:/.test(requestCurrentURL(request))){
288+
if(request.origin&&urlHasHttpsScheme(request.origin)&&!urlHasHttpsScheme(requestCurrentURL(request))){
289289
serializedOrigin=null
290290
}
291291
break
@@ -944,6 +944,41 @@ async function readAllBytes (reader, successSteps, failureSteps) {
944944
}
945945
}
946946

947+
/**
948+
* @see https://fetch.spec.whatwg.org/#is-local
949+
* @param {URL} url
950+
*/
951+
functionurlIsLocal(url){
952+
assert('protocol'inurl)// ensure it's a url object
953+
954+
constprotocol=url.protocol
955+
956+
returnprotocol==='about:'||protocol==='blob:'||protocol==='data:'
957+
}
958+
959+
/**
960+
* @param {string|URL} url
961+
*/
962+
functionurlHasHttpsScheme(url){
963+
if(typeofurl==='string'){
964+
returnurl.startsWith('https:')
965+
}
966+
967+
returnurl.protocol==='https:'
968+
}
969+
970+
/**
971+
* @see https://fetch.spec.whatwg.org/#http-scheme
972+
* @param {URL} url
973+
*/
974+
functionurlIsHttpHttpsScheme(url){
975+
assert('protocol'inurl)// ensure it's a url object
976+
977+
constprotocol=url.protocol
978+
979+
returnprotocol==='http:'||protocol==='https:'
980+
}
981+
947982
/**
948983
* Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0.
949984
*/
@@ -988,5 +1023,8 @@ module.exports = {
9881023
isReadableStreamLike,
9891024
readableStreamClose,
9901025
isomorphicEncode,
991-
isomorphicDecode
1026+
isomorphicDecode,
1027+
urlIsLocal,
1028+
urlHasHttpsScheme,
1029+
urlIsHttpHttpsScheme
9921030
}

0 commit comments

Comments
 (0)