deepv-code 1.0.182 → 1.0.183

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 (193) hide show
  1. package/bundle/dvcode.js +635 -635
  2. package/package.json +1 -1
  3. package/bundle/assets/help/README.md +0 -113
  4. package/bundle/assets/sounds/README.md +0 -74
  5. package/bundle/node_modules/undici/LICENSE +0 -21
  6. package/bundle/node_modules/undici/README.md +0 -472
  7. package/bundle/node_modules/undici/docs/docs/api/Agent.md +0 -83
  8. package/bundle/node_modules/undici/docs/docs/api/BalancedPool.md +0 -99
  9. package/bundle/node_modules/undici/docs/docs/api/CacheStorage.md +0 -30
  10. package/bundle/node_modules/undici/docs/docs/api/CacheStore.md +0 -151
  11. package/bundle/node_modules/undici/docs/docs/api/Client.md +0 -281
  12. package/bundle/node_modules/undici/docs/docs/api/ClientStats.md +0 -27
  13. package/bundle/node_modules/undici/docs/docs/api/Connector.md +0 -115
  14. package/bundle/node_modules/undici/docs/docs/api/ContentType.md +0 -57
  15. package/bundle/node_modules/undici/docs/docs/api/Cookies.md +0 -101
  16. package/bundle/node_modules/undici/docs/docs/api/Debug.md +0 -62
  17. package/bundle/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +0 -204
  18. package/bundle/node_modules/undici/docs/docs/api/Dispatcher.md +0 -1200
  19. package/bundle/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +0 -159
  20. package/bundle/node_modules/undici/docs/docs/api/Errors.md +0 -49
  21. package/bundle/node_modules/undici/docs/docs/api/EventSource.md +0 -45
  22. package/bundle/node_modules/undici/docs/docs/api/Fetch.md +0 -52
  23. package/bundle/node_modules/undici/docs/docs/api/H2CClient.md +0 -262
  24. package/bundle/node_modules/undici/docs/docs/api/MockAgent.md +0 -603
  25. package/bundle/node_modules/undici/docs/docs/api/MockCallHistory.md +0 -197
  26. package/bundle/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +0 -43
  27. package/bundle/node_modules/undici/docs/docs/api/MockClient.md +0 -77
  28. package/bundle/node_modules/undici/docs/docs/api/MockErrors.md +0 -12
  29. package/bundle/node_modules/undici/docs/docs/api/MockPool.md +0 -548
  30. package/bundle/node_modules/undici/docs/docs/api/Pool.md +0 -84
  31. package/bundle/node_modules/undici/docs/docs/api/PoolStats.md +0 -35
  32. package/bundle/node_modules/undici/docs/docs/api/ProxyAgent.md +0 -227
  33. package/bundle/node_modules/undici/docs/docs/api/RedirectHandler.md +0 -96
  34. package/bundle/node_modules/undici/docs/docs/api/RetryAgent.md +0 -45
  35. package/bundle/node_modules/undici/docs/docs/api/RetryHandler.md +0 -117
  36. package/bundle/node_modules/undici/docs/docs/api/Util.md +0 -25
  37. package/bundle/node_modules/undici/docs/docs/api/WebSocket.md +0 -85
  38. package/bundle/node_modules/undici/docs/docs/api/api-lifecycle.md +0 -91
  39. package/bundle/node_modules/undici/docs/docs/best-practices/client-certificate.md +0 -64
  40. package/bundle/node_modules/undici/docs/docs/best-practices/mocking-request.md +0 -190
  41. package/bundle/node_modules/undici/docs/docs/best-practices/proxy.md +0 -127
  42. package/bundle/node_modules/undici/docs/docs/best-practices/writing-tests.md +0 -20
  43. package/bundle/node_modules/undici/index-fetch.js +0 -35
  44. package/bundle/node_modules/undici/index.d.ts +0 -3
  45. package/bundle/node_modules/undici/index.js +0 -183
  46. package/bundle/node_modules/undici/lib/api/abort-signal.js +0 -59
  47. package/bundle/node_modules/undici/lib/api/api-connect.js +0 -110
  48. package/bundle/node_modules/undici/lib/api/api-pipeline.js +0 -252
  49. package/bundle/node_modules/undici/lib/api/api-request.js +0 -199
  50. package/bundle/node_modules/undici/lib/api/api-stream.js +0 -209
  51. package/bundle/node_modules/undici/lib/api/api-upgrade.js +0 -110
  52. package/bundle/node_modules/undici/lib/api/index.js +0 -7
  53. package/bundle/node_modules/undici/lib/api/readable.js +0 -558
  54. package/bundle/node_modules/undici/lib/api/util.js +0 -95
  55. package/bundle/node_modules/undici/lib/cache/memory-cache-store.js +0 -234
  56. package/bundle/node_modules/undici/lib/cache/sqlite-cache-store.js +0 -461
  57. package/bundle/node_modules/undici/lib/core/connect.js +0 -164
  58. package/bundle/node_modules/undici/lib/core/constants.js +0 -143
  59. package/bundle/node_modules/undici/lib/core/diagnostics.js +0 -196
  60. package/bundle/node_modules/undici/lib/core/errors.js +0 -244
  61. package/bundle/node_modules/undici/lib/core/request.js +0 -397
  62. package/bundle/node_modules/undici/lib/core/symbols.js +0 -68
  63. package/bundle/node_modules/undici/lib/core/tree.js +0 -160
  64. package/bundle/node_modules/undici/lib/core/util.js +0 -988
  65. package/bundle/node_modules/undici/lib/dispatcher/agent.js +0 -135
  66. package/bundle/node_modules/undici/lib/dispatcher/balanced-pool.js +0 -206
  67. package/bundle/node_modules/undici/lib/dispatcher/client-h1.js +0 -1615
  68. package/bundle/node_modules/undici/lib/dispatcher/client-h2.js +0 -798
  69. package/bundle/node_modules/undici/lib/dispatcher/client.js +0 -614
  70. package/bundle/node_modules/undici/lib/dispatcher/dispatcher-base.js +0 -161
  71. package/bundle/node_modules/undici/lib/dispatcher/dispatcher.js +0 -48
  72. package/bundle/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +0 -151
  73. package/bundle/node_modules/undici/lib/dispatcher/fixed-queue.js +0 -159
  74. package/bundle/node_modules/undici/lib/dispatcher/h2c-client.js +0 -122
  75. package/bundle/node_modules/undici/lib/dispatcher/pool-base.js +0 -191
  76. package/bundle/node_modules/undici/lib/dispatcher/pool.js +0 -118
  77. package/bundle/node_modules/undici/lib/dispatcher/proxy-agent.js +0 -275
  78. package/bundle/node_modules/undici/lib/dispatcher/retry-agent.js +0 -35
  79. package/bundle/node_modules/undici/lib/global.js +0 -32
  80. package/bundle/node_modules/undici/lib/handler/cache-handler.js +0 -448
  81. package/bundle/node_modules/undici/lib/handler/cache-revalidation-handler.js +0 -124
  82. package/bundle/node_modules/undici/lib/handler/decorator-handler.js +0 -67
  83. package/bundle/node_modules/undici/lib/handler/redirect-handler.js +0 -227
  84. package/bundle/node_modules/undici/lib/handler/retry-handler.js +0 -342
  85. package/bundle/node_modules/undici/lib/handler/unwrap-handler.js +0 -96
  86. package/bundle/node_modules/undici/lib/handler/wrap-handler.js +0 -95
  87. package/bundle/node_modules/undici/lib/interceptor/cache.js +0 -372
  88. package/bundle/node_modules/undici/lib/interceptor/dns.js +0 -432
  89. package/bundle/node_modules/undici/lib/interceptor/dump.js +0 -111
  90. package/bundle/node_modules/undici/lib/interceptor/redirect.js +0 -21
  91. package/bundle/node_modules/undici/lib/interceptor/response-error.js +0 -95
  92. package/bundle/node_modules/undici/lib/interceptor/retry.js +0 -19
  93. package/bundle/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  94. package/bundle/node_modules/undici/lib/llhttp/constants.d.ts +0 -97
  95. package/bundle/node_modules/undici/lib/llhttp/constants.js +0 -498
  96. package/bundle/node_modules/undici/lib/llhttp/constants.js.map +0 -1
  97. package/bundle/node_modules/undici/lib/llhttp/llhttp-wasm.js +0 -15
  98. package/bundle/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +0 -15
  99. package/bundle/node_modules/undici/lib/llhttp/utils.d.ts +0 -2
  100. package/bundle/node_modules/undici/lib/llhttp/utils.js +0 -15
  101. package/bundle/node_modules/undici/lib/llhttp/utils.js.map +0 -1
  102. package/bundle/node_modules/undici/lib/mock/mock-agent.js +0 -224
  103. package/bundle/node_modules/undici/lib/mock/mock-call-history.js +0 -248
  104. package/bundle/node_modules/undici/lib/mock/mock-client.js +0 -64
  105. package/bundle/node_modules/undici/lib/mock/mock-errors.js +0 -19
  106. package/bundle/node_modules/undici/lib/mock/mock-interceptor.js +0 -209
  107. package/bundle/node_modules/undici/lib/mock/mock-pool.js +0 -64
  108. package/bundle/node_modules/undici/lib/mock/mock-symbols.js +0 -31
  109. package/bundle/node_modules/undici/lib/mock/mock-utils.js +0 -433
  110. package/bundle/node_modules/undici/lib/mock/pending-interceptors-formatter.js +0 -43
  111. package/bundle/node_modules/undici/lib/util/cache.js +0 -368
  112. package/bundle/node_modules/undici/lib/util/date.js +0 -259
  113. package/bundle/node_modules/undici/lib/util/stats.js +0 -32
  114. package/bundle/node_modules/undici/lib/util/timers.js +0 -423
  115. package/bundle/node_modules/undici/lib/web/cache/cache.js +0 -862
  116. package/bundle/node_modules/undici/lib/web/cache/cachestorage.js +0 -152
  117. package/bundle/node_modules/undici/lib/web/cache/util.js +0 -45
  118. package/bundle/node_modules/undici/lib/web/cookies/constants.js +0 -12
  119. package/bundle/node_modules/undici/lib/web/cookies/index.js +0 -199
  120. package/bundle/node_modules/undici/lib/web/cookies/parse.js +0 -322
  121. package/bundle/node_modules/undici/lib/web/cookies/util.js +0 -282
  122. package/bundle/node_modules/undici/lib/web/eventsource/eventsource-stream.js +0 -399
  123. package/bundle/node_modules/undici/lib/web/eventsource/eventsource.js +0 -484
  124. package/bundle/node_modules/undici/lib/web/eventsource/util.js +0 -37
  125. package/bundle/node_modules/undici/lib/web/fetch/LICENSE +0 -21
  126. package/bundle/node_modules/undici/lib/web/fetch/body.js +0 -532
  127. package/bundle/node_modules/undici/lib/web/fetch/constants.js +0 -131
  128. package/bundle/node_modules/undici/lib/web/fetch/data-url.js +0 -744
  129. package/bundle/node_modules/undici/lib/web/fetch/dispatcher-weakref.js +0 -46
  130. package/bundle/node_modules/undici/lib/web/fetch/formdata-parser.js +0 -501
  131. package/bundle/node_modules/undici/lib/web/fetch/formdata.js +0 -263
  132. package/bundle/node_modules/undici/lib/web/fetch/global.js +0 -40
  133. package/bundle/node_modules/undici/lib/web/fetch/headers.js +0 -719
  134. package/bundle/node_modules/undici/lib/web/fetch/index.js +0 -2258
  135. package/bundle/node_modules/undici/lib/web/fetch/request.js +0 -1099
  136. package/bundle/node_modules/undici/lib/web/fetch/response.js +0 -636
  137. package/bundle/node_modules/undici/lib/web/fetch/util.js +0 -1782
  138. package/bundle/node_modules/undici/lib/web/fetch/webidl.js +0 -740
  139. package/bundle/node_modules/undici/lib/web/websocket/connection.js +0 -325
  140. package/bundle/node_modules/undici/lib/web/websocket/constants.js +0 -126
  141. package/bundle/node_modules/undici/lib/web/websocket/events.js +0 -331
  142. package/bundle/node_modules/undici/lib/web/websocket/frame.js +0 -138
  143. package/bundle/node_modules/undici/lib/web/websocket/permessage-deflate.js +0 -70
  144. package/bundle/node_modules/undici/lib/web/websocket/receiver.js +0 -454
  145. package/bundle/node_modules/undici/lib/web/websocket/sender.js +0 -109
  146. package/bundle/node_modules/undici/lib/web/websocket/stream/websocketerror.js +0 -83
  147. package/bundle/node_modules/undici/lib/web/websocket/stream/websocketstream.js +0 -485
  148. package/bundle/node_modules/undici/lib/web/websocket/util.js +0 -338
  149. package/bundle/node_modules/undici/lib/web/websocket/websocket.js +0 -686
  150. package/bundle/node_modules/undici/package.json +0 -149
  151. package/bundle/node_modules/undici/scripts/strip-comments.js +0 -10
  152. package/bundle/node_modules/undici/types/README.md +0 -6
  153. package/bundle/node_modules/undici/types/agent.d.ts +0 -35
  154. package/bundle/node_modules/undici/types/api.d.ts +0 -43
  155. package/bundle/node_modules/undici/types/balanced-pool.d.ts +0 -29
  156. package/bundle/node_modules/undici/types/cache-interceptor.d.ts +0 -172
  157. package/bundle/node_modules/undici/types/cache.d.ts +0 -36
  158. package/bundle/node_modules/undici/types/client-stats.d.ts +0 -15
  159. package/bundle/node_modules/undici/types/client.d.ts +0 -110
  160. package/bundle/node_modules/undici/types/connector.d.ts +0 -34
  161. package/bundle/node_modules/undici/types/content-type.d.ts +0 -21
  162. package/bundle/node_modules/undici/types/cookies.d.ts +0 -30
  163. package/bundle/node_modules/undici/types/diagnostics-channel.d.ts +0 -66
  164. package/bundle/node_modules/undici/types/dispatcher.d.ts +0 -281
  165. package/bundle/node_modules/undici/types/env-http-proxy-agent.d.ts +0 -21
  166. package/bundle/node_modules/undici/types/errors.d.ts +0 -171
  167. package/bundle/node_modules/undici/types/eventsource.d.ts +0 -61
  168. package/bundle/node_modules/undici/types/fetch.d.ts +0 -210
  169. package/bundle/node_modules/undici/types/formdata.d.ts +0 -108
  170. package/bundle/node_modules/undici/types/global-dispatcher.d.ts +0 -9
  171. package/bundle/node_modules/undici/types/global-origin.d.ts +0 -7
  172. package/bundle/node_modules/undici/types/h2c-client.d.ts +0 -75
  173. package/bundle/node_modules/undici/types/handlers.d.ts +0 -15
  174. package/bundle/node_modules/undici/types/header.d.ts +0 -160
  175. package/bundle/node_modules/undici/types/index.d.ts +0 -75
  176. package/bundle/node_modules/undici/types/interceptors.d.ts +0 -34
  177. package/bundle/node_modules/undici/types/mock-agent.d.ts +0 -68
  178. package/bundle/node_modules/undici/types/mock-call-history.d.ts +0 -111
  179. package/bundle/node_modules/undici/types/mock-client.d.ts +0 -25
  180. package/bundle/node_modules/undici/types/mock-errors.d.ts +0 -12
  181. package/bundle/node_modules/undici/types/mock-interceptor.d.ts +0 -93
  182. package/bundle/node_modules/undici/types/mock-pool.d.ts +0 -25
  183. package/bundle/node_modules/undici/types/patch.d.ts +0 -29
  184. package/bundle/node_modules/undici/types/pool-stats.d.ts +0 -19
  185. package/bundle/node_modules/undici/types/pool.d.ts +0 -41
  186. package/bundle/node_modules/undici/types/proxy-agent.d.ts +0 -29
  187. package/bundle/node_modules/undici/types/readable.d.ts +0 -68
  188. package/bundle/node_modules/undici/types/retry-agent.d.ts +0 -8
  189. package/bundle/node_modules/undici/types/retry-handler.d.ts +0 -116
  190. package/bundle/node_modules/undici/types/util.d.ts +0 -18
  191. package/bundle/node_modules/undici/types/utility.d.ts +0 -7
  192. package/bundle/node_modules/undici/types/webidl.d.ts +0 -266
  193. package/bundle/node_modules/undici/types/websocket.d.ts +0 -184
