diff --git a/meshipkvm.js b/meshipkvm.js index 488093df..3d2408e7 100644 --- a/meshipkvm.js +++ b/meshipkvm.js @@ -161,6 +161,39 @@ function CreateIPKVMManager(parent) { return 'node/' + domainid + '/' + parent.crypto.createHash('sha384').update(Buffer.from(meshid + '/' + portid)).digest().toString('base64').replace(/\+/g, '@').replace(/\//g, '$'); } + // Parse an incoming HTTP request URL + function parseIpKvmUrl(domain, url) { + const q = require('url').parse(url, true); + const i = q.path.indexOf('/ipkvm.ashx/'); + if (i == -1) return null; + const urlargs = q.path.substring(i + 12).split('/'); + if (urlargs[0].length != 64) return null; + const nodeid = 'node/' + domain.id + '/' + urlargs[0]; + const nid = urlargs[0]; + const kvmport = obj.managedPorts[nodeid]; + if (kvmport == null) return null; + const kvmmanager = obj.managedGroups[kvmport.meshid]; + if (kvmmanager == null) return null; + urlargs.shift(); + var relurl = '/' + urlargs.join('/') + if (relurl.endsWith('/.websocket')) { relurl = relurl.substring(0, relurl.length - 11); } + return { relurl: relurl, preurl: q.path.substring(0, i + 76), nodeid: nodeid, nid: nid, kvmmanager: kvmmanager, kvmport: kvmport }; + } + + // Handle a IP-KVM HTTP get request + obj.handleIpKvmGet = function(domain, req, res, next) { + const reqinfo = parseIpKvmUrl(domain, req.url); + if (reqinfo == null) { next(); return; } + reqinfo.kvmmanager.handleIpKvmGet(domain, reqinfo, req, res, next); + } + + // Handle a IP-KVM HTTP websocket request + obj.handleIpKvmWebSocket = function (domain, ws, req) { + const reqinfo = parseIpKvmUrl(domain, req.url); + if (reqinfo == null) { try { ws.close(); } catch (ex) { } return; } + reqinfo.kvmmanager.handleIpKvmWebSocket(domain, reqinfo, ws, req); + } + return obj; } @@ -422,6 +455,31 @@ function CreateRaritanKX3Manager(hostname, port, username, password) { req.end(); } + // Handle a IP-KVM HTTP get request + obj.handleIpKvmGet = function (domain, reqinfo, req, res, next) { + if (reqinfo.relurl == '/') { res.redirect(reqinfo.preurl + '/jsclient/Client.asp#portId=' + reqinfo.kvmport.portid); return; } + + // Example: /jsclient/Client.asp#portId=P_000d5d20f64c_1 + obj.fetch(reqinfo.relurl, null, [res, reqinfo], function (server, args, data, rres) { + const resx = args[0], xreqinfo = args[1]; + if (rres.headers['content-type']) { resx.set('content-type', rres.headers['content-type']); } + + // We need to replace the WebSocket code in one of the files to make it work with our server. + // Replace "b=new WebSocket(e+"//"+c+"/"+g);" in file "/js/js_kvm_client.1604062083669.min.js" + if (xreqinfo.relurl.startsWith('/js/js_kvm_client.')) { + data = data.replace('b=new WebSocket(e+"//"+c+"/"+g);', 'b=new WebSocket(e+"//"+c+"/ipkvm.ashx/' + xreqinfo.nid + '/"+g);'); + } + + resx.end(data); + }); + } + + // Handle a IP-KVM HTTP websocket request + obj.handleIpKvmWebSocket = function (domain, reqinfo, ws, req) { + //console.log('handleIpKvmWebSocket', reqinfo.preurl); + // TODO + } + return obj; } diff --git a/webserver.js b/webserver.js index b32508e0..9d8e6ae2 100644 --- a/webserver.js +++ b/webserver.js @@ -5853,51 +5853,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF obj.app.ws(url + 'ipkvm.ashx/*', function (ws, req) { const domain = getDomain(req); if (domain == null) { parent.debug('web', 'ipkvm: failed domain checks.'); try { ws.close(); } catch (ex) { } return; } - const q = require('url').parse(req.url, true); - const i = q.path.indexOf('/ipkvm.ashx/'); - if (i == -1) { parent.debug('web', 'ipkvm: failed url checks.'); try { ws.close(); } catch (ex) { } return; } - const urlargs = q.path.substring(i + 12).split('/'); - if (urlargs[0].length != 64) { parent.debug('web', 'ipkvm: failed nodeid length checks.'); try { ws.close(); } catch (ex) { } return; } - const nodeid = 'node/' + domain.id + '/' + urlargs[0]; - const nid = urlargs[0]; - const kvmport = parent.ipKvmManager.managedPorts[nodeid]; - if (kvmport == null) { parent.debug('web', 'ipkvm: failed port checks.'); try { ws.close(); } catch (ex) { } return; } - const kvmmanager = parent.ipKvmManager.managedGroups[kvmport.meshid]; - if (kvmmanager == null) { parent.debug('web', 'ipkvm: failed manager checks.'); try { ws.close(); } catch (ex) { } return; } - urlargs.shift(); - var relurl = '/' + urlargs.join('/') - if (relurl.endsWith('/.websocket')) { relurl = relurl.substring(0, relurl.length - 11); } - console.log('ws', relurl); // TODO + parent.ipKvmManager.handleIpKvmWebSocket(domain, ws, req); }); obj.app.get(url + 'ipkvm.ashx/*', function (req, res, next) { const domain = getDomain(req); - if (domain == null) { return; } - const q = require('url').parse(req.url, true); - const i = q.path.indexOf('/ipkvm.ashx/'); - if (i == -1) { next(); return; } - const urlargs = q.path.substring(i + 12).split('/'); - if (urlargs[0].length != 64) { next(); return; } - const nodeid = 'node/' + domain.id + '/' + urlargs[0]; - const nid = urlargs[0]; - const kvmport = parent.ipKvmManager.managedPorts[nodeid]; - if (kvmport == null) { next(); return; } - const kvmmanager = parent.ipKvmManager.managedGroups[kvmport.meshid]; - if (kvmmanager == null) { next(); return; } - urlargs.shift(); - const relurl = '/' + urlargs.join('/') + '#portId=' + kvmport.portid; - // Example: /jsclient/Client.asp#portId=P_000d5d20f64c_1 - kvmmanager.fetch(relurl, null, [res, nid], function (server, args, data, rres) { - const resx = args[0], nidx = args[1]; - if (rres.headers['content-type']) { resx.set('content-type', rres.headers['content-type']); } - - // We need to replace the WebSocket code in one of the files to make it work with our server. - // Replace "b=new WebSocket(e+"//"+c+"/"+g);" in file "/js/js_kvm_client.1604062083669.min.js" - if (relurl.startsWith('/js/js_kvm_client.')) { - data = data.replace('b=new WebSocket(e+"//"+c+"/"+g);', 'b=new WebSocket(e+"//"+c+"/ipkvm.ashx/' + nidx + '/"+g);'); - } - - resx.end(data); - }); + if (domain == null) return; + parent.ipKvmManager.handleIpKvmGet(domain, req, res, next); }); }