Skip to content

Commit 42104ff

Browse files
Merge pull request #18 from adobe/bugfix/ACNA-1682
fix(breaking): ACNA-1682 - HTTP/HTTPS proxy agent logic
2 parents ec1037a + b598877 commit 42104ff

File tree

3 files changed

+48
-30
lines changed

3 files changed

+48
-30
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
coverage
44
launch.json
55
package-lock.json
6+
yarn.lock
67
/node_modules/
78
junit.xml
89
test-report.html

src/ProxyFetch.js

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,39 @@ const { codes } = require('./SDKErrors')
1616
const HttpProxyAgent = require('http-proxy-agent')
1717
const HttpsProxyAgent = require('https-proxy-agent')
1818
const { urlToHttpOptions } = require('./utils')
19-
const http = require('http')
2019

2120
/* global Response, Request */
2221

22+
/**
23+
* @private
24+
*
25+
* @param {string} resourceUrl an endpoint url for proxyAgent selection
26+
* @param {object} authOptions an object which contains auth information
27+
* @returns {http.Agent} a http.Agent for basic auth proxy
28+
*/
29+
function proxyAgent (resourceUrl, authOptions) {
30+
const { proxyUrl, username, password, rejectUnauthorized = true } = authOptions
31+
const proxyOpts = urlToHttpOptions(proxyUrl)
32+
33+
if (!proxyOpts.auth && username && password) {
34+
logger.debug('username and password not set in proxy url, using credentials passed in the constructor.')
35+
proxyOpts.auth = `${username}:${password}`
36+
}
37+
38+
// the passing on of this property to the underlying implementation only works on https-proxy-agent@2.2.4
39+
// this is only used for unit-tests and passed in the constructor
40+
proxyOpts.rejectUnauthorized = rejectUnauthorized
41+
if (rejectUnauthorized === false) {
42+
logger.warn(`proxyAgent - rejectUnauthorized is set to ${rejectUnauthorized}`)
43+
}
44+
45+
if (resourceUrl.startsWith('https')) {
46+
return new HttpsProxyAgent(proxyOpts)
47+
} else {
48+
return new HttpProxyAgent(proxyOpts)
49+
}
50+
}
51+
2352
/**
2453
* Proxy Auth Options
2554
*
@@ -55,34 +84,6 @@ class ProxyFetch {
5584
return this
5685
}
5786

58-
/**
59-
* Returns the http.Agent used for this proxy
60-
*
61-
* @returns {http.Agent} a http.Agent for basic auth proxy
62-
*/
63-
proxyAgent () {
64-
const { proxyUrl, username, password, rejectUnauthorized = true } = this.authOptions
65-
const proxyOpts = urlToHttpOptions(proxyUrl)
66-
67-
if (!proxyOpts.auth && username && password) {
68-
logger.debug('username and password not set in proxy url, using credentials passed in the constructor.')
69-
proxyOpts.auth = `${username}:${password}`
70-
}
71-
72-
// the passing on of this property to the underlying implementation only works on https-proxy-agent@2.2.4
73-
// this is only used for unit-tests and passed in the constructor
74-
proxyOpts.rejectUnauthorized = rejectUnauthorized
75-
if (rejectUnauthorized === false) {
76-
logger.warn(`proxyAgent - rejectUnauthorized is set to ${rejectUnauthorized}`)
77-
}
78-
79-
if (proxyOpts.protocol.startsWith('https')) {
80-
return new HttpsProxyAgent(proxyOpts)
81-
} else {
82-
return new HttpProxyAgent(proxyOpts)
83-
}
84-
}
85-
8687
/**
8788
* Fetch function, using the configured NTLM Auth options.
8889
*
@@ -93,7 +94,7 @@ class ProxyFetch {
9394
async fetch (resource, options = {}) {
9495
return originalFetch(resource, {
9596
...options,
96-
agent: this.proxyAgent()
97+
agent: proxyAgent(resource, this.authOptions)
9798
})
9899
}
99100
}

test/proxy.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ describe('http proxy', () => {
110110

111111
const testUrl = `${protocol}://localhost:${apiServerPort}/mirror?${queryString.stringify(queryObject)}`
112112
const response = await proxyFetch.fetch(testUrl, { headers })
113+
const spy = jest.spyOn(proxyFetch, 'fetch').mockImplementation(() => testUrl)
114+
const pattern = /\b^http\b/
115+
expect(proxyFetch.fetch()).toMatch(new RegExp(pattern))
116+
spy.mockRestore()
113117
expect(response.ok).toEqual(true)
114118
const json = await response.json()
115119
expect(json).toStrictEqual(queryObject)
@@ -134,6 +138,10 @@ describe('http proxy', () => {
134138

135139
const testUrl = `${protocol}://localhost:${apiServerPort}/mirror?${queryString.stringify(queryObject)}`
136140
const response = await proxyFetch.fetch(testUrl, { headers })
141+
const spy = jest.spyOn(proxyFetch, 'fetch').mockImplementation(() => testUrl)
142+
const pattern = /\b^https\b/
143+
expect(proxyFetch.fetch()).not.toMatch(new RegExp(pattern))
144+
spy.mockRestore()
137145
expect(response.ok).toEqual(false)
138146
expect(response.status).toEqual(403)
139147
})
@@ -249,6 +257,10 @@ describe('https proxy', () => {
249257

250258
const testUrl = `${protocol}://localhost:${apiServerPort}/mirror?${queryString.stringify(queryObject)}`
251259
const response = await proxyFetch.fetch(testUrl, { headers })
260+
const spy = jest.spyOn(proxyFetch, 'fetch').mockImplementation(() => testUrl)
261+
const pattern = /\b^https\b/
262+
expect(proxyFetch.fetch()).toMatch(new RegExp(pattern))
263+
spy.mockRestore()
252264
expect(response.ok).toEqual(true)
253265
const json = await response.json()
254266
expect(json).toStrictEqual(queryObject)
@@ -268,6 +280,10 @@ describe('https proxy', () => {
268280

269281
const testUrl = `${protocol}://localhost:${apiServerPort}/mirror?${queryString.stringify(queryObject)}`
270282
const response = await proxyFetch.fetch(testUrl, { headers })
283+
const spy = jest.spyOn(proxyFetch, 'fetch').mockImplementation(() => testUrl)
284+
const pattern = /\b^http\b/
285+
expect(proxyFetch.fetch()).not.toMatch(new RegExp(pattern))
286+
spy.mockRestore()
271287
expect(response.ok).toEqual(false)
272288
expect(response.status).toEqual(403)
273289
})

0 commit comments

Comments
 (0)