@nxtedition/nxt-undici 6.0.19 → 6.0.21
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/lib/interceptor/cache.js +23 -25
- package/lib/interceptor/response-retry.js +11 -9
- package/lib/utils.js +29 -10
- package/package.json +1 -1
package/lib/interceptor/cache.js
CHANGED
|
@@ -3,6 +3,7 @@ import { DecoratorHandler, parseCacheControl } from '../utils.js'
|
|
|
3
3
|
|
|
4
4
|
const DEFAULT_STORE = new undici.cacheStores.SqliteCacheStore({ location: ':memory:' })
|
|
5
5
|
const MAX_ENTRY_SIZE = 128 * 1024
|
|
6
|
+
const EMPTY_BUFFER = Buffer.alloc(0)
|
|
6
7
|
|
|
7
8
|
class CacheHandler extends DecoratorHandler {
|
|
8
9
|
#key
|
|
@@ -164,40 +165,37 @@ export default () => (dispatch) => (opts, handler) => {
|
|
|
164
165
|
)
|
|
165
166
|
}
|
|
166
167
|
|
|
168
|
+
const { statusCode, headers, body } = entry ?? { statusCode: 504, headers: {} }
|
|
169
|
+
|
|
167
170
|
let aborted = false
|
|
168
|
-
let paused = false
|
|
169
171
|
const abort = (reason) => {
|
|
170
172
|
if (!aborted) {
|
|
171
173
|
aborted = true
|
|
172
174
|
handler.onError(reason)
|
|
173
175
|
}
|
|
174
176
|
}
|
|
175
|
-
const resume = () => {
|
|
176
|
-
if (paused && !aborted) {
|
|
177
|
-
handler.onComplete()
|
|
178
|
-
paused = false
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
177
|
|
|
182
|
-
|
|
183
|
-
try {
|
|
184
|
-
handler.onConnect(abort)
|
|
185
|
-
if (aborted) {
|
|
186
|
-
return
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (handler.onHeaders(statusCode, headers, resume) === false) {
|
|
190
|
-
paused = true
|
|
191
|
-
}
|
|
178
|
+
let state = 0
|
|
192
179
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
180
|
+
const resume = () => {
|
|
181
|
+
try {
|
|
182
|
+
let paused = false
|
|
183
|
+
while (!paused && !aborted) {
|
|
184
|
+
state += 1
|
|
185
|
+
if (state === 1) {
|
|
186
|
+
handler.onConnect(abort)
|
|
187
|
+
} else if (state === 2) {
|
|
188
|
+
paused = handler.onHeaders(statusCode, headers, resume) === false
|
|
189
|
+
} else if (state === 3) {
|
|
190
|
+
paused = handler.onData(body ?? EMPTY_BUFFER) === false
|
|
191
|
+
} else if (state === 4) {
|
|
192
|
+
handler.onComplete({})
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
} catch (err) {
|
|
196
|
+
abort(err)
|
|
199
197
|
}
|
|
200
|
-
} catch (err) {
|
|
201
|
-
abort(err)
|
|
202
198
|
}
|
|
199
|
+
|
|
200
|
+
resume()
|
|
203
201
|
}
|
|
@@ -64,8 +64,6 @@ class Handler extends DecoratorHandler {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
onHeaders(statusCode, headers, resume) {
|
|
67
|
-
this.#resume = resume
|
|
68
|
-
|
|
69
67
|
if (this.#error == null) {
|
|
70
68
|
assert(this.#etag == null)
|
|
71
69
|
assert(this.#pos == null)
|
|
@@ -73,18 +71,18 @@ class Handler extends DecoratorHandler {
|
|
|
73
71
|
assert(this.#headersSent === false)
|
|
74
72
|
|
|
75
73
|
if (headers.trailer) {
|
|
76
|
-
return this.#onHeaders(statusCode, headers)
|
|
74
|
+
return this.#onHeaders(statusCode, headers, resume)
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
const contentLength = headers['content-length'] ? Number(headers['content-length']) : null
|
|
80
78
|
if (contentLength != null && !Number.isFinite(contentLength)) {
|
|
81
|
-
return this.#onHeaders(statusCode, headers)
|
|
79
|
+
return this.#onHeaders(statusCode, headers, resume)
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
if (statusCode === 206) {
|
|
85
83
|
const range = parseRangeHeader(headers['content-range'])
|
|
86
84
|
if (!range) {
|
|
87
|
-
return this.#onHeaders(statusCode, headers)
|
|
85
|
+
return this.#onHeaders(statusCode, headers, resume)
|
|
88
86
|
}
|
|
89
87
|
|
|
90
88
|
const { start, size, end = size } = range
|
|
@@ -104,7 +102,7 @@ class Handler extends DecoratorHandler {
|
|
|
104
102
|
this.#end = contentLength
|
|
105
103
|
this.#etag = headers.etag
|
|
106
104
|
} else {
|
|
107
|
-
return this.#onHeaders(statusCode, headers)
|
|
105
|
+
return this.#onHeaders(statusCode, headers, resume)
|
|
108
106
|
}
|
|
109
107
|
|
|
110
108
|
// Weak etags are not useful for comparison nor cache
|
|
@@ -117,7 +115,9 @@ class Handler extends DecoratorHandler {
|
|
|
117
115
|
assert(Number.isFinite(this.#pos))
|
|
118
116
|
assert(this.#end == null || Number.isFinite(this.#end))
|
|
119
117
|
|
|
120
|
-
|
|
118
|
+
this.#resume = resume
|
|
119
|
+
|
|
120
|
+
return this.#onHeaders(statusCode, headers, () => this.#resume?.())
|
|
121
121
|
} else if (statusCode === 206 || (this.#pos === 0 && statusCode === 200)) {
|
|
122
122
|
assert(this.#etag != null || !this.#pos)
|
|
123
123
|
|
|
@@ -134,6 +134,8 @@ class Handler extends DecoratorHandler {
|
|
|
134
134
|
assert(this.#pos === start, 'content-range mismatch')
|
|
135
135
|
assert(this.#end == null || this.#end === end, 'content-range mismatch')
|
|
136
136
|
|
|
137
|
+
this.#resume = resume
|
|
138
|
+
|
|
137
139
|
// TODO (fix): What if we were paused before the error?
|
|
138
140
|
return true
|
|
139
141
|
} else {
|
|
@@ -211,10 +213,10 @@ class Handler extends DecoratorHandler {
|
|
|
211
213
|
super.onError(err)
|
|
212
214
|
}
|
|
213
215
|
|
|
214
|
-
#onHeaders(statusCode, headers) {
|
|
216
|
+
#onHeaders(statusCode, headers, resume) {
|
|
215
217
|
assert(!this.#headersSent)
|
|
216
218
|
this.#headersSent = true
|
|
217
|
-
return super.onHeaders(statusCode, headers,
|
|
219
|
+
return super.onHeaders(statusCode, headers, resume)
|
|
218
220
|
}
|
|
219
221
|
}
|
|
220
222
|
|
package/lib/utils.js
CHANGED
|
@@ -256,6 +256,8 @@ export function bodyLength(body) {
|
|
|
256
256
|
|
|
257
257
|
export class DecoratorHandler {
|
|
258
258
|
#handler
|
|
259
|
+
#aborted = false
|
|
260
|
+
#errored = false
|
|
259
261
|
|
|
260
262
|
constructor(handler) {
|
|
261
263
|
if (typeof handler !== 'object' || handler === null) {
|
|
@@ -264,28 +266,45 @@ export class DecoratorHandler {
|
|
|
264
266
|
this.#handler = handler
|
|
265
267
|
}
|
|
266
268
|
|
|
267
|
-
onConnect(
|
|
268
|
-
|
|
269
|
+
onConnect(abort) {
|
|
270
|
+
this.#aborted = false
|
|
271
|
+
this.#errored = false
|
|
272
|
+
|
|
273
|
+
return this.#handler.onConnect?.((reason) => {
|
|
274
|
+
this.#aborted = true
|
|
275
|
+
abort(reason)
|
|
276
|
+
})
|
|
269
277
|
}
|
|
270
278
|
|
|
271
279
|
onUpgrade(...args) {
|
|
272
|
-
|
|
280
|
+
if (!this.#aborted && !this.#errored) {
|
|
281
|
+
return this.#handler.onUpgrade?.(...args)
|
|
282
|
+
}
|
|
273
283
|
}
|
|
274
284
|
|
|
275
285
|
onHeaders(...args) {
|
|
276
|
-
|
|
286
|
+
if (!this.#aborted && !this.#errored) {
|
|
287
|
+
return this.#handler.onHeaders?.(...args)
|
|
288
|
+
}
|
|
277
289
|
}
|
|
278
290
|
|
|
279
|
-
onData(
|
|
280
|
-
|
|
291
|
+
onData(data) {
|
|
292
|
+
if (!this.#aborted && !this.#errored && data != null) {
|
|
293
|
+
return this.#handler.onData?.(data)
|
|
294
|
+
}
|
|
281
295
|
}
|
|
282
296
|
|
|
283
|
-
onComplete(
|
|
284
|
-
|
|
297
|
+
onComplete(trailers) {
|
|
298
|
+
if (!this.#aborted && !this.#errored) {
|
|
299
|
+
return this.#handler.onComplete?.(trailers)
|
|
300
|
+
}
|
|
285
301
|
}
|
|
286
302
|
|
|
287
|
-
onError(
|
|
288
|
-
|
|
303
|
+
onError(err) {
|
|
304
|
+
if (!this.#errored) {
|
|
305
|
+
this.#errored = true
|
|
306
|
+
return this.#handler.onError?.(err)
|
|
307
|
+
}
|
|
289
308
|
}
|
|
290
309
|
}
|
|
291
310
|
|