Skip to content

Commit 8ac252d

Browse files
committed
refactor: proxy interceptor
1 parent 04c8acb commit 8ac252d

File tree

3 files changed

+43
-85
lines changed

3 files changed

+43
-85
lines changed

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ module.exports.DecoratorHandler = DecoratorHandler
3737
module.exports.RedirectHandler = RedirectHandler
3838
module.exports.createRedirectInterceptor = createRedirectInterceptor
3939
module.exports.interceptors = {
40-
Proxy: require('./lib/interceptor/proxy'),
40+
proxy: require('./lib/interceptor/proxy'),
4141
redirect: require('./lib/interceptor/redirect'),
4242
retry: require('./lib/interceptor/retry')
4343
}

lib/interceptor/proxy.js

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,11 @@
11
'use strict'
2-
3-
const { InvalidArgumentError } = require('../core/errors')
42
const ProxyAgent = require('../dispatcher/proxy-agent')
5-
const Dispatcher = require('../dispatcher/dispatcher')
6-
7-
class ProxyInterceptor extends Dispatcher {
8-
constructor (dispatcher, opts) {
9-
if (dispatcher == null) {
10-
throw new InvalidArgumentError(
11-
'Dispatcher instance is mandatory for ProxyInterceptor'
12-
)
13-
}
14-
15-
if (typeof opts === 'string') {
16-
opts = { uri: opts }
17-
}
18-
19-
if (!opts || (!opts.uri && !(opts instanceof URL))) {
20-
throw new InvalidArgumentError(
21-
'Proxy opts.uri or instance of URL is mandatory'
22-
)
23-
}
243

25-
if (opts.auth && opts.token) {
26-
throw new InvalidArgumentError(
27-
'opts.auth cannot be used in combination with opts.token'
28-
)
4+
module.exports = opts => {
5+
const agent = new ProxyAgent(opts)
6+
return () => {
7+
return function proxyInterceptor (opts, handler) {
8+
return agent.dispatch(opts, handler)
299
}
30-
31-
super()
32-
this.dispatcher = dispatcher
33-
this.agent = new ProxyAgent(opts)
34-
}
35-
36-
dispatch (opts, handler) {
37-
return this.agent.dispatch(opts, handler)
38-
}
39-
40-
close () {
41-
return this.dispatcher.close().then(() => this.agent.close())
4210
}
4311
}
44-
45-
module.exports = ProxyInterceptor

test/interceptors/proxy.js

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,22 @@ const {
1515
getGlobalDispatcher,
1616
setGlobalDispatcher,
1717
request,
18-
Pool,
19-
Dispatcher
18+
Pool
2019
} = require('../..')
2120
const { InvalidArgumentError } = require('../../lib/core/errors')
22-
const { Proxy } = interceptors
21+
const { proxy: proxyInterceptor } = interceptors
2322

2423
test('should throw error when no uri is provided', t => {
2524
t = tspl(t, { plan: 2 })
26-
t.throws(() => new Proxy(), InvalidArgumentError)
27-
t.throws(() => new Proxy(null, {}), InvalidArgumentError)
25+
t.throws(() => proxyInterceptor(), InvalidArgumentError)
26+
t.throws(() => proxyInterceptor({}), InvalidArgumentError)
2827
})
2928

3029
test('using auth in combination with token should throw', t => {
3130
t = tspl(t, { plan: 1 })
3231
t.throws(
3332
() =>
34-
new Proxy({}, {
33+
proxyInterceptor({
3534
auth: 'foo',
3635
token: 'Bearer bar',
3736
uri: 'http://example.com'
@@ -42,26 +41,20 @@ test('using auth in combination with token should throw', t => {
4241

4342
test('should accept string, URL and object as options', t => {
4443
t = tspl(t, { plan: 3 })
45-
t.doesNotThrow(() => new Proxy({}, 'http://example.com'))
46-
t.doesNotThrow(() => new Proxy({}, new URL('http://example.com')))
47-
t.doesNotThrow(() => new Proxy({}, { uri: 'http://example.com' }))
44+
t.doesNotThrow(() => proxyInterceptor('http://example.com'))
45+
t.doesNotThrow(() => proxyInterceptor(new URL('http://example.com')))
46+
t.doesNotThrow(() => proxyInterceptor({ uri: 'http://example.com' }))
4847
})
4948

50-
test('use proxy-agent to connect through proxy', { skip: true }, async t => {
51-
t = tspl(t, { plan: 8 })
52-
const CustomDispatcher = class extends Dispatcher {
53-
constructor (dispatcher) {
54-
super()
55-
this.dispatcher = dispatcher
56-
}
57-
58-
dispatch (opts, handler) {
59-
t.ok(true, 'should call dispatch')
60-
return this.dispatcher.dispatch(opts, handler)
61-
}
49+
test('should work with nested dispatch', async t => {
50+
t = tspl(t, { plan: 7 })
51+
let counter = 0
52+
const customDispatch = dispatcher => {
53+
const binded = dispatcher.dispatch.bind(dispatcher)
54+
return (opts, handler) => {
55+
counter++
6256

63-
close () {
64-
return this.dispatcher.close()
57+
return binded(opts, handler)
6558
}
6659
}
6760
const server = await buildServer()
@@ -73,9 +66,9 @@ test('use proxy-agent to connect through proxy', { skip: true }, async t => {
7366
const client = new Client(serverUrl)
7467
const parsedOrigin = new URL(serverUrl)
7568
const dispatcher = client.compose([
76-
(dispatcher) => new CustomDispatcher(dispatcher),
77-
(dispatcher) => new Proxy(dispatcher, proxyUrl),
78-
(dispatcher) => new CustomDispatcher(dispatcher)
69+
customDispatch, // not called
70+
proxyInterceptor(proxyUrl), // chain restarted here
71+
customDispatch
7972
])
8073

8174
proxy.on('connect', () => {
@@ -107,13 +100,14 @@ test('use proxy-agent to connect through proxy', { skip: true }, async t => {
107100
'keep-alive',
108101
'should remain the connection open'
109102
)
103+
t.equal(counter, 1, 'should call customDispatch twice')
110104

111105
server.close()
112106
proxy.close()
113107
await dispatcher.close()
114108
})
115109

116-
test('use proxy-interceptor to connect through proxy when composing dispatcher', async t => {
110+
test('use proxy-agent to connect through proxy', async t => {
117111
t = tspl(t, { plan: 6 })
118112
const server = await buildServer()
119113
const proxy = await buildProxy()
@@ -124,9 +118,7 @@ test('use proxy-interceptor to connect through proxy when composing dispatcher',
124118
const client = new Client(serverUrl)
125119
const parsedOrigin = new URL(serverUrl)
126120

127-
const dispatcher = client.compose(
128-
dispatcher => new Proxy(dispatcher, proxyUrl)
129-
)
121+
const dispatcher = client.compose(proxyInterceptor(proxyUrl))
130122

131123
proxy.on('connect', () => {
132124
t.ok(true, 'should connect to proxy')
@@ -194,7 +186,7 @@ test('use proxy agent to connect through proxy using Pool', async t => {
194186
}
195187
const client = new Client(serverUrl)
196188
const dispatcher = client.compose(
197-
dispatcher => new Proxy(dispatcher, {
189+
proxyInterceptor({
198190
auth: Buffer.from('user:pass').toString('base64'),
199191
uri: proxyUrl,
200192
clientFactory
@@ -227,7 +219,7 @@ test('use proxy-agent to connect through proxy using path with params', async t
227219
const proxyUrl = `http://localhost:${proxy.address().port}`
228220
const client = new Client(serverUrl)
229221
const parsedOrigin = new URL(serverUrl)
230-
const dispatcher = client.compose(dispatcher => new Proxy(dispatcher, proxyUrl))
222+
const dispatcher = client.compose(proxyInterceptor(proxyUrl))
231223

232224
proxy.on('connect', () => {
233225
t.ok(true, 'should call proxy')
@@ -272,7 +264,7 @@ test('use proxy-agent to connect through proxy with basic auth in URL', async t
272264
const proxyUrl = `http://user:pass@localhost:${proxy.address().port}`
273265
const client = new Client(serverUrl)
274266
const parsedOrigin = new URL(serverUrl)
275-
const dispatcher = client.compose(dispatcher => new Proxy(dispatcher, proxyUrl))
267+
const dispatcher = client.compose(proxyInterceptor(proxyUrl))
276268

277269
proxy.authenticate = function (req, fn) {
278270
t.ok(true, 'authentication should be called')
@@ -326,7 +318,7 @@ test('use proxy-agent with auth', async t => {
326318
const client = new Client(serverUrl)
327319
const parsedOrigin = new URL(serverUrl)
328320
const dispatcher = client.compose(
329-
dispatcher => new Proxy(dispatcher, {
321+
proxyInterceptor({
330322
auth: Buffer.from('user:pass').toString('base64'),
331323
uri: proxyUrl
332324
})
@@ -384,7 +376,7 @@ test('use proxy-agent with token', async t => {
384376
const client = new Client(serverUrl)
385377
const parsedOrigin = new URL(serverUrl)
386378
const dispatcher = client.compose(
387-
dispatcher => new Proxy(dispatcher, {
379+
proxyInterceptor({
388380
token: `Bearer ${Buffer.from('user:pass').toString('base64')}`,
389381
uri: proxyUrl
390382
})
@@ -441,7 +433,7 @@ test('use proxy-agent with custom headers', async t => {
441433
const proxyUrl = `http://user:pass@localhost:${proxy.address().port}`
442434
const client = new Client(serverUrl)
443435
const dispatcher = client.compose(
444-
dispatcher => new Proxy(dispatcher, {
436+
proxyInterceptor({
445437
uri: proxyUrl,
446438
headers: {
447439
'User-Agent': 'Foobar/1.0.0'
@@ -479,7 +471,7 @@ test('sending proxy-authorization in request headers should throw', async t => {
479471
const proxyUrl = `http://localhost:${proxy.address().port}`
480472
const client = new Client(serverUrl)
481473
const dispatcher = client.compose(
482-
dispatcher => new Proxy(dispatcher, {
474+
proxyInterceptor({
483475
uri: proxyUrl
484476
})
485477
)
@@ -541,7 +533,7 @@ test('use proxy-agent with setGlobalDispatcher', async t => {
541533
const parsedOrigin = new URL(serverUrl)
542534
const defaultDispatcher = getGlobalDispatcher()
543535

544-
setGlobalDispatcher(defaultDispatcher.compose(dispatcher => new Proxy(dispatcher, proxyUrl)))
536+
setGlobalDispatcher(defaultDispatcher.compose(proxyInterceptor(proxyUrl)))
545537
after(() => setGlobalDispatcher(defaultDispatcher))
546538

547539
proxy.on('connect', () => {
@@ -587,7 +579,7 @@ test('ProxyAgent correctly sends headers when using fetch - #1355, #1623', async
587579

588580
const serverUrl = `http://localhost:${server.address().port}`
589581
const proxyUrl = `http://localhost:${proxy.address().port}`
590-
setGlobalDispatcher(defaultDispatcher.compose(dispatcher => new Proxy(dispatcher, proxyUrl)))
582+
setGlobalDispatcher(defaultDispatcher.compose(proxyInterceptor(proxyUrl)))
591583

592584
after(() => setGlobalDispatcher(defaultDispatcher))
593585

@@ -638,7 +630,7 @@ test('should throw when proxy does not return 200', async t => {
638630
return false
639631
}
640632

641-
const client = new Client(serverUrl).compose(dispatcher => new Proxy(dispatcher, proxyUrl))
633+
const client = new Client(serverUrl).compose(proxyInterceptor(proxyUrl))
642634
try {
643635
await client.request({ path: '/', method: 'GET' })
644636
t.fail()
@@ -664,7 +656,7 @@ test('pass ProxyAgent proxy status code error when using fetch - #2161', async t
664656
return false
665657
}
666658

667-
const client = new Client(serverUrl).compose(dispatcher => new Proxy(dispatcher, proxyUrl))
659+
const client = new Client(serverUrl).compose(proxyInterceptor(proxyUrl))
668660
try {
669661
await fetch(serverUrl, { dispatcher: client })
670662
t.fail()
@@ -686,7 +678,7 @@ test('Proxy via HTTP to HTTPS endpoint', async t => {
686678
const serverUrl = `https://localhost:${server.address().port}`
687679
const proxyUrl = `http://localhost:${proxy.address().port}`
688680
const client = new Client(serverUrl).compose(
689-
dispatcher => new Proxy(dispatcher, {
681+
proxyInterceptor({
690682
uri: proxyUrl,
691683
requestTls: {
692684
ca: [
@@ -750,7 +742,7 @@ test('Proxy via HTTPS to HTTPS endpoint', async t => {
750742
const serverUrl = `https://localhost:${server.address().port}`
751743
const proxyUrl = `https://localhost:${proxy.address().port}`
752744
const proxyAgent = new Client(serverUrl).compose(
753-
dispatcher => new Proxy(dispatcher, {
745+
proxyInterceptor({
754746
uri: proxyUrl,
755747
proxyTls: {
756748
ca: [
@@ -825,7 +817,7 @@ test('Proxy via HTTPS to HTTP endpoint', async t => {
825817
const serverUrl = `http://localhost:${server.address().port}`
826818
const proxyUrl = `https://localhost:${proxy.address().port}`
827819
const proxyAgent = new Client(serverUrl).compose(
828-
dispatcher => new Proxy(dispatcher, {
820+
proxyInterceptor({
829821
uri: proxyUrl,
830822
proxyTls: {
831823
ca: [
@@ -881,7 +873,7 @@ test('Proxy via HTTP to HTTP endpoint', async t => {
881873

882874
const serverUrl = `http://localhost:${server.address().port}`
883875
const proxyUrl = `http://localhost:${proxy.address().port}`
884-
const proxyAgent = new Client(serverUrl).compose(dispatcher => new Proxy(dispatcher, proxyUrl))
876+
const proxyAgent = new Client(serverUrl).compose(proxyInterceptor(proxyUrl))
885877

886878
server.on('request', function (req, res) {
887879
t.ok(!req.connection.encrypted)

0 commit comments

Comments
 (0)