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.
- package/README.md +27 -46
- package/docs/docs/api/Agent.md +14 -17
- package/docs/docs/api/BalancedPool.md +16 -16
- package/docs/docs/api/CacheStore.md +131 -0
- package/docs/docs/api/Client.md +12 -14
- package/docs/docs/api/Debug.md +1 -1
- package/docs/docs/api/Dispatcher.md +98 -194
- package/docs/docs/api/EnvHttpProxyAgent.md +12 -13
- package/docs/docs/api/MockAgent.md +5 -3
- package/docs/docs/api/MockClient.md +5 -5
- package/docs/docs/api/MockPool.md +4 -3
- package/docs/docs/api/Pool.md +15 -16
- package/docs/docs/api/PoolStats.md +1 -1
- package/docs/docs/api/ProxyAgent.md +3 -3
- package/docs/docs/api/RedirectHandler.md +1 -1
- package/docs/docs/api/RetryAgent.md +1 -1
- package/docs/docs/api/RetryHandler.md +4 -4
- package/docs/docs/api/WebSocket.md +46 -4
- package/docs/docs/api/api-lifecycle.md +11 -11
- package/docs/docs/best-practices/mocking-request.md +2 -2
- package/docs/docs/best-practices/proxy.md +1 -1
- package/index.d.ts +1 -1
- package/index.js +23 -7
- package/lib/api/abort-signal.js +2 -0
- package/lib/api/api-connect.js +3 -1
- package/lib/api/api-pipeline.js +7 -6
- package/lib/api/api-request.js +33 -48
- package/lib/api/api-stream.js +39 -50
- package/lib/api/api-upgrade.js +5 -3
- package/lib/api/readable.js +235 -62
- package/lib/api/util.js +2 -0
- package/lib/cache/memory-cache-store.js +177 -0
- package/lib/cache/sqlite-cache-store.js +446 -0
- package/lib/core/constants.js +35 -10
- package/lib/core/diagnostics.js +122 -128
- package/lib/core/errors.js +6 -6
- package/lib/core/request.js +13 -11
- package/lib/core/symbols.js +2 -1
- package/lib/core/tree.js +9 -1
- package/lib/core/util.js +237 -49
- package/lib/dispatcher/agent.js +3 -17
- package/lib/dispatcher/balanced-pool.js +5 -8
- package/lib/dispatcher/client-h1.js +379 -134
- package/lib/dispatcher/client-h2.js +173 -107
- package/lib/dispatcher/client.js +19 -32
- package/lib/dispatcher/dispatcher-base.js +6 -35
- package/lib/dispatcher/dispatcher.js +7 -24
- package/lib/dispatcher/fixed-queue.js +91 -49
- package/lib/dispatcher/pool-stats.js +2 -0
- package/lib/dispatcher/pool.js +3 -6
- package/lib/dispatcher/proxy-agent.js +3 -6
- package/lib/handler/cache-handler.js +393 -0
- package/lib/handler/cache-revalidation-handler.js +124 -0
- package/lib/handler/decorator-handler.js +27 -0
- package/lib/handler/redirect-handler.js +54 -59
- package/lib/handler/retry-handler.js +77 -109
- package/lib/handler/unwrap-handler.js +96 -0
- package/lib/handler/wrap-handler.js +98 -0
- package/lib/interceptor/cache.js +350 -0
- package/lib/interceptor/dns.js +375 -0
- package/lib/interceptor/dump.js +2 -2
- package/lib/interceptor/redirect.js +11 -14
- package/lib/interceptor/response-error.js +18 -7
- package/lib/llhttp/constants.d.ts +97 -0
- package/lib/llhttp/constants.js +412 -192
- package/lib/llhttp/constants.js.map +1 -0
- package/lib/llhttp/llhttp-wasm.js +11 -1
- package/lib/llhttp/llhttp_simd-wasm.js +11 -1
- package/lib/llhttp/utils.d.ts +2 -0
- package/lib/llhttp/utils.js +9 -9
- package/lib/llhttp/utils.js.map +1 -0
- package/lib/mock/mock-agent.js +5 -8
- package/lib/mock/mock-client.js +9 -4
- package/lib/mock/mock-errors.js +3 -1
- package/lib/mock/mock-interceptor.js +8 -6
- package/lib/mock/mock-pool.js +9 -4
- package/lib/mock/mock-symbols.js +3 -1
- package/lib/mock/mock-utils.js +29 -5
- package/lib/util/cache.js +360 -0
- package/lib/web/cache/cache.js +24 -21
- package/lib/web/cache/cachestorage.js +1 -1
- package/lib/web/cookies/index.js +29 -14
- package/lib/web/cookies/parse.js +8 -3
- package/lib/web/eventsource/eventsource-stream.js +9 -8
- package/lib/web/eventsource/eventsource.js +10 -6
- package/lib/web/fetch/body.js +43 -41
- package/lib/web/fetch/constants.js +12 -5
- package/lib/web/fetch/data-url.js +3 -3
- package/lib/web/fetch/formdata-parser.js +72 -45
- package/lib/web/fetch/formdata.js +65 -54
- package/lib/web/fetch/headers.js +118 -86
- package/lib/web/fetch/index.js +58 -67
- package/lib/web/fetch/request.js +136 -77
- package/lib/web/fetch/response.js +87 -56
- package/lib/web/fetch/util.js +259 -109
- package/lib/web/fetch/webidl.js +113 -68
- package/lib/web/websocket/connection.js +76 -147
- package/lib/web/websocket/constants.js +70 -10
- package/lib/web/websocket/events.js +4 -2
- package/lib/web/websocket/frame.js +45 -3
- package/lib/web/websocket/receiver.js +29 -33
- package/lib/web/websocket/sender.js +18 -13
- package/lib/web/websocket/stream/websocketerror.js +83 -0
- package/lib/web/websocket/stream/websocketstream.js +485 -0
- package/lib/web/websocket/util.js +128 -77
- package/lib/web/websocket/websocket.js +234 -135
- package/package.json +24 -36
- package/scripts/strip-comments.js +3 -1
- package/types/agent.d.ts +7 -7
- package/types/api.d.ts +24 -24
- package/types/balanced-pool.d.ts +11 -11
- package/types/cache-interceptor.d.ts +172 -0
- package/types/client.d.ts +11 -12
- package/types/cookies.d.ts +2 -0
- package/types/diagnostics-channel.d.ts +10 -10
- package/types/dispatcher.d.ts +113 -90
- package/types/env-http-proxy-agent.d.ts +2 -2
- package/types/errors.d.ts +53 -47
- package/types/fetch.d.ts +17 -16
- package/types/formdata.d.ts +7 -7
- package/types/global-dispatcher.d.ts +4 -4
- package/types/global-origin.d.ts +5 -5
- package/types/handlers.d.ts +7 -7
- package/types/header.d.ts +157 -1
- package/types/index.d.ts +44 -46
- package/types/interceptors.d.ts +25 -8
- package/types/mock-agent.d.ts +21 -18
- package/types/mock-client.d.ts +4 -4
- package/types/mock-errors.d.ts +3 -3
- package/types/mock-interceptor.d.ts +19 -19
- package/types/mock-pool.d.ts +4 -4
- package/types/patch.d.ts +0 -4
- package/types/pool-stats.d.ts +8 -8
- package/types/pool.d.ts +12 -12
- package/types/proxy-agent.d.ts +4 -4
- package/types/readable.d.ts +18 -15
- package/types/retry-agent.d.ts +1 -1
- package/types/retry-handler.d.ts +10 -10
- package/types/util.d.ts +3 -3
- package/types/utility.d.ts +7 -0
- package/types/webidl.d.ts +44 -6
- package/types/websocket.d.ts +34 -1
- package/docs/docs/api/DispatchInterceptor.md +0 -60
- package/lib/interceptor/redirect-interceptor.js +0 -21
- package/lib/mock/pluralizer.js +0 -29
- package/lib/web/cache/symbols.js +0 -5
- package/lib/web/fetch/file.js +0 -126
- package/lib/web/fetch/symbols.js +0 -9
- package/lib/web/fileapi/encoding.js +0 -290
- package/lib/web/fileapi/filereader.js +0 -344
- package/lib/web/fileapi/progressevent.js +0 -78
- package/lib/web/fileapi/symbols.js +0 -10
- package/lib/web/fileapi/util.js +0 -391
- package/lib/web/websocket/symbols.js +0 -12
- package/types/file.d.ts +0 -39
- package/types/filereader.d.ts +0 -54
package/lib/web/fetch/util.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const { Transform } = require('node:stream')
|
|
4
4
|
const zlib = require('node:zlib')
|
|
5
|
-
const { redirectStatusSet,
|
|
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 {
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
422
|
+
// Note: we need to clone it as it's mutated
|
|
401
423
|
referrerSource = new URL(globalOrigin)
|
|
402
|
-
|
|
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
|
-
|
|
422
|
-
|
|
423
|
-
|
|
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 '
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
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 '
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
511
|
-
|
|
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
|
-
//
|
|
516
|
-
|
|
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
|
|
521
|
-
|
|
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
|
|
524
|
-
|
|
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
|
-
|
|
638
|
+
// origin’s host is "localhost" or "localhost."
|
|
639
|
+
if (origin.hostname === 'localhost' || origin.hostname === 'localhost.') {
|
|
640
|
+
return true
|
|
641
|
+
}
|
|
527
642
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
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
|
-
|
|
653
|
+
// 7. If origin’s scheme component is one which the user agent considers to
|
|
654
|
+
// be authenticated, return "Potentially Trustworthy".
|
|
533
655
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
return true
|
|
537
|
-
}
|
|
656
|
+
// 8. If origin has been configured as a trustworthy origin, return
|
|
657
|
+
// "Potentially Trustworthy".
|
|
538
658
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
(originAsURL.hostname.endsWith('.localhost'))) {
|
|
543
|
-
return true
|
|
544
|
-
}
|
|
659
|
+
// 9. Return "Not Trustworthy".
|
|
660
|
+
return false
|
|
661
|
+
}
|
|
545
662
|
|
|
546
|
-
|
|
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 {
|
|
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
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1112
|
-
|
|
1252
|
+
try {
|
|
1253
|
+
do {
|
|
1254
|
+
const { done, value: chunk } = await reader.read()
|
|
1113
1255
|
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1256
|
+
if (done) {
|
|
1257
|
+
// 1. Call successSteps with bytes.
|
|
1258
|
+
successSteps(Buffer.concat(bytes, byteLength))
|
|
1259
|
+
return
|
|
1260
|
+
}
|
|
1118
1261
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
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
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
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
|
}
|