@nocobase/plugin-idp-oauth 2.1.0-alpha.17 → 2.1.0-alpha.18
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/build.config.ts +1 -1
- package/dist/externalVersion.js +4 -4
- package/dist/node_modules/light-my-request/package.json +1 -1
- package/dist/node_modules/undici/LICENSE +21 -0
- package/dist/node_modules/undici/README.md +741 -0
- package/dist/node_modules/undici/docs/docs/api/Agent.md +84 -0
- package/dist/node_modules/undici/docs/docs/api/BalancedPool.md +99 -0
- package/dist/node_modules/undici/docs/docs/api/CacheStorage.md +30 -0
- package/dist/node_modules/undici/docs/docs/api/CacheStore.md +164 -0
- package/dist/node_modules/undici/docs/docs/api/Client.md +285 -0
- package/dist/node_modules/undici/docs/docs/api/ClientStats.md +27 -0
- package/dist/node_modules/undici/docs/docs/api/Connector.md +115 -0
- package/dist/node_modules/undici/docs/docs/api/ContentType.md +57 -0
- package/dist/node_modules/undici/docs/docs/api/Cookies.md +101 -0
- package/dist/node_modules/undici/docs/docs/api/Debug.md +62 -0
- package/dist/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +315 -0
- package/dist/node_modules/undici/docs/docs/api/Dispatcher.md +1392 -0
- package/dist/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +159 -0
- package/dist/node_modules/undici/docs/docs/api/Errors.md +49 -0
- package/dist/node_modules/undici/docs/docs/api/EventSource.md +45 -0
- package/dist/node_modules/undici/docs/docs/api/Fetch.md +60 -0
- package/dist/node_modules/undici/docs/docs/api/GlobalInstallation.md +139 -0
- package/dist/node_modules/undici/docs/docs/api/H2CClient.md +263 -0
- package/dist/node_modules/undici/docs/docs/api/MockAgent.md +603 -0
- package/dist/node_modules/undici/docs/docs/api/MockCallHistory.md +197 -0
- package/dist/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +43 -0
- package/dist/node_modules/undici/docs/docs/api/MockClient.md +81 -0
- package/dist/node_modules/undici/docs/docs/api/MockErrors.md +12 -0
- package/dist/node_modules/undici/docs/docs/api/MockPool.md +555 -0
- package/dist/node_modules/undici/docs/docs/api/Pool.md +84 -0
- package/dist/node_modules/undici/docs/docs/api/PoolStats.md +35 -0
- package/dist/node_modules/undici/docs/docs/api/ProxyAgent.md +229 -0
- package/dist/node_modules/undici/docs/docs/api/RedirectHandler.md +93 -0
- package/dist/node_modules/undici/docs/docs/api/RetryAgent.md +50 -0
- package/dist/node_modules/undici/docs/docs/api/RetryHandler.md +118 -0
- package/dist/node_modules/undici/docs/docs/api/RoundRobinPool.md +145 -0
- package/dist/node_modules/undici/docs/docs/api/SnapshotAgent.md +616 -0
- package/dist/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +274 -0
- package/dist/node_modules/undici/docs/docs/api/Util.md +25 -0
- package/dist/node_modules/undici/docs/docs/api/WebSocket.md +141 -0
- package/dist/node_modules/undici/docs/docs/api/api-lifecycle.md +91 -0
- package/dist/node_modules/undici/docs/docs/best-practices/client-certificate.md +64 -0
- package/dist/node_modules/undici/docs/docs/best-practices/crawling.md +58 -0
- package/dist/node_modules/undici/docs/docs/best-practices/mocking-request.md +190 -0
- package/dist/node_modules/undici/docs/docs/best-practices/proxy.md +127 -0
- package/dist/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +224 -0
- package/dist/node_modules/undici/docs/docs/best-practices/writing-tests.md +63 -0
- package/dist/node_modules/undici/index-fetch.js +65 -0
- package/dist/node_modules/undici/index.d.ts +3 -0
- package/dist/node_modules/undici/index.js +234 -0
- package/dist/node_modules/undici/lib/api/abort-signal.js +59 -0
- package/dist/node_modules/undici/lib/api/api-connect.js +110 -0
- package/dist/node_modules/undici/lib/api/api-pipeline.js +252 -0
- package/dist/node_modules/undici/lib/api/api-request.js +214 -0
- package/dist/node_modules/undici/lib/api/api-stream.js +209 -0
- package/dist/node_modules/undici/lib/api/api-upgrade.js +111 -0
- package/dist/node_modules/undici/lib/api/index.js +7 -0
- package/dist/node_modules/undici/lib/api/readable.js +580 -0
- package/dist/node_modules/undici/lib/cache/memory-cache-store.js +234 -0
- package/dist/node_modules/undici/lib/cache/sqlite-cache-store.js +461 -0
- package/dist/node_modules/undici/lib/core/connect.js +137 -0
- package/dist/node_modules/undici/lib/core/constants.js +143 -0
- package/dist/node_modules/undici/lib/core/diagnostics.js +227 -0
- package/dist/node_modules/undici/lib/core/errors.js +477 -0
- package/dist/node_modules/undici/lib/core/request.js +438 -0
- package/dist/node_modules/undici/lib/core/socks5-client.js +407 -0
- package/dist/node_modules/undici/lib/core/socks5-utils.js +203 -0
- package/dist/node_modules/undici/lib/core/symbols.js +75 -0
- package/dist/node_modules/undici/lib/core/tree.js +160 -0
- package/dist/node_modules/undici/lib/core/util.js +992 -0
- package/dist/node_modules/undici/lib/dispatcher/agent.js +158 -0
- package/dist/node_modules/undici/lib/dispatcher/balanced-pool.js +219 -0
- package/dist/node_modules/undici/lib/dispatcher/client-h1.js +1610 -0
- package/dist/node_modules/undici/lib/dispatcher/client-h2.js +995 -0
- package/dist/node_modules/undici/lib/dispatcher/client.js +659 -0
- package/dist/node_modules/undici/lib/dispatcher/dispatcher-base.js +165 -0
- package/dist/node_modules/undici/lib/dispatcher/dispatcher.js +48 -0
- package/dist/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +146 -0
- package/dist/node_modules/undici/lib/dispatcher/fixed-queue.js +135 -0
- package/dist/node_modules/undici/lib/dispatcher/h2c-client.js +51 -0
- package/dist/node_modules/undici/lib/dispatcher/pool-base.js +214 -0
- package/dist/node_modules/undici/lib/dispatcher/pool.js +118 -0
- package/dist/node_modules/undici/lib/dispatcher/proxy-agent.js +318 -0
- package/dist/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
- package/dist/node_modules/undici/lib/dispatcher/round-robin-pool.js +137 -0
- package/dist/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +249 -0
- package/dist/node_modules/undici/lib/encoding/index.js +33 -0
- package/dist/node_modules/undici/lib/global.js +50 -0
- package/dist/node_modules/undici/lib/handler/cache-handler.js +578 -0
- package/dist/node_modules/undici/lib/handler/cache-revalidation-handler.js +124 -0
- package/dist/node_modules/undici/lib/handler/decorator-handler.js +67 -0
- package/dist/node_modules/undici/lib/handler/deduplication-handler.js +460 -0
- package/dist/node_modules/undici/lib/handler/redirect-handler.js +238 -0
- package/dist/node_modules/undici/lib/handler/retry-handler.js +394 -0
- package/dist/node_modules/undici/lib/handler/unwrap-handler.js +100 -0
- package/dist/node_modules/undici/lib/handler/wrap-handler.js +105 -0
- package/dist/node_modules/undici/lib/interceptor/cache.js +495 -0
- package/dist/node_modules/undici/lib/interceptor/decompress.js +259 -0
- package/dist/node_modules/undici/lib/interceptor/deduplicate.js +117 -0
- package/dist/node_modules/undici/lib/interceptor/dns.js +571 -0
- package/dist/node_modules/undici/lib/interceptor/dump.js +112 -0
- package/dist/node_modules/undici/lib/interceptor/redirect.js +21 -0
- package/dist/node_modules/undici/lib/interceptor/response-error.js +95 -0
- package/dist/node_modules/undici/lib/interceptor/retry.js +19 -0
- package/dist/node_modules/undici/lib/llhttp/.gitkeep +0 -0
- package/dist/node_modules/undici/lib/llhttp/constants.d.ts +195 -0
- package/dist/node_modules/undici/lib/llhttp/constants.js +531 -0
- package/dist/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
- package/dist/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
- package/dist/node_modules/undici/lib/llhttp/utils.d.ts +2 -0
- package/dist/node_modules/undici/lib/llhttp/utils.js +12 -0
- package/dist/node_modules/undici/lib/mock/mock-agent.js +232 -0
- package/dist/node_modules/undici/lib/mock/mock-call-history.js +248 -0
- package/dist/node_modules/undici/lib/mock/mock-client.js +68 -0
- package/dist/node_modules/undici/lib/mock/mock-errors.js +29 -0
- package/dist/node_modules/undici/lib/mock/mock-interceptor.js +209 -0
- package/dist/node_modules/undici/lib/mock/mock-pool.js +68 -0
- package/dist/node_modules/undici/lib/mock/mock-symbols.js +32 -0
- package/dist/node_modules/undici/lib/mock/mock-utils.js +486 -0
- package/dist/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
- package/dist/node_modules/undici/lib/mock/snapshot-agent.js +353 -0
- package/dist/node_modules/undici/lib/mock/snapshot-recorder.js +588 -0
- package/dist/node_modules/undici/lib/mock/snapshot-utils.js +158 -0
- package/dist/node_modules/undici/lib/util/cache.js +407 -0
- package/dist/node_modules/undici/lib/util/date.js +653 -0
- package/dist/node_modules/undici/lib/util/promise.js +28 -0
- package/dist/node_modules/undici/lib/util/runtime-features.js +124 -0
- package/dist/node_modules/undici/lib/util/stats.js +32 -0
- package/dist/node_modules/undici/lib/util/timers.js +425 -0
- package/dist/node_modules/undici/lib/web/cache/cache.js +864 -0
- package/dist/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
- package/dist/node_modules/undici/lib/web/cache/util.js +45 -0
- package/dist/node_modules/undici/lib/web/cookies/constants.js +12 -0
- package/dist/node_modules/undici/lib/web/cookies/index.js +199 -0
- package/dist/node_modules/undici/lib/web/cookies/parse.js +322 -0
- package/dist/node_modules/undici/lib/web/cookies/util.js +282 -0
- package/dist/node_modules/undici/lib/web/eventsource/eventsource-stream.js +399 -0
- package/dist/node_modules/undici/lib/web/eventsource/eventsource.js +501 -0
- package/dist/node_modules/undici/lib/web/eventsource/util.js +29 -0
- package/dist/node_modules/undici/lib/web/fetch/LICENSE +21 -0
- package/dist/node_modules/undici/lib/web/fetch/body.js +509 -0
- package/dist/node_modules/undici/lib/web/fetch/constants.js +131 -0
- package/dist/node_modules/undici/lib/web/fetch/data-url.js +596 -0
- package/dist/node_modules/undici/lib/web/fetch/formdata-parser.js +575 -0
- package/dist/node_modules/undici/lib/web/fetch/formdata.js +259 -0
- package/dist/node_modules/undici/lib/web/fetch/global.js +40 -0
- package/dist/node_modules/undici/lib/web/fetch/headers.js +719 -0
- package/dist/node_modules/undici/lib/web/fetch/index.js +2397 -0
- package/dist/node_modules/undici/lib/web/fetch/request.js +1115 -0
- package/dist/node_modules/undici/lib/web/fetch/response.js +641 -0
- package/dist/node_modules/undici/lib/web/fetch/util.js +1520 -0
- package/dist/node_modules/undici/lib/web/infra/index.js +229 -0
- package/dist/node_modules/undici/lib/web/subresource-integrity/Readme.md +9 -0
- package/dist/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +307 -0
- package/dist/node_modules/undici/lib/web/webidl/index.js +1006 -0
- package/dist/node_modules/undici/lib/web/websocket/connection.js +329 -0
- package/dist/node_modules/undici/lib/web/websocket/constants.js +126 -0
- package/dist/node_modules/undici/lib/web/websocket/events.js +331 -0
- package/dist/node_modules/undici/lib/web/websocket/frame.js +133 -0
- package/dist/node_modules/undici/lib/web/websocket/permessage-deflate.js +118 -0
- package/dist/node_modules/undici/lib/web/websocket/receiver.js +450 -0
- package/dist/node_modules/undici/lib/web/websocket/sender.js +109 -0
- package/dist/node_modules/undici/lib/web/websocket/stream/websocketerror.js +104 -0
- package/dist/node_modules/undici/lib/web/websocket/stream/websocketstream.js +497 -0
- package/dist/node_modules/undici/lib/web/websocket/util.js +347 -0
- package/dist/node_modules/undici/lib/web/websocket/websocket.js +751 -0
- package/dist/node_modules/undici/package.json +152 -0
- package/dist/node_modules/undici/scripts/strip-comments.js +10 -0
- package/dist/node_modules/undici/types/README.md +6 -0
- package/dist/node_modules/undici/types/agent.d.ts +32 -0
- package/dist/node_modules/undici/types/api.d.ts +43 -0
- package/dist/node_modules/undici/types/balanced-pool.d.ts +30 -0
- package/dist/node_modules/undici/types/cache-interceptor.d.ts +179 -0
- package/dist/node_modules/undici/types/cache.d.ts +36 -0
- package/dist/node_modules/undici/types/client-stats.d.ts +15 -0
- package/dist/node_modules/undici/types/client.d.ts +123 -0
- package/dist/node_modules/undici/types/connector.d.ts +36 -0
- package/dist/node_modules/undici/types/content-type.d.ts +21 -0
- package/dist/node_modules/undici/types/cookies.d.ts +30 -0
- package/dist/node_modules/undici/types/diagnostics-channel.d.ts +74 -0
- package/dist/node_modules/undici/types/dispatcher.d.ts +273 -0
- package/dist/node_modules/undici/types/env-http-proxy-agent.d.ts +22 -0
- package/dist/node_modules/undici/types/errors.d.ts +177 -0
- package/dist/node_modules/undici/types/eventsource.d.ts +66 -0
- package/dist/node_modules/undici/types/fetch.d.ts +231 -0
- package/dist/node_modules/undici/types/formdata.d.ts +114 -0
- package/dist/node_modules/undici/types/global-dispatcher.d.ts +9 -0
- package/dist/node_modules/undici/types/global-origin.d.ts +7 -0
- package/dist/node_modules/undici/types/h2c-client.d.ts +73 -0
- package/dist/node_modules/undici/types/handlers.d.ts +14 -0
- package/dist/node_modules/undici/types/header.d.ts +160 -0
- package/dist/node_modules/undici/types/index.d.ts +91 -0
- package/dist/node_modules/undici/types/interceptors.d.ts +80 -0
- package/dist/node_modules/undici/types/mock-agent.d.ts +68 -0
- package/dist/node_modules/undici/types/mock-call-history.d.ts +111 -0
- package/dist/node_modules/undici/types/mock-client.d.ts +27 -0
- package/dist/node_modules/undici/types/mock-errors.d.ts +12 -0
- package/dist/node_modules/undici/types/mock-interceptor.d.ts +94 -0
- package/dist/node_modules/undici/types/mock-pool.d.ts +27 -0
- package/dist/node_modules/undici/types/patch.d.ts +29 -0
- package/dist/node_modules/undici/types/pool-stats.d.ts +19 -0
- package/dist/node_modules/undici/types/pool.d.ts +41 -0
- package/dist/node_modules/undici/types/proxy-agent.d.ts +29 -0
- package/dist/node_modules/undici/types/readable.d.ts +68 -0
- package/dist/node_modules/undici/types/retry-agent.d.ts +8 -0
- package/dist/node_modules/undici/types/retry-handler.d.ts +125 -0
- package/dist/node_modules/undici/types/round-robin-pool.d.ts +41 -0
- package/dist/node_modules/undici/types/snapshot-agent.d.ts +109 -0
- package/dist/node_modules/undici/types/socks5-proxy-agent.d.ts +25 -0
- package/dist/node_modules/undici/types/util.d.ts +18 -0
- package/dist/node_modules/undici/types/utility.d.ts +7 -0
- package/dist/node_modules/undici/types/webidl.d.ts +347 -0
- package/dist/node_modules/undici/types/websocket.d.ts +188 -0
- package/package.json +2 -2
|
@@ -0,0 +1,571 @@
|
|
|
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
|
+
function hasSafeIterator (headers) {
|
|
9
|
+
const prototype = Object.getPrototypeOf(headers)
|
|
10
|
+
const ownIterator = Object.prototype.hasOwnProperty.call(headers, Symbol.iterator)
|
|
11
|
+
return ownIterator || (prototype != null && prototype !== Object.prototype && typeof headers[Symbol.iterator] === 'function')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function isHostHeader (key) {
|
|
15
|
+
return typeof key === 'string' && key.toLowerCase() === 'host'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function normalizeHeaders (headers) {
|
|
19
|
+
if (headers == null) {
|
|
20
|
+
return null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (Array.isArray(headers)) {
|
|
24
|
+
if (headers.length === 0 || !Array.isArray(headers[0])) {
|
|
25
|
+
return headers
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const normalized = []
|
|
29
|
+
for (const header of headers) {
|
|
30
|
+
if (Array.isArray(header) && header.length === 2) {
|
|
31
|
+
normalized.push(header[0], header[1])
|
|
32
|
+
} else {
|
|
33
|
+
normalized.push(header)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return normalized
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (typeof headers === 'object' && hasSafeIterator(headers)) {
|
|
41
|
+
const normalized = []
|
|
42
|
+
for (const header of headers) {
|
|
43
|
+
if (Array.isArray(header) && header.length === 2) {
|
|
44
|
+
normalized.push(header[0], header[1])
|
|
45
|
+
} else {
|
|
46
|
+
normalized.push(header)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return normalized
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return headers
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function hasHostHeader (headers) {
|
|
57
|
+
if (headers == null) {
|
|
58
|
+
return false
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (Array.isArray(headers)) {
|
|
62
|
+
if (headers.length === 0) {
|
|
63
|
+
return false
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (let i = 0; i < headers.length; i += 2) {
|
|
67
|
+
if (isHostHeader(headers[i])) {
|
|
68
|
+
return true
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return false
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (typeof headers === 'object') {
|
|
76
|
+
for (const key in headers) {
|
|
77
|
+
if (isHostHeader(key)) {
|
|
78
|
+
return true
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function withHostHeader (host, headers) {
|
|
87
|
+
const normalizedHeaders = normalizeHeaders(headers)
|
|
88
|
+
|
|
89
|
+
if (hasHostHeader(normalizedHeaders)) {
|
|
90
|
+
return normalizedHeaders
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (Array.isArray(normalizedHeaders)) {
|
|
94
|
+
return ['host', host, ...normalizedHeaders]
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (normalizedHeaders && typeof normalizedHeaders === 'object') {
|
|
98
|
+
return {
|
|
99
|
+
host,
|
|
100
|
+
...normalizedHeaders
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return { host }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
class DNSStorage {
|
|
108
|
+
#maxItems = 0
|
|
109
|
+
#records = new Map()
|
|
110
|
+
|
|
111
|
+
constructor (opts) {
|
|
112
|
+
this.#maxItems = opts.maxItems
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
get size () {
|
|
116
|
+
return this.#records.size
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
get (hostname) {
|
|
120
|
+
return this.#records.get(hostname) ?? null
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
set (hostname, records) {
|
|
124
|
+
this.#records.set(hostname, records)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
delete (hostname) {
|
|
128
|
+
this.#records.delete(hostname)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Delegate to storage decide can we do more lookups or not
|
|
132
|
+
full () {
|
|
133
|
+
return this.size >= this.#maxItems
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
class DNSInstance {
|
|
138
|
+
#maxTTL = 0
|
|
139
|
+
#maxItems = 0
|
|
140
|
+
dualStack = true
|
|
141
|
+
affinity = null
|
|
142
|
+
lookup = null
|
|
143
|
+
pick = null
|
|
144
|
+
storage = null
|
|
145
|
+
|
|
146
|
+
constructor (opts) {
|
|
147
|
+
this.#maxTTL = opts.maxTTL
|
|
148
|
+
this.#maxItems = opts.maxItems
|
|
149
|
+
this.dualStack = opts.dualStack
|
|
150
|
+
this.affinity = opts.affinity
|
|
151
|
+
this.lookup = opts.lookup ?? this.#defaultLookup
|
|
152
|
+
this.pick = opts.pick ?? this.#defaultPick
|
|
153
|
+
this.storage = opts.storage ?? new DNSStorage(opts)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
runLookup (origin, opts, cb) {
|
|
157
|
+
const ips = this.storage.get(origin.hostname)
|
|
158
|
+
|
|
159
|
+
// If full, we just return the origin
|
|
160
|
+
if (ips == null && this.storage.full()) {
|
|
161
|
+
cb(null, origin)
|
|
162
|
+
return
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const newOpts = {
|
|
166
|
+
affinity: this.affinity,
|
|
167
|
+
dualStack: this.dualStack,
|
|
168
|
+
lookup: this.lookup,
|
|
169
|
+
pick: this.pick,
|
|
170
|
+
...opts.dns,
|
|
171
|
+
maxTTL: this.#maxTTL,
|
|
172
|
+
maxItems: this.#maxItems
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// If no IPs we lookup
|
|
176
|
+
if (ips == null) {
|
|
177
|
+
this.lookup(origin, newOpts, (err, addresses) => {
|
|
178
|
+
if (err || addresses == null || addresses.length === 0) {
|
|
179
|
+
cb(err ?? new InformationalError('No DNS entries found'))
|
|
180
|
+
return
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
this.setRecords(origin, addresses)
|
|
184
|
+
const records = this.storage.get(origin.hostname)
|
|
185
|
+
|
|
186
|
+
const ip = this.pick(
|
|
187
|
+
origin,
|
|
188
|
+
records,
|
|
189
|
+
newOpts.affinity
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
let port
|
|
193
|
+
if (typeof ip.port === 'number') {
|
|
194
|
+
port = `:${ip.port}`
|
|
195
|
+
} else if (origin.port !== '') {
|
|
196
|
+
port = `:${origin.port}`
|
|
197
|
+
} else {
|
|
198
|
+
port = ''
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
cb(
|
|
202
|
+
null,
|
|
203
|
+
new URL(`${origin.protocol}//${
|
|
204
|
+
ip.family === 6 ? `[${ip.address}]` : ip.address
|
|
205
|
+
}${port}`)
|
|
206
|
+
)
|
|
207
|
+
})
|
|
208
|
+
} else {
|
|
209
|
+
// If there's IPs we pick
|
|
210
|
+
const ip = this.pick(
|
|
211
|
+
origin,
|
|
212
|
+
ips,
|
|
213
|
+
newOpts.affinity
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
// If no IPs we lookup - deleting old records
|
|
217
|
+
if (ip == null) {
|
|
218
|
+
this.storage.delete(origin.hostname)
|
|
219
|
+
this.runLookup(origin, opts, cb)
|
|
220
|
+
return
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
let port
|
|
224
|
+
if (typeof ip.port === 'number') {
|
|
225
|
+
port = `:${ip.port}`
|
|
226
|
+
} else if (origin.port !== '') {
|
|
227
|
+
port = `:${origin.port}`
|
|
228
|
+
} else {
|
|
229
|
+
port = ''
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
cb(
|
|
233
|
+
null,
|
|
234
|
+
new URL(`${origin.protocol}//${
|
|
235
|
+
ip.family === 6 ? `[${ip.address}]` : ip.address
|
|
236
|
+
}${port}`)
|
|
237
|
+
)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
#defaultLookup (origin, opts, cb) {
|
|
242
|
+
lookup(
|
|
243
|
+
origin.hostname,
|
|
244
|
+
{
|
|
245
|
+
all: true,
|
|
246
|
+
family: this.dualStack === false ? this.affinity : 0,
|
|
247
|
+
order: 'ipv4first'
|
|
248
|
+
},
|
|
249
|
+
(err, addresses) => {
|
|
250
|
+
if (err) {
|
|
251
|
+
return cb(err)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const results = new Map()
|
|
255
|
+
|
|
256
|
+
for (const addr of addresses) {
|
|
257
|
+
// On linux we found duplicates, we attempt to remove them with
|
|
258
|
+
// the latest record
|
|
259
|
+
results.set(`${addr.address}:${addr.family}`, addr)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
cb(null, results.values())
|
|
263
|
+
}
|
|
264
|
+
)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
#defaultPick (origin, hostnameRecords, affinity) {
|
|
268
|
+
let ip = null
|
|
269
|
+
const { records, offset } = hostnameRecords
|
|
270
|
+
|
|
271
|
+
let family
|
|
272
|
+
if (this.dualStack) {
|
|
273
|
+
if (affinity == null) {
|
|
274
|
+
// Balance between ip families
|
|
275
|
+
if (offset == null || offset === maxInt) {
|
|
276
|
+
hostnameRecords.offset = 0
|
|
277
|
+
affinity = 4
|
|
278
|
+
} else {
|
|
279
|
+
hostnameRecords.offset++
|
|
280
|
+
affinity = (hostnameRecords.offset & 1) === 1 ? 6 : 4
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (records[affinity] != null && records[affinity].ips.length > 0) {
|
|
285
|
+
family = records[affinity]
|
|
286
|
+
} else {
|
|
287
|
+
family = records[affinity === 4 ? 6 : 4]
|
|
288
|
+
}
|
|
289
|
+
} else {
|
|
290
|
+
family = records[affinity]
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// If no IPs we return null
|
|
294
|
+
if (family == null || family.ips.length === 0) {
|
|
295
|
+
return ip
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (family.offset == null || family.offset === maxInt) {
|
|
299
|
+
family.offset = 0
|
|
300
|
+
} else {
|
|
301
|
+
family.offset++
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const position = family.offset % family.ips.length
|
|
305
|
+
ip = family.ips[position] ?? null
|
|
306
|
+
|
|
307
|
+
if (ip == null) {
|
|
308
|
+
return ip
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (Date.now() - ip.timestamp > ip.ttl) { // record TTL is already in ms
|
|
312
|
+
// We delete expired records
|
|
313
|
+
// It is possible that they have different TTL, so we manage them individually
|
|
314
|
+
family.ips.splice(position, 1)
|
|
315
|
+
return this.pick(origin, hostnameRecords, affinity)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return ip
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
pickFamily (origin, ipFamily) {
|
|
322
|
+
const records = this.storage.get(origin.hostname)?.records
|
|
323
|
+
if (!records) {
|
|
324
|
+
return null
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const family = records[ipFamily]
|
|
328
|
+
if (!family) {
|
|
329
|
+
return null
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (family.offset == null || family.offset === maxInt) {
|
|
333
|
+
family.offset = 0
|
|
334
|
+
} else {
|
|
335
|
+
family.offset++
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const position = family.offset % family.ips.length
|
|
339
|
+
const ip = family.ips[position] ?? null
|
|
340
|
+
if (ip == null) {
|
|
341
|
+
return ip
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (Date.now() - ip.timestamp > ip.ttl) { // record TTL is already in ms
|
|
345
|
+
// We delete expired records
|
|
346
|
+
// It is possible that they have different TTL, so we manage them individually
|
|
347
|
+
family.ips.splice(position, 1)
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return ip
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
setRecords (origin, addresses) {
|
|
354
|
+
const timestamp = Date.now()
|
|
355
|
+
const records = { records: { 4: null, 6: null } }
|
|
356
|
+
let minTTL = this.#maxTTL
|
|
357
|
+
for (const record of addresses) {
|
|
358
|
+
record.timestamp = timestamp
|
|
359
|
+
if (typeof record.ttl === 'number') {
|
|
360
|
+
// The record TTL is expected to be in ms
|
|
361
|
+
record.ttl = Math.min(record.ttl, this.#maxTTL)
|
|
362
|
+
minTTL = Math.min(minTTL, record.ttl)
|
|
363
|
+
} else {
|
|
364
|
+
record.ttl = this.#maxTTL
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const familyRecords = records.records[record.family] ?? { ips: [] }
|
|
368
|
+
|
|
369
|
+
familyRecords.ips.push(record)
|
|
370
|
+
records.records[record.family] = familyRecords
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// We provide a default TTL if external storage will be used without TTL per record-level support
|
|
374
|
+
this.storage.set(origin.hostname, records, { ttl: minTTL })
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
deleteRecords (origin) {
|
|
378
|
+
this.storage.delete(origin.hostname)
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
getHandler (meta, opts) {
|
|
382
|
+
return new DNSDispatchHandler(this, meta, opts)
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
class DNSDispatchHandler extends DecoratorHandler {
|
|
387
|
+
#state = null
|
|
388
|
+
#opts = null
|
|
389
|
+
#dispatch = null
|
|
390
|
+
#origin = null
|
|
391
|
+
#controller = null
|
|
392
|
+
#newOrigin = null
|
|
393
|
+
#firstTry = true
|
|
394
|
+
|
|
395
|
+
constructor (state, { origin, handler, dispatch, newOrigin }, opts) {
|
|
396
|
+
super(handler)
|
|
397
|
+
this.#origin = origin
|
|
398
|
+
this.#newOrigin = newOrigin
|
|
399
|
+
this.#opts = { ...opts }
|
|
400
|
+
this.#state = state
|
|
401
|
+
this.#dispatch = dispatch
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
onResponseError (controller, err) {
|
|
405
|
+
switch (err.code) {
|
|
406
|
+
case 'ETIMEDOUT':
|
|
407
|
+
case 'ECONNREFUSED': {
|
|
408
|
+
if (this.#state.dualStack) {
|
|
409
|
+
if (!this.#firstTry) {
|
|
410
|
+
super.onResponseError(controller, err)
|
|
411
|
+
return
|
|
412
|
+
}
|
|
413
|
+
this.#firstTry = false
|
|
414
|
+
|
|
415
|
+
// Pick an ip address from the other family
|
|
416
|
+
const otherFamily = this.#newOrigin.hostname[0] === '[' ? 4 : 6
|
|
417
|
+
const ip = this.#state.pickFamily(this.#origin, otherFamily)
|
|
418
|
+
if (ip == null) {
|
|
419
|
+
super.onResponseError(controller, err)
|
|
420
|
+
return
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
let port
|
|
424
|
+
if (typeof ip.port === 'number') {
|
|
425
|
+
port = `:${ip.port}`
|
|
426
|
+
} else if (this.#origin.port !== '') {
|
|
427
|
+
port = `:${this.#origin.port}`
|
|
428
|
+
} else {
|
|
429
|
+
port = ''
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
const dispatchOpts = {
|
|
433
|
+
...this.#opts,
|
|
434
|
+
origin: `${this.#origin.protocol}//${
|
|
435
|
+
ip.family === 6 ? `[${ip.address}]` : ip.address
|
|
436
|
+
}${port}`,
|
|
437
|
+
headers: withHostHeader(this.#origin.host, this.#opts.headers)
|
|
438
|
+
}
|
|
439
|
+
this.#dispatch(dispatchOpts, this)
|
|
440
|
+
return
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// if dual-stack disabled, we error out
|
|
444
|
+
super.onResponseError(controller, err)
|
|
445
|
+
break
|
|
446
|
+
}
|
|
447
|
+
case 'ENOTFOUND':
|
|
448
|
+
this.#state.deleteRecords(this.#origin)
|
|
449
|
+
super.onResponseError(controller, err)
|
|
450
|
+
break
|
|
451
|
+
default:
|
|
452
|
+
super.onResponseError(controller, err)
|
|
453
|
+
break
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
module.exports = interceptorOpts => {
|
|
459
|
+
if (
|
|
460
|
+
interceptorOpts?.maxTTL != null &&
|
|
461
|
+
(typeof interceptorOpts?.maxTTL !== 'number' || interceptorOpts?.maxTTL < 0)
|
|
462
|
+
) {
|
|
463
|
+
throw new InvalidArgumentError('Invalid maxTTL. Must be a positive number')
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (
|
|
467
|
+
interceptorOpts?.maxItems != null &&
|
|
468
|
+
(typeof interceptorOpts?.maxItems !== 'number' ||
|
|
469
|
+
interceptorOpts?.maxItems < 1)
|
|
470
|
+
) {
|
|
471
|
+
throw new InvalidArgumentError(
|
|
472
|
+
'Invalid maxItems. Must be a positive number and greater than zero'
|
|
473
|
+
)
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
if (
|
|
477
|
+
interceptorOpts?.affinity != null &&
|
|
478
|
+
interceptorOpts?.affinity !== 4 &&
|
|
479
|
+
interceptorOpts?.affinity !== 6
|
|
480
|
+
) {
|
|
481
|
+
throw new InvalidArgumentError('Invalid affinity. Must be either 4 or 6')
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (
|
|
485
|
+
interceptorOpts?.dualStack != null &&
|
|
486
|
+
typeof interceptorOpts?.dualStack !== 'boolean'
|
|
487
|
+
) {
|
|
488
|
+
throw new InvalidArgumentError('Invalid dualStack. Must be a boolean')
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (
|
|
492
|
+
interceptorOpts?.lookup != null &&
|
|
493
|
+
typeof interceptorOpts?.lookup !== 'function'
|
|
494
|
+
) {
|
|
495
|
+
throw new InvalidArgumentError('Invalid lookup. Must be a function')
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (
|
|
499
|
+
interceptorOpts?.pick != null &&
|
|
500
|
+
typeof interceptorOpts?.pick !== 'function'
|
|
501
|
+
) {
|
|
502
|
+
throw new InvalidArgumentError('Invalid pick. Must be a function')
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (
|
|
506
|
+
interceptorOpts?.storage != null &&
|
|
507
|
+
(typeof interceptorOpts?.storage?.get !== 'function' ||
|
|
508
|
+
typeof interceptorOpts?.storage?.set !== 'function' ||
|
|
509
|
+
typeof interceptorOpts?.storage?.full !== 'function' ||
|
|
510
|
+
typeof interceptorOpts?.storage?.delete !== 'function'
|
|
511
|
+
)
|
|
512
|
+
) {
|
|
513
|
+
throw new InvalidArgumentError('Invalid storage. Must be a object with methods: { get, set, full, delete }')
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
const dualStack = interceptorOpts?.dualStack ?? true
|
|
517
|
+
let affinity
|
|
518
|
+
if (dualStack) {
|
|
519
|
+
affinity = interceptorOpts?.affinity ?? null
|
|
520
|
+
} else {
|
|
521
|
+
affinity = interceptorOpts?.affinity ?? 4
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const opts = {
|
|
525
|
+
maxTTL: interceptorOpts?.maxTTL ?? 10e3, // Expressed in ms
|
|
526
|
+
lookup: interceptorOpts?.lookup ?? null,
|
|
527
|
+
pick: interceptorOpts?.pick ?? null,
|
|
528
|
+
dualStack,
|
|
529
|
+
affinity,
|
|
530
|
+
maxItems: interceptorOpts?.maxItems ?? Infinity,
|
|
531
|
+
storage: interceptorOpts?.storage
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
const instance = new DNSInstance(opts)
|
|
535
|
+
|
|
536
|
+
return dispatch => {
|
|
537
|
+
return function dnsInterceptor (origDispatchOpts, handler) {
|
|
538
|
+
const origin =
|
|
539
|
+
origDispatchOpts.origin.constructor === URL
|
|
540
|
+
? origDispatchOpts.origin
|
|
541
|
+
: new URL(origDispatchOpts.origin)
|
|
542
|
+
|
|
543
|
+
if (isIP(origin.hostname) !== 0) {
|
|
544
|
+
return dispatch(origDispatchOpts, handler)
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
instance.runLookup(origin, origDispatchOpts, (err, newOrigin) => {
|
|
548
|
+
if (err) {
|
|
549
|
+
return handler.onResponseError(null, err)
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
const dispatchOpts = {
|
|
553
|
+
...origDispatchOpts,
|
|
554
|
+
servername: origin.hostname, // For SNI on TLS
|
|
555
|
+
origin: newOrigin.origin,
|
|
556
|
+
headers: withHostHeader(origin.host, origDispatchOpts.headers)
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
dispatch(
|
|
560
|
+
dispatchOpts,
|
|
561
|
+
instance.getHandler(
|
|
562
|
+
{ origin, dispatch, handler, newOrigin },
|
|
563
|
+
origDispatchOpts
|
|
564
|
+
)
|
|
565
|
+
)
|
|
566
|
+
})
|
|
567
|
+
|
|
568
|
+
return true
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { InvalidArgumentError, RequestAbortedError } = require('../core/errors')
|
|
4
|
+
const DecoratorHandler = require('../handler/decorator-handler')
|
|
5
|
+
|
|
6
|
+
class DumpHandler extends DecoratorHandler {
|
|
7
|
+
#maxSize = 1024 * 1024
|
|
8
|
+
#dumped = false
|
|
9
|
+
#size = 0
|
|
10
|
+
#controller = null
|
|
11
|
+
aborted = false
|
|
12
|
+
reason = false
|
|
13
|
+
|
|
14
|
+
constructor ({ maxSize, signal }, handler) {
|
|
15
|
+
if (maxSize != null && (!Number.isFinite(maxSize) || maxSize < 1)) {
|
|
16
|
+
throw new InvalidArgumentError('maxSize must be a number greater than 0')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
super(handler)
|
|
20
|
+
|
|
21
|
+
this.#maxSize = maxSize ?? this.#maxSize
|
|
22
|
+
// this.#handler = handler
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#abort (reason) {
|
|
26
|
+
this.aborted = true
|
|
27
|
+
this.reason = reason
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
onRequestStart (controller, context) {
|
|
31
|
+
controller.abort = this.#abort.bind(this)
|
|
32
|
+
this.#controller = controller
|
|
33
|
+
|
|
34
|
+
return super.onRequestStart(controller, context)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
onResponseStart (controller, statusCode, headers, statusMessage) {
|
|
38
|
+
const contentLength = headers['content-length']
|
|
39
|
+
|
|
40
|
+
if (contentLength != null && contentLength > this.#maxSize) {
|
|
41
|
+
throw new RequestAbortedError(
|
|
42
|
+
`Response size (${contentLength}) larger than maxSize (${
|
|
43
|
+
this.#maxSize
|
|
44
|
+
})`
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (this.aborted === true) {
|
|
49
|
+
return true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return super.onResponseStart(controller, statusCode, headers, statusMessage)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
onResponseError (controller, err) {
|
|
56
|
+
if (this.#dumped) {
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// On network errors before connect, controller will be null
|
|
61
|
+
err = this.#controller?.reason ?? err
|
|
62
|
+
|
|
63
|
+
super.onResponseError(controller, err)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
onResponseData (controller, chunk) {
|
|
67
|
+
this.#size = this.#size + chunk.length
|
|
68
|
+
|
|
69
|
+
if (this.#size >= this.#maxSize) {
|
|
70
|
+
this.#dumped = true
|
|
71
|
+
|
|
72
|
+
if (this.aborted === true) {
|
|
73
|
+
super.onResponseError(controller, this.reason)
|
|
74
|
+
} else {
|
|
75
|
+
super.onResponseEnd(controller, {})
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return true
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
onResponseEnd (controller, trailers) {
|
|
83
|
+
if (this.#dumped) {
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (this.#controller.aborted === true) {
|
|
88
|
+
super.onResponseError(controller, this.reason)
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
super.onResponseEnd(controller, trailers)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function createDumpInterceptor (
|
|
97
|
+
{ maxSize: defaultMaxSize } = {
|
|
98
|
+
maxSize: 1024 * 1024
|
|
99
|
+
}
|
|
100
|
+
) {
|
|
101
|
+
return dispatch => {
|
|
102
|
+
return function Intercept (opts, handler) {
|
|
103
|
+
const { dumpMaxSize = defaultMaxSize } = opts
|
|
104
|
+
|
|
105
|
+
const dumpHandler = new DumpHandler({ maxSize: dumpMaxSize, signal: opts.signal }, handler)
|
|
106
|
+
|
|
107
|
+
return dispatch(opts, dumpHandler)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = createDumpInterceptor
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const RedirectHandler = require('../handler/redirect-handler')
|
|
4
|
+
|
|
5
|
+
function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections } = {}) {
|
|
6
|
+
return (dispatch) => {
|
|
7
|
+
return function Intercept (opts, handler) {
|
|
8
|
+
const { maxRedirections = defaultMaxRedirections, ...rest } = opts
|
|
9
|
+
|
|
10
|
+
if (maxRedirections == null || maxRedirections === 0) {
|
|
11
|
+
return dispatch(opts, handler)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const dispatchOpts = { ...rest } // Stop sub dispatcher from also redirecting.
|
|
15
|
+
const redirectHandler = new RedirectHandler(dispatch, maxRedirections, dispatchOpts, handler)
|
|
16
|
+
return dispatch(dispatchOpts, redirectHandler)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = createRedirectInterceptor
|