@@ -1,1782 +0,0 @@
1
- 'use strict'
2
-
3
- const { Transform } = require('node:stream')
4
- const zlib = require('node:zlib')
5
- const { redirectStatusSet, referrerPolicyTokens, badPortsSet } = require('./constants')
6
- const { getGlobalOrigin } = require('./global')
7
- const { collectASequenceOfCodePoints, collectAnHTTPQuotedString, removeChars, parseMIMEType } = require('./data-url')
8
- const { performance } = require('node:perf_hooks')
9
- const { ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = require('../../core/util')
10
- const assert = require('node:assert')
11
- const { isUint8Array } = require('node:util/types')
12
- const { webidl } = require('./webidl')
13
-
14
- let supportedHashes = []
15
-
16
- // https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable
17
- /** @type {import('crypto')} */
18
- let crypto
19
- try {
20
- crypto = require('node:crypto')
21
- const possibleRelevantHashes = ['sha256', 'sha384', 'sha512']
22
- supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash))
23
- /* c8 ignore next 3 */
24
- } catch {
25
-
26
- }
27
-
28
- function responseURL (response) {
29
- // https://fetch.spec.whatwg.org/#responses
30
- // A response has an associated URL. It is a pointer to the last URL
31
- // in response’s URL list and null if response’s URL list is empty.
32
- const urlList = response.urlList
33
- const length = urlList.length
34
- return length === 0 ? null : urlList[length - 1].toString()
35
- }
36
-
37
- // https://fetch.spec.whatwg.org/#concept-response-location-url
38
- function responseLocationURL (response, requestFragment) {
39
- // 1. If response’s status is not a redirect status, then return null.
40
- if (!redirectStatusSet.has(response.status)) {
41
- return null
42
- }
43
-
44
- // 2. Let location be the result of extracting header list values given
45
- // `Location` and response’s header list.
46
- let location = response.headersList.get('location', true)
47
-
48
- // 3. If location is a header value, then set location to the result of
49
- // parsing location with response’s URL.
50
- if (location !== null && isValidHeaderValue(location)) {
51
- if (!isValidEncodedURL(location)) {
52
- // Some websites respond location header in UTF-8 form without encoding them as ASCII
53
- // and major browsers redirect them to correctly UTF-8 encoded addresses.
54
- // Here, we handle that behavior in the same way.
55
- location = normalizeBinaryStringToUtf8(location)
56
- }
57
- location = new URL(location, responseURL(response))
58
- }
59
-
60
- // 4. If location is a URL whose fragment is null, then set location’s
61
- // fragment to requestFragment.
62
- if (location && !location.hash) {
63
- location.hash = requestFragment
64
- }
65
-
66
- // 5. Return location.
67
- return location
68
- }
69
-
70
- /**
71
- * @see https://www.rfc-editor.org/rfc/rfc1738#section-2.2
72
- * @param {string} url
73
- * @returns {boolean}
74
- */
75
- function isValidEncodedURL (url) {
76
- for (let i = 0; i < url.length; ++i) {
77
- const code = url.charCodeAt(i)
78
-
79
- if (
80
- code > 0x7E || // Non-US-ASCII + DEL
81
- code < 0x20 // Control characters NUL - US
82
- ) {
83
- return false
84
- }
85
- }
86
- return true
87
- }
88
-
89
- /**
90
- * If string contains non-ASCII characters, assumes it's UTF-8 encoded and decodes it.
91
- * Since UTF-8 is a superset of ASCII, this will work for ASCII strings as well.
92
- * @param {string} value
93
- * @returns {string}
94
- */
95
- function normalizeBinaryStringToUtf8 (value) {
96
- return Buffer.from(value, 'binary').toString('utf8')
97
- }
98
-
99
- /** @returns {URL} */
100
- function requestCurrentURL (request) {
101
- return request.urlList[request.urlList.length - 1]
102
- }
103
-
104
- function requestBadPort (request) {
105
- // 1. Let url be request’s current URL.
106
- const url = requestCurrentURL(request)
107
-
108
- // 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port,
109
- // then return blocked.
110
- if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) {
111
- return 'blocked'
112
- }
113
-
114
- // 3. Return allowed.
115
- return 'allowed'
116
- }
117
-
118
- function isErrorLike (object) {
119
- return object instanceof Error || (
120
- object?.constructor?.name === 'Error' ||
121
- object?.constructor?.name === 'DOMException'
122
- )
123
- }
124
-
125
- // Check whether |statusText| is a ByteString and
126
- // matches the Reason-Phrase token production.
127
- // RFC 2616: https://tools.ietf.org/html/rfc2616
128
- // RFC 7230: https://tools.ietf.org/html/rfc7230
129
- // "reason-phrase = *( HTAB / SP / VCHAR / obs-text )"
130
- // https://github.com/chromium/chromium/blob/94.0.4604.1/third_party/blink/renderer/core/fetch/response.cc#L116
131
- function isValidReasonPhrase (statusText) {
132
- for (let i = 0; i < statusText.length; ++i) {
133
- const c = statusText.charCodeAt(i)
134
- if (
135
- !(
136
- (
137
- c === 0x09 || // HTAB
138
- (c >= 0x20 && c <= 0x7e) || // SP / VCHAR
139
- (c >= 0x80 && c <= 0xff)
140
- ) // obs-text
141
- )
142
- ) {
143
- return false
144
- }
145
- }
146
- return true
147
- }
148
-
149
- /**
150
- * @see https://fetch.spec.whatwg.org/#header-name
151
- * @param {string} potentialValue
152
- */
153
- const isValidHeaderName = isValidHTTPToken
154
-
155
- /**
156
- * @see https://fetch.spec.whatwg.org/#header-value
157
- * @param {string} potentialValue
158
- */
159
- function isValidHeaderValue (potentialValue) {
160
- // - Has no leading or trailing HTTP tab or space bytes.
161
- // - Contains no 0x00 (NUL) or HTTP newline bytes.
162
- return (
163
- potentialValue[0] === '\t' ||
164
- potentialValue[0] === ' ' ||
165
- potentialValue[potentialValue.length - 1] === '\t' ||
166
- potentialValue[potentialValue.length - 1] === ' ' ||
167
- potentialValue.includes('\n') ||
168
- potentialValue.includes('\r') ||
169
- potentialValue.includes('\0')
170
- ) === false
171
- }
172
-
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) {
178
- // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` and response’s header list.
179
- const policyHeader = (actualResponse.headersList.get('referrer-policy', true) ?? '').split(',')
180
-
181
- // 2. Let policy be the empty string.
182
- let policy = ''
183
-
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.
185
-
186
- // Note: As the referrer-policy can contain multiple policies
187
- // separated by comma, we need to loop through all of them
188
- // and pick the first valid one.
189
- // Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#specify_a_fallback_policy
190
- if (policyHeader.length) {
191
- // The right-most policy takes precedence.
192
- // The left-most policy is the fallback.
193
- for (let i = policyHeader.length; i !== 0; i--) {
194
- const token = policyHeader[i - 1].trim()
195
- if (referrerPolicyTokens.has(token)) {
196
- policy = token
197
- break
198
- }
199
- }
200
- }
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
-
219
- // 2. If policy is not the empty string, then set request’s referrer policy to policy.
220
- if (policy !== '') {
221
- request.referrerPolicy = policy
222
- }
223
- }
224
-
225
- // https://fetch.spec.whatwg.org/#cross-origin-resource-policy-check
226
- function crossOriginResourcePolicyCheck () {
227
- // TODO
228
- return 'allowed'
229
- }
230
-
231
- // https://fetch.spec.whatwg.org/#concept-cors-check
232
- function corsCheck () {
233
- // TODO
234
- return 'success'
235
- }
236
-
237
- // https://fetch.spec.whatwg.org/#concept-tao-check
238
- function TAOCheck () {
239
- // TODO
240
- return 'success'
241
- }
242
-
243
- function appendFetchMetadata (httpRequest) {
244
- // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-dest-header
245
- // TODO
246
-
247
- // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-mode-header
248
-
249
- // 1. Assert: r’s url is a potentially trustworthy URL.
250
- // TODO
251
-
252
- // 2. Let header be a Structured Header whose value is a token.
253
- let header = null
254
-
255
- // 3. Set header’s value to r’s mode.
256
- header = httpRequest.mode
257
-
258
- // 4. Set a structured field value `Sec-Fetch-Mode`/header in r’s header list.
259
- httpRequest.headersList.set('sec-fetch-mode', header, true)
260
-
261
- // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header
262
- // TODO
263
-
264
- // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-user-header
265
- // TODO
266
- }
267
-
268
- // https://fetch.spec.whatwg.org/#append-a-request-origin-header
269
- function appendRequestOriginHeader (request) {
270
- // 1. Let serializedOrigin be the result of byte-serializing a request origin
271
- // with request.
272
- // TODO: implement "byte-serializing a request origin"
273
- let serializedOrigin = request.origin
274
-
275
- // - "'client' is changed to an origin during fetching."
276
- // This doesn't happen in undici (in most cases) because undici, by default,
277
- // has no concept of origin.
278
- // - request.origin can also be set to request.client.origin (client being
279
- // an environment settings object), which is undefined without using
280
- // setGlobalOrigin.
281
- if (serializedOrigin === 'client' || serializedOrigin === undefined) {
282
- return
283
- }
284
-
285
- // 2. If request’s response tainting is "cors" or request’s mode is "websocket",
286
- // then append (`Origin`, serializedOrigin) to request’s header list.
287
- // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then:
288
- if (request.responseTainting === 'cors' || request.mode === 'websocket') {
289
- request.headersList.append('origin', serializedOrigin, true)
290
- } else if (request.method !== 'GET' && request.method !== 'HEAD') {
291
- // 1. Switch on request’s referrer policy:
292
- switch (request.referrerPolicy) {
293
- case 'no-referrer':
294
- // Set serializedOrigin to `null`.
295
- serializedOrigin = null
296
- break
297
- case 'no-referrer-when-downgrade':
298
- case 'strict-origin':
299
- case 'strict-origin-when-cross-origin':
300
- // If request’s origin is a tuple origin, its scheme is "https", and
301
- // request’s current URL’s scheme is not "https", then set
302
- // serializedOrigin to `null`.
303
- if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) {
304
- serializedOrigin = null
305
- }
306
- break
307
- case 'same-origin':
308
- // If request’s origin is not same origin with request’s current URL’s
309
- // origin, then set serializedOrigin to `null`.
310
- if (!sameOrigin(request, requestCurrentURL(request))) {
311
- serializedOrigin = null
312
- }
313
- break
314
- default:
315
- // Do nothing.
316
- }
317
-
318
- // 2. Append (`Origin`, serializedOrigin) to request’s header list.
319
- request.headersList.append('origin', serializedOrigin, true)
320
- }
321
- }
322
-
323
- // https://w3c.github.io/hr-time/#dfn-coarsen-time
324
- function coarsenTime (timestamp, crossOriginIsolatedCapability) {
325
- // TODO
326
- return timestamp
327
- }
328
-
329
- // https://fetch.spec.whatwg.org/#clamp-and-coarsen-connection-timing-info
330
- function clampAndCoarsenConnectionTimingInfo (connectionTimingInfo, defaultStartTime, crossOriginIsolatedCapability) {
331
- if (!connectionTimingInfo?.startTime || connectionTimingInfo.startTime < defaultStartTime) {
332
- return {
333
- domainLookupStartTime: defaultStartTime,
334
- domainLookupEndTime: defaultStartTime,
335
- connectionStartTime: defaultStartTime,
336
- connectionEndTime: defaultStartTime,
337
- secureConnectionStartTime: defaultStartTime,
338
- ALPNNegotiatedProtocol: connectionTimingInfo?.ALPNNegotiatedProtocol
339
- }
340
- }
341
-
342
- return {
343
- domainLookupStartTime: coarsenTime(connectionTimingInfo.domainLookupStartTime, crossOriginIsolatedCapability),
344
- domainLookupEndTime: coarsenTime(connectionTimingInfo.domainLookupEndTime, crossOriginIsolatedCapability),
345
- connectionStartTime: coarsenTime(connectionTimingInfo.connectionStartTime, crossOriginIsolatedCapability),
346
- connectionEndTime: coarsenTime(connectionTimingInfo.connectionEndTime, crossOriginIsolatedCapability),
347
- secureConnectionStartTime: coarsenTime(connectionTimingInfo.secureConnectionStartTime, crossOriginIsolatedCapability),
348
- ALPNNegotiatedProtocol: connectionTimingInfo.ALPNNegotiatedProtocol
349
- }
350
- }
351
-
352
- // https://w3c.github.io/hr-time/#dfn-coarsened-shared-current-time
353
- function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) {
354
- return coarsenTime(performance.now(), crossOriginIsolatedCapability)
355
- }
356
-
357
- // https://fetch.spec.whatwg.org/#create-an-opaque-timing-info
358
- function createOpaqueTimingInfo (timingInfo) {
359
- return {
360
- startTime: timingInfo.startTime ?? 0,
361
- redirectStartTime: 0,
362
- redirectEndTime: 0,
363
- postRedirectStartTime: timingInfo.startTime ?? 0,
364
- finalServiceWorkerStartTime: 0,
365
- finalNetworkResponseStartTime: 0,
366
- finalNetworkRequestStartTime: 0,
367
- endTime: 0,
368
- encodedBodySize: 0,
369
- decodedBodySize: 0,
370
- finalConnectionTimingInfo: null
371
- }
372
- }
373
-
374
- // https://html.spec.whatwg.org/multipage/origin.html#policy-container
375
- function makePolicyContainer () {
376
- // Note: the fetch spec doesn't make use of embedder policy or CSP list
377
- return {
378
- referrerPolicy: 'strict-origin-when-cross-origin'
379
- }
380
- }
381
-
382
- // https://html.spec.whatwg.org/multipage/origin.html#clone-a-policy-container
383
- function clonePolicyContainer (policyContainer) {
384
- return {
385
- referrerPolicy: policyContainer.referrerPolicy
386
- }
387
- }
388
-
389
- /**
390
- * Determine request’s Referrer
391
- *
392
- * @see https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
393
- */
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
-
399
- // 1. Let policy be request's referrer policy.
400
- const policy = request.referrerPolicy
401
-
402
- // Note: policy cannot (shouldn't) be null or an empty string.
403
- assert(policy)
404
-
405
- // 2. Let environment be request’s client.
406
-
407
- let referrerSource = null
408
-
409
- // 3. Switch on request’s referrer:
410
-
411
- // "client"
412
- if (request.referrer === 'client') {
413
- // Note: node isn't a browser and doesn't implement document/iframes,
414
- // so we bypass this step and replace it with our own.
415
-
416
- const globalOrigin = getGlobalOrigin()
417
-
418
- if (!globalOrigin || globalOrigin.origin === 'null') {
419
- return 'no-referrer'
420
- }
421
-
422
- // Note: we need to clone it as it's mutated
423
- referrerSource = new URL(globalOrigin)
424
- // a URL
425
- } else if (webidl.is.URL(request.referrer)) {
426
- // Let referrerSource be request’s referrer.
427
- referrerSource = request.referrer
428
- }
429
-
430
- // 4. Let request’s referrerURL be the result of stripping referrerSource for
431
- // use as a referrer.
432
- let referrerURL = stripURLForReferrer(referrerSource)
433
-
434
- // 5. Let referrerOrigin be the result of stripping referrerSource for use as
435
- // a referrer, with the origin-only flag set to true.
436
- const referrerOrigin = stripURLForReferrer(referrerSource, true)
437
-
438
- // 6. If the result of serializing referrerURL is a string whose length is
439
- // greater than 4096, set referrerURL to referrerOrigin.
440
- if (referrerURL.toString().length > 4096) {
441
- referrerURL = referrerOrigin
442
- }
443
-
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.
448
-
449
- // 8. Execute the switch statements corresponding to the value of policy:
450
- switch (policy) {
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
- }
475
- case 'strict-origin-when-cross-origin': {
476
- const currentURL = requestCurrentURL(request)
477
-
478
- // 1. If the origin of referrerURL and the origin of request’s current
479
- // URL are the same, then return referrerURL.
480
- if (sameOrigin(referrerURL, currentURL)) {
481
- return referrerURL
482
- }
483
-
484
- // 2. If referrerURL is a potentially trustworthy URL and request’s
485
- // current URL is not a potentially trustworthy URL, then return no
486
- // referrer.
487
- if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) {
488
- return 'no-referrer'
489
- }
490
-
491
- // 3. Return referrerOrigin.
492
- return referrerOrigin
493
- }
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
- }
522
- }
523
- }
524
-
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
- *
533
- * @see https://w3c.github.io/webappsec-referrer-policy/#strip-url
534
- * @param {URL} url
535
- * @param {boolean} [originOnly=false]
536
- */
537
- function stripURLForReferrer (url, originOnly = false) {
538
- // 1. Assert: url is a URL.
539
- assert(webidl.is.URL(url))
540
-
541
- // Note: Create a new URL instance to avoid mutating the original URL.
542
- url = new URL(url)
543
-
544
- // 2. If url’s scheme is a local scheme, then return no referrer.
545
- if (urlIsLocal(url)) {
546
- return 'no-referrer'
547
- }
548
-
549
- // 3. Set url’s username to the empty string.
550
- url.username = ''
551
-
552
- // 4. Set url’s password to the empty string.
553
- url.password = ''
554
-
555
- // 5. Set url’s fragment to null.
556
- url.hash = ''
557
-
558
- // 6. If the origin-only flag is true, then:
559
- if (originOnly === true) {
560
- // 1. Set url’s path to « the empty string ».
561
- url.pathname = ''
562
-
563
- // 2. Set url’s query to null.
564
- url.search = ''
565
- }
566
-
567
- // 7. Return url.
568
- return url
569
- }
570
-
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') {
617
- return false
618
- }
619
-
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:') {
626
- return true
627
- }
628
-
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
- }
634
-
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:
637
-
638
- // origin’s host is "localhost" or "localhost."
639
- if (origin.hostname === 'localhost' || origin.hostname === 'localhost.') {
640
- return true
641
- }
642
-
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
- }
652
-
653
- // 7. If origin’s scheme component is one which the user agent considers to
654
- // be authenticated, return "Potentially Trustworthy".
655
-
656
- // 8. If origin has been configured as a trustworthy origin, return
657
- // "Potentially Trustworthy".
658
-
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)) {
679
- return false
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)
699
- }
700
-
701
- /**
702
- * @see https://w3c.github.io/webappsec-subresource-integrity/#does-response-match-metadatalist
703
- * @param {Uint8Array} bytes
704
- * @param {string} metadataList
705
- */
706
- function bytesMatch (bytes, metadataList) {
707
- // If node is not built with OpenSSL support, we cannot check
708
- // a request's integrity, so allow it by default (the spec will
709
- // allow requests if an invalid hash is given, as precedence).
710
- /* istanbul ignore if: only if node is built with --without-ssl */
711
- if (crypto === undefined) {
712
- return true
713
- }
714
-
715
- // 1. Let parsedMetadata be the result of parsing metadataList.
716
- const parsedMetadata = parseMetadata(metadataList)
717
-
718
- // 2. If parsedMetadata is no metadata, return true.
719
- if (parsedMetadata === 'no metadata') {
720
- return true
721
- }
722
-
723
- // 3. If response is not eligible for integrity validation, return false.
724
- // TODO
725
-
726
- // 4. If parsedMetadata is the empty set, return true.
727
- if (parsedMetadata.length === 0) {
728
- return true
729
- }
730
-
731
- // 5. Let metadata be the result of getting the strongest
732
- // metadata from parsedMetadata.
733
- const strongest = getStrongestMetadata(parsedMetadata)
734
- const metadata = filterMetadataListByAlgorithm(parsedMetadata, strongest)
735
-
736
- // 6. For each item in metadata:
737
- for (const item of metadata) {
738
- // 1. Let algorithm be the alg component of item.
739
- const algorithm = item.algo
740
-
741
- // 2. Let expectedValue be the val component of item.
742
- const expectedValue = item.hash
743
-
744
- // See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e
745
- // "be liberal with padding". This is annoying, and it's not even in the spec.
746
-
747
- // 3. Let actualValue be the result of applying algorithm to bytes.
748
- let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64')
749
-
750
- if (actualValue[actualValue.length - 1] === '=') {
751
- if (actualValue[actualValue.length - 2] === '=') {
752
- actualValue = actualValue.slice(0, -2)
753
- } else {
754
- actualValue = actualValue.slice(0, -1)
755
- }
756
- }
757
-
758
- // 4. If actualValue is a case-sensitive match for expectedValue,
759
- // return true.
760
- if (compareBase64Mixed(actualValue, expectedValue)) {
761
- return true
762
- }
763
- }
764
-
765
- // 7. Return false.
766
- return false
767
- }
768
-
769
- // https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options
770
- // https://www.w3.org/TR/CSP2/#source-list-syntax
771
- // https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1
772
- const parseHashWithOptions = /(?<algo>sha256|sha384|sha512)-((?<hash>[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i
773
-
774
- /**
775
- * @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata
776
- * @param {string} metadata
777
- */
778
- function parseMetadata (metadata) {
779
- // 1. Let result be the empty set.
780
- /** @type {{ algo: string, hash: string }[]} */
781
- const result = []
782
-
783
- // 2. Let empty be equal to true.
784
- let empty = true
785
-
786
- // 3. For each token returned by splitting metadata on spaces:
787
- for (const token of metadata.split(' ')) {
788
- // 1. Set empty to false.
789
- empty = false
790
-
791
- // 2. Parse token as a hash-with-options.
792
- const parsedToken = parseHashWithOptions.exec(token)
793
-
794
- // 3. If token does not parse, continue to the next token.
795
- if (
796
- parsedToken === null ||
797
- parsedToken.groups === undefined ||
798
- parsedToken.groups.algo === undefined
799
- ) {
800
- // Note: Chromium blocks the request at this point, but Firefox
801
- // gives a warning that an invalid integrity was given. The
802
- // correct behavior is to ignore these, and subsequently not
803
- // check the integrity of the resource.
804
- continue
805
- }
806
-
807
- // 4. Let algorithm be the hash-algo component of token.
808
- const algorithm = parsedToken.groups.algo.toLowerCase()
809
-
810
- // 5. If algorithm is a hash function recognized by the user
811
- // agent, add the parsed token to result.
812
- if (supportedHashes.includes(algorithm)) {
813
- result.push(parsedToken.groups)
814
- }
815
- }
816
-
817
- // 4. Return no metadata if empty is true, otherwise return result.
818
- if (empty === true) {
819
- return 'no metadata'
820
- }
821
-
822
- return result
823
- }
824
-
825
- /**
826
- * @param {{ algo: 'sha256' | 'sha384' | 'sha512' }[]} metadataList
827
- */
828
- function getStrongestMetadata (metadataList) {
829
- // Let algorithm be the algo component of the first item in metadataList.
830
- // Can be sha256
831
- let algorithm = metadataList[0].algo
832
- // If the algorithm is sha512, then it is the strongest
833
- // and we can return immediately
834
- if (algorithm[3] === '5') {
835
- return algorithm
836
- }
837
-
838
- for (let i = 1; i < metadataList.length; ++i) {
839
- const metadata = metadataList[i]
840
- // If the algorithm is sha512, then it is the strongest
841
- // and we can break the loop immediately
842
- if (metadata.algo[3] === '5') {
843
- algorithm = 'sha512'
844
- break
845
- // If the algorithm is sha384, then a potential sha256 or sha384 is ignored
846
- } else if (algorithm[3] === '3') {
847
- continue
848
- // algorithm is sha256, check if algorithm is sha384 and if so, set it as
849
- // the strongest
850
- } else if (metadata.algo[3] === '3') {
851
- algorithm = 'sha384'
852
- }
853
- }
854
- return algorithm
855
- }
856
-
857
- function filterMetadataListByAlgorithm (metadataList, algorithm) {
858
- if (metadataList.length === 1) {
859
- return metadataList
860
- }
861
-
862
- let pos = 0
863
- for (let i = 0; i < metadataList.length; ++i) {
864
- if (metadataList[i].algo === algorithm) {
865
- metadataList[pos++] = metadataList[i]
866
- }
867
- }
868
-
869
- metadataList.length = pos
870
-
871
- return metadataList
872
- }
873
-
874
- /**
875
- * Compares two base64 strings, allowing for base64url
876
- * in the second string.
877
- *
878
- * @param {string} actualValue always base64
879
- * @param {string} expectedValue base64 or base64url
880
- * @returns {boolean}
881
- */
882
- function compareBase64Mixed (actualValue, expectedValue) {
883
- if (actualValue.length !== expectedValue.length) {
884
- return false
885
- }
886
- for (let i = 0; i < actualValue.length; ++i) {
887
- if (actualValue[i] !== expectedValue[i]) {
888
- if (
889
- (actualValue[i] === '+' && expectedValue[i] === '-') ||
890
- (actualValue[i] === '/' && expectedValue[i] === '_')
891
- ) {
892
- continue
893
- }
894
- return false
895
- }
896
- }
897
-
898
- return true
899
- }
900
-
901
- // https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request
902
- function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) {
903
- // TODO
904
- }
905
-
906
- /**
907
- * @link {https://html.spec.whatwg.org/multipage/origin.html#same-origin}
908
- * @param {URL} A
909
- * @param {URL} B
910
- */
911
- function sameOrigin (A, B) {
912
- // 1. If A and B are the same opaque origin, then return true.
913
- if (A.origin === B.origin && A.origin === 'null') {
914
- return true
915
- }
916
-
917
- // 2. If A and B are both tuple origins and their schemes,
918
- // hosts, and port are identical, then return true.
919
- if (A.protocol === B.protocol && A.hostname === B.hostname && A.port === B.port) {
920
- return true
921
- }
922
-
923
- // 3. Return false.
924
- return false
925
- }
926
-
927
- function createDeferredPromise () {
928
- let res
929
- let rej
930
- const promise = new Promise((resolve, reject) => {
931
- res = resolve
932
- rej = reject
933
- })
934
-
935
- return { promise, resolve: res, reject: rej }
936
- }
937
-
938
- function isAborted (fetchParams) {
939
- return fetchParams.controller.state === 'aborted'
940
- }
941
-
942
- function isCancelled (fetchParams) {
943
- return fetchParams.controller.state === 'aborted' ||
944
- fetchParams.controller.state === 'terminated'
945
- }
946
-
947
- /**
948
- * @see https://fetch.spec.whatwg.org/#concept-method-normalize
949
- * @param {string} method
950
- */
951
- function normalizeMethod (method) {
952
- return normalizedMethodRecordsBase[method.toLowerCase()] ?? method
953
- }
954
-
955
- // https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string
956
- function serializeJavascriptValueToJSONString (value) {
957
- // 1. Let result be ? Call(%JSON.stringify%, undefined, « value »).
958
- const result = JSON.stringify(value)
959
-
960
- // 2. If result is undefined, then throw a TypeError.
961
- if (result === undefined) {
962
- throw new TypeError('Value is not JSON serializable')
963
- }
964
-
965
- // 3. Assert: result is a string.
966
- assert(typeof result === 'string')
967
-
968
- // 4. Return result.
969
- return result
970
- }
971
-
972
- // https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object
973
- const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))
974
-
975
- /**
976
- * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
977
- * @param {string} name name of the instance
978
- * @param {((target: any) => any)} kInternalIterator
979
- * @param {string | number} [keyIndex]
980
- * @param {string | number} [valueIndex]
981
- */
982
- function createIterator (name, kInternalIterator, keyIndex = 0, valueIndex = 1) {
983
- class FastIterableIterator {
984
- /** @type {any} */
985
- #target
986
- /** @type {'key' | 'value' | 'key+value'} */
987
- #kind
988
- /** @type {number} */
989
- #index
990
-
991
- /**
992
- * @see https://webidl.spec.whatwg.org/#dfn-default-iterator-object
993
- * @param {unknown} target
994
- * @param {'key' | 'value' | 'key+value'} kind
995
- */
996
- constructor (target, kind) {
997
- this.#target = target
998
- this.#kind = kind
999
- this.#index = 0
1000
- }
1001
-
1002
- next () {
1003
- // 1. Let interface be the interface for which the iterator prototype object exists.
1004
- // 2. Let thisValue be the this value.
1005
- // 3. Let object be ? ToObject(thisValue).
1006
- // 4. If object is a platform object, then perform a security
1007
- // check, passing:
1008
- // 5. If object is not a default iterator object for interface,
1009
- // then throw a TypeError.
1010
- if (typeof this !== 'object' || this === null || !(#target in this)) {
1011
- throw new TypeError(
1012
- `'next' called on an object that does not implement interface ${name} Iterator.`
1013
- )
1014
- }
1015
-
1016
- // 6. Let index be object’s index.
1017
- // 7. Let kind be object’s kind.
1018
- // 8. Let values be object’s target's value pairs to iterate over.
1019
- const index = this.#index
1020
- const values = kInternalIterator(this.#target)
1021
-
1022
- // 9. Let len be the length of values.
1023
- const len = values.length
1024
-
1025
- // 10. If index is greater than or equal to len, then return
1026
- // CreateIterResultObject(undefined, true).
1027
- if (index >= len) {
1028
- return {
1029
- value: undefined,
1030
- done: true
1031
- }
1032
- }
1033
-
1034
- // 11. Let pair be the entry in values at index index.
1035
- const { [keyIndex]: key, [valueIndex]: value } = values[index]
1036
-
1037
- // 12. Set object’s index to index + 1.
1038
- this.#index = index + 1
1039
-
1040
- // 13. Return the iterator result for pair and kind.
1041
-
1042
- // https://webidl.spec.whatwg.org/#iterator-result
1043
-
1044
- // 1. Let result be a value determined by the value of kind:
1045
- let result
1046
- switch (this.#kind) {
1047
- case 'key':
1048
- // 1. Let idlKey be pair’s key.
1049
- // 2. Let key be the result of converting idlKey to an
1050
- // ECMAScript value.
1051
- // 3. result is key.
1052
- result = key
1053
- break
1054
- case 'value':
1055
- // 1. Let idlValue be pair’s value.
1056
- // 2. Let value be the result of converting idlValue to
1057
- // an ECMAScript value.
1058
- // 3. result is value.
1059
- result = value
1060
- break
1061
- case 'key+value':
1062
- // 1. Let idlKey be pair’s key.
1063
- // 2. Let idlValue be pair’s value.
1064
- // 3. Let key be the result of converting idlKey to an
1065
- // ECMAScript value.
1066
- // 4. Let value be the result of converting idlValue to
1067
- // an ECMAScript value.
1068
- // 5. Let array be ! ArrayCreate(2).
1069
- // 6. Call ! CreateDataProperty(array, "0", key).
1070
- // 7. Call ! CreateDataProperty(array, "1", value).
1071
- // 8. result is array.
1072
- result = [key, value]
1073
- break
1074
- }
1075
-
1076
- // 2. Return CreateIterResultObject(result, false).
1077
- return {
1078
- value: result,
1079
- done: false
1080
- }
1081
- }
1082
- }
1083
-
1084
- // https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
1085
- // @ts-ignore
1086
- delete FastIterableIterator.prototype.constructor
1087
-
1088
- Object.setPrototypeOf(FastIterableIterator.prototype, esIteratorPrototype)
1089
-
1090
- Object.defineProperties(FastIterableIterator.prototype, {
1091
- [Symbol.toStringTag]: {
1092
- writable: false,
1093
- enumerable: false,
1094
- configurable: true,
1095
- value: `${name} Iterator`
1096
- },
1097
- next: { writable: true, enumerable: true, configurable: true }
1098
- })
1099
-
1100
- /**
1101
- * @param {unknown} target
1102
- * @param {'key' | 'value' | 'key+value'} kind
1103
- * @returns {IterableIterator<any>}
1104
- */
1105
- return function (target, kind) {
1106
- return new FastIterableIterator(target, kind)
1107
- }
1108
- }
1109
-
1110
- /**
1111
- * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
1112
- * @param {string} name name of the instance
1113
- * @param {any} object class
1114
- * @param {(target: any) => any} kInternalIterator
1115
- * @param {string | number} [keyIndex]
1116
- * @param {string | number} [valueIndex]
1117
- */
1118
- function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, valueIndex = 1) {
1119
- const makeIterator = createIterator(name, kInternalIterator, keyIndex, valueIndex)
1120
-
1121
- const properties = {
1122
- keys: {
1123
- writable: true,
1124
- enumerable: true,
1125
- configurable: true,
1126
- value: function keys () {
1127
- webidl.brandCheck(this, object)
1128
- return makeIterator(this, 'key')
1129
- }
1130
- },
1131
- values: {
1132
- writable: true,
1133
- enumerable: true,
1134
- configurable: true,
1135
- value: function values () {
1136
- webidl.brandCheck(this, object)
1137
- return makeIterator(this, 'value')
1138
- }
1139
- },
1140
- entries: {
1141
- writable: true,
1142
- enumerable: true,
1143
- configurable: true,
1144
- value: function entries () {
1145
- webidl.brandCheck(this, object)
1146
- return makeIterator(this, 'key+value')
1147
- }
1148
- },
1149
- forEach: {
1150
- writable: true,
1151
- enumerable: true,
1152
- configurable: true,
1153
- value: function forEach (callbackfn, thisArg = globalThis) {
1154
- webidl.brandCheck(this, object)
1155
- webidl.argumentLengthCheck(arguments, 1, `${name}.forEach`)
1156
- if (typeof callbackfn !== 'function') {
1157
- throw new TypeError(
1158
- `Failed to execute 'forEach' on '${name}': parameter 1 is not of type 'Function'.`
1159
- )
1160
- }
1161
- for (const { 0: key, 1: value } of makeIterator(this, 'key+value')) {
1162
- callbackfn.call(thisArg, value, key, this)
1163
- }
1164
- }
1165
- }
1166
- }
1167
-
1168
- return Object.defineProperties(object.prototype, {
1169
- ...properties,
1170
- [Symbol.iterator]: {
1171
- writable: true,
1172
- enumerable: false,
1173
- configurable: true,
1174
- value: properties.entries.value
1175
- }
1176
- })
1177
- }
1178
-
1179
- /**
1180
- * @see https://fetch.spec.whatwg.org/#body-fully-read
1181
- */
1182
- function fullyReadBody (body, processBody, processBodyError) {
1183
- // 1. If taskDestination is null, then set taskDestination to
1184
- // the result of starting a new parallel queue.
1185
-
1186
- // 2. Let successSteps given a byte sequence bytes be to queue a
1187
- // fetch task to run processBody given bytes, with taskDestination.
1188
- const successSteps = processBody
1189
-
1190
- // 3. Let errorSteps be to queue a fetch task to run processBodyError,
1191
- // with taskDestination.
1192
- const errorSteps = processBodyError
1193
-
1194
- // 4. Let reader be the result of getting a reader for body’s stream.
1195
- // If that threw an exception, then run errorSteps with that
1196
- // exception and return.
1197
- let reader
1198
-
1199
- try {
1200
- reader = body.stream.getReader()
1201
- } catch (e) {
1202
- errorSteps(e)
1203
- return
1204
- }
1205
-
1206
- // 5. Read all bytes from reader, given successSteps and errorSteps.
1207
- readAllBytes(reader, successSteps, errorSteps)
1208
- }
1209
-
1210
- /**
1211
- * @param {ReadableStreamController<Uint8Array>} controller
1212
- */
1213
- function readableStreamClose (controller) {
1214
- try {
1215
- controller.close()
1216
- controller.byobRequest?.respond(0)
1217
- } catch (err) {
1218
- // TODO: add comment explaining why this error occurs.
1219
- if (!err.message.includes('Controller is already closed') && !err.message.includes('ReadableStream is already closed')) {
1220
- throw err
1221
- }
1222
- }
1223
- }
1224
-
1225
- const invalidIsomorphicEncodeValueRegex = /[^\x00-\xFF]/ // eslint-disable-line
1226
-
1227
- /**
1228
- * @see https://infra.spec.whatwg.org/#isomorphic-encode
1229
- * @param {string} input
1230
- */
1231
- function isomorphicEncode (input) {
1232
- // 1. Assert: input contains no code points greater than U+00FF.
1233
- assert(!invalidIsomorphicEncodeValueRegex.test(input))
1234
-
1235
- // 2. Return a byte sequence whose length is equal to input’s code
1236
- // point length and whose bytes have the same values as the
1237
- // values of input’s code points, in the same order
1238
- return input
1239
- }
1240
-
1241
- /**
1242
- * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes
1243
- * @see https://streams.spec.whatwg.org/#read-loop
1244
- * @param {ReadableStreamDefaultReader} reader
1245
- * @param {(bytes: Uint8Array) => void} successSteps
1246
- * @param {(error: Error) => void} failureSteps
1247
- */
1248
- async function readAllBytes (reader, successSteps, failureSteps) {
1249
- const bytes = []
1250
- let byteLength = 0
1251
-
1252
- try {
1253
- do {
1254
- const { done, value: chunk } = await reader.read()
1255
-
1256
- if (done) {
1257
- // 1. Call successSteps with bytes.
1258
- successSteps(Buffer.concat(bytes, byteLength))
1259
- return
1260
- }
1261
-
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
- }
1268
-
1269
- // 2. Append the bytes represented by chunk to bytes.
1270
- bytes.push(chunk)
1271
- byteLength += chunk.length
1272
-
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)
1278
- }
1279
- }
1280
-
1281
- /**
1282
- * @see https://fetch.spec.whatwg.org/#is-local
1283
- * @param {URL} url
1284
- * @returns {boolean}
1285
- */
1286
- function urlIsLocal (url) {
1287
- assert('protocol' in url) // ensure it's a url object
1288
-
1289
- const protocol = url.protocol
1290
-
1291
- // A URL is local if its scheme is a local scheme.
1292
- // A local scheme is "about", "blob", or "data".
1293
- return protocol === 'about:' || protocol === 'blob:' || protocol === 'data:'
1294
- }
1295
-
1296
- /**
1297
- * @param {string|URL} url
1298
- * @returns {boolean}
1299
- */
1300
- function urlHasHttpsScheme (url) {
1301
- return (
1302
- (
1303
- typeof url === 'string' &&
1304
- url[5] === ':' &&
1305
- url[0] === 'h' &&
1306
- url[1] === 't' &&
1307
- url[2] === 't' &&
1308
- url[3] === 'p' &&
1309
- url[4] === 's'
1310
- ) ||
1311
- url.protocol === 'https:'
1312
- )
1313
- }
1314
-
1315
- /**
1316
- * @see https://fetch.spec.whatwg.org/#http-scheme
1317
- * @param {URL} url
1318
- */
1319
- function urlIsHttpHttpsScheme (url) {
1320
- assert('protocol' in url) // ensure it's a url object
1321
-
1322
- const protocol = url.protocol
1323
-
1324
- return protocol === 'http:' || protocol === 'https:'
1325
- }
1326
-
1327
- /**
1328
- * @see https://fetch.spec.whatwg.org/#simple-range-header-value
1329
- * @param {string} value
1330
- * @param {boolean} allowWhitespace
1331
- */
1332
- function simpleRangeHeaderValue (value, allowWhitespace) {
1333
- // 1. Let data be the isomorphic decoding of value.
1334
- // Note: isomorphic decoding takes a sequence of bytes (ie. a Uint8Array) and turns it into a string,
1335
- // nothing more. We obviously don't need to do that if value is a string already.
1336
- const data = value
1337
-
1338
- // 2. If data does not start with "bytes", then return failure.
1339
- if (!data.startsWith('bytes')) {
1340
- return 'failure'
1341
- }
1342
-
1343
- // 3. Let position be a position variable for data, initially pointing at the 5th code point of data.
1344
- const position = { position: 5 }
1345
-
1346
- // 4. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space,
1347
- // from data given position.
1348
- if (allowWhitespace) {
1349
- collectASequenceOfCodePoints(
1350
- (char) => char === '\t' || char === ' ',
1351
- data,
1352
- position
1353
- )
1354
- }
1355
-
1356
- // 5. If the code point at position within data is not U+003D (=), then return failure.
1357
- if (data.charCodeAt(position.position) !== 0x3D) {
1358
- return 'failure'
1359
- }
1360
-
1361
- // 6. Advance position by 1.
1362
- position.position++
1363
-
1364
- // 7. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space, from
1365
- // data given position.
1366
- if (allowWhitespace) {
1367
- collectASequenceOfCodePoints(
1368
- (char) => char === '\t' || char === ' ',
1369
- data,
1370
- position
1371
- )
1372
- }
1373
-
1374
- // 8. Let rangeStart be the result of collecting a sequence of code points that are ASCII digits,
1375
- // from data given position.
1376
- const rangeStart = collectASequenceOfCodePoints(
1377
- (char) => {
1378
- const code = char.charCodeAt(0)
1379
-
1380
- return code >= 0x30 && code <= 0x39
1381
- },
1382
- data,
1383
- position
1384
- )
1385
-
1386
- // 9. Let rangeStartValue be rangeStart, interpreted as decimal number, if rangeStart is not the
1387
- // empty string; otherwise null.
1388
- const rangeStartValue = rangeStart.length ? Number(rangeStart) : null
1389
-
1390
- // 10. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space,
1391
- // from data given position.
1392
- if (allowWhitespace) {
1393
- collectASequenceOfCodePoints(
1394
- (char) => char === '\t' || char === ' ',
1395
- data,
1396
- position
1397
- )
1398
- }
1399
-
1400
- // 11. If the code point at position within data is not U+002D (-), then return failure.
1401
- if (data.charCodeAt(position.position) !== 0x2D) {
1402
- return 'failure'
1403
- }
1404
-
1405
- // 12. Advance position by 1.
1406
- position.position++
1407
-
1408
- // 13. If allowWhitespace is true, collect a sequence of code points that are HTTP tab
1409
- // or space, from data given position.
1410
- // Note from Khafra: its the same step as in #8 again lol
1411
- if (allowWhitespace) {
1412
- collectASequenceOfCodePoints(
1413
- (char) => char === '\t' || char === ' ',
1414
- data,
1415
- position
1416
- )
1417
- }
1418
-
1419
- // 14. Let rangeEnd be the result of collecting a sequence of code points that are
1420
- // ASCII digits, from data given position.
1421
- // Note from Khafra: you wouldn't guess it, but this is also the same step as #8
1422
- const rangeEnd = collectASequenceOfCodePoints(
1423
- (char) => {
1424
- const code = char.charCodeAt(0)
1425
-
1426
- return code >= 0x30 && code <= 0x39
1427
- },
1428
- data,
1429
- position
1430
- )
1431
-
1432
- // 15. Let rangeEndValue be rangeEnd, interpreted as decimal number, if rangeEnd
1433
- // is not the empty string; otherwise null.
1434
- // Note from Khafra: THE SAME STEP, AGAIN!!!
1435
- // Note: why interpret as a decimal if we only collect ascii digits?
1436
- const rangeEndValue = rangeEnd.length ? Number(rangeEnd) : null
1437
-
1438
- // 16. If position is not past the end of data, then return failure.
1439
- if (position.position < data.length) {
1440
- return 'failure'
1441
- }
1442
-
1443
- // 17. If rangeEndValue and rangeStartValue are null, then return failure.
1444
- if (rangeEndValue === null && rangeStartValue === null) {
1445
- return 'failure'
1446
- }
1447
-
1448
- // 18. If rangeStartValue and rangeEndValue are numbers, and rangeStartValue is
1449
- // greater than rangeEndValue, then return failure.
1450
- // Note: ... when can they not be numbers?
1451
- if (rangeStartValue > rangeEndValue) {
1452
- return 'failure'
1453
- }
1454
-
1455
- // 19. Return (rangeStartValue, rangeEndValue).
1456
- return { rangeStartValue, rangeEndValue }
1457
- }
1458
-
1459
- /**
1460
- * @see https://fetch.spec.whatwg.org/#build-a-content-range
1461
- * @param {number} rangeStart
1462
- * @param {number} rangeEnd
1463
- * @param {number} fullLength
1464
- */
1465
- function buildContentRange (rangeStart, rangeEnd, fullLength) {
1466
- // 1. Let contentRange be `bytes `.
1467
- let contentRange = 'bytes '
1468
-
1469
- // 2. Append rangeStart, serialized and isomorphic encoded, to contentRange.
1470
- contentRange += isomorphicEncode(`${rangeStart}`)
1471
-
1472
- // 3. Append 0x2D (-) to contentRange.
1473
- contentRange += '-'
1474
-
1475
- // 4. Append rangeEnd, serialized and isomorphic encoded to contentRange.
1476
- contentRange += isomorphicEncode(`${rangeEnd}`)
1477
-
1478
- // 5. Append 0x2F (/) to contentRange.
1479
- contentRange += '/'
1480
-
1481
- // 6. Append fullLength, serialized and isomorphic encoded to contentRange.
1482
- contentRange += isomorphicEncode(`${fullLength}`)
1483
-
1484
- // 7. Return contentRange.
1485
- return contentRange
1486
- }
1487
-
1488
- // A Stream, which pipes the response to zlib.createInflate() or
1489
- // zlib.createInflateRaw() depending on the first byte of the Buffer.
1490
- // If the lower byte of the first byte is 0x08, then the stream is
1491
- // interpreted as a zlib stream, otherwise it's interpreted as a
1492
- // raw deflate stream.
1493
- class InflateStream extends Transform {
1494
- #zlibOptions
1495
-
1496
- /** @param {zlib.ZlibOptions} [zlibOptions] */
1497
- constructor (zlibOptions) {
1498
- super()
1499
- this.#zlibOptions = zlibOptions
1500
- }
1501
-
1502
- _transform (chunk, encoding, callback) {
1503
- if (!this._inflateStream) {
1504
- if (chunk.length === 0) {
1505
- callback()
1506
- return
1507
- }
1508
- this._inflateStream = (chunk[0] & 0x0F) === 0x08
1509
- ? zlib.createInflate(this.#zlibOptions)
1510
- : zlib.createInflateRaw(this.#zlibOptions)
1511
-
1512
- this._inflateStream.on('data', this.push.bind(this))
1513
- this._inflateStream.on('end', () => this.push(null))
1514
- this._inflateStream.on('error', (err) => this.destroy(err))
1515
- }
1516
-
1517
- this._inflateStream.write(chunk, encoding, callback)
1518
- }
1519
-
1520
- _final (callback) {
1521
- if (this._inflateStream) {
1522
- this._inflateStream.end()
1523
- this._inflateStream = null
1524
- }
1525
- callback()
1526
- }
1527
- }
1528
-
1529
- /**
1530
- * @param {zlib.ZlibOptions} [zlibOptions]
1531
- * @returns {InflateStream}
1532
- */
1533
- function createInflate (zlibOptions) {
1534
- return new InflateStream(zlibOptions)
1535
- }
1536
-
1537
- /**
1538
- * @see https://fetch.spec.whatwg.org/#concept-header-extract-mime-type
1539
- * @param {import('./headers').HeadersList} headers
1540
- */
1541
- function extractMimeType (headers) {
1542
- // 1. Let charset be null.
1543
- let charset = null
1544
-
1545
- // 2. Let essence be null.
1546
- let essence = null
1547
-
1548
- // 3. Let mimeType be null.
1549
- let mimeType = null
1550
-
1551
- // 4. Let values be the result of getting, decoding, and splitting `Content-Type` from headers.
1552
- const values = getDecodeSplit('content-type', headers)
1553
-
1554
- // 5. If values is null, then return failure.
1555
- if (values === null) {
1556
- return 'failure'
1557
- }
1558
-
1559
- // 6. For each value of values:
1560
- for (const value of values) {
1561
- // 6.1. Let temporaryMimeType be the result of parsing value.
1562
- const temporaryMimeType = parseMIMEType(value)
1563
-
1564
- // 6.2. If temporaryMimeType is failure or its essence is "*/*", then continue.
1565
- if (temporaryMimeType === 'failure' || temporaryMimeType.essence === '*/*') {
1566
- continue
1567
- }
1568
-
1569
- // 6.3. Set mimeType to temporaryMimeType.
1570
- mimeType = temporaryMimeType
1571
-
1572
- // 6.4. If mimeType’s essence is not essence, then:
1573
- if (mimeType.essence !== essence) {
1574
- // 6.4.1. Set charset to null.
1575
- charset = null
1576
-
1577
- // 6.4.2. If mimeType’s parameters["charset"] exists, then set charset to
1578
- // mimeType’s parameters["charset"].
1579
- if (mimeType.parameters.has('charset')) {
1580
- charset = mimeType.parameters.get('charset')
1581
- }
1582
-
1583
- // 6.4.3. Set essence to mimeType’s essence.
1584
- essence = mimeType.essence
1585
- } else if (!mimeType.parameters.has('charset') && charset !== null) {
1586
- // 6.5. Otherwise, if mimeType’s parameters["charset"] does not exist, and
1587
- // charset is non-null, set mimeType’s parameters["charset"] to charset.
1588
- mimeType.parameters.set('charset', charset)
1589
- }
1590
- }
1591
-
1592
- // 7. If mimeType is null, then return failure.
1593
- if (mimeType == null) {
1594
- return 'failure'
1595
- }
1596
-
1597
- // 8. Return mimeType.
1598
- return mimeType
1599
- }
1600
-
1601
- /**
1602
- * @see https://fetch.spec.whatwg.org/#header-value-get-decode-and-split
1603
- * @param {string|null} value
1604
- */
1605
- function gettingDecodingSplitting (value) {
1606
- // 1. Let input be the result of isomorphic decoding value.
1607
- const input = value
1608
-
1609
- // 2. Let position be a position variable for input, initially pointing at the start of input.
1610
- const position = { position: 0 }
1611
-
1612
- // 3. Let values be a list of strings, initially empty.
1613
- const values = []
1614
-
1615
- // 4. Let temporaryValue be the empty string.
1616
- let temporaryValue = ''
1617
-
1618
- // 5. While position is not past the end of input:
1619
- while (position.position < input.length) {
1620
- // 5.1. Append the result of collecting a sequence of code points that are not U+0022 (")
1621
- // or U+002C (,) from input, given position, to temporaryValue.
1622
- temporaryValue += collectASequenceOfCodePoints(
1623
- (char) => char !== '"' && char !== ',',
1624
- input,
1625
- position
1626
- )
1627
-
1628
- // 5.2. If position is not past the end of input, then:
1629
- if (position.position < input.length) {
1630
- // 5.2.1. If the code point at position within input is U+0022 ("), then:
1631
- if (input.charCodeAt(position.position) === 0x22) {
1632
- // 5.2.1.1. Append the result of collecting an HTTP quoted string from input, given position, to temporaryValue.
1633
- temporaryValue += collectAnHTTPQuotedString(
1634
- input,
1635
- position
1636
- )
1637
-
1638
- // 5.2.1.2. If position is not past the end of input, then continue.
1639
- if (position.position < input.length) {
1640
- continue
1641
- }
1642
- } else {
1643
- // 5.2.2. Otherwise:
1644
-
1645
- // 5.2.2.1. Assert: the code point at position within input is U+002C (,).
1646
- assert(input.charCodeAt(position.position) === 0x2C)
1647
-
1648
- // 5.2.2.2. Advance position by 1.
1649
- position.position++
1650
- }
1651
- }
1652
-
1653
- // 5.3. Remove all HTTP tab or space from the start and end of temporaryValue.
1654
- temporaryValue = removeChars(temporaryValue, true, true, (char) => char === 0x9 || char === 0x20)
1655
-
1656
- // 5.4. Append temporaryValue to values.
1657
- values.push(temporaryValue)
1658
-
1659
- // 5.6. Set temporaryValue to the empty string.
1660
- temporaryValue = ''
1661
- }
1662
-
1663
- // 6. Return values.
1664
- return values
1665
- }
1666
-
1667
- /**
1668
- * @see https://fetch.spec.whatwg.org/#concept-header-list-get-decode-split
1669
- * @param {string} name lowercase header name
1670
- * @param {import('./headers').HeadersList} list
1671
- */
1672
- function getDecodeSplit (name, list) {
1673
- // 1. Let value be the result of getting name from list.
1674
- const value = list.get(name, true)
1675
-
1676
- // 2. If value is null, then return null.
1677
- if (value === null) {
1678
- return null
1679
- }
1680
-
1681
- // 3. Return the result of getting, decoding, and splitting value.
1682
- return gettingDecodingSplitting(value)
1683
- }
1684
-
1685
- const textDecoder = new TextDecoder()
1686
-
1687
- /**
1688
- * @see https://encoding.spec.whatwg.org/#utf-8-decode
1689
- * @param {Buffer} buffer
1690
- */
1691
- function utf8DecodeBytes (buffer) {
1692
- if (buffer.length === 0) {
1693
- return ''
1694
- }
1695
-
1696
- // 1. Let buffer be the result of peeking three bytes from
1697
- // ioQueue, converted to a byte sequence.
1698
-
1699
- // 2. If buffer is 0xEF 0xBB 0xBF, then read three
1700
- // bytes from ioQueue. (Do nothing with those bytes.)
1701
- if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
1702
- buffer = buffer.subarray(3)
1703
- }
1704
-
1705
- // 3. Process a queue with an instance of UTF-8’s
1706
- // decoder, ioQueue, output, and "replacement".
1707
- const output = textDecoder.decode(buffer)
1708
-
1709
- // 4. Return output.
1710
- return output
1711
- }
1712
-
1713
- class EnvironmentSettingsObjectBase {
1714
- get baseUrl () {
1715
- return getGlobalOrigin()
1716
- }
1717
-
1718
- get origin () {
1719
- return this.baseUrl?.origin
1720
- }
1721
-
1722
- policyContainer = makePolicyContainer()
1723
- }
1724
-
1725
- class EnvironmentSettingsObject {
1726
- settingsObject = new EnvironmentSettingsObjectBase()
1727
- }
1728
-
1729
- const environmentSettingsObject = new EnvironmentSettingsObject()
1730
-
1731
- module.exports = {
1732
- isAborted,
1733
- isCancelled,
1734
- isValidEncodedURL,
1735
- createDeferredPromise,
1736
- ReadableStreamFrom,
1737
- tryUpgradeRequestToAPotentiallyTrustworthyURL,
1738
- clampAndCoarsenConnectionTimingInfo,
1739
- coarsenedSharedCurrentTime,
1740
- determineRequestsReferrer,
1741
- makePolicyContainer,
1742
- clonePolicyContainer,
1743
- appendFetchMetadata,
1744
- appendRequestOriginHeader,
1745
- TAOCheck,
1746
- corsCheck,
1747
- crossOriginResourcePolicyCheck,
1748
- createOpaqueTimingInfo,
1749
- setRequestReferrerPolicyOnRedirect,
1750
- isValidHTTPToken,
1751
- requestBadPort,
1752
- requestCurrentURL,
1753
- responseURL,
1754
- responseLocationURL,
1755
- isURLPotentiallyTrustworthy,
1756
- isValidReasonPhrase,
1757
- sameOrigin,
1758
- normalizeMethod,
1759
- serializeJavascriptValueToJSONString,
1760
- iteratorMixin,
1761
- createIterator,
1762
- isValidHeaderName,
1763
- isValidHeaderValue,
1764
- isErrorLike,
1765
- fullyReadBody,
1766
- bytesMatch,
1767
- readableStreamClose,
1768
- isomorphicEncode,
1769
- urlIsLocal,
1770
- urlHasHttpsScheme,
1771
- urlIsHttpHttpsScheme,
1772
- readAllBytes,
1773
- simpleRangeHeaderValue,
1774
- buildContentRange,
1775
- parseMetadata,
1776
- createInflate,
1777
- extractMimeType,
1778
- getDecodeSplit,
1779
- utf8DecodeBytes,
1780
- environmentSettingsObject,
1781
- isOriginIPPotentiallyTrustworthy
1782
- }