@@ -37,7 +37,10 @@ const {
3737 isErrorLike,
3838 fullyReadBody,
3939 readableStreamClose,
40- isomorphicEncode
40+ isomorphicEncode,
41+ urlIsLocal,
42+ urlIsHttpHttpsScheme,
43+ urlHasHttpsScheme
4144} = require ( './util' )
4245const { kState, kHeaders, kGuard, kRealm, kHeadersCaseInsensitive } = require ( './symbols' )
4346const assert = require ( 'assert' )
@@ -272,7 +275,7 @@ function finalizeAndReportTiming (response, initiatorType = 'other') {
272275 let cacheState = response . cacheState
273276
274277 // 6. If originalURL’s scheme is not an HTTP(S) scheme, then return.
275- if ( ! / ^ h t t p s ? : / . 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- ! / ^ ( a b o u t | b l o b | d a t a ) : / . 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 ( ! / ^ h t t p s ? : / . test ( requestCurrentURL ( request ) . protocol ) ) {
626+ if ( ! urlIsHttpHttpsScheme ( requestCurrentURL ( request ) ) ) {
627627 // Return a network error.
628628 return makeNetworkError ( '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 ( ! / ^ h t t p s ? : / . test ( locationURL . protocol ) ) {
1133+ if ( ! urlIsHttpHttpsScheme ( locationURL ) ) {
11341134 return makeNetworkError ( '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 ( / ^ h t t p s : / . 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 let bytes
1848+ let isFailure
18481849 try {
18491850 const { done, value } = await fetchParams . 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 const val = 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 } else if ( 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 ( const coding of codings ) {
2001- if ( / ( x - ) ? g z i p / . 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- } else if ( / ( x - ) ? d e f l a t e / . test ( coding ) ) {
2011+ } else if ( coding === 'deflate' ) {
20042012 decoders . push ( zlib . createInflate ( ) )
20052013 } else if ( coding === 'br' ) {
20062014 decoders . push ( zlib . createBrotliDecompress ( ) )
0 commit comments