Skip to content

Commit 36a6940

Browse files
committed
Support connecting to unix sockets
1 parent 1a6d3c6 commit 36a6940

File tree

3 files changed

+62
-28
lines changed

3 files changed

+62
-28
lines changed

lib/configproxy.js

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,34 @@ export class ConfigurableProxy extends EventEmitter {
388388
});
389389
}
390390

391+
proxyOptsForTarget(target, reqUrl) {
392+
var proxyOptions = { target };
393+
394+
if (target.protocol.startsWith("unix")) {
395+
proxyOptions.secure = false;
396+
proxyOptions.target.socketPath = decodeURIComponent(target.host);
397+
proxyOptions.target.pathname = (target.pathname ? target.pathname + "/" : "") + reqUrl;
398+
} else {
399+
// No need for agents for unix sockets
400+
// No support for https for unix sockets
401+
proxyOptions.secure = target.protocol.slice(-2) === "s:";
402+
403+
if (proxyOptions.secure) {
404+
proxyOptions.agent = this.httpsAgent;
405+
} else {
406+
proxyOptions.agent = this.httpAgent;
407+
}
408+
}
409+
410+
if (proxyOptions.secure && this.options.clientSsl) {
411+
proxyOptions.target.key = this.options.clientSsl.key;
412+
proxyOptions.target.cert = this.options.clientSsl.cert;
413+
proxyOptions.target.ca = this.options.clientSsl.ca;
414+
}
415+
416+
return proxyOptions;
417+
}
418+
391419
async targetForReq(req) {
392420
var metricsTimerEnd = this.metrics.findTargetForReqSummary.startTimer();
393421
// return proxy target for a given url path
@@ -463,23 +491,13 @@ export class ConfigurableProxy extends EventEmitter {
463491
// error request is $errorTarget/$code?url=$requestUrl
464492
urlSpec.searchParams.set("url", req.url);
465493
urlSpec.pathname = urlSpec.pathname + code.toString();
466-
var secure = /https/gi.test(urlSpec.protocol) ? true : false;
467494
var url = urlSpec.toString();
468495
this.log.debug("Requesting custom error page: %s", url);
469496

470-
// construct request options
471-
var options = {
472-
method: "GET",
473-
};
474-
475-
// add client SSL config if error target is using https
476-
if (secure && this.options.clientSsl) {
477-
options.key = this.options.clientSsl.key;
478-
options.cert = this.options.clientSsl.cert;
479-
options.ca = this.options.clientSsl.ca;
480-
}
497+
var options = this.proxyOptsForTarget(urlSpec, req.url);
498+
options.method = "GET";
481499

482-
var errorRequest = (secure ? https : http).request(url, options, function (upstream) {
500+
var errorRequest = (options.secure ? https : http).request(url, options, function (upstream) {
483501
if (res.writableEnded) return; // response already done
484502
["content-type", "content-encoding"].map(function (key) {
485503
if (!upstream.headers[key]) return;
@@ -557,19 +575,8 @@ export class ConfigurableProxy extends EventEmitter {
557575
}
558576

559577
target = new URL(target);
560-
var proxyOptions = { target };
561-
if (that.options.clientSsl) {
562-
target.key = that.options.clientSsl.key;
563-
target.cert = that.options.clientSsl.cert;
564-
target.ca = that.options.clientSsl.ca;
565-
}
578+
var proxyOptions = this.proxyOptsForTarget(target, req.url);
566579

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

575582
// add error handling

lib/testutil.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,22 @@ import { defaultLogger } from "./log.js";
99
var servers = [];
1010

1111
// TODO: make this an options dict
12-
export function addTarget(proxy, path, port, websocket, targetPath, sslOptions) {
12+
export function addTarget(proxy, path, port, websocket, targetPath, sslOptions, unixSocketPath) {
1313
var proto = sslOptions ? "https" : "http";
14-
var target = proto + "://127.0.0.1:" + port;
14+
var listenTarget;
15+
var target;
16+
17+
if (unixSocketPath) {
18+
listenTarget = decodeURIComponent(unixSocketPath);
19+
target = "unix+" + proto + "://" + unixSocketPath;
20+
} else {
21+
target = proto + "://" + "127.0.0.1:" + port;
22+
listenTarget = port;
23+
}
1524
if (targetPath) {
1625
target = target + targetPath;
1726
}
27+
1828
var server;
1929
var data = {
2030
target: target,
@@ -48,7 +58,7 @@ export function addTarget(proxy, path, port, websocket, targetPath, sslOptions)
4858
});
4959
}
5060

51-
server.listen(port);
61+
server.listen(listenTarget);
5262
servers.push(server);
5363
return proxy.addRoute(path, { target: target }).then(() => {
5464
// routes are created with an activity timestamp artificially shifted into the past

test/proxy_spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,4 +512,21 @@ describe("Proxy Tests", function () {
512512
})
513513
.then(done);
514514
});
515+
516+
it("proxy to unix socket test", function (done) {
517+
var proxyPort = 55557;
518+
var unixSocketUri = "%2Ftmp%2Ftest.sock";
519+
520+
util
521+
.setupProxy(proxyPort, {}, [])
522+
.then((proxy) => util.addTarget(proxy, "/unix", 0, false, null, null, unixSocketUri))
523+
.then(() => fetch("http://127.0.0.1:" + proxyPort + "/unix"))
524+
.then((res) => {
525+
expect(res.status).toEqual(200);
526+
})
527+
.catch((err) => {
528+
done.fail(err);
529+
})
530+
.then(done);
531+
});
515532
});

0 commit comments

Comments
 (0)