From 046dd30786e1560e9e9ae8cf69b61055d17ab301 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Fri, 5 Aug 2022 11:47:03 -0700 Subject: [PATCH] Added support for text/event-stream in web relay (#4369) --- apprelays.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/apprelays.js b/apprelays.js index bc910eb3..bebe15eb 100644 --- a/apprelays.js +++ b/apprelays.js @@ -136,8 +136,8 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain, // Check to see if any of the tunnels are free var count = 0; for (var i in tunnels) { - count += (tunnels[i].isWebSocket ? 0 : 1); - if ((tunnels[i].relayActive == true) && (tunnels[i].res == null) && (tunnels[i].isWebSocket == false)) { + count += ((tunnels[i].isWebSocket || tunnels[i].isStreaming) ? 0 : 1); + if ((tunnels[i].relayActive == true) && (tunnels[i].res == null) && (tunnels[i].isWebSocket == false) && (tunnels[i].isStreaming == false)) { // Found a free tunnel, use it const x = pendingRequests.shift(); if (x[2] == true) { tunnels[i].processWebSocket(x[0], x[1]); } else { tunnels[i].processRequest(x[0], x[1]); } @@ -226,7 +226,8 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) { obj.lastOperation = Date.now(); obj.relayActive = false; obj.closed = false; - obj.isWebSocket = false; + obj.isWebSocket = false; // If true, this request will not close and so, it can't be allowed to hold up other requests + obj.isStreaming = false; // If true, this request will not close and so, it can't be allowed to hold up other requests obj.processedRequestCount = 0; const constants = (require('crypto').constants ? require('crypto').constants : require('constants')); // require('constants') is deprecated in Node 11.10, use require('crypto').constants instead. @@ -243,6 +244,9 @@ 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