undici 6.21.0 → 7.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/README.md +27 -46
  2. package/docs/docs/api/Agent.md +14 -17
  3. package/docs/docs/api/BalancedPool.md +16 -16
  4. package/docs/docs/api/CacheStore.md +131 -0
  5. package/docs/docs/api/Client.md +12 -14
  6. package/docs/docs/api/Debug.md +1 -1
  7. package/docs/docs/api/Dispatcher.md +98 -194
  8. package/docs/docs/api/EnvHttpProxyAgent.md +12 -13
  9. package/docs/docs/api/MockAgent.md +5 -3
  10. package/docs/docs/api/MockClient.md +5 -5
  11. package/docs/docs/api/MockPool.md +4 -3
  12. package/docs/docs/api/Pool.md +15 -16
  13. package/docs/docs/api/PoolStats.md +1 -1
  14. package/docs/docs/api/ProxyAgent.md +3 -3
  15. package/docs/docs/api/RedirectHandler.md +1 -1
  16. package/docs/docs/api/RetryAgent.md +1 -1
  17. package/docs/docs/api/RetryHandler.md +4 -4
  18. package/docs/docs/api/WebSocket.md +46 -4
  19. package/docs/docs/api/api-lifecycle.md +11 -11
  20. package/docs/docs/best-practices/mocking-request.md +2 -2
  21. package/docs/docs/best-practices/proxy.md +1 -1
  22. package/index.d.ts +1 -1
  23. package/index.js +23 -7
  24. package/lib/api/abort-signal.js +2 -0
  25. package/lib/api/api-connect.js +3 -1
  26. package/lib/api/api-pipeline.js +7 -6
  27. package/lib/api/api-request.js +33 -48
  28. package/lib/api/api-stream.js +39 -50
  29. package/lib/api/api-upgrade.js +5 -3
  30. package/lib/api/readable.js +235 -62
  31. package/lib/api/util.js +2 -0
  32. package/lib/cache/memory-cache-store.js +177 -0
  33. package/lib/cache/sqlite-cache-store.js +446 -0
  34. package/lib/core/constants.js +35 -10
  35. package/lib/core/diagnostics.js +122 -128
  36. package/lib/core/errors.js +6 -6
  37. package/lib/core/request.js +13 -11
  38. package/lib/core/symbols.js +2 -1
  39. package/lib/core/tree.js +9 -1
  40. package/lib/core/util.js +237 -49
  41. package/lib/dispatcher/agent.js +3 -17
  42. package/lib/dispatcher/balanced-pool.js +5 -8
  43. package/lib/dispatcher/client-h1.js +379 -134
  44. package/lib/dispatcher/client-h2.js +173 -107
  45. package/lib/dispatcher/client.js +19 -32
  46. package/lib/dispatcher/dispatcher-base.js +6 -35
  47. package/lib/dispatcher/dispatcher.js +7 -24
  48. package/lib/dispatcher/fixed-queue.js +91 -49
  49. package/lib/dispatcher/pool-stats.js +2 -0
  50. package/lib/dispatcher/pool.js +3 -6
  51. package/lib/dispatcher/proxy-agent.js +3 -6
  52. package/lib/handler/cache-handler.js +393 -0
  53. package/lib/handler/cache-revalidation-handler.js +124 -0
  54. package/lib/handler/decorator-handler.js +27 -0
  55. package/lib/handler/redirect-handler.js +54 -59
  56. package/lib/handler/retry-handler.js +77 -109
  57. package/lib/handler/unwrap-handler.js +96 -0
  58. package/lib/handler/wrap-handler.js +98 -0
  59. package/lib/interceptor/cache.js +350 -0
  60. package/lib/interceptor/dns.js +375 -0
  61. package/lib/interceptor/dump.js +2 -2
  62. package/lib/interceptor/redirect.js +11 -14
  63. package/lib/interceptor/response-error.js +18 -7
  64. package/lib/llhttp/constants.d.ts +97 -0
  65. package/lib/llhttp/constants.js +412 -192
  66. package/lib/llhttp/constants.js.map +1 -0
  67. package/lib/llhttp/llhttp-wasm.js +11 -1
  68. package/lib/llhttp/llhttp_simd-wasm.js +11 -1
  69. package/lib/llhttp/utils.d.ts +2 -0
  70. package/lib/llhttp/utils.js +9 -9
  71. package/lib/llhttp/utils.js.map +1 -0
  72. package/lib/mock/mock-agent.js +5 -8
  73. package/lib/mock/mock-client.js +9 -4
  74. package/lib/mock/mock-errors.js +3 -1
  75. package/lib/mock/mock-interceptor.js +8 -6
  76. package/lib/mock/mock-pool.js +9 -4
  77. package/lib/mock/mock-symbols.js +3 -1
  78. package/lib/mock/mock-utils.js +29 -5
  79. package/lib/util/cache.js +360 -0
  80. package/lib/web/cache/cache.js +24 -21
  81. package/lib/web/cache/cachestorage.js +1 -1
  82. package/lib/web/cookies/index.js +29 -14
  83. package/lib/web/cookies/parse.js +8 -3
  84. package/lib/web/eventsource/eventsource-stream.js +9 -8
  85. package/lib/web/eventsource/eventsource.js +10 -6
  86. package/lib/web/fetch/body.js +43 -41
  87. package/lib/web/fetch/constants.js +12 -5
  88. package/lib/web/fetch/data-url.js +3 -3
  89. package/lib/web/fetch/formdata-parser.js +72 -45
  90. package/lib/web/fetch/formdata.js +65 -54
  91. package/lib/web/fetch/headers.js +118 -86
  92. package/lib/web/fetch/index.js +58 -67
  93. package/lib/web/fetch/request.js +136 -77
  94. package/lib/web/fetch/response.js +87 -56
  95. package/lib/web/fetch/util.js +259 -109
  96. package/lib/web/fetch/webidl.js +113 -68
  97. package/lib/web/websocket/connection.js +76 -147
  98. package/lib/web/websocket/constants.js +70 -10
  99. package/lib/web/websocket/events.js +4 -2
  100. package/lib/web/websocket/frame.js +45 -3
  101. package/lib/web/websocket/receiver.js +29 -33
  102. package/lib/web/websocket/sender.js +18 -13
  103. package/lib/web/websocket/stream/websocketerror.js +83 -0
  104. package/lib/web/websocket/stream/websocketstream.js +485 -0
  105. package/lib/web/websocket/util.js +128 -77
  106. package/lib/web/websocket/websocket.js +234 -135
  107. package/package.json +24 -36
  108. package/scripts/strip-comments.js +3 -1
  109. package/types/agent.d.ts +7 -7
  110. package/types/api.d.ts +24 -24
  111. package/types/balanced-pool.d.ts +11 -11
  112. package/types/cache-interceptor.d.ts +172 -0
  113. package/types/client.d.ts +11 -12
  114. package/types/cookies.d.ts +2 -0
  115. package/types/diagnostics-channel.d.ts +10 -10
  116. package/types/dispatcher.d.ts +113 -90
  117. package/types/env-http-proxy-agent.d.ts +2 -2
  118. package/types/errors.d.ts +53 -47
  119. package/types/fetch.d.ts +17 -16
  120. package/types/formdata.d.ts +7 -7
  121. package/types/global-dispatcher.d.ts +4 -4
  122. package/types/global-origin.d.ts +5 -5
  123. package/types/handlers.d.ts +7 -7
  124. package/types/header.d.ts +157 -1
  125. package/types/index.d.ts +44 -46
  126. package/types/interceptors.d.ts +25 -8
  127. package/types/mock-agent.d.ts +21 -18
  128. package/types/mock-client.d.ts +4 -4
  129. package/types/mock-errors.d.ts +3 -3
  130. package/types/mock-interceptor.d.ts +19 -19
  131. package/types/mock-pool.d.ts +4 -4
  132. package/types/patch.d.ts +0 -4
  133. package/types/pool-stats.d.ts +8 -8
  134. package/types/pool.d.ts +12 -12
  135. package/types/proxy-agent.d.ts +4 -4
  136. package/types/readable.d.ts +18 -15
  137. package/types/retry-agent.d.ts +1 -1
  138. package/types/retry-handler.d.ts +10 -10
  139. package/types/util.d.ts +3 -3
  140. package/types/utility.d.ts +7 -0
  141. package/types/webidl.d.ts +44 -6
  142. package/types/websocket.d.ts +34 -1
  143. package/docs/docs/api/DispatchInterceptor.md +0 -60
  144. package/lib/interceptor/redirect-interceptor.js +0 -21
  145. package/lib/mock/pluralizer.js +0 -29
  146. package/lib/web/cache/symbols.js +0 -5
  147. package/lib/web/fetch/file.js +0 -126
  148. package/lib/web/fetch/symbols.js +0 -9
  149. package/lib/web/fileapi/encoding.js +0 -290
  150. package/lib/web/fileapi/filereader.js +0 -344
  151. package/lib/web/fileapi/progressevent.js +0 -78
  152. package/lib/web/fileapi/symbols.js +0 -10
  153. package/lib/web/fileapi/util.js +0 -391
  154. package/lib/web/websocket/symbols.js +0 -12
  155. package/types/file.d.ts +0 -39
  156. package/types/filereader.d.ts +0 -54
