1
0
Fork 0
forked from svrjs/svrjs

Update to SVR.JS 3.10.0

This commit is contained in:
Dorian Niemiec 2023-09-11 23:23:54 +02:00
parent 9fa9c047d1
commit ae3cf033be
5 changed files with 135 additions and 184 deletions

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>SVR.JS 3.9.6</title> <title>SVR.JS 3.10.0</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<style> <style>
@ -12,7 +12,7 @@
</style> </style>
</head> </head>
<body> <body>
<h1>Welcome to SVR.JS 3.9.6</h1> <h1>Welcome to SVR.JS 3.10.0</h1>
<br/> <br/>
<img src="/logo.png" style="width: 256px;" /> <img src="/logo.png" style="width: 256px;" />
<br/> <br/>
@ -117,14 +117,10 @@
</div> </div>
<p>Changes:</p> <p>Changes:</p>
<ul> <ul>
<li>Changed enableRemoteLogBrowsing property to be false by default.</li> <li>Added warning about worker count being limited to one when using Bun 1.0 and newer with shimmed (not native) clustering module.</li>
<li>Fixed log files only partially saving on failed master startup.</li> <li>Disabled server-side JavaScript bug workaround for Bun 1.0 and newer (it's not needed anymore for these Bun versions).</li>
<li>Mitigated security vulnerability: Sensitive data is no longer leaked from temp directory inside SVR.JS installation directory.</li> <li>Improved clustering shim for Bun.</li>
<li>SVR.JS now logs certificate loading errors.</li> <li>Improved web root error handling.</li>
</ul>
<p>Bugs:</p>
<ul>
<li>On first load server-side JavaScript will fail to load when SVR.JS is running on Bun.</li>
</ul> </ul>
<br/> <br/>
<a href="/tests.html">Tests</a><br/> <a href="/tests.html">Tests</a><br/>

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>SVR.JS 3.9.6 Licenses</title> <title>SVR.JS 3.10.0 Licenses</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<style> <style>
@ -12,8 +12,8 @@
</style> </style>
</head> </head>
<body> <body>
<h1>SVR.JS 3.9.6 Licenses</h1> <h1>SVR.JS 3.10.0 Licenses</h1>
<h2>SVR.JS 3.9.6</h2> <h2>SVR.JS 3.10.0</h2>
<div style="display: inline-block; text-align: left; border-width: 2px; border-style: solid; border-color: gray; padding: 8px;"> <div style="display: inline-block; text-align: left; border-width: 2px; border-style: solid; border-color: gray; padding: 8px;">
MIT License<br/> MIT License<br/>
<br/> <br/>
@ -37,7 +37,7 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br/> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br/>
SOFTWARE.<br/> SOFTWARE.<br/>
</div> </div>
<h2>Packages used by SVR.JS 3.9.6 and utilities</h2> <h2>Packages used by SVR.JS 3.10.0 and utilities</h2>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">

View file

@ -9,12 +9,12 @@
// ext - File extension of requested file // ext - File extension of requested file
// uobject - Request URL object // uobject - Request URL object
// search - Request URL queries // search - Request URL queries
// defaultPage - An index page location (deprecated, always returns 'index.json') // defaultPage - An index page location (deprecated, always returns 'index.html')
// users - A list of users (deprecated) // users - A list of users (deprecated)
// page404 - 404 Not Found page location // page404 - 404 Not Found page location
// head - A head of server response // head - A head of server response
// foot - A foot of server response // foot - A foot of server response
// fd - A response body used by responseEnd method // fd - Currently unused
// elseCallback - Method summoning SVR.JS internal callbacks // elseCallback - Method summoning SVR.JS internal callbacks
// callServerError - Method to end with server error // callServerError - Method to end with server error
// getCustomHeaders - Method to get headers defined in config.json file // getCustomHeaders - Method to get headers defined in config.json file

269
svr.js
View file

@ -81,7 +81,7 @@ function deleteFolderRecursive(path) {
} }
var os = require("os"); var os = require("os");
var version = "3.9.6"; var version = "3.10.0";
var singlethreaded = false; var singlethreaded = false;
if (process.versions) process.versions.svrjs = version; // Inject SVR.JS into process.versions if (process.versions) process.versions.svrjs = version; // Inject SVR.JS into process.versions
@ -151,6 +151,7 @@ if (!singlethreaded) {
cluster.isMaster = !process.env.NODE_UNIQUE_ID; cluster.isMaster = !process.env.NODE_UNIQUE_ID;
cluster.isPrimary = cluster.isMaster; cluster.isPrimary = cluster.isMaster;
cluster.isWorker = !cluster.isMaster; cluster.isWorker = !cluster.isMaster;
cluster.__shimmed__ = true;
if (cluster.isWorker) { if (cluster.isWorker) {
// Shim the cluster.worker object for worker processes // Shim the cluster.worker object for worker processes
@ -289,6 +290,10 @@ if (!singlethreaded) {
newWorker.send(message, fakeParam2, fakeParam3, fakeParam4, tries + 1); newWorker.send(message, fakeParam2, fakeParam3, fakeParam4, tries + 1);
} }
}; };
} else {
newWorker.on("exit", function () {
delete cluster.workers[newWorker.id];
});
} }
cluster.workers[newWorker.id] = newWorker; cluster.workers[newWorker.id] = newWorker;
@ -325,6 +330,7 @@ var SVRJSInitialized = false;
var exiting = false; var exiting = false;
var reallyExiting = false; var reallyExiting = false;
var crashed = false; var crashed = false;
var threadLimitWarned = false;
function SVRJSFork() { function SVRJSFork() {
// Log // Log
@ -332,27 +338,47 @@ function SVRJSFork() {
// Fork new worker // Fork new worker
var newWorker = {}; var newWorker = {};
try { try {
newWorker = cluster.fork(); if (!threadLimitWarned && cluster.__shimmed__ && process.isBun && process.versions.bun && process.versions.bun[0] != "0") {
threadLimitWarned = true;
serverconsole.locwarnmessage("SVR.JS limited the number of workers to one, because of startup problems in Bun 1.0 and newer with shimmed (not native) clustering module. Reliability may suffer.");
}
if (!(cluster.__shimmed__ && process.isBun && process.versions.bun && process.versions.bun[0] != "0" && Object.keys(cluster.workers) > 0)) {
newWorker = cluster.fork();
} else {
if (SVRJSInitialized) serverconsole.locwarnmessage("SVR.JS limited the number of workers to one, because of startup problems in Bun 1.0 and newer with shimmed (not native) clustering module. Reliability may suffer.");
}
} catch (err) { } catch (err) {
if(err.name == "NotImplementedError") { if(err.name == "NotImplementedError") {
// If cluster.fork throws a NotImplementedError, shim cluster module // If cluster.fork throws a NotImplementedError, shim cluster module
cluster.bunShim(); cluster.bunShim();
newWorker = cluster.fork(); if (!threadLimitWarned && cluster.__shimmed__ && process.isBun && process.versions.bun && process.versions.bun[0] != "0") {
threadLimitWarned = true;
serverconsole.locwarnmessage("SVR.JS limited the number of workers to one, because of startup problems in Bun 1.0 and newer with shimmed (not native) clustering module. Reliability may suffer.");
}
if (!(cluster.__shimmed__ && process.isBun && process.versions.bun && process.versions.bun[0] != "0" && Object.keys(cluster.workers) > 0)) {
newWorker = cluster.fork();
} else {
if (SVRJSInitialized) serverconsole.locwarnmessage("SVR.JS limited the number of workers to one, because of startup problems in Bun 1.0 and newer with shimmed (not native) clustering module. Reliability may suffer.");
}
} else { } else {
throw err; throw err;
} }
} }
newWorker.on("error", function (err) {
if(!reallyExiting) serverconsole.locwarnmessage("There was a problem when handling SVR.JS worker! (from master process side) Reason: " + err.message); // Add event listeners
}); if(newWorker.on) {
newWorker.on("exit", function () { newWorker.on("error", function (err) {
if (!exiting && Object.keys(cluster.workers).length == 0) { if(!reallyExiting) serverconsole.locwarnmessage("There was a problem when handling SVR.JS worker! (from master process side) Reason: " + err.message);
crashed = true; });
SVRJSFork(); newWorker.on("exit", function () {
} if (!exiting && Object.keys(cluster.workers).length == 0) {
}); crashed = true;
newWorker.on("message", bruteForceListenerWrapper(newWorker)); SVRJSFork();
newWorker.on("message", listenConnListener); }
});
newWorker.on("message", bruteForceListenerWrapper(newWorker));
newWorker.on("message", listenConnListener);
}
} }
var http = require("http"); var http = require("http");
@ -1151,11 +1177,12 @@ if (configJSON.rewriteDirtyURLs != undefined) rewriteDirtyURLs = configJSON.rewr
if (configJSON.errorPages != undefined) errorPages = configJSON.errorPages; if (configJSON.errorPages != undefined) errorPages = configJSON.errorPages;
if (configJSON.useWebRootServerSideScript != undefined) useWebRootServerSideScript = configJSON.useWebRootServerSideScript; if (configJSON.useWebRootServerSideScript != undefined) useWebRootServerSideScript = configJSON.useWebRootServerSideScript;
if (configJSON.exposeModsInErrorPages != undefined) exposeModsInErrorPages = configJSON.exposeModsInErrorPages; if (configJSON.exposeModsInErrorPages != undefined) exposeModsInErrorPages = configJSON.exposeModsInErrorPages;
if (configJSON.wwwroot != undefined) {
var wwwroot = configJSON.wwwroot; var wwwrootError = null;
if (cluster.isPrimary || cluster.isPrimary === undefined) process.chdir(wwwroot); try {
} else { if (cluster.isPrimary || cluster.isPrimary === undefined) process.chdir(configJSON.wwwroot != undefined ? configJSON.wwwroot : __dirname);
if (cluster.isPrimary || cluster.isPrimary === undefined) process.chdir(__dirname); } catch(err) {
wwwrootError = err;
} }
// Compability for older mods // Compability for older mods
@ -1266,6 +1293,7 @@ if (!fs.existsSync(__dirname + "/config.json")) {
} }
var certificateError = null; var certificateError = null;
// Load SNI // Load SNI
if (secure) { if (secure) {
try { try {
@ -1444,7 +1472,7 @@ if (!disableMods) {
// Define the temporary server-side JavaScript file name // Define the temporary server-side JavaScript file name
var tempServerSideScriptName = "serverSideScript.js"; var tempServerSideScriptName = "serverSideScript.js";
if (!process.isBun && cluster.isPrimary === false) { if (!(process.isBun && process.versions.bun && process.versions.bun[0] == "0") && cluster.isPrimary === false) {
// If not the master process and it's not Bun, create a unique temporary server-side JavaScript file name for each worker // If not the master process and it's not Bun, create a unique temporary server-side JavaScript file name for each worker
tempServerSideScriptName = ".serverSideScript_w" + Math.floor(Math.random() * 65536) + ".js"; tempServerSideScriptName = ".serverSideScript_w" + Math.floor(Math.random() * 65536) + ".js";
} }
@ -1804,6 +1832,57 @@ forbiddenPaths.serverSideScriptDirectories.push(getInitializePath("./mods"));
forbiddenPaths.temp = getInitializePath("./temp"); forbiddenPaths.temp = getInitializePath("./temp");
forbiddenPaths.log = getInitializePath("./log"); forbiddenPaths.log = getInitializePath("./log");
// Error descriptions
var serverErrorDescs = {
200: "The request succeeded! :)",
201: "New resource has been created.",
202: "The request has been accepted for processing, but the processing has not been completed.",
400: "The request you made is invalid.",
401: "You need to authenticate yourself in order to access the requested file.",
402: "You need to pay in order to access the requested file.",
403: "You don't have access to the requested file.",
404: "The requested file doesn't exist. If you have typed URL manually, then please check the spelling.",
405: "Method used to access the requested file isn't allowed.",
406: "The request is capable of generating only not acceptable content.",
407: "You need to authenticate yourself in order to use the proxy.",
408: "You have timed out.",
409: "The request you sent conflicts with the current state of the server.",
410: "The requested file is permanently deleted.",
411: "Content-Length property is required.",
412: "The server doesn't meet preconditions you put in the request.",
413: "The request you sent is too large.",
414: "URL you sent is too long.",
415: "The media type of request you sent isn't supported by the server.",
416: "Content-Range you sent is unsatisfiable.",
417: "Expectation in Expect property couldn't be satisfied.",
418: "The server (teapot) can't brew any coffee! ;)",
421: "The request you made isn't intended for this server.",
422: "The server couldn't process content sent by you.",
423: "The requested file is locked.",
424: "The request depends on another failed request.",
425: "The server is unwilling to risk processing a request that might be replayed.",
426: "You need to upgrade protocols you use to request a file.",
428: "The request you sent needs to be conditional, but it isn't.",
429: "You sent too much requests to the server.",
431: "The request you sent contains headers, that are too large.",
451: "The requested file isn't accessible for legal reasons.",
497: "You sent non-TLS request to the HTTPS server.",
500: "The server had an unexpected error. Below, the error stack is shown: </p><code>{stack}</code><p>Please contact with developer/administrator at <i>{contact}</i>.",
501: "The request requires use of a function, which isn't currently implemented by the server.",
502: "The server had an error, while it was acting as a gateway.</p><p>Please contact with developer/administrator at <i>{contact}</i>.",
503: "The service provided by the server is currently unavailable, possibly due to maintenance downtime or capacity problems. Please try again later.</p><p>Please contact with developer/administrator at <i>{contact}</i>.",
504: "The server couldn't get response in time, while it was acting as a gateway.</p><p>Please contact with developer/administrator at <i>{contact}</i>.",
505: "The server doesn't support HTTP version used in the request.",
506: "Variant header is configured to be engaged in content negotiation.</p><p>Please contact with developer/administrator at <i>{contact}</i>.",
507: "The server ran out of disk space neccessary to complete the request.",
508: "The server detected an infinite loop while processing the request.",
509: "The server has it's bandwidth limit exceeded.</p><p>Please contact with developer/administrator at <i>{contact}</i>.",
510: "The server requires an extended HTTP request. The request you made isn't an extended HTTP request.",
511: "You need to authenticate yourself in order to get network access.",
598: "The server couldn't get response in time, while it was acting as a proxy.",
599: "The server couldn't connect in time, while it was acting as a proxy."
};
// Create server // Create server
if (!cluster.isPrimary) { if (!cluster.isPrimary) {
var reqcounter = 0; var reqcounter = 0;
@ -2250,24 +2329,12 @@ if (!cluster.isPrimary) {
var head = fs.existsSync("./.head") ? fs.readFileSync("./.head").toString() : (fs.existsSync("./head.html") ? fs.readFileSync("./head.html").toString() : ""); // header var head = fs.existsSync("./.head") ? fs.readFileSync("./.head").toString() : (fs.existsSync("./head.html") ? fs.readFileSync("./head.html").toString() : ""); // header
var foot = fs.existsSync("./.foot") ? fs.readFileSync("./.foot").toString() : (fs.existsSync("./foot.html") ? fs.readFileSync("./foot.html").toString() : ""); // footer var foot = fs.existsSync("./.foot") ? fs.readFileSync("./.foot").toString() : (fs.existsSync("./foot.html") ? fs.readFileSync("./foot.html").toString() : ""); // footer
var fd = ""; function responseEnd(body) {
//If body is Buffer, then it is converted to String anyway.
function responseEnd(d) { res.write(head + body + foot);
if (d === undefined) d = fd;
res.write(head + d + foot);
res.end(); res.end();
} }
var serverErrorDescs = {
400: "The request you made is invalid.",
405: "Method used to access the requested file isn't allowed.",
408: "You have timed out.",
414: "URL you sent is too long.",
431: "The request you sent contains headers, that are too large.",
451: "The requested file isn't accessible for legal reasons.",
497: "You sent non-TLS request to the HTTPS server."
};
// Server error calling method // Server error calling method
function callServerError(errorCode, extName, stack, ch) { function callServerError(errorCode, extName, stack, ch) {
function getErrorFileName(list, callback, _i) { function getErrorFileName(list, callback, _i) {
@ -2375,8 +2442,7 @@ if (!cluster.isPrimary) {
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);
fd += data.toString().replace(/{errorMessage}/g, errorCode.toString() + " " + http.STATUS_CODES[errorCode]).replace(/{errorDesc}/g, serverErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, "&nbsp;&nbsp;")).replace(/{server}/g, "" + (exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS") + ((!exposeModsInErrorPages || extName == undefined) ? "" : " " + extName)).replace(/{contact}/g, serverAdmin.replace(/\./g, "[dot]").replace(/@/g, "[at]")); responseEnd(data.toString().replace(/{errorMessage}/g, errorCode.toString() + " " + http.STATUS_CODES[errorCode]).replace(/{errorDesc}/g, serverErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, "&nbsp;&nbsp;")).replace(/{server}/g, "" + (exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS") + ((!exposeModsInErrorPages || extName == undefined) ? "" : " " + extName)).replace(/{contact}/g, serverAdmin.replace(/\./g, "[dot]").replace(/@/g, "[at]")));
responseEnd();
} catch (err) { } catch (err) {
var additionalError = 500; var additionalError = 500;
if (err.code == "ENOENT") { if (err.code == "ENOENT") {
@ -2894,91 +2960,12 @@ if (!cluster.isPrimary) {
var head = fs.existsSync("./.head") ? fs.readFileSync("./.head").toString() : (fs.existsSync("./head.html") ? fs.readFileSync("./head.html").toString() : ""); // header var head = fs.existsSync("./.head") ? fs.readFileSync("./.head").toString() : (fs.existsSync("./head.html") ? fs.readFileSync("./head.html").toString() : ""); // header
var foot = fs.existsSync("./.foot") ? fs.readFileSync("./.foot").toString() : (fs.existsSync("./foot.html") ? fs.readFileSync("./foot.html").toString() : ""); // footer var foot = fs.existsSync("./.foot") ? fs.readFileSync("./.foot").toString() : (fs.existsSync("./foot.html") ? fs.readFileSync("./foot.html").toString() : ""); // footer
var fd = ""; function responseEnd(body) {
//If body is Buffer, then it is converted to String anyway.
function responseEnd(d) { res.write(head + body + foot);
if (d === undefined) d = fd;
res.write(head + d + foot);
res.end(); res.end();
} }
/*
UNUSED CODE:
// function responseEndGzip(d) {
// if (d === undefined) d = fd;
// zlib.gzip(head + d + foot, function (err, buff) {
// if (err) {
// throw err;
// } else {
// res.write(buff);
// res.end();
// }
// });
// }
//
// function responseEndDeflate(d) {
// if (d === undefined) d = fd;
// zlib.deflateRaw(head + d + foot, function (err, buff) {
// if (err) {
// throw err;
// } else {
// res.write(buff);
// res.end();
// }
// });
// }
*/
// Error descriptions
var serverErrorDescs = {
200: "The request succeeded! :)",
201: "New resource has been created.",
202: "The request has been accepted for processing, but the processing has not been completed.",
400: "The request you made is invalid.",
401: "You need to authenticate yourself in order to access the requested file.",
402: "You need to pay in order to access the requested file.",
403: "You don't have access to the requested file.",
404: "The requested file doesn't exist. If you have typed URL manually, then please check the spelling.",
405: "Method used to access the requested file isn't allowed.",
406: "The request is capable of generating only not acceptable content.",
407: "You need to authenticate yourself in order to use the proxy.",
408: "You have timed out.",
409: "The request you sent conflicts with the current state of the server.",
410: "The requested file is permanently deleted.",
411: "Content-Length property is required.",
412: "The server doesn't meet preconditions you put in the request.",
413: "The request you sent is too large.",
414: "URL you sent is too long.",
415: "The media type of request you sent isn't supported by the server.",
416: "Content-Range you sent is unsatisfiable.",
417: "Expectation in Expect property couldn't be satisfied.",
418: "The server (teapot) can't brew any coffee! ;)",
421: "The request you made isn't intended for this server.",
422: "The server couldn't process content sent by you.",
423: "The requested file is locked.",
424: "The request depends on another failed request.",
425: "The server is unwilling to risk processing a request that might be replayed.",
426: "You need to upgrade protocols you use to request a file.",
428: "The request you sent needs to be conditional, but it isn't.",
429: "You sent too much requests to the server.",
431: "The request you sent contains headers, that are too large.",
451: "The requested file isn't accessible for legal reasons.",
500: "The server had an unexpected error. Below, the error stack is shown: </p><code>{stack}</code><p>Please contact with developer/administrator at <i>{contact}</i>.",
501: "The request requires use of a function, which isn't currently implemented by the server.",
502: "The server had an error, while it was acting as a gateway.</p><p>Please contact with developer/administrator at <i>{contact}</i>.",
503: "The service provided by the server is currently unavailable, possibly due to maintenance downtime or capacity problems. Please try again later.</p><p>Please contact with developer/administrator at <i>{contact}</i>.",
504: "The server couldn't get response in time, while it was acting as a gateway.</p><p>Please contact with developer/administrator at <i>{contact}</i>.",
505: "The server doesn't support HTTP version used in the request.",
506: "Variant header is configured to be engaged in content negotiation.</p><p>Please contact with developer/administrator at <i>{contact}</i>.",
507: "The server ran out of disk space neccessary to complete the request.",
508: "The server detected an infinite loop while processing the request.",
509: "The server has it's bandwidth limit exceeded.</p><p>Please contact with developer/administrator at <i>{contact}</i>.",
510: "The server requires an extended HTTP request. The request you made isn't an extended HTTP request.",
511: "You need to authenticate yourself in order to get network access.",
598: "The server couldn't get response in time, while it was acting as a proxy.",
599: "The server couldn't connect in time, while it was acting as a proxy."
};
// Server error calling method // Server error calling method
function callServerError(errorCode, extName, stack, ch) { function callServerError(errorCode, extName, stack, ch) {
if (typeof errorCode !== "number") { if (typeof errorCode !== "number") {
@ -3109,8 +3096,7 @@ if (!cluster.isPrimary) {
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);
fd += data.toString().replace(/{errorMessage}/g, errorCode.toString() + " " + http.STATUS_CODES[errorCode]).replace(/{errorDesc}/g, serverErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, "&nbsp;&nbsp;")).replace(/{path}/g, req.url.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{server}/g, "" + (exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS") + ((!exposeModsInErrorPages || extName == undefined) ? "" : " " + extName) + ((req.headers.host == undefined || isProxy) ? "" : " on " + String(req.headers.host).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"))).replace(/{contact}/g, serverAdmin.replace(/\./g, "[dot]").replace(/@/g, "[at]")); // Replace placeholders in error response responseEnd(data.toString().replace(/{errorMessage}/g, errorCode.toString() + " " + http.STATUS_CODES[errorCode]).replace(/{errorDesc}/g, serverErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, "&nbsp;&nbsp;")).replace(/{path}/g, req.url.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{server}/g, "" + (exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS") + ((!exposeModsInErrorPages || extName == undefined) ? "" : " " + extName) + ((req.headers.host == undefined || isProxy) ? "" : " on " + String(req.headers.host).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"))).replace(/{contact}/g, serverAdmin.replace(/\./g, "[dot]").replace(/@/g, "[at]"))); // Replace placeholders in error response
responseEnd();
} catch (err) { } catch (err) {
var additionalError = 500; var additionalError = 500;
// Handle additional error cases // Handle additional error cases
@ -3294,7 +3280,7 @@ if (!cluster.isPrimary) {
} }
useMods.reverse().forEach(function (modO) { useMods.reverse().forEach(function (modO) {
modFunction = modO.callback(req, res, serverconsole, responseEnd, href, ext, uobject, search, "index.html", users, page404, head, foot, fd, modFunction, configJSON, callServerError, getCustomHeaders, origHref, redirect, parsePostData); modFunction = modO.callback(req, res, serverconsole, responseEnd, href, ext, uobject, search, "index.html", users, page404, head, foot, "", modFunction, configJSON, callServerError, getCustomHeaders, origHref, redirect, parsePostData);
}); });
// Execute modfunction // Execute modfunction
@ -3313,38 +3299,6 @@ if (!cluster.isPrimary) {
} else { } else {
vresCalled = true; vresCalled = true;
} }
/*
UNUSED CODE
// function responseEndGzip(d) {
// if (d === undefined) d = fd;
// zlib.gzip(head + d + foot, function (err, buff) {
// if (err) {
// throw err;
// } else {
// res.write(buff);
// res.end();
// }
// });
// }
//
// function responseEndDeflate(d) {
// if (d === undefined) d = fd;
// zlib.deflateRaw(head + d + foot, function (err, buff) {
// if (err) {
// throw err;
// } else {
// res.write(buff);
// res.end();
// }
// });
// }
*/
function responseEnd(d) {
if (d === undefined) d = fd;
res.write(head + d + foot);
res.end();
}
if (req.socket == null) { if (req.socket == null) {
serverconsole.errmessage("Client socket is null!!!"); serverconsole.errmessage("Client socket is null!!!");
@ -4505,7 +4459,7 @@ if (!cluster.isPrimary) {
} }
} }
serverconsole.reqmessage("Client is logged in as \"" + username + "\""); serverconsole.reqmessage("Client is logged in as \"" + username + "\"");
modExecute(mods, vres(req, res, serverconsole, responseEnd, href, ext, uobject, search, "index.html", users, page404, head, foot, fd, callServerError, getCustomHeaders, origHref, redirect, parsePostData)); modExecute(mods, vres(req, res, serverconsole, responseEnd, href, ext, uobject, search, "index.html", users, page404, head, foot, "", callServerError, getCustomHeaders, origHref, redirect, parsePostData));
} }
} catch(err) { } catch(err) {
callServerError(500, undefined, generateErrorStack(err)); callServerError(500, undefined, generateErrorStack(err));
@ -4552,7 +4506,7 @@ if (!cluster.isPrimary) {
process.send("\x12AUTHQ" + reqip); process.send("\x12AUTHQ" + reqip);
} }
} else { } else {
modExecute(mods, vres(req, res, serverconsole, responseEnd, href, ext, uobject, search, "index.html", users, page404, head, foot, fd, callServerError, getCustomHeaders, origHref, redirect, parsePostData)); modExecute(mods, vres(req, res, serverconsole, responseEnd, href, ext, uobject, search, "index.html", users, page404, head, foot, "", callServerError, getCustomHeaders, origHref, redirect, parsePostData));
} }
} }
} catch (err) { } catch (err) {
@ -4871,6 +4825,7 @@ function start(init) {
if (netIPs.indexOf(listenAddress) > -1) throw new Error("SVR.JS can't listen on subnet address."); if (netIPs.indexOf(listenAddress) > -1) throw new Error("SVR.JS can't listen on subnet address.");
} }
if(certificateError) throw new Error("There was a problem with SSL certificate/private key: " + certificateError.message); if(certificateError) throw new Error("There was a problem with SSL certificate/private key: " + certificateError.message);
if(wwwrootError) throw new Error("There was a problem with your web root: " + wwwrootError.message);
} }
// Information about starting the server // Information about starting the server
@ -5569,7 +5524,7 @@ if (cluster.isPrimary || cluster.isPrimary === undefined) {
} catch (err) { } catch (err) {
// Error! // Error!
} }
if (process.isBun) { if (process.isBun && process.versions.bun && process.versions.bun[0] == "0") {
try { try {
fs.writeFileSync(__dirname + "/temp/serverSideScript.js", "// Placeholder server-side JavaScript to workaround Bun bug.\r\n"); fs.writeFileSync(__dirname + "/temp/serverSideScript.js", "// Placeholder server-side JavaScript to workaround Bun bug.\r\n");
} catch (err) { } catch (err) {

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>SVR.JS 3.9.6 Tests</title> <title>SVR.JS 3.10.0 Tests</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<style> <style>
@ -12,7 +12,7 @@
</style> </style>
</head> </head>
<body> <body>
<h1>SVR.JS 3.9.6 Tests</h1> <h1>SVR.JS 3.10.0 Tests</h1>
<h2>Directory</h2> <h2>Directory</h2>
<iframe src="/testdir" width="50%" height="300px"></iframe> <iframe src="/testdir" width="50%" height="300px"></iframe>
<h2>Directory (with query)</h2> <h2>Directory (with query)</h2>