diff --git a/zefie_wtvp_minisrv/app.js b/zefie_wtvp_minisrv/app.js index 8d10bda0..66c51c6e 100644 --- a/zefie_wtvp_minisrv/app.js +++ b/zefie_wtvp_minisrv/app.js @@ -791,7 +791,7 @@ async function processPath(socket, service_vault_file_path, request_headers = [] request_headers.service_file_path = service_vault_file_path; request_headers.raw_file = true; // process flashroms - if (minisrv_config.services[service_name].is_flashrom_service && (wtvshared.getFileExt(service_vault_file_path).toLowerCase() === "rom" || wtvshared.getFileExt(service_vault_file_path).toLowerCase() === "brom")) { + if (minisrv_config.services[(pc_service_name || service_name)].is_flashrom_service && (wtvshared.getFileExt(service_vault_file_path).toLowerCase() === "rom" || wtvshared.getFileExt(service_vault_file_path).toLowerCase() === "brom")) { let bf0app_update = false; const request_path = request_headers.request_url.replace(service_name + ":/", ""); const romtype = ssid_sessions[socket.ssid].get("wtv-client-rom-type"); @@ -1192,7 +1192,7 @@ minisrv-no-mail-count: true`; } else if (handlerModules["wtvhttp"] && ((shortURL.includes('http://') || shortURL.includes('https://')) || (use_external_proxy === true && shortURL.includes(service_name + "://")) && !pc_services)) { handlerModules["wtvhttp"].doHTTPProxy(socket, request_headers); } else if (handlerModules["wtvgopher"] && shortURL.startsWith("gopher://")) { - handlerModules["wtvgopher"].handleGopherRequest(socket, request_headers, wtvshared, sendToClient); + handlerModules["wtvgopher"].handleGopherRequest(socket, request_headers); } else if (handlerModules["wtvftp"] &&shortURL.startsWith('ftp://')) { if (minisrv_config.config.debug_flags.show_headers) console.debug(" * Incoming FTP request on WTVP socket ID", socket.id, await wtvshared.decodePostData(await wtvshared.filterRequestLog(await wtvshared.filterSSID(request_headers)))); handlerModules["wtvftp"].handleFTPRequest(socket, request_headers); @@ -2234,7 +2234,7 @@ Object.keys(minisrv_config.services).forEach(function (k) { let extraVar = eval(minisrv_config.services[k].handler_extra_vars[i]); args.push(extraVar); } - const constructorArgs = [minisrv_config, k, ...args]; + const constructorArgs = [minisrv_config, k, wtvshared, sendToClient, ...args]; handlerModules[minisrv_config.services[k].handler_module.toLowerCase()] = new handlerModules[minisrv_config.services[k].handler_module + "_main"](...constructorArgs); } loadedModule = true; diff --git a/zefie_wtvp_minisrv/includes/classes/WTVFTP.js b/zefie_wtvp_minisrv/includes/classes/WTVFTP.js index df2d16e0..8c5b5823 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTVFTP.js +++ b/zefie_wtvp_minisrv/includes/classes/WTVFTP.js @@ -1,5 +1,3 @@ -const dns = require('dns'); - class WTVFTP { wtvshared = null; wtvmime = null; @@ -9,15 +7,14 @@ class WTVFTP { ftp = null; url = null; - constructor(minisrv_config, service_name, sendToClient) { + constructor(minisrv_config, service_name, wtvshared, sendToClient, wtvmime) { this.minisrv_config = minisrv_config; this.sendToClient = sendToClient; - const WTVShared = require("./WTVShared.js")['WTVShared']; - const WTVMime = require("./WTVMime.js"); + this.wtvshared = wtvshared; + this.wtvmime = wtvmime; this.url = require('url'); this.ftp = require('ftp'); - this.wtvshared = new WTVShared(minisrv_config); - this.wtvmime = new WTVMime(minisrv_config); + this.dns = require('dns'); } handleFTPRequest(socket, request_headers) { @@ -118,7 +115,7 @@ class WTVFTP { }); // FIX: Resolve host to IPv4 address before connecting - dns.lookup(host, { family: 4 }, (err, address) => { + this.dns.lookup(host, { family: 4 }, (err, address) => { if (err) { this.sendToClient(socket, { 'Status': '500 DNS resolution error', 'Content-Type': 'text/plain' }, 'DNS resolution error'); return; diff --git a/zefie_wtvp_minisrv/includes/classes/WTVGopher.js b/zefie_wtvp_minisrv/includes/classes/WTVGopher.js index f3c3f06f..50b7b2ef 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTVGopher.js +++ b/zefie_wtvp_minisrv/includes/classes/WTVGopher.js @@ -1,11 +1,12 @@ -const WTVMime = require('./WTVMime.js'); const net = require('net'); class WTVGopher { // Adapted from WebTV Redialed's Gopher support - constructor(...[minisrv_config, service_name]) { + constructor(...[minisrv_config, service_name, wtvshared, sendToClient, wtvmime]) { this.minisrv_config = minisrv_config; - this.wtvmime = new WTVMime(minisrv_config); + this.wtvshared = wtvshared; + this.wtvmime = wtvmime; + this.sendToClient = sendToClient; this.logGopher = minisrv_config.services[service_name].log_raw_gopher || false; } @@ -131,12 +132,12 @@ class WTVGopher { return html; } - async handleGopherRequest(socket, request_headers, wtvshared, sendToClient) { + async handleGopherRequest(socket, request_headers) { if (this.minisrv_config.config.debug_flags.show_headers) { console.log("Gopher: Client Request on socket ID", socket.id, - await wtvshared.decodePostData( - wtvshared.filterRequestLog(wtvshared.filterSSID(request_headers)) + await this.wtvshared.decodePostData( + this.wtvshared.filterRequestLog(this.wtvshared.filterSSID(request_headers)) )); } @@ -225,7 +226,7 @@ class WTVGopher { "Content-Type": mimetype } - sendToClient(socket, headers, imageData); + this.sendToClient(socket, headers, imageData); return; } else { // convert gophermap to html @@ -235,7 +236,7 @@ class WTVGopher { "Status": "200 OK", "Content-Type": "text/html" } - sendToClient(socket, headers, htmlData); + this.sendToClient(socket, headers, htmlData); } }); @@ -251,7 +252,7 @@ class WTVGopher { } else if (friendlyErr.includes('ENOTFOUND')) { friendlyErr = "Host not found"; } - sendToClient(socket, {"Status": "400 Gopher Error: " + friendlyErr}, friendlyErr); + this.sendToClient(socket, {"Status": "400 Gopher Error: " + friendlyErr}, friendlyErr); }); } } diff --git a/zefie_wtvp_minisrv/includes/classes/WTVHTTP.js b/zefie_wtvp_minisrv/includes/classes/WTVHTTP.js index 68b0eab8..ebf014f4 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTVHTTP.js +++ b/zefie_wtvp_minisrv/includes/classes/WTVHTTP.js @@ -1,10 +1,8 @@ -const {WTVShared, clientShowAlert} = require('./WTVShared.js'); - class WTVHTTP { - constructor(...[minisrv_config, service_name, http, sendToClient]) { + constructor(...[minisrv_config, service_name, wtvshared, sendToClient, http]) { this.minisrv_config = minisrv_config; this.service_name = service_name; - this.wtvshared = new WTVShared(minisrv_config); + this.wtvshared = wtvshared; this.sendToClient = sendToClient; this.http = http; this.https = require('follow-redirects').https diff --git a/zefie_wtvp_minisrv/includes/classes/WTVPNM.js b/zefie_wtvp_minisrv/includes/classes/WTVPNM.js index 508541a4..11352db5 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTVPNM.js +++ b/zefie_wtvp_minisrv/includes/classes/WTVPNM.js @@ -16,11 +16,8 @@ // If the hash matches, the client is authenticated and the server starts sending UDP packets. const net = require('net'); -const fs = require('fs'); -const path = require('path'); const crypto = require('crypto'); const dgram = require('dgram'); -const { WTVShared } = require('./WTVShared.js'); class WTVPNM { minisrv_config = null; @@ -30,11 +27,11 @@ class WTVPNM { wtvshared = null; sessions = new Map(); - constructor(...[minisrv_config, service_name]) { + constructor(...[minisrv_config, service_name, wtvshared, sendToClient]) { this.minisrv_config = minisrv_config; this.service_name = service_name; this.service_config = minisrv_config.services[service_name] || {}; - this.wtvshared = new WTVShared(minisrv_config, true); + this.wtvshared = wtvshared; this.server = net.createServer((socket) => this.handleConnection(socket)); // Descriptor server-id mapping uses full 16-bit source UDP port: @@ -676,7 +673,7 @@ class WTVPNM { for (const variant of extensionVariants) { const candidate = this.wtvshared.makeSafePath(base, variant); this.debugLog('testing media candidate', candidate); - if (candidate && fs.existsSync(candidate) && fs.lstatSync(candidate).isFile()) { + if (candidate && this.wtvshared.fs.existsSync(candidate) && this.wtvshared.fs.lstatSync(candidate).isFile()) { if (this.service_config.debug) { this.debugLog('media file found', variant, '->', candidate); } @@ -694,7 +691,7 @@ class WTVPNM { const requestedPath = this.normalizeRequestedMediaPath(requestedMedia); if (!requestedPath) return []; - const ext = path.posix.extname(requestedPath).toLowerCase(); + const ext = this.wtvshared.path.posix.extname(requestedPath).toLowerCase(); const stem = ext.length > 0 ? requestedPath.slice(0, -ext.length) : requestedPath; const variants = [requestedPath]; @@ -1172,13 +1169,13 @@ class WTVPNM { prepareMediaData(session) { if (!session || session.mediaFrames) return; - if (!session.mediaPath || !fs.existsSync(session.mediaPath)) { + if (!session.mediaPath || !this.wtvshared.fs.existsSync(session.mediaPath)) { this.debugLog('prepareMediaData: media path missing or not found', session.id, session.mediaPath); return; } try { - const media = fs.readFileSync(session.mediaPath); + const media = this.wtvshared.fs.readFileSync(session.mediaPath); this.debugLog('prepareMediaData: loaded media file', session.id, `size=${media.length} bytes`); const classicRa = this.parseClassicRaHeader(media); @@ -1830,7 +1827,7 @@ class WTVPNM { let raBuffer = null; if (session && session.mediaPath) { try { - raBuffer = fs.readFileSync(session.mediaPath); + raBuffer = this.wtvshared.fs.readFileSync(session.mediaPath); } catch(e) { this.debugLog('buildDescriptor error reading media', session.mediaPath, e.message); } @@ -2400,8 +2397,8 @@ class WTVPNM { const challengeBuf = Buffer.from(challenge, 'latin1'); const requestedMedia = session?.requestedMedia || ''; const requestedMediaPath = this.normalizeRequestedMediaPath(requestedMedia); - const resolvedBase = session?.mediaPath ? path.basename(session.mediaPath) : ''; - const requestedDir = requestedMediaPath ? path.posix.dirname(requestedMediaPath) : ''; + const resolvedBase = session?.mediaPath ? this.wtvshared.path.basename(session.mediaPath) : ''; + const requestedDir = requestedMediaPath ? this.wtvshared.path.posix.dirname(requestedMediaPath) : ''; const resolvedMedia = resolvedBase ? (requestedDir && requestedDir !== '.' ? `${requestedDir}/${resolvedBase}` : resolvedBase) : requestedMediaPath; diff --git a/zefie_wtvp_minisrv/includes/config.json b/zefie_wtvp_minisrv/includes/config.json index ea3c882b..bd67b6d1 100644 --- a/zefie_wtvp_minisrv/includes/config.json +++ b/zefie_wtvp_minisrv/includes/config.json @@ -304,7 +304,7 @@ "port": 1650, "connections": 3, "handler_module": "WTVFTP", - "handler_extra_vars": ["sendToClient"] + "handler_extra_vars": ["wtvmime"] }, "http": { // http upstream @@ -318,7 +318,7 @@ "max_response_size": 16, // Megabytes "disallow_no_slash": true, "handler_module": "WTVHTTP", - "handler_extra_vars": ["http", "sendToClient"] + "handler_extra_vars": ["http"] }, "https": { // https upstream @@ -332,7 +332,7 @@ "max_response_size": 16, // Megabytes "disallow_no_slash": true, "handler_module": "WTVHTTP", - "handler_extra_vars": ["http", "sendToClient"], + "handler_extra_vars": ["http"], "allow_self_signed_ssl": false, // If true, will allow self-signed SSL certificates via the proxy. "support_bitdefender_self_signed_proxy": true // If the user has bitdefender installed, it is intercepting SSL connections and re-signing them with its own self-signed certificate. Enabling this will add the Bitdefender certificate to the trusted store for the https service, allowing it to proxy https connections without errors. }, @@ -350,7 +350,7 @@ "max_response_size": 16, // Megabytes "disallow_no_slash": true, "handler_module": "WTVHTTP", - "handler_extra_vars": ["http", "sendToClient"] + "handler_extra_vars": ["http"] }, "gopher": { // Gopher processor @@ -361,7 +361,8 @@ "uses_service_vault": false, // For custom services that use modules instead of service vaults "disallow_no_slash": true, "log_raw_gopher": false, // set to true to log raw gopher responses to the console for debugging - "handler_module": "WTVGopher" + "handler_module": "WTVGopher", + "handler_extra_vars": ["wtvmime"] }, "wtv-passport": { // wtv-passport (for messenger)