summaryrefslogtreecommitdiff
path: root/ext/websocket
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2024-06-25 06:39:02 -0700
committerGitHub <noreply@github.com>2024-06-25 19:09:02 +0530
commita1ff1a453c309c2f14c64ec31a3c43ef784781e2 (patch)
treee10c6c6e84e70d02adcefc54dd4dd2e9ccc60203 /ext/websocket
parent13aa1d70e905f1e1ec57d7eb57ad57d09d09deb2 (diff)
fix(ext/websocket): drop connection when close frame not ack (#24301)
Fixes #24292
Diffstat (limited to 'ext/websocket')
-rw-r--r--ext/websocket/01_websocket.js12
-rw-r--r--ext/websocket/lib.rs8
2 files changed, 18 insertions, 2 deletions
diff --git a/ext/websocket/01_websocket.js b/ext/websocket/01_websocket.js
index afe543da5..60580a56c 100644
--- a/ext/websocket/01_websocket.js
+++ b/ext/websocket/01_websocket.js
@@ -424,6 +424,18 @@ class WebSocket extends EventTarget {
const rid = this[_rid];
while (this[_readyState] !== CLOSED) {
const kind = await op_ws_next_event(rid);
+ /* close the connection if read was cancelled, and we didn't get a close frame */
+ if (
+ (this[_readyState] == CLOSING) &&
+ kind <= 3 && this[_role] !== CLIENT
+ ) {
+ this[_readyState] = CLOSED;
+
+ const event = new CloseEvent("close");
+ this.dispatchEvent(event);
+ core.tryClose(rid);
+ break;
+ }
switch (kind) {
case 0: {
diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs
index 87503120b..5c3e8d7b1 100644
--- a/ext/websocket/lib.rs
+++ b/ext/websocket/lib.rs
@@ -699,10 +699,14 @@ pub async fn op_ws_close(
#[smi] code: Option<u16>,
#[string] reason: Option<String>,
) -> Result<(), AnyError> {
- let resource = state
+ let Ok(resource) = state
.borrow_mut()
.resource_table
- .get::<ServerWebSocket>(rid)?;
+ .get::<ServerWebSocket>(rid)
+ else {
+ return Ok(());
+ };
+
let frame = reason
.map(|reason| Frame::close(code.unwrap_or(1005), reason.as_bytes()))
.unwrap_or_else(|| Frame::close_raw(vec![].into()));