pc_services now uses node Express

- reduces chance of error with older webtv clients sending http request
- version bump to 0.9.32
This commit is contained in:
zefie
2022-10-10 15:40:09 -04:00
parent 300a8427cd
commit d4ceda7211
4 changed files with 1217 additions and 285 deletions

View File

@@ -19,6 +19,8 @@ const WTVMime = require("./WTVMime.js");
const { WTVShared, clientShowAlert } = require("./WTVShared.js"); const { WTVShared, clientShowAlert } = require("./WTVShared.js");
const WTVFlashrom = require("./WTVFlashrom.js"); const WTVFlashrom = require("./WTVFlashrom.js");
const vm = require('vm'); const vm = require('vm');
const express = require('express');
const { url } = require('inspector');
process process
.on('SIGTERM', shutdown('SIGTERM')) .on('SIGTERM', shutdown('SIGTERM'))
@@ -39,6 +41,7 @@ var ssid_sessions = new Array();
var socket_sessions = new Array(); var socket_sessions = new Array();
var ports = []; var ports = [];
var pc_ports = [];
// add .reverse() feature to all JavaScript Strings in this application // add .reverse() feature to all JavaScript Strings in this application
// works for service vault scripts too. // works for service vault scripts too.
@@ -185,7 +188,11 @@ var runScriptInVM = function (script_data, user_contextObj = {}, privileged = fa
return contextObj; // updated context object with whatever global varibles the script set return contextObj; // updated context object with whatever global varibles the script set
} }
async function processPath(socket, service_vault_file_path, request_headers = new Array(), service_name, shared_romcache = null) { function sendToPCClient(headers, data) {
}
async function processPath(socket, service_vault_file_path, request_headers = new Array(), service_name, shared_romcache = null, pc_services = false) {
var headers, data = null; var headers, data = null;
var request_is_async = false; var request_is_async = false;
var service_vault_found = false; var service_vault_found = false;
@@ -208,11 +215,14 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
// format: [ ourvarname, scriptsvarname ] // format: [ ourvarname, scriptsvarname ]
["headers", "headers"], // we need to be able to read the script's response headers ["headers", "headers"], // we need to be able to read the script's response headers
["data", "data"], // we need to be able to read the script's response data ["data", "data"], // we need to be able to read the script's response data
["request_is_async", "request_is_async"], // we need to know if the script is async or not ["request_is_async", "request_is_async"] // we need to know if the script is async or not
["ssid_sessions", "ssid_sessions"], // global ssid_sessions object for privileged service scripts, such as wtv-setup, wtv-head-waiter, etc ]
["socket_sessions", "socket_sessions"], // global socket_sessions object for privileged service scripts, such as wtv-1800, etc
[`ssid_sessions[${socket.ssid}]`, "session_data"] // user-specific session data from unprivileged scripts if (!pc_services) {
]; updateFromVM.push(["ssid_sessions", "ssid_sessions"]); // global ssid_sessions object for privileged service scripts, such as wtv-setup, wtv-head-waiter, etc
updateFromVM.push(["socket_sessions", "socket_sessions"]); // global socket_sessions object for privileged service scripts, such as wtv-1800, etc
updateFromVM.push([`ssid_sessions[${socket.ssid}]`, "session_data"]); // user-specific session data from unprivileged scripts
}
try { try {
service_vaults.forEach(function (service_vault_dir) { service_vaults.forEach(function (service_vault_dir) {
@@ -238,6 +248,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
} else { } else {
service_vault_file_path = wtvshared.makeSafePath(service_vault_dir, service_path); service_vault_file_path = wtvshared.makeSafePath(service_vault_dir, service_path);
} }
// deny access to catchall file name directly // deny access to catchall file name directly
var service_path_split = service_path.split("/"); var service_path_split = service_path.split("/");
var service_path_request_file = service_path_split[service_path_split.length - 1]; var service_path_request_file = service_path_split[service_path_split.length - 1];
@@ -373,7 +384,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
var script_data = fs.readFileSync(service_vault_file_path + ".js").toString(); var script_data = fs.readFileSync(service_vault_file_path + ".js").toString();
var priv = false; var priv = false;
if (minisrv_config.services[service_name]) priv = (minisrv_config.services[service_name].privileged) ? true : false; if (minisrv_config.services[service_name]) priv = (minisrv_config.services[service_name].privileged) ? true : false;
else if (socket.minisrv_pc_mode) priv = (minisrv_config.services['pc_services'].privileged) ? true : false; else if (pc_services) priv = (minisrv_config.services['pc_services'].privileged) ? true : false;
var vmResults = runScriptInVM(script_data, contextObj, priv, service_vault_file_path + ".js"); var vmResults = runScriptInVM(script_data, contextObj, priv, service_vault_file_path + ".js");
// Here we read back certain data from the ServiceVault Script Context Object // Here we read back certain data from the ServiceVault Script Context Object
@@ -417,7 +428,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
var script_data = fs.readFileSync(catchall_file).toString(); var script_data = fs.readFileSync(catchall_file).toString();
var priv = false; var priv = false;
if (minisrv_config.services[service_name]) priv = (minisrv_config.services[service_name].privileged) ? true : false; if (minisrv_config.services[service_name]) priv = (minisrv_config.services[service_name].privileged) ? true : false;
else if (socket.minisrv_pc_mode) priv = (minisrv_config.services['pc_services'].privileged) ? true : false; else if (pc_services) priv = (minisrv_config.services['pc_services'].privileged) ? true : false;
runScriptInVM(script_data, contextObj, priv, catchall_file); runScriptInVM(script_data, contextObj, priv, catchall_file);
@@ -444,7 +455,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
var errpage = wtvshared.doErrorPage(400); var errpage = wtvshared.doErrorPage(400);
headers = errpage[0]; headers = errpage[0];
data = errpage[1]; data = errpage[1];
if (socket.minisrv_pc_mode) { if (pc_services) {
if (minisrv_config.services.pc_services.show_verbose_errors) if (minisrv_config.services.pc_services.show_verbose_errors)
data += "<br><br>The interpreter said:<br><pre>" + e.stack + "</pre>"; data += "<br><br>The interpreter said:<br><pre>" + e.stack + "</pre>";
} }
@@ -453,12 +464,12 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
if (!request_is_async) { if (!request_is_async) {
if (!service_vault_found) { if (!service_vault_found) {
console.error(" * Could not find a Service Vault for " + service_name + ":/" + service_path.replace(service_name + path.sep, "").replace(path.sep, '/')); console.error(" * Could not find a Service Vault for " + service_name + ":/" + service_path.replace(service_name + path.sep, "").replace(path.sep, '/'));
var errpage = wtvshared.doErrorPage(404, null, socket.minisrv_pc_mode); var errpage = wtvshared.doErrorPage(404, null, pc_services);
headers = errpage[0]; headers = errpage[0];
data = errpage[1]; data = errpage[1];
} }
if (headers == null && !request_is_async) { if (headers == null && !request_is_async) {
var errpage = wtvshared.doErrorPage(400, null, socket.minisrv_pc_mode); var errpage = wtvshared.doErrorPage(400, null, pc_services);
headers = errpage[0]; headers = errpage[0];
data = errpage[1]; data = errpage[1];
console.error(" * Scripting or Data error: Headers were not defined. (headers,data) as follows:") console.error(" * Scripting or Data error: Headers were not defined. (headers,data) as follows:")
@@ -486,29 +497,27 @@ function verifyServicePort(service_name, socket) {
return false; return false;
} }
async function processURL(socket, request_headers) { async function processURL(socket, request_headers, pc_services = false) {
var shortURL, headers, data, service_name = ""; var shortURL, headers, data, service_name = "";
var enable_multi_query = false; var enable_multi_query = false;
request_headers.query = new Array(); request_headers.query = {};
if (request_headers.request_url) { if (request_headers.request_url) {
if (pc_services) {
service_name = verifyServicePort(request_headers.service_name, socket);
delete request_headers.service_name;
}
if (request_headers.request_url.indexOf('?') >= 0) { if (request_headers.request_url.indexOf('?') >= 0) {
shortURL = request_headers.request_url.split('?')[0]; shortURL = request_headers.request_url.split('?')[0];
if (socket.minisrv_pc_mode) if (!service_name) service_name = verifyServicePort(shortURL.split(':')[0], socket);
service_name = verifyServicePort("pc_services", socket);
else
service_name = verifyServicePort(shortURL.split(':')[0], socket);
if (!service_name) { if (!service_name) {
service_name = verifyServicePort("pc_services", socket); var errpage = wtvshared.doErrorPage(500, null, pc_services);
socket.minisrv_pc_mode = true;
}
if (!service_name) {
var errpage = wtvshared.doErrorPage(500, null, socket.minisrv_pc_mode);
socket_sessions[socket.id].close_me = true; socket_sessions[socket.id].close_me = true;
sendToClient(socket, errpage[0], errpage[1]); sendToClient(socket, errpage[0], errpage[1]);
return return
} }
if (request_headers.request_url.indexOf('?') >= 0) {
shortURL = request_headers.request_url.split('?')[0];
if (minisrv_config.services[service_name]) enable_multi_query = minisrv_config.services[service_name].enable_multi_query || false; if (minisrv_config.services[service_name]) enable_multi_query = minisrv_config.services[service_name].enable_multi_query || false;
var qraw = request_headers.request_url.split('?')[1]; var qraw = request_headers.request_url.split('?')[1];
if (qraw.length > 0) { if (qraw.length > 0) {
@@ -534,6 +543,9 @@ async function processURL(socket, request_headers) {
} else { } else {
shortURL = unescape(request_headers.request_url); shortURL = unescape(request_headers.request_url);
} }
} else {
shortURL = unescape(request_headers.request_url);
}
if (request_headers['wtv-request-type']) socket_sessions[socket.id].wtv_request_type = request_headers['wtv-request-type']; if (request_headers['wtv-request-type']) socket_sessions[socket.id].wtv_request_type = request_headers['wtv-request-type'];
@@ -598,49 +610,9 @@ async function processURL(socket, request_headers) {
shortURL_split.shift(); shortURL_split.shift();
var shortURL_service_path = shortURL_split.join(":"); var shortURL_service_path = shortURL_split.join(":");
shortURL = shortURL_service_name + ":/" + shortURL_service_path; shortURL = shortURL_service_name + ":/" + shortURL_service_path;
} else if (shortURL.indexOf(":") == -1 && request_headers.request.indexOf("HTTP/1") > 0 && request_headers.Host && socket.ssid == null) {
// PC browsers typically send a Host header
if (minisrv_config.services.pc_services) {
if (!minisrv_config.services.pc_services.disabled) {
socket.minisrv_pc_mode = true;
service_name = verifyServicePort("pc_services", socket);
if (!service_name) {
if (minisrv_config.services.pc_services.drop_connection_on_wrong_port) {
// just close the connection, no fancy error
socket.end();
return;
}
var errpage = wtvshared.doErrorPage(500, null, socket.minisrv_pc_mode);
socket_sessions[socket.id].close_me = true;
sendToClient(socket, errpage[0], errpage[1]);
return;
}
// if a directory, request index
if (shortURL.substring(shortURL.length - 1) == "/") shortURL += "index";
shortURL = service_name + ":" + shortURL;
} else {
// minimal pc mode to send error
socket.minisrv_pc_mode = true;
var errpage = wtvshared.doErrorPage(401, "PC services are disabled on this server", socket.minisrv_pc_mode);
headers = errpage[0];
data = errpage[1]
socket_sessions[socket.id].close_me = true;
sendToClient(socket, headers, data);
return;
}
} else {
// minimal pc mode to send error
socket.minisrv_pc_mode = true;
var errpage = wtvshared.doErrorPage(401, "PC services are disabled on this server", socket.minisrv_pc_mode);
headers = errpage[0];
data = errpage[1]
socket_sessions[socket.id].close_me = true;
sendToClient(socket, headers, data);
return;
}
} }
if (!socket.minisrv_pc_mode && !socket.ssid) { if (socket.ssid) {
// skip box auth tests for pc mode // skip box auth tests for pc mode
// check security // check security
@@ -704,10 +676,10 @@ minisrv-no-mail-count: true`;
} else { } else {
console.log(" * " + reqverb + " for " + request_headers.request_url, 'on', socket.id); console.log(" * " + reqverb + " for " + request_headers.request_url, 'on', socket.id);
} }
if (!socket.minisrv_pc_mode) { if (!pc_services) {
var service_name = verifyServicePort(shortURL.split(':/')[0], socket); var service_name = verifyServicePort(shortURL.split(':/')[0], socket);
if (!service_name) { if (!service_name) {
var errpage = wtvshared.doErrorPage(500, null, socket.minisrv_pc_mode); var errpage = wtvshared.doErrorPage(500, null, pc_services);
socket_sessions[socket.id].close_me = true; socket_sessions[socket.id].close_me = true;
sendToClient(socket, errpage[0], errpage[1]); sendToClient(socket, errpage[0], errpage[1]);
return return
@@ -720,9 +692,14 @@ minisrv-no-mail-count: true`;
} }
if (minisrv_config.config.debug_flags.show_headers) console.log(" * Incoming headers on socket ID", socket.id, (await wtvshared.decodePostData(wtvshared.filterRequestLog(wtvshared.filterSSID(request_headers))))); if (minisrv_config.config.debug_flags.show_headers) console.log(" * Incoming headers on socket ID", socket.id, (await wtvshared.decodePostData(wtvshared.filterRequestLog(wtvshared.filterSSID(request_headers)))));
socket_sessions[socket.id].request_headers = request_headers; socket_sessions[socket.id].request_headers = request_headers;
processPath(socket, urlToPath, request_headers, service_name, shared_romcache); processPath(socket, urlToPath, request_headers, service_name, shared_romcache, pc_services);
} else if (shortURL.indexOf('http://') >= 0 || shortURL.indexOf('https://') >= 0) { } else if ((shortURL.indexOf('http://') >= 0 || shortURL.indexOf('https://') >= 0) && !pc_services) {
doHTTPProxy(socket, request_headers); doHTTPProxy(socket, request_headers);
} else if (pc_services) {
// if a directory, request index
if (shortURL.substring(shortURL.length - 1) == "/") shortURL += "index";
var urlToPath = wtvshared.fixPathSlashes(service_name + path.sep + shortURL);
processPath(socket, urlToPath, request_headers, service_name, shared_romcache, pc_services);
} else { } else {
// error reading headers (no request_url provided) // error reading headers (no request_url provided)
var errpage = wtvshared.doErrorPage(400); var errpage = wtvshared.doErrorPage(400);
@@ -922,7 +899,7 @@ function stripHeaders(headers_obj, whitelist) {
function headerStringToObj(headers, response = false) { function headerStringToObj(headers, response = false) {
var inc_headers = 0; var inc_headers = 0;
var headers_obj = new Array(); var headers_obj = {};
var headers_obj_pre = headers.split("\n"); var headers_obj_pre = headers.split("\n");
headers_obj_pre.forEach(function (d) { headers_obj_pre.forEach(function (d) {
if (/^SECURE ON/.test(d) && !response) { if (/^SECURE ON/.test(d) && !response) {
@@ -973,6 +950,7 @@ async function sendToClient(socket, headers_obj, data) {
socket.destroy(); socket.destroy();
return; return;
} }
if (!socket.res) {
var wtv_connection_close = (headers_obj["wtv-connection-close"]) ? true : false; var wtv_connection_close = (headers_obj["wtv-connection-close"]) ? true : false;
if (typeof (headers_obj["wtv-connection-close"]) != 'undefined') delete headers_obj["wtv-connection-close"]; if (typeof (headers_obj["wtv-connection-close"]) != 'undefined') delete headers_obj["wtv-connection-close"];
@@ -988,6 +966,7 @@ async function sendToClient(socket, headers_obj, data) {
if (headers_obj['wtv-mail-count']) delete headers_obj['wtv-mail-count']; if (headers_obj['wtv-mail-count']) delete headers_obj['wtv-mail-count'];
delete headers_obj['minisrv-no-mail-count']; delete headers_obj['minisrv-no-mail-count'];
} }
}
// add Connection header if missing, default to Keep-Alive // add Connection header if missing, default to Keep-Alive
if (!headers_obj.Connection) { if (!headers_obj.Connection) {
@@ -1041,6 +1020,10 @@ async function sendToClient(socket, headers_obj, data) {
delete headers_obj["minisrv-force-compression"]; delete headers_obj["minisrv-force-compression"];
} }
if (socket.res) { // pc mode with response object available
if (compression_type == 1) compression_type = 2; // just in case
}
// compress if needed // compress if needed
if (compression_type > 0 && content_length > 0 && headers_obj['Response'].substring(0, 3) == "200") { if (compression_type > 0 && content_length > 0 && headers_obj['Response'].substring(0, 3) == "200") {
var uncompressed_content_length = content_length; var uncompressed_content_length = content_length;
@@ -1076,7 +1059,7 @@ async function sendToClient(socket, headers_obj, data) {
if (uncompressed_content_length != compressed_content_length) if (minisrv_config.config.debug_flags.debug) console.log(" # Compression stats: Orig Size:", uncompressed_content_length, "~ Comp Size:", compressed_content_length, "~ Ratio:", compression_ratio, "~ Saved:", compression_percentage.toString() + "%"); if (uncompressed_content_length != compressed_content_length) if (minisrv_config.config.debug_flags.debug) console.log(" # Compression stats: Orig Size:", uncompressed_content_length, "~ Comp Size:", compressed_content_length, "~ Ratio:", compression_ratio, "~ Saved:", compression_percentage.toString() + "%");
} }
if (!socket.res) {
// encrypt if needed // encrypt if needed
if (socket_sessions[socket.id].secure == true && !socket_sessions[socket.id].do_not_encrypt) { if (socket_sessions[socket.id].secure == true && !socket_sessions[socket.id].do_not_encrypt) {
headers_obj["wtv-encrypted"] = 'true'; headers_obj["wtv-encrypted"] = 'true';
@@ -1092,6 +1075,7 @@ async function sendToClient(socket, headers_obj, data) {
if (headers_obj["wtv-encrypted"]) delete headers_obj["wtv-encrypted"]; if (headers_obj["wtv-encrypted"]) delete headers_obj["wtv-encrypted"];
if (headers_obj["secure"]) delete headers_obj["secure"]; if (headers_obj["secure"]) delete headers_obj["secure"];
} }
}
// calculate content length // calculate content length
@@ -1109,6 +1093,7 @@ async function sendToClient(socket, headers_obj, data) {
} }
if (!socket.res) {
// Send wtv-ticket if it has been flagged as updated // Send wtv-ticket if it has been flagged as updated
if (ssid_sessions[socket.ssid]) { if (ssid_sessions[socket.ssid]) {
if (ssid_sessions[socket.ssid].data_store.wtvsec_login) { if (ssid_sessions[socket.ssid].data_store.wtvsec_login) {
@@ -1121,28 +1106,11 @@ async function sendToClient(socket, headers_obj, data) {
} }
} }
} }
}
if (!socket.res) {
var end_of_line = "\n"; var end_of_line = "\n";
if (socket.minisrv_pc_mode) {
end_of_line = "\r\n";
headers_obj['Response'] = "HTTP/1.0 " + headers_obj['Response'];
}
/* // wtv-request-type download wants minimal headers?
if (data.byteLength > 0) {
if (socket_sessions[socket.id].wtv_request_type == "download") {
if (headers_obj['Content-Type'] != "wtv/download-list") {
// minimalize headers
var new_headers = { "Response": headers_obj['Response'].split(" ")[0] + " " }
if (headers_obj['wtv-encrypted']) new_headers['wtv-encrypted'] = headers_obj['wtv-encrypted'];
new_headers["content-type"] = headers_obj['Content-Type'];
new_headers["content-length"] = headers_obj['Content-length'];
headers_obj = new_headers;
}
}
}
*/
// header object to string // header object to string
if (minisrv_config.config.debug_flags.show_headers) console.log(" * Outgoing headers on socket ID", socket.id, (await wtvshared.filterSSID(headers_obj))); if (minisrv_config.config.debug_flags.show_headers) console.log(" * Outgoing headers on socket ID", socket.id, (await wtvshared.filterSSID(headers_obj)));
Object.keys(headers_obj).forEach(function (k) { Object.keys(headers_obj).forEach(function (k) {
@@ -1163,8 +1131,18 @@ async function sendToClient(socket, headers_obj, data) {
socket_sessions[socket.id].destroy_me = true; socket_sessions[socket.id].destroy_me = true;
} }
} }
}
// send to client // send to client
if (socket.res) {
var resCode = parseInt(headers_obj.Response.substr(0, 3));
headers_obj['x-powered-by'] = "Express via " + z_title;
socket.res.writeHead(resCode, headers_obj);
socket.res.end(data);
var log_obj = Object.assign({}, socket.res.getHeaders());
if (minisrv_config.config.debug_flags.show_headers) console.log(" * Outgoing PC headers on " + socket.service_name + " socket ID", socket.id, log_obj);
} else {
var toClient = null; var toClient = null;
if (typeof data == 'string') { if (typeof data == 'string') {
toClient = headers + end_of_line + data; toClient = headers + end_of_line + data;
@@ -1182,6 +1160,7 @@ async function sendToClient(socket, headers_obj, data) {
if (minisrv_config.config.debug_flags.quiet) console.log(" * Sent" + verbosity_mod + " " + headers_obj.Response + " to client (Content-Type:", headers_obj['Content-Type'], "~", headers_obj['Content-length'], "bytes)"); if (minisrv_config.config.debug_flags.quiet) console.log(" * Sent" + verbosity_mod + " " + headers_obj.Response + " to client (Content-Type:", headers_obj['Content-Type'], "~", headers_obj['Content-length'], "bytes)");
} }
} }
}
async function sendToSocket(socket, data) { async function sendToSocket(socket, data) {
var chunk_size = 16384; var chunk_size = 16384;
@@ -1542,13 +1521,7 @@ async function processRequest(socket, data_hex, skipSecure = false, encryptedReq
socket_sessions[socket.id].headers = headers; socket_sessions[socket.id].headers = headers;
} }
} else { } else {
if (!socket.ssid) {
// incomplete, dont use https on pc services yet
socket = new tls.TLSSocket(socket);
socket.minisrv_pc_mode = true;
console.log(socket)
console.log("pc https?");
} else {
// handle streaming POST // handle streaming POST
if (socket_sessions[socket.id].expecting_post_data && headers) { if (socket_sessions[socket.id].expecting_post_data && headers) {
socket_sessions[socket.id].headers = headers; socket_sessions[socket.id].headers = headers;
@@ -1676,7 +1649,6 @@ async function processRequest(socket, data_hex, skipSecure = false, encryptedReq
} }
} }
} }
}
async function cleanupSocket(socket) { async function cleanupSocket(socket) {
try { try {
@@ -1784,8 +1756,8 @@ function reloadConfig() {
// SERVER START // SERVER START
var git_commit = getGitRevision() var git_commit = getGitRevision()
var z_title = "zefie's wtv minisrv v" + require('./package.json').version; var z_title = "zefie's wtv minisrv v" + require('./package.json').version;
if (git_commit) console.log("**** Welcome to " + z_title + " (git " + git_commit + ") ****"); if (git_commit) z_title += " (git " + git_commit + ")";
else console.log("**** Welcome to " + z_title + " ****"); console.log("**** Welcome to " + z_title + " ****");
const wtvshared = new WTVShared(); // creates minisrv_config const wtvshared = new WTVShared(); // creates minisrv_config
minisrv_config = wtvshared.getMiniSrvConfig(); // snatches minisrv_config minisrv_config = wtvshared.getMiniSrvConfig(); // snatches minisrv_config
@@ -1834,7 +1806,8 @@ Object.keys(minisrv_config.services).forEach(function (k) {
minisrv_config.services[k].host = service_ip; minisrv_config.services[k].host = service_ip;
} }
if (minisrv_config.services[k].port && !minisrv_config.services[k].nobind) { if (minisrv_config.services[k].port && !minisrv_config.services[k].nobind) {
ports.push(minisrv_config.services[k].port); if (minisrv_config.services[k].pc_services) pc_ports.push(minisrv_config.services[k].port);
else ports.push(minisrv_config.services[k].port);
} }
// minisrv_config service toString // minisrv_config service toString
minisrv_config.services[k].toString = function (overrides) { minisrv_config.services[k].toString = function (overrides) {
@@ -1892,8 +1865,22 @@ process.on('uncaughtException', function (err) {
}); });
function findServiceByPort(port) {
var service_name = null;
Object.keys(minisrv_config.services).forEach(function (k) {
if (service_name) return;
if (minisrv_config.services[k].port) {
if (port == parseInt(minisrv_config.services[k].port))
service_name = k;
}
})
return service_name;
}
var initstring = ''; var initstring = '';
ports.sort(); ports.sort();
pc_ports.sort();
// de-duplicate ports in case user configured multiple services on same port // de-duplicate ports in case user configured multiple services on same port
const bind_ports = [...new Set(ports)] const bind_ports = [...new Set(ports)]
@@ -1909,6 +1896,40 @@ bind_ports.every(function (v) {
} }
return false; return false;
}); });
// PC Services via express
// de-duplicate ports in case user configured multiple services on same port
const pc_bind_ports = [...new Set(pc_ports)]
if (!minisrv_config.config.bind_ip) minisrv_config.config.bind_ip = "0.0.0.0";
pc_bind_ports.every(function (v) {
try {
var server = express();
server.listen(v, minisrv_config.config.bind_ip);
initstring += v + ", ";
server.get('*', (req, res) => {
var request_headers = {};
req.socket.id = parseInt(crc16('CCITT-FALSE', Buffer.from(String(req.socket.remoteAddress) + String(req.socket.remotePort), "utf8")).toString(16), 16);
socket_sessions[req.socket.id] = [];
var service_name = findServiceByPort(v);
request_headers['request'] = "GET " + req.originalUrl + " HTTP/1.1";
request_headers.request_url = req.originalUrl;
Object.keys(req.headers).forEach(function (k) {
request_headers[k] = req.headers[k];
});
request_headers.query = req.query;
if (minisrv_config.config.debug_flags.show_headers) console.log(" * Incoming PC Headers on", service_name, "socket ID", req.socket.id, wtvshared.filterRequestLog(request_headers));
request_headers.service_name = service_name;
req.socket.minisrv_pc_mode = true;
req.socket.res = res;
req.socket.service_name = service_name;
processURL(req.socket, request_headers, true)
})
return true;
} catch (e) {
throw ("Could not bind to port", v, "on", minisrv_config.config.bind_ip, e.toString());
}
return false;
});
initstring = initstring.substring(0, initstring.length - 2); initstring = initstring.substring(0, initstring.length - 2);

View File

@@ -155,6 +155,8 @@
}, },
"pc_services": { "pc_services": {
"port": 1699, "port": 1699,
"pc_services": true,
"hide_minisrv_version": true,
"disabled": true, "disabled": true,
"servicevault_dir": "http_pc", "servicevault_dir": "http_pc",
"drop_connection_on_wrong_port": false, "drop_connection_on_wrong_port": false,

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "zefie_wtvp_minisrv", "name": "zefie_wtvp_minisrv",
"version": "0.9.31", "version": "0.9.32",
"description": "WebTV Service (WTVP) Emulation Server", "description": "WebTV Service (WTVP) Emulation Server",
"main": "app.js", "main": "app.js",
"homepage": "https://github.com/zefie/zefie_wtvp_minisrv", "homepage": "https://github.com/zefie/zefie_wtvp_minisrv",
@@ -31,6 +31,7 @@
"crypto-js": "^4.1.1", "crypto-js": "^4.1.1",
"easy-crc": "0.0.2", "easy-crc": "0.0.2",
"endianness": "^8.0.2", "endianness": "^8.0.2",
"express": "^4.18.2",
"html-entities": "^2.3.3", "html-entities": "^2.3.3",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",
"mime-types": "^2.1.35", "mime-types": "^2.1.35",