@noodleseed/one 0.22.0 → 0.23.0
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/dist/commands/author-loop.d.ts.map +1 -1
- package/dist/commands/author-loop.js +2 -2
- package/dist/commands/author-loop.js.map +1 -1
- package/dist/commands/catalog-dispatch.d.ts.map +1 -1
- package/dist/commands/catalog-dispatch.js +21 -2
- package/dist/commands/catalog-dispatch.js.map +1 -1
- package/dist/commands/deploy-ops.d.ts.map +1 -1
- package/dist/commands/deploy-ops.js +28 -11
- package/dist/commands/deploy-ops.js.map +1 -1
- package/dist/first-run.d.ts +11 -0
- package/dist/first-run.d.ts.map +1 -1
- package/dist/first-run.js +19 -4
- package/dist/first-run.js.map +1 -1
- package/dist/project-scaffold-templates.d.ts +11 -0
- package/dist/project-scaffold-templates.d.ts.map +1 -0
- package/dist/project-scaffold-templates.js +359 -0
- package/dist/project-scaffold-templates.js.map +1 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +1 -323
- package/dist/project.js.map +1 -1
- package/dist/react.d.ts +2 -2
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/validate.d.ts +12 -0
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +11 -0
- package/dist/validate.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js +6 -9
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/authoring/dist/index.d.ts +3 -3
- package/node_modules/@noodle-borg/authoring/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/index.js +1 -1
- package/node_modules/@noodle-borg/authoring/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react/components.d.ts +302 -7
- package/node_modules/@noodle-borg/authoring/dist/react/components.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react/components.js +39 -7
- package/node_modules/@noodle-borg/authoring/dist/react/components.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react/index.d.ts +4 -2
- package/node_modules/@noodle-borg/authoring/dist/react/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react/index.js +2 -1
- package/node_modules/@noodle-borg/authoring/dist/react/index.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react/semantic-components.d.ts +2618 -0
- package/node_modules/@noodle-borg/authoring/dist/react/semantic-components.d.ts.map +1 -0
- package/node_modules/@noodle-borg/authoring/dist/react/semantic-components.js +110 -0
- package/node_modules/@noodle-borg/authoring/dist/react/semantic-components.js.map +1 -0
- package/node_modules/@noodle-borg/authoring/dist/react.d.ts +2 -2
- package/node_modules/@noodle-borg/authoring/dist/react.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react.js +1 -1
- package/node_modules/@noodle-borg/authoring/dist/react.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/recording.d.ts +1 -1
- package/node_modules/@noodle-borg/authoring/dist/recording.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/recording.js +14 -1
- package/node_modules/@noodle-borg/authoring/dist/recording.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts +25 -2
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.js +7 -3
- package/node_modules/@noodle-borg/authoring/dist/server.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/compile.d.ts.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/compile.js +20 -8
- package/node_modules/@noodle-borg/compiler/dist/compile.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +2 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +6 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js.map +1 -1
- package/node_modules/@noodle-borg/connector-http/package.json +1 -1
- package/node_modules/@noodle-borg/protocol/dist/mapping.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/mapping.js +8 -0
- package/node_modules/@noodle-borg/protocol/dist/mapping.js.map +1 -1
- package/node_modules/hono/dist/adapter/aws-lambda/handler.js +15 -21
- package/node_modules/hono/dist/adapter/bun/websocket.js +3 -1
- package/node_modules/hono/dist/adapter/lambda-edge/handler.js +8 -2
- package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +15 -21
- package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +3 -1
- package/node_modules/hono/dist/cjs/adapter/lambda-edge/handler.js +8 -2
- package/node_modules/hono/dist/cjs/helper/css/common.js +3 -1
- package/node_modules/hono/dist/cjs/helper/css/index.js +9 -1
- package/node_modules/hono/dist/cjs/jsx/base.js +8 -14
- package/node_modules/hono/dist/cjs/jsx/components.js +41 -21
- package/node_modules/hono/dist/cjs/jsx/context.js +131 -5
- package/node_modules/hono/dist/cjs/jsx/streaming.js +9 -7
- package/node_modules/hono/dist/cjs/middleware/cors/index.js +2 -5
- package/node_modules/hono/dist/cjs/middleware/serve-static/index.js +2 -2
- package/node_modules/hono/dist/cjs/utils/body.js +12 -4
- package/node_modules/hono/dist/cjs/utils/buffer.js +2 -1
- package/node_modules/hono/dist/cjs/validator/validator.js +3 -3
- package/node_modules/hono/dist/helper/css/common.js +3 -1
- package/node_modules/hono/dist/helper/css/index.js +9 -1
- package/node_modules/hono/dist/jsx/base.js +15 -15
- package/node_modules/hono/dist/jsx/components.js +42 -22
- package/node_modules/hono/dist/jsx/context.js +129 -5
- package/node_modules/hono/dist/jsx/streaming.js +10 -8
- package/node_modules/hono/dist/middleware/cors/index.js +2 -5
- package/node_modules/hono/dist/middleware/serve-static/index.js +2 -2
- package/node_modules/hono/dist/types/adapter/aws-lambda/handler.d.ts +1 -1
- package/node_modules/hono/dist/types/jsx/base.d.ts +1 -3
- package/node_modules/hono/dist/types/jsx/context.d.ts +39 -0
- package/node_modules/hono/dist/types/middleware/context-storage/index.d.ts +2 -2
- package/node_modules/hono/dist/types/utils/body.d.ts +1 -1
- package/node_modules/hono/dist/utils/body.js +12 -4
- package/node_modules/hono/dist/utils/buffer.js +2 -1
- package/node_modules/hono/dist/validator/validator.js +3 -3
- package/node_modules/hono/package.json +9 -10
- package/node_modules/tailwindcss/dist/chunk-HMCCH6MG.mjs +1 -0
- package/node_modules/tailwindcss/dist/default-theme.mjs +1 -1
- package/node_modules/tailwindcss/dist/lib.js +13 -13
- package/node_modules/tailwindcss/dist/lib.mjs +18 -18
- package/node_modules/tailwindcss/package.json +2 -2
- package/node_modules/undici/README.md +3 -2
- package/node_modules/undici/docs/docs/api/Agent.md +248 -44
- package/node_modules/undici/docs/docs/api/BalancedPool.md +246 -48
- package/node_modules/undici/docs/docs/api/CacheStorage.md +171 -13
- package/node_modules/undici/docs/docs/api/CacheStore.md +294 -98
- package/node_modules/undici/docs/docs/api/Client.md +365 -178
- package/node_modules/undici/docs/docs/api/ClientStats.md +80 -14
- package/node_modules/undici/docs/docs/api/Connector.md +118 -36
- package/node_modules/undici/docs/docs/api/ContentType.md +65 -25
- package/node_modules/undici/docs/docs/api/Cookies.md +125 -47
- package/node_modules/undici/docs/docs/api/Debug.md +34 -18
- package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +364 -164
- package/node_modules/undici/docs/docs/api/Dispatcher.md +479 -1093
- package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +101 -87
- package/node_modules/undici/docs/docs/api/Errors.md +503 -40
- package/node_modules/undici/docs/docs/api/EventSource.md +294 -32
- package/node_modules/undici/docs/docs/api/Fetch.md +680 -31
- package/node_modules/undici/docs/docs/api/GlobalInstallation.md +78 -98
- package/node_modules/undici/docs/docs/api/H2CClient.md +298 -176
- package/node_modules/undici/docs/docs/api/Interceptors.md +355 -0
- package/node_modules/undici/docs/docs/api/MockAgent.md +314 -322
- package/node_modules/undici/docs/docs/api/MockCallHistory.md +272 -98
- package/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +189 -26
- package/node_modules/undici/docs/docs/api/MockClient.md +151 -33
- package/node_modules/undici/docs/docs/api/MockErrors.md +56 -5
- package/node_modules/undici/docs/docs/api/MockPool.md +299 -263
- package/node_modules/undici/docs/docs/api/Pool.md +235 -43
- package/node_modules/undici/docs/docs/api/PoolStats.md +119 -13
- package/node_modules/undici/docs/docs/api/ProxyAgent.md +179 -160
- package/node_modules/undici/docs/docs/api/RedirectHandler.md +238 -63
- package/node_modules/undici/docs/docs/api/RetryAgent.md +113 -26
- package/node_modules/undici/docs/docs/api/RetryHandler.md +161 -77
- package/node_modules/undici/docs/docs/api/RoundRobinPool.md +166 -72
- package/node_modules/undici/docs/docs/api/SnapshotAgent.md +264 -542
- package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +162 -186
- package/node_modules/undici/docs/docs/api/Util.md +68 -11
- package/node_modules/undici/docs/docs/api/WebSocket.md +475 -80
- package/node_modules/undici/docs/docs/api/api-lifecycle.md +100 -32
- package/node_modules/undici/docs/docs/best-practices/client-certificate.md +2 -0
- package/node_modules/undici/docs/docs/best-practices/crawling.md +3 -1
- package/node_modules/undici/docs/docs/best-practices/migrating-from-v7-to-v8.md +6 -4
- package/node_modules/undici/docs/docs/best-practices/mocking-request.md +9 -7
- package/node_modules/undici/docs/docs/best-practices/proxy.md +3 -1
- package/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +10 -8
- package/node_modules/undici/docs/docs/best-practices/writing-tests.md +2 -0
- package/node_modules/undici/docs/docs/{GettingStarted.md → getting-started.md} +22 -19
- package/node_modules/undici/docs/docs/index.md +779 -0
- package/node_modules/undici/docs/docs/site.json +125 -0
- package/node_modules/undici/docs/docs/type-map.json +79 -0
- package/node_modules/undici/lib/api/api-request.js +7 -1
- package/node_modules/undici/lib/api/readable.js +47 -2
- package/node_modules/undici/lib/core/errors.js +20 -0
- package/node_modules/undici/lib/core/request.js +1 -1
- package/node_modules/undici/lib/core/util.js +24 -1
- package/node_modules/undici/lib/dispatcher/client-h1.js +92 -1
- package/node_modules/undici/lib/dispatcher/client-h2.js +322 -118
- package/node_modules/undici/lib/dispatcher/client.js +6 -2
- package/node_modules/undici/lib/dispatcher/dispatcher-base.js +1 -0
- package/node_modules/undici/lib/dispatcher/proxy-agent.js +42 -7
- package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +4 -2
- package/node_modules/undici/lib/handler/redirect-handler.js +1 -0
- package/node_modules/undici/lib/handler/retry-handler.js +57 -19
- package/node_modules/undici/lib/util/cache.js +8 -2
- package/node_modules/undici/lib/web/cookies/parse.js +20 -27
- package/node_modules/undici/lib/web/cookies/util.js +1 -1
- package/node_modules/undici/lib/web/eventsource/eventsource.js +7 -18
- package/node_modules/undici/lib/web/eventsource/util.js +32 -1
- package/node_modules/undici/lib/web/fetch/body.js +43 -0
- package/node_modules/undici/lib/web/fetch/constants.js +1 -1
- package/node_modules/undici/lib/web/fetch/index.js +11 -2
- package/node_modules/undici/lib/web/fetch/request.js +1 -0
- package/node_modules/undici/lib/web/fetch/util.js +4 -1
- package/node_modules/undici/lib/web/websocket/receiver.js +20 -3
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -1
- package/node_modules/undici/lib/web/websocket/websocket.js +3 -1
- package/node_modules/undici/package.json +1 -1
- package/node_modules/undici/types/client.d.ts +6 -1
- package/node_modules/undici/types/cookies.d.ts +1 -1
- package/node_modules/undici/types/errors.d.ts +10 -0
- package/node_modules/undici/types/fetch.d.ts +1 -0
- package/node_modules/undici/types/handlers.d.ts +2 -0
- package/node_modules/undici/types/proxy-agent.d.ts +7 -0
- package/package.json +4 -4
- package/react/styles.css +510 -5
- package/react/styles.source.css +850 -0
- package/node_modules/hono/dist/tsconfig.build.tsbuildinfo +0 -1
- package/node_modules/tailwindcss/dist/chunk-XVOTX5KS.mjs +0 -1
|
@@ -395,7 +395,9 @@ class Client extends DispatcherBase {
|
|
|
395
395
|
const requests = this[kQueue].splice(this[kPendingIdx])
|
|
396
396
|
for (let i = 0; i < requests.length; i++) {
|
|
397
397
|
const request = requests[i]
|
|
398
|
-
|
|
398
|
+
if (request != null) {
|
|
399
|
+
util.errorRequest(this, request, err)
|
|
400
|
+
}
|
|
399
401
|
}
|
|
400
402
|
|
|
401
403
|
const callback = () => {
|
|
@@ -434,7 +436,9 @@ function onError (client, err) {
|
|
|
434
436
|
|
|
435
437
|
for (let i = 0; i < requests.length; i++) {
|
|
436
438
|
const request = requests[i]
|
|
437
|
-
|
|
439
|
+
if (request != null) {
|
|
440
|
+
util.errorRequest(client, request, err)
|
|
441
|
+
}
|
|
438
442
|
}
|
|
439
443
|
assert(client[kSize] === 0)
|
|
440
444
|
}
|
|
@@ -4,7 +4,7 @@ const { kProxy, kClose, kDestroy, kDispatch } = require('../core/symbols')
|
|
|
4
4
|
const Agent = require('./agent')
|
|
5
5
|
const Pool = require('./pool')
|
|
6
6
|
const DispatcherBase = require('./dispatcher-base')
|
|
7
|
-
const { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError } = require('../core/errors')
|
|
7
|
+
const { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError, ProxyConnectionError } = require('../core/errors')
|
|
8
8
|
const buildConnector = require('../core/connect')
|
|
9
9
|
const Client = require('./client')
|
|
10
10
|
const { channels } = require('../core/diagnostics')
|
|
@@ -37,10 +37,15 @@ function defaultAgentFactory (origin, opts) {
|
|
|
37
37
|
return new Pool(origin, opts)
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
function shouldProxyTunnel (requestProtocol, proxyTunnel) {
|
|
41
|
+
return proxyTunnel === true || requestProtocol !== 'http:'
|
|
42
|
+
}
|
|
43
|
+
|
|
40
44
|
class Http1ProxyWrapper extends DispatcherBase {
|
|
41
45
|
#client
|
|
46
|
+
#proxyServername
|
|
42
47
|
|
|
43
|
-
constructor (proxyUrl, { headers = {}, connect, factory }) {
|
|
48
|
+
constructor (proxyUrl, { headers = {}, connect, factory, proxyServername }) {
|
|
44
49
|
if (!proxyUrl) {
|
|
45
50
|
throw new InvalidArgumentError('Proxy URL is mandatory')
|
|
46
51
|
}
|
|
@@ -48,6 +53,7 @@ class Http1ProxyWrapper extends DispatcherBase {
|
|
|
48
53
|
super()
|
|
49
54
|
|
|
50
55
|
this[kProxyHeaders] = headers
|
|
56
|
+
this.#proxyServername = proxyServername
|
|
51
57
|
if (factory) {
|
|
52
58
|
this.#client = factory(proxyUrl, { connect })
|
|
53
59
|
} else {
|
|
@@ -82,6 +88,13 @@ class Http1ProxyWrapper extends DispatcherBase {
|
|
|
82
88
|
}
|
|
83
89
|
opts.headers = { ...this[kProxyHeaders], ...headers }
|
|
84
90
|
|
|
91
|
+
// Pin the SNI/cert hostname to the proxy. Without this the underlying
|
|
92
|
+
// Client would derive it from the (rewritten) Host header, which points
|
|
93
|
+
// at the target — wrong for the TLS handshake to the proxy itself.
|
|
94
|
+
if (this.#proxyServername != null) {
|
|
95
|
+
opts.servername = this.#proxyServername
|
|
96
|
+
}
|
|
97
|
+
|
|
85
98
|
return this.#client[kDispatch](opts, handler)
|
|
86
99
|
}
|
|
87
100
|
|
|
@@ -105,7 +118,7 @@ class ProxyAgent extends DispatcherBase {
|
|
|
105
118
|
throw new InvalidArgumentError('Proxy opts.clientFactory must be a function.')
|
|
106
119
|
}
|
|
107
120
|
|
|
108
|
-
const { proxyTunnel
|
|
121
|
+
const { proxyTunnel, connectTimeout } = opts
|
|
109
122
|
|
|
110
123
|
super()
|
|
111
124
|
|
|
@@ -132,6 +145,7 @@ class ProxyAgent extends DispatcherBase {
|
|
|
132
145
|
}
|
|
133
146
|
|
|
134
147
|
const connect = buildConnector({ timeout: connectTimeout, ...opts.proxyTls })
|
|
148
|
+
const connectHTTP1 = buildConnector({ timeout: connectTimeout, ...opts.proxyTls, allowH2: false })
|
|
135
149
|
this[kConnectEndpoint] = buildConnector({ timeout: connectTimeout, ...opts.requestTls })
|
|
136
150
|
this[kConnectEndpointHTTP1] = buildConnector({ timeout: connectTimeout, ...opts.requestTls, allowH2: false })
|
|
137
151
|
|
|
@@ -147,15 +161,28 @@ class ProxyAgent extends DispatcherBase {
|
|
|
147
161
|
factory: agentFactory,
|
|
148
162
|
username: opts.username || username,
|
|
149
163
|
password: opts.password || password,
|
|
150
|
-
proxyTls: opts.proxyTls
|
|
164
|
+
proxyTls: opts.proxyTls,
|
|
165
|
+
requestTls: opts.requestTls
|
|
151
166
|
})
|
|
152
167
|
}
|
|
153
168
|
|
|
154
|
-
if (!
|
|
169
|
+
if (!shouldProxyTunnel(protocol, this[kTunnelProxy])) {
|
|
170
|
+
const forwardConnect = this[kProxy].protocol === 'https:'
|
|
171
|
+
? (opts, cb) => connectHTTP1(opts, (err, socket) => {
|
|
172
|
+
if (err && err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') {
|
|
173
|
+
cb(new SecureProxyConnectionError(err))
|
|
174
|
+
} else {
|
|
175
|
+
cb(err, socket)
|
|
176
|
+
}
|
|
177
|
+
})
|
|
178
|
+
: connectHTTP1
|
|
155
179
|
return new Http1ProxyWrapper(this[kProxy].uri, {
|
|
156
180
|
headers: this[kProxyHeaders],
|
|
157
|
-
connect,
|
|
158
|
-
factory: agentFactory
|
|
181
|
+
connect: forwardConnect,
|
|
182
|
+
factory: agentFactory,
|
|
183
|
+
proxyServername: this[kProxy].protocol === 'https:'
|
|
184
|
+
? (this[kProxyTls]?.servername || proxyHostname)
|
|
185
|
+
: undefined
|
|
159
186
|
})
|
|
160
187
|
}
|
|
161
188
|
return agentFactory(origin, options)
|
|
@@ -230,6 +257,14 @@ class ProxyAgent extends DispatcherBase {
|
|
|
230
257
|
if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') {
|
|
231
258
|
// Throw a custom error to avoid loop in client.js#connect
|
|
232
259
|
callback(new SecureProxyConnectionError(err))
|
|
260
|
+
} else if (err.code === 'UND_ERR_SOCKET') {
|
|
261
|
+
// A socket failure while establishing the tunnel means the CONNECT
|
|
262
|
+
// never completed, so there is nothing to recover - the proxy just
|
|
263
|
+
// tore down the connection. client.js#onError treats UND_ERR_SOCKET
|
|
264
|
+
// as a recoverable error on an established connection and leaves the
|
|
265
|
+
// request queued, which makes connect() retry forever. Surface it as
|
|
266
|
+
// a non-recoverable proxy error so the request fails instead. (#3897)
|
|
267
|
+
callback(new ProxyConnectionError(err))
|
|
233
268
|
} else {
|
|
234
269
|
callback(err)
|
|
235
270
|
}
|
|
@@ -19,6 +19,7 @@ const kProxyAuth = Symbol('proxy auth')
|
|
|
19
19
|
const kProxyProtocol = Symbol('proxy protocol')
|
|
20
20
|
const kPools = Symbol('pools')
|
|
21
21
|
const kConnector = Symbol('connector')
|
|
22
|
+
const kRequestTls = Symbol('request tls settings')
|
|
22
23
|
|
|
23
24
|
// Static flag to ensure warning is only emitted once per process
|
|
24
25
|
let experimentalWarningEmitted = false
|
|
@@ -53,6 +54,7 @@ class Socks5ProxyAgent extends DispatcherBase {
|
|
|
53
54
|
this[kProxyUrl] = url
|
|
54
55
|
this[kProxyHeaders] = options.headers || {}
|
|
55
56
|
this[kProxyProtocol] = options.proxyTls ? 'https:' : 'http:'
|
|
57
|
+
this[kRequestTls] = options.requestTls
|
|
56
58
|
|
|
57
59
|
// Extract auth from URL or options
|
|
58
60
|
this[kProxyAuth] = {
|
|
@@ -205,9 +207,9 @@ class Socks5ProxyAgent extends DispatcherBase {
|
|
|
205
207
|
}
|
|
206
208
|
debug('upgrading to TLS')
|
|
207
209
|
finalSocket = tls.connect({
|
|
210
|
+
...this[kRequestTls],
|
|
208
211
|
socket,
|
|
209
|
-
servername: targetHost
|
|
210
|
-
...connectOpts.tls || {}
|
|
212
|
+
servername: this[kRequestTls]?.servername || targetHost
|
|
211
213
|
})
|
|
212
214
|
|
|
213
215
|
const tlsReady = Promise.withResolvers()
|
|
@@ -55,6 +55,7 @@ class RedirectHandler {
|
|
|
55
55
|
// https://tools.ietf.org/html/rfc7231#section-6.4.2
|
|
56
56
|
// https://fetch.spec.whatwg.org/#http-redirect-fetch
|
|
57
57
|
// In case of HTTP 301 or 302 with POST, change the method to GET
|
|
58
|
+
// QUERY is safe (RFC 10008) and should not change method like GET.
|
|
58
59
|
if ((statusCode === 301 || statusCode === 302) && this.opts.method === 'POST') {
|
|
59
60
|
this.opts.method = 'GET'
|
|
60
61
|
if (util.isStream(this.opts.body)) {
|
|
@@ -14,6 +14,28 @@ function calculateRetryAfterHeader (retryAfter) {
|
|
|
14
14
|
return isNaN(retryTime) ? 0 : retryTime - Date.now()
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
// A stable controller handed to the downstream handler for the lifetime of the
|
|
18
|
+
// request. Each transparent retry/resume is a *separate* dispatch with its
|
|
19
|
+
// *own* connection controller. Without a stable proxy the downstream body keeps
|
|
20
|
+
// flow-controlling the original (now-dead) controller while data flows on the
|
|
21
|
+
// new one: backpressure pauses the new connection's controller, but the
|
|
22
|
+
// consumer's resume() targets the old one, so the resumed body stalls forever.
|
|
23
|
+
// The proxy always forwards to the controller of the currently active connection.
|
|
24
|
+
class RetryController {
|
|
25
|
+
constructor () {
|
|
26
|
+
this.target = null
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
pause () { this.target?.pause() }
|
|
30
|
+
resume () { this.target?.resume() }
|
|
31
|
+
abort (reason) { this.target?.abort(reason) }
|
|
32
|
+
get paused () { return this.target?.paused ?? false }
|
|
33
|
+
get aborted () { return this.target?.aborted ?? false }
|
|
34
|
+
get reason () { return this.target?.reason ?? null }
|
|
35
|
+
get rawHeaders () { return this.target?.rawHeaders ?? null }
|
|
36
|
+
get rawTrailers () { return this.target?.rawTrailers ?? null }
|
|
37
|
+
}
|
|
38
|
+
|
|
17
39
|
class RetryHandler {
|
|
18
40
|
constructor (opts, { dispatch, handler }) {
|
|
19
41
|
const { retryOptions, ...dispatchOpts } = opts
|
|
@@ -45,7 +67,7 @@ class RetryHandler {
|
|
|
45
67
|
timeoutFactor: timeoutFactor ?? 2,
|
|
46
68
|
maxRetries: maxRetries ?? 5,
|
|
47
69
|
// What errors we should retry
|
|
48
|
-
methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'],
|
|
70
|
+
methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE', 'QUERY'],
|
|
49
71
|
// Indicates which errors to retry
|
|
50
72
|
statusCodes: statusCodes ?? [500, 502, 503, 504, 429],
|
|
51
73
|
// List of errors to retry
|
|
@@ -70,6 +92,7 @@ class RetryHandler {
|
|
|
70
92
|
this.etag = null
|
|
71
93
|
this.statusCode = null
|
|
72
94
|
this.headers = null
|
|
95
|
+
this.controllerProxy = new RetryController()
|
|
73
96
|
}
|
|
74
97
|
|
|
75
98
|
onResponseStartWithRetry (controller, statusCode, headers, statusMessage, err) {
|
|
@@ -77,7 +100,7 @@ class RetryHandler {
|
|
|
77
100
|
// Preserve old behavior for status codes that are not eligible for retry
|
|
78
101
|
if (this.retryOpts.statusCodes.includes(statusCode) === false) {
|
|
79
102
|
this.headersSent = true
|
|
80
|
-
this.handler.onResponseStart?.(
|
|
103
|
+
this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage)
|
|
81
104
|
} else {
|
|
82
105
|
this.error = err
|
|
83
106
|
}
|
|
@@ -87,14 +110,14 @@ class RetryHandler {
|
|
|
87
110
|
|
|
88
111
|
if (isDisturbed(this.opts.body)) {
|
|
89
112
|
this.headersSent = true
|
|
90
|
-
this.handler.onResponseStart?.(
|
|
113
|
+
this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage)
|
|
91
114
|
return
|
|
92
115
|
}
|
|
93
116
|
|
|
94
117
|
function shouldRetry (passedErr) {
|
|
95
118
|
if (passedErr) {
|
|
96
119
|
this.headersSent = true
|
|
97
|
-
this.handler.onResponseStart?.(
|
|
120
|
+
this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage)
|
|
98
121
|
controller.resume()
|
|
99
122
|
return
|
|
100
123
|
}
|
|
@@ -103,6 +126,13 @@ class RetryHandler {
|
|
|
103
126
|
controller.resume()
|
|
104
127
|
}
|
|
105
128
|
|
|
129
|
+
// The pause()/resume() pair (here and in shouldRetry) acts on THIS
|
|
130
|
+
// connection's controller -- never the downstream proxy. We hold this exact
|
|
131
|
+
// connection while the retry policy decides (possibly after a timeout) and
|
|
132
|
+
// must resume the same one. Routing this through controllerProxy would risk
|
|
133
|
+
// resuming a different connection if a later dispatch re-points the proxy in
|
|
134
|
+
// between, leaving this one paused forever -- the very stall the proxy exists
|
|
135
|
+
// to prevent.
|
|
106
136
|
controller.pause()
|
|
107
137
|
this.retryOpts.retry(
|
|
108
138
|
err,
|
|
@@ -115,13 +145,19 @@ class RetryHandler {
|
|
|
115
145
|
}
|
|
116
146
|
|
|
117
147
|
onRequestStart (controller, context) {
|
|
148
|
+
// request.js creates a fresh RequestController per dispatch and passes that
|
|
149
|
+
// same instance to every later callback of the dispatch. onRequestStart is
|
|
150
|
+
// the first callback (it is where the controller is created), so re-pointing
|
|
151
|
+
// the proxy here is enough to keep it on the active connection across every
|
|
152
|
+
// transparent retry/resume.
|
|
153
|
+
this.controllerProxy.target = controller
|
|
118
154
|
if (!this.headersSent) {
|
|
119
|
-
this.handler.onRequestStart?.(
|
|
155
|
+
this.handler.onRequestStart?.(this.controllerProxy, context)
|
|
120
156
|
}
|
|
121
157
|
}
|
|
122
158
|
|
|
123
|
-
onRequestUpgrade (
|
|
124
|
-
this.handler.onRequestUpgrade?.(
|
|
159
|
+
onRequestUpgrade (_controller, statusCode, headers, socket) {
|
|
160
|
+
this.handler.onRequestUpgrade?.(this.controllerProxy, statusCode, headers, socket)
|
|
125
161
|
}
|
|
126
162
|
|
|
127
163
|
static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) {
|
|
@@ -248,7 +284,7 @@ class RetryHandler {
|
|
|
248
284
|
if (range == null) {
|
|
249
285
|
this.headersSent = true
|
|
250
286
|
this.handler.onResponseStart?.(
|
|
251
|
-
|
|
287
|
+
this.controllerProxy,
|
|
252
288
|
statusCode,
|
|
253
289
|
headers,
|
|
254
290
|
statusMessage
|
|
@@ -295,7 +331,7 @@ class RetryHandler {
|
|
|
295
331
|
|
|
296
332
|
this.headersSent = true
|
|
297
333
|
this.handler.onResponseStart?.(
|
|
298
|
-
|
|
334
|
+
this.controllerProxy,
|
|
299
335
|
statusCode,
|
|
300
336
|
headers,
|
|
301
337
|
statusMessage
|
|
@@ -308,17 +344,17 @@ class RetryHandler {
|
|
|
308
344
|
}
|
|
309
345
|
}
|
|
310
346
|
|
|
311
|
-
onResponseData (
|
|
347
|
+
onResponseData (_controller, chunk) {
|
|
312
348
|
if (this.error) {
|
|
313
349
|
return
|
|
314
350
|
}
|
|
315
351
|
|
|
316
352
|
this.start += chunk.length
|
|
317
353
|
|
|
318
|
-
this.handler.onResponseData?.(
|
|
354
|
+
this.handler.onResponseData?.(this.controllerProxy, chunk)
|
|
319
355
|
}
|
|
320
356
|
|
|
321
|
-
onResponseEnd (
|
|
357
|
+
onResponseEnd (_controller, trailers) {
|
|
322
358
|
if (this.error && this.retryOpts.throwOnError) {
|
|
323
359
|
throw this.error
|
|
324
360
|
}
|
|
@@ -335,13 +371,13 @@ class RetryHandler {
|
|
|
335
371
|
}
|
|
336
372
|
}
|
|
337
373
|
this.retryCount = 0
|
|
338
|
-
return this.handler.onResponseEnd?.(
|
|
374
|
+
return this.handler.onResponseEnd?.(this.controllerProxy, trailers)
|
|
339
375
|
}
|
|
340
376
|
|
|
341
|
-
this.retry(
|
|
377
|
+
this.retry()
|
|
342
378
|
}
|
|
343
379
|
|
|
344
|
-
retry (
|
|
380
|
+
retry () {
|
|
345
381
|
if (this.start !== 0) {
|
|
346
382
|
const headers = { range: `bytes=${this.start}-${this.end ?? ''}` }
|
|
347
383
|
|
|
@@ -363,23 +399,25 @@ class RetryHandler {
|
|
|
363
399
|
this.retryCountCheckpoint = this.retryCount
|
|
364
400
|
this.dispatch(this.opts, this)
|
|
365
401
|
} catch (err) {
|
|
366
|
-
this.handler.onResponseError?.(
|
|
402
|
+
this.handler.onResponseError?.(this.controllerProxy, err)
|
|
367
403
|
}
|
|
368
404
|
}
|
|
369
405
|
|
|
370
406
|
onResponseError (controller, err) {
|
|
407
|
+
// controller is THIS failed connection (not the proxy): we inspect whether
|
|
408
|
+
// the consumer aborted it to decide retry-vs-propagate.
|
|
371
409
|
if (controller?.aborted || isDisturbed(this.opts.body)) {
|
|
372
|
-
this.handler.onResponseError?.(
|
|
410
|
+
this.handler.onResponseError?.(this.controllerProxy, err)
|
|
373
411
|
return
|
|
374
412
|
}
|
|
375
413
|
|
|
376
414
|
function shouldRetry (returnedErr) {
|
|
377
415
|
if (!returnedErr) {
|
|
378
|
-
this.retry(
|
|
416
|
+
this.retry()
|
|
379
417
|
return
|
|
380
418
|
}
|
|
381
419
|
|
|
382
|
-
this.handler?.onResponseError?.(
|
|
420
|
+
this.handler?.onResponseError?.(this.controllerProxy, returnedErr)
|
|
383
421
|
}
|
|
384
422
|
|
|
385
423
|
// We reconcile in case of a mix between network errors
|
|
@@ -228,6 +228,10 @@ function parseCacheControlHeader (header) {
|
|
|
228
228
|
headers[headers.length - 1] = lastHeader
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
+
for (let j = 0; j < headers.length; j++) {
|
|
232
|
+
headers[j] = headers[j].trim()
|
|
233
|
+
}
|
|
234
|
+
|
|
231
235
|
if (key in output) {
|
|
232
236
|
output[key] = output[key].concat(headers)
|
|
233
237
|
} else {
|
|
@@ -236,10 +240,12 @@ function parseCacheControlHeader (header) {
|
|
|
236
240
|
}
|
|
237
241
|
} else {
|
|
238
242
|
// Something like `no-cache="some-header"`
|
|
243
|
+
const fieldName = value.trim()
|
|
244
|
+
|
|
239
245
|
if (key in output) {
|
|
240
|
-
output[key] = output[key].concat(
|
|
246
|
+
output[key] = output[key].concat(fieldName)
|
|
241
247
|
} else {
|
|
242
|
-
output[key] = [
|
|
248
|
+
output[key] = [fieldName]
|
|
243
249
|
}
|
|
244
250
|
}
|
|
245
251
|
|
|
@@ -4,7 +4,6 @@ const { collectASequenceOfCodePointsFast } = require('../infra')
|
|
|
4
4
|
const { maxNameValuePairSize, maxAttributeValueSize } = require('./constants')
|
|
5
5
|
const { isCTLExcludingHtab } = require('./util')
|
|
6
6
|
const assert = require('node:assert')
|
|
7
|
-
const { unescape: qsUnescape } = require('node:querystring')
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* @description Parses the field-value attributes of a set-cookie header string.
|
|
@@ -82,7 +81,7 @@ function parseSetCookie (header) {
|
|
|
82
81
|
// store arbitrary data in a cookie-value SHOULD encode that data, for
|
|
83
82
|
// example, using Base64 [RFC4648].
|
|
84
83
|
return {
|
|
85
|
-
name, value
|
|
84
|
+
name, value, ...parseUnparsedAttributes(unparsedAttributes)
|
|
86
85
|
}
|
|
87
86
|
}
|
|
88
87
|
|
|
@@ -179,8 +178,9 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
|
|
|
179
178
|
|
|
180
179
|
// 2. If the attribute-value failed to parse as a cookie date, ignore
|
|
181
180
|
// the cookie-av.
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
if (!Number.isNaN(expiryTime.getTime())) {
|
|
182
|
+
cookieAttributeList.expires = expiryTime
|
|
183
|
+
}
|
|
184
184
|
} else if (attributeNameLowercase === 'max-age') {
|
|
185
185
|
// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.2
|
|
186
186
|
// If the attribute-name case-insensitively matches the string "Max-
|
|
@@ -280,32 +280,25 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
|
|
|
280
280
|
// If the attribute-name case-insensitively matches the string
|
|
281
281
|
// "SameSite", the user agent MUST process the cookie-av as follows:
|
|
282
282
|
|
|
283
|
-
// 1. Let enforcement be "Default".
|
|
284
|
-
let enforcement = 'Default'
|
|
285
|
-
|
|
286
283
|
const attributeValueLowercase = attributeValue.toLowerCase()
|
|
287
|
-
// 2. If cookie-av's attribute-value is a case-insensitive match for
|
|
288
|
-
// "None", set enforcement to "None".
|
|
289
|
-
if (attributeValueLowercase.includes('none')) {
|
|
290
|
-
enforcement = 'None'
|
|
291
|
-
}
|
|
292
284
|
|
|
293
|
-
//
|
|
294
|
-
// "
|
|
295
|
-
|
|
296
|
-
|
|
285
|
+
// 1. If cookie-av's attribute-value is a case-insensitive match for
|
|
286
|
+
// "None", append an attribute to the cookie-attribute-list with an
|
|
287
|
+
// attribute-name of "SameSite" and an attribute-value of "None".
|
|
288
|
+
if (attributeValueLowercase === 'none') {
|
|
289
|
+
cookieAttributeList.sameSite = 'None'
|
|
290
|
+
} else if (attributeValueLowercase === 'strict') {
|
|
291
|
+
// 2. If cookie-av's attribute-value is a case-insensitive match for
|
|
292
|
+
// "Strict", append an attribute to the cookie-attribute-list with
|
|
293
|
+
// an attribute-name of "SameSite" and an attribute-value of
|
|
294
|
+
// "Strict".
|
|
295
|
+
cookieAttributeList.sameSite = 'Strict'
|
|
296
|
+
} else if (attributeValueLowercase === 'lax') {
|
|
297
|
+
// 3. If cookie-av's attribute-value is a case-insensitive match for
|
|
298
|
+
// "Lax", append an attribute to the cookie-attribute-list with an
|
|
299
|
+
// attribute-name of "SameSite" and an attribute-value of "Lax".
|
|
300
|
+
cookieAttributeList.sameSite = 'Lax'
|
|
297
301
|
}
|
|
298
|
-
|
|
299
|
-
// 4. If cookie-av's attribute-value is a case-insensitive match for
|
|
300
|
-
// "Lax", set enforcement to "Lax".
|
|
301
|
-
if (attributeValueLowercase.includes('lax')) {
|
|
302
|
-
enforcement = 'Lax'
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// 5. Append an attribute to the cookie-attribute-list with an
|
|
306
|
-
// attribute-name of "SameSite" and an attribute-value of
|
|
307
|
-
// enforcement.
|
|
308
|
-
cookieAttributeList.sameSite = enforcement
|
|
309
302
|
} else {
|
|
310
303
|
cookieAttributeList.unparsed ??= []
|
|
311
304
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const { pipeline } = require('node:stream')
|
|
4
4
|
const { fetching } = require('../fetch')
|
|
5
|
-
const { makeRequest } = require('../fetch/request')
|
|
6
5
|
const { webidl } = require('../webidl')
|
|
7
6
|
const { EventSourceStream } = require('./eventsource-stream')
|
|
8
7
|
const { parseMIMEType } = require('../fetch/data-url')
|
|
@@ -10,6 +9,7 @@ const { createFastMessageEvent } = require('../websocket/events')
|
|
|
10
9
|
const { isNetworkError } = require('../fetch/response')
|
|
11
10
|
const { kEnumerableProperty } = require('../../core/util')
|
|
12
11
|
const { environmentSettingsObject } = require('../fetch/util')
|
|
12
|
+
const { createPotentialCORSRequest } = require('./util')
|
|
13
13
|
|
|
14
14
|
let experimentalWarned = false
|
|
15
15
|
|
|
@@ -160,33 +160,22 @@ class EventSource extends EventTarget {
|
|
|
160
160
|
|
|
161
161
|
// 8. Let request be the result of creating a potential-CORS request given
|
|
162
162
|
// urlRecord, the empty string, and corsAttributeState.
|
|
163
|
-
const
|
|
164
|
-
redirect: 'follow',
|
|
165
|
-
keepalive: true,
|
|
166
|
-
// @see https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes
|
|
167
|
-
mode: 'cors',
|
|
168
|
-
credentials: corsAttributeState === 'anonymous'
|
|
169
|
-
? 'same-origin'
|
|
170
|
-
: 'omit',
|
|
171
|
-
referrer: 'no-referrer'
|
|
172
|
-
}
|
|
163
|
+
const request = createPotentialCORSRequest(urlRecord, '', corsAttributeState)
|
|
173
164
|
|
|
174
165
|
// 9. Set request's client to settings.
|
|
175
|
-
|
|
166
|
+
request.client = environmentSettingsObject.settingsObject
|
|
176
167
|
|
|
177
168
|
// 10. User agents may set (`Accept`, `text/event-stream`) in request's header list.
|
|
178
|
-
|
|
169
|
+
request.headersList.set('Accept', 'text/event-stream')
|
|
179
170
|
|
|
180
171
|
// 11. Set request's cache mode to "no-store".
|
|
181
|
-
|
|
172
|
+
request.cache = 'no-store'
|
|
182
173
|
|
|
183
174
|
// 12. Set request's initiator type to "other".
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
initRequest.urlList = [new URL(this.#url)]
|
|
175
|
+
request.initiator = 'other'
|
|
187
176
|
|
|
188
177
|
// 13. Set ev's request to request.
|
|
189
|
-
this.#request =
|
|
178
|
+
this.#request = request
|
|
190
179
|
|
|
191
180
|
this.#connect()
|
|
192
181
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { makeRequest } = require('../fetch/request')
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Checks if the given value is a valid LastEventId.
|
|
5
7
|
* @param {string} value
|
|
@@ -23,7 +25,36 @@ function isASCIINumber (value) {
|
|
|
23
25
|
return true
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
function createPotentialCORSRequest (url, destination, corsAttributeState, sameOriginFallback) {
|
|
29
|
+
// 1. Let mode be "no-cors" if corsAttributeState is No CORS, and "cors" otherwise.
|
|
30
|
+
let mode = corsAttributeState === 'no cors' ? 'no-cors' : 'cors'
|
|
31
|
+
|
|
32
|
+
// 2. If same-origin fallback flag is set and mode is "no-cors", set mode to "same-origin".
|
|
33
|
+
if (sameOriginFallback && mode === 'no-cors') {
|
|
34
|
+
mode = 'same-origin'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 3. Let credentialsMode be "include".
|
|
38
|
+
let credentialsMode = 'include'
|
|
39
|
+
|
|
40
|
+
// 4. If corsAttributeState is Anonymous, set credentialsMode to "same-origin".
|
|
41
|
+
if (corsAttributeState === 'anonymous') {
|
|
42
|
+
credentialsMode = 'same-origin'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 5. Return a new request whose URL is url, destination is destination, mode is mode,
|
|
46
|
+
// credentials mode is credentialsMode, and whose use-URL-credentials flag is set.
|
|
47
|
+
return makeRequest({
|
|
48
|
+
urlList: [url],
|
|
49
|
+
destination,
|
|
50
|
+
mode,
|
|
51
|
+
credentials: credentialsMode,
|
|
52
|
+
useURLCredentials: true
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
26
56
|
module.exports = {
|
|
27
57
|
isValidLastEventId,
|
|
28
|
-
isASCIINumber
|
|
58
|
+
isASCIINumber,
|
|
59
|
+
createPotentialCORSRequest
|
|
29
60
|
}
|
|
@@ -392,6 +392,49 @@ function bodyMixinMethods (instance, getInternalState) {
|
|
|
392
392
|
return consumeBody(this, (bytes) => {
|
|
393
393
|
return new Uint8Array(bytes)
|
|
394
394
|
}, instance, getInternalState)
|
|
395
|
+
},
|
|
396
|
+
|
|
397
|
+
textStream () {
|
|
398
|
+
const this_ = getInternalState(this)
|
|
399
|
+
|
|
400
|
+
// 1. If this is unusable, then throw a TypeError.
|
|
401
|
+
if (bodyUnusable(this_)) {
|
|
402
|
+
throw new TypeError('Body is unusable: Body has already been read')
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// 2. If this’s body is null:
|
|
406
|
+
if (this_.body == null) {
|
|
407
|
+
// 2.1. Let emptyStream be a new ReadableStream in this’s relevant realm.
|
|
408
|
+
// 2.2. Set up emptyStream.
|
|
409
|
+
/** @type {ReadableStreamDefaultController<any>} */
|
|
410
|
+
let controller
|
|
411
|
+
const emptyStream = new ReadableStream({
|
|
412
|
+
start: (c) => {
|
|
413
|
+
controller = c
|
|
414
|
+
},
|
|
415
|
+
pull: () => Promise.resolve(),
|
|
416
|
+
cancel: () => Promise.resolve()
|
|
417
|
+
}, {
|
|
418
|
+
size: () => 1
|
|
419
|
+
})
|
|
420
|
+
|
|
421
|
+
// 2.3. Close emptyStream.
|
|
422
|
+
controller.close()
|
|
423
|
+
|
|
424
|
+
// 2.4. Return emptyStream.
|
|
425
|
+
return emptyStream
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// 3. Let stream be this’s body’s stream.
|
|
429
|
+
/** @type {ReadableStream} */
|
|
430
|
+
const stream = this_.body.stream
|
|
431
|
+
|
|
432
|
+
// 4. Let decoder be a new TextDecoderStream object in this’s relevant realm.
|
|
433
|
+
// 5. Set up decoder with UTF-8.
|
|
434
|
+
const decoder = new TextDecoderStream('UTF-8')
|
|
435
|
+
|
|
436
|
+
// 6. Return the result of stream, piped through decoder.
|
|
437
|
+
return stream.pipeThrough(decoder)
|
|
395
438
|
}
|
|
396
439
|
}
|
|
397
440
|
|
|
@@ -46,7 +46,7 @@ const referrerPolicyTokensSet = new Set(referrerPolicyTokens)
|
|
|
46
46
|
|
|
47
47
|
const requestRedirect = /** @type {const} */ (['follow', 'manual', 'error'])
|
|
48
48
|
|
|
49
|
-
const safeMethods = /** @type {const} */ (['GET', 'HEAD', 'OPTIONS', 'TRACE'])
|
|
49
|
+
const safeMethods = /** @type {const} */ (['GET', 'HEAD', 'OPTIONS', 'TRACE', 'QUERY'])
|
|
50
50
|
const safeMethodsSet = new Set(safeMethods)
|
|
51
51
|
|
|
52
52
|
const requestMode = /** @type {const} */ (['navigate', 'same-origin', 'no-cors', 'cors'])
|