X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fkiak.git;a=blobdiff_plain;f=main.js;h=b24e9f39f6c16c208bd17d6d21f32ae44c27f82c;hp=2db22401c5e2e73cd1ea0b4adaf45cc1c998fcfa;hb=69adc9a3512752d627e126dde85c859fcba9fb63;hpb=d37eeff687a6a392fb574e602940b4e96b828aea diff --git a/main.js b/main.js index 2db2240..b24e9f3 100644 --- a/main.js +++ b/main.js @@ -1,50 +1,129 @@ const fs = require('fs') const ws = require('ws') const https = require('https') -const http = require('http') const getport = require('get-port') -const argv = require('minimist')(process.argv.slice(2)) +const mime = require('mime') -const https_router_opts = { - key: fs.readFileSync('stunnel.key'), - cert: fs.readFileSync('stunnel.cert') +const argv = require('minimist')(process.argv.slice(2), { + string: [ 'ca-cert', 'ca-key', 'config', 'client-js', 'host-js', 'electron', 'port' ], + boolean: [ 'remote-host' ], + alias: { c: 'config', + j: 'client-js', + J: 'host-js', + C: 'ca-cert', + K: 'ca-key', + e: 'electron', + r: 'remote-host', + p: 'port' + }, + default: { config: undefined, + 'client-js': 'client.js', + 'host-js': 'host.js', + 'ca-cert': 'stunnel.cert', + 'ca-key': 'stunnel.key', + 'remote-host': true, + 'port': 2443 + }, + stopEarly: true, + unknown: (opt) => { + console.log(process.argv.join(" ") + '\nUnknown operator: ' + opt + ` +Usage: strapp [OPTION]... +Route https connections from a hardware port to a remote host, and initiate +peer-to-peer connection with clients. + +CONFIG + -c, --config=path Configuration file to use (/etc/strapp.conf) + - overridden by command line opts + -j, --client-js=path Path to the client Strapp code (./strapp-client.js) + -J, --host-js=path Path to the host Strapp code (./strapp-host.js) + -C, --ca-cert=path Accessible location of the CA Cert (./stunnel.cert) + -K, --ca-key=path Accessible location of the CA Key (./stunnel.key) + -p, --port=number The local port to bind HTTPS listener to (2443) + +ROUTING + -e, --electron=route Route to the local electron user (nil) + - enables optional electron dependency + -d, --dedicated=route Route all incoming connections to this route (nil) + - used in conjunction with '-e=my_route' + +(c)2017 jk software +`) + process.exit() + } +}) + +//TODO: if (argv['config'] !== undefined), read and apply to argv without overwrite +if (argv['www-path'] == undefined) + argv['www-path'] = 'www' +else if (String(argv['www-path']).endsWith('/')) + argv['www-path'] = argv['www-path'].slice(0,-1) + +const routerOpts = { + key: fs.readFileSync(argv['ca-key']), + cert: fs.readFileSync(argv['ca-cert']) } +const skelPage = String(fs.readFileSync('skel.html')).split("") +const clientJS = fs.readFileSync(argv['client-js']) +const hostJS = fs.readFileSync(argv['host-js']) +const routes = {} +const fileBuf = {} +let fbSize = 0 +fs.readdirSync(argv['www-path']).forEach((file) => { + if (fbSize++ < 50) { + fileBuf[file] = { mime: mime.lookup(argv['www-path'] + '/' + file), + data: fs.readFileSync(argv['www-path'] + '/' + file) + } + } +}) -let https_routes = {} -const https_router = https.createServer(https_router_opts, (request, response) => { - let ht_argv = request.url.slice(1).split("?") - console.log(ht_argv) - if (ht_argv[0] in https_routes) { - response.writeHead(200, { 'Content-Type': 'text/plain' }) - response.write('You are a remote client\r\n') - let route = https_routes[ht_argv[0]] - response.write('You should connect to ' + route.host + "\r\nOn port: " + route.port + "\r\n") +const router = https.createServer(routerOpts, (request, response) => { + const htArgv = request.url.slice(1).split("?") + let routeName = htArgv[0].split('/')[0] + if (routeName === '') + routeName = 'index.html' + if (routeName.indexOf('.') != -1) { + if (routeName in fileBuf) { + response.writeHead(200, { 'Content-Type': fileBuf[routeName].mime }) + response.write(fileBuf[routeName].data) + } + else { + if ('404.html' in fileBuf) { + response.writeHead(404, fileBuf['404.html'].mime) + response.write(fileBuf['404.html'].data) + } + else + response.writeHead(404) + } response.end() } - else if (ht_argv[0].indexOf(".") == -1) { - https_routes[ht_argv[0]] = 'true' + else if (routeName in routes) { + const route = routes[routeName] response.writeHead(200, { 'Content-Type': 'text/html' }) - let new_route = {} - new_route.host = request.headers['x-forwarded-for'] || request.connection.remoteAddress + response.write(skelPage[0] + clientJS + skelPage[1]) + response.end() + route.socket.send(request.headers['x-forwarded-for'] || request.connection.remoteAddress) + } + else { + routes[htArgv[0]] = true + const newRoute = {} + newRoute.host = request.headers['x-forwarded-for'] || request.connection.remoteAddress getport().then( (port) => { - new_route.port = port - new_route.httpd = https.createServer(https_router_opts, (request, response) => { - }).listen(port) - new_route.ws = new ws.Server( { server: new_route.httpd } ) - new_route.ws.on('connection', (ws) => { console.log("socket connected"); ws.send("CONNECTED") } ) - new_route.ws.on('message', (msg) => { console.log("Received message" + msg) }) - console.log("Listening for websocket socket " + new_route.port + " on " + new_route.host) - console.log(new_route) - https_routes[ht_argv[0]] = new_route + newRoute.port = port + newRoute.httpd = https.createServer(routerOpts, (request, response) => { + }).listen(newRoute.port) + + newRoute.ws = new ws.Server( { server: newRoute.httpd } ) + newRoute.ws.on('connection', (ws) => { console.log("socket connected"); newRoute.socket = ws; ws.send("CONNECTED") } ) + newRoute.ws.on('message', (msg) => { console.log("Received message" + msg) }) + console.log("Listening for websocket " + newRoute.host + " on port " + newRoute.port) + routes[htArgv[0]] = newRoute }).then(() => { - let str = String(fs.readFileSync('remote-server.html')) - response.write(str.replace("$HOST","www.strapp.io").replace("$PORT",new_route.port)) + response.writeHead(200, { 'Content-Type': 'text/html' }) + response.write(skelPage[0] + 'const _strapp_host = \'www.strapp.io\'\n\tconst _strapp_port = \'' + newRoute.port + '\'\n' + hostJS + skelPage[1]) response.end() }) } -}).listen(2443) - - +}).listen(argv['port']) -if ("electron" in process.versions); +//TODO: if ("electron" in process.versions) open a local renderwindow, and route to it