@@ -2,11 +2,11 @@
2
2
 
3
3
  const { Transform } = require('node:stream')
4
4
  const zlib = require('node:zlib')
5
- const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = require('./constants')
5
+ const { redirectStatusSet, referrerPolicyTokens, badPortsSet } = require('./constants')
6
6
  const { getGlobalOrigin } = require('./global')
7
7
  const { collectASequenceOfCodePoints, collectAnHTTPQuotedString, removeChars, parseMIMEType } = require('./data-url')
8
8
  const { performance } = require('node:perf_hooks')
9
- const { isBlobLike, ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = require('../../core/util')
9
+ const { ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = require('../../core/util')
10
10
  const assert = require('node:assert')
11
11
  const { isUint8Array } = require('node:util/types')
12
12
  const { webidl } = require('./webidl')
@@ -170,29 +170,24 @@ function isValidHeaderValue (potentialValue) {
170
170
  ) === false
171
171
  }
172
172
 
173
- // https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect
174
- function setRequestReferrerPolicyOnRedirect (request, actualResponse) {
175
- // Given a request request and a response actualResponse, this algorithm
176
- // updates request’s referrer policy according to the Referrer-Policy
177
- // header (if any) in actualResponse.
178
-
179
- // 1. Let policy be the result of executing § 8.1 Parse a referrer policy
180
- // from a Referrer-Policy header on actualResponse.
181
-
182
- // 8.1 Parse a referrer policy from a Referrer-Policy header
173
+ /**
174
+ * Parse a referrer policy from a Referrer-Policy header
175
+ * @see https://w3c.github.io/webappsec-referrer-policy/#parse-referrer-policy-from-header
176
+ */
177
+ function parseReferrerPolicy (actualResponse) {
183
178
  // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` and response’s header list.
184
- const { headersList } = actualResponse
179
+ const policyHeader = (actualResponse.headersList.get('referrer-policy', true) ?? '').split(',')
180
+
185
181
  // 2. Let policy be the empty string.
182
+ let policy = ''
183
+
186
184
  // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty string, then set policy to token.
187
- // 4. Return policy.
188
- const policyHeader = (headersList.get('referrer-policy', true) ?? '').split(',')
189
185
 
190
186
  // Note: As the referrer-policy can contain multiple policies
191
187
  // separated by comma, we need to loop through all of them
192
188
  // and pick the first valid one.
193
189
  // Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#specify_a_fallback_policy
194
- let policy = ''
195
- if (policyHeader.length > 0) {
190
+ if (policyHeader.length) {
196
191
  // The right-most policy takes precedence.
197
192
  // The left-most policy is the fallback.
198
193
  for (let i = policyHeader.length; i !== 0; i--) {
@@ -204,6 +199,23 @@ function setRequestReferrerPolicyOnRedirect (request, actualResponse) {
204
199
  }
205
200
  }
206
201
 
202
+ // 4. Return policy.
203
+ return policy
204
+ }
205
+
206
+ /**
207
+ * Given a request request and a response actualResponse, this algorithm
208
+ * updates request’s referrer policy according to the Referrer-Policy
209
+ * header (if any) in actualResponse.
210
+ * @see https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect
211
+ * @param {import('./request').Request} request
212
+ * @param {import('./response').Response} actualResponse
213
+ */
214
+ function setRequestReferrerPolicyOnRedirect (request, actualResponse) {
215
+ // 1. Let policy be the result of executing § 8.1 Parse a referrer policy
216
+ // from a Referrer-Policy header on actualResponse.
217
+ const policy = parseReferrerPolicy(actualResponse)
218
+
207
219
  // 2. If policy is not the empty string, then set request’s referrer policy to policy.
208
220
  if (policy !== '') {
209
221
  request.referrerPolicy = policy
@@ -374,8 +386,16 @@ function clonePolicyContainer (policyContainer) {
374
386
  }
375
387
  }
376
388
 
377
- // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
389
+ /**
390
+ * Determine request’s Referrer
391
+ *
392
+ * @see https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
393
+ */
378
394
  function determineRequestsReferrer (request) {
395
+ // Given a request request, we can determine the correct referrer information
396
+ // to send by examining its referrer policy as detailed in the following
397
+ // steps, which return either no referrer or a URL:
398
+
379
399
  // 1. Let policy be request's referrer policy.
380
400
  const policy = request.referrerPolicy
381
401
 
@@ -387,6 +407,8 @@ function determineRequestsReferrer (request) {
387
407
  let referrerSource = null
388
408
 
389
409
  // 3. Switch on request’s referrer:
410
+
411
+ // "client"
390
412
  if (request.referrer === 'client') {
391
413
  // Note: node isn't a browser and doesn't implement document/iframes,
392
414
  // so we bypass this step and replace it with our own.
@@ -397,9 +419,10 @@ function determineRequestsReferrer (request) {
397
419
  return 'no-referrer'
398
420
  }
399
421
 
400
- // note: we need to clone it as it's mutated
422
+ // Note: we need to clone it as it's mutated
401
423
  referrerSource = new URL(globalOrigin)
402
- } else if (request.referrer instanceof URL) {
424
+ // a URL
425
+ } else if (webidl.is.URL(request.referrer)) {
403
426
  // Let referrerSource be request’s referrer.
404
427
  referrerSource = request.referrer
405
428
  }
@@ -418,18 +441,37 @@ function determineRequestsReferrer (request) {
418
441
  referrerURL = referrerOrigin
419
442
  }
420
443
 
421
- const areSameOrigin = sameOrigin(request, referrerURL)
422
- const isNonPotentiallyTrustWorthy = isURLPotentiallyTrustworthy(referrerURL) &&
423
- !isURLPotentiallyTrustworthy(request.url)
444
+ // 7. The user agent MAY alter referrerURL or referrerOrigin at this point
445
+ // to enforce arbitrary policy considerations in the interests of minimizing
446
+ // data leakage. For example, the user agent could strip the URL down to an
447
+ // origin, modify its host, replace it with an empty string, etc.
424
448
 
425
449
  // 8. Execute the switch statements corresponding to the value of policy:
426
450
  switch (policy) {
427
- case 'origin': return referrerOrigin != null ? referrerOrigin : stripURLForReferrer(referrerSource, true)
428
- case 'unsafe-url': return referrerURL
429
- case 'same-origin':
430
- return areSameOrigin ? referrerOrigin : 'no-referrer'
431
- case 'origin-when-cross-origin':
432
- return areSameOrigin ? referrerURL : referrerOrigin
451
+ case 'no-referrer':
452
+ // Return no referrer
453
+ return 'no-referrer'
454
+ case 'origin':
455
+ // Return referrerOrigin
456
+ if (referrerOrigin != null) {
457
+ return referrerOrigin
458
+ }
459
+ return stripURLForReferrer(referrerSource, true)
460
+ case 'unsafe-url':
461
+ // Return referrerURL.
462
+ return referrerURL
463
+ case 'strict-origin': {
464
+ const currentURL = requestCurrentURL(request)
465
+
466
+ // 1. If referrerURL is a potentially trustworthy URL and request’s
467
+ // current URL is not a potentially trustworthy URL, then return no
468
+ // referrer.
469
+ if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) {
470
+ return 'no-referrer'
471
+ }
472
+ // 2. Return referrerOrigin
473
+ return referrerOrigin
474
+ }
433
475
  case 'strict-origin-when-cross-origin': {
434
476
  const currentURL = requestCurrentURL(request)
435
477
 
@@ -449,39 +491,58 @@ function determineRequestsReferrer (request) {
449
491
  // 3. Return referrerOrigin.
450
492
  return referrerOrigin
451
493
  }
452
- case 'strict-origin': // eslint-disable-line
453
- /**
454
- * 1. If referrerURL is a potentially trustworthy URL and
455
- * request’s current URL is not a potentially trustworthy URL,
456
- * then return no referrer.
457
- * 2. Return referrerOrigin
458
- */
459
- case 'no-referrer-when-downgrade': // eslint-disable-line
460
- /**
461
- * 1. If referrerURL is a potentially trustworthy URL and
462
- * request’s current URL is not a potentially trustworthy URL,
463
- * then return no referrer.
464
- * 2. Return referrerOrigin
465
- */
466
-
467
- default: // eslint-disable-line
468
- return isNonPotentiallyTrustWorthy ? 'no-referrer' : referrerOrigin
494
+ case 'same-origin':
495
+ // 1. If the origin of referrerURL and the origin of request’s current
496
+ // URL are the same, then return referrerURL.
497
+ if (sameOrigin(request, referrerURL)) {
498
+ return referrerURL
499
+ }
500
+ // 2. Return no referrer.
501
+ return 'no-referrer'
502
+ case 'origin-when-cross-origin':
503
+ // 1. If the origin of referrerURL and the origin of request’s current
504
+ // URL are the same, then return referrerURL.
505
+ if (sameOrigin(request, referrerURL)) {
506
+ return referrerURL
507
+ }
508
+ // 2. Return referrerOrigin.
509
+ return referrerOrigin
510
+ case 'no-referrer-when-downgrade': {
511
+ const currentURL = requestCurrentURL(request)
512
+
513
+ // 1. If referrerURL is a potentially trustworthy URL and request’s
514
+ // current URL is not a potentially trustworthy URL, then return no
515
+ // referrer.
516
+ if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) {
517
+ return 'no-referrer'
518
+ }
519
+ // 2. Return referrerOrigin
520
+ return referrerOrigin
521
+ }
469
522
  }
470
523
  }
471
524
 
472
525
  /**
526
+ * Certain portions of URLs must not be included when sending a URL as the
527
+ * value of a `Referer` header: a URLs fragment, username, and password
528
+ * components must be stripped from the URL before it’s sent out. This
529
+ * algorithm accepts a origin-only flag, which defaults to false. If set to
530
+ * true, the algorithm will additionally remove the URL’s path and query
531
+ * components, leaving only the scheme, host, and port.
532
+ *
473
533
  * @see https://w3c.github.io/webappsec-referrer-policy/#strip-url
474
534
  * @param {URL} url
475
- * @param {boolean|undefined} originOnly
535
+ * @param {boolean} [originOnly=false]
476
536
  */
477
- function stripURLForReferrer (url, originOnly) {
537
+ function stripURLForReferrer (url, originOnly = false) {
478
538
  // 1. Assert: url is a URL.
479
- assert(url instanceof URL)
539
+ assert(webidl.is.URL(url))
480
540
 
541
+ // Note: Create a new URL instance to avoid mutating the original URL.
481
542
  url = new URL(url)
482
543
 
483
544
  // 2. If url’s scheme is a local scheme, then return no referrer.
484
- if (url.protocol === 'file:' || url.protocol === 'about:' || url.protocol === 'blank:') {
545
+ if (urlIsLocal(url)) {
485
546
  return 'no-referrer'
486
547
  }
487
548
 
@@ -495,7 +556,7 @@ function stripURLForReferrer (url, originOnly) {
495
556
  url.hash = ''
496
557
 
497
558
  // 6. If the origin-only flag is true, then:
498
- if (originOnly) {
559
+ if (originOnly === true) {
499
560
  // 1. Set url’s path to « the empty string ».
500
561
  url.pathname = ''
501
562
 
@@ -507,45 +568,134 @@ function stripURLForReferrer (url, originOnly) {
507
568
  return url
508
569
  }
509
570
 
510
- function isURLPotentiallyTrustworthy (url) {
511
- if (!(url instanceof URL)) {
571
+ const potentialleTrustworthyIPv4RegExp = new RegExp('^(?:' +
572
+ '(?:127\\.)' +
573
+ '(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){2}' +
574
+ '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])' +
575
+ ')$')
576
+
577
+ const potentialleTrustworthyIPv6RegExp = new RegExp('^(?:' +
578
+ '(?:(?:0{1,4}):){7}(?:(?:0{0,3}1))|' +
579
+ '(?:(?:0{1,4}):){1,6}(?::(?:0{0,3}1))|' +
580
+ '(?:::(?:0{0,3}1))|' +
581
+ ')$')
582
+
583
+ /**
584
+ * Check if host matches one of the CIDR notations 127.0.0.0/8 or ::1/128.
585
+ *
586
+ * @param {string} origin
587
+ * @returns {boolean}
588
+ */
589
+ function isOriginIPPotentiallyTrustworthy (origin) {
590
+ // IPv6
591
+ if (origin.includes(':')) {
592
+ // Remove brackets from IPv6 addresses
593
+ if (origin[0] === '[' && origin[origin.length - 1] === ']') {
594
+ origin = origin.slice(1, -1)
595
+ }
596
+ return potentialleTrustworthyIPv6RegExp.test(origin)
597
+ }
598
+
599
+ // IPv4
600
+ return potentialleTrustworthyIPv4RegExp.test(origin)
601
+ }
602
+
603
+ /**
604
+ * A potentially trustworthy origin is one which a user agent can generally
605
+ * trust as delivering data securely.
606
+ *
607
+ * Return value `true` means `Potentially Trustworthy`.
608
+ * Return value `false` means `Not Trustworthy`.
609
+ *
610
+ * @see https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy
611
+ * @param {string} origin
612
+ * @returns {boolean}
613
+ */
614
+ function isOriginPotentiallyTrustworthy (origin) {
615
+ // 1. If origin is an opaque origin, return "Not Trustworthy".
616
+ if (origin == null || origin === 'null') {
512
617
  return false
513
618
  }
514
619
 
515
- // If child of about, return true
516
- if (url.href === 'about:blank' || url.href === 'about:srcdoc') {
620
+ // 2. Assert: origin is a tuple origin.
621
+ origin = new URL(origin)
622
+
623
+ // 3. If origin’s scheme is either "https" or "wss",
624
+ // return "Potentially Trustworthy".
625
+ if (origin.protocol === 'https:' || origin.protocol === 'wss:') {
517
626
  return true
518
627
  }
519
628
 
520
- // If scheme is data, return true
521
- if (url.protocol === 'data:') return true
629
+ // 4. If origin’s host matches one of the CIDR notations 127.0.0.0/8 or
630
+ // ::1/128 [RFC4632], return "Potentially Trustworthy".
631
+ if (isOriginIPPotentiallyTrustworthy(origin.hostname)) {
632
+ return true
633
+ }
522
634
 
523
- // If file, return true
524
- if (url.protocol === 'file:') return true
635
+ // 5. If the user agent conforms to the name resolution rules in
636
+ // [let-localhost-be-localhost] and one of the following is true:
525
637
 
526
- return isOriginPotentiallyTrustworthy(url.origin)
638
+ // origin’s host is "localhost" or "localhost."
639
+ if (origin.hostname === 'localhost' || origin.hostname === 'localhost.') {
640
+ return true
641
+ }
527
642
 
528
- function isOriginPotentiallyTrustworthy (origin) {
529
- // If origin is explicitly null, return false
530
- if (origin == null || origin === 'null') return false
643
+ // origin’s host ends with ".localhost" or ".localhost."
644
+ if (origin.hostname.endsWith('.localhost') || origin.hostname.endsWith('.localhost.')) {
645
+ return true
646
+ }
647
+
648
+ // 6. If origin’s scheme is "file", return "Potentially Trustworthy".
649
+ if (origin.protocol === 'file:') {
650
+ return true
651
+ }
531
652
 
532
- const originAsURL = new URL(origin)
653
+ // 7. If origin’s scheme component is one which the user agent considers to
654
+ // be authenticated, return "Potentially Trustworthy".
533
655
 
534
- // If secure, return true
535
- if (originAsURL.protocol === 'https:' || originAsURL.protocol === 'wss:') {
536
- return true
537
- }
656
+ // 8. If origin has been configured as a trustworthy origin, return
657
+ // "Potentially Trustworthy".
538
658
 
539
- // If localhost or variants, return true
540
- if (/^127(?:\.[0-9]+){0,2}\.[0-9]+$|^\[(?:0*:)*?:?0*1\]$/.test(originAsURL.hostname) ||
541
- (originAsURL.hostname === 'localhost' || originAsURL.hostname.includes('localhost.')) ||
542
- (originAsURL.hostname.endsWith('.localhost'))) {
543
- return true
544
- }
659
+ // 9. Return "Not Trustworthy".
660
+ return false
661
+ }
545
662
 
546
- // If any other, return false
663
+ /**
664
+ * A potentially trustworthy URL is one which either inherits context from its
665
+ * creator (about:blank, about:srcdoc, data) or one whose origin is a
666
+ * potentially trustworthy origin.
667
+ *
668
+ * Return value `true` means `Potentially Trustworthy`.
669
+ * Return value `false` means `Not Trustworthy`.
670
+ *
671
+ * @see https://www.w3.org/TR/secure-contexts/#is-url-trustworthy
672
+ * @param {URL} url
673
+ * @returns {boolean}
674
+ */
675
+ function isURLPotentiallyTrustworthy (url) {
676
+ // Given a URL record (url), the following algorithm returns "Potentially
677
+ // Trustworthy" or "Not Trustworthy" as appropriate:
678
+ if (!webidl.is.URL(url)) {
547
679
  return false
548
680
  }
681
+
682
+ // 1. If url is "about:blank" or "about:srcdoc",
683
+ // return "Potentially Trustworthy".
684
+ if (url.href === 'about:blank' || url.href === 'about:srcdoc') {
685
+ return true
686
+ }
687
+
688
+ // 2. If url’s scheme is "data", return "Potentially Trustworthy".
689
+ if (url.protocol === 'data:') return true
690
+
691
+ // Note: The origin of blob: URLs is the origin of the context in which they
692
+ // were created. Therefore, blobs created in a trustworthy origin will
693
+ // themselves be potentially trustworthy.
694
+ if (url.protocol === 'blob:') return true
695
+
696
+ // 3. Return the result of executing § 3.1 Is origin potentially trustworthy?
697
+ // on url’s origin.
698
+ return isOriginPotentiallyTrustworthy(url.origin)
549
699
  }
550
700
 
551
701
  /**
@@ -825,7 +975,7 @@ const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbo
825
975
  /**
826
976
  * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
827
977
  * @param {string} name name of the instance
828
- * @param {symbol} kInternalIterator
978
+ * @param {((target: any) => any)} kInternalIterator
829
979
  * @param {string | number} [keyIndex]
830
980
  * @param {string | number} [valueIndex]
831
981
  */
@@ -867,7 +1017,7 @@ function createIterator (name, kInternalIterator, keyIndex = 0, valueIndex = 1)
867
1017
  // 7. Let kind be object’s kind.
868
1018
  // 8. Let values be object’s target's value pairs to iterate over.
869
1019
  const index = this.#index
870
- const values = this.#target[kInternalIterator]
1020
+ const values = kInternalIterator(this.#target)
871
1021
 
872
1022
  // 9. Let len be the length of values.
873
1023
  const len = values.length
@@ -961,7 +1111,7 @@ function createIterator (name, kInternalIterator, keyIndex = 0, valueIndex = 1)
961
1111
  * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
962
1112
  * @param {string} name name of the instance
963
1113
  * @param {any} object class
964
- * @param {symbol} kInternalIterator
1114
+ * @param {(target: any) => any} kInternalIterator
965
1115
  * @param {string | number} [keyIndex]
966
1116
  * @param {string | number} [valueIndex]
967
1117
  */
@@ -1029,7 +1179,7 @@ function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, valueInde
1029
1179
  /**
1030
1180
  * @see https://fetch.spec.whatwg.org/#body-fully-read
1031
1181
  */
1032
- async function fullyReadBody (body, processBody, processBodyError) {
1182
+ function fullyReadBody (body, processBody, processBodyError) {
1033
1183
  // 1. If taskDestination is null, then set taskDestination to
1034
1184
  // the result of starting a new parallel queue.
1035
1185
 
@@ -1054,18 +1204,7 @@ async function fullyReadBody (body, processBody, processBodyError) {
1054
1204
  }
1055
1205
 
1056
1206
  // 5. Read all bytes from reader, given successSteps and errorSteps.
1057
- try {
1058
- successSteps(await readAllBytes(reader))
1059
- } catch (e) {
1060
- errorSteps(e)
1061
- }
1062
- }
1063
-
1064
- function isReadableStreamLike (stream) {
1065
- return stream instanceof ReadableStream || (
1066
- stream[Symbol.toStringTag] === 'ReadableStream' &&
1067
- typeof stream.tee === 'function'
1068
- )
1207
+ readAllBytes(reader, successSteps, errorSteps)
1069
1208
  }
1070
1209
 
1071
1210
  /**
@@ -1103,42 +1242,54 @@ function isomorphicEncode (input) {
1103
1242
  * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes
1104
1243
  * @see https://streams.spec.whatwg.org/#read-loop
1105
1244
  * @param {ReadableStreamDefaultReader} reader
1245
+ * @param {(bytes: Uint8Array) => void} successSteps
1246
+ * @param {(error: Error) => void} failureSteps
1106
1247
  */
1107
- async function readAllBytes (reader) {
1248
+ async function readAllBytes (reader, successSteps, failureSteps) {
1108
1249
  const bytes = []
1109
1250
  let byteLength = 0
1110
1251
 
1111
- while (true) {
1112
- const { done, value: chunk } = await reader.read()
1252
+ try {
1253
+ do {
1254
+ const { done, value: chunk } = await reader.read()
1113
1255
 
1114
- if (done) {
1115
- // 1. Call successSteps with bytes.
1116
- return Buffer.concat(bytes, byteLength)
1117
- }
1256
+ if (done) {
1257
+ // 1. Call successSteps with bytes.
1258
+ successSteps(Buffer.concat(bytes, byteLength))
1259
+ return
1260
+ }
1118
1261
 
1119
- // 1. If chunk is not a Uint8Array object, call failureSteps
1120
- // with a TypeError and abort these steps.
1121
- if (!isUint8Array(chunk)) {
1122
- throw new TypeError('Received non-Uint8Array chunk')
1123
- }
1262
+ // 1. If chunk is not a Uint8Array object, call failureSteps
1263
+ // with a TypeError and abort these steps.
1264
+ if (!isUint8Array(chunk)) {
1265
+ failureSteps(TypeError('Received non-Uint8Array chunk'))
1266
+ return
1267
+ }
1124
1268
 
1125
- // 2. Append the bytes represented by chunk to bytes.
1126
- bytes.push(chunk)
1127
- byteLength += chunk.length
1269
+ // 2. Append the bytes represented by chunk to bytes.
1270
+ bytes.push(chunk)
1271
+ byteLength += chunk.length
1128
1272
 
1129
1273
  // 3. Read-loop given reader, bytes, successSteps, and failureSteps.
1274
+ } while (true)
1275
+ } catch (e) {
1276
+ // 1. Call failureSteps with e.
1277
+ failureSteps(e)
1130
1278
  }
1131
1279
  }
1132
1280
 
1133
1281
  /**
1134
1282
  * @see https://fetch.spec.whatwg.org/#is-local
1135
1283
  * @param {URL} url
1284
+ * @returns {boolean}
1136
1285
  */
1137
1286
  function urlIsLocal (url) {
1138
1287
  assert('protocol' in url) // ensure it's a url object
1139
1288
 
1140
1289
  const protocol = url.protocol
1141
1290
 
1291
+ // A URL is local if its scheme is a local scheme.
1292
+ // A local scheme is "about", "blob", or "data".
1142
1293
  return protocol === 'about:' || protocol === 'blob:' || protocol === 'data:'
1143
1294
  }
1144
1295
 
@@ -1601,7 +1752,6 @@ module.exports = {
1601
1752
  requestCurrentURL,
1602
1753
  responseURL,
1603
1754
  responseLocationURL,
1604
- isBlobLike,
1605
1755
  isURLPotentiallyTrustworthy,
1606
1756
  isValidReasonPhrase,
1607
1757
  sameOrigin,
@@ -1614,7 +1764,6 @@ module.exports = {
1614
1764
  isErrorLike,
1615
1765
  fullyReadBody,
1616
1766
  bytesMatch,
1617
- isReadableStreamLike,
1618
1767
  readableStreamClose,
1619
1768
  isomorphicEncode,
1620
1769
  urlIsLocal,
@@ -1628,5 +1777,6 @@ module.exports = {
1628
1777
  extractMimeType,
1629
1778
  getDecodeSplit,
1630
1779
  utf8DecodeBytes,
1631
- environmentSettingsObject
1780
+ environmentSettingsObject,
1781
+ isOriginIPPotentiallyTrustworthy
1632
1782
  }