| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var net = require('net'); | 
					
						
							|  |  |  | var tls = require('tls'); | 
					
						
							|  |  |  | var http = require('http'); | 
					
						
							|  |  |  | var sni = require('sni'); | 
					
						
							|  |  |  | var url = require('url'); | 
					
						
							|  |  |  | var jwt = require('jsonwebtoken'); | 
					
						
							|  |  |  | //var packer = require('tunnel-packer');
 | 
					
						
							|  |  |  | //var Transform = require('stream').Transform;
 | 
					
						
							|  |  |  | var tlsOpts = require('localhost.daplie.com-certificates').merge({}); | 
					
						
							|  |  |  | var Duplex = require('stream').Duplex; | 
					
						
							|  |  |  | var WebSocketServer = require('ws').Server; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Tunnel Packer | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | var packer = require('tunnel-packer'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var Transform = require('stream').Transform; | 
					
						
							|  |  |  | var util = require('util'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function MyTransform(options) { | 
					
						
							|  |  |  |   if (!(this instanceof MyTransform)) { | 
					
						
							|  |  |  |     return new MyTransform(options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   this.__my_addr = options.address; | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |   this.__my_service = options.service; | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |   Transform.call(this, options); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | util.inherits(MyTransform, Transform); | 
					
						
							|  |  |  | function transform(me, data, encoding, callback) { | 
					
						
							|  |  |  |   var address = me.__my_addr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |   address.service = address.service || me.__my_service; | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |   me.push(packer.pack(address, data)); | 
					
						
							|  |  |  |   callback(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | MyTransform.prototype._transform = function (data, encoding, callback) { | 
					
						
							|  |  |  |   return transform(this, data, encoding, callback); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function socketToAddr(socket) { | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |   return { | 
					
						
							|  |  |  |     family: socket.remoteFamily || socket._remoteFamily | 
					
						
							|  |  |  |   , address: socket.remoteAddress || socket._remoteAddress | 
					
						
							|  |  |  |   , port: socket.remotePort || socket._remotePort | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function addrToId(address) { | 
					
						
							|  |  |  |   return address.family + ',' + address.address + ',' + address.port; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function socketToId(socket) { | 
					
						
							|  |  |  |   return addrToId(socketToAddr(socket)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  | require('cluster-store').create().then(function (store) { | 
					
						
							|  |  |  |   var remotes = {}; | 
					
						
							|  |  |  |   var selfname = 'pokemap.hellabit.com'; | 
					
						
							|  |  |  |   var secret = 'shhhhh'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var httpServer = http.createServer(function (req, res) { | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |     console.log('req.socket.encrypted', req.socket.encrypted); | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |     res.end('Hello, World!'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   var wss = new WebSocketServer({ server: httpServer }); | 
					
						
							|  |  |  |   var tcp3000 = net.createServer(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  | 	wss.on('connection', function (ws) { | 
					
						
							|  |  |  |     console.log('todo connection'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  | 		var location = url.parse(ws.upgradeReq.url, true); | 
					
						
							|  |  |  |     //var token = jwt.decode(location.query.access_token);
 | 
					
						
							|  |  |  |     var token = jwt.verify(location.query.access_token, secret); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |     console.log('location, token'); | 
					
						
							|  |  |  |     console.log(location.query.access_token); | 
					
						
							|  |  |  |     console.log(token); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |     if (!token) { | 
					
						
							|  |  |  |       ws.send({ error: { message: "invalid access token", code: "E_INVALID_TOKEN" } }); | 
					
						
							|  |  |  |       ws.close(); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |     console.log('token.name:', token.name); | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |     if (!token.name) { | 
					
						
							|  |  |  |       ws.send({ error: { message: "invalid server name", code: "E_INVALID_NAME" } }); | 
					
						
							|  |  |  |       ws.close(); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ws.on('close', function () { | 
					
						
							|  |  |  |       console.log("TODO cleanup"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |     var remote = remotes[token.name] = remotes[token.name] || {}; | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |     // TODO allow more than one remote per servername
 | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |     remote.ws = ws; | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |     remote.servername = token.name; | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |     remote.id = socketToId(ws.upgradeReq.socket); | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |     console.log("remote.id", remote.id); | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |     // TODO allow tls to be decrypted by server if client is actually a browser
 | 
					
						
							|  |  |  |     // and we haven't implemented tls in the browser yet
 | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |     remote.decrypt = token.decrypt; | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |     // TODO how to allow a child process to communicate with this one?
 | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |     remote.clients = {}; | 
					
						
							|  |  |  |     remote.handle = { address: null, handle: null }; | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |     remote.unpacker = packer.create({ onMessage: function (opts) { | 
					
						
							|  |  |  |       // opts.data
 | 
					
						
							|  |  |  |       var cid = addrToId(opts); | 
					
						
							|  |  |  |       var cstream = remote.clients[cid]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       console.log("remote '" + remote.servername + " : " + remote.id + "' has data for '" + cid + "'", opts.data.byteLength); | 
					
						
							|  |  |  |       console.log('cstream.remoteAddress', cstream.remoteAddress, cstream.remoteAddress); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!cstream) { | 
					
						
							|  |  |  |         // TODO end
 | 
					
						
							|  |  |  |         console.log('TODO: [end] no client for', cid, opts.data.toString('utf8').substr(0, 100)); | 
					
						
							|  |  |  |         //remote.socket.write(packer.pack(opts, Buffer.from('|__END__|')));
 | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |       cstream.browser.write(opts.data); | 
					
						
							|  |  |  |     } }); | 
					
						
							|  |  |  |     ws.on('message', function (chunk) { | 
					
						
							|  |  |  |       console.log('message from home cloud to tunneler to browser', chunk.byteLength); | 
					
						
							|  |  |  |       remote.unpacker.fns.addChunk(chunk); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     store.set(token.name, remote.handle); | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tcp3000.listen(3000, function () { | 
					
						
							|  |  |  |     console.log('listening on 3000'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var tls3000 = tls.createServer(tlsOpts, function (tlsSocket) { | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |     console.log('tls connection'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* | 
					
						
							|  |  |  |     tlsSocket.on('data', function (chunk) { | 
					
						
							|  |  |  |       console.log('secure chunk'); | 
					
						
							|  |  |  |       console.log(''); | 
					
						
							|  |  |  |       console.log(chunk.toString()); | 
					
						
							|  |  |  |       console.log(''); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |     console.log(''); | 
					
						
							|  |  |  |     console.log(''); | 
					
						
							|  |  |  |     console.log(''); | 
					
						
							|  |  |  |     console.log('tlsSocket.*Address'); | 
					
						
							|  |  |  |     console.log(''); | 
					
						
							|  |  |  |     //console.log(tlsSocket._handle._parentWrap._handle.owner.stream);
 | 
					
						
							|  |  |  |     console.log('r', tlsSocket._handle._parentWrap._handle.owner.stream.remoteAddress); | 
					
						
							|  |  |  |     tlsSocket._remoteFamily = tlsSocket._handle._parentWrap._handle.owner.stream.remoteFamily; | 
					
						
							|  |  |  |     tlsSocket._remoteAddress = tlsSocket._handle._parentWrap._handle.owner.stream.remoteAddress; | 
					
						
							|  |  |  |     tlsSocket._remotePort = tlsSocket._handle._parentWrap._handle.owner.stream.remotePort; | 
					
						
							|  |  |  |     console.log('r', tlsSocket.remoteAddress); | 
					
						
							|  |  |  |     // https://github.com/nodejs/node/issues/8854
 | 
					
						
							|  |  |  |     // tlsSocket._remoteAddress = remoteAddress; // causes core dump
 | 
					
						
							|  |  |  |     console.log('s', tlsSocket._remoteAddress); | 
					
						
							|  |  |  |     //tlsSocket.remoteFamily = tlsSocket.remoteFamily || tlsSocket._handle._parentWrap._handle.owner.stream.remoteFamily;
 | 
					
						
							|  |  |  |     //tlsSocket.remoteAddress = tlsSocket.remoteAddress || tlsSocket._handle._parentWrap._handle.owner.remoteAddress;
 | 
					
						
							|  |  |  |     //tlsSocket.remotePort = tlsSocket.remotePort || tlsSocket._handle._parentWrap._handle.owner.remotePort;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //console.log(tlsSocket.localAddress);
 | 
					
						
							|  |  |  |     //console.log(tlsSocket.address);
 | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |     httpServer.emit('connection', tlsSocket); | 
					
						
							|  |  |  |     /* | 
					
						
							|  |  |  |     tlsSocket.on('data', function (chunk) { | 
					
						
							|  |  |  |       console.log('chunk', chunk.byteLength); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     */ | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var Dup = { | 
					
						
							|  |  |  |     write: function (chunk, encoding, cb) { | 
					
						
							|  |  |  |       //console.log('_write', chunk.byteLength);
 | 
					
						
							|  |  |  |       this.__my_socket.write(chunk, encoding); | 
					
						
							|  |  |  |       cb(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , read: function (size) { | 
					
						
							|  |  |  |       //console.log('_read');
 | 
					
						
							|  |  |  |       var x = this.__my_socket.read(size); | 
					
						
							|  |  |  |       if (x) { | 
					
						
							|  |  |  |         console.log('_read', size); | 
					
						
							|  |  |  |         this.push(x); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |   function connectHttp(servername, socket) { | 
					
						
							|  |  |  |     console.log("connectHttp('" + servername + "', socket)"); | 
					
						
							|  |  |  |     socket.__my_servername = servername; | 
					
						
							|  |  |  |     httpServer.emit('connection', socket); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function connectHttps(servername, socket) { | 
					
						
							|  |  |  |     // none of these methods work:
 | 
					
						
							|  |  |  |     // httpsServer.emit('connection', socket);  // this didn't work
 | 
					
						
							|  |  |  |     // tlsServer.emit('connection', socket);    // this didn't work either
 | 
					
						
							|  |  |  |     //console.log('chunkLen', firstChunk.byteLength);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var myDuplex = new Duplex(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     myDuplex.__my_socket = socket; | 
					
						
							|  |  |  |     myDuplex._write = Dup.write; | 
					
						
							|  |  |  |     myDuplex._read = Dup.read; | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |     console.log('plainSocket.*Address'); | 
					
						
							|  |  |  |     console.log('remote:', socket.remoteAddress); | 
					
						
							|  |  |  |     console.log('local:', socket.localAddress); | 
					
						
							|  |  |  |     console.log('address():', socket.address()); | 
					
						
							|  |  |  |     myDuplex.remoteFamily = socket.remoteFamily; | 
					
						
							|  |  |  |     myDuplex.remoteAddress = socket.remoteAddress; | 
					
						
							|  |  |  |     myDuplex.remotePort = socket.remotePort; | 
					
						
							|  |  |  |     myDuplex.localFamily = socket.localFamily; | 
					
						
							|  |  |  |     myDuplex.localAddress = socket.localAddress; | 
					
						
							|  |  |  |     myDuplex.localPort = socket.localPort; | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     console.log('connectHttps servername', servername); | 
					
						
							|  |  |  |     tls3000.emit('connection', myDuplex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     socket.on('data', function (chunk) { | 
					
						
							|  |  |  |       console.log('[' + Date.now() + '] socket data', chunk.byteLength); | 
					
						
							|  |  |  |       myDuplex.push(chunk); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |   function pipeWs(servername, service, browser, remote) { | 
					
						
							|  |  |  |     console.log('pipeWs'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //var remote = remotes[servername];
 | 
					
						
							|  |  |  |     var ws = remote.ws; | 
					
						
							|  |  |  |     //var address = socketToAddr(ws.upgradeReq.socket);
 | 
					
						
							|  |  |  |     var baddress = socketToAddr(browser); | 
					
						
							|  |  |  |     var cid = addrToId(baddress); | 
					
						
							|  |  |  |     console.log('servername:', servername); | 
					
						
							|  |  |  |     console.log('service:', service); | 
					
						
							|  |  |  |     baddress.service = service; | 
					
						
							|  |  |  |     var wrapForRemote = new MyTransform({ | 
					
						
							|  |  |  |       id: cid | 
					
						
							|  |  |  |     //, remoteId: remote.id
 | 
					
						
							|  |  |  |     , address: baddress | 
					
						
							|  |  |  |     , servername: servername | 
					
						
							|  |  |  |     , service: service | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     console.log('home-cloud is', socketToId(remote)); | 
					
						
							|  |  |  |     console.log('browser is', cid); | 
					
						
							|  |  |  |     var bstream = remote.clients[cid] = { | 
					
						
							|  |  |  |       wrapped: browser.pipe(wrapForRemote) | 
					
						
							|  |  |  |     , browser: browser | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     //var bstream = remote.clients[cid] = wrapForRemote.pipe(browser);
 | 
					
						
							|  |  |  |     bstream.wrapped.on('data', function (pchunk) { | 
					
						
							|  |  |  |       // var chunk = socket.read();
 | 
					
						
							|  |  |  |       console.log('[bstream] data from browser to tunneler', pchunk.byteLength); | 
					
						
							|  |  |  |       console.log(JSON.stringify(pchunk.toString())); | 
					
						
							|  |  |  |       ws.send(pchunk, { binary: true }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     bstream.wrapped.on('error', function () { | 
					
						
							|  |  |  |       // TODO send end to tunneler
 | 
					
						
							|  |  |  |       delete remote.clients[cid]; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     bstream.wrapped.on('end', function () { | 
					
						
							|  |  |  |       delete remote.clients[cid]; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tcp3000.on('connection', function (browser) { | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |     // this works when I put it here, but I don't know if it's tls yet here
 | 
					
						
							|  |  |  |     // httpsServer.emit('connection', socket);
 | 
					
						
							|  |  |  |     //tls3000.emit('connection', socket);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //var tlsSocket = new tls.TLSSocket(socket, { secureContext: tls.createSecureContext(tlsOpts) });
 | 
					
						
							|  |  |  |     //tlsSocket.on('data', function (chunk) {
 | 
					
						
							|  |  |  |     //  console.log('dummy', chunk.byteLength);
 | 
					
						
							|  |  |  |     //});
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //return;
 | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |     browser.once('data', function (firstChunk) { | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |       // BUG XXX: this assumes that the packet won't be chunked smaller
 | 
					
						
							|  |  |  |       // than the 'hello' or the point of the 'Host' header.
 | 
					
						
							|  |  |  |       // This is fairly reasonable, but there are edge cases where
 | 
					
						
							|  |  |  |       // it does not hold (such as manual debugging with telnet)
 | 
					
						
							|  |  |  |       // and so it should be fixed at some point in the future
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // defer after return (instead of being in many places)
 | 
					
						
							|  |  |  |       process.nextTick(function () { | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |         browser.unshift(firstChunk); | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var service = 'tcp'; | 
					
						
							|  |  |  |       var servername; | 
					
						
							|  |  |  |       var str; | 
					
						
							|  |  |  |       var m; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       function tryTls() { | 
					
						
							|  |  |  |         if (!servername || selfname === servername) { | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |           console.log('this is a server or an unknown'); | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |           connectHttps(servername, browser); | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (remotes[servername]) { | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |           console.log("pipeWs(servername, service, socket, remotes['" + servername + "'])"); | 
					
						
							|  |  |  |           pipeWs(servername, service, browser, remotes[servername]); | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // https://github.com/mscdex/httpolyglot/issues/3#issuecomment-173680155
 | 
					
						
							|  |  |  |       if (22 === firstChunk[0]) { | 
					
						
							|  |  |  |         // TLS
 | 
					
						
							|  |  |  |         service = 'https'; | 
					
						
							|  |  |  |         servername = (sni(firstChunk)||'').toLowerCase(); | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |         console.log("tls hello servername:", servername); | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |         tryTls(); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (firstChunk[0] > 32 && firstChunk[0] < 127) { | 
					
						
							|  |  |  |         str = firstChunk.toString(); | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |         m = str.match(/(?:^|[\r\n])Host: ([^\r\n]+)[\r\n]*/im); | 
					
						
							|  |  |  |         servername = (m && m[1].toLowerCase() || '').split(':')[0]; | 
					
						
							|  |  |  |         console.log('servername', servername); | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |         if (/HTTP\//i.test(str)) { | 
					
						
							|  |  |  |           service = 'http'; | 
					
						
							|  |  |  |           if (/\/\.well-known\//.test(str)) { | 
					
						
							|  |  |  |             // HTTP
 | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |             if (remotes[servername]) { | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |               pipeWs(servername, service, browser, remotes[servername]); | 
					
						
							| 
									
										
										
										
											2016-09-28 01:26:16 -04:00
										 |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |             connectHttp(servername, browser); | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             // redirect to https
 | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |             connectHttp(servername, browser); | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |           } | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       console.error("Got unexpected connection", str); | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |       browser.write(JSON.stringify({ error: { | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |         message: "not sure what you were trying to do there..." | 
					
						
							|  |  |  |       , code: 'E_INVALID_PROTOCOL' } | 
					
						
							|  |  |  |       })); | 
					
						
							| 
									
										
										
										
											2016-09-29 22:20:38 -04:00
										 |  |  |       browser.end(); | 
					
						
							| 
									
										
										
										
											2016-09-27 17:56:06 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); |