From 0c6ba4c1a866b0cf34330cc5d94ee3e34671067d Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Tue, 16 Jul 2019 14:02:52 +0100 Subject: [PATCH] monkeypatch socket.io to fix frame handler in v0.9.16 --- services/real-time/app.coffee | 3 ++ services/real-time/socket.io.patch.js | 43 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 services/real-time/socket.io.patch.js diff --git a/services/real-time/app.coffee b/services/real-time/app.coffee index 4effc386df..7b53730ce6 100644 --- a/services/real-time/app.coffee +++ b/services/real-time/app.coffee @@ -23,6 +23,9 @@ CookieParser = require("cookie-parser") DrainManager = require("./app/js/DrainManager") HealthCheckManager = require("./app/js/HealthCheckManager") +# work around frame handler bug in socket.io v0.9.16 +require("./socket.io.patch.js") + # Set up socket.io server app = express() Metrics.injectMetricsRoute(app) diff --git a/services/real-time/socket.io.patch.js b/services/real-time/socket.io.patch.js new file mode 100644 index 0000000000..21a9608133 --- /dev/null +++ b/services/real-time/socket.io.patch.js @@ -0,0 +1,43 @@ +var io = require("socket.io"); + +if (io.version === "0.9.16") { + console.log("patching socket.io hybi-16 transport frame prototype"); + var transports = require("socket.io/lib/transports/websocket/hybi-16.js"); + transports.prototype.frame = patchedFrameHandler; + // file hybi-07-12 has the same problem but no browsers are using that protocol now +} + +function patchedFrameHandler(opcode, str) { + var dataBuffer = new Buffer(str), + dataLength = dataBuffer.length, + startOffset = 2, + secondByte = dataLength; + if (dataLength === 65536) { + console.log("fixing invalid frame length in socket.io"); + } + if (dataLength > 65535) { + // original code had > 65536 + startOffset = 10; + secondByte = 127; + } else if (dataLength > 125) { + startOffset = 4; + secondByte = 126; + } + var outputBuffer = new Buffer(dataLength + startOffset); + outputBuffer[0] = opcode; + outputBuffer[1] = secondByte; + dataBuffer.copy(outputBuffer, startOffset); + switch (secondByte) { + case 126: + outputBuffer[2] = dataLength >>> 8; + outputBuffer[3] = dataLength % 256; + break; + case 127: + var l = dataLength; + for (var i = 1; i <= 8; ++i) { + outputBuffer[startOffset - i] = l & 0xff; + l >>>= 8; + } + } + return outputBuffer; +}