From 4cb8e99430bcb6667e6e42dd9b22ea24f1bad313 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 26 Apr 2021 11:45:28 +0100 Subject: [PATCH] Timeout http upgrade requests that are not otherwise handled Fixes #2956 --- .../@node-red/runtime/lib/index.js | 21 +++++++++++++++++++ packages/node_modules/node-red/settings.js | 6 ++++++ 2 files changed, 27 insertions(+) diff --git a/packages/node_modules/@node-red/runtime/lib/index.js b/packages/node_modules/@node-red/runtime/lib/index.js index 30481740f..c09d202f9 100644 --- a/packages/node_modules/@node-red/runtime/lib/index.js +++ b/packages/node_modules/@node-red/runtime/lib/index.js @@ -64,6 +64,27 @@ var server; */ function init(userSettings,httpServer,_adminApi) { server = httpServer; + + if (server && server.on) { + // Add a listener to the upgrade event so that we can properly timeout connection + // attempts that do not get handled by any nodes in the user's flow. + // See #2956 + server.on('upgrade',(request, socket, head) => { + // Add a no-op handler to the error event in case nothing upgrades this socket + // before the remote end closes it. This ensures we don't get as uncaughtException + socket.on("error", err => {}) + setTimeout(function() { + // If this request has been handled elsewhere, the upgrade will have + // been completed and bytes written back to the client. + // If nothing has been written on the socket, nothing has handled the + // upgrade, so we can consider this an unhandled upgrade. + if (socket.bytesWritten === 0) { + socket.destroy(); + } + },userSettings.inboundWebSocketTimeout || 5000) + }); + } + userSettings.version = getVersion(); settings.init(userSettings); diff --git a/packages/node_modules/node-red/settings.js b/packages/node_modules/node-red/settings.js index 331654ed8..a39731f37 100644 --- a/packages/node_modules/node-red/settings.js +++ b/packages/node_modules/node-red/settings.js @@ -46,6 +46,12 @@ module.exports = { // defaults to 10Mb //execMaxBufferSize: 10000000, + // Timeout in milliseconds for inbound WebSocket connections that do not + // match any configured node. + // defaults to 5000 + //inboundWebSocketTimeout: 5000 + + // The maximum length, in characters, of any message sent to the debug sidebar tab debugMaxLength: 1000,