@openclaw/slack 2026.9.7 → 2026.10.1-beta.1
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/.setup/{account-inspect-DWBXpER6.mjs → account-inspect-Cs-7DXXW.mjs} +1 -1
- package/dist/.setup/{accounts-D_N9IqNA.mjs → accounts-CDgkV7Cm.mjs} +4 -16
- package/dist/.setup/{action-runtime-DfWvuiZd.mjs → action-runtime-DJ1daRAZ.mjs} +5 -7
- package/dist/.setup/action-runtime.runtime-CdWL2mLC.mjs +2 -0
- package/dist/.setup/{actions-Df0CzcDl.mjs → actions-DDoAJnrH.mjs} +16 -35
- package/dist/.setup/{approval-handler.runtime-Ed6Sw5VK.mjs → approval-handler.runtime-BcE_shWc.mjs} +5 -5
- package/dist/.setup/{approval-message-updates-BadvtA7R.mjs → approval-message-updates-EgKGmFXx.mjs} +1 -1
- package/dist/.setup/{channel-C7bgPSTE.mjs → channel-DgKSu8Iv.mjs} +46 -48
- package/dist/.setup/{channel-type-ClOttrZ5.mjs → channel-type-B9zYYzBU.mjs} +4 -4
- package/dist/.setup/{channel.setup-Dh2jzAjN.mjs → channel.setup-BYIlwbQ7.mjs} +27 -27
- package/dist/.setup/{config-schema-BZCxmHKG.mjs → config-schema-BH0K9-Um.mjs} +4 -0
- package/dist/.setup/{directory-config-BOUWH3hR.mjs → directory-config-B_by7zrc.mjs} +2 -2
- package/dist/.setup/{directory-live-B2O4B_Ho.mjs → directory-live-C48wazJt.mjs} +3 -3
- package/dist/.setup/{doctor-contract-CRN1Z_c7.mjs → doctor-contract-Cd4-VzIM.mjs} +28 -28
- package/dist/.setup/{message-tool-api-Cu4lwlGy.mjs → message-tool-api-CcjLPN3v.mjs} +2 -2
- package/dist/.setup/{monitor-BPVfkumU.mjs → monitor-BuYBDmm7.mjs} +190 -315
- package/dist/.setup/{outbound-adapter-Bv48XUjq.mjs → outbound-adapter-BZFkK-mw.mjs} +6 -17
- package/dist/.setup/{pipeline.runtime-B1H63Frf.mjs → pipeline.runtime-CIepKmZt.mjs} +241 -247
- package/dist/.setup/{policy-D-jfM174.mjs → policy-KKTqEiDv.mjs} +12 -22
- package/dist/.setup/{probe-B2Y9qc_z.mjs → probe-BVlJ3dp0.mjs} +4 -7
- package/dist/.setup/{relay-source-BpKdjsll.mjs → relay-source-CC3h6M7y.mjs} +2 -2
- package/dist/.setup/{replies-BAnUtr2f.mjs → replies-DHbuthIR.mjs} +12 -26
- package/dist/.setup/{reply-blocks-SE1kTE3I.mjs → reply-blocks-CKnO4BSG.mjs} +4 -29
- package/dist/.setup/{resolve-channels-XXBn8UU_.mjs → resolve-channels-HR0TgArR.mjs} +2 -2
- package/dist/.setup/{resolve-users-DW0ngD03.mjs → resolve-users-BNYBhF0q.mjs} +4 -4
- package/dist/.setup/rolldown-runtime-B4FMCO8f.mjs +28 -0
- package/dist/.setup/{scopes-CasuDvaa.mjs → scopes-DrDbyUH2.mjs} +1 -1
- package/dist/.setup/secret-contract-B-Qm6aQQ.mjs +65 -0
- package/dist/.setup/{secret-contract-api-Dp6290Vg.mjs → secret-contract-api-DmUVxIRs.mjs} +1 -1
- package/dist/.setup/{security-audit-BqDc-6VL.mjs → security-audit-C1nOGzJa.mjs} +1 -1
- package/dist/.setup/{send-BOVLQi3n.mjs → send-CgPI3Zj8.mjs} +22 -53
- package/dist/.setup/{session-status-DscajIsd.mjs → session-status-D46GHwOV.mjs} +39 -49
- package/dist/.setup/{setup-plugin-api-DTtbTKNk.mjs → setup-plugin-api-ZrHs0N4U.mjs} +1 -1
- package/dist/.setup/{setup-surface-Dn7QgWRE.mjs → setup-surface-83lxvE2y.mjs} +10 -13
- package/dist/.setup/{shared-qau-uDGl.mjs → shared-VtmYNj-v.mjs} +53 -57
- package/dist/.setup/{slash-dispatch.runtime--AEzLVBF.mjs → slash-dispatch.runtime-gBj_uaLM.mjs} +1 -1
- package/dist/account-inspect-api.js +1 -1
- package/dist/api.js +13 -13
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/control-ui/2f4b1e827be6b68ced2ea0d8b7da8529a4eafbe72be27ee37e1064bdd530ec10/index.js +1 -0
- package/dist/directory-contract-api.js +1 -1
- package/dist/doctor-contract-api.js +1 -1
- package/dist/message-tool-api.js +1 -1
- package/dist/runtime-api.js +10 -10
- package/dist/secret-contract-api.js +1 -1
- package/dist/security-contract-api.js +1 -1
- package/dist/setup-entry.js +2 -2
- package/dist/setup-plugin-api.js +1 -1
- package/node_modules/undici/README.md +10 -1
- package/node_modules/undici/docs/docs/api/Agent.md +8 -8
- package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +9 -6
- package/node_modules/undici/docs/docs/api/Dispatcher.md +9 -0
- package/node_modules/undici/docs/docs/api/Errors.md +25 -0
- package/node_modules/undici/docs/docs/api/Fetch.md +10 -0
- package/node_modules/undici/docs/docs/api/Interceptors.md +4 -3
- package/node_modules/undici/docs/docs/api/Pool.md +5 -6
- package/node_modules/undici/docs/docs/index.md +10 -1
- package/node_modules/undici/lib/api/readable.js +1 -2
- package/node_modules/undici/lib/core/request.js +23 -2
- package/node_modules/undici/lib/core/util.js +0 -39
- package/node_modules/undici/lib/dispatcher/client-h1.js +11 -4
- package/node_modules/undici/lib/dispatcher/client-h2.js +52 -8
- package/node_modules/undici/lib/dispatcher/client.js +6 -1
- package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +21 -6
- package/node_modules/undici/lib/dispatcher/pool-base.js +63 -2
- package/node_modules/undici/lib/dispatcher/pool.js +90 -7
- package/node_modules/undici/lib/dispatcher/proxy-agent.js +16 -3
- package/node_modules/undici/lib/handler/deduplication-handler.js +24 -11
- package/node_modules/undici/lib/handler/redirect-handler.js +5 -0
- package/node_modules/undici/lib/handler/retry-handler.js +72 -13
- package/node_modules/undici/lib/interceptor/cache.js +4 -1
- package/node_modules/undici/lib/interceptor/decompress.js +236 -69
- package/node_modules/undici/lib/web/cache/cache.js +17 -8
- package/node_modules/undici/lib/web/cache/cachestorage.js +11 -5
- package/node_modules/undici/lib/web/cookies/index.js +19 -7
- package/node_modules/undici/lib/web/cookies/util.js +3 -1
- package/node_modules/undici/lib/web/eventsource/eventsource.js +25 -1
- package/node_modules/undici/lib/web/fetch/body.js +22 -15
- package/node_modules/undici/lib/web/fetch/data-url.js +6 -6
- package/node_modules/undici/lib/web/fetch/formdata.js +30 -36
- package/node_modules/undici/lib/web/fetch/headers.js +34 -31
- package/node_modules/undici/lib/web/fetch/index.js +46 -25
- package/node_modules/undici/lib/web/fetch/request.js +74 -79
- package/node_modules/undici/lib/web/fetch/response.js +43 -44
- package/node_modules/undici/lib/web/fetch/util.js +7 -7
- package/node_modules/undici/lib/web/infra/index.js +16 -1
- package/node_modules/undici/lib/web/webidl/index.js +2 -14
- package/node_modules/undici/lib/web/websocket/connection.js +33 -12
- package/node_modules/undici/lib/web/websocket/events.js +43 -26
- package/node_modules/undici/lib/web/websocket/receiver.js +2 -0
- package/node_modules/undici/lib/web/websocket/stream/websocketerror.js +13 -10
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +19 -4
- package/node_modules/undici/lib/web/websocket/websocket.js +44 -41
- package/node_modules/undici/package.json +1 -1
- package/node_modules/undici/types/diagnostics-channel.d.ts +2 -1
- package/node_modules/undici/types/interceptors.d.ts +1 -1
- package/node_modules/undici/types/webidl.d.ts +13 -7
- package/openclaw.plugin.json +4 -1
- package/package.json +14 -6
- package/dist/.setup/action-runtime.runtime-Ck4bAWOX.mjs +0 -2
- package/dist/.setup/secret-contract-BaZcu6P_.mjs +0 -82
- package/dist/.setup/streaming-compat-C5Wut626.mjs +0 -62
|
@@ -9,8 +9,63 @@ const DecoratorHandler = require('../handler/decorator-handler')
|
|
|
9
9
|
/** @typedef {import('node:stream').Transform} Controller */
|
|
10
10
|
/** @typedef {Transform&import('node:zlib').Zlib} DecompressorStream */
|
|
11
11
|
|
|
12
|
+
class DecompressController {
|
|
13
|
+
#onPause
|
|
14
|
+
#onResume
|
|
15
|
+
#onAbort
|
|
16
|
+
#paused = false
|
|
17
|
+
|
|
18
|
+
constructor (onPause, onResume, onAbort) {
|
|
19
|
+
this.#onPause = onPause
|
|
20
|
+
this.#onResume = onResume
|
|
21
|
+
this.#onAbort = onAbort
|
|
22
|
+
this.target = null
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
pause () {
|
|
26
|
+
if (this.#paused) {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
this.#paused = true
|
|
31
|
+
this.#onPause()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
resume () {
|
|
35
|
+
if (!this.#paused) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
this.#paused = false
|
|
40
|
+
this.#onResume()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
abort (reason) {
|
|
44
|
+
this.target?.abort(reason)
|
|
45
|
+
this.#onAbort(reason)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get paused () { return this.#paused }
|
|
49
|
+
get aborted () { return this.target?.aborted ?? false }
|
|
50
|
+
get reason () { return this.target?.reason ?? null }
|
|
51
|
+
get rawHeaders () { return this.target?.rawHeaders ?? null }
|
|
52
|
+
set rawHeaders (value) {
|
|
53
|
+
if (this.target) {
|
|
54
|
+
this.target.rawHeaders = value
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get rawTrailers () { return this.target?.rawTrailers ?? null }
|
|
59
|
+
set rawTrailers (value) {
|
|
60
|
+
if (this.target) {
|
|
61
|
+
this.target.rawTrailers = value
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
12
66
|
/** @type {Record<string, () => DecompressorStream>} */
|
|
13
67
|
const supportedEncodings = {
|
|
68
|
+
__proto__: null,
|
|
14
69
|
gzip: createGunzip,
|
|
15
70
|
'x-gzip': createGunzip,
|
|
16
71
|
br: createBrotliDecompress,
|
|
@@ -21,7 +76,7 @@ const supportedEncodings = {
|
|
|
21
76
|
}
|
|
22
77
|
|
|
23
78
|
const defaultSkipStatusCodes = /** @type {const} */ ([204, 304])
|
|
24
|
-
const defaultMaxSize =
|
|
79
|
+
const defaultMaxSize = 0
|
|
25
80
|
|
|
26
81
|
/**
|
|
27
82
|
* Limits the output of one stage in a decompression chain.
|
|
@@ -53,7 +108,7 @@ let warningEmitted = /** @type {boolean} */ (false)
|
|
|
53
108
|
* @typedef {Object} DecompressHandlerOptions
|
|
54
109
|
* @property {number[]|Readonly<number[]>} [skipStatusCodes=[204, 304]] - List of status codes to skip decompression for
|
|
55
110
|
* @property {boolean} [skipErrorResponses] - Whether to skip decompression for error responses (status codes >= 400)
|
|
56
|
-
* @property {number} [maxSize=
|
|
111
|
+
* @property {number} [maxSize=0] - Maximum decompressed response size in bytes. 0 disables the limit
|
|
57
112
|
*/
|
|
58
113
|
|
|
59
114
|
class DecompressHandler extends DecoratorHandler {
|
|
@@ -73,16 +128,130 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
73
128
|
#terminated = false
|
|
74
129
|
/** @type {boolean} */
|
|
75
130
|
#inputEnded = false
|
|
131
|
+
/** @type {boolean} */
|
|
132
|
+
#inputBackpressured = false
|
|
133
|
+
/** @type {boolean} */
|
|
134
|
+
#upstreamPaused = false
|
|
135
|
+
/** @type {boolean} */
|
|
136
|
+
#draining = false
|
|
137
|
+
/** @type {boolean} */
|
|
138
|
+
#drainRequested = false
|
|
139
|
+
/** @type {boolean} */
|
|
140
|
+
#completionPending = false
|
|
141
|
+
/** @type {DecompressorStream | undefined} */
|
|
142
|
+
#finalDecompressor
|
|
143
|
+
/** @type {DecompressController} */
|
|
144
|
+
#controller
|
|
76
145
|
|
|
77
146
|
constructor (handler, { skipStatusCodes = defaultSkipStatusCodes, skipErrorResponses = true, maxSize = defaultMaxSize } = {}) {
|
|
78
|
-
if (!Number.isSafeInteger(maxSize) || maxSize <
|
|
79
|
-
throw new InvalidArgumentError('maxSize must be a
|
|
147
|
+
if (!Number.isSafeInteger(maxSize) || maxSize < 0) {
|
|
148
|
+
throw new InvalidArgumentError('maxSize must be a non-negative integer')
|
|
80
149
|
}
|
|
81
150
|
|
|
82
151
|
super(handler)
|
|
83
152
|
this.#skipStatusCodes = skipStatusCodes
|
|
84
153
|
this.#skipErrorResponses = skipErrorResponses
|
|
85
154
|
this.#maxSize = maxSize
|
|
155
|
+
this.#controller = new DecompressController(
|
|
156
|
+
() => this.#onDownstreamPause(),
|
|
157
|
+
() => this.#onDownstreamResume(),
|
|
158
|
+
reason => {
|
|
159
|
+
if (this.#inputEnded && !this.#terminated) {
|
|
160
|
+
this.onResponseError(this.#controller, reason)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
#onDownstreamPause () {
|
|
167
|
+
this.#pauseUpstream()
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
#onDownstreamResume () {
|
|
171
|
+
const drainWasDeferred = this.#draining
|
|
172
|
+
this.#drainOutput()
|
|
173
|
+
if (!drainWasDeferred) {
|
|
174
|
+
this.#resumeUpstreamIfNeeded()
|
|
175
|
+
this.#finishIfReady()
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
#pauseUpstream () {
|
|
180
|
+
if (!this.#upstreamPaused && !this.#terminated) {
|
|
181
|
+
this.#upstreamPaused = true
|
|
182
|
+
this.#controller.target?.pause()
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
#resumeUpstreamIfNeeded () {
|
|
187
|
+
if (this.#upstreamPaused && !this.#controller.paused && !this.#inputBackpressured) {
|
|
188
|
+
this.#upstreamPaused = false
|
|
189
|
+
if (!this.#inputEnded) {
|
|
190
|
+
this.#controller.target?.resume()
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
#drainOutput () {
|
|
196
|
+
if (this.#terminated || this.#controller.paused || !this.#finalDecompressor) {
|
|
197
|
+
return
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (this.#draining) {
|
|
201
|
+
this.#drainRequested = true
|
|
202
|
+
return
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
this.#draining = true
|
|
206
|
+
try {
|
|
207
|
+
do {
|
|
208
|
+
this.#drainRequested = false
|
|
209
|
+
let chunk
|
|
210
|
+
while (!this.#terminated && !this.#controller.paused && (chunk = this.#finalDecompressor.read()) !== null) {
|
|
211
|
+
if (this.#maxSize > 0) {
|
|
212
|
+
const decompressedSize = this.#decompressedSize + chunk.length
|
|
213
|
+
if (decompressedSize > this.#maxSize) {
|
|
214
|
+
this.#fail(new ResponseExceededMaxSizeError(
|
|
215
|
+
`Decompressed response size (${decompressedSize}) exceeded maxSize (${this.#maxSize})`
|
|
216
|
+
))
|
|
217
|
+
return
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
this.#decompressedSize = decompressedSize
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const result = super.onResponseData(this.#controller, chunk)
|
|
224
|
+
if (result === false && !this.#controller.paused) {
|
|
225
|
+
this.#controller.pause()
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
} while (this.#drainRequested && !this.#terminated && !this.#controller.paused)
|
|
229
|
+
} finally {
|
|
230
|
+
this.#draining = false
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
this.#resumeUpstreamIfNeeded()
|
|
234
|
+
this.#finishIfReady()
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
#finishIfReady () {
|
|
238
|
+
if (this.#terminated || !this.#completionPending || this.#controller.paused || this.#draining) {
|
|
239
|
+
return
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
this.#terminated = true
|
|
243
|
+
this.#cleanupDecompressors()
|
|
244
|
+
super.onResponseEnd(this.#controller, this.#trailers)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
#onDecompressionEnd () {
|
|
248
|
+
if (this.#terminated) {
|
|
249
|
+
return
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
this.#completionPending = true
|
|
253
|
+
this.#drainOutput()
|
|
254
|
+
this.#finishIfReady()
|
|
86
255
|
}
|
|
87
256
|
|
|
88
257
|
/**
|
|
@@ -138,7 +307,7 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
138
307
|
const streams = []
|
|
139
308
|
for (let i = 0; i < decompressors.length; i++) {
|
|
140
309
|
streams.push(decompressors[i])
|
|
141
|
-
if (i < decompressors.length - 1) {
|
|
310
|
+
if (i < decompressors.length - 1 && this.#maxSize > 0) {
|
|
142
311
|
streams.push(createMaxSizeLimiter(this.#maxSize))
|
|
143
312
|
}
|
|
144
313
|
}
|
|
@@ -148,11 +317,10 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
148
317
|
|
|
149
318
|
/**
|
|
150
319
|
* Stops decompression and reports an error.
|
|
151
|
-
* @param {Controller} controller - The controller to coordinate with
|
|
152
320
|
* @param {Error} error - The decompression error
|
|
153
321
|
* @returns {void}
|
|
154
322
|
*/
|
|
155
|
-
#fail (
|
|
323
|
+
#fail (error) {
|
|
156
324
|
if (this.#terminated) {
|
|
157
325
|
return
|
|
158
326
|
}
|
|
@@ -160,75 +328,41 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
160
328
|
if (this.#inputEnded) {
|
|
161
329
|
// The request is already marked complete once the compressed input ends,
|
|
162
330
|
// so controller.abort() can no longer propagate decoder flush errors.
|
|
163
|
-
this.onResponseError(controller, error)
|
|
331
|
+
this.onResponseError(this.#controller, error)
|
|
164
332
|
} else {
|
|
165
|
-
controller.abort(error)
|
|
333
|
+
this.#controller.abort(error)
|
|
166
334
|
}
|
|
167
335
|
}
|
|
168
336
|
|
|
169
337
|
/**
|
|
170
|
-
* Sets up event handlers for
|
|
338
|
+
* Sets up event handlers for the final decompressor stream.
|
|
171
339
|
* @param {DecompressorStream} decompressor - The decompressor stream
|
|
172
|
-
* @param {Controller} controller - The controller to coordinate with
|
|
173
340
|
* @returns {void}
|
|
174
341
|
*/
|
|
175
|
-
#setupDecompressorEvents (decompressor
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
let chunk
|
|
182
|
-
while ((chunk = decompressor.read()) !== null) {
|
|
183
|
-
const decompressedSize = this.#decompressedSize + chunk.length
|
|
184
|
-
if (decompressedSize > this.#maxSize) {
|
|
185
|
-
this.#fail(controller, new ResponseExceededMaxSizeError(
|
|
186
|
-
`Decompressed response size (${decompressedSize}) exceeded maxSize (${this.#maxSize})`
|
|
187
|
-
))
|
|
188
|
-
return
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
this.#decompressedSize = decompressedSize
|
|
192
|
-
const result = super.onResponseData(controller, chunk)
|
|
193
|
-
if (result === false) {
|
|
194
|
-
break
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
decompressor.on('error', (error) => {
|
|
200
|
-
this.#fail(controller, error)
|
|
201
|
-
})
|
|
342
|
+
#setupDecompressorEvents (decompressor) {
|
|
343
|
+
this.#finalDecompressor = decompressor
|
|
344
|
+
decompressor.on('readable', () => this.#drainOutput())
|
|
345
|
+
decompressor.on('error', (error) => this.#fail(error))
|
|
202
346
|
}
|
|
203
347
|
|
|
204
348
|
/**
|
|
205
349
|
* Sets up event handling for a single decompressor
|
|
206
|
-
* @param {Controller} controller - The controller to handle events
|
|
207
350
|
* @returns {void}
|
|
208
351
|
*/
|
|
209
|
-
#setupSingleDecompressor (
|
|
352
|
+
#setupSingleDecompressor () {
|
|
210
353
|
const decompressor = this.#decompressors[0]
|
|
211
|
-
this.#setupDecompressorEvents(decompressor
|
|
354
|
+
this.#setupDecompressorEvents(decompressor)
|
|
212
355
|
|
|
213
|
-
decompressor.on('end', () =>
|
|
214
|
-
if (this.#terminated) {
|
|
215
|
-
return
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
this.#terminated = true
|
|
219
|
-
this.#cleanupDecompressors()
|
|
220
|
-
super.onResponseEnd(controller, this.#trailers)
|
|
221
|
-
})
|
|
356
|
+
decompressor.on('end', () => this.#onDecompressionEnd())
|
|
222
357
|
}
|
|
223
358
|
|
|
224
359
|
/**
|
|
225
360
|
* Sets up event handling for multiple chained decompressors using pipeline
|
|
226
|
-
* @param {Controller} controller - The controller to handle events
|
|
227
361
|
* @returns {void}
|
|
228
362
|
*/
|
|
229
|
-
#setupMultipleDecompressors (
|
|
363
|
+
#setupMultipleDecompressors () {
|
|
230
364
|
const lastDecompressor = this.#decompressors[this.#decompressors.length - 1]
|
|
231
|
-
this.#setupDecompressorEvents(lastDecompressor
|
|
365
|
+
this.#setupDecompressorEvents(lastDecompressor)
|
|
232
366
|
|
|
233
367
|
pipeline(this.#decompressors, (err) => {
|
|
234
368
|
if (this.#terminated) {
|
|
@@ -236,13 +370,26 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
236
370
|
}
|
|
237
371
|
|
|
238
372
|
if (err) {
|
|
239
|
-
this.#fail(
|
|
373
|
+
this.#fail(err)
|
|
240
374
|
return
|
|
241
375
|
}
|
|
242
376
|
|
|
243
|
-
this.#
|
|
244
|
-
|
|
245
|
-
|
|
377
|
+
this.#onDecompressionEnd()
|
|
378
|
+
})
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
#setupInputBackpressure () {
|
|
382
|
+
const decompressor = this.#decompressors[0]
|
|
383
|
+
decompressor.on('drain', () => {
|
|
384
|
+
if (this.#terminated) {
|
|
385
|
+
return
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
this.#inputBackpressured = false
|
|
389
|
+
if (!this.#controller.paused) {
|
|
390
|
+
this.#drainOutput()
|
|
391
|
+
this.#resumeUpstreamIfNeeded()
|
|
392
|
+
}
|
|
246
393
|
})
|
|
247
394
|
}
|
|
248
395
|
|
|
@@ -252,6 +399,16 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
252
399
|
*/
|
|
253
400
|
#cleanupDecompressors () {
|
|
254
401
|
this.#decompressors.length = 0
|
|
402
|
+
this.#finalDecompressor = undefined
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
onRequestStart (controller, context) {
|
|
406
|
+
this.#controller.target = controller
|
|
407
|
+
return super.onRequestStart(this.#controller, context)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
onRequestUpgrade (controller, statusCode, headers, socket) {
|
|
411
|
+
return super.onRequestUpgrade(this.#controller, statusCode, headers, socket)
|
|
255
412
|
}
|
|
256
413
|
|
|
257
414
|
/**
|
|
@@ -262,18 +419,24 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
262
419
|
* @returns {void}
|
|
263
420
|
*/
|
|
264
421
|
onResponseStart (controller, statusCode, headers, statusMessage) {
|
|
265
|
-
|
|
422
|
+
// Repeated field lines reach us as an array. RFC 9110 section 5.3 lets a
|
|
423
|
+
// recipient join them with commas, which yields the single-line form the
|
|
424
|
+
// decompression chain already handles.
|
|
425
|
+
const rawContentEncoding = headers['content-encoding']
|
|
426
|
+
const contentEncoding = Array.isArray(rawContentEncoding)
|
|
427
|
+
? rawContentEncoding.join(',')
|
|
428
|
+
: rawContentEncoding
|
|
266
429
|
|
|
267
430
|
// If content encoding is not supported or status code is in skip list
|
|
268
431
|
if (this.#shouldSkipDecompression(contentEncoding, statusCode)) {
|
|
269
|
-
return super.onResponseStart(controller, statusCode, headers, statusMessage)
|
|
432
|
+
return super.onResponseStart(this.#controller, statusCode, headers, statusMessage)
|
|
270
433
|
}
|
|
271
434
|
|
|
272
435
|
const decompressors = this.#createDecompressionChain(contentEncoding.toLowerCase())
|
|
273
436
|
|
|
274
437
|
if (decompressors.length === 0) {
|
|
275
438
|
this.#cleanupDecompressors()
|
|
276
|
-
return super.onResponseStart(controller, statusCode, headers, statusMessage)
|
|
439
|
+
return super.onResponseStart(this.#controller, statusCode, headers, statusMessage)
|
|
277
440
|
}
|
|
278
441
|
|
|
279
442
|
this.#decompressors = decompressors
|
|
@@ -281,8 +444,8 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
281
444
|
// Remove compression headers since we're decompressing
|
|
282
445
|
const { 'content-encoding': _, 'content-length': __, ...newHeaders } = headers
|
|
283
446
|
|
|
284
|
-
if (controller
|
|
285
|
-
const rawHeaders = controller.rawHeaders
|
|
447
|
+
if (this.#controller.rawHeaders) {
|
|
448
|
+
const rawHeaders = this.#controller.rawHeaders
|
|
286
449
|
|
|
287
450
|
if (Array.isArray(rawHeaders)) {
|
|
288
451
|
const filteredHeaders = []
|
|
@@ -308,13 +471,14 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
308
471
|
}
|
|
309
472
|
}
|
|
310
473
|
|
|
474
|
+
this.#setupInputBackpressure()
|
|
311
475
|
if (this.#decompressors.length === 1) {
|
|
312
|
-
this.#setupSingleDecompressor(
|
|
476
|
+
this.#setupSingleDecompressor()
|
|
313
477
|
} else {
|
|
314
|
-
this.#setupMultipleDecompressors(
|
|
478
|
+
this.#setupMultipleDecompressors()
|
|
315
479
|
}
|
|
316
480
|
|
|
317
|
-
return super.onResponseStart(controller, statusCode, newHeaders, statusMessage)
|
|
481
|
+
return super.onResponseStart(this.#controller, statusCode, newHeaders, statusMessage)
|
|
318
482
|
}
|
|
319
483
|
|
|
320
484
|
/**
|
|
@@ -324,10 +488,13 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
324
488
|
*/
|
|
325
489
|
onResponseData (controller, chunk) {
|
|
326
490
|
if (this.#decompressors.length > 0) {
|
|
327
|
-
this.#decompressors[0].write(chunk)
|
|
491
|
+
if (!this.#decompressors[0].write(chunk)) {
|
|
492
|
+
this.#inputBackpressured = true
|
|
493
|
+
this.#pauseUpstream()
|
|
494
|
+
}
|
|
328
495
|
return
|
|
329
496
|
}
|
|
330
|
-
super.onResponseData(controller, chunk)
|
|
497
|
+
return super.onResponseData(this.#controller, chunk)
|
|
331
498
|
}
|
|
332
499
|
|
|
333
500
|
/**
|
|
@@ -342,7 +509,7 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
342
509
|
this.#decompressors[0].end()
|
|
343
510
|
return
|
|
344
511
|
}
|
|
345
|
-
super.onResponseEnd(controller, trailers)
|
|
512
|
+
return super.onResponseEnd(this.#controller, trailers)
|
|
346
513
|
}
|
|
347
514
|
|
|
348
515
|
/**
|
|
@@ -360,7 +527,7 @@ class DecompressHandler extends DecoratorHandler {
|
|
|
360
527
|
decompressor.destroy()
|
|
361
528
|
}
|
|
362
529
|
this.#cleanupDecompressors()
|
|
363
|
-
super.onResponseError(controller, err)
|
|
530
|
+
super.onResponseError(this.#controller, err)
|
|
364
531
|
}
|
|
365
532
|
}
|
|
366
533
|
|
|
@@ -41,7 +41,7 @@ class Cache {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
async match (request, options = {}) {
|
|
44
|
-
webidl.brandCheck(this, Cache)
|
|
44
|
+
webidl.brandCheck(this, webidl.is.Cache)
|
|
45
45
|
|
|
46
46
|
const prefix = 'Cache.match'
|
|
47
47
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
@@ -59,7 +59,7 @@ class Cache {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
async matchAll (request = undefined, options = {}) {
|
|
62
|
-
webidl.brandCheck(this, Cache)
|
|
62
|
+
webidl.brandCheck(this, webidl.is.Cache)
|
|
63
63
|
|
|
64
64
|
const prefix = 'Cache.matchAll'
|
|
65
65
|
if (request !== undefined) request = webidl.converters.RequestInfo(request)
|
|
@@ -69,7 +69,7 @@ class Cache {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
async add (request) {
|
|
72
|
-
webidl.brandCheck(this, Cache)
|
|
72
|
+
webidl.brandCheck(this, webidl.is.Cache)
|
|
73
73
|
|
|
74
74
|
const prefix = 'Cache.add'
|
|
75
75
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
@@ -87,7 +87,7 @@ class Cache {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
async addAll (requests) {
|
|
90
|
-
webidl.brandCheck(this, Cache)
|
|
90
|
+
webidl.brandCheck(this, webidl.is.Cache)
|
|
91
91
|
|
|
92
92
|
const prefix = 'Cache.addAll'
|
|
93
93
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
@@ -185,7 +185,10 @@ class Cache {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
},
|
|
188
|
-
processResponseEndOfBody (
|
|
188
|
+
// Possible spec bug. If the body is never read, `processResponseEndOfBody` (which is attached to a TransformStream's flush hook)
|
|
189
|
+
// never runs, so this would hang. This hook, on the other hand, always reads the body.
|
|
190
|
+
// https://github.com/nodejs/undici/issues/5615
|
|
191
|
+
processResponseConsumeBody (response) {
|
|
189
192
|
// 1.
|
|
190
193
|
if (response.aborted) {
|
|
191
194
|
responsePromise.reject(new DOMException('aborted', 'AbortError'))
|
|
@@ -257,7 +260,7 @@ class Cache {
|
|
|
257
260
|
}
|
|
258
261
|
|
|
259
262
|
async put (request, response) {
|
|
260
|
-
webidl.brandCheck(this, Cache)
|
|
263
|
+
webidl.brandCheck(this, webidl.is.Cache)
|
|
261
264
|
|
|
262
265
|
const prefix = 'Cache.put'
|
|
263
266
|
webidl.argumentLengthCheck(arguments, 2, prefix)
|
|
@@ -388,7 +391,7 @@ class Cache {
|
|
|
388
391
|
}
|
|
389
392
|
|
|
390
393
|
async delete (request, options = {}) {
|
|
391
|
-
webidl.brandCheck(this, Cache)
|
|
394
|
+
webidl.brandCheck(this, webidl.is.Cache)
|
|
392
395
|
|
|
393
396
|
const prefix = 'Cache.delete'
|
|
394
397
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
@@ -454,7 +457,7 @@ class Cache {
|
|
|
454
457
|
* @returns {Promise<readonly Request[]>}
|
|
455
458
|
*/
|
|
456
459
|
async keys (request = undefined, options = {}) {
|
|
457
|
-
webidl.brandCheck(this, Cache)
|
|
460
|
+
webidl.brandCheck(this, webidl.is.Cache)
|
|
458
461
|
|
|
459
462
|
const prefix = 'Cache.keys'
|
|
460
463
|
|
|
@@ -804,6 +807,12 @@ class Cache {
|
|
|
804
807
|
// 6.
|
|
805
808
|
return Object.freeze(responseList)
|
|
806
809
|
}
|
|
810
|
+
|
|
811
|
+
static {
|
|
812
|
+
webidl.is.Cache = (arg) => {
|
|
813
|
+
return arg != null && typeof arg === 'object' && #relevantRequestResponseList in arg
|
|
814
|
+
}
|
|
815
|
+
}
|
|
807
816
|
}
|
|
808
817
|
|
|
809
818
|
Object.defineProperties(Cache.prototype, {
|
|
@@ -21,7 +21,7 @@ class CacheStorage {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
async match (request, options = {}) {
|
|
24
|
-
webidl.brandCheck(this, CacheStorage)
|
|
24
|
+
webidl.brandCheck(this, webidl.is.CacheStorage)
|
|
25
25
|
webidl.argumentLengthCheck(arguments, 1, 'CacheStorage.match')
|
|
26
26
|
|
|
27
27
|
request = webidl.converters.RequestInfo(request)
|
|
@@ -58,7 +58,7 @@ class CacheStorage {
|
|
|
58
58
|
* @returns {Promise<boolean>}
|
|
59
59
|
*/
|
|
60
60
|
async has (cacheName) {
|
|
61
|
-
webidl.brandCheck(this, CacheStorage)
|
|
61
|
+
webidl.brandCheck(this, webidl.is.CacheStorage)
|
|
62
62
|
|
|
63
63
|
const prefix = 'CacheStorage.has'
|
|
64
64
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
@@ -76,7 +76,7 @@ class CacheStorage {
|
|
|
76
76
|
* @returns {Promise<Cache>}
|
|
77
77
|
*/
|
|
78
78
|
async open (cacheName) {
|
|
79
|
-
webidl.brandCheck(this, CacheStorage)
|
|
79
|
+
webidl.brandCheck(this, webidl.is.CacheStorage)
|
|
80
80
|
|
|
81
81
|
const prefix = 'CacheStorage.open'
|
|
82
82
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
@@ -110,7 +110,7 @@ class CacheStorage {
|
|
|
110
110
|
* @returns {Promise<boolean>}
|
|
111
111
|
*/
|
|
112
112
|
async delete (cacheName) {
|
|
113
|
-
webidl.brandCheck(this, CacheStorage)
|
|
113
|
+
webidl.brandCheck(this, webidl.is.CacheStorage)
|
|
114
114
|
|
|
115
115
|
const prefix = 'CacheStorage.delete'
|
|
116
116
|
webidl.argumentLengthCheck(arguments, 1, prefix)
|
|
@@ -125,7 +125,7 @@ class CacheStorage {
|
|
|
125
125
|
* @returns {Promise<string[]>}
|
|
126
126
|
*/
|
|
127
127
|
async keys () {
|
|
128
|
-
webidl.brandCheck(this, CacheStorage)
|
|
128
|
+
webidl.brandCheck(this, webidl.is.CacheStorage)
|
|
129
129
|
|
|
130
130
|
// 2.1
|
|
131
131
|
const keys = this.#caches.keys()
|
|
@@ -133,6 +133,12 @@ class CacheStorage {
|
|
|
133
133
|
// 2.2
|
|
134
134
|
return [...keys]
|
|
135
135
|
}
|
|
136
|
+
|
|
137
|
+
static {
|
|
138
|
+
webidl.is.CacheStorage = (arg) => {
|
|
139
|
+
return arg != null && typeof arg === 'object' && #caches in arg
|
|
140
|
+
}
|
|
141
|
+
}
|
|
136
142
|
}
|
|
137
143
|
|
|
138
144
|
Object.defineProperties(CacheStorage.prototype, {
|
|
@@ -3,9 +3,19 @@
|
|
|
3
3
|
const { parseSetCookie } = require('./parse')
|
|
4
4
|
const { stringify } = require('./util')
|
|
5
5
|
const { webidl } = require('../webidl')
|
|
6
|
-
const { Headers } = require('../fetch/headers')
|
|
7
6
|
|
|
8
|
-
const
|
|
7
|
+
const globalHeadersBrandCheck = (arg) => webidl.brandCheck(arg, webidl.util.MakeTypeAssertion(globalThis.Headers))
|
|
8
|
+
const undiciHeadersBrandCheck = (arg) => webidl.brandCheck(arg, webidl.is.Headers)
|
|
9
|
+
|
|
10
|
+
function brandCheckHeaders (arg) {
|
|
11
|
+
try {
|
|
12
|
+
undiciHeadersBrandCheck(arg)
|
|
13
|
+
return
|
|
14
|
+
} catch {
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
globalHeadersBrandCheck(arg)
|
|
18
|
+
}
|
|
9
19
|
|
|
10
20
|
/**
|
|
11
21
|
* @typedef {Object} Cookie
|
|
@@ -28,12 +38,14 @@ const brandChecks = webidl.brandCheckMultiple([Headers, globalThis.Headers].filt
|
|
|
28
38
|
function getCookies (headers) {
|
|
29
39
|
webidl.argumentLengthCheck(arguments, 1, 'getCookies')
|
|
30
40
|
|
|
31
|
-
|
|
41
|
+
brandCheckHeaders(headers)
|
|
32
42
|
|
|
33
43
|
const cookie = headers.get('cookie')
|
|
34
44
|
|
|
45
|
+
// A null prototype keeps a cookie named `__proto__` from hitting the
|
|
46
|
+
// Object.prototype setter, which would silently drop it.
|
|
35
47
|
/** @type {Record<string, string>} */
|
|
36
|
-
const out = {}
|
|
48
|
+
const out = { __proto__: null }
|
|
37
49
|
|
|
38
50
|
if (!cookie) {
|
|
39
51
|
return out
|
|
@@ -55,7 +67,7 @@ function getCookies (headers) {
|
|
|
55
67
|
* @returns {void}
|
|
56
68
|
*/
|
|
57
69
|
function deleteCookie (headers, name, attributes) {
|
|
58
|
-
|
|
70
|
+
brandCheckHeaders(headers)
|
|
59
71
|
|
|
60
72
|
const prefix = 'deleteCookie'
|
|
61
73
|
webidl.argumentLengthCheck(arguments, 2, prefix)
|
|
@@ -80,7 +92,7 @@ function deleteCookie (headers, name, attributes) {
|
|
|
80
92
|
function getSetCookies (headers) {
|
|
81
93
|
webidl.argumentLengthCheck(arguments, 1, 'getSetCookies')
|
|
82
94
|
|
|
83
|
-
|
|
95
|
+
brandCheckHeaders(headers)
|
|
84
96
|
|
|
85
97
|
const cookies = headers.getSetCookie()
|
|
86
98
|
|
|
@@ -109,7 +121,7 @@ function parseCookie (cookie) {
|
|
|
109
121
|
function setCookie (headers, cookie) {
|
|
110
122
|
webidl.argumentLengthCheck(arguments, 2, 'setCookie')
|
|
111
123
|
|
|
112
|
-
|
|
124
|
+
brandCheckHeaders(headers)
|
|
113
125
|
|
|
114
126
|
cookie = webidl.converters.Cookie(cookie)
|
|
115
127
|
|
|
@@ -315,7 +315,9 @@ function stringify (cookie) {
|
|
|
315
315
|
out.push(`Path=${cookie.path}`)
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
-
|
|
318
|
+
// A numeric 0 is the Unix epoch, not an absent value -- the same reason the
|
|
319
|
+
// Max-Age check above tests the type rather than truthiness.
|
|
320
|
+
if (cookie.expires != null && cookie.expires.toString() !== 'Invalid Date') {
|
|
319
321
|
out.push(`Expires=${toIMFDate(cookie.expires)}`)
|
|
320
322
|
}
|
|
321
323
|
|