From 3a94acf27ea1eff8bd1125450f07c0c366332e80 Mon Sep 17 00:00:00 2001 From: Minteck Date: Sun, 17 Oct 2021 20:08:04 +0200 Subject: Initial commit --- server/check.js | 34 +++++ server/commands.js | 32 +++++ server/core.js | 32 +++++ server/frhtml.js | 222 +++++++++++++++++++++++++++++++ server/http.js | 380 +++++++++++++++++++++++++++++++++++++++++++++++++++++ server/log.js | 33 +++++ server/version.js | 5 + 7 files changed, 738 insertions(+) create mode 100644 server/check.js create mode 100644 server/commands.js create mode 100644 server/core.js create mode 100644 server/frhtml.js create mode 100644 server/http.js create mode 100644 server/log.js create mode 100644 server/version.js (limited to 'server') diff --git a/server/check.js b/server/check.js new file mode 100644 index 0000000..0acd1c1 --- /dev/null +++ b/server/check.js @@ -0,0 +1,34 @@ +module.exports.check = function () { + log.verbose("Check init") + var net = require('net'); + log.verbose("Net rq init ok") + var server = net.createServer(); + log.verbose("net.createServer ok") + + server.once('error', function(err) { + log.verbose("err: " + err.code) + if (err.code === 'EADDRINUSE') { + log.error("Port is busy, aborting.") + } else { + log.error("Cannot open port.") + } + }); + + server.once('listening', function() { + log.verbose("listening ok") + log.info("Port is available") + log.verbose("server close ok") + server.close(); + server = undefined; + log.verbose("http init start") + log.info("Initialising HTTP module...") + global.ws = require('./http.js') + log.verbose("http init stop") + ws.start() + log.verbose("server start") + }); + + log.verbose("all ok") + server.listen(config.port); + log.verbose("listen ok") +} \ No newline at end of file diff --git a/server/commands.js b/server/commands.js new file mode 100644 index 0000000..d5ed2e8 --- /dev/null +++ b/server/commands.js @@ -0,0 +1,32 @@ +module.exports = (config, callback) => { + log.verbose("start command") + global.commandDone = false; + const exec = require('child_process').exec; + exec(config.command, (err, stdout, stderr) => { + if (err) { + log.warn("Command plugin error: " + err.toString()); + global.commandReturnOutput = { + error: true, + errorMessage: err.toString(), + verbose: { + stdout: stdout, + stderr: stderr + } + } + global.commandDone = true; + callback(); + } else { + log.info("Command plugin successfully terminated"); + global.commandReturnOutput = { + error: false, + errorMessage: null, + verbose: { + stdout: stdout, + stderr: stderr + } + } + global.commandDone = true; + callback(commandReturnOutput); + } + }); +} \ No newline at end of file diff --git a/server/core.js b/server/core.js new file mode 100644 index 0000000..c166e3a --- /dev/null +++ b/server/core.js @@ -0,0 +1,32 @@ +global.mpws = require('./version'); + +global.log = require('./log') +global.fs = require('fs') +log.info("Reading configuration...") +global.config = require('../global/config.json') +log.info("Checking configuration integrity...") +log.verbose("Checking 'port'") +if (isNaN(config.port)) { + log.error("'port' is invalid") +} +log.verbose("Checking 'document_root'") +if (typeof config.document_root == 'string') { + log.info("Loading storage module...") + if (config.document_root.startsWith(".")) { + global.wwwdata = __dirname + "/../" + config.document_root + global.private = __dirname + "/../" + config.document_root + "/../private"; + } else { + global.wwwdata = config.document_root + global.private = config.document_root + "/../private"; + } + if (fs.existsSync(wwwdata)) { + log.info("Will start Satellite at " + wwwdata) + log.info("Checking for port availability...") + log.verbose("Running server/check.js/check") + require('./check.js').check() + } else { + log.error("'document_root' cannot be found") + } +} else { + log.error("'document_root' is invalid") +} \ No newline at end of file diff --git a/server/frhtml.js b/server/frhtml.js new file mode 100644 index 0000000..3825a01 --- /dev/null +++ b/server/frhtml.js @@ -0,0 +1,222 @@ +String.prototype.replacei = function (search, replace) { + var regex = new RegExp(search, "ig"); + return this.replace(regex, replace); +} + +module.exports.ConvertirVersHTML = function (contenu) { + + // Définition des/du type(s) + contenu = contenu.replacei('TYPEDOCUMENT','DOCTYPE') + + // Définition du balisage HTML + contenu = contenu.replacei('','
') + contenu = contenu.replacei('','
') + + // Containeurs + contenu = contenu.replacei('','
') + contenu = contenu.replacei('
','') + contenu = contenu.replacei(' + + + + + Mon site Web + + Ceci est mon site Web + C'est un super site Web que j'ai fait tout seul + + + Il utilise le machin que j'ai découvert qui nous permet de programmer en français + + + +` \ No newline at end of file diff --git a/server/http.js b/server/http.js new file mode 100644 index 0000000..4d67836 --- /dev/null +++ b/server/http.js @@ -0,0 +1,380 @@ +global.fs = require('fs') +global.os = require('os') +global.mime = require('node-mime'); +global.dirconf = null; + +module.exports.start = function () { + String.prototype.replacei = function (search, replace) { + var regex = new RegExp(search, "ig"); + return this.replace(regex, replace); + } + + global.http = require('http'); + + http.createServer(function (req, res) { + global.res = res; + req.url_orig = req.url; + log.verbose("request: " + req.connection.remoteAddress + "; " + req.url) + + if (req.url.startsWith("/@info")) { + log.verbose("return info"); + file = wwwdata + req.url.slice(6); + + json = new Object + json.file = req.url.slice(6) + if (fs.existsSync(file)) { + if (fs.lstatSync(file).isDirectory()) { + json.type = "inode/directory" + json.size = null + json.inode = null + json.device = null + json.mode = null + } else { + json.type = mime.lookUpType(file.split(".").pop()); + // json.type = file.split(".").pop(); + json.size = fs.lstatSync(file).size + json.inode = fs.lstatSync(file).ino + json.device = fs.lstatSync(file).dev + json.mode = fs.lstatSync(file).mode + } + } else { + if (json.file.startsWith("/debug")) { + json.type = "mpws-special/debuginfo"; + json.size = null + json.inode = null + json.device = null + json.mode = null + } else if (json.file.startsWith("/@info")) { + json.type = "mpws-special/fileinfo"; + json.size = null + json.inode = null + json.device = null + json.mode = null + } else if (json.file.startsWith("/@json")) { + json.type = "mpws-special/fileapi"; + json.size = null + json.inode = null + json.device = null + json.mode = null + } else { + json.type = "error/notfound"; + json.size = null + json.inode = null + json.device = null + json.mode = null + } + } + + res.writeHead(200, {'Content-Type': 'application/json'}); + res.write(JSON.stringify(json)); + res.end() + return; + } + + if (req.url.startsWith("/@json")) { + log.verbose("return json"); + file = wwwdata + req.url.slice(6); + + json = new Object + json.file = req.url.slice(6) + if (fs.existsSync(file)) { + if (fs.lstatSync(file).isDirectory()) { + json.type = "inode/directory" + json.size = null + json.inode = null + json.device = null + json.mode = null + json.lines = null + } else { + json.type = mime.lookUpType(file.split(".").pop()); + json.size = fs.lstatSync(file).size + json.inode = fs.lstatSync(file).ino + json.device = fs.lstatSync(file).dev + json.mode = fs.lstatSync(file).mode + json.lines = fs.readFileSync(file).toString().split("\n"); + } + } else { + if (json.file.startsWith("/debug")) { + json.type = "mpws-special/debuginfo"; + json.size = null + json.inode = null + json.device = null + json.mode = null + json.lines = null + } else if (json.file.startsWith("/@info")) { + json.type = "mpws-special/fileinfo"; + json.size = null + json.inode = null + json.device = null + json.mode = null + json.lines = null + } else if (json.file.startsWith("/@json")) { + json.type = "mpws-special/fileapi"; + json.size = null + json.inode = null + json.device = null + json.mode = null + json.lines = null + } else { + json.type = "error/notfound"; + json.size = null + json.inode = null + json.device = null + json.mode = null + json.lines = null + } + } + + res.writeHead(200, {'Content-Type': 'application/json'}); + res.write(JSON.stringify(json)); + res.end() + return; + } + + if (req.url == "/debug") { + log.verbose("return debug") + res.writeHead(200, {'Content-Type': 'application/json'}); + var date = new Date(); + var hour = date.getHours(); + // hour = (hour < 10 ? "0" : "") + hour; + var min = date.getMinutes(); + // min = (min < 10 ? "0" : "") + min; + var sec = date.getSeconds(); + // sec = (sec < 10 ? "0" : "") + sec; + var year = date.getFullYear(); + var month = date.getMonth() + 1; + // month = (month < 10 ? "0" : "") + month; + var day = date.getDate(); + // day = (day < 10 ? "0" : "") + day; + debug = { + "version": { + "server": mpws.version, + "kernel": process.version.replace("v", "") + }, + "date": { + "day": day, + "month": month, + "year": year, + "hour": hour, + "min": min, + "sec": sec + }, + "server": { + "process": { + "pid": process.pid, + "name": process.title, + "priority": os.getPriority(process.pid) + }, + "software": { + "hostname": os.hostname(), + "arch": os.arch(), + "platform": os.platform(), + "release": os.release(), + "type": os.type(), + "uptime": os.uptime(), + "tempfiles": os.tmpdir() + }, + "hardware": { + "cpus": os.cpus(), + "network": os.networkInterfaces(), + "memory": { + "total": os.totalmem(), + "free": os.freemem(), + "used": os.totalmem() - os.freemem(), + "process": process.memoryUsage() + } + } + } + } + res.write(JSON.stringify(debug)); + res.end(); + return; + } + // res.writeHead(200, {'Content-Type': 'text/html'}); + // res.write('Node.js says hello!'); + // res.end(); + frhtml = false; + ejs = false; + if (req.url.includes(".")) { + } else { + if (fs.existsSync(wwwdata + req.url + "/index.html")) { + req.url = req.url + "/index.html" + } else if (fs.existsSync(wwwdata + req.url + "/index.fr.html")) { + req.url = req.url + "/index.fr.html" + frhtml = true; + } else { + req.url = req.url + "/index.ejs" + ejs = true; + } + } + if (req.url.endsWith('.fr.html')) { + frhtml = true; + } + if (req.url.includes("..")) { + if (config.errors_show_trace) { + trace = "
Satellite Server - System Backtrace

Server Backtrace:
401F0000 PERMISSION_DENIED
00000001 SERVER_RUNTIME
0000001A HTTP_WEBSERVER

Kernel Backtrace:
" + } else { + trace = ""; + } + log.verbose("return 401") + res.writeHead(401, {'Content-Type': 'text/html'}); + res.write("Satellite Fatal Error

Internal Server Error

Minteck Satellite Server returned an error while trying to request your file.

0x401: Forbidden
" + req.url + "

Minteck Satellite Server " + mpws.version + ", kernel " + process.version + "" + trace + ""); + res.end(); + return; + } + global.dirconf = null; + if (fs.existsSync(wwwdata + req.url.substring(0, req.url.indexOf('/')) + "/" + config.access)) { + log.verbose('reading ' + config.access + ' file...') + try { + if (require.cache[require.resolve(wwwdata + req.url.substring(0, req.url.indexOf('/')) + "/" + config.access)]) { + delete require.cache[require.resolve(wwwdata + req.url.substring(0, req.url.indexOf('/')) + "/" + config.access)] + } + global.dirconf = require(wwwdata + req.url.substring(0, req.url.indexOf('/')) + "/" + config.access) + } catch (err) { + global.dirconf = null; + if (config.errors_show_trace) { + trace = "
Satellite Server - System Backtrace

Server Backtrace:
50A00000 INVALID_DIR_CONF
00000001 SERVER_RUNTIME
0000001A HTTP_WEBSERVER

Kernel Backtrace:
" + err.toString().replace('\n', '
') + "
" + } else { + trace = ""; + } + log.verbose("return 500") + res.writeHead(500, {'Content-Type': 'text/html'}); + res.write("Satellite Fatal Error

Internal Server Error

Minteck Satellite Server returned an error while trying to request your file.

0x50A: Invalid Directory Configuration
" + req.url + "

Minteck Satellite Server " + mpws.version + ", kernel " + process.version + "" + trace + ""); + res.end(); + return; + } + if (dirconf == null) { + } else { + if (typeof (dirconf.access) != "undefined") { + if (typeof (dirconf.access) == "boolean") { + if (dirconf.access == false) { + if (config.errors_show_trace) { + trace = "
Satellite Server - System Backtrace

Server Backtrace:
401F0000 PERMISSION_DENIED
00000001 SERVER_RUNTIME
0000001A HTTP_WEBSERVER

Kernel Backtrace:
" + } else { + trace = ""; + } + log.verbose("return 401") + res.writeHead(500, {'Content-Type': 'text/html'}); + res.write("Satellite Fatal Error

Internal Server Error

Minteck Satellite Server returned an error while trying to request your file.

0x401: Forbidden
" + req.url + "

Minteck Satellite Server " + mpws.version + ", kernel " + process.version + "" + trace + ""); + res.end(); + return; + } + } + } + } + } + if (fs.existsSync(wwwdata + req.url) || fs.existsSync(wwwdata + req.url_orig + "/$command.json")) { + if (fs.existsSync(wwwdata + req.url_orig + "/$command.json")) { + res.writeHead(200, { + 'Content-Type': 'application/json', + 'Set-Cookie': '__mpws_request=' + year + month + day + hour + min + sec + }); + filebuffer = fs.readFileSync(wwwdata + req.url_orig + "/$command.json"); + filestring = filebuffer.toString() + filejson = JSON.parse(filestring); + require('./commands.js')(filejson, (callback) => { + output = JSON.stringify(callback); + res.write(output); + res.end(); + }); + return; + } + if (frhtml) { + log.verbose("return " + mime.lookUpType((wwwdata + req.url).split(".").pop())) + log.verbose("parser: frhtml"); + var date = new Date(); + var hour = date.getHours(); + hour = (hour < 10 ? "0" : "") + hour; + var min = date.getMinutes(); + min = (min < 10 ? "0" : "") + min; + var sec = date.getSeconds(); + sec = (sec < 10 ? "0" : "") + sec; + var year = date.getFullYear(); + var month = date.getMonth() + 1; + month = (month < 10 ? "0" : "") + month; + var day = date.getDate(); + day = (day < 10 ? "0" : "") + day; + res.writeHead(200, { + 'Content-Type': mime.lookUpType((wwwdata + req.url).split(".").pop()), + 'Set-Cookie': '__mpws_request=' + year + month + day + hour + min + sec + }); + res.write(require('./frhtml.js').ConvertirVersHTML(fs.readFileSync(wwwdata + req.url).toString())); + res.end(); + return; + } else if (ejs) { + log.verbose("return " + mime.lookUpType((wwwdata + req.url).split(".").pop())) + log.verbose("parser: ejs"); + var date = new Date(); + var hour = date.getHours(); + hour = (hour < 10 ? "0" : "") + hour; + var min = date.getMinutes(); + min = (min < 10 ? "0" : "") + min; + var sec = date.getSeconds(); + sec = (sec < 10 ? "0" : "") + sec; + var year = date.getFullYear(); + var month = date.getMonth() + 1; + month = (month < 10 ? "0" : "") + month; + var day = date.getDate(); + day = (day < 10 ? "0" : "") + day; + res.writeHead(200, { + 'Content-Type': "text/html", + 'Set-Cookie': '__mpws_request=' + year + month + day + hour + min + sec + }); + try { + require('ejs').renderFile(wwwdata + req.url, {wwwdata, private, req, res}, (err, str) => { + if (err) throw err; + res.write(str); + res.end(); + }) + } catch (e) { + res.writeHead(200, { + 'Content-Type': "text/plain", + 'Set-Cookie': '__mpws_request=' + year + month + day + hour + min + sec + }); + res.write(e.stack); + res.end(); + } + return; + } else { + var type = mime.lookUpType((wwwdata + req.url).split(".").pop()); + log.verbose("return " + type) + var date = new Date(); + var hour = date.getHours(); + hour = (hour < 10 ? "0" : "") + hour; + var min = date.getMinutes(); + min = (min < 10 ? "0" : "") + min; + var sec = date.getSeconds(); + sec = (sec < 10 ? "0" : "") + sec; + var year = date.getFullYear(); + var month = date.getMonth() + 1; + month = (month < 10 ? "0" : "") + month; + var day = date.getDate(); + day = (day < 10 ? "0" : "") + day; + res.writeHead(200, { + 'Content-Type': type, + 'Set-Cookie': '__mpws_request=' + year + month + day + hour + min + sec + }); + if (req.url.endsWith("/$command.json")) { + prejson = JSON.parse(fs.readFileSync(wwwdata + req.url)); + prejson.token = "<-- TOKEN TRUNCATED - Access file on real server to get the authentication token -->" + res.write(JSON.stringify(prejson)); + } else { + res.write(fs.readFileSync(wwwdata + req.url)); + } + res.end(); + return; + } + } else { + if (config.errors_show_trace) { + trace = "
Satellite Server - System Backtrace

Server Backtrace:
404F0000 FILE_NOT_FOUND
00000001 SERVER_RUNTIME
0000001A HTTP_WEBSERVER

Kernel Backtrace:
" + } else { + trace = ""; + } + log.verbose("return 404") + res.writeHead(404, {'Content-Type': 'text/html'}); + res.write("Satellite Server Fatal Error

Internal Server Error

Minteck Satellite Server returned an error while trying to request your file.

0x404: Not Found
" + req.url + "

Minteck Satellite Server " + mpws.version + ", kernel " + process.version + "" + trace + ""); + res.end(); + } + }).listen(config.port); + log.info('Started Satellite at port ' + config.port) +} \ No newline at end of file diff --git a/server/log.js b/server/log.js new file mode 100644 index 0000000..5b1e1fe --- /dev/null +++ b/server/log.js @@ -0,0 +1,33 @@ +time = 0 +const cluster = require('cluster'); + +function fix(number) { + return "0000000000".substr(0, 10 - Math.round(number * 100000).toString().length) + Math.round(number * 100000).toString() +} + +function fix2(number) { + return "000".substr(0, 3 - number.toString().length) + number.toString(); +} + +module.exports.info = function (logel) { + time = fix(process.uptime()); + console.log("[" + fix2(cluster.worker.id) + "] " + "[" + time + "] [info] " + logel); +} + +module.exports.verbose = function (logel) { + time = fix(process.uptime()); + if (config.verbose) { + console.log("[" + fix2(cluster.worker.id) + "] " + "[" + time + "] [verbose] " + logel); + } +} + +module.exports.warn = function (logel) { + time = fix(process.uptime()); + console.log("[" + fix2(cluster.worker.id) + "] " + "[" + time + "] [warn] " + logel); +} + +module.exports.error = function (logel) { + time = fix(process.uptime()); + console.log("[" + fix2(cluster.worker.id) + "] " + "[" + time + "] [error] " + logel); + process.exit() +} \ No newline at end of file diff --git a/server/version.js b/server/version.js new file mode 100644 index 0000000..f66b03b --- /dev/null +++ b/server/version.js @@ -0,0 +1,5 @@ +module.exports = { + "website": "9.0.0", + "version": require('../package.json').version, + "copyright": "2019-2021" +} \ No newline at end of file -- cgit