Improved handling of HTTP session socket closure (#4369)

Ylian Saint-Hilaire committed Aug 8, 2022 at 16:39 UTC 1257c4bc3a4e2848076bf0984a8b8a2381254a9b
1 file changed +11 -1
apprelays.js
+11 -1
@@ -241,6 +241,9 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
241 obj.onconnect = null;
242 obj.onNextRequest = null;
243
244 + // Called when we need to close the tunnel because the response stream has closed
245 + function handleResponseClosure() { obj.close(); }
246 +
247 // Process a HTTP request
248 obj.processRequest = function (req, res) {
249 if (obj.relayActive == false) { console.log("ERROR: Attempt to use an unconnected tunnel"); return false; }
@@ -249,6 +252,9 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
252 // Check if this is a websocket
253 if (req.headers['upgrade'] == 'websocket') { console.log('Attempt to process a websocket in HTTP tunnel method.'); res.end(); return false; }
254
255 + // If the response stream is closed, close this tunnel right away
256 + res.socket.on('end', handleResponseClosure);
257 +
258 // Construct the HTTP request
259 var request = req.method + ' ' + req.url + ' HTTP/' + req.httpVersion + '\r\n';
260 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
@@ -288,6 +294,9 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
294 // Pause the websocket until we get a tunnel connected
295 obj.ws._socket.pause();
296
297 + // If the response stream is closed, close this tunnel right away
298 + res.socket.on('end', function () { obj.close(); });
299 +
300 // Remove the trailing '/.websocket' if needed
301 var baseurl = req.url, i = req.url.indexOf('?');
302 if (i > 0) { baseurl = req.url.substring(0, i); }
@@ -392,7 +401,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
401 }
402
403 // Close any pending request
395 - if (obj.res) { obj.res.end(); delete obj.res; }
404 + if (obj.res) { obj.res.socket.removeListener('end', handleResponseClosure); obj.res.end(); delete obj.res; }
405 if (obj.ws) { obj.ws.close(); delete obj.ws; }
406
407 // Event disconnection
@@ -689,6 +698,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
698 // If we are done, close the response
699 if (done == true) {
700 // Close the response
701 + obj.res.socket.removeListener('end', handleResponseClosure);
702 obj.res.end();
703 delete obj.res;
704