forked from svrjs/svrjs
Update to SVR.JS 4.0.0-beta3
This commit is contained in:
parent
920d942016
commit
c5af172d1e
26 changed files with 201 additions and 184 deletions
|
@ -217,17 +217,13 @@ esbuild
|
||||||
archive.pipe(output);
|
archive.pipe(output);
|
||||||
|
|
||||||
// Add everything in the "dist" directory except for "svr.js" and "svr.compressed"
|
// Add everything in the "dist" directory except for "svr.js" and "svr.compressed"
|
||||||
const distFilesAndDirectories = fs.existsSync(__dirname + "/dist")
|
archive.glob("**/*", {
|
||||||
? fs.readdirSync(__dirname + "/dist")
|
cwd: __dirname + "/dist",
|
||||||
: [];
|
ignore: [
|
||||||
distFilesAndDirectories.forEach((entry) => {
|
"svr.js",
|
||||||
if (entry == "svr.js" || entry == "svr.compressed") return;
|
"svr.compressed"
|
||||||
const stats = fs.statSync(__dirname + "/dist/" + entry);
|
],
|
||||||
if (stats.isDirectory()) {
|
dot: true
|
||||||
archive.directory(__dirname + "/dist/" + entry, entry);
|
|
||||||
} else if (stats.isFile()) {
|
|
||||||
archive.file(__dirname + "/dist/" + entry, { name: entry });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a stream for the "svr.compressed" file
|
// Create a stream for the "svr.compressed" file
|
||||||
|
|
|
@ -44,7 +44,7 @@ function clientErrorHandler(err, socket) {
|
||||||
if (err.code === "ECONNRESET" || !socket.writable) {
|
if (err.code === "ECONNRESET" || !socket.writable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
socket.end(x, function () {
|
socket.end(x, () => {
|
||||||
try {
|
try {
|
||||||
socket.destroy();
|
socket.destroy();
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
@ -60,9 +60,9 @@ function clientErrorHandler(err, socket) {
|
||||||
headers = Object.assign({}, headers);
|
headers = Object.assign({}, headers);
|
||||||
headers["Date"] = new Date().toGMTString();
|
headers["Date"] = new Date().toGMTString();
|
||||||
headers["Connection"] = "close";
|
headers["Connection"] = "close";
|
||||||
Object.keys(headers).forEach(function (headername) {
|
Object.keys(headers).forEach((headername) => {
|
||||||
if (headername.toLowerCase() == "set-cookie") {
|
if (headername.toLowerCase() == "set-cookie") {
|
||||||
headers[headername].forEach(function (headerValueS) {
|
headers[headername].forEach((headerValueS) => {
|
||||||
if (
|
if (
|
||||||
// eslint-disable-next-line no-control-regex
|
// eslint-disable-next-line no-control-regex
|
||||||
headername.match(/[^\x09\x20-\x7e\x80-\xff]|.:/) ||
|
headername.match(/[^\x09\x20-\x7e\x80-\xff]|.:/) ||
|
||||||
|
@ -105,7 +105,7 @@ function clientErrorHandler(err, socket) {
|
||||||
locmessage: (msg) => serverconsole.locmessage(msg, reqId),
|
locmessage: (msg) => serverconsole.locmessage(msg, reqId),
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.on("close", function (hasError) {
|
socket.on("close", (hasError) => {
|
||||||
if (
|
if (
|
||||||
!hasError ||
|
!hasError ||
|
||||||
err.code == "ERR_SSL_HTTP_REQUEST" ||
|
err.code == "ERR_SSL_HTTP_REQUEST" ||
|
||||||
|
@ -114,7 +114,7 @@ function clientErrorHandler(err, socket) {
|
||||||
logFacilities.locmessage("Client disconnected.");
|
logFacilities.locmessage("Client disconnected.");
|
||||||
else logFacilities.locmessage("Client disconnected due to error.");
|
else logFacilities.locmessage("Client disconnected due to error.");
|
||||||
});
|
});
|
||||||
socket.on("error", function () {});
|
socket.on("error", () => {});
|
||||||
|
|
||||||
// Header and footer placeholders
|
// Header and footer placeholders
|
||||||
let head = "";
|
let head = "";
|
||||||
|
@ -178,7 +178,7 @@ function clientErrorHandler(err, socket) {
|
||||||
if (p) callback(p);
|
if (p) callback(p);
|
||||||
else {
|
else {
|
||||||
if (errorCode == 404) {
|
if (errorCode == 404) {
|
||||||
fs.access(config.page404, fs.constants.F_OK, function (err) {
|
fs.access(config.page404, fs.constants.F_OK, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
fs.access(
|
fs.access(
|
||||||
"." + errorCode.toString(),
|
"." + errorCode.toString(),
|
||||||
|
@ -229,7 +229,7 @@ function clientErrorHandler(err, socket) {
|
||||||
getErrorFileName(list, callback, _i + 1);
|
getErrorFileName(list, callback, _i + 1);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
fs.access(list[_i].path, fs.constants.F_OK, function (err) {
|
fs.access(list[_i].path, fs.constants.F_OK, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
getErrorFileName(list, callback, _i + 1);
|
getErrorFileName(list, callback, _i + 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -239,7 +239,7 @@ function clientErrorHandler(err, socket) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
getErrorFileName(config.errorPages, function (errorFile) {
|
getErrorFileName(config.errorPages, (errorFile) => {
|
||||||
if (Object.prototype.toString.call(stack) === "[object Error]")
|
if (Object.prototype.toString.call(stack) === "[object Error]")
|
||||||
stack = generateErrorStack(stack);
|
stack = generateErrorStack(stack);
|
||||||
if (stack === undefined)
|
if (stack === undefined)
|
||||||
|
@ -313,7 +313,7 @@ function clientErrorHandler(err, socket) {
|
||||||
);
|
);
|
||||||
res.end();
|
res.end();
|
||||||
} else {
|
} else {
|
||||||
fs.readFile(errorFile, function (err, data) {
|
fs.readFile(errorFile, (err, data) => {
|
||||||
try {
|
try {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
res.writeHead(errorCode, http.STATUS_CODES[errorCode], cheaders);
|
res.writeHead(errorCode, http.STATUS_CODES[errorCode], cheaders);
|
||||||
|
|
|
@ -29,8 +29,8 @@ function noproxyHandler(req, socket, head) {
|
||||||
// SVR.JS configuration object (modified)
|
// SVR.JS configuration object (modified)
|
||||||
const config = deepClone(process.serverConfig);
|
const config = deepClone(process.serverConfig);
|
||||||
|
|
||||||
var reqip = socket.remoteAddress;
|
const reqip = socket.remoteAddress;
|
||||||
var reqport = socket.remotePort;
|
const reqport = socket.remotePort;
|
||||||
process.reqcounter++;
|
process.reqcounter++;
|
||||||
logFacilities.locmessage(
|
logFacilities.locmessage(
|
||||||
`Somebody connected to ${
|
`Somebody connected to ${
|
||||||
|
|
|
@ -32,12 +32,11 @@ function proxyHandler(req, socket, head) {
|
||||||
// SVR.JS configuration object (modified)
|
// SVR.JS configuration object (modified)
|
||||||
const config = deepClone(process.serverConfig);
|
const config = deepClone(process.serverConfig);
|
||||||
|
|
||||||
config.generateServerString = () => {
|
config.generateServerString = () =>
|
||||||
return generateServerString(config.exposeServerVersion);
|
generateServerString(config.exposeServerVersion);
|
||||||
};
|
|
||||||
|
|
||||||
var reqip = socket.remoteAddress;
|
const reqip = socket.remoteAddress;
|
||||||
var reqport = socket.remotePort;
|
const reqport = socket.remotePort;
|
||||||
process.reqcounter++;
|
process.reqcounter++;
|
||||||
logFacilities.locmessage(
|
logFacilities.locmessage(
|
||||||
`Somebody connected to ${
|
`Somebody connected to ${
|
||||||
|
|
|
@ -34,9 +34,8 @@ function requestHandler(req, res) {
|
||||||
// SVR.JS configuration object (modified)
|
// SVR.JS configuration object (modified)
|
||||||
const config = deepClone(process.serverConfig);
|
const config = deepClone(process.serverConfig);
|
||||||
|
|
||||||
config.generateServerString = () => {
|
config.generateServerString = () =>
|
||||||
return generateServerString(config.exposeServerVersion);
|
generateServerString(config.exposeServerVersion);
|
||||||
};
|
|
||||||
|
|
||||||
// getCustomHeaders() in SVR.JS 3.x
|
// getCustomHeaders() in SVR.JS 3.x
|
||||||
config.getCustomHeaders = () => {
|
config.getCustomHeaders = () => {
|
||||||
|
@ -79,7 +78,7 @@ function requestHandler(req, res) {
|
||||||
if (table == undefined) table = this.tHeaders;
|
if (table == undefined) table = this.tHeaders;
|
||||||
if (table == undefined) table = {};
|
if (table == undefined) table = {};
|
||||||
table = Object.assign({}, table);
|
table = Object.assign({}, table);
|
||||||
Object.keys(table).forEach(function (key) {
|
Object.keys(table).forEach((key) => {
|
||||||
const al = key.toLowerCase();
|
const al = key.toLowerCase();
|
||||||
if (
|
if (
|
||||||
al == "transfer-encoding" ||
|
al == "transfer-encoding" ||
|
||||||
|
@ -343,7 +342,7 @@ function requestHandler(req, res) {
|
||||||
if (p) callback(p);
|
if (p) callback(p);
|
||||||
else {
|
else {
|
||||||
if (errorCode == 404) {
|
if (errorCode == 404) {
|
||||||
fs.access(config.page404, fs.constants.F_OK, function (err) {
|
fs.access(config.page404, fs.constants.F_OK, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
fs.access(
|
fs.access(
|
||||||
"." + errorCode.toString(),
|
"." + errorCode.toString(),
|
||||||
|
@ -400,7 +399,7 @@ function requestHandler(req, res) {
|
||||||
getErrorFileName(list, callback, _i + 1);
|
getErrorFileName(list, callback, _i + 1);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
fs.access(list[_i].path, fs.constants.F_OK, function (err) {
|
fs.access(list[_i].path, fs.constants.F_OK, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
getErrorFileName(list, callback, _i + 1);
|
getErrorFileName(list, callback, _i + 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -410,7 +409,7 @@ function requestHandler(req, res) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
getErrorFileName(config.errorPages, function (errorFile) {
|
getErrorFileName(config.errorPages, (errorFile) => {
|
||||||
// Generate error stack if not provided
|
// Generate error stack if not provided
|
||||||
if (Object.prototype.toString.call(stack) === "[object Error]")
|
if (Object.prototype.toString.call(stack) === "[object Error]")
|
||||||
stack = generateErrorStack(stack);
|
stack = generateErrorStack(stack);
|
||||||
|
@ -442,7 +441,7 @@ function requestHandler(req, res) {
|
||||||
cheaders["Allow"] = "GET, POST, HEAD, OPTIONS";
|
cheaders["Allow"] = "GET, POST, HEAD, OPTIONS";
|
||||||
|
|
||||||
// Read the error file and replace placeholders with error information
|
// Read the error file and replace placeholders with error information
|
||||||
fs.readFile(errorFile, function (err, data) {
|
fs.readFile(errorFile, (err, data) => {
|
||||||
try {
|
try {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
res.writeHead(errorCode, http.STATUS_CODES[errorCode], cheaders);
|
res.writeHead(errorCode, http.STATUS_CODES[errorCode], cheaders);
|
||||||
|
|
|
@ -38,7 +38,7 @@ function serverErrorHandler(err, isRedirect, server, start) {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Probably main process exited
|
// Probably main process exited
|
||||||
}
|
}
|
||||||
setTimeout(function () {
|
setTimeout(() => {
|
||||||
const errno = os.constants.errno[err.code];
|
const errno = os.constants.errno[err.code];
|
||||||
process.exit(errno !== undefined ? errno : 1);
|
process.exit(errno !== undefined ? errno : 1);
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
64
src/index.js
64
src/index.js
|
@ -134,16 +134,14 @@ for (
|
||||||
args[i] == "/h" ||
|
args[i] == "/h" ||
|
||||||
args[i] == "/?"
|
args[i] == "/?"
|
||||||
) {
|
) {
|
||||||
console.log(name + " usage:");
|
console.log(`${name} usage:`);
|
||||||
console.log(
|
console.log(
|
||||||
"node svr.js [-h] [--help] [-?] [/h] [/?] [--secure] [--reset] [--clean] [--disable-mods] [--single-threaded] [-v] [--version]",
|
"node svr.js [-h] [--help] [-?] [/h] [/?] [--secure] [--reset] [--clean] [--disable-mods] [--single-threaded] [-v] [--version]",
|
||||||
);
|
);
|
||||||
console.log("-h -? /h /? --help -- Displays help");
|
console.log("-h -? /h /? --help -- Displays help");
|
||||||
console.log("--clean -- Cleans up files created by " + name);
|
console.log("--clean -- Cleans up files created by " + name);
|
||||||
console.log(
|
console.log(
|
||||||
"--reset -- Resets " +
|
`--reset -- Resets ${name} to default settings (WARNING: DANGEROUS)`,
|
||||||
name +
|
|
||||||
" to default settings (WARNING: DANGEROUS)",
|
|
||||||
);
|
);
|
||||||
console.log("--secure -- Runs HTTPS server");
|
console.log("--secure -- Runs HTTPS server");
|
||||||
console.log("--disable-mods -- Disables mods (safe mode)");
|
console.log("--disable-mods -- Disables mods (safe mode)");
|
||||||
|
@ -180,17 +178,15 @@ for (
|
||||||
} else if (args[i] == "--single-threaded") {
|
} else if (args[i] == "--single-threaded") {
|
||||||
process.singleThreaded = true;
|
process.singleThreaded = true;
|
||||||
} else {
|
} else {
|
||||||
console.log("Unrecognized argument: " + args[i]);
|
console.log(`Unrecognized argument: ${args[i]}`);
|
||||||
console.log(name + " usage:");
|
console.log(`${name} usage:`);
|
||||||
console.log(
|
console.log(
|
||||||
"node svr.js [-h] [--help] [-?] [/h] [/?] [--secure] [--reset] [--clean] [--disable-mods] [--single-threaded] [-v] [--version]",
|
"node svr.js [-h] [--help] [-?] [/h] [/?] [--secure] [--reset] [--clean] [--disable-mods] [--single-threaded] [-v] [--version]",
|
||||||
);
|
);
|
||||||
console.log("-h -? /h /? --help -- Displays help");
|
console.log("-h -? /h /? --help -- Displays help");
|
||||||
console.log("--clean -- Cleans up files created by " + name);
|
console.log("--clean -- Cleans up files created by " + name);
|
||||||
console.log(
|
console.log(
|
||||||
"--reset -- Resets " +
|
`--reset -- Resets ${name} to default settings (WARNING: DANGEROUS)`,
|
||||||
name +
|
|
||||||
" to default settings (WARNING: DANGEROUS)",
|
|
||||||
);
|
);
|
||||||
console.log("--secure -- Runs HTTPS server");
|
console.log("--secure -- Runs HTTPS server");
|
||||||
console.log("--disable-mods -- Disables mods (safe mode)");
|
console.log("--disable-mods -- Disables mods (safe mode)");
|
||||||
|
@ -422,7 +418,7 @@ try {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ifaceEx = err;
|
ifaceEx = err;
|
||||||
}
|
}
|
||||||
var ips = [];
|
let ips = [];
|
||||||
const brdIPs = ["255.255.255.255", "127.255.255.255", "0.255.255.255"];
|
const brdIPs = ["255.255.255.255", "127.255.255.255", "0.255.255.255"];
|
||||||
const netIPs = ["127.0.0.0"];
|
const netIPs = ["127.0.0.0"];
|
||||||
|
|
||||||
|
@ -461,7 +457,7 @@ if (ips.length == 0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server IP address
|
// Server IP address
|
||||||
var host = ips[ips.length - 1];
|
let host = ips[ips.length - 1];
|
||||||
if (!host) host = "[offline]";
|
if (!host) host = "[offline]";
|
||||||
|
|
||||||
// Public IP address-related
|
// Public IP address-related
|
||||||
|
@ -821,7 +817,7 @@ if (!disableMods) {
|
||||||
crypto.__disabled__ === undefined
|
crypto.__disabled__ === undefined
|
||||||
? "var crypto = require('crypto');\r\nvar https = require('https');\r\n"
|
? "var crypto = require('crypto');\r\nvar https = require('https');\r\n"
|
||||||
: ""
|
: ""
|
||||||
}var stream = require('stream');\r\nvar customvar1;\r\nvar customvar2;\r\nvar customvar3;\r\nvar customvar4;\r\n\r\nfunction Mod() {}\r\nMod.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, authUser) {\r\nreturn () => {\r\nvar disableEndElseCallbackExecute = false;\r\nfunction filterHeaders(e){var r={};return Object.keys(e).forEach(((t) => {null!==e[t]&&void 0!==e[t]&&("object"==typeof e[t]?r[t]=JSON.parse(JSON.stringify(e[t])):r[t]=e[t])})),r}\r\nfunction checkHostname(e){if(void 0===e||"*"==e)return!0;if(req.headers.host&&0==e.indexOf("*.")&&"*."!=e){var r=e.substring(2);if(req.headers.host==r||req.headers.host.indexOf("."+r)==req.headers.host.length-r.length-1)return!0}else if(req.headers.host&&req.headers.host==e)return!0;return!1}\r\nfunction checkHref(e){return href==e||"win32"==os.platform()&&href.toLowerCase()==e.toLowerCase()}\r\n`;
|
}var stream = require('stream');\r\nvar customvar1;\r\nvar customvar2;\r\nvar customvar3;\r\nvar customvar4;\r\n\r\nfunction Mod() {}\r\nMod.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, authUser) {\r\nreturn function() {\r\nvar disableEndElseCallbackExecute = false;\r\nfunction filterHeaders(e){var r={};return Object.keys(e).forEach((function(t){null!==e[t]&&void 0!==e[t]&&("object"==typeof e[t]?r[t]=JSON.parse(JSON.stringify(e[t])):r[t]=e[t])})),r}\r\nfunction checkHostname(e){if(void 0===e||"*"==e)return!0;if(req.headers.host&&0==e.indexOf("*.")&&"*."!=e){var r=e.substring(2);if(req.headers.host==r||req.headers.host.indexOf("."+r)==req.headers.host.length-r.length-1)return!0}else if(req.headers.host&&req.headers.host==e)return!0;return!1}\r\nfunction checkHref(e){return href==e||"win32"==os.platform()&&href.toLowerCase()==e.toLowerCase()}\r\n`;
|
||||||
const modfoot =
|
const modfoot =
|
||||||
"\r\nif(!disableEndElseCallbackExecute) {\r\ntry{\r\nelseCallback();\r\n} catch(err) {\r\n}\r\n}\r\n}\r\n}\r\nmodule.exports = Mod;";
|
"\r\nif(!disableEndElseCallbackExecute) {\r\ntry{\r\nelseCallback();\r\n} catch(err) {\r\n}\r\n}\r\n}\r\n}\r\nmodule.exports = Mod;";
|
||||||
// Write the modified server side script to the temp folder
|
// Write the modified server side script to the temp folder
|
||||||
|
@ -1132,7 +1128,7 @@ if (process.serverConfig.secure) {
|
||||||
key: sniCredentialsSingle.key,
|
key: sniCredentialsSingle.key,
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
var snMatches = sniCredentialsSingle.name.match(
|
let snMatches = sniCredentialsSingle.name.match(
|
||||||
/^([^:[]*|\[[^]]*\]?)((?::.*)?)$/,
|
/^([^:[]*|\[[^]]*\]?)((?::.*)?)$/,
|
||||||
);
|
);
|
||||||
if (!snMatches[1][0].match(/^\.+$/))
|
if (!snMatches[1][0].match(/^\.+$/))
|
||||||
|
@ -1414,7 +1410,7 @@ function SVRJSFork() {
|
||||||
"Starting next thread, because previous one hung up/crashed...",
|
"Starting next thread, because previous one hung up/crashed...",
|
||||||
);
|
);
|
||||||
// Fork new worker
|
// Fork new worker
|
||||||
var newWorker = {};
|
let newWorker = {};
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
!threadLimitWarned &&
|
!threadLimitWarned &&
|
||||||
|
@ -1518,7 +1514,7 @@ function getWorkerCountToFork() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function forkWorkers(workersToFork, callback) {
|
function forkWorkers(workersToFork, callback) {
|
||||||
for (var i = 0; i < workersToFork; i++) {
|
for (let i = 0; i < workersToFork; i++) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
SVRJSFork();
|
SVRJSFork();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1582,9 +1578,9 @@ function msgListener(message) {
|
||||||
|
|
||||||
// Save configuration file
|
// Save configuration file
|
||||||
function saveConfig() {
|
function saveConfig() {
|
||||||
for (var i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
try {
|
try {
|
||||||
var configJSONobj = {};
|
let configJSONobj = {};
|
||||||
if (fs.existsSync(process.dirname + "/config.json"))
|
if (fs.existsSync(process.dirname + "/config.json"))
|
||||||
configJSONobj = JSON.parse(
|
configJSONobj = JSON.parse(
|
||||||
fs.readFileSync(process.dirname + "/config.json").toString(),
|
fs.readFileSync(process.dirname + "/config.json").toString(),
|
||||||
|
@ -1674,12 +1670,14 @@ function saveConfig() {
|
||||||
if (configJSONobj.optOutOfStatisticsServer === undefined)
|
if (configJSONobj.optOutOfStatisticsServer === undefined)
|
||||||
configJSONobj.optOutOfStatisticsServer = false;
|
configJSONobj.optOutOfStatisticsServer = false;
|
||||||
|
|
||||||
var configString = JSON.stringify(configJSONobj, null, 2) + "\n";
|
fs.writeFileSync(
|
||||||
fs.writeFileSync(__dirname + "/config.json", configString);
|
process.dirname + "/config.json",
|
||||||
|
JSON.stringify(configJSONobj, null, 2) + "\n",
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (i >= 2) throw err;
|
if (i >= 2) throw err;
|
||||||
var now = Date.now();
|
const now = Date.now();
|
||||||
while (Date.now() - now < 2);
|
while (Date.now() - now < 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1717,9 +1715,7 @@ function start(init) {
|
||||||
/^(?:0\.|1\.0\.|1\.1\.[0-9](?![0-9])|1\.1\.1[0-2](?![0-9]))/,
|
/^(?:0\.|1\.0\.|1\.1\.[0-9](?![0-9])|1\.1\.1[0-2](?![0-9]))/,
|
||||||
)
|
)
|
||||||
) &&
|
) &&
|
||||||
process.serverConfig.users.some((entry) => {
|
process.serverConfig.users.some((entry) => entry.pbkdf2)
|
||||||
return entry.pbkdf2;
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
serverconsole.locwarnmessage(
|
serverconsole.locwarnmessage(
|
||||||
"PBKDF2 password hashing function in Bun versions older than v1.1.13 blocks the event loop, which may result in denial of service.",
|
"PBKDF2 password hashing function in Bun versions older than v1.1.13 blocks the event loop, which may result in denial of service.",
|
||||||
|
@ -1967,8 +1963,8 @@ function start(init) {
|
||||||
}, 300000);
|
}, 300000);
|
||||||
} else if (cluster.isPrimary) {
|
} else if (cluster.isPrimary) {
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
var allWorkers = Object.keys(cluster.workers);
|
let allWorkers = Object.keys(cluster.workers);
|
||||||
var goodWorkers = [];
|
let goodWorkers = [];
|
||||||
|
|
||||||
const checkWorker = (callback, _id) => {
|
const checkWorker = (callback, _id) => {
|
||||||
if (typeof _id === "undefined") _id = 0;
|
if (typeof _id === "undefined") _id = 0;
|
||||||
|
@ -2058,8 +2054,8 @@ function start(init) {
|
||||||
commands[line.split(" ")[0]] !== undefined &&
|
commands[line.split(" ")[0]] !== undefined &&
|
||||||
commands[line.split(" ")[0]] !== null
|
commands[line.split(" ")[0]] !== null
|
||||||
) {
|
) {
|
||||||
var argss = line.split(" ");
|
let argss = line.split(" ");
|
||||||
var command = argss.shift();
|
const command = argss.shift();
|
||||||
commands[command](argss, (msg) => process.send(msg));
|
commands[command](argss, (msg) => process.send(msg));
|
||||||
process.send("\x12END");
|
process.send("\x12END");
|
||||||
} else {
|
} else {
|
||||||
|
@ -2087,15 +2083,15 @@ function start(init) {
|
||||||
const command = argss.shift();
|
const command = argss.shift();
|
||||||
if (line != "") {
|
if (line != "") {
|
||||||
if (cluster.isPrimary !== undefined) {
|
if (cluster.isPrimary !== undefined) {
|
||||||
var allWorkers = Object.keys(cluster.workers);
|
let allWorkers = Object.keys(cluster.workers);
|
||||||
if (command == "block")
|
if (command == "block")
|
||||||
commands.block(argss, serverconsole.climessage);
|
commands.block(argss, serverconsole.climessage);
|
||||||
if (command == "unblock")
|
if (command == "unblock")
|
||||||
commands.unblock(argss, serverconsole.climessage);
|
commands.unblock(argss, serverconsole.climessage);
|
||||||
if (command == "restart") {
|
if (command == "restart") {
|
||||||
var stopError = false;
|
let stopError = false;
|
||||||
exiting = true;
|
exiting = true;
|
||||||
for (var i = 0; i < allWorkers.length; i++) {
|
for (let i = 0; i < allWorkers.length; i++) {
|
||||||
try {
|
try {
|
||||||
if (cluster.workers[allWorkers[i]]) {
|
if (cluster.workers[allWorkers[i]]) {
|
||||||
cluster.workers[allWorkers[i]].kill();
|
cluster.workers[allWorkers[i]].kill();
|
||||||
|
@ -2150,9 +2146,7 @@ function start(init) {
|
||||||
commands[command](argss, serverconsole.climessage);
|
commands[command](argss, serverconsole.climessage);
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
serverconsole.climessage(
|
serverconsole.climessage(`Unrecognized command "${command}".`);
|
||||||
'Unrecognized command "' + command + '".',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2224,7 +2218,7 @@ function start(init) {
|
||||||
!process.serverConfig.secure
|
!process.serverConfig.secure
|
||||||
) {
|
) {
|
||||||
// It doesn't support through Unix sockets or Windows named pipes
|
// It doesn't support through Unix sockets or Windows named pipes
|
||||||
var address = (
|
let address = (
|
||||||
typeof process.serverConfig.port == "number" && listenAddress
|
typeof process.serverConfig.port == "number" && listenAddress
|
||||||
? listenAddress
|
? listenAddress
|
||||||
: "localhost"
|
: "localhost"
|
||||||
|
@ -2232,7 +2226,7 @@ function start(init) {
|
||||||
if (address.indexOf(":") > -1) {
|
if (address.indexOf(":") > -1) {
|
||||||
address = "[" + address + "]";
|
address = "[" + address + "]";
|
||||||
}
|
}
|
||||||
var connection = http2.connect(
|
const connection = http2.connect(
|
||||||
"http://" +
|
"http://" +
|
||||||
address +
|
address +
|
||||||
":" +
|
":" +
|
||||||
|
|
|
@ -23,14 +23,14 @@ module.exports.commands = {
|
||||||
if (ip == undefined || JSON.stringify(ip) == "[]") {
|
if (ip == undefined || JSON.stringify(ip) == "[]") {
|
||||||
if (!cluster.isPrimary === false) log("Cannot block non-existent IP.");
|
if (!cluster.isPrimary === false) log("Cannot block non-existent IP.");
|
||||||
} else {
|
} else {
|
||||||
for (var i = 0; i < ip.length; i++) {
|
ip.forEach((ipAddress) => {
|
||||||
if (ip[i] != "localhost" && ip[i].indexOf(":") == -1) {
|
if (ipAddress !== "localhost" && ipAddress.indexOf(":") == -1) {
|
||||||
ip[i] = "::ffff:" + ip[i];
|
ipAddress = "::ffff:" + ipAddress;
|
||||||
}
|
}
|
||||||
if (!blocklist.check(ip[i])) {
|
if (!blocklist.check(ipAddress)) {
|
||||||
blocklist.add(ip[i]);
|
blocklist.add(ipAddress);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
process.serverConfig.blacklist = blocklist.raw;
|
process.serverConfig.blacklist = blocklist.raw;
|
||||||
if (!cluster.isPrimary === false) log("IPs successfully blocked.");
|
if (!cluster.isPrimary === false) log("IPs successfully blocked.");
|
||||||
passCommand(ip, log);
|
passCommand(ip, log);
|
||||||
|
@ -40,12 +40,12 @@ module.exports.commands = {
|
||||||
if (ip == undefined || JSON.stringify(ip) == "[]") {
|
if (ip == undefined || JSON.stringify(ip) == "[]") {
|
||||||
if (!cluster.isPrimary === false) log("Cannot unblock non-existent IP.");
|
if (!cluster.isPrimary === false) log("Cannot unblock non-existent IP.");
|
||||||
} else {
|
} else {
|
||||||
for (var i = 0; i < ip.length; i++) {
|
ip.forEach((ipAddress) => {
|
||||||
if (ip[i].indexOf(":") == -1) {
|
if (ipAddress !== "localhost" && ipAddress.indexOf(":") == -1) {
|
||||||
ip[i] = "::ffff:" + ip[i];
|
ipAddress = "::ffff:" + ipAddress;
|
||||||
}
|
}
|
||||||
blocklist.remove(ip[i]);
|
blocklist.remove(ipAddress);
|
||||||
}
|
});
|
||||||
process.serverConfig.blacklist = blocklist.raw;
|
process.serverConfig.blacklist = blocklist.raw;
|
||||||
if (!cluster.isPrimary === false) log("IPs successfully unblocked.");
|
if (!cluster.isPrimary === false) log("IPs successfully unblocked.");
|
||||||
passCommand(ip, log);
|
passCommand(ip, log);
|
||||||
|
|
|
@ -29,7 +29,7 @@ let passwordHashCacheIntervalId = -1;
|
||||||
// Non-standard code object
|
// Non-standard code object
|
||||||
let nonStandardCodes = [];
|
let nonStandardCodes = [];
|
||||||
process.serverConfig.nonStandardCodes.forEach((nonStandardCodeRaw) => {
|
process.serverConfig.nonStandardCodes.forEach((nonStandardCodeRaw) => {
|
||||||
var newObject = {};
|
let newObject = {};
|
||||||
Object.keys(nonStandardCodeRaw).forEach((nsKey) => {
|
Object.keys(nonStandardCodeRaw).forEach((nsKey) => {
|
||||||
if (nsKey != "users") {
|
if (nsKey != "users") {
|
||||||
newObject[nsKey] = nonStandardCodeRaw[nsKey];
|
newObject[nsKey] = nonStandardCodeRaw[nsKey];
|
||||||
|
@ -42,12 +42,12 @@ process.serverConfig.nonStandardCodes.forEach((nonStandardCodeRaw) => {
|
||||||
|
|
||||||
if (!cluster.isPrimary) {
|
if (!cluster.isPrimary) {
|
||||||
passwordHashCacheIntervalId = setInterval(() => {
|
passwordHashCacheIntervalId = setInterval(() => {
|
||||||
pbkdf2Cache = pbkdf2Cache.filter((entry) => {
|
pbkdf2Cache = pbkdf2Cache.filter(
|
||||||
return entry.addDate > new Date() - 3600000;
|
(entry) => entry.addDate > new Date() - 3600000,
|
||||||
});
|
);
|
||||||
scryptCache = scryptCache.filter((entry) => {
|
scryptCache = scryptCache.filter(
|
||||||
return entry.addDate > new Date() - 3600000;
|
(entry) => entry.addDate > new Date() - 3600000,
|
||||||
});
|
);
|
||||||
}, 1800000);
|
}, 1800000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
);
|
);
|
||||||
if (nonStandardCodes[i].regex) {
|
if (nonStandardCodes[i].regex) {
|
||||||
// Regex match
|
// Regex match
|
||||||
var createdRegex = createRegex(nonStandardCodes[i].regex, true);
|
const createdRegex = createRegex(nonStandardCodes[i].regex, true);
|
||||||
isMatch =
|
isMatch =
|
||||||
req.url.match(createdRegex) ||
|
req.url.match(createdRegex) ||
|
||||||
hrefWithoutDuplicateSlashes.match(createdRegex);
|
hrefWithoutDuplicateSlashes.match(createdRegex);
|
||||||
|
@ -192,11 +192,10 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
cacheEntry = scryptCache.find((entry) => {
|
cacheEntry = scryptCache.find(
|
||||||
return (
|
(entry) =>
|
||||||
entry.password == hashedPassword && entry.salt == list[_i].salt
|
entry.password == hashedPassword && entry.salt == list[_i].salt,
|
||||||
);
|
);
|
||||||
});
|
|
||||||
if (cacheEntry) {
|
if (cacheEntry) {
|
||||||
cb(cacheEntry.hash);
|
cb(cacheEntry.hash);
|
||||||
} else {
|
} else {
|
||||||
|
@ -226,11 +225,10 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
cacheEntry = pbkdf2Cache.find((entry) => {
|
cacheEntry = pbkdf2Cache.find(
|
||||||
return (
|
(entry) =>
|
||||||
entry.password == hashedPassword && entry.salt == list[_i].salt
|
entry.password == hashedPassword && entry.salt == list[_i].salt,
|
||||||
);
|
);
|
||||||
});
|
|
||||||
if (cacheEntry) {
|
if (cacheEntry) {
|
||||||
cb(cacheEntry.hash);
|
cb(cacheEntry.hash);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,7 +9,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
!config.disableNonEncryptedServer &&
|
!config.disableNonEncryptedServer &&
|
||||||
!config.disableToHTTPSRedirect
|
!config.disableToHTTPSRedirect
|
||||||
) {
|
) {
|
||||||
var hostx = req.headers.host;
|
const hostx = req.headers.host;
|
||||||
if (hostx === undefined) {
|
if (hostx === undefined) {
|
||||||
logFacilities.errmessage("Host header is missing.");
|
logFacilities.errmessage("Host header is missing.");
|
||||||
res.error(400);
|
res.error(400);
|
||||||
|
@ -22,7 +22,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isPublicServer = !(
|
const isPublicServer = !(
|
||||||
req.socket.realRemoteAddress
|
req.socket.realRemoteAddress
|
||||||
? req.socket.realRemoteAddress
|
? req.socket.realRemoteAddress
|
||||||
: req.socket.remoteAddress
|
: req.socket.remoteAddress
|
||||||
|
@ -30,11 +30,11 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
/^(?:localhost$|::1$|f[c-d][0-9a-f]{2}:|(?:::ffff:)?(?:(?:127|10)\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|192\.168\.[0-9]{1,3}\.[0-9]{1,3}|172\.(?:1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3})$)/i,
|
/^(?:localhost$|::1$|f[c-d][0-9a-f]{2}:|(?:::ffff:)?(?:(?:127|10)\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|192\.168\.[0-9]{1,3}\.[0-9]{1,3}|172\.(?:1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3})$)/i,
|
||||||
);
|
);
|
||||||
|
|
||||||
var destinationPort = 0;
|
let destinationPort = 0;
|
||||||
|
|
||||||
var parsedHostx = hostx.match(/(\[[^\]]*\]|[^:]*)(?::([0-9]+))?/);
|
const parsedHostx = hostx.match(/(\[[^\]]*\]|[^:]*)(?::([0-9]+))?/);
|
||||||
var hostname = parsedHostx[1];
|
let hostname = parsedHostx[1];
|
||||||
var hostPort = parsedHostx[2] ? parseInt(parsedHostx[2]) : 80;
|
let hostPort = parsedHostx[2] ? parseInt(parsedHostx[2]) : 80;
|
||||||
if (isNaN(hostPort)) hostPort = 80;
|
if (isNaN(hostPort)) hostPort = 80;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
module.exports = (req, res, logFacilities, config, next) => {
|
module.exports = (req, res, logFacilities, config, next) => {
|
||||||
if (!req.isProxy) {
|
if (!req.isProxy) {
|
||||||
var hkh = config.getCustomHeaders();
|
const hkh = config.getCustomHeaders();
|
||||||
Object.keys(hkh).forEach((hkS) => {
|
Object.keys(hkh).forEach((hkS) => {
|
||||||
try {
|
try {
|
||||||
res.setHeader(hkS, hkh[hkS]);
|
res.setHeader(hkS, hkh[hkS]);
|
||||||
|
|
|
@ -30,7 +30,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
fs.stat(
|
fs.stat(
|
||||||
"." + decodeURIComponent(req.parsedURL.pathname),
|
"." + decodeURIComponent(req.parsedURL.pathname),
|
||||||
(err, stats) => {
|
(err, stats) => {
|
||||||
var _fileState = 3;
|
let _fileState = 3;
|
||||||
if (err) {
|
if (err) {
|
||||||
_fileState = 3;
|
_fileState = 3;
|
||||||
} else if (stats.isDirectory()) {
|
} else if (stats.isDirectory()) {
|
||||||
|
@ -126,7 +126,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
logFacilities.errmessage("Content blocked.");
|
logFacilities.errmessage("Content blocked.");
|
||||||
return;
|
return;
|
||||||
} else if (sHref != req.parsedURL.pathname) {
|
} else if (sHref != req.parsedURL.pathname) {
|
||||||
var rewrittenAgainURL =
|
const rewrittenAgainURL =
|
||||||
sHref +
|
sHref +
|
||||||
(req.parsedURL.search ? req.parsedURL.search : "") +
|
(req.parsedURL.search ? req.parsedURL.search : "") +
|
||||||
(req.parsedURL.hash ? req.parsedURL.hash : "");
|
(req.parsedURL.hash ? req.parsedURL.hash : "");
|
||||||
|
|
|
@ -34,7 +34,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
let levelDownCount = 0;
|
let levelDownCount = 0;
|
||||||
|
|
||||||
// Loop through the path components
|
// Loop through the path components
|
||||||
for (var i = 0; i < pathComponents.length; i++) {
|
for (let i = 0; i < pathComponents.length; i++) {
|
||||||
// If the component is "..", decrement the levelUpCount
|
// If the component is "..", decrement the levelUpCount
|
||||||
if (".." === pathComponents[i]) {
|
if (".." === pathComponents[i]) {
|
||||||
levelUpCount--;
|
levelUpCount--;
|
||||||
|
@ -313,7 +313,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
// Helper function to check if compression is allowed for the file
|
// Helper function to check if compression is allowed for the file
|
||||||
const canCompress = (path, list) => {
|
const canCompress = (path, list) => {
|
||||||
let canCompress = true;
|
let canCompress = true;
|
||||||
for (var i = 0; i < list.length; i++) {
|
for (let i = 0; i < list.length; i++) {
|
||||||
if (createRegex(list[i], true).test(path)) {
|
if (createRegex(list[i], true).test(path)) {
|
||||||
canCompress = false;
|
canCompress = false;
|
||||||
break;
|
break;
|
||||||
|
@ -437,7 +437,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
})
|
})
|
||||||
.on("open", () => {
|
.on("open", () => {
|
||||||
try {
|
try {
|
||||||
var resStream = {};
|
let resStream = {};
|
||||||
if (useBrotli && isCompressable) {
|
if (useBrotli && isCompressable) {
|
||||||
resStream = zlib.createBrotliCompress();
|
resStream = zlib.createBrotliCompress();
|
||||||
resStream.pipe(res);
|
resStream.pipe(res);
|
||||||
|
@ -738,7 +738,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
// Get stats for all files in the directory and generate the listing
|
// Get stats for all files in the directory and generate the listing
|
||||||
getStatsForAllFiles(list, readFrom, (filelist) => {
|
getStatsForAllFiles(list, readFrom, (filelist) => {
|
||||||
let directoryListingRows = [];
|
let directoryListingRows = [];
|
||||||
for (var i = 0; i < filelist.length; i++) {
|
for (let i = 0; i < filelist.length; i++) {
|
||||||
if (filelist[i].name[0] !== ".") {
|
if (filelist[i].name[0] !== ".") {
|
||||||
const estats = filelist[i].stats;
|
const estats = filelist[i].stats;
|
||||||
const ename = filelist[i].name;
|
const ename = filelist[i].name;
|
||||||
|
@ -773,7 +773,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
||||||
.replace(/>/g, ">")}</a></td><td>${
|
.replace(/>/g, ">")}</a></td><td>${
|
||||||
estats.isDirectory()
|
estats.isDirectory()
|
||||||
? "-"
|
? "-"
|
||||||
: sizify(estats.size.toString())
|
: sizify(estats.size)
|
||||||
}</td><td>${estats.mtime.toDateString()}</td></tr>\r\n`;
|
}</td><td>${estats.mtime.toDateString()}</td></tr>\r\n`;
|
||||||
|
|
||||||
// Determine the file type and set the appropriate image and alt text
|
// Determine the file type and set the appropriate image and alt text
|
||||||
|
|
|
@ -26,9 +26,7 @@ if (!process.singleThreaded) {
|
||||||
cluster.worker = {
|
cluster.worker = {
|
||||||
id: parseInt(process.env.NODE_UNIQUE_ID),
|
id: parseInt(process.env.NODE_UNIQUE_ID),
|
||||||
process: process,
|
process: process,
|
||||||
isDead: () => {
|
isDead: () => false,
|
||||||
return false;
|
|
||||||
},
|
|
||||||
send: (message, ...params) => {
|
send: (message, ...params) => {
|
||||||
process.send(message, ...params);
|
process.send(message, ...params);
|
||||||
},
|
},
|
||||||
|
@ -98,9 +96,7 @@ if (!process.singleThreaded) {
|
||||||
});
|
});
|
||||||
|
|
||||||
newWorker.process = newWorker;
|
newWorker.process = newWorker;
|
||||||
newWorker.isDead = () => {
|
newWorker.isDead = () => newWorker.exitCode !== null || newWorker.killed;
|
||||||
return newWorker.exitCode !== null || newWorker.killed;
|
|
||||||
};
|
|
||||||
newWorker.id = newEnvironment.NODE_UNIQUE_ID;
|
newWorker.id = newEnvironment.NODE_UNIQUE_ID;
|
||||||
|
|
||||||
function checkSendImplementation(worker) {
|
function checkSendImplementation(worker) {
|
||||||
|
|
|
@ -54,16 +54,23 @@ function isIndexOfForbiddenPath(decodedHref, match) {
|
||||||
if (typeof forbiddenPath === "string") {
|
if (typeof forbiddenPath === "string") {
|
||||||
const forbiddenPathLower = isWin32 ? forbiddenPath.toLowerCase() : null;
|
const forbiddenPathLower = isWin32 ? forbiddenPath.toLowerCase() : null;
|
||||||
return isWin32
|
return isWin32
|
||||||
? decodedHrefLower.indexOf(forbiddenPathLower) == 0
|
? decodedHrefLower === forbiddenPathLower ||
|
||||||
: decodedHref.indexOf(forbiddenPath) == 0;
|
decodedHrefLower.indexOf(forbiddenPathLower + "/") == 0
|
||||||
|
: decodedHref === forbiddenPath ||
|
||||||
|
decodedHref.indexOf(forbiddenPath + "/") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof forbiddenPath === "object") {
|
if (typeof forbiddenPath === "object") {
|
||||||
return isWin32
|
return isWin32
|
||||||
? forbiddenPath.some(
|
? forbiddenPath.some(
|
||||||
(path) => decodedHrefLower.indexOf(path.toLowerCase()) == 0,
|
(path) =>
|
||||||
|
decodedHrefLower === path.toLowerCase() ||
|
||||||
|
decodedHrefLower.indexOf(path.toLowerCase() + "/") == 0,
|
||||||
)
|
)
|
||||||
: forbiddenPath.some((path) => decodedHref.indexOf(path) == 0);
|
: forbiddenPath.some(
|
||||||
|
(path) =>
|
||||||
|
decodedHref === path || decodedHref.indexOf(path + "/") == 0,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
// Generate V8-style error stack from Error object.
|
// Generate V8-style error stack from Error object.
|
||||||
function generateErrorStack(errorObject) {
|
function generateErrorStack(errorObject) {
|
||||||
// Split the error stack by newlines.
|
// Split the error stack by newlines.
|
||||||
var errorStack = errorObject.stack ? errorObject.stack.split("\n") : [];
|
const errorStack = errorObject.stack ? errorObject.stack.split("\n") : [];
|
||||||
|
|
||||||
// If the error stack starts with the error name, return the original stack (it is V8-style then).
|
// If the error stack starts with the error name, return the original stack (it is V8-style then).
|
||||||
if (
|
if (
|
||||||
errorStack.some((errorStackLine) => {
|
errorStack.some(
|
||||||
return errorStackLine.indexOf(errorObject.name) == 0;
|
(errorStackLine) => errorStackLine.indexOf(errorObject.name) == 0,
|
||||||
})
|
)
|
||||||
) {
|
) {
|
||||||
return errorObject.stack;
|
return errorObject.stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new error stack with the error name and code (if available).
|
// Create a new error stack with the error name and code (if available).
|
||||||
var newErrorStack = [
|
let newErrorStack = [
|
||||||
errorObject.name +
|
errorObject.name +
|
||||||
(errorObject.code ? ": " + errorObject.code : "") +
|
(errorObject.code ? ": " + errorObject.code : "") +
|
||||||
(errorObject.message == "" ? "" : ": " + errorObject.message),
|
(errorObject.message == "" ? "" : ": " + errorObject.message),
|
||||||
|
@ -23,12 +23,12 @@ function generateErrorStack(errorObject) {
|
||||||
errorStack.forEach((errorStackLine) => {
|
errorStack.forEach((errorStackLine) => {
|
||||||
if (errorStackLine != "") {
|
if (errorStackLine != "") {
|
||||||
// Split the line into function and location parts (if available).
|
// Split the line into function and location parts (if available).
|
||||||
var errorFrame = errorStackLine.split("@");
|
let errorFrame = errorStackLine.split("@");
|
||||||
var location = "";
|
let location = "";
|
||||||
if (errorFrame.length > 1 && errorFrame[0] == "global code")
|
if (errorFrame.length > 1 && errorFrame[0] == "global code")
|
||||||
errorFrame.shift();
|
errorFrame.shift();
|
||||||
if (errorFrame.length > 1) location = errorFrame.pop();
|
if (errorFrame.length > 1) location = errorFrame.pop();
|
||||||
var func = errorFrame.join("@");
|
const func = errorFrame.join("@");
|
||||||
|
|
||||||
// Build the new error stack entry with function and location information.
|
// Build the new error stack entry with function and location information.
|
||||||
newErrorStack.push(
|
newErrorStack.push(
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
const os = require("os");
|
const os = require("os");
|
||||||
|
|
||||||
function getOS() {
|
function getOS() {
|
||||||
var osType = os.type();
|
const osType = os.type();
|
||||||
var platform = os.platform();
|
const platform = os.platform();
|
||||||
if (platform == "android") {
|
if (platform == "android") {
|
||||||
return "Android";
|
return "Android";
|
||||||
} else if (osType == "Windows_NT" || osType == "WindowsNT") {
|
} else if (osType == "Windows_NT" || osType == "WindowsNT") {
|
||||||
var arch = os.arch();
|
const arch = os.arch();
|
||||||
if (arch == "ia32") {
|
if (arch == "ia32") {
|
||||||
return "Win32";
|
return "Win32";
|
||||||
} else if (arch == "x64") {
|
} else if (arch == "x64") {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
function ipBlockList(rawBlockList) {
|
function ipBlockList(rawBlockList) {
|
||||||
// Initialize the instance with empty arrays
|
// Initialize the instance with empty arrays
|
||||||
if (rawBlockList === undefined) rawBlockList = [];
|
if (rawBlockList === undefined) rawBlockList = [];
|
||||||
var instance = {
|
const instance = {
|
||||||
raw: [],
|
raw: [],
|
||||||
rawtoPreparedMap: [],
|
rawtoPreparedMap: [],
|
||||||
prepared: [],
|
prepared: [],
|
||||||
|
@ -10,9 +10,8 @@ function ipBlockList(rawBlockList) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to normalize IPv4 address (remove leading zeros)
|
// Function to normalize IPv4 address (remove leading zeros)
|
||||||
const normalizeIPv4Address = (address) => {
|
const normalizeIPv4Address = (address) =>
|
||||||
return address.replace(/(^|\.)(?:0(?!\.|$))+/g, "$1");
|
address.replace(/(^|\.)(?:0(?!\.|$))+/g, "$1");
|
||||||
};
|
|
||||||
|
|
||||||
// Function to expand IPv6 address to full format
|
// Function to expand IPv6 address to full format
|
||||||
const expandIPv6Address = (address) => {
|
const expandIPv6Address = (address) => {
|
||||||
|
@ -236,9 +235,7 @@ function ipBlockList(rawBlockList) {
|
||||||
? checkIfIPv4CIDRMatches
|
? checkIfIPv4CIDRMatches
|
||||||
: checkIfIPv6CIDRMatches;
|
: checkIfIPv6CIDRMatches;
|
||||||
|
|
||||||
return instance.cidrs.some((iCidr) => {
|
return instance.cidrs.some((iCidr) => checkMethod(ipParsedObject, iCidr));
|
||||||
return checkMethod(ipParsedObject, iCidr);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add initial raw block list values to the instance
|
// Add initial raw block list values to the instance
|
||||||
|
|
|
@ -4,9 +4,8 @@ function ipMatch(IP1, IP2) {
|
||||||
if (!IP2) return false;
|
if (!IP2) return false;
|
||||||
|
|
||||||
// Function to normalize IPv4 address (remove leading zeros)
|
// Function to normalize IPv4 address (remove leading zeros)
|
||||||
const normalizeIPv4Address = (address) => {
|
const normalizeIPv4Address = (address) =>
|
||||||
return address.replace(/(^|\.)(?:0(?!\.|$))+/g, "$1");
|
address.replace(/(^|\.)(?:0(?!\.|$))+/g, "$1");
|
||||||
};
|
|
||||||
|
|
||||||
// Function to expand IPv6 address to full format
|
// Function to expand IPv6 address to full format
|
||||||
const expandIPv6Address = (address) => {
|
const expandIPv6Address = (address) => {
|
||||||
|
|
|
@ -14,7 +14,7 @@ function calculateBroadcastIPv4FromCidr(ipWithCidr) {
|
||||||
.split(".")
|
.split(".")
|
||||||
.map((num, index) => {
|
.map((num, index) => {
|
||||||
// Calculate resulting 8-bit
|
// Calculate resulting 8-bit
|
||||||
var power = Math.max(Math.min(mask - index * 8, 8), 0);
|
const power = Math.max(Math.min(mask - index * 8, 8), 0);
|
||||||
return (
|
return (
|
||||||
(parseInt(num) & ((Math.pow(2, power) - 1) << (8 - power))) |
|
(parseInt(num) & ((Math.pow(2, power) - 1) << (8 - power))) |
|
||||||
(Math.pow(2, 8 - power) - 1)
|
(Math.pow(2, 8 - power) - 1)
|
||||||
|
@ -39,7 +39,7 @@ function calculateNetworkIPv4FromCidr(ipWithCidr) {
|
||||||
.split(".")
|
.split(".")
|
||||||
.map((num, index) => {
|
.map((num, index) => {
|
||||||
// Calculate resulting 8-bit
|
// Calculate resulting 8-bit
|
||||||
var power = Math.max(Math.min(mask - index * 8, 8), 0);
|
const power = Math.max(Math.min(mask - index * 8, 8), 0);
|
||||||
return (
|
return (
|
||||||
parseInt(num) &
|
parseInt(num) &
|
||||||
((Math.pow(2, power) - 1) << (8 - power))
|
((Math.pow(2, power) - 1) << (8 - power))
|
||||||
|
|
|
@ -78,7 +78,7 @@ function LOG(s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server console function
|
// Server console function
|
||||||
var serverconsole = {
|
const serverconsole = {
|
||||||
climessage: (msg, reqId) => {
|
climessage: (msg, reqId) => {
|
||||||
if (msg.indexOf("\n") != -1) {
|
if (msg.indexOf("\n") != -1) {
|
||||||
msg.split("\n").forEach((nmsg) => {
|
msg.split("\n").forEach((nmsg) => {
|
||||||
|
|
|
@ -22,37 +22,14 @@ function sha256(s) {
|
||||||
return (msw << 16) | (lsw & 0xffff);
|
return (msw << 16) | (lsw & 0xffff);
|
||||||
};
|
};
|
||||||
|
|
||||||
const S = (X, n) => {
|
const S = (X, n) => (X >>> n) | (X << (32 - n));
|
||||||
return (X >>> n) | (X << (32 - n));
|
const R = (X, n) => X >>> n;
|
||||||
};
|
const Ch = (x, y, z) => (x & y) ^ (~x & z);
|
||||||
|
const Maj = (x, y, z) => (x & y) ^ (x & z) ^ (y & z);
|
||||||
const R = (X, n) => {
|
const Sigma0256 = (x) => S(x, 2) ^ S(x, 13) ^ S(x, 22);
|
||||||
return X >>> n;
|
const Sigma1256 = (x) => S(x, 6) ^ S(x, 11) ^ S(x, 25);
|
||||||
};
|
const Gamma0256 = (x) => S(x, 7) ^ S(x, 18) ^ R(x, 3);
|
||||||
|
const Gamma1256 = (x) => S(x, 17) ^ S(x, 19) ^ R(x, 10);
|
||||||
const Ch = (x, y, z) => {
|
|
||||||
return (x & y) ^ (~x & z);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Maj = (x, y, z) => {
|
|
||||||
return (x & y) ^ (x & z) ^ (y & z);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Sigma0256 = (x) => {
|
|
||||||
return S(x, 2) ^ S(x, 13) ^ S(x, 22);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Sigma1256 = (x) => {
|
|
||||||
return S(x, 6) ^ S(x, 11) ^ S(x, 25);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Gamma0256 = (x) => {
|
|
||||||
return S(x, 7) ^ S(x, 18) ^ R(x, 3);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Gamma1256 = (x) => {
|
|
||||||
return S(x, 17) ^ S(x, 19) ^ R(x, 10);
|
|
||||||
};
|
|
||||||
|
|
||||||
function coreSha256(m, l) {
|
function coreSha256(m, l) {
|
||||||
const K = new Array(
|
const K = new Array(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
function sizify(bytes, addI) {
|
function sizify(bytes, addI) {
|
||||||
if (bytes === 0) return "0";
|
if (bytes == 0) return "0";
|
||||||
if (bytes < 0) bytes = -bytes;
|
if (bytes < 0) bytes = -bytes;
|
||||||
|
|
||||||
const prefixes = ["", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q"];
|
const prefixes = ["", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q"];
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"version": "4.0.0-beta2",
|
"version": "4.0.0-beta3",
|
||||||
"name": "SVR.JS",
|
"name": "SVR.JS",
|
||||||
"documentationURL": "https://svrjs.org/docs/tentative",
|
"documentationURL": "https://svrjs.org/docs/tentative",
|
||||||
"statisticsServerCollectEndpoint": "https://statistics.svrjs.org/collect.svr",
|
"statisticsServerCollectEndpoint": "https://statistics.svrjs.org/collect.svr",
|
||||||
"changes": [
|
"changes": [
|
||||||
"Fixed the bug with \"ext\" variable for .tar.gz mods.",
|
"Fixed the bug related to forbidden path checking.",
|
||||||
"Fixed the regular expression in the URL parser.",
|
"Fixed \"NaN\" file sizes in directory listings.",
|
||||||
"Optimized many functions"
|
"SVR.JS zip archives now include empty directories."
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,13 @@ describe("Forbidden paths handling", () => {
|
||||||
expect(
|
expect(
|
||||||
isIndexOfForbiddenPath("/notforbidden/", "serverSideScriptDirectories"),
|
isIndexOfForbiddenPath("/notforbidden/", "serverSideScriptDirectories"),
|
||||||
).toBe(false);
|
).toBe(false);
|
||||||
|
expect(isIndexOfForbiddenPath("/config.json.fake", "config")).toBe(false);
|
||||||
|
expect(
|
||||||
|
isIndexOfForbiddenPath(
|
||||||
|
"/node_modules_fake/",
|
||||||
|
"serverSideScriptDirectories",
|
||||||
|
),
|
||||||
|
).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should handle case insensitivity on Windows", () => {
|
test("should handle case insensitivity on Windows", () => {
|
||||||
|
|
|
@ -51,4 +51,52 @@ describe("URL sanitizer", () => {
|
||||||
test('should return "/" for empty sanitized resource', () => {
|
test('should return "/" for empty sanitized resource', () => {
|
||||||
expect(sanitizeURL("/../..")).toBe("/");
|
expect(sanitizeURL("/../..")).toBe("/");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("should encode special characters", () => {
|
||||||
|
expect(sanitizeURL("/test<path>")).toBe("/test%3Cpath%3E");
|
||||||
|
expect(sanitizeURL("/test^path")).toBe("/test%5Epath");
|
||||||
|
expect(sanitizeURL("/test`path")).toBe("/test%60path");
|
||||||
|
expect(sanitizeURL("/test{path}")).toBe("/test%7Bpath%7D");
|
||||||
|
expect(sanitizeURL("/test|path")).toBe("/test%7Cpath");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should preserve certain characters", () => {
|
||||||
|
expect(sanitizeURL("/test!path")).toBe("/test!path");
|
||||||
|
expect(sanitizeURL("/test$path")).toBe("/test$path");
|
||||||
|
expect(sanitizeURL("/test&path")).toBe("/test&path");
|
||||||
|
expect(sanitizeURL("/test-path")).toBe("/test-path");
|
||||||
|
expect(sanitizeURL("/test=path")).toBe("/test=path");
|
||||||
|
expect(sanitizeURL("/test@path")).toBe("/test@path");
|
||||||
|
expect(sanitizeURL("/test_path")).toBe("/test_path");
|
||||||
|
expect(sanitizeURL("/test~path")).toBe("/test~path");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should decode URL-encoded characters while preserving certain characters", () => {
|
||||||
|
expect(sanitizeURL("/test%20path")).toBe("/test%20path");
|
||||||
|
expect(sanitizeURL("/test%21path")).toBe("/test!path");
|
||||||
|
expect(sanitizeURL("/test%22path")).toBe("/test%22path");
|
||||||
|
expect(sanitizeURL("/test%24path")).toBe("/test$path");
|
||||||
|
expect(sanitizeURL("/test%25path")).toBe("/test%25path");
|
||||||
|
expect(sanitizeURL("/test%26path")).toBe("/test&path");
|
||||||
|
expect(sanitizeURL("/test%2Dpath")).toBe("/test-path");
|
||||||
|
expect(sanitizeURL("/test%3Cpath")).toBe("/test%3Cpath");
|
||||||
|
expect(sanitizeURL("/test%3Dpath")).toBe("/test=path");
|
||||||
|
expect(sanitizeURL("/test%3Epath")).toBe("/test%3Epath");
|
||||||
|
expect(sanitizeURL("/test%40path")).toBe("/test@path");
|
||||||
|
expect(sanitizeURL("/test%5Fpath")).toBe("/test_path");
|
||||||
|
expect(sanitizeURL("/test%7Dpath")).toBe("/test%7Dpath");
|
||||||
|
expect(sanitizeURL("/test%7Epath")).toBe("/test~path");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should decode URL-encoded alphanumeric characters while preserving certain characters", () => {
|
||||||
|
expect(sanitizeURL("/conf%69g.json")).toBe("/config.json");
|
||||||
|
expect(sanitizeURL("/CONF%49G.JSON")).toBe("/CONFIG.JSON");
|
||||||
|
expect(sanitizeURL("/svr%32.js")).toBe("/svr2.js");
|
||||||
|
expect(sanitizeURL("/%73%76%72%32%2E%6A%73")).toBe("/svr2.js");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should decode URL-encoded characters regardless of the letter case of the URL encoding", () => {
|
||||||
|
expect(sanitizeURL("/%5f")).toBe("/_");
|
||||||
|
expect(sanitizeURL("/%5F")).toBe("/_");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Reference in a new issue