h3x/
client.rs

1use std::sync::Arc;
2
3use http::uri::Authority;
4
5pub use crate::message::stream::{ReadToStringError, StreamError};
6use crate::{
7    connection::{Connection, settings::Settings},
8    pool::{self, Pool},
9    quic,
10};
11
12mod message;
13pub use message::{PendingRequest, Request, RequestError, Response};
14
15#[cfg(feature = "gm-quic")]
16mod gm_quic;
17#[cfg(feature = "gm-quic")]
18pub use crate::{
19    client::gm_quic::{BuildClientError, GmQuicClientBuilder, GmQuicClientTlsBuilder},
20    util::tls::InvalidIdentity,
21};
22
23#[derive(Debug, Clone)]
24pub struct Client<C: quic::Connect> {
25    pool: Pool<C::Connection>,
26    client: C,
27    settings: Arc<Settings>,
28}
29
30#[bon::bon]
31impl<C: quic::Connect> Client<C> {
32    #[builder(
33        builder_type(vis = "pub"),
34        start_fn(name = from_quic_client, vis = "pub")
35    )]
36    fn new(
37        #[builder(default = Pool::global().clone())] pool: Pool<C::Connection>,
38        client: C,
39        #[builder(default)] settings: Arc<Settings>,
40    ) -> Self {
41        Self {
42            pool,
43            client,
44            settings,
45        }
46    }
47
48    pub fn quic_clinet(&self) -> &C {
49        &self.client
50    }
51
52    pub fn quic_client_mut(&mut self) -> &mut C {
53        &mut self.client
54    }
55
56    pub async fn connect(
57        &self,
58        server: Authority,
59    ) -> Result<Arc<Connection<C::Connection>>, pool::ConnectError<C::Error>> {
60        let host_port = server
61            .as_str()
62            .rsplit_once('@')
63            .map(|(_username_password, host_port)| host_port)
64            .unwrap_or(server.as_str());
65        let connect = async || self.client.connect(host_port).await;
66        self.pool
67            .reuse_or_connect_with(server.clone(), self.settings.clone(), connect)
68            .await
69    }
70}
71
72#[cfg(feature = "gm-quic")]
73pub fn builder() -> gm_quic::GmQuicClientTlsBuilder {
74    Client::builder()
75}