mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
Bumps [tokio-tungstenite](https://github.com/snapview/tokio-tungstenite) from 0.24.0 to 0.30.0. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/snapview/tokio-tungstenite/blob/master/CHANGELOG.md">tokio-tungstenite's changelog</a>.</em></p> <blockquote> <h1>0.30.0</h1> <ul> <li>Update <code>tungstenite</code> to <code>0.30.0</code>. See <a href="https://github.com/snapview/tungstenite-rs/blob/master/CHANGELOG.md"><code>tungstenite</code> release</a>.</li> </ul> <h1>0.29.0</h1> <ul> <li>Update <code>tungstenite</code> to <code>0.29.0</code>. See <a href="https://github.com/snapview/tungstenite-rs/blob/master/CHANGELOG.md"><code>tungstenite</code> release</a>.</li> </ul> <h1>0.28.0</h1> <ul> <li>Update <code>tungstenite</code> to <code>0.28.0</code>. See <a href="https://github.com/snapview/tungstenite-rs/blob/master/CHANGELOG.md"><code>tungstenite</code> release</a>.</li> </ul> <h1>0.27.0</h1> <ul> <li>See <a href="https://github.com/snapview/tungstenite-rs/blob/master/CHANGELOG.md#0270">performance updates in <code>tungstenite-rs</code></a>.</li> </ul> <h1>0.26.2</h1> <ul> <li>Update <code>tungstenite</code>, see <a href="https://github.com/snapview/tungstenite-rs/blob/master/CHANGELOG.md#0262">changes here</a>.</li> </ul> <h1>0.26.1</h1> <ul> <li>Update <code>tungstenite</code> to address an issue that might cause UB in certain cases.</li> </ul> <h1>0.26.0</h1> <ul> <li>Update <code>tungstenite</code> to <code>0.26.0</code> (<a href="https://github.com/snapview/tungstenite-rs/blob/master/CHANGELOG.md#0260">breaking changes</a>).</li> </ul> <h1>0.25.0</h1> <ul> <li>Update <code>tungstenite</code> to <code>0.25.0</code> (<a href="https://github.com/snapview/tungstenite-rs/blob/master/CHANGELOG.md#0250">important updates!</a>).</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="4994a07803"><code>4994a07</code></a> Bump version</li> <li><a href="753ca72690"><code>753ca72</code></a> Document cancel safety of reading from WebSocketStream (<a href="https://redirect.github.com/snapview/tokio-tungstenite/issues/378">#378</a>)</li> <li><a href="751d7e2bc2"><code>751d7e2</code></a> Update version number listed in Readme (<a href="https://redirect.github.com/snapview/tokio-tungstenite/issues/375">#375</a>)</li> <li><a href="57fc3d0276"><code>57fc3d0</code></a> docs(CHANGELOG.md): fix <code>tungstenite</code> versions (<a href="https://redirect.github.com/snapview/tokio-tungstenite/issues/374">#374</a>)</li> <li><a href="7930ff2f82"><code>7930ff2</code></a> Bump version</li> <li><a href="38d04656fe"><code>38d0465</code></a> Update Readme (<a href="https://redirect.github.com/snapview/tokio-tungstenite/issues/369">#369</a>)</li> <li><a href="35d110c24c"><code>35d110c</code></a> Implement into_inner to get the underlying stream (<a href="https://redirect.github.com/snapview/tokio-tungstenite/issues/367">#367</a>)</li> <li><a href="f3ae75d1de"><code>f3ae75d</code></a> Update <code>tungstenite</code> version and fix bugs</li> <li><a href="25b544e43f"><code>25b544e</code></a> Allow getting a reference to the shared inner stream (<a href="https://redirect.github.com/snapview/tokio-tungstenite/issues/363">#363</a>)</li> <li><a href="e855f9eb8c"><code>e855f9e</code></a> Fix errors in the examples caused by <code>Utf8Error</code></li> <li>Additional commits viewable in <a href="https://github.com/snapview/tokio-tungstenite/compare/v0.24.0...v0.30.0">compare view</a></li> </ul> </details> <br /> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: JerrettDavis <mxjerrett@gmail.com>
96 lines
3.5 KiB
Rust
96 lines
3.5 KiB
Rust
//! WebSocket proxy: bidirectional pump + close propagation.
|
|
|
|
mod common;
|
|
|
|
use std::net::SocketAddr;
|
|
use std::time::Duration;
|
|
|
|
use common::start_proxy;
|
|
use futures_util::{SinkExt, StreamExt};
|
|
use tokio_tungstenite::tungstenite::protocol::CloseFrame;
|
|
use tokio_tungstenite::tungstenite::Message;
|
|
|
|
/// Spawns an upstream WS echo server. Handshake uses tungstenite over a raw TCP listener.
|
|
async fn echo_upstream() -> (SocketAddr, tokio::sync::oneshot::Sender<()>) {
|
|
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
|
|
let addr = listener.local_addr().unwrap();
|
|
let (stop_tx, mut stop_rx) = tokio::sync::oneshot::channel();
|
|
tokio::spawn(async move {
|
|
loop {
|
|
tokio::select! {
|
|
_ = &mut stop_rx => break,
|
|
accepted = listener.accept() => {
|
|
let Ok((stream, _)) = accepted else { continue };
|
|
tokio::spawn(async move {
|
|
let Ok(ws) = tokio_tungstenite::accept_async(stream).await else { return };
|
|
let (mut sink, mut src) = ws.split();
|
|
while let Some(Ok(msg)) = src.next().await {
|
|
match msg {
|
|
Message::Close(cf) => {
|
|
let _ = sink.send(Message::Close(cf)).await;
|
|
break;
|
|
}
|
|
m => {
|
|
if sink.send(m).await.is_err() { break; }
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
});
|
|
(addr, stop_tx)
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn ws_text_and_binary_round_trip() {
|
|
let (upstream_addr, _stop) = echo_upstream().await;
|
|
let proxy = start_proxy(&format!("http://{upstream_addr}")).await;
|
|
|
|
let url = format!("{}/ws", proxy.ws_url());
|
|
let (mut ws, _) = tokio_tungstenite::connect_async(&url).await.unwrap();
|
|
|
|
for i in 0..5 {
|
|
let m = format!("hello-{i}");
|
|
ws.send(Message::Text(m.clone().into())).await.unwrap();
|
|
let echoed = ws.next().await.unwrap().unwrap();
|
|
match echoed {
|
|
Message::Text(t) => assert_eq!(t.as_str(), m),
|
|
other => panic!("expected text, got {other:?}"),
|
|
}
|
|
}
|
|
for i in 0..5u8 {
|
|
let m: Vec<u8> = (0..32u8).map(|b| b ^ i).collect();
|
|
ws.send(Message::Binary(m.clone().into())).await.unwrap();
|
|
let echoed = ws.next().await.unwrap().unwrap();
|
|
match echoed {
|
|
Message::Binary(b) => assert_eq!(b.to_vec(), m),
|
|
other => panic!("expected binary, got {other:?}"),
|
|
}
|
|
}
|
|
ws.send(Message::Close(None)).await.unwrap();
|
|
proxy.shutdown().await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn ws_client_close_propagates() {
|
|
let (upstream_addr, _stop) = echo_upstream().await;
|
|
let proxy = start_proxy(&format!("http://{upstream_addr}")).await;
|
|
|
|
let (mut ws, _) = tokio_tungstenite::connect_async(format!("{}/ws", proxy.ws_url()))
|
|
.await
|
|
.unwrap();
|
|
|
|
ws.send(Message::Close(Some(CloseFrame {
|
|
code: tokio_tungstenite::tungstenite::protocol::frame::coding::CloseCode::Normal,
|
|
reason: "bye".into(),
|
|
})))
|
|
.await
|
|
.unwrap();
|
|
|
|
// Server-side echo will reflect the close; we should see a Close back.
|
|
let got = tokio::time::timeout(Duration::from_secs(3), ws.next()).await;
|
|
assert!(got.is_ok(), "expected close echo within 3s");
|
|
proxy.shutdown().await;
|
|
}
|