I put together the following simple test of wtransport, as an experiment:
use clap::Parser;
use tokio::io::AsyncReadExt;
#[derive(Parser)]
#[command(name = "wtransport-test")]
enum WtransportTest {
Client(Client),
Server,
}
#[derive(Parser)]
struct Client {
/// Server certificate hash
hash: wtransport::tls::Sha256Digest,
}
#[tokio::main]
async fn main() -> eyre::Result<()> {
match WtransportTest::parse() {
WtransportTest::Client(args) => client(args).await,
WtransportTest::Server => server().await,
}
}
async fn client(args: Client) -> eyre::Result<()> {
let config = wtransport::ClientConfig::builder()
.with_bind_default()
.with_server_certificate_hashes([args.hash])
.build();
let connection = wtransport::Endpoint::client(config)?
.connect("https://localhost:4433/demo-path")
.await?;
println!("Established WebTransport connection");
let mut recv_stream = connection.accept_uni().await?;
println!("Accepted unidirectional stream");
let mut s = String::new();
recv_stream.read_to_string(&mut s).await?;
println!("Read string: {s}");
Ok(())
}
async fn server() -> eyre::Result<()> {
let identity = wtransport::Identity::self_signed(["localhost"])?;
let hash = identity.certificate_chain().as_slice()[0].hash();
println!("Created server certificate with hash {hash}");
let config = wtransport::ServerConfig::builder()
.with_bind_default(4433)
.with_identity(identity)
.build();
let server = wtransport::Endpoint::server(config)?;
println!("Established listening server");
let incoming_session = server.accept().await;
println!(
"Got incoming session from {}",
incoming_session.remote_address()
);
let incoming_request = incoming_session.await?;
println!(
"Incoming request has authority {}, path {}",
incoming_request.authority(),
incoming_request.path()
);
let connection = incoming_request.accept().await?;
println!("Accepted connection");
let mut send_stream = connection.open_uni().await?.await?;
println!("Established unidirectional stream");
send_stream.write_all(b"Hello world!").await?;
println!("Sent data");
send_stream.finish().await?;
println!("Finished");
Ok(())
}
This uses the following [dependencies] in Cargo.toml:
clap = { version = "4.5.49", features = ["deprecated", "derive"] }
eyre = "0.6.12"
tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread"] }
wtransport = { version = "0.6.1", features = ["aws-lc-rs", "self-signed"], default-features = false }
To test this, run it with server which will print a hash, then run it with client that-hash.
Sometimes, both the server and client will complete as expected. However, sometimes, the server will do this:
Created server certificate with hash 83:4e:3c:d4:4d:a3:5d:19:e8:54:f5:72:ee:7d:a0:25:e7:c3:13:a1:9d:6a:0b:75:54:f9:bc:04:d3:3b:cc:17
Established listening server
Got incoming session from [::1]:50257
Incoming request has authority localhost:4433, path /demo-path
Accepted connection
Established unidirectional stream
Sent data
And then hang, never printing "Finished".
I put together the following simple test of wtransport, as an experiment:
This uses the following
[dependencies]inCargo.toml:To test this, run it with
serverwhich will print a hash, then run it withclient that-hash.Sometimes, both the server and client will complete as expected. However, sometimes, the server will do this:
And then hang, never printing "Finished".