started webtransport test server

This commit is contained in:
Maccesch 2023-09-15 02:40:49 +01:00
parent 7cabae75b6
commit b146bb864e
10 changed files with 204 additions and 5 deletions

4
.idea/leptos-use.iml generated
View file

@ -54,6 +54,8 @@
<sourceFolder url="file://$MODULE_DIR$/examples/use_raf_fn/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/examples/use_raf_fn/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_webtransport/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/examples/use_webtransport/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_geolocation/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/examples/use_geolocation/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_webtransport_with_server/client/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_webtransport_with_server/server/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/examples/use_event_listener/target" /> <excludeFolder url="file://$MODULE_DIR$/examples/use_event_listener/target" />
<excludeFolder url="file://$MODULE_DIR$/target" /> <excludeFolder url="file://$MODULE_DIR$/target" />
<excludeFolder url="file://$MODULE_DIR$/docs/book/book" /> <excludeFolder url="file://$MODULE_DIR$/docs/book/book" />
@ -115,6 +117,8 @@
<excludeFolder url="file://$MODULE_DIR$/examples/watch_debounced/dist" /> <excludeFolder url="file://$MODULE_DIR$/examples/watch_debounced/dist" />
<excludeFolder url="file://$MODULE_DIR$/examples/watch_pausable/dist" /> <excludeFolder url="file://$MODULE_DIR$/examples/watch_pausable/dist" />
<excludeFolder url="file://$MODULE_DIR$/examples/watch_throttled/dist" /> <excludeFolder url="file://$MODULE_DIR$/examples/watch_throttled/dist" />
<excludeFolder url="file://$MODULE_DIR$/examples/use_webtransport_with_server/client/target" />
<excludeFolder url="file://$MODULE_DIR$/examples/use_webtransport_with_server/server/target" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />

View file

@ -46,7 +46,8 @@ members = [
] ]
exclude = [ exclude = [
"ssr" "ssr",
"use_webtransport_with_server",
] ]
[package] [package]

View file

