From fcec1f44ada51099f56cbd8089a70c57e54ba28c Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Wed, 18 Sep 2024 15:56:20 +0200 Subject: [PATCH] fix(eio): discard all pending packets when the server is closed --- packages/engine.io/lib/socket.ts | 8 +++- packages/engine.io/test/server.js | 61 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/packages/engine.io/lib/socket.ts b/packages/engine.io/lib/socket.ts index 3ec838e3a..bd8ff655f 100644 --- a/packages/engine.io/lib/socket.ts +++ b/packages/engine.io/lib/socket.ts @@ -554,6 +554,10 @@ export class Socket extends EventEmitter { * @return {Socket} for chaining */ public close(discard?: boolean) { + if (discard && (this.readyState === "open" || this.readyState === "closing")) { + return this.closeTransport(discard); + } + if ("open" !== this.readyState) return; this.readyState = "closing"; @@ -570,7 +574,7 @@ export class Socket extends EventEmitter { return; } - debug("the buffer is empty, closing the transport right away", discard); + debug("the buffer is empty, closing the transport right away"); this.closeTransport(discard); } @@ -581,7 +585,7 @@ export class Socket extends EventEmitter { * @private */ private closeTransport(discard: boolean) { - debug("closing the transport (discard? %s)", discard); + debug("closing the transport (discard? %s)", !!discard); if (discard) this.transport.discard(); this.transport.close(this.onClose.bind(this, "forced close")); } diff --git a/packages/engine.io/test/server.js b/packages/engine.io/test/server.js index 25d87ce45..35b198835 100644 --- a/packages/engine.io/test/server.js +++ b/packages/engine.io/test/server.js @@ -1634,6 +1634,67 @@ describe("server", () => { }); }); + it("should discard the packets in the writeBuffer when stopping the server", (done) => { + engine = listen((port) => { + const clientSocket = new ClientSocket(`ws://localhost:${port}`); + + clientSocket.on("data", () => { + done(new Error("should not happen")); + }); + + clientSocket.on("close", (reason) => { + expect(reason).to.eql("transport error"); + + clientSocket.close(); + done(); + }); + + engine.on("connection", (socket) => { + socket.write("hello"); + engine.close(); + }); + }); + }); + + it("should discard the packets in the writeBuffer when stopping the server (2)", (done) => { + engine = listen((port) => { + const clientSocket = new ClientSocket(`ws://localhost:${port}`); + + clientSocket.on("data", () => { + done(new Error("should not happen")); + }); + + clientSocket.on("close", (reason) => { + expect(reason).to.eql("transport error"); + + clientSocket.close(); + done(); + }); + + engine.on("connection", (socket) => { + socket.write("hello"); + socket.close(); // readyState is now "closing" + engine.close(); + }); + }); + }); + + it("should not discard the packets in the writeBuffer when closing gracefully", (done) => { + engine = listen((port) => { + const clientSocket = new ClientSocket(`ws://localhost:${port}`); + + clientSocket.on("data", (val) => { + expect(val).to.eql("hello"); + done(); + }); + + engine.on("connection", (socket) => { + socket.write("hello"); + socket.close(); + }); + }); + }); + describe("graceful close", () => { before(function () { if (process.env.EIO_WS_ENGINE === "uws") {