Compare commits
6 commits
a3e4ee2328
...
519e68465a
Author | SHA1 | Date | |
---|---|---|---|
519e68465a | |||
1161256ab9 | |||
1a7e602198 | |||
e1b6ca8803 | |||
3a8cdccc0d | |||
7a658613fe |
11 changed files with 320 additions and 308 deletions
|
@ -6,7 +6,8 @@ const archiver = require("archiver");
|
|||
const dependencies = JSON.parse(fs.readFileSync(__dirname + "/package.json")).dependencies || {};
|
||||
const requiredDependencyList = Object.keys(dependencies);
|
||||
let dependencyList = Object.keys(dependencies);
|
||||
const version = JSON.parse(fs.readFileSync(__dirname + "/svrjs.json")).version;
|
||||
const svrjsInfo = JSON.parse(fs.readFileSync(__dirname + "/svrjs.json"));
|
||||
const {name, version, documentationURL} = svrjsInfo;
|
||||
|
||||
// Function to find and add all dependencies into the dependencyList array.
|
||||
function findAllDependencies(curList) {
|
||||
|
@ -53,7 +54,8 @@ let licenseElements = "";
|
|||
dependencyList.forEach((dependency) => {
|
||||
const packageJSON = JSON.parse(fs.readFileSync(__dirname + "/node_modules/" + dependency.replace(/\/\.\./g,"") + "/package.json").toString());
|
||||
licenseElements += licenseElementTemplate({
|
||||
name: packageJSON.name,
|
||||
moduleName: packageJSON.name,
|
||||
name: name,
|
||||
license: packageJSON.license,
|
||||
description: packageJSON.description || "No description",
|
||||
author: packageJSON.author ? packageJSON.author.name : packageJSON.author,
|
||||
|
@ -63,24 +65,28 @@ dependencyList.forEach((dependency) => {
|
|||
|
||||
// Generate pages
|
||||
const licensesPage = layoutTemplate({
|
||||
title: "SVR.JS " + version + " Licenses",
|
||||
title: name + " " + version + " Licenses",
|
||||
content: licensesTemplate({
|
||||
name: name,
|
||||
version: version,
|
||||
licenses: licenseElements
|
||||
})
|
||||
});
|
||||
|
||||
const testsPage = layoutTemplate({
|
||||
title: "SVR.JS " + version + " Tests",
|
||||
title: name + " " + version + " Tests",
|
||||
content: testsTemplate({
|
||||
name: name,
|
||||
version: version
|
||||
})
|
||||
});
|
||||
|
||||
const indexPage = layoutTemplate({
|
||||
title: "SVR.JS " + version,
|
||||
title: name + " " + version,
|
||||
content: indexTemplate({
|
||||
version: version
|
||||
name: name,
|
||||
version: version,
|
||||
documentationURL: documentationURL
|
||||
})
|
||||
});
|
||||
|
||||
|
|
130
src/index.js
130
src/index.js
|
@ -1,10 +1,10 @@
|
|||
const http = require("http");
|
||||
const fs = require("fs");
|
||||
const cluster = require("./utils/clusterBunShim.js"); // Cluster module with shim for Bun
|
||||
//const generateErrorStack = require("./utils/generateErrorStack.js");
|
||||
const getOS = require("./utils/getOS.js");
|
||||
//const getOS = require("./utils/getOS.js");
|
||||
const generateServerString = require("./utils/generateServerString.js")
|
||||
const svrjsInfo = require("../svrjs.json");
|
||||
const version = svrjsInfo.version;
|
||||
const {version} = svrjsInfo;
|
||||
//const parseURL = require("./utils/urlParser.js");
|
||||
//const fixNodeMojibakeURL = require("./utils/urlMojibakeFixer.js");
|
||||
|
||||
|
@ -20,7 +20,65 @@ if (!fs.existsSync(__dirname + "/log")) fs.mkdirSync(__dirname + "/log");
|
|||
if (!fs.existsSync(__dirname + "/mods")) fs.mkdirSync(__dirname + "/mods");
|
||||
if (!fs.existsSync(__dirname + "/temp")) fs.mkdirSync(__dirname + "/temp");
|
||||
|
||||
const serverconsoleConstructor = require("./utils/serverconsole.js");
|
||||
// TODO: process.singleThreaded flag
|
||||
process.singleThreaded = true;
|
||||
const cluster = require("./utils/clusterBunShim.js"); // Cluster module with shim for Bun
|
||||
|
||||
process.serverConfig = {};
|
||||
|
||||
// TODO: configuration from config.json
|
||||
if (process.serverConfig.users === undefined) process.serverConfig.users = [];
|
||||
if (process.serverConfig.secure) {
|
||||
if (process.serverConfig.key === undefined) process.serverConfig.key = "cert/key.key";
|
||||
if (process.serverConfig.cert === undefined) process.serverConfig.cert = "cert/cert.crt";
|
||||
if (process.serverConfig.sport === undefined) process.serverConfig.sport = 443;
|
||||
if (process.serverConfig.spubport === undefined) process.serverConfig.spubport = 443;
|
||||
if (process.serverConfig.sni === undefined) process.serverConfig.sni = {};
|
||||
if (process.serverConfig.enableOCSPStapling === undefined) process.serverConfig.enableOCSPStapling = false;
|
||||
}
|
||||
if (process.serverConfig.port === undefined) process.serverConfig.port = 80;
|
||||
if (process.serverConfig.pubport === undefined) process.serverConfig.pubport = 80;
|
||||
if (process.serverConfig.domain === undefined && process.serverConfig.domian !== undefined) process.serverConfig.domain = process.serverConfig.domian;
|
||||
delete process.serverConfig.domian;
|
||||
if (process.serverConfig.page404 === undefined) process.serverConfig.page404 = "404.html";
|
||||
//process.serverConfig.timestamp = timestamp; //TODO
|
||||
//process.serverConfig.blacklist = blocklist.raw; //TODO
|
||||
if (process.serverConfig.nonStandardCodes === undefined) process.serverConfig.nonStandardCodes = [];
|
||||
if (process.serverConfig.enableCompression === undefined) process.serverConfig.enableCompression = true;
|
||||
if (process.serverConfig.customHeaders === undefined) process.serverConfig.customHeaders = {};
|
||||
if (process.serverConfig.enableHTTP2 === undefined) process.serverConfig.enableHTTP2 = false;
|
||||
if (process.serverConfig.enableLogging === undefined) process.serverConfig.enableLogging = true;
|
||||
if (process.serverConfig.enableDirectoryListing === undefined) process.serverConfig.enableDirectoryListing = true;
|
||||
if (process.serverConfig.enableDirectoryListingWithDefaultHead === undefined) process.serverConfig.enableDirectoryListingWithDefaultHead = false;
|
||||
if (process.serverConfig.serverAdministratorEmail === undefined) process.serverConfig.serverAdministratorEmail = "[no contact information]";
|
||||
if (process.serverConfig.stackHidden === undefined) process.serverConfig.stackHidden = false;
|
||||
if (process.serverConfig.enableRemoteLogBrowsing === undefined) process.serverConfig.enableRemoteLogBrowsing = false;
|
||||
if (process.serverConfig.exposeServerVersion === undefined) process.serverConfig.exposeServerVersion = true;
|
||||
if (process.serverConfig.disableServerSideScriptExpose === undefined) process.serverConfig.disableServerSideScriptExpose = true;
|
||||
if (process.serverConfig.allowStatus === undefined) process.serverConfig.allowStatus = true;
|
||||
if (process.serverConfig.rewriteMap === undefined) process.serverConfig.rewriteMap = [];
|
||||
if (process.serverConfig.dontCompress === undefined) process.serverConfig.dontCompress = ["/.*\\.ipxe$/", "/.*\\.(?:jpe?g|png|bmp|tiff|jfif|gif|webp)$/", "/.*\\.(?:[id]mg|iso|flp)$/", "/.*\\.(?:zip|rar|bz2|[gb7x]z|lzma|tar)$/", "/.*\\.(?:mp[34]|mov|wm[av]|avi|webm|og[gv]|mk[va])$/"];
|
||||
if (process.serverConfig.enableIPSpoofing === undefined) process.serverConfig.enableIPSpoofing = false;
|
||||
if (process.serverConfig.secure === undefined) process.serverConfig.secure = false;
|
||||
if (process.serverConfig.disableNonEncryptedServer === undefined) process.serverConfig.disableNonEncryptedServer = false;
|
||||
if (process.serverConfig.disableToHTTPSRedirect === undefined) process.serverConfig.disableToHTTPSRedirect = false;
|
||||
if (process.serverConfig.enableETag === undefined) process.serverConfig.enableETag = true;
|
||||
if (process.serverConfig.disableUnusedWorkerTermination === undefined) process.serverConfig.disableUnusedWorkerTermination = false;
|
||||
if (process.serverConfig.rewriteDirtyURLs === undefined) process.serverConfig.rewriteDirtyURLs = false;
|
||||
if (process.serverConfig.errorPages === undefined) process.serverConfig.errorPages = [];
|
||||
if (process.serverConfig.useWebRootServerSideScript === undefined) process.serverConfig.useWebRootServerSideScript = true;
|
||||
if (process.serverConfig.exposeModsInErrorPages === undefined) process.serverConfig.exposeModsInErrorPages = true;
|
||||
if (process.serverConfig.disableTrailingSlashRedirects === undefined) process.serverConfig.disableTrailingSlashRedirects = false;
|
||||
if (process.serverConfig.environmentVariables === undefined) process.serverConfig.environmentVariables = {};
|
||||
if (process.serverConfig.wwwrootPostfixesVHost === undefined) process.serverConfig.wwwrootPostfixesVHost = [];
|
||||
if (process.serverConfig.wwwrootPostfixPrefixesVHost === undefined) process.serverConfig.wwwrootPostfixPrefixesVHost = [];
|
||||
if (process.serverConfig.allowDoubleSlashes === undefined) process.serverConfig.allowDoubleSlashes = false;
|
||||
if (process.serverConfig.allowPostfixDoubleSlashes === undefined) process.serverConfig.allowPostfixDoubleSlashes = false;
|
||||
if (process.serverConfig.optOutOfStatisticsServer === undefined) process.serverConfig.optOutOfStatisticsServer = false;
|
||||
|
||||
process.serverConfig.version = version; // Compatiblity for very old SVR.JS mods
|
||||
|
||||
const serverconsole = require("./utils/serverconsole.js");
|
||||
|
||||
let inspectorURL = undefined;
|
||||
try {
|
||||
|
@ -39,69 +97,13 @@ if (!process.stdout.isTTY && !inspectorURL) {
|
|||
process.stdout._writev = function () {};
|
||||
}
|
||||
|
||||
let configJSON = {};
|
||||
|
||||
// TODO: configuration from config.json
|
||||
if (configJSON.users === undefined) configJSON.users = [];
|
||||
if (configJSON.secure) {
|
||||
if (configJSON.key === undefined) configJSON.key = "cert/key.key";
|
||||
if (configJSON.cert === undefined) configJSON.cert = "cert/cert.crt";
|
||||
if (configJSON.sport === undefined) configJSON.sport = 443;
|
||||
if (configJSON.spubport === undefined) configJSON.spubport = 443;
|
||||
if (configJSON.sni === undefined) configJSON.sni = {};
|
||||
if (configJSON.enableOCSPStapling === undefined) configJSON.enableOCSPStapling = false;
|
||||
}
|
||||
if (configJSON.port === undefined) configJSON.port = 80;
|
||||
if (configJSON.pubport === undefined) configJSON.pubport = 80;
|
||||
if (configJSON.domain === undefined && configJSON.domian !== undefined) configJSON.domain = configJSON.domian;
|
||||
delete configJSON.domian;
|
||||
if (configJSON.page404 === undefined) configJSON.page404 = "404.html";
|
||||
//configJSON.timestamp = timestamp; //TODO
|
||||
//configJSON.blacklist = blocklist.raw; //TODO
|
||||
if (configJSON.nonStandardCodes === undefined) configJSON.nonStandardCodes = [];
|
||||
if (configJSON.enableCompression === undefined) configJSON.enableCompression = true;
|
||||
if (configJSON.customHeaders === undefined) configJSON.customHeaders = {};
|
||||
if (configJSON.enableHTTP2 === undefined) configJSON.enableHTTP2 = false;
|
||||
if (configJSON.enableLogging === undefined) configJSON.enableLogging = true;
|
||||
if (configJSON.enableDirectoryListing === undefined) configJSON.enableDirectoryListing = true;
|
||||
if (configJSON.enableDirectoryListingWithDefaultHead === undefined) configJSON.enableDirectoryListingWithDefaultHead = false;
|
||||
if (configJSON.serverAdministratorEmail === undefined) configJSON.serverAdministratorEmail = "[no contact information]";
|
||||
if (configJSON.stackHidden === undefined) configJSON.stackHidden = false;
|
||||
if (configJSON.enableRemoteLogBrowsing === undefined) configJSON.enableRemoteLogBrowsing = false;
|
||||
if (configJSON.exposeServerVersion === undefined) configJSON.exposeServerVersion = true;
|
||||
if (configJSON.disableServerSideScriptExpose === undefined) configJSON.disableServerSideScriptExpose = true;
|
||||
if (configJSON.allowStatus === undefined) configJSON.allowStatus = true;
|
||||
if (configJSON.rewriteMap === undefined) configJSON.rewriteMap = [];
|
||||
if (configJSON.dontCompress === undefined) configJSON.dontCompress = ["/.*\\.ipxe$/", "/.*\\.(?:jpe?g|png|bmp|tiff|jfif|gif|webp)$/", "/.*\\.(?:[id]mg|iso|flp)$/", "/.*\\.(?:zip|rar|bz2|[gb7x]z|lzma|tar)$/", "/.*\\.(?:mp[34]|mov|wm[av]|avi|webm|og[gv]|mk[va])$/"];
|
||||
if (configJSON.enableIPSpoofing === undefined) configJSON.enableIPSpoofing = false;
|
||||
if (configJSON.secure === undefined) configJSON.secure = false;
|
||||
if (configJSON.disableNonEncryptedServer === undefined) configJSON.disableNonEncryptedServer = false;
|
||||
if (configJSON.disableToHTTPSRedirect === undefined) configJSON.disableToHTTPSRedirect = false;
|
||||
if (configJSON.enableETag === undefined) configJSON.enableETag = true;
|
||||
if (configJSON.disableUnusedWorkerTermination === undefined) configJSON.disableUnusedWorkerTermination = false;
|
||||
if (configJSON.rewriteDirtyURLs === undefined) configJSON.rewriteDirtyURLs = false;
|
||||
if (configJSON.errorPages === undefined) configJSON.errorPages = [];
|
||||
if (configJSON.useWebRootServerSideScript === undefined) configJSON.useWebRootServerSideScript = true;
|
||||
if (configJSON.exposeModsInErrorPages === undefined) configJSON.exposeModsInErrorPages = true;
|
||||
if (configJSON.disableTrailingSlashRedirects === undefined) configJSON.disableTrailingSlashRedirects = false;
|
||||
if (configJSON.environmentVariables === undefined) configJSON.environmentVariables = {};
|
||||
if (configJSON.wwwrootPostfixesVHost === undefined) configJSON.wwwrootPostfixesVHost = [];
|
||||
if (configJSON.wwwrootPostfixPrefixesVHost === undefined) configJSON.wwwrootPostfixPrefixesVHost = [];
|
||||
if (configJSON.allowDoubleSlashes === undefined) configJSON.allowDoubleSlashes = false;
|
||||
if (configJSON.allowPostfixDoubleSlashes === undefined) configJSON.allowPostfixDoubleSlashes = false;
|
||||
if (configJSON.optOutOfStatisticsServer === undefined) configJSON.optOutOfStatisticsServer = false;
|
||||
|
||||
configJSON.version = version; // Compatiblity for very old SVR.JS mods
|
||||
|
||||
var wwwrootError = null;
|
||||
try {
|
||||
if (cluster.isPrimary || cluster.isPrimary === undefined) process.chdir(configJSON.wwwroot != undefined ? configJSON.wwwroot : __dirname);
|
||||
if (cluster.isPrimary || cluster.isPrimary === undefined) process.chdir(process.serverConfig.wwwroot != undefined ? process.serverConfig.wwwroot : __dirname);
|
||||
} catch (err) {
|
||||
wwwrootError = err;
|
||||
}
|
||||
|
||||
const serverconsole = serverconsoleConstructor(configJSON.enableLogging);
|
||||
|
||||
let middleware = [
|
||||
require("./middleware/core.js"),
|
||||
require("./middleware/urlSanitizer.js"),
|
||||
|
@ -131,7 +133,7 @@ function requestHandler(req, res) {
|
|||
};
|
||||
|
||||
// SVR.JS configuration object (modified)
|
||||
const config = Object.assign(configJSON);
|
||||
const config = Object.assign(process.serverConfig);
|
||||
|
||||
let index = 0;
|
||||
|
||||
|
@ -148,7 +150,7 @@ function requestHandler(req, res) {
|
|||
logFacilities.errmessage("Stack:");
|
||||
logFacilities.errmessage(err.stack);
|
||||
res.writeHead(500, "Internal Server Error", {
|
||||
Server: (config.exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS")
|
||||
Server: generateServerString(config.exposeServerVersion)
|
||||
});
|
||||
res.end("Error while executing the request handler");
|
||||
}
|
||||
|
@ -157,7 +159,7 @@ function requestHandler(req, res) {
|
|||
if (res.error) res.error(404);
|
||||
else {
|
||||
res.writeHead(404, "Not Found", {
|
||||
Server: (config.exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS")
|
||||
Server: generateServerString(config.exposeServerVersion)
|
||||
});
|
||||
res.end("Request handler missing");
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ const http = require("http");
|
|||
const fs = require("fs");
|
||||
const net = require("net");
|
||||
const generateErrorStack = require("../utils/generateErrorStack.js");
|
||||
const generateServerString = require("../utils/generateServerString.js");
|
||||
const serverHTTPErrorDescs = require("../res/httpErrorDescriptions.js");
|
||||
const fixNodeMojibakeURL = require("../utils/urlMojibakeFixer.js");
|
||||
const getOS = require("../utils/getOS.js");
|
||||
const ipMatch = require("../utils/ipMatch.js");
|
||||
const svrjsInfo = require("../../svrjs.json");
|
||||
const version = svrjsInfo.version;
|
||||
|
@ -37,6 +37,11 @@ module.exports = (req, res, logFacilities, config, next) => {
|
|||
return false;
|
||||
};
|
||||
|
||||
config.generateServerString = () => {
|
||||
return generateServerString(config.exposeServerVersion);
|
||||
};
|
||||
|
||||
// getCustomHeaders() in SVR.JS 3.x
|
||||
config.getCustomHeaders = () => {
|
||||
let ph = Object.assign(config.customHeaders);
|
||||
if (config.customHeadersVHost) {
|
||||
|
@ -63,17 +68,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
|||
if (typeof ph[phk] == "string")
|
||||
ph[phk] = ph[phk].replace(/\{path\}/g, req.url);
|
||||
});
|
||||
ph["Server"] = config.exposeServerVersion
|
||||
? "SVR.JS/" +
|
||||
version +
|
||||
" (" +
|
||||
getOS() +
|
||||
"; " +
|
||||
(process.isBun
|
||||
? "Bun/v" + process.versions.bun + "; like Node.JS/" + process.version
|
||||
: "Node.JS/" + process.version) +
|
||||
")"
|
||||
: "SVR.JS";
|
||||
ph["Server"] = config.generateServerString();
|
||||
return ph;
|
||||
};
|
||||
|
||||
|
@ -588,20 +583,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
|||
/{server}/g,
|
||||
"" +
|
||||
(
|
||||
(config.exposeServerVersion
|
||||
? "SVR.JS/" +
|
||||
version +
|
||||
" (" +
|
||||
getOS() +
|
||||
"; " +
|
||||
(process.isBun
|
||||
? "Bun/v" +
|
||||
process.versions.bun +
|
||||
"; like Node.JS/" +
|
||||
process.version
|
||||
: "Node.JS/" + process.version) +
|
||||
")"
|
||||
: "SVR.JS") +
|
||||
config.generateServerString() +
|
||||
(!config.exposeModsInErrorPages || extName == undefined
|
||||
? ""
|
||||
: " " + extName)
|
||||
|
|
|
@ -3,228 +3,231 @@ const os = require("os");
|
|||
const path = require("path");
|
||||
|
||||
let cluster = {};
|
||||
try {
|
||||
// Import cluster module
|
||||
cluster = require("cluster");
|
||||
} catch (err) {
|
||||
// Clustering is not supported!
|
||||
}
|
||||
|
||||
// Cluster & IPC shim for Bun
|
||||
if (!process.singleThreaded) {
|
||||
try {
|
||||
// Import cluster module
|
||||
cluster = require("cluster");
|
||||
} catch (err) {
|
||||
// Clustering is not supported!
|
||||
}
|
||||
|
||||
cluster.bunShim = function () {
|
||||
cluster.isMaster = !process.env.NODE_UNIQUE_ID;
|
||||
cluster.isPrimary = cluster.isMaster;
|
||||
cluster.isWorker = !cluster.isMaster;
|
||||
cluster.__shimmed__ = true;
|
||||
// Cluster & IPC shim for Bun
|
||||
|
||||
if (cluster.isWorker) {
|
||||
// Shim the cluster.worker object for worker processes
|
||||
cluster.worker = {
|
||||
id: parseInt(process.env.NODE_UNIQUE_ID),
|
||||
process: process,
|
||||
isDead: function () {
|
||||
return false;
|
||||
},
|
||||
send: function (message, b, c, d) {
|
||||
process.send(message, b, c, d);
|
||||
},
|
||||
};
|
||||
cluster.bunShim = function () {
|
||||
cluster.isMaster = !process.env.NODE_UNIQUE_ID;
|
||||
cluster.isPrimary = cluster.isMaster;
|
||||
cluster.isWorker = !cluster.isMaster;
|
||||
cluster.__shimmed__ = true;
|
||||
|
||||
if (!process.send) {
|
||||
// Shim the process.send function for worker processes
|
||||
if (cluster.isWorker) {
|
||||
// Shim the cluster.worker object for worker processes
|
||||
cluster.worker = {
|
||||
id: parseInt(process.env.NODE_UNIQUE_ID),
|
||||
process: process,
|
||||
isDead: function () {
|
||||
return false;
|
||||
},
|
||||
send: function (message, b, c, d) {
|
||||
process.send(message, b, c, d);
|
||||
},
|
||||
};
|
||||
|
||||
// Create a fake IPC server to receive messages
|
||||
let fakeIPCServer = net.createServer(function (socket) {
|
||||
let receivedData = "";
|
||||
if (!process.send) {
|
||||
// Shim the process.send function for worker processes
|
||||
|
||||
socket.on("data", function (data) {
|
||||
receivedData += data.toString();
|
||||
// Create a fake IPC server to receive messages
|
||||
let fakeIPCServer = net.createServer(function (socket) {
|
||||
let receivedData = "";
|
||||
|
||||
socket.on("data", function (data) {
|
||||
receivedData += data.toString();
|
||||
});
|
||||
|
||||
socket.on("end", function () {
|
||||
process.emit("message", receivedData);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on("end", function () {
|
||||
process.emit("message", receivedData);
|
||||
});
|
||||
});
|
||||
fakeIPCServer.listen(
|
||||
os.platform() === "win32"
|
||||
? path.join(
|
||||
"\\\\?\\pipe",
|
||||
__dirname,
|
||||
"temp/.W" + process.pid + ".ipc",
|
||||
)
|
||||
: __dirname + "/temp/.W" + process.pid + ".ipc",
|
||||
);
|
||||
|
||||
process.send = function (message) {
|
||||
// Create a fake IPC connection to send messages
|
||||
let fakeIPCConnection = net.createConnection(
|
||||
fakeIPCServer.listen(
|
||||
os.platform() === "win32"
|
||||
? path.join(
|
||||
"\\\\?\\pipe",
|
||||
__dirname,
|
||||
"temp/.P" + process.pid + ".ipc",
|
||||
"temp/.W" + process.pid + ".ipc",
|
||||
)
|
||||
: __dirname + "/temp/.P" + process.pid + ".ipc",
|
||||
function () {
|
||||
fakeIPCConnection.end(message);
|
||||
},
|
||||
: __dirname + "/temp/.W" + process.pid + ".ipc",
|
||||
);
|
||||
};
|
||||
|
||||
process.removeFakeIPC = function () {
|
||||
// Close IPC server
|
||||
process.send = function () {};
|
||||
fakeIPCServer.close();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Custom implementation for cluster.fork()
|
||||
cluster._workersCounter = 1;
|
||||
cluster.workers = {};
|
||||
cluster.fork = function (env) {
|
||||
const child_process = require("child_process");
|
||||
let newEnvironment = Object.assign(env ? env : process.env);
|
||||
newEnvironment.NODE_UNIQUE_ID = cluster._workersCounter;
|
||||
let newArguments = Object.assign(process.argv);
|
||||
let command = newArguments.shift();
|
||||
let newWorker = child_process.spawn(command, newArguments, {
|
||||
env: newEnvironment,
|
||||
stdio: ["inherit", "inherit", "inherit", "ipc"],
|
||||
});
|
||||
|
||||
newWorker.process = newWorker;
|
||||
newWorker.isDead = function () {
|
||||
return newWorker.exitCode !== null || newWorker.killed;
|
||||
};
|
||||
newWorker.id = newEnvironment.NODE_UNIQUE_ID;
|
||||
|
||||
function checkSendImplementation(worker) {
|
||||
let sendImplemented = true;
|
||||
|
||||
if (
|
||||
!(
|
||||
process.versions &&
|
||||
process.versions.bun &&
|
||||
process.versions.bun[0] != "0"
|
||||
)
|
||||
) {
|
||||
if (!worker.send) {
|
||||
sendImplemented = false;
|
||||
}
|
||||
|
||||
let oldLog = console.log;
|
||||
console.log = function (a, b, c, d, e, f) {
|
||||
if (
|
||||
a == "ChildProcess.prototype.send() - Sorry! Not implemented yet"
|
||||
) {
|
||||
throw new Error("NOT IMPLEMENTED");
|
||||
} else {
|
||||
oldLog(a, b, c, d, e, f);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
worker.send(undefined);
|
||||
} catch (err) {
|
||||
if (err.message === "NOT IMPLEMENTED") {
|
||||
sendImplemented = false;
|
||||
}
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
console.log = oldLog;
|
||||
}
|
||||
|
||||
return sendImplemented;
|
||||
}
|
||||
|
||||
if (!checkSendImplementation(newWorker)) {
|
||||
// Create a fake IPC server for worker process to receive messages
|
||||
let fakeWorkerIPCServer = net.createServer(function (socket) {
|
||||
let receivedData = "";
|
||||
|
||||
socket.on("data", function (data) {
|
||||
receivedData += data.toString();
|
||||
});
|
||||
|
||||
socket.on("end", function () {
|
||||
newWorker.emit("message", receivedData);
|
||||
});
|
||||
});
|
||||
fakeWorkerIPCServer.listen(
|
||||
os.platform() === "win32"
|
||||
? path.join(
|
||||
"\\\\?\\pipe",
|
||||
__dirname,
|
||||
"temp/.P" + newWorker.process.pid + ".ipc",
|
||||
)
|
||||
: __dirname + "/temp/.P" + newWorker.process.pid + ".ipc",
|
||||
);
|
||||
|
||||
// Cleanup when worker process exits
|
||||
newWorker.on("exit", function () {
|
||||
fakeWorkerIPCServer.close();
|
||||
delete cluster.workers[newWorker.id];
|
||||
});
|
||||
|
||||
newWorker.send = function (
|
||||
message,
|
||||
fakeParam2,
|
||||
fakeParam3,
|
||||
fakeParam4,
|
||||
tries,
|
||||
) {
|
||||
if (!tries) tries = 0;
|
||||
|
||||
try {
|
||||
// Create a fake IPC connection to send messages to worker process
|
||||
let fakeWorkerIPCConnection = net.createConnection(
|
||||
process.send = function (message) {
|
||||
// Create a fake IPC connection to send messages
|
||||
let fakeIPCConnection = net.createConnection(
|
||||
os.platform() === "win32"
|
||||
? path.join(
|
||||
"\\\\?\\pipe",
|
||||
__dirname,
|
||||
"temp/.W" + newWorker.process.pid + ".ipc",
|
||||
"temp/.P" + process.pid + ".ipc",
|
||||
)
|
||||
: __dirname + "/temp/.W" + newWorker.process.pid + ".ipc",
|
||||
: __dirname + "/temp/.P" + process.pid + ".ipc",
|
||||
function () {
|
||||
fakeWorkerIPCConnection.end(message);
|
||||
fakeIPCConnection.end(message);
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
if (tries > 50) throw err;
|
||||
newWorker.send(
|
||||
message,
|
||||
fakeParam2,
|
||||
fakeParam3,
|
||||
fakeParam4,
|
||||
tries + 1,
|
||||
);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
newWorker.on("exit", function () {
|
||||
delete cluster.workers[newWorker.id];
|
||||
});
|
||||
};
|
||||
|
||||
process.removeFakeIPC = function () {
|
||||
// Close IPC server
|
||||
process.send = function () {};
|
||||
fakeIPCServer.close();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cluster.workers[newWorker.id] = newWorker;
|
||||
cluster._workersCounter++;
|
||||
return newWorker;
|
||||
};
|
||||
};
|
||||
// Custom implementation for cluster.fork()
|
||||
cluster._workersCounter = 1;
|
||||
cluster.workers = {};
|
||||
cluster.fork = function (env) {
|
||||
const child_process = require("child_process");
|
||||
let newEnvironment = Object.assign(env ? env : process.env);
|
||||
newEnvironment.NODE_UNIQUE_ID = cluster._workersCounter;
|
||||
let newArguments = Object.assign(process.argv);
|
||||
let command = newArguments.shift();
|
||||
let newWorker = child_process.spawn(command, newArguments, {
|
||||
env: newEnvironment,
|
||||
stdio: ["inherit", "inherit", "inherit", "ipc"],
|
||||
});
|
||||
|
||||
if (
|
||||
process.isBun &&
|
||||
(cluster.isMaster === undefined ||
|
||||
(cluster.isMaster && process.env.NODE_UNIQUE_ID))
|
||||
) {
|
||||
cluster.bunShim();
|
||||
newWorker.process = newWorker;
|
||||
newWorker.isDead = function () {
|
||||
return newWorker.exitCode !== null || newWorker.killed;
|
||||
};
|
||||
newWorker.id = newEnvironment.NODE_UNIQUE_ID;
|
||||
|
||||
function checkSendImplementation(worker) {
|
||||
let sendImplemented = true;
|
||||
|
||||
if (
|
||||
!(
|
||||
process.versions &&
|
||||
process.versions.bun &&
|
||||
process.versions.bun[0] != "0"
|
||||
)
|
||||
) {
|
||||
if (!worker.send) {
|
||||
sendImplemented = false;
|
||||
}
|
||||
|
||||
let oldLog = console.log;
|
||||
console.log = function (a, b, c, d, e, f) {
|
||||
if (
|
||||
a == "ChildProcess.prototype.send() - Sorry! Not implemented yet"
|
||||
) {
|
||||
throw new Error("NOT IMPLEMENTED");
|
||||
} else {
|
||||
oldLog(a, b, c, d, e, f);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
worker.send(undefined);
|
||||
} catch (err) {
|
||||
if (err.message === "NOT IMPLEMENTED") {
|
||||
sendImplemented = false;
|
||||
}
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
console.log = oldLog;
|
||||
}
|
||||
|
||||
return sendImplemented;
|
||||
}
|
||||
|
||||
if (!checkSendImplementation(newWorker)) {
|
||||
// Create a fake IPC server for worker process to receive messages
|
||||
let fakeWorkerIPCServer = net.createServer(function (socket) {
|
||||
let receivedData = "";
|
||||
|
||||
socket.on("data", function (data) {
|
||||
receivedData += data.toString();
|
||||
});
|
||||
|
||||
socket.on("end", function () {
|
||||
newWorker.emit("message", receivedData);
|
||||
});
|
||||
});
|
||||
fakeWorkerIPCServer.listen(
|
||||
os.platform() === "win32"
|
||||
? path.join(
|
||||
"\\\\?\\pipe",
|
||||
__dirname,
|
||||
"temp/.P" + newWorker.process.pid + ".ipc",
|
||||
)
|
||||
: __dirname + "/temp/.P" + newWorker.process.pid + ".ipc",
|
||||
);
|
||||
|
||||
// Cleanup when worker process exits
|
||||
newWorker.on("exit", function () {
|
||||
fakeWorkerIPCServer.close();
|
||||
delete cluster.workers[newWorker.id];
|
||||
});
|
||||
|
||||
newWorker.send = function (
|
||||
message,
|
||||
fakeParam2,
|
||||
fakeParam3,
|
||||
fakeParam4,
|
||||
tries,
|
||||
) {
|
||||
if (!tries) tries = 0;
|
||||
|
||||
try {
|
||||
// Create a fake IPC connection to send messages to worker process
|
||||
let fakeWorkerIPCConnection = net.createConnection(
|
||||
os.platform() === "win32"
|
||||
? path.join(
|
||||
"\\\\?\\pipe",
|
||||
__dirname,
|
||||
"temp/.W" + newWorker.process.pid + ".ipc",
|
||||
)
|
||||
: __dirname + "/temp/.W" + newWorker.process.pid + ".ipc",
|
||||
function () {
|
||||
fakeWorkerIPCConnection.end(message);
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
if (tries > 50) throw err;
|
||||
newWorker.send(
|
||||
message,
|
||||
fakeParam2,
|
||||
fakeParam3,
|
||||
fakeParam4,
|
||||
tries + 1,
|
||||
);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
newWorker.on("exit", function () {
|
||||
delete cluster.workers[newWorker.id];
|
||||
});
|
||||
}
|
||||
|
||||
cluster.workers[newWorker.id] = newWorker;
|
||||
cluster._workersCounter++;
|
||||
return newWorker;
|
||||
};
|
||||
};
|
||||
|
||||
if (
|
||||
process.isBun &&
|
||||
(cluster.isMaster === undefined ||
|
||||
(cluster.isMaster && process.env.NODE_UNIQUE_ID))
|
||||
) {
|
||||
cluster.bunShim();
|
||||
}
|
||||
|
||||
// Shim cluster.isPrimary field
|
||||
if (cluster.isPrimary === undefined && cluster.isMaster !== undefined)
|
||||
cluster.isPrimary = cluster.isMaster;
|
||||
}
|
||||
|
||||
// Shim cluster.isPrimary field
|
||||
if (cluster.isPrimary === undefined && cluster.isMaster !== undefined)
|
||||
cluster.isPrimary = cluster.isMaster;
|
||||
|
||||
module.exports = cluster;
|
||||
|
|
20
src/utils/generateServerString.js
Normal file
20
src/utils/generateServerString.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
const svrjsInfo = require("../../svrjs.json");
|
||||
const {version, name} = svrjsInfo;
|
||||
const getOS = require("./getOS.js");
|
||||
|
||||
function generateServerString(exposeServerVersion) {
|
||||
return exposeServerVersion
|
||||
? name +
|
||||
"/" +
|
||||
version +
|
||||
" (" +
|
||||
getOS() +
|
||||
"; " +
|
||||
(process.isBun
|
||||
? "Bun/v" + process.versions.bun + "; like Node.JS/" + process.version
|
||||
: "Node.JS/" + process.version) +
|
||||
")"
|
||||
: name;
|
||||
}
|
||||
|
||||
module.exports = generateServerString;
|
|
@ -1,6 +1,6 @@
|
|||
const fs = require("fs");
|
||||
|
||||
let enableLoggingIntoFile = false;
|
||||
let enableLoggingIntoFile = process.serverConfig.enableLogging;
|
||||
let logFile = undefined;
|
||||
let logSync = false;
|
||||
let cluster = require("./clusterBunShim.js");
|
||||
|
@ -271,7 +271,4 @@ process.exit = function (code) {
|
|||
}
|
||||
};
|
||||
|
||||
module.exports = (enableLoggingIntoFileParam) => {
|
||||
enableLoggingIntoFile = enableLoggingIntoFileParam;
|
||||
return serverconsole;
|
||||
};
|
||||
module.exports = serverconsole;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
{
|
||||
"version": "Nightly-GitMain"
|
||||
"version": "Nightly-GitNext",
|
||||
"name": "SVR.JS",
|
||||
"documentationURL": "https://svrjs.org/docs"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<h1>Welcome to SVR.JS <%= version %></h1>
|
||||
<h1>Welcome to <%= name %> <%= version %></h1>
|
||||
<% if (version.indexOf("Nightly-") == 0) { %>
|
||||
<div style="background-color: #ffff00; color: #000000; border-color: #ff7f00; border-width: 5px; border-style: solid; padding: 5px; display: inline-block;">
|
||||
<b style="font-size: 26px">WARNING!</b><br />
|
||||
|
@ -82,8 +82,8 @@
|
|||
<p>
|
||||
<a href="/tests.html">Tests</a><br />
|
||||
<a href="/licenses/">Licenses</a><br />
|
||||
<a href="/svrjsstatus.svr">SVR.JS status page</a><br />
|
||||
<a href="https://svrjs.org/docs">SVR.JS documentation</a>
|
||||
<a href="/svrjsstatus.svr"><%= name %> status page</a><br />
|
||||
<a href="<%= documentationURL %>"><%= name %> documentation</a>
|
||||
</p>
|
||||
<img src="/powered.png" />
|
||||
</body>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
|
||||
<div style="float: right;">License: <%= license %></div>
|
||||
<div style="font-size: 20px;">
|
||||
<b><%= name %></b><% if (author) { %> (by <%= author %>)<% } %>
|
||||
<b><%= moduleName %></b><% if (author) { %> (by <%= author %>)<% } %>
|
||||
</div>
|
||||
<div style="font-size: 12px;">
|
||||
<%= description %><% if (required) { %><br/>
|
||||
<b>Required by SVR.JS.</b><% } %>
|
||||
<b>Required by <%= name %>.</b><% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<h1>SVR.JS <%= version %> Licenses</h1>
|
||||
<h2>SVR.JS <%= version %></h2>
|
||||
<h1><%= name %> <%= version %> Licenses</h1>
|
||||
<h2><%= name %> <%= version %></h2>
|
||||
<div style="display: inline-block; text-align: left; border-width: 2px; border-style: solid; border-color: gray; padding: 8px;">
|
||||
MIT License<br/>
|
||||
<br/>
|
||||
|
@ -23,7 +23,7 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br/>
|
||||
SOFTWARE.<br/>
|
||||
</div>
|
||||
<h2>Packages used by SVR.JS <%= version %></h2>
|
||||
<h2>Packages used by <%= name %> <%= version %></h2>
|
||||
<div style="width: 100%; max-width: 1280px; margin: auto">
|
||||
<%- licenses %>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<h1>SVR.JS <%= version %> Tests</h1>
|
||||
<h1><%= name %> <%= version %> Tests</h1>
|
||||
<h2>Directory (without trailing slash)</h2>
|
||||
<iframe src="/testdir" width="75%" height="300px"></iframe>
|
||||
<h2>Directory (with query)</h2>
|
||||
|
|
Loading…
Reference in a new issue