forked from coolaj86/goldilocks.js
		
	
		
			
				
	
	
		
			138 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| module.exports.create = function (opts, servers) {
 | |
|   // servers = { plainserver, server }
 | |
|   var Oauth3 = require('oauth3-cli');
 | |
|   var Tunnel = require('daplie-tunnel').create({
 | |
|     Oauth3: Oauth3
 | |
|   , PromiseA: opts.PromiseA
 | |
|   , CLI: {
 | |
|       init: function (/*rs, ws, state, options*/) {
 | |
|         // noop
 | |
|       }
 | |
|     }
 | |
|   }).Tunnel;
 | |
|   var stunnel = require('stunnel');
 | |
|   var killcount = 0;
 | |
| 
 | |
|   /*
 | |
|   var Dup = {
 | |
|     write: function (chunk, encoding, cb) {
 | |
|       this.__my_socket.push(chunk, encoding);
 | |
|       cb();
 | |
|     }
 | |
|   , read: function (size) {
 | |
|       var x = this.__my_socket.read(size);
 | |
|       if (x) { this.push(x); }
 | |
|     }
 | |
|   , setTimeout: function () {
 | |
|       console.log('TODO implement setTimeout on Duplex');
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var httpServer = require('http').createServer(function (req, res) {
 | |
|     console.log('req.socket.encrypted', req.socket.encrypted);
 | |
|     res.end('Hello, tunneled World!');
 | |
|   });
 | |
| 
 | |
|   var tlsServer = require('tls').createServer(opts.httpsOptions, function (tlsSocket) {
 | |
|     console.log('tls connection');
 | |
|     // things get a little messed up here
 | |
|     httpServer.emit('connection', tlsSocket);
 | |
| 
 | |
|     // try again
 | |
|     //servers.server.emit('connection', tlsSocket);
 | |
|   });
 | |
|   */
 | |
| 
 | |
|   process.on('SIGINT', function () {
 | |
|     killcount += 1;
 | |
|     console.log('[quit] closing http and https servers');
 | |
|     if (killcount >= 3) {
 | |
|       process.exit(1);
 | |
|     }
 | |
|     if (servers.server) {
 | |
|       servers.server.close();
 | |
|     }
 | |
|     if (servers.insecureServer) {
 | |
|       servers.insecureServer.close();
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   return Tunnel.token({
 | |
|     refreshToken: opts.refreshToken
 | |
|   , email: opts.email
 | |
|   , domains: [ opts.servername ]
 | |
|   , device: { hostname: opts.devicename || opts.device }
 | |
|   }).then(function (result) {
 | |
|     // { jwt, tunnelUrl }
 | |
|     return stunnel.connect({
 | |
|       token: result.jwt
 | |
|     , stunneld: result.tunnelUrl
 | |
|       // XXX TODO BUG // this is just for testing
 | |
|     , insecure: /*opts.insecure*/ true
 | |
|     , locals: [
 | |
|         { protocol: 'https'
 | |
|         , hostname: opts.servername
 | |
|         , port: opts.port
 | |
|         }
 | |
|       , { protocol: 'http'
 | |
|         , hostname: opts.servername
 | |
|         , port: opts.insecurePort || opts.port
 | |
|         }
 | |
|       ]
 | |
|       // a simple passthru is proving to not be so simple
 | |
|     , net: require('net') /*
 | |
|       {
 | |
|         createConnection: function (info, cb) {
 | |
|           // data is the hello packet / first chunk
 | |
|           // info = { data, servername, port, host, remoteAddress: { family, address, port } }
 | |
| 
 | |
|           var myDuplex = new (require('stream').Duplex)();
 | |
|           var myDuplex2 = new (require('stream').Duplex)();
 | |
|           // duplex = { write, push, end, events: [ 'readable', 'data', 'error', 'end' ] };
 | |
| 
 | |
|           myDuplex2.__my_socket = myDuplex;
 | |
|           myDuplex.__my_socket = myDuplex2;
 | |
| 
 | |
|           myDuplex2._write = Dup.write;
 | |
|           myDuplex2._read = Dup.read;
 | |
| 
 | |
|           myDuplex._write = Dup.write;
 | |
|           myDuplex._read = Dup.read;
 | |
| 
 | |
|           myDuplex.remoteFamily = info.remoteFamily;
 | |
|           myDuplex.remoteAddress = info.remoteAddress;
 | |
|           myDuplex.remotePort = info.remotePort;
 | |
| 
 | |
|           // socket.local{Family,Address,Port}
 | |
|           myDuplex.localFamily = 'IPv4';
 | |
|           myDuplex.localAddress = '127.0.01';
 | |
|           myDuplex.localPort = info.port;
 | |
| 
 | |
|           myDuplex.setTimeout = Dup.setTimeout;
 | |
| 
 | |
|           // this doesn't seem to work so well
 | |
|           //servers.server.emit('connection', myDuplex);
 | |
| 
 | |
|           // try a little more manual wrapping / unwrapping
 | |
|           var firstByte = info.data[0];
 | |
|           if (firstByte < 32 || firstByte >= 127) {
 | |
|             tlsServer.emit('connection', myDuplex);
 | |
|           }
 | |
|           else {
 | |
|             httpServer.emit('connection', myDuplex);
 | |
|           }
 | |
| 
 | |
|           if (cb) {
 | |
|             process.nextTick(cb);
 | |
|           }
 | |
| 
 | |
|           return myDuplex2;
 | |
|         }
 | |
|       }
 | |
|       //*/
 | |
|     });
 | |
|   });
 | |
| };
 |