#!/usr/bin/env node// A WebSocket to TCP socket proxy// Copyright 2012 Joel Martin// Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)// Known to work with node 0.8.9// Requires node modules: ws and optimist// npm install ws optimistfunction getIPAdress() { var interfaces = require('os').networkInterfaces(); for (var devName in interfaces) { var iface = interfaces[devName]; for (var i = 0; i < iface.length; i++) { var alias = iface[i]; console.log('🚀:', 'alias', JSON.stringify(alias)); // if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) { // return alias.address; // } } }}const http = require('http');const https = require('https');const url = require('url');const net = require('net');const path = require('path');const fs = require('fs');const mime = require('mime-types');var argv = require('optimist').argv, Buffer = require('buffer').Buffer, WebSocketServer = require('ws').Server, webServer, wsServer, source_host, source_port, target_host, target_port, web_path = null;const ArgvWeb = path.resolve(__dirname, "noVNC");// Handle new WebSocket clientfunction handleSocket(client, req) { var clientAddr = client._socket.remoteAddress, log; var start_time = new Date().getTime(); console.log(req ? req.url : client.upgradeReq.url); log = function (msg) { console.log(' ' + clientAddr + ': ' + msg); }; log('WebSocket connection'); log('Version ' + client.protocolVersion + ', subprotocol: ' + client.protocol); if (argv.record) { var rs = fs.createWriteStream(argv.record + '/' + new Date().toISOString().replace(/:/g, "_")); rs.write('var VNC_frame_data = [\n'); } else { var rs = null; } var target = net.createConnection(target_port, target_host, function () { log('connected to target'); }); target.on('data', function (data) { //log("sending message: " + data); if (rs) { var tdelta = Math.floor(new Date().getTime()) - start_time; var rsdata = '\'{' + tdelta + '{' + decodeBuffer(data) + '\',\n'; rs.write(rsdata); } try { client.send(data); } catch (e) { log("Client closed, cleaning up target"); target.end(); } }); target.on('end', function () { log('target disconnected'); client.close(); if (rs) { rs.end('\'EOF\'];\n'); } }); target.on('error', function () { log('target connection error'); target.end(); client.close(); if (rs) { rs.end('\'EOF\'];\n'); } }); client.on('message', function (msg) { //log('got message: ' + msg); if (rs) { var rdelta = Math.floor(new Date().getTime()) - start_time; var rsdata = ('\'}' + rdelta + '}' + decodeBuffer(msg) + '\',\n'); rs.write(rsdata); } target.write(msg); }); client.on('close', function (code, reason) { log('WebSocket client disconnected: ' + code + ' [' + reason + ']'); target.end(); }); client.on('error', function (a) { log('WebSocket client error: ' + a); target.end(); });};function decodeBuffer(buf) { var returnString = ''; for (var i = 0; i < buf.length; i++) { if (buf[i] >= 48 && buf[i] <= 90) { returnString += String.fromCharCode(buf[i]); } else if (buf[i] === 95) { returnString += String.fromCharCode(buf[i]); } else if (buf[i] >= 97 && buf[i] <= 122) { returnString += String.fromCharCode(buf[i]); } else { var charToConvert = buf[i].toString(16); if (charToConvert.length === 0) { returnString += '\\x00'; } else if (charToConvert.length === 1) { returnString += '\\x0' + charToConvert; } else { returnString += '\\x' + charToConvert; } } } return returnString;}// Send an HTTP error responsehttp_error = function (response, code, msg) { response.writeHead(code, { "Content-Type": "text/plain" }); response.write(msg + "\n"); response.end(); return;};// Process an HTTP static file requesthttp_request = function (request, response) { // console.log("pathname: " + url.parse(req.url).pathname); // res.writeHead(200, {'Content-Type': 'text/plain'}); // res.end('okay'); if (!ArgvWeb) { return http_error(response, 403, "403 Permission Denied"); } var uri = url.parse(request.url).pathname , filename = path.join(ArgvWeb, uri); fs.exists(filename, function (exists) { if (!exists) { return http_error(response, 404, "404 Not Found"); } if (fs.statSync(filename).isDirectory()) { filename += '/index.html'; } fs.readFile(filename, "binary", function (err, file) { if (err) { return http_error(response, 500, err); } var headers = {}; var contentType = mime.contentType(path.extname(filename)); if (contentType !== false) { headers['Content-Type'] = contentType; } response.writeHead(200, headers); response.write(file, "binary"); response.end(); }); });};// parse source and target arguments into partstry { source_arg = "3003"; target_arg = "192.168.137.1:5900"; // target_arg = "10.143.133.222:3389"; try { source_arg = argv._[0].toString(); target_arg = argv._[1].toString(); } catch (error) { } var idx; idx = source_arg.indexOf(":"); if (idx >= 0) { source_host = source_arg.slice(0, idx); source_port = parseInt(source_arg.slice(idx + 1), 10); } else { source_host = ""; source_port = parseInt(source_arg, 10); } idx = target_arg.indexOf(":"); if (idx < 0) { throw ("target must be host:port"); } target_host = target_arg.slice(0, idx); target_port = parseInt(target_arg.slice(idx + 1), 10); if (isNaN(source_port) || isNaN(target_port)) { throw ("illegal port"); }} catch (e) { console.error("websockify.js [--web web_dir] [--cert cert.pem [--key key.pem]] [--record dir] [source_addr:]source_port target_addr:target_port"); process.exit(2);}console.log("WebSocket settings: ");console.log(" - proxying from " + source_host + ":" + source_port + " to " + target_host + ":" + target_port);console.log(`${getIPAdress()}`);if (ArgvWeb) { console.log(" - Web server active. Serving: " + ArgvWeb);}function proxyRequest(cReq, cRes) { console.log("cReq.url", cReq.url); var u = url.parse(cReq.url); var options = { hostname: u.hostname, port: u.port || 80, path: u.path, method: cReq.method, headers: cReq.headers }; var pReq = http.request(options, function (pRes) { cRes.writeHead(pRes.statusCode, pRes.headers); pRes.pipe(cRes); }).on('error', function (e) { cRes.end(); }); cReq.pipe(pReq);}if (argv.cert) { argv.key = argv.key || argv.cert; var cert = fs.readFileSync(argv.cert), key = fs.readFileSync(argv.key); console.log(" - Running in encrypted HTTPS (wss://) mode using: " + argv.cert + ", " + argv.key); webServer = https.createServer({ cert: cert, key: key }, http_request);} else { console.log(" - Running in unencrypted HTTP (ws://) mode"); webServer = http.createServer(http_request);}webServer.listen(source_port, () => { wsServer = new WebSocketServer({ server: webServer }); wsServer.on('connection', handleSocket);});