fix: fix a syntax error in the beginning of the source
[reverse-proxy-mod.git] / index.js
blob40f85c70eafdc0e753ea40f867350eceea363b17
1 var fs = require("fs");
2 var os = require("os");
3 var http = require("http");
4 var https = require("https");
5 var net = require("net");
6 var tls = require("tls");
8 var proxyConfig = {};
9 if (fs.existsSync(__dirname + "/../../../reverse-proxy-config.json")) proxyConfig = JSON.parse(fs.readFileSync(__dirname + "/../../../reverse-proxy-config.json").toString());
10 else fs.writeFileSync(__dirname + "/../../../reverse-proxy-config.json", "{}");
12 function Mod() {}
13 Mod.prototype.callback = function callback(req, res, serverconsole, responseEnd, href, ext, uobject, search, defaultpage, users, page404, head, foot, fd, elseCallback, configJSON, callServerError, getCustomHeaders, origHref, redirect, parsePostData) {
14 return function () {
15 var hostnames = Object.keys(proxyConfig);
16 var isPath = false;
17 var matchingHostname = null;
18 for (var i = 0; i < hostnames.length; i++) {
19 if (hostnames[i] == "*") {
20 matchingHostname = "*";
21 break;
22 } else if (hostnames[i][0] == "/" && (href == hostnames[i] || href.indexOf(hostnames[i] + "/") == 0)) {
23 matchingHostname = hostnames[i];
24 isPath = true;
25 break;
26 } else if (req.headers.host && hostnames[i].indexOf("*.") == 0 && hostnames[i] != "*.") {
27 var hostnamesRoot = hostnames[i].substr(2);
28 if (req.headers.host == hostnamesRoot || (req.headers.host.length > hostnamesRoot.length && req.headers.host.indexOf("." + hostnamesRoot) == req.headers.host.length - hostnamesRoot.length - 1)) {
29 matchingHostname = hostnames[i];
30 break;
32 } else if (req.headers.host && req.headers.host == hostnames[i]) {
33 matchingHostname = hostnames[i];
34 break;
37 if (matchingHostname) {
38 var hostname = proxyConfig[matchingHostname].hostname;
39 var port = proxyConfig[matchingHostname].port;
40 var secureHostname = proxyConfig[matchingHostname].secureHostname;
41 var securePort = proxyConfig[matchingHostname].securePort;
42 var removeCustomHeaders = proxyConfig[matchingHostname].removeCustomHeaders;
43 if (!port) port = 80;
44 if (!securePort && secureHostname) securePort = 443;
45 if (!hostname) {
46 callServerError(500, "reverse-proxy-mod/1.1.5", new Error("Proxy server is misconfigured. Hostname property is missing."));
47 return;
49 if (removeCustomHeaders === undefined || removeCustomHeaders) {
50 try {
51 var x = res.getHeaderNames();
52 for (var i = 0; i < x.length; i++) {
53 res.removeHeader(x[i]);
55 } catch (ex) {}
57 var preparedPath = req.url;
58 if(isPath) {
59 if(preparedPath == matchingHostname) {
60 preparedPath = "/";
61 } else {
62 preparedPath = preparedPath.replace(matchingHostname.substring(1) + "/","");
63 if(preparedPath == "") preparedPath = "/";
66 var hdrs = JSON.parse(JSON.stringify(req.headers));
67 hdrs["x-forwarded-for"] = req.socket.remoteAddress;
68 hdrs["x-forwarded-proto"] = req.socket.encrypted ? "https" : "http";
69 hdrs["x-svr-js-client"] = req.socket.remoteAddress + ":" + req.socket.remotePort;
70 delete hdrs[":method"];
71 delete hdrs[":scheme"];
72 delete hdrs[":authority"];
73 delete hdrs[":path"];
74 delete hdrs["keep-alive"];
75 if ((req.httpVersion == "1.1" || req.httpVersion == "1.0") && String(hdrs["connection"]).toLowerCase() == "upgrade") {
76 var socket = ((secureHostname && req.socket.encrypted) ? tls : net).createConnection({
77 host: (secureHostname && req.socket.encrypted) ? secureHostname : hostname,
78 port: (secureHostname && req.socket.encrypted) ? securePort : port,
79 joinDuplicateHeaders: true,
80 rejectUnauthorized: false
81 }, function () {
82 serverconsole.resmessage("Connected to back-end!");
83 socket.pipe(res.socket);
84 socket.write(req.method + " " + preparedPath + " HTTP/1.1\r\n");
85 Object.keys(hdrs).forEach(function (headerName) {
86 var header = hdrs[headerName];
87 if (typeof header === "object") {
88 header.forEach(function (value) {
89 socket.write(headerName + ": " + value + "\r\n");
90 });
91 } else {
92 socket.write(headerName + ": " + header + "\r\n");
94 });
95 socket.write("\r\n");
96 req.socket.pipe(socket);
97 }).on("error", (ex) => {
98 try {
99 if (ex.code == "ENOTFOUND" || ex.code == "EHOSTUNREACH" || ex.code == "ECONNREFUSED") {
100 callServerError(503, "reverse-proxy-mod/1.1.5", ex); //Server error
101 } else if (ex.code == "ETIMEDOUT") {
102 callServerError(504, "reverse-proxy-mod/1.1.5", ex); //Server error
103 } else {
104 callServerError(502, "reverse-proxy-mod/1.1.5", ex); //Server error
106 } catch (ex) {}
107 serverconsole.errmessage("Client fails to recieve content."); //Log into SVR.JS
109 } else {
110 if (String(hdrs["connection"]).toLowerCase() != "upgrade") hdrs["connection"] = "close";
111 var options = {
112 hostname: (secureHostname && req.socket.encrypted) ? secureHostname : hostname,
113 port: (secureHostname && req.socket.encrypted) ? securePort : port,
114 path: preparedPath,
115 method: req.method,
116 headers: hdrs,
117 joinDuplicateHeaders: true,
118 rejectUnauthorized: false
120 var proxy = ((secureHostname && req.socket.encrypted) ? https : http).request(options, function (sres) {
121 serverconsole.resmessage("Connected to back-end!");
122 if (String(hdrs["connection"]).toLowerCase() != "upgrade") {
123 delete sres.headers["connection"];
124 delete sres.headers["Connection"];
126 delete sres.headers["transfer-encoding"];
127 delete sres.headers["Transfer-Encoding"];
128 delete sres.headers["keep-alive"];
129 delete sres.headers["Keep-Alive"];
130 try {
131 res.writeHead(sres.statusCode, sres.headers);
132 sres.pipe(res);
133 res.prependListener("end", function () {
134 try {
135 sres.end();
136 } catch (ex) {}
138 } catch (ex) {
139 callServerError(502, "reverse-proxy-mod/1.1.5", ex); //Server error
142 proxy.on("error", function (ex) {
143 try {
144 if (ex.code == "ENOTFOUND" || ex.code == "EHOSTUNREACH" || ex.code == "ECONNREFUSED") {
145 callServerError(503, "reverse-proxy-mod/1.1.5", ex); //Server error
146 } else if (ex.code == "ETIMEDOUT") {
147 callServerError(504, "reverse-proxy-mod/1.1.5", ex); //Server error
148 } else {
149 callServerError(502, "reverse-proxy-mod/1.1.5", ex); //Server error
151 } catch (ex) {}
152 serverconsole.errmessage("Client fails to recieve content."); //Log into SVR.JS
154 req.pipe(proxy);
155 req.prependListener("end", function () {
156 try {
157 proxy.end();
158 } catch (ex) {}
161 } else if ((href == "/reverse-proxy-config.json" || (os.platform() == "win32" && href.toLowerCase() == "/reverse-proxy-config.json")) && path.normalize(__dirname + "/../../..") == process.cwd()) {
162 callServerError(403, "reverse-proxy-mod/1.1.5");
163 } else {
164 elseCallback();
169 module.exports = Mod;