Web relay text/event-stream improvement (#4369) and relay disconnect fix.

Ylian Saint-Hilaire committed Aug 5, 2022 at 15:39 UTC fe24dccd8cd055808d38e362bd4040e00535c0f4
3 files changed +20 -11
apprelays.js
+11 -3
@@ -183,6 +183,10 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain,
183 }
184 }
185 }
186 + tunnel.onNextRequest = function () {
187 + parent.parent.debug('webrelay', 'tunnel-onNextRequest');
188 + handleNextRequest();
189 + }
190 tunnel.connect(userid, nodeid, addr, port, appid);
191 tunnel.tunnelId = nextTunnelId++;
192 tunnels[tunnel.tunnelId] = tunnel;
@@ -235,6 +239,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
239 obj.onclose = null;
240 obj.oncompleted = null;
241 obj.onconnect = null;
242 + obj.onNextRequest = null;
243
244 // Process a HTTP request
245 obj.processRequest = function (req, res) {
@@ -244,9 +249,6 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
249 // Check if this is a websocket
250 if (req.headers['upgrade'] == 'websocket') { console.log('Attempt to process a websocket in HTTP tunnel method.'); res.end(); return false; }
251
247 - // Check if this is a streaming request
248 - if ((req.headers['content-type'] != null) && (req.headers['content-type'].toLowerCase() == 'text/event-stream')) { obj.isStreaming = true; }
249 -
252 // Construct the HTTP request
253 var request = req.method + ' ' + req.url + ' HTTP/' + req.httpVersion + '\r\n';
254 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) {
512 }
513 }
514
515 + // Check if this is a streaming response
516 + if ((obj.socketXHeader['content-type'] != null) && (obj.socketXHeader['content-type'].toLowerCase().indexOf('text/event-stream') >= 0)) {
517 + obj.isStreaming = true; // This tunnel is now a streaming tunnel and will not close anytime soon.
518 + 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.
519 + }
520 +
521 // Check if this HTTP request has a body
522 if (obj.socketXHeader['content-length'] != null) { obj.socketParseState = 1; }
523 if ((obj.socketXHeader['connection'] != null) && (obj.socketXHeader['connection'].toLowerCase() == 'close')) { obj.socketParseState = 1; }
public/scripts/agent-redir-ws-0.1.1.js
+2 -1
@@ -296,7 +296,8 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
296 //obj.debug('Agent Redir Socket Stopped');
297 obj.connectstate = -1;
298 if (obj.socket != null) {
299 - try { if (obj.socket.readyState == 1) { obj.sendCtrlMsg('{"ctrlChannel":"102938","type":"close"}'); obj.socket.close(); } } catch (e) { }
299 + try { if (obj.socket.readyState == 1) { obj.sendCtrlMsg('{"ctrlChannel":"102938","type":"close"}'); } } catch (ex) { } // If connected, send the close command
300 + try { if (obj.socket.readyState <= 1) { obj.socket.close(); } } catch (ex) { } // If connecting or connected, close the websocket
301 obj.socket = null;
302 }
303 obj.xxStateChange(0);
views/default.handlebars
+7 -7
@@ -9849,12 +9849,13 @@
9849
9850 // Called when the terminal state changes
9851 function onTerminalStateChange(xterminal, state) {
9852 + if (terminal != xterminal) return;
9853 var xstate = state;
9854 if ((xstate == 3) && (xterminal.contype == 2)) { xstate++; }
9855 var str = StatusStrs[xstate];
9856 if (xstate == 3) {
9856 - if (terminal.contype == 3) { str += ", SSH"; }
9857 - if (terminal.webRtcActive == true) { str += ", WebRTC"; }
9857 + if (xterminal.contype == 3) { str += ", SSH"; }
9858 + if (xterminal.webRtcActive == true) { str += ", WebRTC"; }
9859 }
9860 QH('termstatus', str);
9861 switch (state) {
@@ -9863,17 +9864,16 @@
9864 QH('termtitle', '');
9865 QV('termRecordIcon', false);
9866 if (xterm == null) {
9866 - xterminal.m.TermResetScreen();
9867 - xterminal.m.TermDraw();
9867 + try { xterminal.m.TermResetScreen(); xterminal.m.TermDraw(); } catch (ex) { }
9868 } else {
9869 xterm.dispose();
9870 xterm = xtermfit = null;
9871 }
9872 - if (terminal != null) { terminal.Stop(); terminal = null; }
9872 + if (xterminal != null) { xterminal.Stop(); terminal = null; }
9873 break;
9874 case 3:
9875 if (xterminal && (xterminal.serverIsRecording == true)) { QV('termRecordIcon', true); }
9876 - terminal.startTime = new Date();
9876 + xterminal.startTime = new Date();
9877 if (updateSessionTimer == null) { updateSessionTimer = setInterval(updateSessionTime, 1000); }
9878 if (xterm != null) { xterm.focus(); }
9879 break;
@@ -9902,7 +9902,7 @@
9902 return obj;
9903 }
9904
9905 - function tunnelUpdate(data) { if (typeof data == 'string') { xterm.writeUtf8(data); } else { xterm.writeUtf8(new Uint8Array(data)); } }
9905 + function tunnelUpdate(data) { if (xterm != null) { if (typeof data == 'string') { xterm.writeUtf8(data); } else { xterm.writeUtf8(new Uint8Array(data)); } } }
9906
9907 function sshTunnelAuthDialog(j, func) {
9908 var x = '';