tonic/transport/channel/
tls.rs1use super::service::TlsConnector;
2use crate::transport::{
3 tls::{Certificate, Identity},
4 Error,
5};
6use http::Uri;
7use tokio_rustls::rustls::pki_types::TrustAnchor;
8
9#[derive(Debug, Clone, Default)]
11pub struct ClientTlsConfig {
12 domain: Option<String>,
13 certs: Vec<Certificate>,
14 trust_anchors: Vec<TrustAnchor<'static>>,
15 identity: Option<Identity>,
16 assume_http2: bool,
17 #[cfg(feature = "tls-native-roots")]
18 with_native_roots: bool,
19 #[cfg(feature = "tls-webpki-roots")]
20 with_webpki_roots: bool,
21}
22
23impl ClientTlsConfig {
24 pub fn new() -> Self {
26 Self::default()
27 }
28
29 pub fn domain_name(self, domain_name: impl Into<String>) -> Self {
31 ClientTlsConfig {
32 domain: Some(domain_name.into()),
33 ..self
34 }
35 }
36
37 pub fn ca_certificate(self, ca_certificate: Certificate) -> Self {
39 let mut certs = self.certs;
40 certs.push(ca_certificate);
41 ClientTlsConfig { certs, ..self }
42 }
43
44 pub fn ca_certificates(self, ca_certificates: impl IntoIterator<Item = Certificate>) -> Self {
46 let mut certs = self.certs;
47 certs.extend(ca_certificates);
48 ClientTlsConfig { certs, ..self }
49 }
50
51 pub fn trust_anchor(self, trust_anchor: TrustAnchor<'static>) -> Self {
53 let mut trust_anchors = self.trust_anchors;
54 trust_anchors.push(trust_anchor);
55 ClientTlsConfig {
56 trust_anchors,
57 ..self
58 }
59 }
60
61 pub fn trust_anchors(
63 mut self,
64 trust_anchors: impl IntoIterator<Item = TrustAnchor<'static>>,
65 ) -> Self {
66 self.trust_anchors.extend(trust_anchors);
67 self
68 }
69
70 pub fn identity(self, identity: Identity) -> Self {
72 ClientTlsConfig {
73 identity: Some(identity),
74 ..self
75 }
76 }
77
78 pub fn assume_http2(self, assume_http2: bool) -> Self {
81 ClientTlsConfig {
82 assume_http2,
83 ..self
84 }
85 }
86
87 #[cfg(feature = "tls-native-roots")]
89 pub fn with_native_roots(self) -> Self {
90 ClientTlsConfig {
91 with_native_roots: true,
92 ..self
93 }
94 }
95
96 #[cfg(feature = "tls-webpki-roots")]
98 pub fn with_webpki_roots(self) -> Self {
99 ClientTlsConfig {
100 with_webpki_roots: true,
101 ..self
102 }
103 }
104
105 pub fn with_enabled_roots(self) -> Self {
107 let config = ClientTlsConfig::new();
108 #[cfg(feature = "tls-native-roots")]
109 let config = config.with_native_roots();
110 #[cfg(feature = "tls-webpki-roots")]
111 let config = config.with_webpki_roots();
112 config
113 }
114
115 pub(crate) fn into_tls_connector(self, uri: &Uri) -> Result<TlsConnector, crate::Error> {
116 let domain = match &self.domain {
117 Some(domain) => domain,
118 None => uri.host().ok_or_else(Error::new_invalid_uri)?,
119 };
120 TlsConnector::new(
121 self.certs,
122 self.trust_anchors,
123 self.identity,
124 domain,
125 self.assume_http2,
126 #[cfg(feature = "tls-native-roots")]
127 self.with_native_roots,
128 #[cfg(feature = "tls-webpki-roots")]
129 self.with_webpki_roots,
130 )
131 }
132}