diff --git a/cli/tests/websocket_test.ts b/cli/tests/websocket_test.ts index b5f86594378a61..8a7fc812c25959 100644 --- a/cli/tests/websocket_test.ts +++ b/cli/tests/websocket_test.ts @@ -295,3 +295,14 @@ Deno.test("Event Handlers order", async () => { }; await promise; }); + +Deno.test("Close without frame", async () => { + const promise = deferred(); + const ws = new WebSocket("ws://localhost:4244"); + ws.onerror = (): void => fail(); + ws.onclose = (e): void => { + assertEquals(e.code, 1005); + promise.resolve(); + }; + await promise; +}); diff --git a/op_crates/websocket/01_websocket.js b/op_crates/websocket/01_websocket.js index d9b1455bdeefb1..4a303679b5f855 100644 --- a/op_crates/websocket/01_websocket.js +++ b/op_crates/websocket/01_websocket.js @@ -350,6 +350,7 @@ }); event.target = this; this.dispatchEvent(event); + core.close(this.#rid); break; } @@ -364,6 +365,7 @@ const closeEv = new CloseEvent("close"); closeEv.target = this; this.dispatchEvent(closeEv); + core.close(this.#rid); break; } diff --git a/op_crates/websocket/lib.rs b/op_crates/websocket/lib.rs index f43ce8b428539b..c914f11c52a2e8 100644 --- a/op_crates/websocket/lib.rs +++ b/op_crates/websocket/lib.rs @@ -322,7 +322,13 @@ pub async fn op_ws_next_event( "reason": frame.reason.as_ref() } }), - Some(Ok(Message::Close(None))) => json!({ "kind": "close" }), + Some(Ok(Message::Close(None))) => json!({ + "kind": "close", + "data": { + "code": 1005, + "reason": "" + } + }), Some(Ok(Message::Ping(_))) => json!({ "kind": "ping" }), Some(Ok(Message::Pong(_))) => json!({ "kind": "pong" }), Some(Err(_)) => json!({ "kind": "error" }), diff --git a/test_util/src/lib.rs b/test_util/src/lib.rs index a2c0b2396624ce..8dcd4f6237e8a6 100644 --- a/test_util/src/lib.rs +++ b/test_util/src/lib.rs @@ -59,6 +59,7 @@ const AUTH_REDIRECT_PORT: u16 = 4551; const HTTPS_PORT: u16 = 5545; const WS_PORT: u16 = 4242; const WSS_PORT: u16 = 4243; +const WS_CLOSE_PORT: u16 = 4244; pub const PERMISSION_VARIANTS: [&str; 5] = ["read", "write", "env", "net", "run"]; @@ -243,6 +244,20 @@ async fn run_ws_server(addr: &SocketAddr) { } } +async fn run_ws_close_server(addr: &SocketAddr) { + let listener = TcpListener::bind(addr).await.unwrap(); + while let Ok((stream, _addr)) = listener.accept().await { + tokio::spawn(async move { + let ws_stream_fut = accept_async(stream); + + let ws_stream = ws_stream_fut.await; + if let Ok(mut ws_stream) = ws_stream { + ws_stream.close(None).await.unwrap(); + } + }); + } +} + async fn get_tls_config( cert: &str, key: &str, @@ -781,6 +796,8 @@ pub async fn run_all_servers() { let ws_server_fut = run_ws_server(&ws_addr); let wss_addr = SocketAddr::from(([127, 0, 0, 1], WSS_PORT)); let wss_server_fut = run_wss_server(&wss_addr); + let ws_close_addr = SocketAddr::from(([127, 0, 0, 1], WS_CLOSE_PORT)); + let ws_close_server_fut = run_ws_close_server(&ws_close_addr); let main_server_fut = wrap_main_server(); let main_server_https_fut = wrap_main_https_server(); @@ -790,6 +807,7 @@ pub async fn run_all_servers() { redirect_server_fut, ws_server_fut, wss_server_fut, + ws_close_server_fut, another_redirect_server_fut, auth_redirect_server_fut, inf_redirects_server_fut,