Skip to content

Commit d41cedc

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

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: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,20 @@ 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+
15+
if (unixSocketPath) {
16+
var listenTarget = decodeURIComponent(unixSocketPath);
17+
var target = "unix+" + proto + "://" + unixSocketPath;
18+
} else {
19+
var target = proto + "://" + "127.0.0.1:" + port;
20+
var listenTarget = port;
21+
}
1522
if (targetPath) {
1623
target = target + targetPath;
1724
}
25+
1826
var server;
1927
var data = {
2028
target: target,
@@ -48,7 +56,7 @@ export function addTarget(proxy, path, port, websocket, targetPath, sslOptions)
4856
});
4957
}
5058

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

test/proxy_spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,4 +512,23 @@ 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) =>
523+
util.addTarget(proxy, "/unix", 0, false, null, null, unixSocketUri)
524+
)
525+
.then(() => fetch("http://127.0.0.1:" + proxyPort + '/unix'))
526+
.then((res) => {
527+
expect(res.status).toEqual(200);
528+
})
529+
.catch((err) => {
530+
done.fail(err);
531+
})
532+
.then(done);
533+
});
515534
});

0 commit comments

Comments
 (0)