From 04c8dd979ce40acaceec1f4507c1ae69325d6158 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Tue, 17 Sep 2024 15:52:14 +0200 Subject: [PATCH] fix(sio-client): close the engine upon decoding exception Related: https://github.com/socketio/socket.io/issues/5128 --- .github/workflows/ci-browser.yml | 2 +- packages/socket.io-client/lib/manager.ts | 8 ++++-- packages/socket.io-client/test/connection.ts | 27 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-browser.yml b/.github/workflows/ci-browser.yml index 7cbbbebc75..f7e495b84a 100644 --- a/.github/workflows/ci-browser.yml +++ b/.github/workflows/ci-browser.yml @@ -14,7 +14,7 @@ permissions: jobs: test-browser: runs-on: ubuntu-latest - timeout-minutes: 10 + timeout-minutes: 20 steps: - name: Checkout repository diff --git a/packages/socket.io-client/lib/manager.ts b/packages/socket.io-client/lib/manager.ts index 8330af13ff..35bae86ae6 100644 --- a/packages/socket.io-client/lib/manager.ts +++ b/packages/socket.io-client/lib/manager.ts @@ -531,7 +531,6 @@ export class Manager< this.skipReconnect = true; this._reconnecting = false; this.onclose("forced close"); - if (this.engine) this.engine.close(); } /** @@ -544,7 +543,11 @@ export class Manager< } /** - * Called upon engine close. + * Called when: + * + * - the low-level engine is closed + * - the parser encountered a badly formatted packet + * - all sockets are disconnected * * @private */ @@ -552,6 +555,7 @@ export class Manager< debug("closed due to %s", reason); this.cleanup(); + this.engine?.close(); this.backoff.reset(); this._readyState = "closed"; this.emitReserved("close", reason, description); diff --git a/packages/socket.io-client/test/connection.ts b/packages/socket.io-client/test/connection.ts index 9a922e9578..7cebb5b14a 100644 --- a/packages/socket.io-client/test/connection.ts +++ b/packages/socket.io-client/test/connection.ts @@ -4,6 +4,7 @@ import hasCORS from "has-cors"; import { install } from "@sinonjs/fake-timers"; import textBlobBuilder from "text-blob-builder"; import { BASE_URL, wrap } from "./support/util"; +import { nextTick } from "engine.io-client"; describe("connection", () => { it("should connect to localhost", () => { @@ -896,4 +897,30 @@ describe("connection", () => { }); }); }); + + it("should close the engine upon decoding exception", () => { + return wrap((done) => { + const manager = new Manager(BASE_URL, { + autoConnect: true, + reconnectionDelay: 50, + }); + + let engine = manager.engine; + + manager.on("open", () => { + nextTick(() => { + // @ts-expect-error emit() is private + manager.engine.emit("data", "bad"); + }); + }); + + manager.on("reconnect", () => { + expect(manager.engine === engine).to.be(false); + expect(engine.readyState).to.eql("closed"); + + manager._close(); + done(); + }); + }); + }); });