From 8aee327bae5b3badb3b6989f643e4fb42d24ead0 Mon Sep 17 00:00:00 2001 From: delvedor Date: Mon, 2 May 2022 18:05:58 +0200 Subject: [PATCH 1/2] Add timeout support --- index.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 0922c99..fac7c53 100644 --- a/index.js +++ b/index.js @@ -21,7 +21,8 @@ class HttpProxyAgent extends http.Agent { path: `${options.host}:${options.port}`, setHost: false, headers: { connection: this.keepAlive ? 'keep-alive' : 'close', host: `${options.host}:${options.port}` }, - agent: false + agent: false, + timeout: options.timeout || 0 } if (this.proxy.username || this.proxy.password) { @@ -44,6 +45,10 @@ class HttpProxyAgent extends http.Agent { } }) + request.once('timeout', () => { + request.destroy(new Error('Proxy timeout')) + }) + request.once('error', err => { request.removeAllListeners() callback(err, null) @@ -70,7 +75,8 @@ class HttpsProxyAgent extends https.Agent { path: `${options.host}:${options.port}`, setHost: false, headers: { connection: this.keepAlive ? 'keep-alive' : 'close', host: `${options.host}:${options.port}` }, - agent: false + agent: false, + timeout: options.timeout || 0 } if (this.proxy.username || this.proxy.password) { @@ -95,6 +101,10 @@ class HttpsProxyAgent extends https.Agent { } }) + request.once('timeout', () => { + request.destroy(new Error('Proxy timeout')) + }) + request.once('error', err => { request.removeAllListeners() callback(err, null) From 713e74c047a2c9c2f7d4fde4d77431e33fffa4c1 Mon Sep 17 00:00:00 2001 From: delvedor Date: Mon, 2 May 2022 18:06:04 +0200 Subject: [PATCH 2/2] Updated test --- test/http-http.test.js | 30 ++++++++++++++++++++++++++++++ test/http-https.test.js | 30 ++++++++++++++++++++++++++++++ test/https-http.test.js | 30 ++++++++++++++++++++++++++++++ test/https-https.test.js | 30 ++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+) diff --git a/test/http-http.test.js b/test/http-http.test.js index b96556a..4354226 100644 --- a/test/http-http.test.js +++ b/test/http-http.test.js @@ -349,3 +349,33 @@ test('Test Host Header', async t => { server.close() proxy.close() }) + +test('Timeout', async t => { + const server = await createServer() + const proxy = await createProxy() + server.on('request', (req, res) => res.end('ok')) + + try { + await request({ + method: 'GET', + hostname: server.address().address, + port: server.address().port, + path: '/', + timeout: 1, + agent: new HttpProxyAgent({ + keepAlive: true, + keepAliveMsecs: 1000, + maxSockets: 256, + maxFreeSockets: 256, + scheduling: 'lifo', + proxy: `http://${proxy.address().address}:${proxy.address().port}` + }) + }) + t.fail('Should throw') + } catch (err) { + t.is(err.message, 'Proxy timeout') + } + + server.close() + proxy.close() +}) diff --git a/test/http-https.test.js b/test/http-https.test.js index c6be10c..3a3d0c7 100644 --- a/test/http-https.test.js +++ b/test/http-https.test.js @@ -311,3 +311,33 @@ test('Configure the agent to NOT reuse sockets', async t => { server.close() proxy.close() }) + +test('Timeout', async t => { + const server = await createSecureServer() + const proxy = await createProxy() + server.on('request', (req, res) => res.end('ok')) + + try { + await request({ + method: 'GET', + hostname: server.address().address, + port: server.address().port, + path: '/', + timeout: 1, + agent: new HttpsProxyAgent({ + keepAlive: true, + keepAliveMsecs: 1000, + maxSockets: 256, + maxFreeSockets: 256, + scheduling: 'lifo', + proxy: `http://${proxy.address().address}:${proxy.address().port}` + }) + }) + t.fail('Should throw') + } catch (err) { + t.is(err.message, 'Proxy timeout') + } + + server.close() + proxy.close() +}) diff --git a/test/https-http.test.js b/test/https-http.test.js index 4f5801c..fd95d6b 100644 --- a/test/https-http.test.js +++ b/test/https-http.test.js @@ -311,3 +311,33 @@ test('Configure the agent to NOT reuse sockets', async t => { server.close() proxy.close() }) + +test('Timeout', async t => { + const server = await createServer() + const proxy = await createSecureProxy() + server.on('request', (req, res) => res.end('ok')) + + try { + await request({ + method: 'GET', + hostname: server.address().address, + port: server.address().port, + path: '/', + timeout: 1, + agent: new HttpProxyAgent({ + keepAlive: true, + keepAliveMsecs: 1000, + maxSockets: 256, + maxFreeSockets: 256, + scheduling: 'lifo', + proxy: `http://${proxy.address().address}:${proxy.address().port}` + }) + }) + t.fail('Should throw') + } catch (err) { + t.is(err.message, 'Proxy timeout') + } + + server.close() + proxy.close() +}) diff --git a/test/https-https.test.js b/test/https-https.test.js index 3ad8929..8428e87 100644 --- a/test/https-https.test.js +++ b/test/https-https.test.js @@ -311,3 +311,33 @@ test('Configure the agent to NOT reuse sockets', async t => { server.close() proxy.close() }) + +test('Timeout', async t => { + const server = await createSecureServer() + const proxy = await createSecureProxy() + server.on('request', (req, res) => res.end('ok')) + + try { + await request({ + method: 'GET', + hostname: server.address().address, + port: server.address().port, + path: '/', + timeout: 1, + agent: new HttpsProxyAgent({ + keepAlive: true, + keepAliveMsecs: 1000, + maxSockets: 256, + maxFreeSockets: 256, + scheduling: 'lifo', + proxy: `http://${proxy.address().address}:${proxy.address().port}` + }) + }) + t.fail('Should throw') + } catch (err) { + t.is(err.message, 'Proxy timeout') + } + + server.close() + proxy.close() +})