undici 6.20.0 → 7.0.0-alpha.2
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/README.md +6 -10
- package/docs/docs/api/Agent.md +0 -3
- package/docs/docs/api/Client.md +1 -3
- package/docs/docs/api/Debug.md +1 -1
- package/docs/docs/api/Dispatcher.md +60 -8
- package/docs/docs/api/EnvHttpProxyAgent.md +0 -1
- package/docs/docs/api/Fetch.md +1 -0
- package/docs/docs/api/MockAgent.md +2 -0
- package/docs/docs/api/MockPool.md +2 -1
- package/docs/docs/api/Pool.md +0 -1
- package/docs/docs/api/RetryAgent.md +1 -1
- package/docs/docs/api/RetryHandler.md +1 -1
- package/docs/docs/api/WebSocket.md +45 -3
- package/index.js +6 -6
- package/lib/api/abort-signal.js +2 -0
- package/lib/api/api-connect.js +3 -1
- package/lib/api/api-pipeline.js +7 -6
- package/lib/api/api-request.js +32 -47
- package/lib/api/api-stream.js +39 -50
- package/lib/api/api-upgrade.js +5 -3
- package/lib/api/readable.js +261 -64
- package/lib/api/util.js +2 -0
- package/lib/core/constants.js +11 -9
- package/lib/core/diagnostics.js +122 -128
- package/lib/core/errors.js +4 -4
- package/lib/core/request.js +11 -9
- package/lib/core/symbols.js +2 -1
- package/lib/core/tree.js +9 -1
- package/lib/core/util.js +219 -48
- package/lib/dispatcher/agent.js +3 -17
- package/lib/dispatcher/balanced-pool.js +5 -8
- package/lib/dispatcher/client-h1.js +278 -54
- package/lib/dispatcher/client-h2.js +1 -1
- package/lib/dispatcher/client.js +23 -34
- package/lib/dispatcher/dispatcher-base.js +2 -34
- package/lib/dispatcher/dispatcher.js +3 -24
- package/lib/dispatcher/fixed-queue.js +91 -49
- package/lib/dispatcher/pool-stats.js +2 -0
- package/lib/dispatcher/pool.js +3 -6
- package/lib/dispatcher/proxy-agent.js +6 -7
- package/lib/handler/decorator-handler.js +24 -0
- package/lib/handler/redirect-handler.js +11 -2
- package/lib/handler/retry-handler.js +12 -3
- package/lib/interceptor/dns.js +346 -0
- package/lib/interceptor/dump.js +2 -2
- package/lib/interceptor/redirect.js +11 -14
- package/lib/interceptor/response-error.js +4 -1
- package/lib/llhttp/constants.d.ts +97 -0
- package/lib/llhttp/constants.js +412 -192
- package/lib/llhttp/constants.js.map +1 -0
- package/lib/llhttp/llhttp-wasm.js +11 -1
- package/lib/llhttp/llhttp_simd-wasm.js +11 -1
- package/lib/llhttp/utils.d.ts +2 -0
- package/lib/llhttp/utils.js +9 -9
- package/lib/llhttp/utils.js.map +1 -0
- package/lib/mock/mock-agent.js +5 -8
- package/lib/mock/mock-client.js +9 -4
- package/lib/mock/mock-errors.js +3 -1
- package/lib/mock/mock-interceptor.js +8 -6
- package/lib/mock/mock-pool.js +9 -4
- package/lib/mock/mock-symbols.js +3 -1
- package/lib/mock/mock-utils.js +29 -5
- package/lib/web/cache/cache.js +24 -21
- package/lib/web/cache/cachestorage.js +1 -1
- package/lib/web/cookies/index.js +17 -13
- package/lib/web/cookies/parse.js +2 -2
- package/lib/web/eventsource/eventsource-stream.js +9 -8
- package/lib/web/eventsource/eventsource.js +10 -6
- package/lib/web/fetch/body.js +42 -36
- package/lib/web/fetch/constants.js +35 -26
- package/lib/web/fetch/data-url.js +1 -1
- package/lib/web/fetch/formdata-parser.js +2 -2
- package/lib/web/fetch/formdata.js +65 -54
- package/lib/web/fetch/headers.js +117 -85
- package/lib/web/fetch/index.js +55 -62
- package/lib/web/fetch/request.js +135 -77
- package/lib/web/fetch/response.js +86 -56
- package/lib/web/fetch/util.js +90 -64
- package/lib/web/fetch/webidl.js +99 -64
- package/lib/web/websocket/connection.js +76 -147
- package/lib/web/websocket/constants.js +3 -4
- package/lib/web/websocket/events.js +4 -2
- package/lib/web/websocket/frame.js +45 -3
- package/lib/web/websocket/receiver.js +29 -33
- package/lib/web/websocket/sender.js +18 -13
- package/lib/web/websocket/stream/websocketerror.js +83 -0
- package/lib/web/websocket/stream/websocketstream.js +485 -0
- package/lib/web/websocket/util.js +128 -77
- package/lib/web/websocket/websocket.js +234 -135
- package/package.json +20 -33
- package/scripts/strip-comments.js +3 -1
- package/types/agent.d.ts +7 -7
- package/types/api.d.ts +24 -24
- package/types/balanced-pool.d.ts +11 -11
- package/types/client.d.ts +11 -12
- package/types/diagnostics-channel.d.ts +10 -10
- package/types/dispatcher.d.ts +96 -97
- package/types/env-http-proxy-agent.d.ts +2 -2
- package/types/errors.d.ts +53 -47
- package/types/fetch.d.ts +8 -8
- package/types/formdata.d.ts +7 -7
- package/types/global-dispatcher.d.ts +4 -4
- package/types/global-origin.d.ts +5 -5
- package/types/handlers.d.ts +4 -4
- package/types/header.d.ts +157 -1
- package/types/index.d.ts +42 -46
- package/types/interceptors.d.ts +22 -8
- package/types/mock-agent.d.ts +21 -18
- package/types/mock-client.d.ts +4 -4
- package/types/mock-errors.d.ts +3 -3
- package/types/mock-interceptor.d.ts +19 -19
- package/types/mock-pool.d.ts +4 -4
- package/types/patch.d.ts +0 -4
- package/types/pool-stats.d.ts +8 -8
- package/types/pool.d.ts +12 -12
- package/types/proxy-agent.d.ts +4 -4
- package/types/readable.d.ts +22 -14
- package/types/retry-agent.d.ts +1 -1
- package/types/retry-handler.d.ts +8 -8
- package/types/util.d.ts +3 -3
- package/types/utility.d.ts +7 -0
- package/types/webidl.d.ts +44 -6
- package/types/websocket.d.ts +34 -1
- package/docs/docs/api/DispatchInterceptor.md +0 -60
- package/lib/interceptor/redirect-interceptor.js +0 -21
- package/lib/mock/pluralizer.js +0 -29
- package/lib/web/cache/symbols.js +0 -5
- package/lib/web/fetch/file.js +0 -126
- package/lib/web/fetch/symbols.js +0 -9
- package/lib/web/fileapi/encoding.js +0 -290
- package/lib/web/fileapi/filereader.js +0 -344
- package/lib/web/fileapi/progressevent.js +0 -78
- package/lib/web/fileapi/symbols.js +0 -10
- package/lib/web/fileapi/util.js +0 -391
- package/lib/web/websocket/symbols.js +0 -12
- package/types/file.d.ts +0 -39
- package/types/filereader.d.ts +0 -54
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const { isIP } = require('node:net')
|
|
3
|
+
const { lookup } = require('node:dns')
|
|
4
|
+
const DecoratorHandler = require('../handler/decorator-handler')
|
|
5
|
+
const { InvalidArgumentError, InformationalError } = require('../core/errors')
|
|
6
|
+
const maxInt = Math.pow(2, 31) - 1
|
|
7
|
+
|
|
8
|
+
class DNSInstance {
|
|
9
|
+
#maxTTL = 0
|
|
10
|
+
#maxItems = 0
|
|
11
|
+
#records = new Map()
|
|
12
|
+
dualStack = true
|
|
13
|
+
affinity = null
|
|
14
|
+
lookup = null
|
|
15
|
+
pick = null
|
|
16
|
+
lastIpFamily = null
|
|
17
|
+
|
|
18
|
+
constructor (opts) {
|
|
19
|
+
this.#maxTTL = opts.maxTTL
|
|
20
|
+
this.#maxItems = opts.maxItems
|
|
21
|
+
this.dualStack = opts.dualStack
|
|
22
|
+
this.affinity = opts.affinity
|
|
23
|
+
this.lookup = opts.lookup ?? this.#defaultLookup
|
|
24
|
+
this.pick = opts.pick ?? this.#defaultPick
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get full () {
|
|
28
|
+
return this.#records.size === this.#maxItems
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
runLookup (origin, opts, cb) {
|
|
32
|
+
const ips = this.#records.get(origin.hostname)
|
|
33
|
+
|
|
34
|
+
// If full, we just return the origin
|
|
35
|
+
if (ips == null && this.full) {
|
|
36
|
+
cb(null, origin.origin)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const newOpts = {
|
|
41
|
+
affinity: this.affinity,
|
|
42
|
+
dualStack: this.dualStack,
|
|
43
|
+
lookup: this.lookup,
|
|
44
|
+
pick: this.pick,
|
|
45
|
+
...opts.dns,
|
|
46
|
+
maxTTL: this.#maxTTL,
|
|
47
|
+
maxItems: this.#maxItems
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// If no IPs we lookup
|
|
51
|
+
if (ips == null) {
|
|
52
|
+
this.lookup(origin, newOpts, (err, addresses) => {
|
|
53
|
+
if (err || addresses == null || addresses.length === 0) {
|
|
54
|
+
cb(err ?? new InformationalError('No DNS entries found'))
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this.setRecords(origin, addresses)
|
|
59
|
+
const records = this.#records.get(origin.hostname)
|
|
60
|
+
|
|
61
|
+
const ip = this.pick(
|
|
62
|
+
origin,
|
|
63
|
+
records,
|
|
64
|
+
// Only set affinity if dual stack is disabled
|
|
65
|
+
// otherwise let it go through normal flow
|
|
66
|
+
!newOpts.dualStack && newOpts.affinity
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
cb(
|
|
70
|
+
null,
|
|
71
|
+
`${origin.protocol}//${
|
|
72
|
+
ip.family === 6 ? `[${ip.address}]` : ip.address
|
|
73
|
+
}${origin.port === '' ? '' : `:${origin.port}`}`
|
|
74
|
+
)
|
|
75
|
+
})
|
|
76
|
+
} else {
|
|
77
|
+
// If there's IPs we pick
|
|
78
|
+
const ip = this.pick(
|
|
79
|
+
origin,
|
|
80
|
+
ips,
|
|
81
|
+
// Only set affinity if dual stack is disabled
|
|
82
|
+
// otherwise let it go through normal flow
|
|
83
|
+
!newOpts.dualStack && newOpts.affinity
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
// If no IPs we lookup - deleting old records
|
|
87
|
+
if (ip == null) {
|
|
88
|
+
this.#records.delete(origin.hostname)
|
|
89
|
+
this.runLookup(origin, opts, cb)
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
cb(
|
|
94
|
+
null,
|
|
95
|
+
`${origin.protocol}//${
|
|
96
|
+
ip.family === 6 ? `[${ip.address}]` : ip.address
|
|
97
|
+
}${origin.port === '' ? '' : `:${origin.port}`}`
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#defaultLookup (origin, opts, cb) {
|
|
103
|
+
lookup(
|
|
104
|
+
origin.hostname,
|
|
105
|
+
{ all: true, family: this.dualStack === false ? this.affinity : 0 },
|
|
106
|
+
(err, addresses) => {
|
|
107
|
+
if (err) {
|
|
108
|
+
return cb(err)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const results = new Map()
|
|
112
|
+
|
|
113
|
+
for (const addr of addresses) {
|
|
114
|
+
const record = {
|
|
115
|
+
address: addr.address,
|
|
116
|
+
ttl: opts.maxTTL,
|
|
117
|
+
family: addr.family
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// On linux we found duplicates, we attempt to remove them with
|
|
121
|
+
// the latest record
|
|
122
|
+
results.set(`${record.address}:${record.family}`, record)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
cb(null, results.values())
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#defaultPick (origin, hostnameRecords, affinity) {
|
|
131
|
+
let ip = null
|
|
132
|
+
const { records, offset = 0 } = hostnameRecords
|
|
133
|
+
let newOffset = 0
|
|
134
|
+
|
|
135
|
+
if (offset === maxInt) {
|
|
136
|
+
newOffset = 0
|
|
137
|
+
} else {
|
|
138
|
+
newOffset = offset + 1
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// We balance between the two IP families
|
|
142
|
+
// If dual-stack disabled, we automatically pick the affinity
|
|
143
|
+
const newIpFamily = (newOffset & 1) === 1 ? 4 : 6
|
|
144
|
+
const family =
|
|
145
|
+
this.dualStack === false
|
|
146
|
+
? records[this.affinity] // If dual-stack is disabled, we pick the default affiniy
|
|
147
|
+
: records[affinity] ?? records[newIpFamily]
|
|
148
|
+
|
|
149
|
+
// If no IPs and we have tried both families or dual stack is disabled, we return null
|
|
150
|
+
if (
|
|
151
|
+
(family == null || family.ips.length === 0) &&
|
|
152
|
+
// eslint-disable-next-line eqeqeq
|
|
153
|
+
(this.dualStack === false || this.lastIpFamily != newIpFamily)
|
|
154
|
+
) {
|
|
155
|
+
return ip
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
family.offset = family.offset ?? 0
|
|
159
|
+
hostnameRecords.offset = newOffset
|
|
160
|
+
|
|
161
|
+
if (family.offset === maxInt) {
|
|
162
|
+
family.offset = 0
|
|
163
|
+
} else {
|
|
164
|
+
family.offset++
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const position = family.offset % family.ips.length
|
|
168
|
+
ip = family.ips[position] ?? null
|
|
169
|
+
|
|
170
|
+
if (ip == null) {
|
|
171
|
+
return ip
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const timestamp = Date.now()
|
|
175
|
+
// Record TTL is already in ms
|
|
176
|
+
if (ip.timestamp != null && timestamp - ip.timestamp > ip.ttl) {
|
|
177
|
+
// We delete expired records
|
|
178
|
+
// It is possible that they have different TTL, so we manage them individually
|
|
179
|
+
family.ips.splice(position, 1)
|
|
180
|
+
return this.pick(origin, hostnameRecords, affinity)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
ip.timestamp = timestamp
|
|
184
|
+
|
|
185
|
+
this.lastIpFamily = newIpFamily
|
|
186
|
+
return ip
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
setRecords (origin, addresses) {
|
|
190
|
+
const records = { records: { 4: null, 6: null } }
|
|
191
|
+
for (const record of addresses) {
|
|
192
|
+
const familyRecords = records.records[record.family] ?? { ips: [] }
|
|
193
|
+
|
|
194
|
+
familyRecords.ips.push(record)
|
|
195
|
+
records.records[record.family] = familyRecords
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
this.#records.set(origin.hostname, records)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
getHandler (meta, opts) {
|
|
202
|
+
return new DNSDispatchHandler(this, meta, opts)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
class DNSDispatchHandler extends DecoratorHandler {
|
|
207
|
+
#state = null
|
|
208
|
+
#opts = null
|
|
209
|
+
#dispatch = null
|
|
210
|
+
#handler = null
|
|
211
|
+
#origin = null
|
|
212
|
+
|
|
213
|
+
constructor (state, { origin, handler, dispatch }, opts) {
|
|
214
|
+
super(handler)
|
|
215
|
+
this.#origin = origin
|
|
216
|
+
this.#handler = handler
|
|
217
|
+
this.#opts = { ...opts }
|
|
218
|
+
this.#state = state
|
|
219
|
+
this.#dispatch = dispatch
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
onError (err) {
|
|
223
|
+
switch (err.code) {
|
|
224
|
+
case 'ETIMEDOUT':
|
|
225
|
+
case 'ECONNREFUSED': {
|
|
226
|
+
if (this.#state.dualStack) {
|
|
227
|
+
// We delete the record and retry
|
|
228
|
+
this.#state.runLookup(this.#origin, this.#opts, (err, newOrigin) => {
|
|
229
|
+
if (err) {
|
|
230
|
+
return this.#handler.onError(err)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const dispatchOpts = {
|
|
234
|
+
...this.#opts,
|
|
235
|
+
origin: newOrigin
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
this.#dispatch(dispatchOpts, this)
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
// if dual-stack disabled, we error out
|
|
242
|
+
return
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
this.#handler.onError(err)
|
|
246
|
+
return
|
|
247
|
+
}
|
|
248
|
+
case 'ENOTFOUND':
|
|
249
|
+
this.#state.deleteRecord(this.#origin)
|
|
250
|
+
// eslint-disable-next-line no-fallthrough
|
|
251
|
+
default:
|
|
252
|
+
this.#handler.onError(err)
|
|
253
|
+
break
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
module.exports = interceptorOpts => {
|
|
259
|
+
if (
|
|
260
|
+
interceptorOpts?.maxTTL != null &&
|
|
261
|
+
(typeof interceptorOpts?.maxTTL !== 'number' || interceptorOpts?.maxTTL < 0)
|
|
262
|
+
) {
|
|
263
|
+
throw new InvalidArgumentError('Invalid maxTTL. Must be a positive number')
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (
|
|
267
|
+
interceptorOpts?.maxItems != null &&
|
|
268
|
+
(typeof interceptorOpts?.maxItems !== 'number' ||
|
|
269
|
+
interceptorOpts?.maxItems < 1)
|
|
270
|
+
) {
|
|
271
|
+
throw new InvalidArgumentError(
|
|
272
|
+
'Invalid maxItems. Must be a positive number and greater than zero'
|
|
273
|
+
)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (
|
|
277
|
+
interceptorOpts?.affinity != null &&
|
|
278
|
+
interceptorOpts?.affinity !== 4 &&
|
|
279
|
+
interceptorOpts?.affinity !== 6
|
|
280
|
+
) {
|
|
281
|
+
throw new InvalidArgumentError('Invalid affinity. Must be either 4 or 6')
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (
|
|
285
|
+
interceptorOpts?.dualStack != null &&
|
|
286
|
+
typeof interceptorOpts?.dualStack !== 'boolean'
|
|
287
|
+
) {
|
|
288
|
+
throw new InvalidArgumentError('Invalid dualStack. Must be a boolean')
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (
|
|
292
|
+
interceptorOpts?.lookup != null &&
|
|
293
|
+
typeof interceptorOpts?.lookup !== 'function'
|
|
294
|
+
) {
|
|
295
|
+
throw new InvalidArgumentError('Invalid lookup. Must be a function')
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (
|
|
299
|
+
interceptorOpts?.pick != null &&
|
|
300
|
+
typeof interceptorOpts?.pick !== 'function'
|
|
301
|
+
) {
|
|
302
|
+
throw new InvalidArgumentError('Invalid pick. Must be a function')
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const opts = {
|
|
306
|
+
maxTTL: interceptorOpts?.maxTTL ?? 10e3, // Expressed in ms
|
|
307
|
+
lookup: interceptorOpts?.lookup ?? null,
|
|
308
|
+
pick: interceptorOpts?.pick ?? null,
|
|
309
|
+
dualStack: interceptorOpts?.dualStack ?? true,
|
|
310
|
+
affinity: interceptorOpts?.affinity ?? 4,
|
|
311
|
+
maxItems: interceptorOpts?.maxItems ?? Infinity
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const instance = new DNSInstance(opts)
|
|
315
|
+
|
|
316
|
+
return dispatch => {
|
|
317
|
+
return function dnsInterceptor (origDispatchOpts, handler) {
|
|
318
|
+
const origin =
|
|
319
|
+
origDispatchOpts.origin.constructor === URL
|
|
320
|
+
? origDispatchOpts.origin
|
|
321
|
+
: new URL(origDispatchOpts.origin)
|
|
322
|
+
|
|
323
|
+
if (isIP(origin.hostname) !== 0) {
|
|
324
|
+
return dispatch(origDispatchOpts, handler)
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
instance.runLookup(origin, origDispatchOpts, (err, newOrigin) => {
|
|
328
|
+
if (err) {
|
|
329
|
+
return handler.onError(err)
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const dispatchOpts = {
|
|
333
|
+
...origDispatchOpts,
|
|
334
|
+
origin: newOrigin
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
dispatch(
|
|
338
|
+
dispatchOpts,
|
|
339
|
+
instance.getHandler({ origin, dispatch, handler }, origDispatchOpts)
|
|
340
|
+
)
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
return true
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
package/lib/interceptor/dump.js
CHANGED
|
@@ -14,12 +14,12 @@ class DumpHandler extends DecoratorHandler {
|
|
|
14
14
|
#handler = null
|
|
15
15
|
|
|
16
16
|
constructor ({ maxSize }, handler) {
|
|
17
|
-
super(handler)
|
|
18
|
-
|
|
19
17
|
if (maxSize != null && (!Number.isFinite(maxSize) || maxSize < 1)) {
|
|
20
18
|
throw new InvalidArgumentError('maxSize must be a number greater than 0')
|
|
21
19
|
}
|
|
22
20
|
|
|
21
|
+
super(handler)
|
|
22
|
+
|
|
23
23
|
this.#maxSize = maxSize ?? this.#maxSize
|
|
24
24
|
this.#handler = handler
|
|
25
25
|
}
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
|
|
2
3
|
const RedirectHandler = require('../handler/redirect-handler')
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const { maxRedirections = globalMaxRedirections, ...baseOpts } = opts
|
|
5
|
+
function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections } = {}) {
|
|
6
|
+
return (dispatch) => {
|
|
7
|
+
return function Intercept (opts, handler) {
|
|
8
|
+
const { maxRedirections = defaultMaxRedirections, ...rest } = opts
|
|
9
9
|
|
|
10
|
-
if (
|
|
10
|
+
if (maxRedirections == null || maxRedirections === 0) {
|
|
11
11
|
return dispatch(opts, handler)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
opts,
|
|
18
|
-
handler
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
return dispatch(baseOpts, redirectHandler)
|
|
14
|
+
const dispatchOpts = { ...rest, maxRedirections: 0 } // Stop sub dispatcher from also redirecting.
|
|
15
|
+
const redirectHandler = new RedirectHandler(dispatch, maxRedirections, dispatchOpts, handler)
|
|
16
|
+
return dispatch(dispatchOpts, redirectHandler)
|
|
22
17
|
}
|
|
23
18
|
}
|
|
24
19
|
}
|
|
20
|
+
|
|
21
|
+
module.exports = createRedirectInterceptor
|
|
@@ -65,7 +65,10 @@ class Handler extends DecoratorHandler {
|
|
|
65
65
|
const stackTraceLimit = Error.stackTraceLimit
|
|
66
66
|
Error.stackTraceLimit = 0
|
|
67
67
|
try {
|
|
68
|
-
err = new ResponseError('Response Error', this.#statusCode,
|
|
68
|
+
err = new ResponseError('Response Error', this.#statusCode, {
|
|
69
|
+
data: this.#body,
|
|
70
|
+
headers: this.#headers
|
|
71
|
+
})
|
|
69
72
|
} finally {
|
|
70
73
|
Error.stackTraceLimit = stackTraceLimit
|
|
71
74
|
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export type IntDict = Record<string, number>;
|
|
2
|
+
export declare const ERROR: IntDict;
|
|
3
|
+
export declare const TYPE: IntDict;
|
|
4
|
+
export declare const FLAGS: IntDict;
|
|
5
|
+
export declare const LENIENT_FLAGS: IntDict;
|
|
6
|
+
export declare const METHODS: IntDict;
|
|
7
|
+
export declare const STATUSES: IntDict;
|
|
8
|
+
export declare const FINISH: IntDict;
|
|
9
|
+
export declare const HEADER_STATE: IntDict;
|
|
10
|
+
export declare const METHODS_HTTP: number[];
|
|
11
|
+
export declare const METHODS_ICE: number[];
|
|
12
|
+
export declare const METHODS_RTSP: number[];
|
|
13
|
+
export declare const METHOD_MAP: IntDict;
|
|
14
|
+
export declare const H_METHOD_MAP: {
|
|
15
|
+
[k: string]: number;
|
|
16
|
+
};
|
|
17
|
+
export declare const STATUSES_HTTP: number[];
|
|
18
|
+
export type CharList = Array<string | number>;
|
|
19
|
+
export declare const ALPHA: CharList;
|
|
20
|
+
export declare const NUM_MAP: {
|
|
21
|
+
0: number;
|
|
22
|
+
1: number;
|
|
23
|
+
2: number;
|
|
24
|
+
3: number;
|
|
25
|
+
4: number;
|
|
26
|
+
5: number;
|
|
27
|
+
6: number;
|
|
28
|
+
7: number;
|
|
29
|
+
8: number;
|
|
30
|
+
9: number;
|
|
31
|
+
};
|
|
32
|
+
export declare const HEX_MAP: {
|
|
33
|
+
0: number;
|
|
34
|
+
1: number;
|
|
35
|
+
2: number;
|
|
36
|
+
3: number;
|
|
37
|
+
4: number;
|
|
38
|
+
5: number;
|
|
39
|
+
6: number;
|
|
40
|
+
7: number;
|
|
41
|
+
8: number;
|
|
42
|
+
9: number;
|
|
43
|
+
A: number;
|
|
44
|
+
B: number;
|
|
45
|
+
C: number;
|
|
46
|
+
D: number;
|
|
47
|
+
E: number;
|
|
48
|
+
F: number;
|
|
49
|
+
a: number;
|
|
50
|
+
b: number;
|
|
51
|
+
c: number;
|
|
52
|
+
d: number;
|
|
53
|
+
e: number;
|
|
54
|
+
f: number;
|
|
55
|
+
};
|
|
56
|
+
export declare const NUM: CharList;
|
|
57
|
+
export declare const ALPHANUM: CharList;
|
|
58
|
+
export declare const MARK: CharList;
|
|
59
|
+
export declare const USERINFO_CHARS: CharList;
|
|
60
|
+
export declare const URL_CHAR: CharList;
|
|
61
|
+
export declare const HEX: CharList;
|
|
62
|
+
export declare const TOKEN: CharList;
|
|
63
|
+
export declare const HEADER_CHARS: CharList;
|
|
64
|
+
export declare const CONNECTION_TOKEN_CHARS: CharList;
|
|
65
|
+
export declare const QUOTED_STRING: CharList;
|
|
66
|
+
export declare const HTAB_SP_VCHAR_OBS_TEXT: CharList;
|
|
67
|
+
export declare const MAJOR: {
|
|
68
|
+
0: number;
|
|
69
|
+
1: number;
|
|
70
|
+
2: number;
|
|
71
|
+
3: number;
|
|
72
|
+
4: number;
|
|
73
|
+
5: number;
|
|
74
|
+
6: number;
|
|
75
|
+
7: number;
|
|
76
|
+
8: number;
|
|
77
|
+
9: number;
|
|
78
|
+
};
|
|
79
|
+
export declare const MINOR: {
|
|
80
|
+
0: number;
|
|
81
|
+
1: number;
|
|
82
|
+
2: number;
|
|
83
|
+
3: number;
|
|
84
|
+
4: number;
|
|
85
|
+
5: number;
|
|
86
|
+
6: number;
|
|
87
|
+
7: number;
|
|
88
|
+
8: number;
|
|
89
|
+
9: number;
|
|
90
|
+
};
|
|
91
|
+
export declare const SPECIAL_HEADERS: {
|
|
92
|
+
connection: number;
|
|
93
|
+
'content-length': number;
|
|
94
|
+
'proxy-connection': number;
|
|
95
|
+
'transfer-encoding': number;
|
|
96
|
+
upgrade: number;
|
|
97
|
+
};
|