diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2024-01-09 19:56:54 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-09 19:56:54 +0530 |
commit | 6db631a432ee916380b62770357adb46edd7c281 (patch) | |
tree | 7374d69b2f26bc66f82a81db069963b0c0b14e37 /test_util/src | |
parent | 19c10c024623a227bc68b6606bc2f32d25030ab7 (diff) |
fix(ext/websocket): pass on uncaught errors in idleTimeout (#21846)
Fixes https://github.com/denoland/deno/issues/21840
The problem was hard to reproduce as its a race condition. I've added a
test that reproduces the problem 1/10 tries. We should move the
idleTimeout handling to Rust (maybe even built into fastwebsocket).
Diffstat (limited to 'test_util/src')
-rw-r--r-- | test_util/src/servers/mod.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/test_util/src/servers/mod.rs b/test_util/src/servers/mod.rs index 304d450b4..d4c40f4fc 100644 --- a/test_util/src/servers/mod.rs +++ b/test_util/src/servers/mod.rs @@ -455,6 +455,54 @@ async fn main_server( ); Ok(response) } + (&Method::GET, "/ghost_ws_client") => { + use tokio::io::AsyncReadExt; + + let mut tcp_stream = TcpStream::connect("localhost:4248").await.unwrap(); + #[cfg(unix)] + // SAFETY: set socket keep alive. + unsafe { + use std::os::fd::AsRawFd; + + let fd = tcp_stream.as_raw_fd(); + let mut val: libc::c_int = 1; + let r = libc::setsockopt( + fd, + libc::SOL_SOCKET, + libc::SO_KEEPALIVE, + &mut val as *mut _ as *mut libc::c_void, + std::mem::size_of_val(&val) as libc::socklen_t, + ); + assert_eq!(r, 0); + } + + // Typical websocket handshake request. + let headers = [ + "GET / HTTP/1.1", + "Host: localhost", + "Upgrade: websocket", + "Connection: Upgrade", + "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==", + "Sec-WebSocket-Version: 13", + "\r\n", + ] + .join("\r\n"); + tcp_stream.write_all(headers.as_bytes()).await.unwrap(); + + let mut buf = [0u8; 200]; + let n = tcp_stream.read(&mut buf).await.unwrap(); + assert!(n > 0); + + // Ghost the server: + // - Close the read half of the connection. + // - forget the TcpStream. + let tcp_stream = tcp_stream.into_std().unwrap(); + let _ = tcp_stream.shutdown(std::net::Shutdown::Read); + std::mem::forget(tcp_stream); + + let res = Response::new(empty_body()); + Ok(res) + } (_, "/multipart_form_data.txt") => { let b = "Preamble\r\n\ --boundary\t \r\n\ |