forked from svrjs/svrjs
Update to SVR.JS 3.10.0
This commit is contained in:
parent
9fa9c047d1
commit
ae3cf033be
5 changed files with 135 additions and 184 deletions
16
index.html
16
index.html
|
@ -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/>
|
||||||
|
|
|
@ -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;">
|
||||||
|
|
|
@ -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
269
svr.js
|
@ -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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, " ")).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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, " ")).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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, " ")).replace(/{path}/g, req.url.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")).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, "&").replace(/</g, "<").replace(/>/g, ">"))).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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, " ")).replace(/{path}/g, req.url.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")).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, "&").replace(/</g, "<").replace(/>/g, ">"))).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) {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Reference in a new issue