Skip to content

Commit 094ff57

Browse files
authored
Merge pull request #492 from minrk/keep-alive
Enable keep-alive, `--keep-alive-timeout` flag added (default: 5000ms)
2 parents 712aeca + 18ffd6f commit 094ff57

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

bin/configurable-http-proxy

+6
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ cli
103103
.option(
104104
"--storage-backend <storage-class>",
105105
"Define an external storage class. Defaults to in-MemoryStore."
106+
)
107+
.option(
108+
"--keep-alive-timeout <timeout>",
109+
"Set timeout (in milliseconds) for Keep-Alive connections",
110+
parseInt
106111
);
107112

108113
// collects multiple flags to an object
@@ -269,6 +274,7 @@ options.redirectTo = args.redirectTo;
269274
options.headers = args.customHeader;
270275
options.timeout = args.timeout;
271276
options.proxyTimeout = args.proxyTimeout;
277+
options.keepAliveTimeout = args.keepAliveTimeout;
272278

273279
// metrics options
274280
options.enableMetrics = !!args.metricsPort;

lib/configproxy.js

+20-3
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,23 @@ class ConfigurableProxy extends EventEmitter {
219219
this.metricsServer = http.createServer(metricsCallback);
220220
}
221221

222+
// need separate agents for http and https requests
223+
// these agents allow our _upstream_ sockets to be kept alive
224+
this.httpAgent = http.globalAgent = new http.Agent({ keepAlive: true });
225+
this.httpsAgent = https.globalAgent = new https.Agent({ keepAlive: true });
226+
227+
// these settings configure requests to the proxy itself to accept keep-alive
228+
var httpOptions = {
229+
keepAlive: true,
230+
keepAliveTimeout: this.options.keepAliveTimeout || 5000,
231+
};
232+
222233
// proxy requests separately
223234
var proxyCallback = logErrors(this.handleProxyWeb);
224235
if (this.options.ssl) {
225-
this.proxyServer = https.createServer(this.options.ssl, proxyCallback);
236+
this.proxyServer = https.createServer({ ...this.options.ssl, ...httpOptions }, proxyCallback);
226237
} else {
227-
this.proxyServer = http.createServer(proxyCallback);
238+
this.proxyServer = http.createServer(httpOptions, proxyCallback);
228239
}
229240
// proxy websockets
230241
this.proxyServer.on("upgrade", bound(this, this.handleProxyWs));
@@ -553,7 +564,13 @@ class ConfigurableProxy extends EventEmitter {
553564
}
554565

555566
// add config argument
556-
args.push({ target: target });
567+
var proxyOptions = { target: target };
568+
if (target.protocol.slice(-2) === "s:") {
569+
proxyOptions.agent = that.httpsAgent;
570+
} else {
571+
proxyOptions.agent = that.httpAgent;
572+
}
573+
args.push(proxyOptions);
557574

558575
// add error handling
559576
args.push(function (e) {

test/proxy_spec.js

+16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// jshint jasmine: true
22
"use strict";
33

4+
var http = require("http");
45
var path = require("path");
56
var util = require("../lib/testutil");
67
var request = require("request-promise-native");
@@ -86,6 +87,21 @@ describe("Proxy Tests", function () {
8687
});
8788
});
8889

90+
it("keep-alive proxy request", function (done) {
91+
var agent = new http.Agent({ keepAlive: true });
92+
r(proxyUrl, { agent: agent, resolveWithFullResponse: true }).then((res) => {
93+
agent.destroy();
94+
var body = JSON.parse(res.body);
95+
expect(body).toEqual(
96+
jasmine.objectContaining({
97+
path: "/",
98+
})
99+
);
100+
expect(res.headers["connection"]).toEqual("keep-alive");
101+
done();
102+
});
103+
});
104+
89105
it("proxyRequest event can modify headers", function (done) {
90106
var called = {};
91107
proxy.on("proxyRequest", function (req, res) {

0 commit comments

Comments
 (0)