From 208e4a9d1b2d1cd236178810fc3ec5fee6376b25 Mon Sep 17 00:00:00 2001 From: delvedor Date: Mon, 2 May 2022 18:32:14 +0200 Subject: [PATCH 1/2] Do not url encode username and password --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index fac7c53..3ee4afe 100644 --- a/index.js +++ b/index.js @@ -26,7 +26,7 @@ class HttpProxyAgent extends http.Agent { } if (this.proxy.username || this.proxy.password) { - const base64 = Buffer.from(`${this.proxy.username || ''}:${this.proxy.password || ''}`).toString('base64') + const base64 = Buffer.from(`${decodeURIComponent(this.proxy.username || '')}:${decodeURIComponent(this.proxy.password || '')}`).toString('base64') requestOptions.headers['proxy-authorization'] = `Basic ${base64}` } @@ -80,7 +80,7 @@ class HttpsProxyAgent extends https.Agent { } if (this.proxy.username || this.proxy.password) { - const base64 = Buffer.from(`${this.proxy.username || ''}:${this.proxy.password || ''}`).toString('base64') + const base64 = Buffer.from(`${decodeURIComponent(this.proxy.username || '')}:${decodeURIComponent(this.proxy.password || '')}`).toString('base64') requestOptions.headers['proxy-authorization'] = `Basic ${base64}` } From 57c8ee3020363967139f5eaf94a14e32df1e88ab Mon Sep 17 00:00:00 2001 From: delvedor Date: Mon, 2 May 2022 18:32:19 +0200 Subject: [PATCH 2/2] Updated test --- test/http-http.test.js | 37 ++++++++++++++++++++++++++++++++++++ test/http-https.test.js | 2 +- test/https-http.test.js | 2 +- test/https-https.test.js | 41 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 78 insertions(+), 4 deletions(-) diff --git a/test/http-http.test.js b/test/http-http.test.js index 4354226..666c8ec 100644 --- a/test/http-http.test.js +++ b/test/http-http.test.js @@ -379,3 +379,40 @@ test('Timeout', async t => { server.close() proxy.close() }) + +test('Username and password should not be encoded', async t => { + const server = await createServer() + const proxy = await createProxy() + server.on('request', (req, res) => res.end('ok')) + + proxy.authenticate = function (req, fn) { + fn(null, req.headers['proxy-authorization'] === `Basic ${Buffer.from('username_with_=:password_with_=').toString('base64')}`) + } + + const response = await request({ + method: 'GET', + hostname: server.address().address, + port: server.address().port, + path: '/', + agent: new HttpProxyAgent({ + keepAlive: true, + keepAliveMsecs: 1000, + maxSockets: 256, + maxFreeSockets: 256, + scheduling: 'lifo', + proxy: `http://username_with_=:password_with_=@${proxy.address().address}:${proxy.address().port}` + }) + }) + + let body = '' + response.setEncoding('utf8') + for await (const chunk of response) { + body += chunk + } + + t.is(body, 'ok') + t.is(response.statusCode, 200) + + server.close() + proxy.close() +}) diff --git a/test/http-https.test.js b/test/http-https.test.js index 3a3d0c7..90f2e90 100644 --- a/test/http-https.test.js +++ b/test/http-https.test.js @@ -320,7 +320,7 @@ test('Timeout', async t => { try { await request({ method: 'GET', - hostname: server.address().address, + hostname: SERVER_HOSTNAME, port: server.address().port, path: '/', timeout: 1, diff --git a/test/https-http.test.js b/test/https-http.test.js index fd95d6b..570fcbc 100644 --- a/test/https-http.test.js +++ b/test/https-http.test.js @@ -330,7 +330,7 @@ test('Timeout', async t => { maxSockets: 256, maxFreeSockets: 256, scheduling: 'lifo', - proxy: `http://${proxy.address().address}:${proxy.address().port}` + proxy: `https://${PROXY_HOSTNAME}:${proxy.address().port}` }) }) t.fail('Should throw') diff --git a/test/https-https.test.js b/test/https-https.test.js index 8428e87..fff5fbc 100644 --- a/test/https-https.test.js +++ b/test/https-https.test.js @@ -320,7 +320,7 @@ test('Timeout', async t => { try { await request({ method: 'GET', - hostname: server.address().address, + hostname: SERVER_HOSTNAME, port: server.address().port, path: '/', timeout: 1, @@ -330,7 +330,7 @@ test('Timeout', async t => { maxSockets: 256, maxFreeSockets: 256, scheduling: 'lifo', - proxy: `http://${proxy.address().address}:${proxy.address().port}` + proxy: `https://${PROXY_HOSTNAME}:${proxy.address().port}` }) }) t.fail('Should throw') @@ -341,3 +341,40 @@ test('Timeout', async t => { server.close() proxy.close() }) + +test('Username and password should not be encoded', async t => { + const server = await createSecureServer() + const proxy = await createSecureProxy() + server.on('request', (req, res) => res.end('ok')) + + proxy.authenticate = function (req, fn) { + fn(null, req.headers['proxy-authorization'] === `Basic ${Buffer.from('username_with_=:password_with_=').toString('base64')}`) + } + + const response = await request({ + method: 'GET', + hostname: SERVER_HOSTNAME, + port: server.address().port, + path: '/', + agent: new HttpsProxyAgent({ + keepAlive: true, + keepAliveMsecs: 1000, + maxSockets: 256, + maxFreeSockets: 256, + scheduling: 'lifo', + proxy: `https://username_with_=:password_with_=@${PROXY_HOSTNAME}:${proxy.address().port}` + }) + }) + + let body = '' + response.setEncoding('utf8') + for await (const chunk of response) { + body += chunk + } + + t.is(body, 'ok') + t.is(response.statusCode, 200) + + server.close() + proxy.close() +})