Skip to content

Commit fe13149

Browse files
committed
chore: use node 22 Set methods for websocket close state
Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
1 parent 79b7ebd commit fe13149

6 files changed

Lines changed: 26 additions & 18 deletions

File tree

lib/web/websocket/connection.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict'
22

3-
const { uid, states, sentCloseFrameState, emptyBuffer, opcodes } = require('./constants')
3+
const { uid, states, sentCloseFrameState, closingHandshakeStates, emptyBuffer, opcodes } = require('./constants')
44
const { parseExtensions, isClosed, isClosing, isEstablished, isConnecting, validateCloseCodeAndReason } = require('./util')
55
const { makeRequest } = require('../fetch/request')
66
const { fetching } = require('../fetch/index')
@@ -245,7 +245,7 @@ function closeWebSocketConnection (object, code, reason, validate = false) {
245245
// Fail the WebSocket connection and set object’s ready state to CLOSING (2). [WSP]
246246
failWebsocketConnection(object)
247247
object.readyState = states.CLOSING
248-
} else if (!object.closeState.has(sentCloseFrameState.SENT) && !object.closeState.has(sentCloseFrameState.RECEIVED)) {
248+
} else if (object.closeState.isDisjointFrom(closingHandshakeStates)) {
249249
// Upon either sending or receiving a Close control frame, it is said
250250
// that _The WebSocket Closing Handshake is Started_ and that the
251251
// WebSocket connection is in the CLOSING state.

lib/web/websocket/constants.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ const sentCloseFrameState = {
4646
RECEIVED: 2
4747
}
4848

49+
/**
50+
* Tracks whether the closing handshake has started or completed.
51+
*
52+
* A close state that is disjoint from this set has not started the closing
53+
* handshake yet. A close state that is a superset of this set has completed it.
54+
*
55+
* @type {ReadonlySet<number>}
56+
*/
57+
const closingHandshakeStates = new Set([
58+
sentCloseFrameState.SENT,
59+
sentCloseFrameState.RECEIVED
60+
])
61+
4962
/**
5063
* The WebSocket opcodes.
5164
*
@@ -116,6 +129,7 @@ const sendHints = {
116129
module.exports = {
117130
uid,
118131
sentCloseFrameState,
132+
closingHandshakeStates,
119133
staticPropertyDescriptors,
120134
states,
121135
opcodes,

lib/web/websocket/receiver.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const { Writable } = require('node:stream')
44
const assert = require('node:assert')
5-
const { parserStates, opcodes, states, emptyBuffer, sentCloseFrameState } = require('./constants')
5+
const { parserStates, opcodes, states, emptyBuffer, sentCloseFrameState, closingHandshakeStates } = require('./constants')
66
const {
77
isValidStatusCode,
88
isValidOpcode,
@@ -434,7 +434,7 @@ class ByteParser extends Writable {
434434

435435
// Upon receiving such a frame, the other peer sends a
436436
// Close frame in response, if it hasn't already sent one.
437-
if (!this.#handler.closeState.has(sentCloseFrameState.SENT) && !this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) {
437+
if (this.#handler.closeState.isDisjointFrom(closingHandshakeStates)) {
438438
// If an endpoint receives a Close frame and did not previously send a
439439
// Close frame, the endpoint MUST send a Close frame in response. (When
440440
// sending a Close frame in response, the endpoint typically echos the

lib/web/websocket/stream/websocketstream.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const { addAbortListener } = require('node:events')
44
const { environmentSettingsObject } = require('../../fetch/util')
5-
const { states, opcodes, sentCloseFrameState } = require('../constants')
5+
const { states, opcodes, closingHandshakeStates } = require('../constants')
66
const { webidl } = require('../../webidl')
77
const { getURLRecord, isValidSubprotocol, isEstablished, utf8Decode } = require('../util')
88
const { establishWebSocketConnection, failWebsocketConnection, closeWebSocketConnection } = require('../connection')
@@ -242,7 +242,7 @@ class WebSocketStream {
242242
// 6.1. Wait until there is sufficient buffer space in stream to send the message.
243243

244244
// 6.2. If the closing handshake has not yet started , Send a WebSocket Message to stream comprised of data using opcode .
245-
if (!this.#handler.closeState.has(sentCloseFrameState.SENT) && !this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) {
245+
if (this.#handler.closeState.isDisjointFrom(closingHandshakeStates)) {
246246
const frame = new WebsocketFrameSend(data)
247247

248248
this.#handler.socket.write(frame.createFrame(opcode), () => {
@@ -347,9 +347,7 @@ class WebSocketStream {
347347

348348
/** @type {import('../websocket').Handler['onSocketClose']} */
349349
#onSocketClose () {
350-
const wasClean =
351-
this.#handler.closeState.has(sentCloseFrameState.SENT) &&
352-
this.#handler.closeState.has(sentCloseFrameState.RECEIVED)
350+
const wasClean = this.#handler.closeState.isSupersetOf(closingHandshakeStates)
353351

354352
// 1. Change the ready state to CLOSED (3).
355353
this.#handler.readyState = states.CLOSED
@@ -376,7 +374,7 @@ class WebSocketStream {
376374
// 1006.
377375
let code = result?.code ?? 1005
378376

379-
if (!this.#handler.closeState.has(sentCloseFrameState.SENT) && !this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) {
377+
if (this.#handler.closeState.isDisjointFrom(closingHandshakeStates)) {
380378
code = 1006
381379
}
382380

lib/web/websocket/websocket.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const { isArrayBuffer } = require('node:util/types')
44
const { webidl } = require('../webidl')
55
const { URLSerializer } = require('../fetch/data-url')
66
const { environmentSettingsObject } = require('../fetch/util')
7-
const { staticPropertyDescriptors, states, sentCloseFrameState, sendHints, opcodes } = require('./constants')
7+
const { staticPropertyDescriptors, states, sentCloseFrameState, closingHandshakeStates, sendHints, opcodes } = require('./constants')
88
const {
99
isConnecting,
1010
isEstablished,
@@ -574,9 +574,7 @@ class WebSocket extends EventTarget {
574574
// If the TCP connection was closed after the
575575
// WebSocket closing handshake was completed, the WebSocket connection
576576
// is said to have been closed _cleanly_.
577-
const wasClean =
578-
this.#handler.closeState.has(sentCloseFrameState.SENT) &&
579-
this.#handler.closeState.has(sentCloseFrameState.RECEIVED)
577+
const wasClean = this.#handler.closeState.isSupersetOf(closingHandshakeStates)
580578

581579
let code = 1005
582580
let reason = ''

test/web-platform-tests/wpt-runner.mjs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const SERVER_READY_CHECKS = [
3131
['wss', (line) => line.includes('wss on port') && line.includes('Listen on:')],
3232
['h2', (line) => line.includes('h2 on port 9000') && line.includes('Starting http2 server')]
3333
]
34+
const SERVER_READY_CHECK_NAMES = new Set(SERVER_READY_CHECKS.map(([name]) => name))
3435

3536
function streamServerLogs (stream, target, onLine) {
3637
let buffer = ''
@@ -173,10 +174,7 @@ async function runWithTestUtil (testFunction) {
173174
const readinessTimeout = setTimeout(() => {
174175
if (!readySettled) {
175176
readySettled = true
176-
const missing = SERVER_READY_CHECKS
177-
.map(([name]) => name)
178-
.filter((name) => !readyChecks.has(name))
179-
.join(', ')
177+
const missing = [...SERVER_READY_CHECK_NAMES.difference(readyChecks)].join(', ')
180178
rejectReady(new Error(`Timed out waiting for WPT server readiness. Missing: ${missing}`))
181179
}
182180
}, 30_000)

0 commit comments

Comments
 (0)