@nxtedition/lib 15.0.31 → 15.0.33
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/undici/index.js +38 -19
- package/lib/undici/interceptor/abort.js +4 -0
- package/lib/undici/interceptor/cache.js +6 -1
- package/lib/undici/interceptor/catch.js +8 -0
- package/lib/undici/interceptor/content.js +4 -0
- package/lib/undici/interceptor/log.js +8 -0
- package/lib/undici/interceptor/proxy.js +36 -17
- package/lib/undici/interceptor/redirect.js +16 -10
- package/lib/undici/interceptor/response-body-retry.js +21 -19
- package/lib/undici/interceptor/response-retry.js +20 -15
- package/lib/undici/interceptor/response-status-retry.js +26 -18
- package/lib/undici/interceptor/signal.js +4 -0
- package/lib/undici/utils.js +23 -11
- package/package.json +1 -1
- package/util/template/index.js +11 -6
package/lib/undici/index.js
CHANGED
|
@@ -77,17 +77,13 @@ const dispatchers = {
|
|
|
77
77
|
cache: require('./interceptor/cache.js'),
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
async function request(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
url = urlOrOpts
|
|
88
|
-
} else if (typeof urlOrOpts === 'object' && urlOrOpts != null) {
|
|
89
|
-
opts = urlOrOpts
|
|
90
|
-
url = opts.url
|
|
80
|
+
async function request(url, opts = {}) {
|
|
81
|
+
if (typeof url === 'string') {
|
|
82
|
+
url = new URL(url)
|
|
83
|
+
} else if (url instanceof URL) {
|
|
84
|
+
// Do nothing...
|
|
85
|
+
} else {
|
|
86
|
+
throw new Error('missing url')
|
|
91
87
|
}
|
|
92
88
|
|
|
93
89
|
const method = opts.method ?? (opts.body ? 'POST' : 'GET')
|
|
@@ -100,6 +96,17 @@ async function request(urlOrOpts, opts = {}) {
|
|
|
100
96
|
headers = opts.headers
|
|
101
97
|
}
|
|
102
98
|
|
|
99
|
+
if (method === 'CONNECT') {
|
|
100
|
+
throw new createError.MethodNotAllowed()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (
|
|
104
|
+
(method === 'HEAD' || method === 'GET') &&
|
|
105
|
+
(parseInt(headers['content-length']) > 0 || headers['transfer-encoding'])
|
|
106
|
+
) {
|
|
107
|
+
throw new createError.BadRequest('HEAD and GET cannot have body')
|
|
108
|
+
}
|
|
109
|
+
|
|
103
110
|
opts = {
|
|
104
111
|
url,
|
|
105
112
|
method,
|
|
@@ -109,16 +116,20 @@ async function request(urlOrOpts, opts = {}) {
|
|
|
109
116
|
'user-agent': opts.userAgent ?? globalThis.userAgent,
|
|
110
117
|
...headers,
|
|
111
118
|
},
|
|
112
|
-
origin:
|
|
113
|
-
path:
|
|
119
|
+
origin: url.origin,
|
|
120
|
+
path: url.search ? `${url.pathname}${url.search ?? ''}` : url.pathname,
|
|
114
121
|
reset: opts.reset ?? false,
|
|
115
122
|
headersTimeout: opts.headersTimeout,
|
|
116
123
|
bodyTimeout: opts.bodyTimeout,
|
|
117
124
|
idempotent,
|
|
118
125
|
signal: opts.signal,
|
|
119
126
|
retry: opts.retry ?? 8,
|
|
127
|
+
proxy: opts.proxy,
|
|
128
|
+
cache: opts.cache,
|
|
129
|
+
upgrade: opts.upgrade,
|
|
120
130
|
follow: { count: opts.maxRedirections ?? 8, ...opts.redirect, ...opts.follow },
|
|
121
131
|
logger: opts.logger,
|
|
132
|
+
maxRedirections: 0, // Disable undici's redirect handling.
|
|
122
133
|
}
|
|
123
134
|
|
|
124
135
|
const expectsPayload = opts.method === 'PUT' || opts.method === 'POST' || opts.method === 'PATCH'
|
|
@@ -141,15 +152,14 @@ async function request(urlOrOpts, opts = {}) {
|
|
|
141
152
|
dispatch = dispatchers.catch(dispatch)
|
|
142
153
|
dispatch = dispatchers.abort(dispatch)
|
|
143
154
|
dispatch = dispatchers.log(dispatch)
|
|
144
|
-
dispatch = dispatchers.responseRetry(dispatch)
|
|
145
|
-
dispatch = dispatchers.responseStatusRetry(dispatch)
|
|
146
|
-
dispatch = dispatchers.responseBodyRetry(dispatch)
|
|
147
|
-
dispatch = dispatchers.content(dispatch)
|
|
148
|
-
dispatch = dispatchers.responseBodyDump(dispatch)
|
|
155
|
+
dispatch = opts.upgrade ? dispatch : dispatchers.responseRetry(dispatch)
|
|
156
|
+
dispatch = opts.upgrade ? dispatch : dispatchers.responseStatusRetry(dispatch)
|
|
157
|
+
dispatch = opts.upgrade ? dispatch : dispatchers.responseBodyRetry(dispatch)
|
|
158
|
+
dispatch = opts.upgrade ? dispatch : dispatchers.content(dispatch)
|
|
149
159
|
dispatch = dispatchers.redirect(dispatch)
|
|
150
160
|
dispatch = dispatchers.signal(dispatch)
|
|
161
|
+
dispatch = opts.upgrade ? dispatch : dispatchers.cache(dispatch)
|
|
151
162
|
dispatch = dispatchers.proxy(dispatch)
|
|
152
|
-
dispatch = dispatchers.cache(dispatch)
|
|
153
163
|
|
|
154
164
|
dispatch(opts, {
|
|
155
165
|
resolve,
|
|
@@ -159,6 +169,15 @@ async function request(urlOrOpts, opts = {}) {
|
|
|
159
169
|
onConnect(abort) {
|
|
160
170
|
this.abort = abort
|
|
161
171
|
},
|
|
172
|
+
onUpgrade(statusCode, rawHeaders, socket) {
|
|
173
|
+
const headers = parseHeaders(rawHeaders)
|
|
174
|
+
|
|
175
|
+
if (statusCode !== 101) {
|
|
176
|
+
this.abort(createError(statusCode, { headers }))
|
|
177
|
+
} else {
|
|
178
|
+
this.resolve({ headers, socket })
|
|
179
|
+
}
|
|
180
|
+
},
|
|
162
181
|
onHeaders(statusCode, rawHeaders, resume, statusMessage) {
|
|
163
182
|
assert(this.abort)
|
|
164
183
|
|
|
@@ -18,6 +18,10 @@ class Handler {
|
|
|
18
18
|
return this.handler.onBodySent?.(chunk)
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
onUpgrade(statusCode, rawHeaders, socket) {
|
|
22
|
+
return this.handler.onUpgrade?.(statusCode, rawHeaders, socket)
|
|
23
|
+
}
|
|
24
|
+
|
|
21
25
|
onHeaders(statusCode, rawHeaders, resume, statusMessage) {
|
|
22
26
|
if (this.reason == null) {
|
|
23
27
|
const ret = this.handler.onHeaders?.(statusCode, rawHeaders, resume, statusMessage)
|
|
@@ -14,6 +14,10 @@ class CacheHandler {
|
|
|
14
14
|
return this.handler.onConnect(abort)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
onUpgrade(statusCode, rawHeaders, socket) {
|
|
18
|
+
return this.handler.onUpgrade?.(statusCode, rawHeaders, socket)
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
onHeaders(statusCode, rawHeaders, resume, statusMessage) {
|
|
18
22
|
// NOTE: Only cache 307 respones for now...
|
|
19
23
|
if (statusCode !== 307) {
|
|
@@ -142,8 +146,9 @@ module.exports = (dispatch) => (opts, handler) => {
|
|
|
142
146
|
|
|
143
147
|
// TODO (fix): Support body...
|
|
144
148
|
assert(opts.method === 'GET' || opts.method === 'HEAD')
|
|
149
|
+
|
|
145
150
|
// Dump body...
|
|
146
|
-
opts.body
|
|
151
|
+
opts.body?.on('error', () => {}).resume()
|
|
147
152
|
|
|
148
153
|
const store = opts.cache === true ? DEFAULT_CACHE_STORE : opts.cache
|
|
149
154
|
|
|
@@ -12,6 +12,14 @@ class Handler {
|
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
onUpgrade(statusCode, rawHeaders, socket) {
|
|
16
|
+
try {
|
|
17
|
+
return this.handler.onUpgrade?.(statusCode, rawHeaders, socket)
|
|
18
|
+
} catch (err) {
|
|
19
|
+
this.abort(err)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
15
23
|
onBodySent(chunk) {
|
|
16
24
|
try {
|
|
17
25
|
return this.handler.onBodySent?.(chunk)
|
|
@@ -18,6 +18,10 @@ class Handler {
|
|
|
18
18
|
return this.handler.onConnect?.(abort)
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
onUpgrade(statusCode, rawHeaders, socket) {
|
|
22
|
+
return this.handler.onUpgrade?.(statusCode, rawHeaders, socket)
|
|
23
|
+
}
|
|
24
|
+
|
|
21
25
|
onBodySent(chunk) {
|
|
22
26
|
return this.handler.onBodySent?.(chunk)
|
|
23
27
|
}
|
|
@@ -23,6 +23,14 @@ class Handler {
|
|
|
23
23
|
})
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
onUpgrade(statusCode, rawHeaders, socket) {
|
|
27
|
+
this.logger.debug({ ureq: this.opts }, 'upstream request upgraded')
|
|
28
|
+
socket.on('close', () => {
|
|
29
|
+
this.logger.debug({ ureq: this.opts }, 'upstream request socket closed')
|
|
30
|
+
})
|
|
31
|
+
return this.handler.onUpgrade?.(statusCode, rawHeaders, socket)
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
onBodySent(chunk) {
|
|
27
35
|
return this.handler.onBodySent?.(chunk)
|
|
28
36
|
}
|
|
@@ -11,6 +11,26 @@ class Handler {
|
|
|
11
11
|
return this.handler.onConnect?.(abort)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
onUpgrade(statusCode, rawHeaders, socket) {
|
|
15
|
+
return this.handler.onUpgrade?.(
|
|
16
|
+
statusCode,
|
|
17
|
+
reduceHeaders(
|
|
18
|
+
{
|
|
19
|
+
headers: rawHeaders,
|
|
20
|
+
httpVersion: this.opts.proxy.httpVersion ?? this.opts.proxy.req?.httpVersion,
|
|
21
|
+
socket: null,
|
|
22
|
+
proxyName: this.opts.proxy.name,
|
|
23
|
+
},
|
|
24
|
+
(acc, key, val) => {
|
|
25
|
+
acc.push(key, val)
|
|
26
|
+
return acc
|
|
27
|
+
},
|
|
28
|
+
[],
|
|
29
|
+
),
|
|
30
|
+
socket,
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
14
34
|
onBodySent(chunk) {
|
|
15
35
|
return this.handler.onBodySent?.(chunk)
|
|
16
36
|
}
|
|
@@ -54,22 +74,21 @@ module.exports = (dispatch) => (opts, handler) => {
|
|
|
54
74
|
return dispatch(opts, handler)
|
|
55
75
|
}
|
|
56
76
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
77
|
+
const headers = reduceHeaders(
|
|
78
|
+
{
|
|
79
|
+
headers: opts.headers ?? {},
|
|
80
|
+
httpVersion: opts.proxy.httpVersion ?? opts.proxy.req?.httpVersion,
|
|
81
|
+
socket: opts.proxy.socket ?? opts.proxy.req?.socket,
|
|
82
|
+
proxyName: opts.proxy.name,
|
|
83
|
+
},
|
|
84
|
+
(obj, key, val) => {
|
|
85
|
+
obj[key] = val
|
|
86
|
+
return obj
|
|
87
|
+
},
|
|
88
|
+
{},
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
opts = { ...opts, headers }
|
|
73
92
|
|
|
74
93
|
return dispatch(opts, new Handler(opts, { handler }))
|
|
75
94
|
}
|
|
@@ -83,7 +102,7 @@ const HOP_EXPR =
|
|
|
83
102
|
function forEachHeader(headers, fn) {
|
|
84
103
|
if (Array.isArray(headers)) {
|
|
85
104
|
for (let n = 0; n < headers.length; n += 2) {
|
|
86
|
-
fn(headers[n + 0], headers[n + 1])
|
|
105
|
+
fn(headers[n + 0].toString(), headers[n + 1].toString())
|
|
87
106
|
}
|
|
88
107
|
} else {
|
|
89
108
|
for (const [key, val] of Object.entries(headers)) {
|
|
@@ -35,7 +35,7 @@ class Handler {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
onUpgrade(statusCode, headers, socket) {
|
|
38
|
-
this.handler.onUpgrade(statusCode, headers, socket)
|
|
38
|
+
this.handler.onUpgrade?.(statusCode, headers, socket)
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
onError(error) {
|
|
@@ -51,18 +51,26 @@ class Handler {
|
|
|
51
51
|
throw new Error(`Disturbed request cannot be redirected.`)
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
const maxCount = this.opts.follow.count
|
|
55
|
-
|
|
56
|
-
if (this.count++ >= maxCount) {
|
|
57
|
-
throw new Error(`Max redirections reached: ${maxCount}.`)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
54
|
this.location = findHeader(headers, 'location')
|
|
61
55
|
|
|
62
56
|
if (!this.location) {
|
|
63
57
|
throw new Error(`Missing redirection location.`)
|
|
64
58
|
}
|
|
65
59
|
|
|
60
|
+
this.count += 1
|
|
61
|
+
|
|
62
|
+
if (typeof this.opts.follow === 'function') {
|
|
63
|
+
if (!this.opts.follow(this.location, this.count)) {
|
|
64
|
+
return this.handler.onHeaders?.(statusCode, headers, resume, statusText)
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
const maxCount = this.opts.follow.count ?? 0
|
|
68
|
+
|
|
69
|
+
if (this.count >= maxCount) {
|
|
70
|
+
throw new Error(`Max redirections reached: ${maxCount}.`)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
66
74
|
const { origin, pathname, search } = parseURL(
|
|
67
75
|
new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)),
|
|
68
76
|
)
|
|
@@ -174,6 +182,4 @@ function cleanRequestHeaders(headers, removeContent, unknownOrigin) {
|
|
|
174
182
|
}
|
|
175
183
|
|
|
176
184
|
module.exports = (dispatch) => (opts, handler) =>
|
|
177
|
-
opts.follow
|
|
178
|
-
? dispatch(opts, new Handler(opts, { handler, dispatch }))
|
|
179
|
-
: dispatch(opts, handler)
|
|
185
|
+
opts.follow ? dispatch(opts, new Handler(opts, { handler, dispatch })) : dispatch(opts, handler)
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
const assert = require('node:assert')
|
|
2
|
-
const {
|
|
3
|
-
parseContentRange,
|
|
4
|
-
isDisturbed,
|
|
5
|
-
findHeader,
|
|
6
|
-
retryAfter: retryAfterFn,
|
|
7
|
-
} = require('../utils.js')
|
|
2
|
+
const { parseContentRange, isDisturbed, findHeader, retry: retryFn } = require('../utils.js')
|
|
8
3
|
|
|
9
4
|
class Handler {
|
|
10
5
|
constructor(opts, { dispatch, handler }) {
|
|
@@ -39,6 +34,10 @@ class Handler {
|
|
|
39
34
|
}
|
|
40
35
|
}
|
|
41
36
|
|
|
37
|
+
onUpgrade(statusCode, rawHeaders, socket) {
|
|
38
|
+
return this.handler.onUpgrade?.(statusCode, rawHeaders, socket)
|
|
39
|
+
}
|
|
40
|
+
|
|
42
41
|
onBodySent(chunk) {
|
|
43
42
|
return this.handler.onBodySent?.(chunk)
|
|
44
43
|
}
|
|
@@ -125,11 +124,23 @@ class Handler {
|
|
|
125
124
|
return this.handler.onError?.(err)
|
|
126
125
|
}
|
|
127
126
|
|
|
128
|
-
const
|
|
129
|
-
if (
|
|
127
|
+
const retryPromise = retryFn(err, this.count++, this.opts)
|
|
128
|
+
if (retryPromise == null) {
|
|
130
129
|
return this.handler.onError?.(err)
|
|
131
130
|
}
|
|
132
|
-
|
|
131
|
+
|
|
132
|
+
retryPromise
|
|
133
|
+
.then(() => {
|
|
134
|
+
this.timeout = null
|
|
135
|
+
try {
|
|
136
|
+
this.dispatch(this.opts, this)
|
|
137
|
+
} catch (err2) {
|
|
138
|
+
this.handler.onError?.(err)
|
|
139
|
+
}
|
|
140
|
+
})
|
|
141
|
+
.catch((err) => {
|
|
142
|
+
this.handler.onError?.(err)
|
|
143
|
+
})
|
|
133
144
|
|
|
134
145
|
this.error = err
|
|
135
146
|
this.opts = {
|
|
@@ -141,16 +152,7 @@ class Handler {
|
|
|
141
152
|
},
|
|
142
153
|
}
|
|
143
154
|
|
|
144
|
-
this.opts.logger?.debug('retrying response body'
|
|
145
|
-
|
|
146
|
-
this.timeout = setTimeout(() => {
|
|
147
|
-
this.timeout = null
|
|
148
|
-
try {
|
|
149
|
-
this.dispatch(this.opts, this)
|
|
150
|
-
} catch (err) {
|
|
151
|
-
this.handler.onError?.(err)
|
|
152
|
-
}
|
|
153
|
-
}, retryAfter)
|
|
155
|
+
this.opts.logger?.debug('retrying response body')
|
|
154
156
|
}
|
|
155
157
|
}
|
|
156
158
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
const { isDisturbed, retryAfter: retryAfterFn } = require('../utils.js')
|
|
1
|
+
const { isDisturbed, retry: retryFn } = require('../utils.js')
|
|
3
2
|
|
|
4
3
|
class Handler {
|
|
5
4
|
constructor(opts, { dispatch, handler }) {
|
|
@@ -31,6 +30,10 @@ class Handler {
|
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
32
|
|
|
33
|
+
onUpgrade(statusCode, rawHeaders, socket) {
|
|
34
|
+
return this.handler.onUpgrade?.(statusCode, rawHeaders, socket)
|
|
35
|
+
}
|
|
36
|
+
|
|
34
37
|
onBodySent(chunk) {
|
|
35
38
|
return this.handler.onBodySent?.(chunk)
|
|
36
39
|
}
|
|
@@ -58,23 +61,25 @@ class Handler {
|
|
|
58
61
|
return this.handler.onError?.(err)
|
|
59
62
|
}
|
|
60
63
|
|
|
61
|
-
const
|
|
62
|
-
if (
|
|
64
|
+
const retryPromise = retryFn(err, this.count++, this.opts)
|
|
65
|
+
if (retryPromise == null) {
|
|
63
66
|
return this.handler.onError?.(err)
|
|
64
67
|
}
|
|
65
|
-
assert(Number.isFinite(retryAfter), 'invalid retryAfter')
|
|
66
68
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
retryPromise
|
|
70
|
+
.then(() => {
|
|
71
|
+
this.timeout = null
|
|
72
|
+
try {
|
|
73
|
+
this.dispatch(this.opts, this)
|
|
74
|
+
} catch (err2) {
|
|
75
|
+
this.handler.onError?.(err)
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
.catch((err) => {
|
|
74
79
|
this.handler.onError?.(err)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
this.
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
this.opts.logger?.debug('retrying response')
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
const { isDisturbed, retryAfter: retryAfterFn } = require('../utils')
|
|
1
|
+
const { isDisturbed, retry: retryFn } = require('../utils')
|
|
3
2
|
const createError = require('http-errors')
|
|
4
3
|
const { parseHeaders } = require('../../../http')
|
|
5
4
|
|
|
@@ -14,7 +13,7 @@ class Handler {
|
|
|
14
13
|
|
|
15
14
|
this.timeout = null
|
|
16
15
|
this.count = 0
|
|
17
|
-
this.
|
|
16
|
+
this.retryPromise = null
|
|
18
17
|
|
|
19
18
|
this.handler.onConnect?.((reason) => {
|
|
20
19
|
this.aborted = true
|
|
@@ -34,6 +33,10 @@ class Handler {
|
|
|
34
33
|
}
|
|
35
34
|
}
|
|
36
35
|
|
|
36
|
+
onUpgrade(statusCode, rawHeaders, socket) {
|
|
37
|
+
return this.handler.onUpgrade?.(statusCode, rawHeaders, socket)
|
|
38
|
+
}
|
|
39
|
+
|
|
37
40
|
onBodySent(chunk) {
|
|
38
41
|
return this.handler.onBodySent?.(chunk)
|
|
39
42
|
}
|
|
@@ -45,13 +48,14 @@ class Handler {
|
|
|
45
48
|
|
|
46
49
|
const err = createError(statusCode, { headers: parseHeaders(rawHeaders) })
|
|
47
50
|
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
51
|
+
const retryPromise = retryFn(err, this.count++, this.opts)
|
|
52
|
+
if (retryPromise == null) {
|
|
50
53
|
return this.handler.onHeaders?.(statusCode, rawHeaders, resume, statusMessage)
|
|
51
54
|
}
|
|
52
|
-
assert(Number.isFinite(retryAfter), 'invalid retryAfter')
|
|
53
55
|
|
|
54
|
-
|
|
56
|
+
retryPromise.catch(() => {})
|
|
57
|
+
|
|
58
|
+
this.retryPromise = retryPromise
|
|
55
59
|
|
|
56
60
|
this.abort(err)
|
|
57
61
|
|
|
@@ -72,21 +76,25 @@ class Handler {
|
|
|
72
76
|
this.timeout = null
|
|
73
77
|
}
|
|
74
78
|
|
|
75
|
-
if (this.
|
|
79
|
+
if (this.retryPromise == null || this.aborted || isDisturbed(this.opts.body)) {
|
|
76
80
|
return this.handler.onError?.(err)
|
|
77
81
|
}
|
|
78
82
|
|
|
79
|
-
this.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
this.retryPromise
|
|
84
|
+
.then(() => {
|
|
85
|
+
this.timeout = null
|
|
86
|
+
try {
|
|
87
|
+
this.dispatch(this.opts, this)
|
|
88
|
+
} catch (err) {
|
|
89
|
+
this.handler.onError?.(err)
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
.catch((err) => {
|
|
86
93
|
this.handler.onError?.(err)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
94
|
+
})
|
|
95
|
+
this.retryPromise = null
|
|
96
|
+
|
|
97
|
+
this.opts.logger?.debug('retrying response status')
|
|
90
98
|
}
|
|
91
99
|
}
|
|
92
100
|
|
package/lib/undici/utils.js
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
const tp = require('node:timers/promises')
|
|
2
|
+
|
|
1
3
|
function isDisturbed(body) {
|
|
2
|
-
|
|
4
|
+
if (body == null || typeof body === 'string' || Buffer.isBuffer(body)) {
|
|
5
|
+
return false
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (body.readableDidRead === false) {
|
|
9
|
+
return false
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return true
|
|
3
13
|
}
|
|
4
14
|
|
|
5
15
|
function parseContentRange(range) {
|
|
@@ -42,16 +52,13 @@ function findHeader(rawHeaders, name) {
|
|
|
42
52
|
return null
|
|
43
53
|
}
|
|
44
54
|
|
|
45
|
-
function
|
|
55
|
+
function retry(err, retryCount, opts) {
|
|
46
56
|
if (opts.retry === null || opts.retry === false) {
|
|
47
57
|
return null
|
|
48
58
|
}
|
|
49
59
|
|
|
50
60
|
if (typeof opts.retry === 'function') {
|
|
51
|
-
|
|
52
|
-
if (ret != null) {
|
|
53
|
-
return ret
|
|
54
|
-
}
|
|
61
|
+
return opts.retry(err, retryCount, opts)
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
const retryMax = opts.retry?.count ?? opts.maxRetries ?? 8
|
|
@@ -61,8 +68,13 @@ function retryAfter(err, retryCount, opts) {
|
|
|
61
68
|
}
|
|
62
69
|
|
|
63
70
|
if (err.statusCode && [420, 429, 502, 503, 504].includes(err.statusCode)) {
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
let retryAfter = err.headers['retry-after'] ? err.headers['retry-after'] * 1e3 : null
|
|
72
|
+
retryAfter = Number.isFinite(retryAfter) ? retryAfter : Math.min(10e3, retryCount * 1e3)
|
|
73
|
+
if (retryAfter != null && Number.isFinite(retryAfter)) {
|
|
74
|
+
return tp.setTimeout(retryAfter, undefined, { signal: opts.signal })
|
|
75
|
+
} else {
|
|
76
|
+
return null
|
|
77
|
+
}
|
|
66
78
|
}
|
|
67
79
|
|
|
68
80
|
if (
|
|
@@ -78,11 +90,11 @@ function retryAfter(err, retryCount, opts) {
|
|
|
78
90
|
'EPIPE',
|
|
79
91
|
].includes(err.code)
|
|
80
92
|
) {
|
|
81
|
-
return Math.min(10e3, retryCount * 1e3)
|
|
93
|
+
return tp.setTimeout(Math.min(10e3, retryCount * 1e3), undefined, { signal: opts.signal })
|
|
82
94
|
}
|
|
83
95
|
|
|
84
96
|
if (err.message && ['other side closed'].includes(err.message)) {
|
|
85
|
-
return Math.min(10e3, retryCount * 1e3)
|
|
97
|
+
return tp.setTimeout(Math.min(10e3, retryCount * 1e3), undefined, { signal: opts.signal })
|
|
86
98
|
}
|
|
87
99
|
|
|
88
100
|
return null
|
|
@@ -165,7 +177,7 @@ module.exports = {
|
|
|
165
177
|
isDisturbed,
|
|
166
178
|
parseContentRange,
|
|
167
179
|
findHeader,
|
|
168
|
-
|
|
180
|
+
retry,
|
|
169
181
|
parseURL,
|
|
170
182
|
parseOrigin,
|
|
171
183
|
}
|
package/package.json
CHANGED
package/util/template/index.js
CHANGED
|
@@ -84,7 +84,7 @@ module.exports = ({ ds, proxify }) => {
|
|
|
84
84
|
let indices
|
|
85
85
|
|
|
86
86
|
for (let i = 0; i < template.length; i++) {
|
|
87
|
-
const resolver =
|
|
87
|
+
const resolver = _compileTemplate(template[i])
|
|
88
88
|
if (resolver) {
|
|
89
89
|
resolvers ??= []
|
|
90
90
|
resolvers.push(resolver)
|
|
@@ -121,7 +121,7 @@ module.exports = ({ ds, proxify }) => {
|
|
|
121
121
|
const keys = Object.keys(template)
|
|
122
122
|
|
|
123
123
|
for (let i = 0; i < keys.length; i++) {
|
|
124
|
-
const resolver =
|
|
124
|
+
const resolver = _compileTemplate(template[keys[i]])
|
|
125
125
|
if (resolver) {
|
|
126
126
|
resolvers ??= []
|
|
127
127
|
resolvers.push(resolver)
|
|
@@ -207,7 +207,7 @@ module.exports = ({ ds, proxify }) => {
|
|
|
207
207
|
return typeof val === 'string' && val.indexOf('{{') !== -1
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
const
|
|
210
|
+
const _compileTemplateCache = weakCache(
|
|
211
211
|
(template) => {
|
|
212
212
|
if (fp.isPlainObject(template)) {
|
|
213
213
|
return compileObjectTemplate(template)
|
|
@@ -222,9 +222,14 @@ module.exports = ({ ds, proxify }) => {
|
|
|
222
222
|
(template, hash) => hash,
|
|
223
223
|
)
|
|
224
224
|
|
|
225
|
-
function
|
|
225
|
+
function _compileTemplate(template) {
|
|
226
226
|
const hash = hashTemplate(template)
|
|
227
|
-
const resolver = hash ?
|
|
227
|
+
const resolver = hash ? _compileTemplateCache(template, hash) : null
|
|
228
|
+
return resolver // ? (args$) => resolver(template, args$) : null
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function compileTemplate(template) {
|
|
232
|
+
const resolver = _compileTemplate(template)
|
|
228
233
|
return resolver ? (args$) => resolver(template, args$) : null
|
|
229
234
|
}
|
|
230
235
|
|
|
@@ -234,7 +239,7 @@ module.exports = ({ ds, proxify }) => {
|
|
|
234
239
|
|
|
235
240
|
function onResolveTemplate(template, args$) {
|
|
236
241
|
try {
|
|
237
|
-
return
|
|
242
|
+
return _compileTemplate(template)?.(template, args$) ?? rxjs.of(template)
|
|
238
243
|
} catch (err) {
|
|
239
244
|
return rxjs.throwError(() => err)
|
|
240
245
|
}
|