Skip to main content

webtrans_wasm/
client.rs

1use js_sys::Uint8Array;
2use url::Url;
3use wasm_bindgen_futures::JsFuture;
4use web_sys::{WebTransport, WebTransportHash, WebTransportOptions};
5
6use crate::{Error, Session};
7
8pub use web_sys::WebTransportCongestionControl as CongestionControl;
9
10/// Builder wrapper for [`WebTransportOptions`].
11#[derive(Debug, Default)]
12pub struct ClientBuilder {
13    options: WebTransportOptions,
14}
15
16impl ClientBuilder {
17    pub fn new() -> Self {
18        Self::default()
19    }
20
21    /// Control whether the client/server is allowed to pool connections.
22    /// In practice, keep this disabled unless you have a specific need.
23    pub fn with_pooling(self, val: bool) -> Self {
24        self.options.set_allow_pooling(val);
25        self
26    }
27
28    /// `true` if QUIC is required, `false` if TCP is an acceptable fallback.
29    pub fn with_unreliable(self, val: bool) -> Self {
30        self.options.set_require_unreliable(val);
31        self
32    }
33
34    /// Hint at the desired congestion control algorithm.
35    pub fn with_congestion_control(self, control: CongestionControl) -> Self {
36        self.options.set_congestion_control(control);
37        self
38    }
39
40    /// Supply SHA-256 hashes for accepted certificates instead of using a root CA.
41    pub fn with_server_certificate_hashes(self, hashes: Vec<Vec<u8>>) -> Client {
42        // Expected format: [{ algorithm: "sha-256", value: hashValue }, ...].
43        let hashes = hashes
44            .into_iter()
45            .map(|hash| {
46                let hash_obj = WebTransportHash::new();
47                hash_obj.set_algorithm("sha-256");
48                hash_obj.set_value_u8_array(&Uint8Array::from(&hash[..]));
49                hash_obj
50            })
51            .collect::<Vec<WebTransportHash>>();
52
53        self.options.set_server_certificate_hashes(&hashes);
54        Client {
55            options: self.options,
56        }
57    }
58
59    pub fn with_system_roots(self) -> Client {
60        Client {
61            options: self.options,
62        }
63    }
64}
65
66/// Build a client with the given URL and options.
67///
68/// See [`WebTransportOptions`].
69#[derive(Clone, Debug, Default)]
70pub struct Client {
71    options: WebTransportOptions,
72}
73
74impl Client {
75    /// Connect once the builder is configured.
76    pub async fn connect(&self, url: Url) -> Result<Session, Error> {
77        let inner = WebTransport::new_with_options(url.as_str(), &self.options)?;
78        JsFuture::from(inner.ready()).await?;
79
80        Ok(Session::new(inner, url))
81    }
82}