71 lines
2.1 KiB
Rust
71 lines
2.1 KiB
Rust
use std::sync::Arc;
|
|
|
|
use iroh::{EndpointAddr, endpoint::{ConnectOptions, QuicTransportConfig}};
|
|
use url::Url;
|
|
|
|
use crate::{ALPN_H3, ClientError, Session};
|
|
|
|
/// A client for connecting to a WebTransport server.
|
|
pub struct Client {
|
|
endpoint: iroh::Endpoint,
|
|
config: QuicTransportConfig,
|
|
}
|
|
|
|
impl Client {
|
|
pub fn new(endpoint: iroh::Endpoint) -> Self {
|
|
Self::with_transport_config(endpoint, Default::default())
|
|
}
|
|
|
|
/// Creates a client from an endpoint and a transport config.
|
|
pub fn with_transport_config(
|
|
endpoint: iroh::Endpoint,
|
|
config: QuicTransportConfig,
|
|
) -> Self {
|
|
Self { endpoint, config }
|
|
}
|
|
|
|
/// Connect to a server over QUIC without HTTP/3.
|
|
pub async fn connect_quic(
|
|
&self,
|
|
addr: impl Into<EndpointAddr>,
|
|
alpn: &[u8],
|
|
) -> Result<Session, ClientError> {
|
|
let conn = self.connect(addr, alpn).await?;
|
|
Ok(Session::raw(conn))
|
|
}
|
|
|
|
/// Connect with a full HTTP/3 handshake and WebTransport semantics.
|
|
///
|
|
/// Note that the url needs to have a `https:` scheme, otherwise the accepting side will
|
|
/// fail to accept the connection.
|
|
pub async fn connect_h3(
|
|
&self,
|
|
addr: impl Into<EndpointAddr>,
|
|
url: Url,
|
|
) -> Result<Session, ClientError> {
|
|
let conn = self.connect(addr, ALPN_H3.as_bytes()).await?;
|
|
// Connect with the connection we established.
|
|
Session::connect_h3(conn, url).await
|
|
}
|
|
|
|
async fn connect(
|
|
&self,
|
|
addr: impl Into<EndpointAddr>,
|
|
alpn: &[u8],
|
|
) -> Result<iroh::endpoint::Connection, ClientError> {
|
|
let opts = ConnectOptions::new().with_transport_config(self.config.clone());
|
|
let conn = self
|
|
.endpoint
|
|
.connect_with_opts(addr, alpn, opts)
|
|
.await
|
|
.map_err(|err| ClientError::Connect(Arc::new(err.into())))?;
|
|
let conn = conn
|
|
.await
|
|
.map_err(|err| ClientError::Connect(Arc::new(err.into())))?;
|
|
Ok(conn)
|
|
}
|
|
|
|
pub async fn close(&self) {
|
|
self.endpoint.close().await;
|
|
}
|
|
}
|