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
111
112
113
114
//! Includes helper functions to build [`Client`]s, and some re-exports from [`hyper::client`] or
//! [`hyper_tls`].

use hyper::body::HttpBody;
pub use hyper::client::{Builder, Client};

use hyper::client::connect::Connect;
pub use hyper::client::connect::HttpConnector;

#[cfg(feature = "https")]
#[cfg_attr(docsrs, doc(cfg(feature = "https")))]
pub use hyper_tls::HttpsConnector;

#[cfg(feature = "__rustls")]
#[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
pub use hyper_rustls::HttpsConnector as RustlsConnector;

#[cfg(feature = "nativetls")]
#[cfg_attr(docsrs, doc(cfg(feature = "nativetls")))]
pub use hyper_tls::HttpsConnector as NativeTlsConnector;

/// Default [`Builder`].
pub fn builder() -> Builder {
    Builder::default()
}

/// Same as [`Client::new()`], except for the `B` parameter.
pub fn http_default<B>() -> Client<HttpConnector, B>
where
    B: HttpBody + Send,
    B::Data: Send,
{
    Builder::default().build_http()
}

/// Alias to [`nativetls_default()`].
#[cfg(any(feature = "https", feature = "nativetls"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "https", feature = "nativetls"))))]
#[inline]
pub fn https_default<B>() -> Client<NativeTlsConnector<HttpConnector>, B>
where
    B: HttpBody + Send,
    B::Data: Send,
{
    nativetls_default()
}

/// With the default [`hyper_tls::HttpsConnector`].
#[cfg(feature = "nativetls")]
#[cfg_attr(docsrs, doc(cfg(feature = "nativetls")))]
pub fn nativetls_default<B>() -> Client<NativeTlsConnector<HttpConnector>, B>
where
    B: HttpBody + Send,
    B::Data: Send,
{
    Builder::default().build(NativeTlsConnector::new())
}

/// With the default [`hyper_rustls::HttpsConnector`].
///
/// The config is determined as follows. I think the cert root is similar to the `reqwest` crate.
///
/// 1. Cert roots
///
/// - if the feature `rustls-webpki-roots` is enabled, then use
/// [`HttpsConnector::with_webpki_roots()`](hyper_rustls::HttpsConnector::with_webpki_roots());
/// - if `rustls-webpki-roots` is disabled and `rustls-native-roots` enabled, then
/// [`HttpsConnector::with_native_roots()`](hyper_rustls::HttpsConnector::with_native_roots());
/// - otherwise compilation fails.
///
/// The feature `rustls` is equivalent to `rustls-webpki-roots`.
///
/// 2. Scheme
///
/// HTTPS only
///
/// 3. HTTP version
///
/// - if the feature `http1` is enabled, then call
/// [`HttpsConnector::enable_http1()`](hyper_rustls::HttpsConnector::enable_http1());
/// - if the feature `rustls-http2` is enabled, then call
/// [`HttpsConnector::enable_http2()`](hyper_rustls::HttpsConnector::enable_http2()).
///
/// This is not exclusive: if both features are enabled, then both mehtods are called.
///
#[cfg(feature = "__rustls")]
#[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
pub fn rustls_default<B>() -> Client<RustlsConnector<HttpConnector>, B>
where
    B: HttpBody + Send,
    B::Data: Send,
{
    let conn = hyper_rustls::HttpsConnectorBuilder::new();
    #[cfg(feature = "rustls-webpki-roots")]
    let conn = conn.with_webpki_roots();
    #[cfg(all(not(feature = "rustls-webpki-roots"), feature = "rustls-native-roots"))]
    let conn = conn.with_native_roots();
    let conn = conn.https_only();
    #[cfg(feature = "http1")]
    let conn = conn.enable_http1();
    #[cfg(feature = "rustls-http2")]
    let conn = conn.enable_http2();
    Builder::default().build(conn.build())
}

/// Default builder and given connector.
pub fn with_connector_default<C, B>(conn: C) -> Client<C, B>
where
    C: Connect + Clone,
    B: HttpBody + Send,
    B::Data: Send,
{
    Builder::default().build(conn)
}