From 2721847c8ce9dcf8ead71148e282b8af323fde17 Mon Sep 17 00:00:00 2001 From: David Xia Date: Tue, 6 Jun 2023 19:49:55 -0400 Subject: [PATCH 1/6] test: enable keepAlive on proxy web server to see if it improves performance. Idea from https://github.com/http-party/node-http-proxy/issues/1058 [docs](https://nodejs.org/api/http.html#new-agentoptions) --- lib/configproxy.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/configproxy.js b/lib/configproxy.js index 619a8dfc..55a3eff1 100644 --- a/lib/configproxy.js +++ b/lib/configproxy.js @@ -219,12 +219,14 @@ class ConfigurableProxy extends EventEmitter { this.metricsServer = http.createServer(metricsCallback); } + var proxyOptions = {keepAlive: true}; + // proxy requests separately var proxyCallback = logErrors(this.handleProxyWeb); if (this.options.ssl) { - this.proxyServer = https.createServer(this.options.ssl, proxyCallback); + this.proxyServer = https.createServer({...this.options.ssl, ...proxyOptions}, proxyCallback); } else { - this.proxyServer = http.createServer(proxyCallback); + this.proxyServer = http.createServer(proxyOptions, proxyCallback); } // proxy websockets this.proxyServer.on("upgrade", bound(this, this.handleProxyWs)); From b460001f8489548eb571ed7dec0e521ff2cc06fd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 23:52:06 +0000 Subject: [PATCH 2/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- lib/configproxy.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/configproxy.js b/lib/configproxy.js index 55a3eff1..0938fbcb 100644 --- a/lib/configproxy.js +++ b/lib/configproxy.js @@ -219,12 +219,15 @@ class ConfigurableProxy extends EventEmitter { this.metricsServer = http.createServer(metricsCallback); } - var proxyOptions = {keepAlive: true}; + var proxyOptions = { keepAlive: true }; // proxy requests separately var proxyCallback = logErrors(this.handleProxyWeb); if (this.options.ssl) { - this.proxyServer = https.createServer({...this.options.ssl, ...proxyOptions}, proxyCallback); + this.proxyServer = https.createServer( + { ...this.options.ssl, ...proxyOptions }, + proxyCallback + ); } else { this.proxyServer = http.createServer(proxyOptions, proxyCallback); } From ebeb1ea145009f046a7ecf81d6e85fd30814689c Mon Sep 17 00:00:00 2001 From: Min RK Date: Thu, 17 Aug 2023 15:46:27 +0200 Subject: [PATCH 3/6] add keepAlive agent to proxy as well so we have keep-alive on both sides --- lib/configproxy.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/configproxy.js b/lib/configproxy.js index 0938fbcb..e4744f04 100644 --- a/lib/configproxy.js +++ b/lib/configproxy.js @@ -173,6 +173,7 @@ class ConfigurableProxy extends EventEmitter { }); } options.ws = true; + this.agent = options.agent = new http.Agent({ keepAlive: true }); var proxy = (this.proxy = httpProxy.createProxyServer(options)); // tornado-style regex routing, @@ -219,17 +220,14 @@ class ConfigurableProxy extends EventEmitter { this.metricsServer = http.createServer(metricsCallback); } - var proxyOptions = { keepAlive: true }; + var httpOptions = { keepAlive: true, agent: this.agent }; // proxy requests separately var proxyCallback = logErrors(this.handleProxyWeb); if (this.options.ssl) { - this.proxyServer = https.createServer( - { ...this.options.ssl, ...proxyOptions }, - proxyCallback - ); + this.proxyServer = https.createServer({ ...this.options.ssl, ...httpOptions }, proxyCallback); } else { - this.proxyServer = http.createServer(proxyOptions, proxyCallback); + this.proxyServer = http.createServer(httpOptions, proxyCallback); } // proxy websockets this.proxyServer.on("upgrade", bound(this, this.handleProxyWs)); From 6c6dddd03937371b305d63bf2fa9f01cf2e1de49 Mon Sep 17 00:00:00 2001 From: Min RK Date: Thu, 17 Aug 2023 15:56:32 +0200 Subject: [PATCH 4/6] expose keep-alive timeout on command-line --- bin/configurable-http-proxy | 6 ++++++ lib/configproxy.js | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/bin/configurable-http-proxy b/bin/configurable-http-proxy index f236ef76..fc8e80e1 100755 --- a/bin/configurable-http-proxy +++ b/bin/configurable-http-proxy @@ -103,6 +103,11 @@ cli .option( "--storage-backend ", "Define an external storage class. Defaults to in-MemoryStore." + ) + .option( + "--keep-alive-timeout ", + "Set timeout (in milliseconds) for Keep-Alive connections", + parseInt ); // collects multiple flags to an object @@ -269,6 +274,7 @@ options.redirectTo = args.redirectTo; options.headers = args.customHeader; options.timeout = args.timeout; options.proxyTimeout = args.proxyTimeout; +options.keepAliveTimeout = args.keepAliveTimeout; // metrics options options.enableMetrics = !!args.metricsPort; diff --git a/lib/configproxy.js b/lib/configproxy.js index e4744f04..4df4fc1c 100644 --- a/lib/configproxy.js +++ b/lib/configproxy.js @@ -220,7 +220,11 @@ class ConfigurableProxy extends EventEmitter { this.metricsServer = http.createServer(metricsCallback); } - var httpOptions = { keepAlive: true, agent: this.agent }; + var httpOptions = { + keepAlive: true, + agent: this.agent, + keepAliveTimeout: this.options.keepAliveTimeout || 5000, + }; // proxy requests separately var proxyCallback = logErrors(this.handleProxyWeb); From 2077bd099882aeb876b280130b72a33b1b5f348e Mon Sep 17 00:00:00 2001 From: Min RK Date: Fri, 18 Aug 2023 10:58:23 +0200 Subject: [PATCH 5/6] need separate agent for http/https --- lib/configproxy.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/configproxy.js b/lib/configproxy.js index 4df4fc1c..1b7dfa96 100644 --- a/lib/configproxy.js +++ b/lib/configproxy.js @@ -173,7 +173,6 @@ class ConfigurableProxy extends EventEmitter { }); } options.ws = true; - this.agent = options.agent = new http.Agent({ keepAlive: true }); var proxy = (this.proxy = httpProxy.createProxyServer(options)); // tornado-style regex routing, @@ -220,9 +219,14 @@ class ConfigurableProxy extends EventEmitter { this.metricsServer = http.createServer(metricsCallback); } + // need separate agents for http and https requests + // these agents allow our _upstream_ sockets to be kept alive + this.httpAgent = http.globalAgent = new http.Agent({ keepAlive: true }); + this.httpsAgent = https.globalAgent = new https.Agent({ keepAlive: true }); + + // these settings configure requests to the proxy itself to accept keep-alive var httpOptions = { keepAlive: true, - agent: this.agent, keepAliveTimeout: this.options.keepAliveTimeout || 5000, }; @@ -560,7 +564,13 @@ class ConfigurableProxy extends EventEmitter { } // add config argument - args.push({ target: target }); + var proxyOptions = { target: target }; + if (target.protocol.slice(-2) === "s:") { + proxyOptions.agent = that.httpsAgent; + } else { + proxyOptions.agent = that.httpAgent; + } + args.push(proxyOptions); // add error handling args.push(function (e) { From 18ffd6f68e2ca9c10ab3a9b76abd7a69c07ae5dc Mon Sep 17 00:00:00 2001 From: Min RK Date: Fri, 18 Aug 2023 10:59:27 +0200 Subject: [PATCH 6/6] test keep-alive headers --- test/proxy_spec.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/proxy_spec.js b/test/proxy_spec.js index 8827d006..46ae514d 100644 --- a/test/proxy_spec.js +++ b/test/proxy_spec.js @@ -1,6 +1,7 @@ // jshint jasmine: true "use strict"; +var http = require("http"); var path = require("path"); var util = require("../lib/testutil"); var request = require("request-promise-native"); @@ -86,6 +87,21 @@ describe("Proxy Tests", function () { }); }); + it("keep-alive proxy request", function (done) { + var agent = new http.Agent({ keepAlive: true }); + r(proxyUrl, { agent: agent, resolveWithFullResponse: true }).then((res) => { + agent.destroy(); + var body = JSON.parse(res.body); + expect(body).toEqual( + jasmine.objectContaining({ + path: "/", + }) + ); + expect(res.headers["connection"]).toEqual("keep-alive"); + done(); + }); + }); + it("proxyRequest event can modify headers", function (done) { var called = {}; proxy.on("proxyRequest", function (req, res) {