From 96c43511761d1eb16f7634313ae3eae6628ed0ba Mon Sep 17 00:00:00 2001 From: Matthias Osswald Date: Mon, 25 May 2020 13:05:12 +0200 Subject: [PATCH 1/3] fix(proxy): use keepAlive agent Using an agent with keepAlive improves performance as the socket is reused across multiple requests. --- lib/middleware/proxy.js | 5 ++++- test/unit/middleware/proxy.spec.js | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/middleware/proxy.js b/lib/middleware/proxy.js index 4f01c3d66..dcc48eee8 100644 --- a/lib/middleware/proxy.js +++ b/lib/middleware/proxy.js @@ -1,4 +1,5 @@ const url = require('url') +const http = require('http') const httpProxy = require('http-proxy') const _ = require('lodash') @@ -42,11 +43,13 @@ function parseProxyConfig (proxies, config) { port = config.port } const changeOrigin = proxyConfiguration.changeOrigin || false + const keepAliveAgent = new http.Agent({ keepAlive: true }) const proxy = httpProxy.createProxyServer({ target: { host: hostname, port, https, protocol }, xfwd: true, changeOrigin: changeOrigin, - secure: config.proxyValidateSSL + secure: config.proxyValidateSSL, + agent: keepAliveAgent }) ;['proxyReq', 'proxyRes'].forEach(function (name) { diff --git a/test/unit/middleware/proxy.spec.js b/test/unit/middleware/proxy.spec.js index 5e97e2290..98f7055b4 100644 --- a/test/unit/middleware/proxy.spec.js +++ b/test/unit/middleware/proxy.spec.js @@ -352,4 +352,13 @@ describe('middleware.proxy', () => { it('should handle empty proxy config', () => { expect(m.parseProxyConfig({})).to.deep.equal([]) }) + + it('should use agent with keepAlive=true', () => { + const proxy = { '/base': 'http://localhost:8000/proxy' } + const parsedProxyConfig = m.parseProxyConfig(proxy, {}) + expect(parsedProxyConfig).to.have.length(1) + expect(parsedProxyConfig[0].proxy.options.agent).to.containSubset({ + keepAlive: true + }) + }) }) From 15590a75a91b231b7baaa82b1b7281cd59674763 Mon Sep 17 00:00:00 2001 From: Matthias Osswald Date: Mon, 25 May 2020 13:05:12 +0200 Subject: [PATCH 2/3] fix(proxy): use https agent for https protocol --- lib/middleware/proxy.js | 6 ++++-- test/unit/middleware/proxy.spec.js | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/middleware/proxy.js b/lib/middleware/proxy.js index dcc48eee8..af7aa95a4 100644 --- a/lib/middleware/proxy.js +++ b/lib/middleware/proxy.js @@ -1,5 +1,6 @@ const url = require('url') -const http = require('http') +const { Agent: httpAgent } = require('http') +const { Agent: httpsAgent } = require('https') const httpProxy = require('http-proxy') const _ = require('lodash') @@ -43,7 +44,8 @@ function parseProxyConfig (proxies, config) { port = config.port } const changeOrigin = proxyConfiguration.changeOrigin || false - const keepAliveAgent = new http.Agent({ keepAlive: true }) + const Agent = https ? httpsAgent : httpAgent + const keepAliveAgent = new Agent({ keepAlive: true }) const proxy = httpProxy.createProxyServer({ target: { host: hostname, port, https, protocol }, xfwd: true, diff --git a/test/unit/middleware/proxy.spec.js b/test/unit/middleware/proxy.spec.js index 98f7055b4..6bfc2c80c 100644 --- a/test/unit/middleware/proxy.spec.js +++ b/test/unit/middleware/proxy.spec.js @@ -353,12 +353,23 @@ describe('middleware.proxy', () => { expect(m.parseProxyConfig({})).to.deep.equal([]) }) - it('should use agent with keepAlive=true', () => { + it('should use http agent with keepAlive=true', () => { const proxy = { '/base': 'http://localhost:8000/proxy' } const parsedProxyConfig = m.parseProxyConfig(proxy, {}) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0].proxy.options.agent).to.containSubset({ - keepAlive: true + keepAlive: true, + protocol: 'http:' + }) + }) + + it('should use https agent with keepAlive=true', () => { + const proxy = { '/base': 'https://localhost:8000/proxy' } + const parsedProxyConfig = m.parseProxyConfig(proxy, {}) + expect(parsedProxyConfig).to.have.length(1) + expect(parsedProxyConfig[0].proxy.options.agent).to.containSubset({ + keepAlive: true, + protocol: 'https:' }) }) }) From f25edeb0354993d38449e94403fcab8a5d8d69e2 Mon Sep 17 00:00:00 2001 From: Matthias Osswald Date: Mon, 25 May 2020 13:05:12 +0200 Subject: [PATCH 3/3] fix(proxy): destroy agents on exit --- lib/middleware/proxy.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/middleware/proxy.js b/lib/middleware/proxy.js index af7aa95a4..7c9a43214 100644 --- a/lib/middleware/proxy.js +++ b/lib/middleware/proxy.js @@ -45,13 +45,13 @@ function parseProxyConfig (proxies, config) { } const changeOrigin = proxyConfiguration.changeOrigin || false const Agent = https ? httpsAgent : httpAgent - const keepAliveAgent = new Agent({ keepAlive: true }) + const agent = new Agent({ keepAlive: true }) const proxy = httpProxy.createProxyServer({ target: { host: hostname, port, https, protocol }, xfwd: true, changeOrigin: changeOrigin, secure: config.proxyValidateSSL, - agent: keepAliveAgent + agent }) ;['proxyReq', 'proxyRes'].forEach(function (name) { @@ -71,7 +71,7 @@ function parseProxyConfig (proxies, config) { res.destroy() }) - return { path: proxyPath, baseUrl: pathname, host: hostname, port, https, proxy } + return { path: proxyPath, baseUrl: pathname, host: hostname, port, https, proxy, agent } }), 'path').reverse() } @@ -117,6 +117,14 @@ function createProxyHandler (proxies, urlRoot) { return createProxy } -exports.create = function (/* config */config, /* config.proxies */proxies) { - return createProxyHandler(parseProxyConfig(proxies, config), config.urlRoot) +exports.create = function (/* config */config, /* config.proxies */proxies, /* emitter */emitter) { + const proxyRecords = parseProxyConfig(proxies, config) + emitter.on('exit', (done) => { + log.debug('Destroying proxy agents') + proxyRecords.forEach((proxyRecord) => { + proxyRecord.agent.destroy() + }) + done() + }) + return createProxyHandler(proxyRecords, config.urlRoot) }