diff --git a/index.js b/index.js index 998e89c..25a7980 100644 --- a/index.js +++ b/index.js @@ -35,6 +35,19 @@ try { } var disableModExposeSupported = process.versions.svrjs && process.versions.svrjs.match(/^(?:Nightly-|(?:[4-9]|[123][0-9])[0-9]*\.|3\.(?:[1-9][0-9]+\.|9\.(?:[1-9])|4\.(?:(?:[3-9]|[12][0-9])[0-9]+|29)))/i); +var normalizedWebrootSupported = process.versions.svrjs && process.versions.svrjs.match(/^(?:Nightly-|(?:[5-9]|[1234][0-9])[0-9]*\.|4\.(?:(?:[1][0-9]|[2-9])+\.))/i); + +function normalizeWebroot(currentWebroot) { + if (currentWebroot === undefined) { + return process.cwd(); + } else if (!path.isAbsolute(currentWebroot)) { + return ( + process.cwd() + (os.platform() == "win32" ? "\\" : "/") + currentWebroot + ); + } else { + return currentWebroot; + } +} function Mod() {} @@ -44,6 +57,8 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e configJSON = configJSONS; } + var detectedWwwroot = normalizedWebrootSupported ? normalizeWebroot(configJSON.wwwroot) : process.cwd(); + function checkIfThereIsA401Rule() { var actually401 = false; @@ -177,15 +192,15 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e var cned = false; args.push(fname); if (passedArgs == "binary") { - filename = (process.cwd() + (os.platform() == "win32" ? "\\" + fname.replace(/\//g, "\\") : "/" + fname)).replace(os.platform() == "win32" ? /\\+/ : /\/+/, os.platform() == "win32" ? "\\" : "/"); + filename = (detectedWwwroot + (os.platform() == "win32" ? "\\" + fname.replace(/\//g, "\\") : "/" + fname)).replace(os.platform() == "win32" ? /\\+/ : /\/+/, os.platform() == "win32" ? "\\" : "/"); args = []; } else if (passedArgs) { if (os.platform() == "win32") { args = passedArgs; - args.push((process.cwd() + ("\\" + fname.replace(/\//g, "\\"))).replace(/\\+/, "\\")); + args.push((detectedWwwroot + ("\\" + fname.replace(/\//g, "\\"))).replace(/\\+/, "\\")); filename = args.shift(); } else { - filename = (process.cwd() + (os.platform() == "win32" ? "\\" + fname.replace(/\//g, "\\") : "/" + fname)).replace(os.platform() == "win32" ? /\\+/ : /\/+/, os.platform() == "win32" ? "\\" : "/"); + filename = (detectedWwwroot + (os.platform() == "win32" ? "\\" + fname.replace(/\//g, "\\") : "/" + fname)).replace(os.platform() == "win32" ? /\\+/ : /\/+/, os.platform() == "win32" ? "\\" : "/"); args = []; } } else { @@ -200,16 +215,15 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e return; } } - args.push((process.cwd() + (os.platform() == "win32" ? "\\" + fname.replace(/\//g, "\\") : "/" + fname)).replace(os.platform() == "win32" ? /\\+/ : /\/+/, os.platform() == "win32" ? "\\" : "/")); + args.push((detectedWwwroot + (os.platform() == "win32" ? "\\" + fname.replace(/\//g, "\\") : "/" + fname)).replace(os.platform() == "win32" ? /\\+/ : /\/+/, os.platform() == "win32" ? "\\" : "/")); filename = args.shift(); } var wd = fname.split("/"); - wd[0] = ""; wd[wd.length - 1] = ""; wd = wd.join(os.platform() == "win32" ? "\\" : "/"); var interpreter = childProcess.spawn(filename, args, { - cwd: (process.cwd() + wd).replace(os.platform() == "win32" ? /\\+/ : /\/+/, os.platform() == "win32" ? "\\" : "/"), + cwd: wd.replace(os.platform() == "win32" ? /\\+/ : /\/+/, os.platform() == "win32" ? "\\" : "/"), env: env }); interpreter.on("error", (error) => { @@ -373,9 +387,9 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e nEnv["SERVER_ADMIN"] = configJSON.serverAdministratorEmail; } nEnv["SERVER_NAME"] = req.headers.host; - nEnv["DOCUMENT_ROOT"] = process.cwd(); + nEnv["DOCUMENT_ROOT"] = detectedWwwroot; nEnv["PATH_INFO"] = decodeURIComponent(b); - nEnv["PATH_TRANSLATED"] = b ? ((process.cwd() + decodeURIComponent(require("os").platform == "win32" ? b.replace(/\//g, "\\") : b)).replace((require("os").platform == "win32" ? /\\\\/g : /\/\//g), (require("os").platform == "win32" ? "\\" : "/"))) : ""; + nEnv["PATH_TRANSLATED"] = b ? ((detectedWwwroot + decodeURIComponent(require("os").platform == "win32" ? b.replace(/\//g, "\\") : b)).replace((require("os").platform == "win32" ? /\\\\/g : /\/\//g), (require("os").platform == "win32" ? "\\" : "/"))) : ""; nEnv["REQUEST_METHOD"] = req.method; nEnv["GATEWAY_INTERFACE"] = "CGI/1.1"; nEnv["REQUEST_URI"] = (!origHref || origHref == href) ? req.url : (origHref + (uobject.search ? ((uobject.search[0] == "?" ? "" : "?") + uobject.search) : "")); @@ -386,7 +400,7 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e nEnv["REMOTE_PORT"] = req.socket.remotePort; } nEnv["SCRIPT_NAME"] = a; - nEnv["SCRIPT_FILENAME"] = (process.cwd() + (require("os").platform == "win32" ? a.replace(/\//g, "\\") : a)).replace((require("os").platform == "win32" ? /\\\\/g : /\/\//g), (require("os").platform == "win32" ? "\\" : "/")); + nEnv["SCRIPT_FILENAME"] = (detectedWwwroot + (require("os").platform == "win32" ? a.replace(/\//g, "\\") : a)).replace((require("os").platform == "win32" ? /\\\\/g : /\/\//g), (require("os").platform == "win32" ? "\\" : "/")); if (req.socket.encrypted) nEnv["HTTPS"] = "ON"; if (req.headers["content-type"]) nEnv["CONTENT_TYPE"] = req.headers["content-type"]; if (req.headers["content-length"]) nEnv["CONTENT_LENGTH"] = req.headers["content-length"]; @@ -397,13 +411,13 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e for (var i = 0; i < nhKeys.length; i++) { nEnv["HTTP_" + nhKeys[i].replace(/[^0-9A-Za-z]+/g, "_").toUpperCase()] = req.headers[nhKeys[i]]; } - executeCGI("." + a, req, res, dh, nEnv); + executeCGI(detectedWwwroot + a, req, res, dh, nEnv); } var isCgiBin = href.match(new RegExp("^/cgi-bin(?:$|[?#/])", os.platform() == "win32" ? "i" : "")); var isScriptExt = scriptExts.indexOf("." + ext) != -1; - if ((href == "/redbrick-interpreters.json" || href == "/redbrick-scriptexts.json" || (os.platform() == "win32" && (href.toLowerCase() == "/redbrick-interpreters.json" || href.toLowerCase() == "/redbrick-scriptexts.json"))) && path.normalize(__dirname + "/../../..") == process.cwd()) { + if ((href == "/redbrick-interpreters.json" || href == "/redbrick-scriptexts.json" || (os.platform() == "win32" && (href.toLowerCase() == "/redbrick-interpreters.json" || href.toLowerCase() == "/redbrick-scriptexts.json"))) && path.normalize(__dirname + "/../../..") == detectedWwwroot) { if (!callServerError) { res.writeHead(403, "Forbidden", { "Content-Type": "text/html", @@ -428,11 +442,11 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e callServerError(403, "RedBrick/" + version); } } else { - fs.stat("." + decodeURIComponent(href), function (err, stats) { + fs.stat(detectedWwwroot + decodeURIComponent(href), function (err, stats) { if (!err) { if (!stats.isFile()) { if (isCgiBin || scriptExts.indexOf(".php") != -1) { - fs.stat("." + decodeURIComponent(href) + "/index.php", function (e2, s2) { + fs.stat(detectedWwwroot + decodeURIComponent(href) + "/index.php", function (e2, s2) { if (!e2 && s2.isFile()) { try { executeCGIWithEnv( @@ -484,7 +498,7 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e } } } else if (isCgiBin || scriptExts.indexOf(".cgi") != -1) { - fs.stat("." + decodeURIComponent(href) + "/index.cgi", function (e3, s3) { + fs.stat(detectedWwwroot + decodeURIComponent(href) + "/index.cgi", function (e3, s3) { if (!e3 && s3.isFile()) { try { executeCGIWithEnv( @@ -544,7 +558,7 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e } }); } else if (scriptExts.indexOf(".cgi") != -1) { - fs.stat("." + decodeURIComponent(href) + "/index.cgi", function (e3, s3) { + fs.stat(detectedWwwroot + decodeURIComponent(href) + "/index.cgi", function (e3, s3) { if (!e3 && s3.isFile()) { try { executeCGIWithEnv( @@ -668,7 +682,7 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e if (!a) b = []; else var b = a.split("/"); var isFile = false; - fs.stat(pth, function (err, stats) { + fs.stat(detectedWwwroot + "/" + pth, function (err, stats) { if (!err && stats.isFile()) { cb({ fpth: pth,