Skip to content
Merged
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,10 @@ required-features = ["http-full", "boring", "acme"]
name = "acme_tls_challenge_using_rustls"
required-features = ["http-full", "rustls", "acme"]

[[example]]
name = "autobahn_client"
required = ["rama-ws", "http-full"]

[[example]]
name = "http_conn_state"
required-features = ["http-full"]
Expand Down
2 changes: 2 additions & 0 deletions docs/book/src/ws.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ ws_echo_server.rs
Secure WebSocket server example (WSS).
- [`ws_over_h2.rs`](https://github.com/plabayo/rama/blob/main/examples/ws_over_h2.rs)
Secure WebSocket server using h2.
- [`autobahn_client.rs`](https://github.com/plabayo/rama/blob/main/examples/autobahn_client.rs)
Run autobahn WebSocket test suite.

In the existing [`http_mitm_proxy_boring.rs`](https://github.com/plabayo/rama/blob/main/examples/http_mitm_proxy_boring.rs) example
you can find inspiration on how to MITM proxy WebSocket traffic. As often it is not the only
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ This directory contains example implementations demonstrating various features a
- [`ws_chat_server.rs`](./ws_chat_server.rs) - WebSocket chat server
- [`ws_tls_server.rs`](./ws_tls_server.rs) - Secure WebSocket server example (WSS)
- [`ws_over_h2.rs`](./ws_over_h2.rs) - Secure WebSocket server example using h2.
- [`autobahn_client.rs`](./autobahn_client.rs) - Run autobahn WebSocket test suite.

### ACME
The following examples show how you can integrate ACME into you webservices (ACME support in Rama is currently still under heavy development)
Expand Down
87 changes: 60 additions & 27 deletions rama-ws/examples/autobahn-client.rs → examples/autobahn_client.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,74 @@
use rama_core::{
//! An example demonstrating how to run the Autobahn WebSocket Test Suite using Rama.
//!
//! This connects to a locally running instance of the [Autobahn TestSuite](https://github.com/crossbario/autobahn-testsuite)
//! via WebSocket to run and report test cases for validating WebSocket protocol conformance.
//! # Prerequisites
//! ## Using provided script
//! - Run script `rama-ws/autobahn/client.sh`
//!
//! # Manually
//!
//! - Run the Autobahn WebSocket TestSuite server locally :
//! ```sh
//! docker run -it --rm -p 9001:9001 crossbario/autobahn-testsuite
//! ```
//! - Make sure the server is listening on `ws://localhost:9001`
//!
//! # Run the example
//!
//! ```sh
//! cargo run --example autobahn_test_client --features=http-full,ws
//! ```
//!
//! # Expected Output
//!
//! The example will:
//! - Fetch the number of test cases
//! - Run each case by echoing back text or binary WebSocket frames
//! - Skip logging expected protocol errors
//! - Submit the final report under the agent name "Rama"
//!
//! You’ll see output for each test case and potential errors (if any).
use rama::{
Context,
error::{BoxError, ErrorContext},
futures::{SinkExt, StreamExt},
http::{
client::EasyHttpWebClient,
ws::{ProtocolError, handshake::client::HttpClientWebSocketExt},
},
telemetry::tracing::{error, info},
};
use rama_http_backend::client::EasyHttpWebClient;
use rama_ws::{ProtocolError, handshake::client::HttpClientWebSocketExt};
use tracing_subscriber::{
EnvFilter, filter::LevelFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt,
};

const AGENT: &str = "Rama";

#[tokio::main]
async fn main() {
tracing_subscriber::registry()
.with(fmt::layer())
.with(
EnvFilter::builder()
.with_default_directive(LevelFilter::DEBUG.into())
.from_env_lossy(),
)
.init();

let total = get_case_count().await.expect("Error getting case count");

for case in 1..=total {
if let Err(err) = run_test(case).await
&& err.downcast_ref::<ProtocolError>().is_none()
{
error!("Testcase failed: {err}")
}
}

update_reports().await.expect("Error updating reports");
}

async fn get_case_count() -> Result<u32, BoxError> {
let client = EasyHttpWebClient::default();
let mut socket = client
Expand Down Expand Up @@ -63,27 +120,3 @@ async fn run_test(case: u32) -> Result<(), BoxError> {

Ok(())
}

#[tokio::main]
async fn main() {
tracing_subscriber::registry()
.with(fmt::layer())
.with(
EnvFilter::builder()
.with_default_directive(LevelFilter::DEBUG.into())
.from_env_lossy(),
)
.init();

let total = get_case_count().await.expect("Error getting case count");

for case in 1..=total {
if let Err(err) = run_test(case).await
&& err.downcast_ref::<ProtocolError>().is_none()
{
error!("Testcase failed: {err}")
}
}

update_reports().await.expect("Error updating reports");
}
Loading
Loading