From fbb8f7e08d5f57894e295573f69a71a1d7392f38 Mon Sep 17 00:00:00 2001 From: uzlopak Date: Sat, 21 Sep 2024 02:24:35 +0200 Subject: [PATCH] fix(websocket): use binary operations instead of a Set for closeStatus --- lib/web/websocket/constants.js | 5 +++-- lib/web/websocket/receiver.js | 8 ++++---- lib/web/websocket/websocket.js | 14 ++++++-------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/web/websocket/constants.js b/lib/web/websocket/constants.js index 76ed34a650e..45484042e61 100644 --- a/lib/web/websocket/constants.js +++ b/lib/web/websocket/constants.js @@ -21,8 +21,9 @@ const states = { } const sentCloseFrameState = { - SENT: 1, - RECEIVED: 2 + NOT_SENT: 0, + SENT: 1 << 0, + RECEIVED: 1 << 1 } const opcodes = { diff --git a/lib/web/websocket/receiver.js b/lib/web/websocket/receiver.js index 69cfa1b3da5..2e5abf37a8c 100644 --- a/lib/web/websocket/receiver.js +++ b/lib/web/websocket/receiver.js @@ -356,7 +356,7 @@ class ByteParser extends Writable { // Upon receiving such a frame, the other peer sends a // Close frame in response, if it hasn't already sent one. - if (!this.#handler.closeState.has(sentCloseFrameState.SENT)) { + if ((this.#handler.closeState & sentCloseFrameState.SENT) === 0) { // If an endpoint receives a Close frame and did not previously send a // Close frame, the endpoint MUST send a Close frame in response. (When // sending a Close frame in response, the endpoint typically echos the @@ -369,14 +369,14 @@ class ByteParser extends Writable { const closeFrame = new WebsocketFrameSend(body) this.#handler.socket.write(closeFrame.createFrame(opcodes.CLOSE)) - this.#handler.closeState.add(sentCloseFrameState.SENT) + this.#handler.closeState |= sentCloseFrameState.SENT } // Upon either sending or receiving a Close control frame, it is said // that _The WebSocket Closing Handshake is Started_ and that the // WebSocket connection is in the CLOSING state. this.#handler.readyState = states.CLOSING - this.#handler.closeState.add(sentCloseFrameState.RECEIVED) + this.#handler.closeState |= sentCloseFrameState.RECEIVED return false } else if (opcode === opcodes.PING) { @@ -385,7 +385,7 @@ class ByteParser extends Writable { // A Pong frame sent in response to a Ping frame must have identical // "Application data" - if (!this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) { + if ((this.#handler.closeState & sentCloseFrameState.RECEIVED) === 0) { const frame = new WebsocketFrameSend(body) this.#handler.socket.write(frame.createFrame(opcodes.PONG)) diff --git a/lib/web/websocket/websocket.js b/lib/web/websocket/websocket.js index 6d68bda43b3..c733989f521 100644 --- a/lib/web/websocket/websocket.js +++ b/lib/web/websocket/websocket.js @@ -39,7 +39,7 @@ const { channels } = require('../../core/diagnostics') * * @property {number} readyState * @property {import('stream').Duplex} socket - * @property {Set} closeState + * @property {number} closeState */ // https://websockets.spec.whatwg.org/#interface-definition @@ -84,7 +84,7 @@ class WebSocket extends EventTarget { readyState: states.CONNECTING, socket: null, - closeState: new Set() + closeState: sentCloseFrameState.NOT_SENT } #url @@ -592,7 +592,7 @@ class WebSocket extends EventTarget { // to CLOSING (2). failWebsocketConnection(this.#handler, 1002, 'Connection was closed before it was established.') this.#handler.readyState = states.CLOSING - } else if (!this.#handler.closeState.has(sentCloseFrameState.SENT) && !this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) { + } else if (this.#handler.closeState === sentCloseFrameState.NOT_SENT) { // Upon either sending or receiving a Close control frame, it is said // that _The WebSocket Closing Handshake is Started_ and that the // WebSocket connection is in the CLOSING state. @@ -630,7 +630,7 @@ class WebSocket extends EventTarget { this.#handler.socket.write(frame.createFrame(opcodes.CLOSE)) - this.#handler.closeState.add(sentCloseFrameState.SENT) + this.#handler.closeState |= sentCloseFrameState.SENT // Upon either sending or receiving a Close control frame, it is said // that _The WebSocket Closing Handshake is Started_ and that the @@ -671,9 +671,7 @@ class WebSocket extends EventTarget { // If the TCP connection was closed after the // WebSocket closing handshake was completed, the WebSocket connection // is said to have been closed _cleanly_. - const wasClean = - this.#handler.closeState.has(sentCloseFrameState.SENT) && - this.#handler.closeState.has(sentCloseFrameState.RECEIVED) + const wasClean = this.#handler.closeState === (sentCloseFrameState.SENT & sentCloseFrameState.RECEIVED) let code = 1005 let reason = '' @@ -683,7 +681,7 @@ class WebSocket extends EventTarget { if (result && !result.error) { code = result.code ?? 1005 reason = result.reason - } else if (!this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) { + } else if ((this.#handler.closeState & sentCloseFrameState.RECEIVED) === 0) { // If _The WebSocket // Connection is Closed_ and no Close control frame was received by the // endpoint (such as could occur if the underlying transport connection