undici 7.0.0-alpha.2 → 7.0.0-alpha.3
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 +1 -1
- package/docs/docs/api/CacheStore.md +116 -0
- package/docs/docs/api/Dispatcher.md +10 -0
- package/index.js +6 -1
- package/lib/api/api-request.js +1 -1
- package/lib/api/readable.js +6 -6
- package/lib/cache/memory-cache-store.js +417 -0
- package/lib/core/constants.js +24 -1
- package/lib/core/util.js +41 -2
- package/lib/dispatcher/client-h1.js +100 -87
- package/lib/dispatcher/client-h2.js +127 -75
- package/lib/dispatcher/pool-base.js +3 -3
- package/lib/handler/cache-handler.js +359 -0
- package/lib/handler/cache-revalidation-handler.js +119 -0
- package/lib/interceptor/cache.js +171 -0
- package/lib/util/cache.js +224 -0
- package/lib/web/cache/cache.js +1 -0
- package/lib/web/cache/cachestorage.js +2 -0
- package/lib/web/eventsource/eventsource.js +2 -0
- package/lib/web/fetch/constants.js +12 -5
- package/lib/web/fetch/data-url.js +2 -2
- package/lib/web/fetch/formdata.js +3 -1
- package/lib/web/fetch/headers.js +2 -0
- package/lib/web/fetch/request.js +3 -1
- package/lib/web/fetch/response.js +3 -1
- package/lib/web/fetch/util.js +171 -47
- package/lib/web/fetch/webidl.js +16 -12
- package/lib/web/websocket/constants.js +67 -6
- package/lib/web/websocket/events.js +4 -0
- package/lib/web/websocket/stream/websocketerror.js +1 -1
- package/lib/web/websocket/websocket.js +2 -0
- package/package.json +7 -3
- package/types/cache-interceptor.d.ts +97 -0
- package/types/fetch.d.ts +9 -8
- package/types/index.d.ts +3 -0
- package/types/interceptors.d.ts +4 -0
- package/types/webidl.d.ts +7 -1
package/lib/web/fetch/util.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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')
|
|
@@ -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,8 +419,9 @@ 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)
|
|
424
|
+
// a URL
|
|
402
425
|
} else if (webidl.is.URL(request.referrer)) {
|
|
403
426
|
// Let referrerSource be request’s referrer.
|
|
404
427
|
referrerSource = request.referrer
|
|
@@ -500,18 +523,26 @@ function determineRequestsReferrer (request) {
|
|
|
500
523
|
}
|
|
501
524
|
|
|
502
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
|
+
*
|
|
503
533
|
* @see https://w3c.github.io/webappsec-referrer-policy/#strip-url
|
|
504
534
|
* @param {URL} url
|
|
505
|
-
* @param {boolean} [originOnly]
|
|
535
|
+
* @param {boolean} [originOnly=false]
|
|
506
536
|
*/
|
|
507
|
-
function stripURLForReferrer (url, originOnly) {
|
|
537
|
+
function stripURLForReferrer (url, originOnly = false) {
|
|
508
538
|
// 1. Assert: url is a URL.
|
|
509
539
|
assert(webidl.is.URL(url))
|
|
510
540
|
|
|
541
|
+
// Note: Create a new URL instance to avoid mutating the original URL.
|
|
511
542
|
url = new URL(url)
|
|
512
543
|
|
|
513
544
|
// 2. If url’s scheme is a local scheme, then return no referrer.
|
|
514
|
-
if (url
|
|
545
|
+
if (urlIsLocal(url)) {
|
|
515
546
|
return 'no-referrer'
|
|
516
547
|
}
|
|
517
548
|
|
|
@@ -525,7 +556,7 @@ function stripURLForReferrer (url, originOnly) {
|
|
|
525
556
|
url.hash = ''
|
|
526
557
|
|
|
527
558
|
// 6. If the origin-only flag is true, then:
|
|
528
|
-
if (originOnly) {
|
|
559
|
+
if (originOnly === true) {
|
|
529
560
|
// 1. Set url’s path to « the empty string ».
|
|
530
561
|
url.pathname = ''
|
|
531
562
|
|
|
@@ -537,45 +568,134 @@ function stripURLForReferrer (url, originOnly) {
|
|
|
537
568
|
return url
|
|
538
569
|
}
|
|
539
570
|
|
|
540
|
-
|
|
541
|
-
|
|
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') {
|
|
542
617
|
return false
|
|
543
618
|
}
|
|
544
619
|
|
|
545
|
-
//
|
|
546
|
-
|
|
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:') {
|
|
547
626
|
return true
|
|
548
627
|
}
|
|
549
628
|
|
|
550
|
-
// If
|
|
551
|
-
|
|
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
|
+
}
|
|
552
634
|
|
|
553
|
-
// If
|
|
554
|
-
|
|
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:
|
|
555
637
|
|
|
556
|
-
|
|
638
|
+
// origin’s host is "localhost" or "localhost."
|
|
639
|
+
if (origin.hostname === 'localhost' || origin.hostname === 'localhost.') {
|
|
640
|
+
return true
|
|
641
|
+
}
|
|
557
642
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
643
|
+
// origin’s host ends with ".localhost" or ".localhost."
|
|
644
|
+
if (origin.hostname.endsWith('.localhost') || origin.hostname.endsWith('.localhost.')) {
|
|
645
|
+
return true
|
|
646
|
+
}
|
|
561
647
|
|
|
562
|
-
|
|
648
|
+
// 6. If origin’s scheme is "file", return "Potentially Trustworthy".
|
|
649
|
+
if (origin.protocol === 'file:') {
|
|
650
|
+
return true
|
|
651
|
+
}
|
|
563
652
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
return true
|
|
567
|
-
}
|
|
653
|
+
// 7. If origin’s scheme component is one which the user agent considers to
|
|
654
|
+
// be authenticated, return "Potentially Trustworthy".
|
|
568
655
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
(originAsURL.hostname === 'localhost' || originAsURL.hostname.includes('localhost.')) ||
|
|
572
|
-
(originAsURL.hostname.endsWith('.localhost'))) {
|
|
573
|
-
return true
|
|
574
|
-
}
|
|
656
|
+
// 8. If origin has been configured as a trustworthy origin, return
|
|
657
|
+
// "Potentially Trustworthy".
|
|
575
658
|
|
|
576
|
-
|
|
659
|
+
// 9. Return "Not Trustworthy".
|
|
660
|
+
return false
|
|
661
|
+
}
|
|
662
|
+
|
|
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)) {
|
|
577
679
|
return false
|
|
578
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)
|
|
579
699
|
}
|
|
580
700
|
|
|
581
701
|
/**
|
|
@@ -1161,12 +1281,15 @@ async function readAllBytes (reader, successSteps, failureSteps) {
|
|
|
1161
1281
|
/**
|
|
1162
1282
|
* @see https://fetch.spec.whatwg.org/#is-local
|
|
1163
1283
|
* @param {URL} url
|
|
1284
|
+
* @returns {boolean}
|
|
1164
1285
|
*/
|
|
1165
1286
|
function urlIsLocal (url) {
|
|
1166
1287
|
assert('protocol' in url) // ensure it's a url object
|
|
1167
1288
|
|
|
1168
1289
|
const protocol = url.protocol
|
|
1169
1290
|
|
|
1291
|
+
// A URL is local if its scheme is a local scheme.
|
|
1292
|
+
// A local scheme is "about", "blob", or "data".
|
|
1170
1293
|
return protocol === 'about:' || protocol === 'blob:' || protocol === 'data:'
|
|
1171
1294
|
}
|
|
1172
1295
|
|
|
@@ -1654,5 +1777,6 @@ module.exports = {
|
|
|
1654
1777
|
extractMimeType,
|
|
1655
1778
|
getDecodeSplit,
|
|
1656
1779
|
utf8DecodeBytes,
|
|
1657
|
-
environmentSettingsObject
|
|
1780
|
+
environmentSettingsObject,
|
|
1781
|
+
isOriginIPPotentiallyTrustworthy
|
|
1658
1782
|
}
|
package/lib/web/fetch/webidl.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { types, inspect } = require('node:util')
|
|
4
|
+
const { markAsUncloneable } = require('node:worker_threads')
|
|
4
5
|
const { toUSVString } = require('../../core/util')
|
|
5
6
|
|
|
6
7
|
const UNDEFINED = 1
|
|
@@ -12,6 +13,8 @@ const BIGINT = 6
|
|
|
12
13
|
const NULL = 7
|
|
13
14
|
const OBJECT = 8 // function and object
|
|
14
15
|
|
|
16
|
+
const FunctionPrototypeSymbolHasInstance = Function.call.bind(Function.prototype[Symbol.hasInstance])
|
|
17
|
+
|
|
15
18
|
/** @type {import('../../../types/webidl').Webidl} */
|
|
16
19
|
const webidl = {
|
|
17
20
|
converters: {},
|
|
@@ -45,7 +48,7 @@ webidl.errors.invalidArgument = function (context) {
|
|
|
45
48
|
|
|
46
49
|
// https://webidl.spec.whatwg.org/#implements
|
|
47
50
|
webidl.brandCheck = function (V, I) {
|
|
48
|
-
if (!I
|
|
51
|
+
if (!FunctionPrototypeSymbolHasInstance(I, V)) {
|
|
49
52
|
const err = new TypeError('Illegal invocation')
|
|
50
53
|
err.code = 'ERR_INVALID_THIS' // node compat.
|
|
51
54
|
throw err
|
|
@@ -53,7 +56,7 @@ webidl.brandCheck = function (V, I) {
|
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
webidl.brandCheckMultiple = function (List) {
|
|
56
|
-
const prototypes = List.map((c) => webidl.util.MakeTypeAssertion(c
|
|
59
|
+
const prototypes = List.map((c) => webidl.util.MakeTypeAssertion(c))
|
|
57
60
|
|
|
58
61
|
return (V) => {
|
|
59
62
|
if (prototypes.every(typeCheck => !typeCheck(V))) {
|
|
@@ -81,9 +84,8 @@ webidl.illegalConstructor = function () {
|
|
|
81
84
|
})
|
|
82
85
|
}
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return (O) => isPrototypeOf.call(Prototype, O)
|
|
87
|
+
webidl.util.MakeTypeAssertion = function (I) {
|
|
88
|
+
return (O) => FunctionPrototypeSymbolHasInstance(I, O)
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
// https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values
|
|
@@ -130,6 +132,8 @@ webidl.util.TypeValueToString = function (o) {
|
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
|
|
135
|
+
webidl.util.markAsUncloneable = markAsUncloneable || (() => {})
|
|
136
|
+
|
|
133
137
|
// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
|
|
134
138
|
webidl.util.ConvertToInt = function (V, bitLength, signedness, opts) {
|
|
135
139
|
let upperBound
|
|
@@ -462,13 +466,13 @@ webidl.nullableConverter = function (converter) {
|
|
|
462
466
|
}
|
|
463
467
|
}
|
|
464
468
|
|
|
465
|
-
webidl.is.ReadableStream = webidl.util.MakeTypeAssertion(ReadableStream
|
|
466
|
-
webidl.is.Blob = webidl.util.MakeTypeAssertion(Blob
|
|
467
|
-
webidl.is.URLSearchParams = webidl.util.MakeTypeAssertion(URLSearchParams
|
|
468
|
-
webidl.is.File = webidl.util.MakeTypeAssertion(
|
|
469
|
-
webidl.is.URL = webidl.util.MakeTypeAssertion(URL
|
|
470
|
-
webidl.is.AbortSignal = webidl.util.MakeTypeAssertion(AbortSignal
|
|
471
|
-
webidl.is.MessagePort = webidl.util.MakeTypeAssertion(MessagePort
|
|
469
|
+
webidl.is.ReadableStream = webidl.util.MakeTypeAssertion(ReadableStream)
|
|
470
|
+
webidl.is.Blob = webidl.util.MakeTypeAssertion(Blob)
|
|
471
|
+
webidl.is.URLSearchParams = webidl.util.MakeTypeAssertion(URLSearchParams)
|
|
472
|
+
webidl.is.File = webidl.util.MakeTypeAssertion(globalThis.File ?? require('node:buffer').File)
|
|
473
|
+
webidl.is.URL = webidl.util.MakeTypeAssertion(URL)
|
|
474
|
+
webidl.is.AbortSignal = webidl.util.MakeTypeAssertion(AbortSignal)
|
|
475
|
+
webidl.is.MessagePort = webidl.util.MakeTypeAssertion(MessagePort)
|
|
472
476
|
|
|
473
477
|
// https://webidl.spec.whatwg.org/#es-DOMString
|
|
474
478
|
webidl.converters.DOMString = function (V, prefix, argument, opts) {
|
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
/**
|
|
4
|
+
* This is a Globally Unique Identifier unique used to validate that the
|
|
5
|
+
* endpoint accepts websocket connections.
|
|
6
|
+
* @see https://www.rfc-editor.org/rfc/rfc6455.html#section-1.3
|
|
7
|
+
* @type {'258EAFA5-E914-47DA-95CA-C5AB0DC85B11'}
|
|
8
|
+
*/
|
|
7
9
|
const uid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
|
|
8
10
|
|
|
9
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* @type {PropertyDescriptor}
|
|
13
|
+
*/
|
|
10
14
|
const staticPropertyDescriptors = {
|
|
11
15
|
enumerable: true,
|
|
12
16
|
writable: false,
|
|
13
17
|
configurable: false
|
|
14
18
|
}
|
|
15
19
|
|
|
20
|
+
/**
|
|
21
|
+
* The states of the WebSocket connection.
|
|
22
|
+
*
|
|
23
|
+
* @readonly
|
|
24
|
+
* @enum
|
|
25
|
+
* @property {0} CONNECTING
|
|
26
|
+
* @property {1} OPEN
|
|
27
|
+
* @property {2} CLOSING
|
|
28
|
+
* @property {3} CLOSED
|
|
29
|
+
*/
|
|
16
30
|
const states = {
|
|
17
31
|
CONNECTING: 0,
|
|
18
32
|
OPEN: 1,
|
|
@@ -20,11 +34,31 @@ const states = {
|
|
|
20
34
|
CLOSED: 3
|
|
21
35
|
}
|
|
22
36
|
|
|
37
|
+
/**
|
|
38
|
+
* @readonly
|
|
39
|
+
* @enum
|
|
40
|
+
* @property {0} NOT_SENT
|
|
41
|
+
* @property {1} PROCESSING
|
|
42
|
+
* @property {2} SENT
|
|
43
|
+
*/
|
|
23
44
|
const sentCloseFrameState = {
|
|
24
45
|
SENT: 1,
|
|
25
46
|
RECEIVED: 2
|
|
26
47
|
}
|
|
27
48
|
|
|
49
|
+
/**
|
|
50
|
+
* The WebSocket opcodes.
|
|
51
|
+
*
|
|
52
|
+
* @readonly
|
|
53
|
+
* @enum
|
|
54
|
+
* @property {0x0} CONTINUATION
|
|
55
|
+
* @property {0x1} TEXT
|
|
56
|
+
* @property {0x2} BINARY
|
|
57
|
+
* @property {0x8} CLOSE
|
|
58
|
+
* @property {0x9} PING
|
|
59
|
+
* @property {0xA} PONG
|
|
60
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6455#section-5.2
|
|
61
|
+
*/
|
|
28
62
|
const opcodes = {
|
|
29
63
|
CONTINUATION: 0x0,
|
|
30
64
|
TEXT: 0x1,
|
|
@@ -34,8 +68,23 @@ const opcodes = {
|
|
|
34
68
|
PONG: 0xA
|
|
35
69
|
}
|
|
36
70
|
|
|
37
|
-
|
|
71
|
+
/**
|
|
72
|
+
* The maximum value for an unsigned 16-bit integer.
|
|
73
|
+
*
|
|
74
|
+
* @type {65535} 2 ** 16 - 1
|
|
75
|
+
*/
|
|
76
|
+
const maxUnsigned16Bit = 65535
|
|
38
77
|
|
|
78
|
+
/**
|
|
79
|
+
* The states of the parser.
|
|
80
|
+
*
|
|
81
|
+
* @readonly
|
|
82
|
+
* @enum
|
|
83
|
+
* @property {0} INFO
|
|
84
|
+
* @property {2} PAYLOADLENGTH_16
|
|
85
|
+
* @property {3} PAYLOADLENGTH_64
|
|
86
|
+
* @property {4} READ_DATA
|
|
87
|
+
*/
|
|
39
88
|
const parserStates = {
|
|
40
89
|
INFO: 0,
|
|
41
90
|
PAYLOADLENGTH_16: 2,
|
|
@@ -43,8 +92,20 @@ const parserStates = {
|
|
|
43
92
|
READ_DATA: 4
|
|
44
93
|
}
|
|
45
94
|
|
|
95
|
+
/**
|
|
96
|
+
* An empty buffer.
|
|
97
|
+
*
|
|
98
|
+
* @type {Buffer}
|
|
99
|
+
*/
|
|
46
100
|
const emptyBuffer = Buffer.allocUnsafe(0)
|
|
47
101
|
|
|
102
|
+
/**
|
|
103
|
+
* @readonly
|
|
104
|
+
* @property {1} text
|
|
105
|
+
* @property {2} typedArray
|
|
106
|
+
* @property {3} arrayBuffer
|
|
107
|
+
* @property {4} blob
|
|
108
|
+
*/
|
|
48
109
|
const sendHints = {
|
|
49
110
|
text: 1,
|
|
50
111
|
typedArray: 2,
|
|
@@ -13,6 +13,7 @@ class MessageEvent extends Event {
|
|
|
13
13
|
constructor (type, eventInitDict = {}) {
|
|
14
14
|
if (type === kConstruct) {
|
|
15
15
|
super(arguments[1], arguments[2])
|
|
16
|
+
webidl.util.markAsUncloneable(this)
|
|
16
17
|
return
|
|
17
18
|
}
|
|
18
19
|
|
|
@@ -25,6 +26,7 @@ class MessageEvent extends Event {
|
|
|
25
26
|
super(type, eventInitDict)
|
|
26
27
|
|
|
27
28
|
this.#eventInit = eventInitDict
|
|
29
|
+
webidl.util.markAsUncloneable(this)
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
get data () {
|
|
@@ -111,6 +113,7 @@ class CloseEvent extends Event {
|
|
|
111
113
|
super(type, eventInitDict)
|
|
112
114
|
|
|
113
115
|
this.#eventInit = eventInitDict
|
|
116
|
+
webidl.util.markAsUncloneable(this)
|
|
114
117
|
}
|
|
115
118
|
|
|
116
119
|
get wasClean () {
|
|
@@ -141,6 +144,7 @@ class ErrorEvent extends Event {
|
|
|
141
144
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
142
145
|
|
|
143
146
|
super(type, eventInitDict)
|
|
147
|
+
webidl.util.markAsUncloneable(this)
|
|
144
148
|
|
|
145
149
|
type = webidl.converters.DOMString(type, prefix, 'type')
|
|
146
150
|
eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {})
|
|
@@ -78,6 +78,6 @@ Object.defineProperties(WebSocketError.prototype, {
|
|
|
78
78
|
}
|
|
79
79
|
})
|
|
80
80
|
|
|
81
|
-
webidl.is.WebSocketError = webidl.util.MakeTypeAssertion(WebSocketError
|
|
81
|
+
webidl.is.WebSocketError = webidl.util.MakeTypeAssertion(WebSocketError)
|
|
82
82
|
|
|
83
83
|
module.exports = { WebSocketError, createUnvalidatedWebSocketError }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "undici",
|
|
3
|
-
"version": "7.0.0-alpha.
|
|
3
|
+
"version": "7.0.0-alpha.3",
|
|
4
4
|
"description": "An HTTP/1.1 client, written from scratch for Node.js",
|
|
5
5
|
"homepage": "https://undici.nodejs.org",
|
|
6
6
|
"bugs": {
|
|
@@ -70,14 +70,18 @@
|
|
|
70
70
|
"lint:fix": "eslint --fix --cache",
|
|
71
71
|
"test": "npm run test:javascript && cross-env NODE_V8_COVERAGE= npm run test:typescript",
|
|
72
72
|
"test:javascript": "npm run test:javascript:no-jest && npm run test:jest",
|
|
73
|
-
"test:javascript:no-jest": "npm run generate-pem && npm run test:unit && npm run test:node-fetch && npm run test:cache && npm run test:interceptors && npm run test:fetch && npm run test:cookies && npm run test:eventsource && npm run test:wpt && npm run test:websocket && npm run test:node-test",
|
|
73
|
+
"test:javascript:no-jest": "npm run generate-pem && npm run test:unit && npm run test:node-fetch && npm run test:cache && npm run test:cache-interceptor && npm run test:interceptors && npm run test:fetch && npm run test:cookies && npm run test:eventsource && npm run test:wpt && npm run test:websocket && npm run test:node-test",
|
|
74
74
|
"test:javascript:without-intl": "npm run test:javascript:no-jest",
|
|
75
75
|
"test:busboy": "borp -p \"test/busboy/*.js\"",
|
|
76
76
|
"test:cache": "borp -p \"test/cache/*.js\"",
|
|
77
|
+
"test:cache-interceptor": "borp -p \"test/cache-interceptor/*.js\"",
|
|
77
78
|
"test:cookies": "borp -p \"test/cookie/*.js\"",
|
|
78
79
|
"test:eventsource": "npm run build:node && borp --expose-gc -p \"test/eventsource/*.js\"",
|
|
79
80
|
"test:fuzzing": "node test/fuzzing/fuzzing.test.js",
|
|
80
81
|
"test:fetch": "npm run build:node && borp --timeout 180000 --expose-gc --concurrency 1 -p \"test/fetch/*.js\" && npm run test:webidl && npm run test:busboy",
|
|
82
|
+
"test:h2": "npm run test:h2:core && npm run test:h2:fetch",
|
|
83
|
+
"test:h2:core": "borp -p \"test/http2*.js\"",
|
|
84
|
+
"test:h2:fetch": "npm run build:node && borp -p \"test/fetch/http2*.js\"",
|
|
81
85
|
"test:interceptors": "borp -p \"test/interceptors/*.js\"",
|
|
82
86
|
"test:jest": "cross-env NODE_V8_COVERAGE= jest",
|
|
83
87
|
"test:unit": "borp --expose-gc -p \"test/*.js\"",
|
|
@@ -107,7 +111,7 @@
|
|
|
107
111
|
"@sinonjs/fake-timers": "^11.1.0",
|
|
108
112
|
"@types/node": "^18.19.50",
|
|
109
113
|
"abort-controller": "^3.0.0",
|
|
110
|
-
"borp": "^0.
|
|
114
|
+
"borp": "^0.18.0",
|
|
111
115
|
"c8": "^10.0.0",
|
|
112
116
|
"cross-env": "^7.0.3",
|
|
113
117
|
"dns-packet": "^5.4.0",
|