Initial commit
This commit is contained in:
commit
7cebf8d001
3 changed files with 309 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
commit.sh
|
304
index.js
Normal file
304
index.js
Normal file
|
@ -0,0 +1,304 @@
|
|||
var https = require("https");
|
||||
var os = require("os");
|
||||
var http = require("http");
|
||||
var url = require("url");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var {
|
||||
spawn
|
||||
} = require("child_process");
|
||||
var version = "UNKNOWN";
|
||||
try {
|
||||
version = JSON.parse(fs.readFileSync(__dirname + "/mod.info")).version;
|
||||
} catch(ex) {
|
||||
//Can"t determine version
|
||||
}
|
||||
var configJSONS = JSON.parse(fs.readFileSync("config.json")); //Read configuration JSON
|
||||
function Mod() {}
|
||||
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) {
|
||||
return function () {
|
||||
if (!configJSON) configJSON = configJSONS;
|
||||
if (!getCustomHeaders) {
|
||||
var bheaders = JSON.parse(JSON.stringify(configJSON.customHeaders));
|
||||
} else {
|
||||
var bheaders = getCustomHeaders();
|
||||
}
|
||||
bheaders["Content-Type"] = "text/html" //HTML output
|
||||
if (!getCustomHeaders) bheaders["Server"] = "SVR.JS/" + configJSON.version + " (" + os.platform()[0].toUpperCase() + os.platform().slice(1) + ")"; //Add Server header
|
||||
function executeCGI(fname, req, res, dh, nEnv) {
|
||||
var env = JSON.parse(JSON.stringify(process.env));
|
||||
var nEnvKeys = Object.keys(nEnv);
|
||||
for(var i=0;i<nEnvKeys.length;i++) {
|
||||
env[nEnvKeys[i]] = nEnv[nEnvKeys[i]];
|
||||
}
|
||||
var exttointerpreter = {
|
||||
".pl": ["perl"],
|
||||
".py": ["python"],
|
||||
".sh": ["bash"],
|
||||
".ksh": ["ksh"],
|
||||
".csh": ["csh"],
|
||||
".bat": ["cmd", "/c"],
|
||||
".cmd": ["cmd", "/c"],
|
||||
".vbs": ["cscript"],
|
||||
".jar": ["java"],
|
||||
".pyw": ["python"],
|
||||
".rb": ["ruby"],
|
||||
".php": ["php-cgi"]
|
||||
}
|
||||
var exttointerpreteruser = {};
|
||||
try {
|
||||
exttointerpreteruser = JSON.parse(fs.readFileSync(__dirname + "/redbrick-interpreters.json"));
|
||||
} catch(ex) {}
|
||||
var script = fs.readFileSync(fname).toString();
|
||||
var fl = script.replace(/[\r\n]+/g, "\n").split("\n")[0];
|
||||
if (fl[0] == undefined) fl[0] = "";
|
||||
var ext = path.extname(fname);
|
||||
var args = [];
|
||||
var buffer = "";
|
||||
var stderr = "";
|
||||
var headerendline = -1;
|
||||
var cned = false;
|
||||
var tempID = "redbrick" + Math.round(Math.random() * 1000000).toString(16) + ext;
|
||||
args.push(fname);
|
||||
if (fl.indexOf("#!") == 0) {
|
||||
if (os.platform() == "win32") {
|
||||
args = fl.substr(2).split(" ");
|
||||
var lns = script.split("\n");
|
||||
if (lns.length < 2) lns = script.split("\r");
|
||||
if (lns.length > 1) lns.shift();
|
||||
fs.writeFileSync(__dirname + "/../../../temp/" + tempID, lns.join(require("os").EOL));
|
||||
args.push(fname);
|
||||
filename = args.shift();
|
||||
} else {
|
||||
filename = (process.cwd() + (os.platform() == "win32" ? "\\" + fname.replace(/\//g, "\\") : "/" + fname)).replace(os.platform() == "win32" ? /\\+/ : /\/+/, os.platform() == "win32" ? "\\" : "/")
|
||||
args = [];
|
||||
}
|
||||
} else if(fl.indexOf("\x7fELF") == 0 || fl.indexOf("MZ") == 0) {
|
||||
filename = (process.cwd() + (os.platform() == "win32" ? "\\" + fname.replace(/\//g, "\\") : "/" + fname)).replace(os.platform() == "win32" ? /\\+/ : /\/+/, os.platform() == "win32" ? "\\" : "/")
|
||||
args = [];
|
||||
} else {
|
||||
args = exttointerpreteruser[ext];
|
||||
if (!args) {
|
||||
args = exttointerpreter[ext];
|
||||
if (!args) {
|
||||
elseCallback();
|
||||
return;
|
||||
}
|
||||
}
|
||||
args.push(fname);
|
||||
filename = args.shift();
|
||||
}
|
||||
|
||||
var wd = fname.split("/");
|
||||
wd[0] = "";
|
||||
wd[wd.length-1] = "";
|
||||
wd = wd.join(os.platform() == "win32" ? "\\" : "/");
|
||||
var interpreter = spawn(filename, args, {
|
||||
cwd: (process.cwd() + wd).replace(os.platform() == "win32" ? /\\+/ : /\/+/, os.platform() == "win32" ? "\\" : "/"),
|
||||
env: env
|
||||
});
|
||||
interpreter.on("error", (error) => {
|
||||
if (!callServerError) {
|
||||
res.writeHead(500, {
|
||||
"Content-Type": "text/html",
|
||||
"Server": "RedBrick/" + version
|
||||
});
|
||||
res.end("<html><head></head><body><h1>RedBrick Error!</h1><p>Reason: " + error.message + "</p></body></html>");
|
||||
} else {
|
||||
callServerError(500, "RedBrick/" + version, error);
|
||||
}
|
||||
});
|
||||
var dataHandler = function (data) {
|
||||
buffer += data.toString("latin1");
|
||||
var m = null;
|
||||
if (!cned) m = buffer.match(/(?:\r\n\r\n|\n\n|\r\r)/);
|
||||
if (!cned && m) {
|
||||
cned = true;
|
||||
eol = m[0];
|
||||
headerendline = m.index;
|
||||
var bheaders = buffer.substr(0, headerendline).split(/(?:\r\n|\n|\r)/);
|
||||
var bheaderso = {};
|
||||
if (dh) bheaderso = dh;
|
||||
var code = 200;
|
||||
var msg = "OK";
|
||||
if (bheaders[0].indexOf("HTTP/") == 0) {
|
||||
var heada = bheaders.shift();
|
||||
code = heada.split(" ")[1];
|
||||
if (heada.split(" ")[2] !== undefined) msg = heada.split(" ").splice(2).join(" ");
|
||||
} else if (bheaders[0].indexOf(":") == -1) {
|
||||
var heada = bheaders.shift();
|
||||
code = heada.split(" ")[0];
|
||||
if (heada.split(" ")[1] !== undefined) msg = heada.split(" ").splice(1).join(" ");
|
||||
}
|
||||
for (var i = 0; i < bheaders.length; i++) {
|
||||
var headerp = bheaders[i].split(": ");
|
||||
var headern = headerp.shift();
|
||||
var headerv = headerp.join(": ");
|
||||
if (headern.toLowerCase() == "status") {
|
||||
code = headerv.split(" ")[0];
|
||||
if (headerv.split(" ")[1] !== undefined) msg = headerv.split(" ").splice(1).join(" ");
|
||||
} else if (headern.toLowerCase() == "set-cookie") {
|
||||
if (!bheaderso["Set-Cookie"]) bheaderso["Set-Cookie"] = [];
|
||||
bheaderso["Set-Cookie"].push(headerv);
|
||||
} else {
|
||||
bheaderso[headern] = headerv;
|
||||
}
|
||||
}
|
||||
|
||||
if(code == 200 && (bheaderso["Location"] || bheaderso["location"])) {
|
||||
code = 302;
|
||||
msg = "Found";
|
||||
}
|
||||
|
||||
try {
|
||||
res.writeHead(code, msg, bheaderso);
|
||||
res.write(buffer.substr(headerendline + eol.length), "latin1");
|
||||
} catch (ex) {
|
||||
if (!callServerError) {
|
||||
res.writeHead(500);
|
||||
res.end(ex.stack);
|
||||
} else {
|
||||
callServerError(500, "RedBrick/" + version, ex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (cned && !res.finished) res.write(data);
|
||||
}
|
||||
}
|
||||
if (interpreter.stdout) {
|
||||
interpreter.stdout.on("data", dataHandler);
|
||||
interpreter.stderr.on("data", function(data) {
|
||||
stderr += data.toString()
|
||||
});
|
||||
req.pipe(interpreter.stdin);
|
||||
interpreter.on("exit", (code, signal) => {
|
||||
if(!cned && (signal || code !== 0)) {
|
||||
var ex = new Error("Process execution failed!" + (stderr ? " Reason: " + stderr.trim() : ""));
|
||||
if (!callServerError) {
|
||||
res.writeHead(500);
|
||||
res.end(ex.stack);
|
||||
} else {
|
||||
callServerError(500, "RedBrick/" + version, ex);
|
||||
}
|
||||
} else {
|
||||
res.end();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function executeCGIWithEnv(a, b, req, res, pubip, port, software, dh) {
|
||||
var nEnv = {};
|
||||
nEnv["QUERY_STRING"] = req.url.split("?")[1];
|
||||
if (nEnv["QUERY_STRING"] == undefined || nEnv["QUERY_STRING"] == "undefined") nEnv["QUERY_STRING"] = "";
|
||||
nEnv["SERVER_SOFTWARE"] = software;
|
||||
nEnv["SERVER_PROTOCOL"] = "HTTP/" + req.httpVersion;
|
||||
nEnv["SERVER_PORT"] = port;
|
||||
nEnv["SERVER_ADDR"] = pubip.replace(/^::ffff:/i, "");
|
||||
nEnv["SERVER_NAME"] = req.headers.host;
|
||||
nEnv["DOCUMENT_ROOT"] = process.cwd();
|
||||
nEnv["PATH_INFO"] = b;
|
||||
nEnv["PATH_TRANSLATED"] = (process.cwd() + (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"] = req.url;
|
||||
nEnv["REMOTE_ADDR"] = (req.socket.realRemoteAddress ? req.socket.realRemoteAddress : ((req.headers["x-forwarded-for"] && configJSON.enableIPSpoofing) ? req.headers["x-forwarded-for"].split(",")[0].replace(/ /g,"") : req.socket.remoteAddress)).replace(/^::ffff:/i, "");
|
||||
nEnv["REMOTE_PORT"] = (req.socket.realRemotePort ? req.socket.realRemotePort : req.socket.remoteAddress);
|
||||
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" ? "\\" : "/"));
|
||||
if (req.headers["content-type"]) nEnv["CONTENT_TYPE"] = req.headers["content-type"];
|
||||
if (req.headers["content-length"]) nEnv["CONTENT_LENGTH"] = req.headers["content-length"];
|
||||
var nh = JSON.parse(JSON.stringify(req.headers));
|
||||
delete nh["content-type"];
|
||||
delete nh["content-length"];
|
||||
var nhKeys = Object.keys(nh);
|
||||
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);
|
||||
}
|
||||
if (href.indexOf("/cgi-bin") == 0) {
|
||||
try {
|
||||
if (fs.existsSync("." + href)) {
|
||||
var invokeElseCallback = false;
|
||||
try {
|
||||
invokeElseCallback = !fs.statSync("." + href).isFile();
|
||||
} catch(ex) { }
|
||||
if (invokeElseCallback) {
|
||||
elseCallback();
|
||||
} else {
|
||||
try {
|
||||
try {
|
||||
executeCGIWithEnv(href, "", req, res, req.socket.localAddress, req.socket.localPort, (getCustomHeaders ? (getCustomHeaders()["Server"] + " RedBrick/" + version) : ("SVR.JS/" + configJSON.version + " (" + os.platform()[0].toUpperCase() + os.platform().slice(1) + "; Node.JS/" + process.version + ") RedBrick/" + version)), bheaders);
|
||||
} catch (ex) {
|
||||
if (!callServerError) {
|
||||
res.writeHead(500, "Internal Server Error", abheaders);
|
||||
res.write("<html><head><title>500 Internal Server Error</title></head><body><h1>500 Internal Server Error</h1><p>A server had unexcepted execption. Below, stack of the error is shown: </p><code>" + ex.stack.replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ /g, " ") + "</code><p>Please contact with developer/administrator of the website.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " + configJSON.version + " (" + os.platform()[0].toUpperCase() + os.platform().slice(1) + "; Node.JS/" + process.version + ") RedBrick/" + version + " " + (req.headers.host == undefined ? "" : " on " + req.headers.host) + "</p></body></html>");
|
||||
res.end();
|
||||
} else {
|
||||
callServerError(500, "RedBrick/" + version, ex);
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
if (!callServerError) {
|
||||
res.writeHead(500);
|
||||
res.end(ex.stack);
|
||||
} else {
|
||||
callServerError(500, "RedBrick/" + version, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
function checkPath(pth, a) {
|
||||
var cpth = pth.split("/");
|
||||
if (cpth.length < 3) return false;
|
||||
if(!a) b = [];
|
||||
else var b = a.split("/");
|
||||
var isFile = false;
|
||||
try {
|
||||
isFile = fs.statSync(pth).isFile();
|
||||
} catch (ex) {}
|
||||
if (fs.existsSync(pth) && isFile) {
|
||||
return {
|
||||
fpth: pth,
|
||||
rpth: "/" + a
|
||||
}
|
||||
} else {
|
||||
b.unshift(cpth.pop());
|
||||
return checkPath(cpth.join("/"), b.join("/"));
|
||||
}
|
||||
}
|
||||
var pathp = checkPath("." + href);
|
||||
if (pathp == false) {
|
||||
elseCallback();
|
||||
} else {
|
||||
try {
|
||||
executeCGIWithEnv(pathp.fpth.substr(1), pathp.rpth, req, res, req.socket.localAddress, req.socket.localPort, (getCustomHeaders ? (getCustomHeaders()["Server"] + " RedBrick/" + version) : ("SVR.JS/" + configJSON.version + " (" + os.platform()[0].toUpperCase() + os.platform().slice(1) + "; Node.JS/" + process.version + ") RedBrick/" + version)), bheaders);
|
||||
} catch (ex) {
|
||||
if (!callServerError) {
|
||||
res.writeHead(500, "Internal Server Error", abheaders);
|
||||
res.write("<html><head><title>500 Internal Server Error</title></head><body><h1>500 Internal Server Error</h1><p>A server had unexcepted execption. Below, stack of the error is shown: </p><code>" + ex.stack.replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ /g, " ") + "</code><p>Please contact with developer/administrator of the website.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " + configJSON.version + " (" + os.platform()[0].toUpperCase() + os.platform().slice(1) + "; Node.JS/" + process.version + ") RedBrick/" + version + " " + (req.headers.host == undefined ? "" : " on " + req.headers.host) + "</p></body></html>");
|
||||
res.end();
|
||||
} else {
|
||||
callServerError(500, "RedBrick/" + version, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (ex) {
|
||||
if (!callServerError) {
|
||||
res.writeHead(500, "Internal Server Error", abheaders);
|
||||
res.write("<html><head><title>500 Internal Server Error</title></head><body><h1>500 Internal Server Error</h1><p>A server had unexcepted execption. Below, stack of the error is shown: </p><code>" + ex.stack.replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ /g, " ") + "</code><p>Please contact with developer/administrator of the website.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " + configJSON.version + " (" + os.platform()[0].toUpperCase() + os.platform().slice(1) + "; Node.JS/" + process.version + ") RedBrick/" + version + " " + (req.headers.host == undefined ? "" : " on " + req.headers.host) + "</p></body></html>");
|
||||
res.end();
|
||||
} else {
|
||||
callServerError(500, "RedBrick/" + version, ex);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
elseCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = Mod;
|
4
mod.info
Executable file
4
mod.info
Executable file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "DorianTech RedBrick CGI engine for SVR.JS",
|
||||
"version": "2.1.0"
|
||||
}
|
Loading…
Reference in a new issue