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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use hyper::{
self,
client::{HttpConnector, ResponseFuture},
Body, Request, Uri,
};
#[cfg(feature = "rustls")]
use hyper_rustls::HttpsConnector;
#[cfg(feature = "tls")]
use hyper_tls::HttpsConnector;
use hyper_proxy as proxy;
use proxy::ProxyConnector;
use hyper_socks2 as socks_proxy;
use socks_proxy::{Auth, SocksConnector};
pub type Https = HttpsConnector<HttpConnector>;
pub type HttpsProxy = ProxyConnector<Https>;
pub type SocksProxy = HttpsConnector<SocksConnector<Https>>;
#[derive(Debug)]
pub enum Client {
Https(hyper::Client<Https>),
HttpsProxy(hyper::Client<HttpsProxy>),
SocksProxy(hyper::Client<SocksProxy>),
}
impl Client {
pub(crate) fn https_proxy(proxy: proxy::Proxy) -> Self {
#[cfg(feature = "rustls")]
let https_connector = HttpsConnector::with_native_roots();
#[cfg(feature = "tls")]
let https_connector = HttpsConnector::new();
let connector = ProxyConnector::from_proxy(https_connector, proxy)
.unwrap_or_else(|error| {
panic!(
"[tbot] Failed to construct a proxy connector: {:#?}",
error
)
});
Self::HttpsProxy(
hyper::Client::builder()
.pool_max_idle_per_host(0)
.build::<HttpsProxy, Body>(connector),
)
}
pub(crate) fn socks_proxy(proxy_addr: Uri, auth: Option<Auth>) -> Self {
#[cfg(feature = "rustls")]
let https_connector = HttpsConnector::with_native_roots();
#[cfg(feature = "tls")]
let https_connector = HttpsConnector::new();
let connector = SocksConnector {
proxy_addr,
auth,
connector: https_connector,
};
let connector = connector.with_tls().unwrap_or_else(|error| {
panic!(
"[tbot] Failed to construct a SOCKS proxy connector: {:#?}",
error
)
});
Self::SocksProxy(
hyper::Client::builder()
.pool_max_idle_per_host(0)
.build::<SocksProxy, Body>(connector),
)
}
#[must_use]
pub(crate) fn https() -> Self {
#[cfg(feature = "rustls")]
let connector = HttpsConnector::with_native_roots();
#[cfg(feature = "tls")]
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::HttpsProxy(proxy) => proxy.get(uri),
Self::SocksProxy(socks_proxy) => socks_proxy.get(uri),
}
}
pub(crate) fn request(&self, req: Request<Body>) -> ResponseFuture {
match self {
Self::Https(https) => https.request(req),
Self::HttpsProxy(proxy) => proxy.request(req),
Self::SocksProxy(socks_proxy) => socks_proxy.request(req),
}
}
}