diff --git a/apprelays.js b/apprelays.js index bebe15eb..af29111c 100644 --- a/apprelays.js +++ b/apprelays.js @@ -183,6 +183,10 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain, } } } + tunnel.onNextRequest = function () { + parent.parent.debug('webrelay', 'tunnel-onNextRequest'); + handleNextRequest(); + } tunnel.connect(userid, nodeid, addr, port, appid); tunnel.tunnelId = nextTunnelId++; tunnels[tunnel.tunnelId] = tunnel; @@ -235,6 +239,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) { obj.onclose = null; obj.oncompleted = null; obj.onconnect = null; + obj.onNextRequest = null; // Process a HTTP request obj.processRequest = function (req, res) { @@ -244,9 +249,6 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) { // Check if this is a websocket if (req.headers['upgrade'] == 'websocket') { console.log('Attempt to process a websocket in HTTP tunnel method.'); res.end(); return false; } - // Check if this is a streaming request - if ((req.headers['content-type'] != null) && (req.headers['content-type'].toLowerCase() == 'text/event-stream')) { obj.isStreaming = true; } - // Construct the HTTP request var request = req.method + ' ' + req.url + ' HTTP/' + req.httpVersion + '\r\n'; const blockedHeaders = ['origin', 'cookie', 'upgrade-insecure-requests', 'sec-ch-ua', 'sec-ch-ua-mobile', 'dnt', 'sec-fetch-user', 'sec-ch-ua-platform', 'sec-fetch-site', 'sec-fetch-mode', 'sec-fetch-dest']; // These are headers we do not forward @@ -510,6 +512,12 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) { } } + // Check if this is a streaming response + if ((obj.socketXHeader['content-type'] != null) && (obj.socketXHeader['content-type'].toLowerCase().indexOf('text/event-stream') >= 0)) { + obj.isStreaming = true; // This tunnel is now a streaming tunnel and will not close anytime soon. + if (obj.onNextRequest != null) obj.onNextRequest(); // Call this so that any HTTP requests that are waitting for this one to finish get handled by a new tunnel. + } + // Check if this HTTP request has a body if (obj.socketXHeader['content-length'] != null) { obj.socketParseState = 1; } if ((obj.socketXHeader['connection'] != null) && (obj.socketXHeader['connection'].toLowerCase() == 'close')) { obj.socketParseState = 1; } diff --git a/public/scripts/agent-redir-ws-0.1.1.js b/public/scripts/agent-redir-ws-0.1.1.js index ef5fcb38..d79a58f5 100644 --- a/public/scripts/agent-redir-ws-0.1.1.js +++ b/public/scripts/agent-redir-ws-0.1.1.js @@ -296,7 +296,8 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au //obj.debug('Agent Redir Socket Stopped'); obj.connectstate = -1; if (obj.socket != null) { - try { if (obj.socket.readyState == 1) { obj.sendCtrlMsg('{"ctrlChannel":"102938","type":"close"}'); obj.socket.close(); } } catch (e) { } + try { if (obj.socket.readyState == 1) { obj.sendCtrlMsg('{"ctrlChannel":"102938","type":"close"}'); } } catch (ex) { } // If connected, send the close command + try { if (obj.socket.readyState <= 1) { obj.socket.close(); } } catch (ex) { } // If connecting or connected, close the websocket obj.socket = null; } obj.xxStateChange(0); diff --git a/views/default.handlebars b/views/default.handlebars index 6e98a115..2bc05d12 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -9849,12 +9849,13 @@ // Called when the terminal state changes function onTerminalStateChange(xterminal, state) { + if (terminal != xterminal) return; var xstate = state; if ((xstate == 3) && (xterminal.contype == 2)) { xstate++; } var str = StatusStrs[xstate]; if (xstate == 3) { - if (terminal.contype == 3) { str += ", SSH"; } - if (terminal.webRtcActive == true) { str += ", WebRTC"; } + if (xterminal.contype == 3) { str += ", SSH"; } + if (xterminal.webRtcActive == true) { str += ", WebRTC"; } } QH('termstatus', str); switch (state) { @@ -9863,17 +9864,16 @@ QH('termtitle', ''); QV('termRecordIcon', false); if (xterm == null) { - xterminal.m.TermResetScreen(); - xterminal.m.TermDraw(); + try { xterminal.m.TermResetScreen(); xterminal.m.TermDraw(); } catch (ex) { } } else { xterm.dispose(); xterm = xtermfit = null; } - if (terminal != null) { terminal.Stop(); terminal = null; } + if (xterminal != null) { xterminal.Stop(); terminal = null; } break; case 3: if (xterminal && (xterminal.serverIsRecording == true)) { QV('termRecordIcon', true); } - terminal.startTime = new Date(); + xterminal.startTime = new Date(); if (updateSessionTimer == null) { updateSessionTimer = setInterval(updateSessionTime, 1000); } if (xterm != null) { xterm.focus(); } break; @@ -9902,7 +9902,7 @@ return obj; } - function tunnelUpdate(data) { if (typeof data == 'string') { xterm.writeUtf8(data); } else { xterm.writeUtf8(new Uint8Array(data)); } } + function tunnelUpdate(data) { if (xterm != null) { if (typeof data == 'string') { xterm.writeUtf8(data); } else { xterm.writeUtf8(new Uint8Array(data)); } } } function sshTunnelAuthDialog(j, func) { var x = '';