1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! A few common connectors for making requests.

use hyper::{
    self,
    client::{HttpConnector, ResponseFuture},
    Body, Request, Uri,
};

#[cfg(feature = "rustls")]
use hyper_rustls::HttpsConnector;
#[cfg(feature = "tls")]
use hyper_tls::HttpsConnector;

pub use hyper_proxy as proxy;
use proxy::ProxyConnector;

/// The default HTTPS connector.
pub type Https = HttpsConnector<HttpConnector>;

/// The default proxy connector.
pub type Proxy = ProxyConnector<Https>;

#[derive(Debug)]
pub(crate) enum Client {
    Https(hyper::Client<Https>),
    Proxy(hyper::Client<Proxy>),
}

impl Client {
    pub(crate) fn proxy(proxy: proxy::Proxy) -> Self {
        let connector =
            ProxyConnector::from_proxy(HttpsConnector::new(), proxy)
                .unwrap_or_else(|error| {
                    panic!(
                        "[tbot] Failed to construct a proxy connector: {:#?}",
                        error
                    )
                });

        Self::Proxy(
            hyper::Client::builder()
                .pool_max_idle_per_host(0)
                .build::<Proxy, Body>(connector),
        )
    }

    #[must_use]
    pub(crate) fn https() -> Self {
        let connector = HttpsConnector::new();

        Self::Https(
            hyper::Client::builder()
                .pool_max_idle_per_host(0)
                .build::<Https, Body>(connector),
        )
    }

    pub(crate) fn get(&self, uri: Uri) -> ResponseFuture {
        match self {
            Self::Https(https) => https.get(uri),
            Self::Proxy(proxy) => proxy.get(uri),
        }
    }

    pub(crate) fn request(&self, req: Request<Body>) -> ResponseFuture {
        match self {
            Self::Https(https) => https.request(req),
            Self::Proxy(proxy) => proxy.request(req),
        }
    }
}