Rick 156a57866d Initial Commit
Init Commit Backend Server
2020-07-02 01:09:01 +02:00

217 lines
6.3 KiB
JavaScript

"use strict";
const fs = require('fs');
const zlib = require('zlib');
const https = require('https');
const selfsigned = require('selfsigned');
function getCookies(req) {
let found = {};
let cookies = req.headers.cookie;
if (cookies) {
for (let cookie of cookies.split(';')) {
let parts = cookie.split('=');
found[parts.shift().trim()] = decodeURI(parts.join('='));
}
}
return found;
}
class Server {
constructor() {
this.buffers = {};
this.startCallback = {};
this.receiveCallback = {};
this.respondCallback = {};
this.ip = serverConfig.ip;
this.port = serverConfig.port;
this.backendUrl = "https://" + this.ip + ":" + this.port;
this.version = "dev-r23.4";
this.mime = {
txt: 'text/plain',
jpg: 'image/jpeg',
png: 'image/png',
json: 'application/json'
};
this.addRespondCallback("DONE", this.killResponse.bind(this));
}
resetBuffer(sessionID) {
this.buffers[sessionID] = undefined;
}
putInBuffer(sessionID, data, bufLength) {
if (this.buffers[sessionID] === undefined || this.buffers[sessionID].allocated !== bufLength) {
this.buffers[sessionID] = {
written: 0,
allocated: bufLength,
buffer: Buffer.alloc(bufLength)
};
}
let buf = this.buffers[sessionID];
data.copy(buf.buffer, buf.written, 0);
buf.written += data.length;
return buf.written === buf.allocated;
}
getFromBuffer(sessionID) {
return this.buffers[sessionID].buffer;
}
addStartCallback(type, worker) {
this.startCallback[type] = worker;
}
addReceiveCallback(type, worker) {
this.receiveCallback[type] = worker;
}
addRespondCallback(type, worker) {
this.respondCallback[type] = worker;
}
getIp() {
return this.ip;
}
getPort() {
return this.port;
}
getBackendUrl() {
return this.backendUrl;
}
getVersion() {
return this.version;
}
generateCertifcate() {
let perms = selfsigned.generate([{ name: 'commonName', value: this.ip + "/" }], { days: 365 });
return {cert: perms.cert, key: perms.private};
}
sendZlibJson(resp, output, sessionID) {
resp.writeHead(200, "OK", {'Content-Type': this.mime['json'], 'content-encoding' : 'deflate', 'Set-Cookie' : 'PHPSESSID=' + sessionID});
zlib.deflate(output, function (err, buf) {
resp.end(buf);
});
}
sendTextJson(resp, output) {
resp.writeHead(200, "OK", {'Content-Type': this.mime['json']});
resp.end(output);
}
sendFile(resp, file) {
let pathSlic = file.split("/");
let type = this.mime[pathSlic[pathSlic.length -1].split(".")[1]] || this.mime['txt'];
let fileStream = fs.createReadStream(file);
fileStream.on('open', function () {
resp.setHeader('Content-Type', type);
fileStream.pipe(resp);
});
}
killResponse() {
return;
}
sendResponse(sessionID, req, resp, body) {
let output = "";
// get response
if (req.method === "POST" || req.method === "PUT") {
output = router.getResponse(req, body, sessionID);
} else {
output = router.getResponse(req, "", sessionID);
}
// execute data received callback
for (let type in this.receiveCallback) {
this.receiveCallback[type](sessionID, req, resp, body, output);
}
// send response
if (output in this.respondCallback) {
this.respondCallback[output](sessionID, req, resp, body);
} else {
this.sendZlibJson(resp, output, sessionID);
}
}
handleRequest(req, resp) {
const IP = req.connection.remoteAddress.replace("::ffff:", "");
const sessionID = parseInt(getCookies(req)['PHPSESSID']);
logger.logRequest("[" + sessionID + "][" + IP + "] " + req.url);
// request without data
if (req.method === "GET") {
server.sendResponse(sessionID, req, resp, "");
}
// request with data
if (req.method === "POST") {
req.on('data', function (data) {
zlib.inflate(data, function (err, body) {
let jsonData = ((body !== typeof "undefined" && body !== null && body !== "") ? body.toString() : '{}');
server.sendResponse(sessionID, req, resp, jsonData);
});
});
}
// emulib responses
if (req.method === "PUT") {
req.on('data', function(data) {
// receive data
if (req.headers.hasOwnProperty("expect")) {
const requestLength = parseInt(req.headers["content-length"]);
if (!server.putInBuffer(parseInt(req.headers.sessionid), data, requestLength)) {
resp.writeContinue();
}
}
}).on('end', function() {
let data = server.getFromBuffer(sessionID);
server.resetBuffer(sessionID);
zlib.inflate(data, function (err, body) {
let jsonData = ((body !== typeof "undefined" && body !== null && body !== "") ? body.toString() : '{}');
server.sendResponse(sessionID, req, resp, jsonData);
});
});
}
}
start() {
// execute start callback
logger.logWarning("Server: executing startup callbacks...");
for (let type in this.startCallback) {
this.startCallback[type]();
}
/* create server */
let httpsServer = https.createServer(this.generateCertifcate(), (req, res) => {
this.handleRequest(req, res);
}).listen(this.port, this.ip, function() {
logger.logSuccess("Started server");
});
/* server is already running */
httpsServer.on('error', function(e) {
logger.logError("» Port " + e.port + " is already in use, check if the server isn't already running");
});
}
}
module.exports.server = new Server();