diff --git a/lib/configproxy.js b/lib/configproxy.js index 98663786..0018cd82 100644 --- a/lib/configproxy.js +++ b/lib/configproxy.js @@ -388,7 +388,7 @@ export class ConfigurableProxy extends EventEmitter { }); } - proxyOptsForTarget(target, reqUrl) { + proxyOptsForTarget(target) { var proxyOptions = { target }; if (target.protocol.startsWith("unix")) { @@ -396,7 +396,6 @@ export class ConfigurableProxy extends EventEmitter { // No support for https for unix sockets proxyOptions.secure = false; proxyOptions.target.socketPath = decodeURIComponent(target.host); - proxyOptions.target.pathname = (target.pathname ? target.pathname + "/" : "") + reqUrl; } else if (target.protocol.startsWith("https")) { proxyOptions.secure = true; proxyOptions.agent = this.httpsAgent; @@ -495,35 +494,47 @@ export class ConfigurableProxy extends EventEmitter { return; } if (this.errorTarget) { - var urlSpec = new URL(this.errorTarget); // error request is $errorTarget/$code?url=$requestUrl - urlSpec.searchParams.set("url", req.url); - urlSpec.pathname = urlSpec.pathname + code.toString(); - var url = urlSpec.toString(); - this.log.debug("Requesting custom error page: %s", url); + var options = this.proxyOptsForTarget(new URL(this.errorTarget)); - var options = this.proxyOptsForTarget(urlSpec, req.url); options.method = "GET"; - var errorRequest = (options.secure ? https : http).request(url, options, (upstream) => { - if (res.writableEnded) { - // response already done - // make sure to consume upstream; - upstream.resume(); - return; + options.target.searchParams.set("url", req.url); + options.target.pathname = options.target.pathname + code.toString(); + + var url = ""; + if (options.target.socketPath) { + options.target.hostname = "localhost"; + url = options.target.toString().substring(5); // chop off unix+ + } else { + url = options.target.toString(); + } + + this.log.debug("Requesting custom error page: %s", url); + + var errorRequest = (options.secure ? https : http).request( + url, + options.target, + (upstream) => { + if (res.writableEnded) { + // response already done + // make sure to consume upstream; + upstream.resume(); + return; + } + ["content-type", "content-encoding"].map((key) => { + if (!upstream.headers[key]) return; + if (res.setHeader) res.setHeader(key, upstream.headers[key]); + }); + if (res.writeHead) res.writeHead(code); + upstream.on("data", (data) => { + if (res.write && !res.writableEnded) res.write(data); + }); + upstream.on("end", () => { + if (res.end) res.end(); + }); } - ["content-type", "content-encoding"].map((key) => { - if (!upstream.headers[key]) return; - if (res.setHeader) res.setHeader(key, upstream.headers[key]); - }); - if (res.writeHead) res.writeHead(code); - upstream.on("data", (data) => { - if (res.write && !res.writableEnded) res.write(data); - }); - upstream.on("end", () => { - if (res.end) res.end(); - }); - }); + ); errorRequest.on("error", (e) => { // custom error failed, fallback on default this.log.error("Failed to get custom error page: %s", e); @@ -588,7 +599,7 @@ export class ConfigurableProxy extends EventEmitter { } target = new URL(target); - var proxyOptions = this.proxyOptsForTarget(target, req.url); + var proxyOptions = this.proxyOptsForTarget(target); args.push(proxyOptions); diff --git a/lib/testutil.js b/lib/testutil.js index 088e6dbe..df6446a0 100644 --- a/lib/testutil.js +++ b/lib/testutil.js @@ -4,7 +4,7 @@ import http from "node:http"; import https from "node:https"; import { WebSocketServer } from "ws"; import { ConfigurableProxy } from "./configproxy.js"; -import { defaultLogger } from "./log.js"; +import { defaultLogger } from "../lib/log.js"; var servers = []; @@ -133,7 +133,12 @@ export function setupProxy(port, options, paths) { }); errorServer.on("listening", onlisten); const errorUrl = new URL(options.errorTarget); - errorServer.listen(errorUrl.port, ip); + if (errorUrl.href.startsWith("unix+")) { + console.log(decodeURIComponent(errorUrl.hostname)); + errorServer.listen(decodeURIComponent(errorUrl.hostname)); + } else { + errorServer.listen(errorUrl.port, ip); + } servers.push(errorServer); } diff --git a/test/proxy_spec.js b/test/proxy_spec.js index 3246bd6a..b1842d50 100644 --- a/test/proxy_spec.js +++ b/test/proxy_spec.js @@ -513,6 +513,22 @@ describe("Proxy Tests", function () { .then(done); }); + it("custom error target with unix socket", function (done) { + var proxyPort = 55550; + util + .setupProxy(proxyPort, { errorTarget: "unix+http://%2Ftmp%2Ftest.sock" }, []) + .then(() => fetch("http://127.0.0.1:" + proxyPort + "/foo/bar")) + .then((res) => { + expect(res.status).toEqual(404); + expect(res.headers.get("content-type")).toEqual("text/plain"); + return res.text(); + }) + .then((body) => { + expect(body).toEqual("/foo/bar"); + }) + .then(done); + }); + it("proxy to unix socket test", function (done) { var proxyPort = 55557; var unixSocketUri = "%2Ftmp%2Ftest.sock"; @@ -520,7 +536,7 @@ describe("Proxy Tests", function () { util .setupProxy(proxyPort, {}, []) .then((proxy) => util.addTarget(proxy, "/unix", 0, false, null, null, unixSocketUri)) - .then(() => fetch("http://127.0.0.1:" + proxyPort + "/unix")) + .then(() => fetch("http://127.0.0.1:" + proxyPort + "/unix/foo")) .then((res) => { expect(res.status).toEqual(200); })