2018-06-01 06:41:32 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var Packer = require('proxy-packer');
|
|
|
|
|
2018-06-19 23:43:28 +00:00
|
|
|
module.exports = function pipeWs(servername, service, srv, conn, serviceport) {
|
2018-06-01 06:41:32 +00:00
|
|
|
var browserAddr = Packer.socketToAddr(conn);
|
|
|
|
var cid = Packer.addrToId(browserAddr);
|
|
|
|
browserAddr.service = service;
|
|
|
|
browserAddr.serviceport = serviceport;
|
|
|
|
browserAddr.name = servername;
|
|
|
|
conn.tunnelCid = cid;
|
2018-06-19 23:43:28 +00:00
|
|
|
var rid = Packer.socketToId(srv.upgradeReq.socket);
|
2018-06-01 06:41:32 +00:00
|
|
|
|
|
|
|
//if (state.debug) { console.log('[pipeWs] client', cid, '=> remote', rid, 'for', servername, 'via', service); }
|
|
|
|
|
|
|
|
function sendWs(data, serviceOverride) {
|
2018-06-19 23:43:28 +00:00
|
|
|
if (srv.ws && (!conn.tunnelClosing || serviceOverride)) {
|
2018-06-01 06:41:32 +00:00
|
|
|
try {
|
2018-06-19 23:43:28 +00:00
|
|
|
srv.ws.send(Packer.pack(browserAddr, data, serviceOverride), { binary: true });
|
2018-06-01 06:41:32 +00:00
|
|
|
// If we can't send data over the websocket as fast as this connection can send it to us
|
|
|
|
// (or there are a lot of connections trying to send over the same websocket) then we
|
|
|
|
// need to pause the connection for a little. We pause all connections if any are paused
|
|
|
|
// to make things more fair so a connection doesn't get stuck waiting for everyone else
|
|
|
|
// to finish because it got caught on the boundary. Also if serviceOverride is set it
|
|
|
|
// means the connection is over, so no need to pause it.
|
2018-06-19 23:43:28 +00:00
|
|
|
if (!serviceOverride && (srv.pausedConns.length || srv.ws.bufferedAmount > 1024*1024)) {
|
2018-06-01 06:41:32 +00:00
|
|
|
// console.log('pausing', cid, 'to allow web socket to catch up');
|
|
|
|
conn.pause();
|
2018-06-19 23:43:28 +00:00
|
|
|
srv.pausedConns.push(conn);
|
2018-06-01 06:41:32 +00:00
|
|
|
}
|
|
|
|
} catch (err) {
|
2018-06-19 23:43:28 +00:00
|
|
|
console.warn('[pipeWs] srv', rid, ' => client', cid, 'error sending websocket message', err);
|
2018-06-01 06:41:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-19 23:43:28 +00:00
|
|
|
srv.clients[cid] = conn;
|
|
|
|
conn.servername = servername;
|
|
|
|
conn.serviceport = serviceport;
|
|
|
|
conn.service = service;
|
2018-06-01 06:41:32 +00:00
|
|
|
|
|
|
|
conn.on('data', function (chunk) {
|
2018-06-19 23:43:28 +00:00
|
|
|
//if (state.debug) { console.log('[pipeWs] client', cid, ' => srv', rid, chunk.byteLength, 'bytes'); }
|
2018-06-01 06:41:32 +00:00
|
|
|
sendWs(chunk);
|
|
|
|
});
|
|
|
|
|
|
|
|
conn.on('error', function (err) {
|
|
|
|
console.warn('[pipeWs] client', cid, 'connection error:', err);
|
|
|
|
});
|
|
|
|
|
|
|
|
conn.on('close', function (hadErr) {
|
|
|
|
//if (state.debug) { console.log('[pipeWs] client', cid, 'closing'); }
|
|
|
|
sendWs(null, hadErr ? 'error': 'end');
|
2018-06-19 23:43:28 +00:00
|
|
|
delete srv.clients[cid];
|
2018-06-01 06:41:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
};
|