tonic/transport/channel/
tls.rs1use super::service::TlsConnector;
2use crate::transport::{
3 tls::{Certificate, Identity},
4 Error,
5};
6use http::Uri;
7use std::time::Duration;
8use tokio_rustls::rustls::pki_types::TrustAnchor;
9
10#[derive(Debug, Clone, Default)]
12pub struct ClientTlsConfig {
13 domain: Option<String>,
14 certs: Vec<Certificate>,
15 trust_anchors: Vec<TrustAnchor<'static>>,
16 identity: Option<Identity>,
17 assume_http2: bool,
18 #[cfg(feature = "tls-native-roots")]
19 with_native_roots: bool,
20 #[cfg(feature = "tls-webpki-roots")]
21 with_webpki_roots: bool,
22 use_key_log: bool,
23 timeout: Option<Duration>,
24}
25
26impl ClientTlsConfig {
27 pub fn new() -> Self {
29 Self::default()
30 }
31
32 pub fn domain_name(self, domain_name: impl Into<String>) -> Self {
34 ClientTlsConfig {
35 domain: Some(domain_name.into()),
36 ..self
37 }
38 }
39
40 pub fn ca_certificate(self, ca_certificate: Certificate) -> Self {
42 let mut certs = self.certs;
43 certs.push(ca_certificate);
44 ClientTlsConfig { certs, ..self }
45 }
46
47 pub fn ca_certificates(self, ca_certificates: impl IntoIterator<Item = Certificate>) -> Self {
49 let mut certs = self.certs;
50 certs.extend(ca_certificates);
51 ClientTlsConfig { certs, ..self }
52 }
53
54 pub fn trust_anchor(self, trust_anchor: TrustAnchor<'static>) -> Self {
56 let mut trust_anchors = self.trust_anchors;
57 trust_anchors.push(trust_anchor);
58 ClientTlsConfig {
59 trust_anchors,
60 ..self
61 }
62 }
63
64 pub fn trust_anchors(
66 mut self,
67 trust_anchors: impl IntoIterator<Item = TrustAnchor<'static>>,
68 ) -> Self {
69 self.trust_anchors.extend(trust_anchors);
70 self
71 }
72
73 pub fn identity(self, identity: Identity) -> Self {
75 ClientTlsConfig {
76 identity: Some(identity),
77 ..self
78 }
79 }
80
81 pub fn assume_http2(self, assume_http2: bool) -> Self {
84 ClientTlsConfig {
85 assume_http2,
86 ..self
87 }
88 }
89
90 pub fn use_key_log(self) -> Self {
92 ClientTlsConfig {
93 use_key_log: true,
94 ..self
95 }
96 }
97
98 #[cfg(feature = "tls-native-roots")]
100 pub fn with_native_roots(self) -> Self {
101 ClientTlsConfig {
102 with_native_roots: true,
103 ..self
104 }
105 }
106
107 #[cfg(feature = "tls-webpki-roots")]
109 pub fn with_webpki_roots(self) -> Self {
110 ClientTlsConfig {
111 with_webpki_roots: true,
112 ..self
113 }
114 }
115
116 pub fn with_enabled_roots(self) -> Self {
118 let config = self;
119
120 #[cfg(feature = "tls-native-roots")]
121 let config = config.with_native_roots();
122 #[cfg(feature = "tls-webpki-roots")]
123 let config = config.with_webpki_roots();
124
125 config
126 }
127
128 pub fn timeout(self, timeout: Duration) -> Self {
130 ClientTlsConfig {
131 timeout: Some(timeout),
132 ..self
133 }
134 }
135
136 pub(crate) fn into_tls_connector(self, uri: &Uri) -> Result<TlsConnector, crate::BoxError> {
137 let domain = match &self.domain {
138 Some(domain) => domain,
139 None => uri.host().ok_or_else(Error::new_invalid_uri)?,
140 };
141 TlsConnector::new(
142 self.certs,
143 self.trust_anchors,
144 self.identity,
145 domain,
146 self.assume_http2,
147 self.use_key_log,
148 self.timeout,
149 #[cfg(feature = "tls-native-roots")]
150 self.with_native_roots,
151 #[cfg(feature = "tls-webpki-roots")]
152 self.with_webpki_roots,
153 )
154 }
155}