1
0
Fork 0
forked from svrjs/svrjs

Clean up SVR.JS code

This commit is contained in:
Dorian Niemiec 2023-12-03 13:58:35 +01:00
parent caf2ad685d
commit ebe310eca6

70
svr.js
View file

@ -1,4 +1,3 @@
///////////////////////////////////////// /////////////////////////////////////////
// // // //
// S V R . J S // // S V R . J S //
@ -312,6 +311,7 @@ if (!singlethreaded) {
// ETag-related // ETag-related
var ETagDB = {}; var ETagDB = {};
function generateETag(filePath, stat) { function generateETag(filePath, stat) {
if (!ETagDB[filePath + "-" + stat.size + "-" + stat.mtime]) ETagDB[filePath + "-" + stat.size + "-" + stat.mtime] = sha256(filePath + "-" + stat.size + "-" + stat.mtime); if (!ETagDB[filePath + "-" + stat.size + "-" + stat.mtime]) ETagDB[filePath + "-" + stat.size + "-" + stat.mtime] = sha256(filePath + "-" + stat.size + "-" + stat.mtime);
return ETagDB[filePath + "-" + stat.size + "-" + stat.mtime]; return ETagDB[filePath + "-" + stat.size + "-" + stat.mtime];
@ -1558,7 +1558,10 @@ if (!disableMods) {
} }
} }
} catch (err) { } catch (err) {
modLoadingErrors.push({error: err, modName: modFileRaw}); modLoadingErrors.push({
error: err,
modName: modFileRaw
});
} }
} }
}); });
@ -2332,6 +2335,7 @@ if (!cluster.isPrimary) {
callback(errorCode.toString() + ".html"); callback(errorCode.toString() + ".html");
return; return;
} }
function medCallback(p) { function medCallback(p) {
if (p) callback(p); if (p) callback(p);
else { else {
@ -3457,26 +3461,26 @@ if (!cluster.isPrimary) {
res.writeHead(200, http.STATUS_CODES[200], customHeaders); res.writeHead(200, http.STATUS_CODES[200], customHeaders);
// Read custom header and footer content (if available) // Read custom header and footer content (if available)
var customDirListingHeader = fs.existsSync(("." + decodeURIComponent(href) + "/.dirhead").replace(/\/+/g, "/")) var customDirListingHeader = fs.existsSync(("." + decodeURIComponent(href) + "/.dirhead").replace(/\/+/g, "/")) ?
? fs.readFileSync(("." + decodeURIComponent(href) + "/.dirhead").replace(/\/+/g, "/")).toString() fs.readFileSync(("." + decodeURIComponent(href) + "/.dirhead").replace(/\/+/g, "/")).toString() :
: (fs.existsSync(("." + decodeURIComponent(href) + "/HEAD.html").replace(/\/+/g, "/")) && (os.platform != "win32" || href != "/")) (fs.existsSync(("." + decodeURIComponent(href) + "/HEAD.html").replace(/\/+/g, "/")) && (os.platform != "win32" || href != "/")) ?
? fs.readFileSync(("." + decodeURIComponent(href) + "/HEAD.html").replace(/\/+/g, "/")).toString() fs.readFileSync(("." + decodeURIComponent(href) + "/HEAD.html").replace(/\/+/g, "/")).toString() :
: ""; "";
var customDirListingFooter = fs.existsSync(("." + decodeURIComponent(href) + "/.dirfoot").replace(/\/+/g, "/")) var customDirListingFooter = fs.existsSync(("." + decodeURIComponent(href) + "/.dirfoot").replace(/\/+/g, "/")) ?
? fs.readFileSync(("." + decodeURIComponent(href) + "/.dirfoot").replace(/\/+/g, "/")).toString() fs.readFileSync(("." + decodeURIComponent(href) + "/.dirfoot").replace(/\/+/g, "/")).toString() :
: (fs.existsSync(("." + decodeURIComponent(href) + "/FOOT.html").replace(/\/+/g, "/")) && (os.platform != "win32" || href != "/")) (fs.existsSync(("." + decodeURIComponent(href) + "/FOOT.html").replace(/\/+/g, "/")) && (os.platform != "win32" || href != "/")) ?
? fs.readFileSync(("." + decodeURIComponent(href) + "/FOOT.html").replace(/\/+/g, "/")).toString() fs.readFileSync(("." + decodeURIComponent(href) + "/FOOT.html").replace(/\/+/g, "/")).toString() :
: ""; "";
// Check if custom header has HTML tag // Check if custom header has HTML tag
var headerHasHTMLTag = customDirListingHeader.replace(/<!--(?:(?:(?!--\>)[\s\S])*|)(?:-->|$)/g, "").match(/<html(?![a-zA-Z0-9])(?:"(?:\\(?:[\s\S]|$)|[^\\"])*(?:"|$)|'(?:\\(?:[\s\S]|$)|[^\\'])*(?:'|$)|[^'">])*(?:>|$)/i); var headerHasHTMLTag = customDirListingHeader.replace(/<!--(?:(?:(?!--\>)[\s\S])*|)(?:-->|$)/g, "").match(/<html(?![a-zA-Z0-9])(?:"(?:\\(?:[\s\S]|$)|[^\\"])*(?:"|$)|'(?:\\(?:[\s\S]|$)|[^\\'])*(?:'|$)|[^'">])*(?:>|$)/i);
// Generate HTML head and footer based on configuration and custom content // Generate HTML head and footer based on configuration and custom content
var htmlHead = (!configJSON.enableDirectoryListingWithDefaultHead || head == "" var htmlHead = (!configJSON.enableDirectoryListingWithDefaultHead || head == "" ?
? (!headerHasHTMLTag (!headerHasHTMLTag ?
? "<!DOCTYPE html><html><head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /></head><body>" "<!DOCTYPE html><html><head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /></head><body>" :
: customDirListingHeader.replace(/<head>/i, "<head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title>")) customDirListingHeader.replace(/<head>/i, "<head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title>")) :
: head.replace(/<head>/i, "<head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title>")) + head.replace(/<head>/i, "<head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title>")) +
(!headerHasHTMLTag ? customDirListingHeader : "") + (!headerHasHTMLTag ? customDirListingHeader : "") +
"<h1>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</h1><table id=\"directoryListing\"> <tr> <th></th> <th>Filename</th> <th>Size</th> <th>Date</th> </tr>" + (checkPathLevel(decodeURIComponent(origHref)) < 1 ? "" : "<tr><td style=\"width: 24px;\"><img src=\"/.dirimages/return.png\" width=\"24px\" height=\"24px\" alt=\"[RET]\" /></td><td style=\"word-wrap: break-word; word-break: break-word; overflow-wrap: break-word;\"><a href=\"" + (origHref).replace(/\/+/g, "/").replace(/\/[^\/]*\/?$/, "/") + "\">Return</a></td><td></td><td></td></tr>"); "<h1>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</h1><table id=\"directoryListing\"> <tr> <th></th> <th>Filename</th> <th>Size</th> <th>Date</th> </tr>" + (checkPathLevel(decodeURIComponent(origHref)) < 1 ? "" : "<tr><td style=\"width: 24px;\"><img src=\"/.dirimages/return.png\" width=\"24px\" height=\"24px\" alt=\"[RET]\" /></td><td style=\"word-wrap: break-word; word-break: break-word; overflow-wrap: break-word;\"><a href=\"" + (origHref).replace(/\/+/g, "/").replace(/\/[^\/]*\/?$/, "/") + "\">Return</a></td><td></td><td></td></tr>");
@ -4318,7 +4322,7 @@ if (!cluster.isPrimary) {
try { try {
callback(); callback();
} catch (ex) { } catch (ex) {
callServerError(500, undefined, ex); callServerError(500, undefined, ex);
} }
} else { } else {
var destinationURL = uobject; var destinationURL = uobject;
@ -4373,7 +4377,12 @@ if (!cluster.isPrimary) {
callServerError(500, undefined, err); callServerError(500, undefined, err);
} else { } else {
var key = derivedKey.toString("hex"); var key = derivedKey.toString("hex");
scryptCache.push({hash: key, password: hashedPassword, salt: list[_i].salt, addDate: new Date()}); scryptCache.push({
hash: key,
password: hashedPassword,
salt: list[_i].salt,
addDate: new Date()
});
cb(key); cb(key);
} }
}); });
@ -4395,7 +4404,12 @@ if (!cluster.isPrimary) {
callServerError(500, undefined, err); callServerError(500, undefined, err);
} else { } else {
var key = derivedKey.toString("hex"); var key = derivedKey.toString("hex");
pbkdf2Cache.push({hash: key, password: hashedPassword, salt: list[_i].salt, addDate: new Date()}); pbkdf2Cache.push({
hash: key,
password: hashedPassword,
salt: list[_i].salt,
addDate: new Date()
});
cb(key); cb(key);
} }
}); });
@ -4438,7 +4452,11 @@ if (!cluster.isPrimary) {
}); });
} }
if (usernameMatch.length == 0) { if (usernameMatch.length == 0) {
usernameMatch.push({name: username, pass: "FAKEPASS", salt: "FAKESALT"}); // Fake credentials usernameMatch.push({
name: username,
pass: "FAKEPASS",
salt: "FAKESALT"
}); // Fake credentials
} }
checkIfPasswordMatches(usernameMatch, password, function (authorized) { checkIfPasswordMatches(usernameMatch, password, function (authorized) {
try { try {
@ -4789,8 +4807,12 @@ function start(init) {
if (configJSON.enableHTTP2 && !secure) serverconsole.locwarnmessage("HTTP/2 without HTTPS may not work in web browsers. Web browsers only support HTTP/2 with HTTPS!"); if (configJSON.enableHTTP2 && !secure) serverconsole.locwarnmessage("HTTP/2 without HTTPS may not work in web browsers. Web browsers only support HTTP/2 with HTTPS!");
if (process.isBun) { if (process.isBun) {
serverconsole.locwarnmessage("Bun support is experimental. Some features of SVR.JS, SVR.JS mods and SVR.JS server-side JavaScript may not work as expected."); serverconsole.locwarnmessage("Bun support is experimental. Some features of SVR.JS, SVR.JS mods and SVR.JS server-side JavaScript may not work as expected.");
if(users.some(function (entry) {return entry.pbkdf2;})) serverconsole.locwarnmessage("PBKDF2 password hashing function in Bun blocks the event loop, which may result in denial of service."); if (users.some(function (entry) {
if(users.some(function (entry) {return entry.scrypt;})) serverconsole.locwarnmessage("scrypt password hashing function in Bun blocks the event loop, which may result in denial of service."); return entry.pbkdf2;
})) serverconsole.locwarnmessage("PBKDF2 password hashing function in Bun blocks the event loop, which may result in denial of service.");
if (users.some(function (entry) {
return entry.scrypt;
})) serverconsole.locwarnmessage("scrypt password hashing function in Bun blocks the event loop, which may result in denial of service.");
} }
if (cluster.isPrimary === undefined) serverconsole.locwarnmessage("You're running SVR.JS on single thread. Reliability may suffer, as the server is stopped after crash."); if (cluster.isPrimary === undefined) serverconsole.locwarnmessage("You're running SVR.JS on single thread. Reliability may suffer, as the server is stopped after crash.");
if (crypto.__disabled__ !== undefined) serverconsole.locwarnmessage("Your Node.JS version doesn't have crypto support! The 'crypto' module is essential for providing cryptographic functionality in Node.JS. Without crypto support, certain security features may be unavailable, and some functionality may not work as expected. It's recommended to use a Node.JS version that includes crypto support to ensure the security and proper functioning of your server."); if (crypto.__disabled__ !== undefined) serverconsole.locwarnmessage("Your Node.JS version doesn't have crypto support! The 'crypto' module is essential for providing cryptographic functionality in Node.JS. Without crypto support, certain security features may be unavailable, and some functionality may not work as expected. It's recommended to use a Node.JS version that includes crypto support to ensure the security and proper functioning of your server.");
@ -5039,6 +5061,7 @@ function start(init) {
setInterval(function () { setInterval(function () {
var allClusters = Object.keys(cluster.workers); var allClusters = Object.keys(cluster.workers);
var goodWorkers = []; var goodWorkers = [];
function checkWorker(callback, _id) { function checkWorker(callback, _id) {
if (typeof _id === "undefined") _id = 0; if (typeof _id === "undefined") _id = 0;
if (_id >= allClusters.length) { if (_id >= allClusters.length) {
@ -5428,6 +5451,7 @@ function start(init) {
minClusters = Math.ceil(cpus * 0.625); minClusters = Math.ceil(cpus * 0.625);
if (minClusters < 2) minClusters = 2; if (minClusters < 2) minClusters = 2;
var goodWorkers = []; var goodWorkers = [];
function checkWorker(callback, _id) { function checkWorker(callback, _id) {
if (typeof _id === "undefined") _id = 0; if (typeof _id === "undefined") _id = 0;
if (_id >= allClusters.length) { if (_id >= allClusters.length) {