@ -1,14 +1,14 @@
[package] [package]
name = "use_webtransport" name = "use_webtransport_with_server_client"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
leptos = { version = "0.5.0-beta2", features = ["nightly", "csr"] } leptos = { version = "0.5.0-rc1", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1" console_error_panic_hook = "0.1"
console_log = "1" console_log = "1"
log = "0.4" log = "0.4"
leptos-use = { path = "../..", features = ["docs"] } leptos-use = { path = "../../..", features = ["docs"] }
web-sys = "0.3" web-sys = "0.3"
[dev-dependencies] [dev-dependencies]

View file

@ -18,7 +18,7 @@ fn Demo() -> impl IntoView {
let id = store_value(0); let id = store_value(0);
let transport = use_webtransport_with_options( let transport = use_webtransport_with_options(
"https://echo.webtransport.day", "https://localhost:4433",
UseWebTransportOptions::default() UseWebTransportOptions::default()
.on_open(move || { .on_open(move || {
set_datagrams_log.update(|log| log.push("Connection opened".to_string())) set_datagrams_log.update(|log| log.push("Connection opened".to_string()))

View file

@ -0,0 +1,15 @@
[package]
name = "webtransport_test_server"
version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1"
base64 = "0.21.0"
rcgen = "0.10.0"
ring = "0.16.20"
time = "0.3.21"
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
wtransport = "0.1"

View file

@ -0,0 +1,9 @@
-----BEGIN CERTIFICATE-----
MIIBNTCB3KADAgECAghq294raE5e9TAKBggqhkjOPQQDAjAUMRIwEAYDVQQDDAls
b2NhbGhvc3QwHhcNMjMwOTEzMDEyNzIxWhcNMjMwOTE3MDEyNzIxWjAUMRIwEAYD
VQQDDAlsb2NhbGhvc3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARel++iw3/0
CPZTew09XTEmyKWGyUW7clEok17gb6BIqVZHy5pZ+P1F/qHSSuJtzZ+WFueVS1ZO
MCDfQql88sIyoxgwFjAUBgNVHREEDTALgglsb2NhbGhvc3QwCgYIKoZIzj0EAwID
SAAwRQIhAMQi1xToDZY8y4zZMOk7JJ3qqFOei6JkNcZf/68Zdgk3AiBCbPgLxaIw
n4bYLm0yqzQ5jzaJcOkrLMBQakaHJMyFoA==
-----END CERTIFICATE-----

View file

@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgsOnsJtFGWK8w011r
400WvxgSScmnnAWFyuQ+o/dhvDGhRANCAARel++iw3/0CPZTew09XTEmyKWGyUW7
clEok17gb6BIqVZHy5pZ+P1F/qHSSuJtzZ+WFueVS1ZOMCDfQql88sIy
-----END PRIVATE KEY-----

View file

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

View file

@ -0,0 +1,50 @@
use base64::engine::general_purpose::STANDARD as Base64Engine;
use base64::Engine;
use rcgen::CertificateParams;
use rcgen::DistinguishedName;
use rcgen::DnType;
use rcgen::KeyPair;
use rcgen::PKCS_ECDSA_P256_SHA256;
use ring::digest::digest;
use ring::digest::SHA256;
use std::fs;
use std::io::Write;
use time::Duration;
use time::OffsetDateTime;
fn main() {
const COMMON_NAME: &str = "localhost";
let mut dname = DistinguishedName::new();
dname.push(DnType::CommonName, COMMON_NAME);
let keypair = KeyPair::generate(&PKCS_ECDSA_P256_SHA256).unwrap();
let digest = digest(&SHA256, &keypair.public_key_der());
let mut cert_params = CertificateParams::new(vec![COMMON_NAME.to_string()]);
cert_params.distinguished_name = dname;
cert_params.alg = &PKCS_ECDSA_P256_SHA256;
cert_params.key_pair = Some(keypair);
cert_params.not_before = OffsetDateTime::now_utc()
.checked_sub(Duration::days(2))
.unwrap();
cert_params.not_after = OffsetDateTime::now_utc()
.checked_add(Duration::days(2))
.unwrap();
let certificate = rcgen::Certificate::from_params(cert_params).unwrap();
fs::File::create("cert.pem")
.unwrap()
.write_all(certificate.serialize_pem().unwrap().as_bytes())
.unwrap();
fs::File::create("key.pem")
.unwrap()
.write_all(certificate.serialize_private_key_pem().as_bytes())
.unwrap();
println!("Certificate generated");
println!("Fingerprint: {}", Base64Engine.encode(digest));
}

View file

@ -0,0 +1,113 @@
use anyhow::Result;
use std::time::Duration;
use tracing::error;
use tracing::info;
use tracing::info_span;
use tracing::Instrument;
use tracing_subscriber::filter::LevelFilter;
use tracing_subscriber::EnvFilter;
use wtransport::endpoint::IncomingSession;
use wtransport::tls::Certificate;
use wtransport::Endpoint;
use wtransport::ServerConfig;
#[tokio::main]
async fn main() -> Result<()> {
init_logging();
let config = ServerConfig::builder()
.with_bind_default(4433)
.with_certificate(Certificate::load("cert.pem", "key.pem")?)
.keep_alive_interval(Some(Duration::from_secs(3)))
.build();
let server = Endpoint::server(config)?;
info!("Server listening at localhost:4433");
for id in 0.. {
let incoming_session = server.accept().await;
tokio::spawn(handle_connection(incoming_session).instrument(info_span!("Connection", id)));
}
Ok(())
}
async fn handle_connection(incoming_session: IncomingSession) {
let result = handle_connection_impl(incoming_session).await;
error!("{:?}", result);
}
async fn handle_connection_impl(incoming_session: IncomingSession) -> Result<()> {
let mut buffer = vec![0; 65536].into_boxed_slice();
info!("Waiting for session request...");
let session_request = incoming_session.await?;
info!(
"New session: Authority: '{}', Path: '{}'",
session_request.authority(),
session_request.path()
);
let connection = session_request.accept().await?;
info!("Waiting for data from client...");
loop {
tokio::select! {
stream = connection.accept_bi() => {
let mut stream = stream?;
info!("Accepted BI stream");
let bytes_read = match stream.1.read(&mut buffer).await? {
Some(bytes_read) => bytes_read,
None => continue,
};
let str_data = std::str::from_utf8(&buffer[..bytes_read])?;
info!("Received (bi) '{str_data}' from client");
stream.0.write_all(b"ACK").await?;
}
stream = connection.accept_uni() => {
let mut stream = stream?;
info!("Accepted UNI stream");
let bytes_read = match stream.read(&mut buffer).await? {
Some(bytes_read) => bytes_read,
None => continue,
};
let str_data = std::str::from_utf8(&buffer[..bytes_read])?;
info!("Received (uni) '{str_data}' from client");
let mut stream = connection.open_uni().await?.await?;
stream.write_all(b"ACK").await?;
}
dgram = connection.receive_datagram() => {
let dgram = dgram?;
let str_data = std::str::from_utf8(&dgram)?;
info!("Received (dgram) '{str_data}' from client");
connection.send_datagram(b"ACK")?;
}
}
}
}
fn init_logging() {
let env_filter = EnvFilter::builder()
.with_default_directive(LevelFilter::INFO.into())
.from_env_lossy();
tracing_subscriber::fmt()
.with_target(true)
.with_level(true)
.with_env_filter(env_filter)
.init();
}