Skip to content

Commit a55ac05

Browse files
authored
ws: move implementation agnostic onFail logic to shared function (#3663)
1 parent 3efc13f commit a55ac05

File tree

4 files changed

+30
-43
lines changed

4 files changed

+30
-43
lines changed

lib/web/websocket/connection.js

+1
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ function establishWebSocketConnection (url, protocols, client, handler, options)
208208
})
209209
}
210210

211+
handler.wasEverConnected = true
211212
handler.onConnectionEstablished(response, extensions)
212213
}
213214
})

lib/web/websocket/stream/websocketstream.js

+6-27
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,14 @@ class WebSocketStream {
3838
/** @type {WritableStream} */
3939
#writableStream
4040

41-
// Each WebSocketStream object has an associated was ever connected , which is a boolean, initially false.
42-
#wasEverConnected = false
43-
4441
// Each WebSocketStream object has an associated boolean handshake aborted , which is initially false.
4542
#handshakeAborted = false
4643

4744
/** @type {import('../websocket').Handler} */
4845
#handler = {
4946
// https://whatpr.org/websockets/48/7b748d3...d5570f3.html#feedback-to-websocket-stream-from-the-protocol
5047
onConnectionEstablished: (response, extensions) => this.#onConnectionEstablished(response, extensions),
51-
onFail: (reason) => this.#onFail(reason),
48+
onFail: (_code, _reason) => {},
5249
onMessage: (opcode, data) => this.#onMessage(opcode, data),
5350
onParserError: (err) => failWebsocketConnection(this.#handler, null, err.message),
5451
onParserDrain: () => this.#handler.socket.resume(),
@@ -71,15 +68,13 @@ class WebSocketStream {
7168
readyState: states.CONNECTING,
7269
socket: null,
7370
closeState: new Set(),
74-
receivedClose: false
71+
controller: null,
72+
wasEverConnected: false
7573
}
7674

7775
/** @type {import('../receiver').ByteParser} */
7876
#parser
7977

80-
/** @type {import('../../fetch/index').Fetch} */
81-
#controller
82-
8378
constructor (url, options = undefined) {
8479
if (!emittedExperimentalWarning) {
8580
process.emitWarning('WebSocketStream is experimental! Expect it to change at any time.', {
@@ -161,7 +156,7 @@ class WebSocketStream {
161156

162157
// 10. Run this step in parallel :
163158
// 10.1. Establish a WebSocket connection given urlRecord , protocols , and client . [FETCH]
164-
this.#controller = establishWebSocketConnection(
159+
this.#handler.controller = establishWebSocketConnection(
165160
urlRecord,
166161
protocols,
167162
client,
@@ -269,7 +264,7 @@ class WebSocketStream {
269264
this.#handler.readyState = states.OPEN
270265

271266
// 2. Set stream ’s was ever connected to true.
272-
this.#wasEverConnected = true
267+
// This is done in the opening handshake.
273268

274269
// 3. Let extensions be the extensions in use .
275270
const extensions = parsedExtensions ?? ''
@@ -367,7 +362,7 @@ class WebSocketStream {
367362
}
368363

369364
// 3. If stream ’s was ever connected is false, then reject stream ’s opened promise with a new WebSocketError.
370-
if (!this.#wasEverConnected) {
365+
if (!this.#handler.wasEverConnected) {
371366
this.#openedPromise.reject(new WebSocketError('Socket never opened'))
372367
}
373368

@@ -422,22 +417,6 @@ class WebSocketStream {
422417
}
423418
}
424419

425-
#onFail (code, reason) {
426-
// If _The WebSocket Connection is Established_ prior to the point where
427-
// the endpoint is required to _Fail the WebSocket Connection_, the
428-
// endpoint SHOULD send a Close frame with an appropriate status code
429-
// (Section 7.4) before proceeding to _Close the WebSocket Connection_.
430-
if (isEstablished(this.#handler.readyState)) {
431-
closeWebSocketConnection(this.#handler, code, reason, false)
432-
}
433-
434-
this.#controller.abort()
435-
436-
if (this.#handler.socket && !this.#handler.socket.destroyed) {
437-
this.#handler.socket.destroy()
438-
}
439-
}
440-
441420
#closeUsingReason (reason) {
442421
// 1. Let code be null.
443422
let code = null

lib/web/websocket/util.js

+16
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,22 @@ function isValidStatusCode (code) {
163163
* @returns {void}
164164
*/
165165
function failWebsocketConnection (handler, code, reason) {
166+
// If _The WebSocket Connection is Established_ prior to the point where
167+
// the endpoint is required to _Fail the WebSocket Connection_, the
168+
// endpoint SHOULD send a Close frame with an appropriate status code
169+
// (Section 7.4) before proceeding to _Close the WebSocket Connection_.
170+
if (isEstablished(handler.readyState)) {
171+
// avoid circular require - performance is not important here
172+
const { closeWebSocketConnection } = require('./connection')
173+
closeWebSocketConnection(handler, code, reason, false)
174+
}
175+
176+
handler.controller.abort()
177+
178+
if (handler.socket?.destroyed === false) {
179+
handler.socket.destroy()
180+
}
181+
166182
handler.onFail(code, reason)
167183
}
168184

lib/web/websocket/websocket.js

+7-16
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ const { channels } = require('../../core/diagnostics')
3838
* @property {number} readyState
3939
* @property {import('stream').Duplex} socket
4040
* @property {Set<number>} closeState
41+
* @property {import('../fetch/index').Fetch} controller
42+
* @property {boolean} [wasEverConnected=false]
4143
*/
4244

4345
// https://websockets.spec.whatwg.org/#interface-definition
@@ -81,11 +83,12 @@ class WebSocket extends EventTarget {
8183

8284
readyState: states.CONNECTING,
8385
socket: null,
84-
closeState: new Set()
86+
closeState: new Set(),
87+
controller: null,
88+
wasEverConnected: false
8589
}
8690

8791
#url
88-
#controller
8992
#binaryType
9093
/** @type {import('./receiver').ByteParser} */
9194
#parser
@@ -138,7 +141,7 @@ class WebSocket extends EventTarget {
138141
// 7. Run this step in parallel:
139142
// 7.1. Establish a WebSocket connection given urlRecord, protocols,
140143
// and client.
141-
this.#controller = establishWebSocketConnection(
144+
this.#handler.controller = establishWebSocketConnection(
142145
urlRecord,
143146
protocols,
144147
client,
@@ -467,25 +470,13 @@ class WebSocket extends EventTarget {
467470
})
468471
}
469472

470-
// If _The WebSocket Connection is Established_ prior to the point where
471-
// the endpoint is required to _Fail the WebSocket Connection_, the
472-
// endpoint SHOULD send a Close frame with an appropriate status code
473-
// (Section 7.4) before proceeding to _Close the WebSocket Connection_.
474-
if (isEstablished(this.#handler.readyState)) {
475-
closeWebSocketConnection(this.#handler, code, reason, false)
476-
} else {
473+
if (!this.#handler.wasEverConnected) {
477474
// If the WebSocket connection could not be established, it is also said
478475
// that _The WebSocket Connection is Closed_, but not _cleanly_.
479476
fireEvent('close', this, (type, init) => new CloseEvent(type, init), {
480477
wasClean: false, code, reason
481478
})
482479
}
483-
484-
this.#controller.abort()
485-
486-
if (this.#handler.socket && !this.#handler.socket.destroyed) {
487-
this.#handler.socket.destroy()
488-
}
489480
}
490481

491482
#onMessage (type, data) {

0 commit comments

Comments
 (0)