Skip to content

Commit 5dd0440

Browse files
committed
refactor: replace internal redirects with high-level ones
1 parent f05646c commit 5dd0440

File tree

11 files changed

+82
-43
lines changed

11 files changed

+82
-43
lines changed

docs/api/Agent.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ Returns: `Agent`
1919
Extends: [`PoolOptions`](Pool.md#parameter-pooloptions)
2020

2121
* **factory** `(origin: URL, opts: Object) => Dispatcher` - Default: `(origin, opts) => new Pool(origin, opts)`
22-
* **maxRedirections** `Integer` - Default: `0`. The number of HTTP redirection to follow unless otherwise specified in `DispatchOptions`.
2322

2423
## Instance Properties
2524

lib/agent.js

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33
const { InvalidArgumentError } = require('./core/errors')
44
const { kClients, kRunning, kClose, kDestroy, kDispatch } = require('./core/symbols')
55
const DispatcherBase = require('./dispatcher-base')
6-
const RedirectHandler = require('./handler/RedirectHandler')
76
const Pool = require('./pool')
87
const Client = require('./client')
98
const util = require('./core/util')
109

1110
const kOnConnect = Symbol('onConnect')
1211
const kOnDisconnect = Symbol('onDisconnect')
1312
const kOnConnectionError = Symbol('onConnectionError')
14-
const kMaxRedirections = Symbol('maxRedirections')
1513
const kOnDrain = Symbol('onDrain')
1614
const kFactory = Symbol('factory')
1715
const kOptions = Symbol('options')
@@ -23,7 +21,7 @@ function defaultFactory (origin, opts) {
2321
}
2422

2523
class Agent extends DispatcherBase {
26-
constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) {
24+
constructor ({ factory = defaultFactory, connect, ...options } = {}) {
2725
super()
2826

2927
if (typeof factory !== 'function') {
@@ -34,16 +32,11 @@ class Agent extends DispatcherBase {
3432
throw new InvalidArgumentError('connect must be a function or an object')
3533
}
3634

37-
if (!Number.isInteger(maxRedirections) || maxRedirections < 0) {
38-
throw new InvalidArgumentError('maxRedirections must be a positive number')
39-
}
40-
4135
if (connect && typeof connect !== 'function') {
4236
connect = { ...connect }
4337
}
4438

4539
this[kOptions] = { ...util.deepClone(options), connect }
46-
this[kMaxRedirections] = maxRedirections
4740
this[kFactory] = factory
4841
this[kClients] = new Map()
4942

@@ -95,18 +88,6 @@ class Agent extends DispatcherBase {
9588
this[kClients].set(key, dispatcher)
9689
}
9790

98-
if (this[kMaxRedirections] > 0) {
99-
return dispatcher.dispatch(
100-
opts,
101-
new RedirectHandler(
102-
dispatcher.dispatch.bind(dispatcher),
103-
this[kMaxRedirections],
104-
opts,
105-
handler
106-
)
107-
)
108-
}
109-
11091
return dispatcher.dispatch(opts, handler)
11192
}
11293

lib/api/api-connect.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const { AsyncResource } = require('node:async_hooks')
44
const { InvalidArgumentError, RequestAbortedError, SocketError } = require('../core/errors')
55
const util = require('../core/util')
6+
const RedirectHandler = require('../handler/RedirectHandler')
67
const { addSignal, removeSignal } = require('./abort-signal')
78

89
class ConnectHandler extends AsyncResource {
@@ -91,6 +92,16 @@ function connect (opts, callback) {
9192

9293
try {
9394
const connectHandler = new ConnectHandler(opts, callback)
95+
96+
if (opts?.maxRedirections != null && (!Number.isInteger(opts?.maxRedirections) || opts?.maxRedirections < 0)) {
97+
throw new InvalidArgumentError('maxRedirections must be a positive number')
98+
}
99+
100+
if (opts?.maxRedirections > 0) {
101+
RedirectHandler.buildDispatch(this, opts.maxRedirections)(opts, connectHandler)
102+
return
103+
}
104+
94105
this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler)
95106
} catch (err) {
96107
if (typeof callback !== 'function') {

lib/api/api-pipeline.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ const {
55
Duplex,
66
PassThrough
77
} = require('node:stream')
8+
const assert = require('node:assert')
9+
const { AsyncResource } = require('node:async_hooks')
810
const {
911
InvalidArgumentError,
1012
InvalidReturnValueError,
1113
RequestAbortedError
1214
} = require('../core/errors')
1315
const util = require('../core/util')
14-
const { AsyncResource } = require('node:async_hooks')
16+
const RedirectHandler = require('../handler/RedirectHandler')
1517
const { addSignal, removeSignal } = require('./abort-signal')
16-
const assert = require('node:assert')
1718

1819
const kResume = Symbol('resume')
1920

@@ -239,7 +240,17 @@ class PipelineHandler extends AsyncResource {
239240
function pipeline (opts, handler) {
240241
try {
241242
const pipelineHandler = new PipelineHandler(opts, handler)
242-
this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler)
243+
244+
if (opts?.maxRedirections != null && (!Number.isInteger(opts?.maxRedirections) || opts?.maxRedirections < 0)) {
245+
throw new InvalidArgumentError('maxRedirections must be a positive number')
246+
}
247+
248+
if (opts?.maxRedirections > 0) {
249+
RedirectHandler.buildDispatch(this, opts.maxRedirections)({ ...opts, body: pipelineHandler.req }, pipelineHandler)
250+
} else {
251+
this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler)
252+
}
253+
243254
return pipelineHandler.ret
244255
} catch (err) {
245256
return new PassThrough().destroy(err)

lib/api/api-request.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
'use strict'
22

3+
const { AsyncResource } = require('node:async_hooks')
34
const Readable = require('./readable')
45
const {
56
InvalidArgumentError,
67
RequestAbortedError
78
} = require('../core/errors')
89
const util = require('../core/util')
10+
const RedirectHandler = require('../handler/RedirectHandler')
911
const { getResolveErrorBodyCallback } = require('./util')
10-
const { AsyncResource } = require('node:async_hooks')
1112
const { addSignal, removeSignal } = require('./abort-signal')
1213

1314
class RequestHandler extends AsyncResource {
@@ -166,7 +167,18 @@ function request (opts, callback) {
166167
}
167168

168169
try {
169-
this.dispatch(opts, new RequestHandler(opts, callback))
170+
const handler = new RequestHandler(opts, callback)
171+
172+
if (opts?.maxRedirections != null && (!Number.isInteger(opts?.maxRedirections) || opts?.maxRedirections < 0)) {
173+
throw new InvalidArgumentError('maxRedirections must be a positive number')
174+
}
175+
176+
if (opts?.maxRedirections > 0) {
177+
RedirectHandler.buildDispatch(this, opts.maxRedirections)(opts, handler)
178+
return
179+
}
180+
181+
this.dispatch(opts, handler)
170182
} catch (err) {
171183
if (typeof callback !== 'function') {
172184
throw err

lib/api/api-stream.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const {
77
RequestAbortedError
88
} = require('../core/errors')
99
const util = require('../core/util')
10+
const RedirectHandler = require('../handler/RedirectHandler')
1011
const { getResolveErrorBodyCallback } = require('./util')
1112
const { AsyncResource } = require('node:async_hooks')
1213
const { addSignal, removeSignal } = require('./abort-signal')
@@ -207,7 +208,18 @@ function stream (opts, factory, callback) {
207208
}
208209

209210
try {
210-
this.dispatch(opts, new StreamHandler(opts, factory, callback))
211+
const handler = new StreamHandler(opts, factory, callback)
212+
213+
if (opts?.maxRedirections != null && (!Number.isInteger(opts?.maxRedirections) || opts?.maxRedirections < 0)) {
214+
throw new InvalidArgumentError('maxRedirections must be a positive number')
215+
}
216+
217+
if (opts?.maxRedirections > 0) {
218+
RedirectHandler.buildDispatch(this, opts.maxRedirections)(opts, handler)
219+
return
220+
}
221+
222+
this.dispatch(opts, handler)
211223
} catch (err) {
212224
if (typeof callback !== 'function') {
213225
throw err

lib/api/api-upgrade.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
'use strict'
22

3-
const { InvalidArgumentError, RequestAbortedError, SocketError } = require('../core/errors')
3+
const assert = require('node:assert')
44
const { AsyncResource } = require('node:async_hooks')
5+
const { InvalidArgumentError, RequestAbortedError, SocketError } = require('../core/errors')
56
const util = require('../core/util')
7+
const RedirectHandler = require('../handler/RedirectHandler')
68
const { addSignal, removeSignal } = require('./abort-signal')
7-
const assert = require('node:assert')
89

910
class UpgradeHandler extends AsyncResource {
1011
constructor (opts, callback) {
@@ -88,11 +89,22 @@ function upgrade (opts, callback) {
8889

8990
try {
9091
const upgradeHandler = new UpgradeHandler(opts, callback)
91-
this.dispatch({
92+
const upgradeOpts = {
9293
...opts,
9394
method: opts.method || 'GET',
9495
upgrade: opts.protocol || 'Websocket'
95-
}, upgradeHandler)
96+
}
97+
98+
if (opts?.maxRedirections != null && (!Number.isInteger(opts?.maxRedirections) || opts?.maxRedirections < 0)) {
99+
throw new InvalidArgumentError('maxRedirections must be a positive number')
100+
}
101+
102+
if (opts?.maxRedirections > 0) {
103+
RedirectHandler.buildDispatch(this, opts.maxRedirections)(upgradeOpts, upgradeHandler)
104+
return
105+
}
106+
107+
this.dispatch(upgradeOpts, upgradeHandler)
96108
} catch (err) {
97109
if (typeof callback !== 'function') {
98110
throw err

lib/client.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ const {
6262
kBodyTimeout,
6363
kStrictContentLength,
6464
kConnector,
65-
kMaxRedirections,
6665
kMaxRequests,
6766
kCounter,
6867
kClose,
@@ -135,7 +134,6 @@ class Client extends DispatcherBase {
135134
tls,
136135
strictContentLength,
137136
maxCachedSessions,
138-
maxRedirections,
139137
connect,
140138
maxRequestsPerClient,
141139
localAddress,
@@ -204,10 +202,6 @@ class Client extends DispatcherBase {
204202
throw new InvalidArgumentError('connect must be a function or an object')
205203
}
206204

207-
if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
208-
throw new InvalidArgumentError('maxRedirections must be a positive number')
209-
}
210-
211205
if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) {
212206
throw new InvalidArgumentError('maxRequestsPerClient must be a positive number')
213207
}
@@ -266,7 +260,6 @@ class Client extends DispatcherBase {
266260
this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3
267261
this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3
268262
this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength
269-
this[kMaxRedirections] = maxRedirections
270263
this[kMaxRequests] = maxRequestsPerClient
271264
this[kClosedResolve] = null
272265
this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1

lib/handler/RedirectHandler.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ class BodyAsyncIterable {
2424
}
2525

2626
class RedirectHandler {
27+
static buildDispatch (dispatcher, maxRedirections) {
28+
if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
29+
throw new InvalidArgumentError('maxRedirections must be a positive number')
30+
}
31+
32+
const dispatch = dispatcher.dispatch.bind(dispatcher)
33+
return (opts, originalHandler) => dispatch(opts, new RedirectHandler(dispatch, maxRedirections, opts, originalHandler))
34+
}
35+
2736
constructor (dispatch, maxRedirections, opts, handler) {
2837
if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
2938
throw new InvalidArgumentError('maxRedirections must be a positive number')

test/redirect-request.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ for (const factory of [
9090

9191
const server = await startRedirectingServer()
9292

93-
const { statusCode, headers, body: bodyStream, context: { history } } = await request(t, server, { maxRedirections: 10 }, `http://${server}/300?key=value`)
93+
const { statusCode, headers, body: bodyStream, context: { history } } = await request(t, server, undefined, `http://${server}/300?key=value`, { maxRedirections: 10 })
9494
const body = await bodyStream.text()
9595

9696
t.strictEqual(statusCode, 200)
@@ -380,10 +380,9 @@ for (const factory of [
380380
t = tspl(t, { plan: 1 })
381381

382382
try {
383-
await request(t, 'localhost', {
383+
await request(t, 'localhost', undefined, 'http://localhost', {
384+
method: 'GET',
384385
maxRedirections: 'INVALID'
385-
}, 'http://localhost', {
386-
method: 'GET'
387386
})
388387

389388
t.fail('Did not throw')

0 commit comments

Comments
 (0)