cloud_sdk_reqwest/blocking/
config.rs1use core::fmt;
2
3#[cfg(any(feature = "blocking-rustls", feature = "blocking-rustls-webpki-roots"))]
4use rustls::ClientConfig;
5#[cfg(feature = "blocking-rustls-webpki-roots")]
6use rustls::RootCertStore;
7#[cfg(feature = "blocking-rustls-webpki-roots")]
8use std::sync::Arc;
9
10#[cfg(not(feature = "blocking-rustls-webpki-roots"))]
11use crate::shared::platform_client_config;
12use crate::shared::{
13 BearerCredential, BuildError, HttpsEndpoint, LinkLocalHttpEndpoint, RawHyperClient,
14 RequestTimeouts, UserAgent,
15};
16
17use super::{BlockingClient, RawBlockingClient};
18
19pub struct BlockingClientBuilder {
22 endpoint: HttpsEndpoint,
23 credential: BearerCredential,
24 user_agent: UserAgent,
25 timeouts: RequestTimeouts,
26}
27
28pub struct RawBlockingClientBuilder {
30 endpoint: HttpsEndpoint,
31 user_agent: UserAgent,
32 timeouts: RequestTimeouts,
33}
34
35pub struct RawLinkLocalBlockingClientBuilder {
37 endpoint: LinkLocalHttpEndpoint,
38 user_agent: UserAgent,
39 timeouts: RequestTimeouts,
40}
41
42impl BlockingClientBuilder {
43 #[must_use]
45 pub const fn new(
46 endpoint: HttpsEndpoint,
47 credential: BearerCredential,
48 user_agent: UserAgent,
49 timeouts: RequestTimeouts,
50 ) -> Self {
51 Self {
52 endpoint,
53 credential,
54 user_agent,
55 timeouts,
56 }
57 }
58
59 pub fn build(self) -> Result<BlockingClient, BuildError> {
61 self.build_inner(true)
62 }
63
64 fn build_inner(self, https_only: bool) -> Result<BlockingClient, BuildError> {
65 if !self.credential.scope.matches_endpoint(&self.endpoint) {
66 return Err(BuildError::CredentialEndpointMismatch);
67 }
68 let settings = ClientSettings {
69 timeouts: self.timeouts,
70 };
71 let client = configured_raw_client(
72 self.endpoint.clone(),
73 &self.user_agent,
74 settings,
75 https_only,
76 )?;
77 Ok(BlockingClient::new(
78 client,
79 self.endpoint,
80 self.credential,
81 !https_only,
82 ))
83 }
84
85 #[cfg(test)]
86 pub(super) fn build_for_loopback(self) -> Result<BlockingClient, BuildError> {
87 self.build_inner(false)
88 }
89}
90
91impl RawBlockingClientBuilder {
92 #[must_use]
94 pub const fn new(
95 endpoint: HttpsEndpoint,
96 user_agent: UserAgent,
97 timeouts: RequestTimeouts,
98 ) -> Self {
99 Self {
100 endpoint,
101 user_agent,
102 timeouts,
103 }
104 }
105
106 pub fn build(self) -> Result<RawBlockingClient, BuildError> {
108 self.build_inner(true)
109 }
110
111 fn build_inner(self, https_only: bool) -> Result<RawBlockingClient, BuildError> {
112 let settings = ClientSettings {
113 timeouts: self.timeouts,
114 };
115 configured_raw_client(self.endpoint, &self.user_agent, settings, https_only)
116 }
117
118 #[cfg(test)]
119 pub(super) fn build_for_loopback(self) -> Result<RawBlockingClient, BuildError> {
120 self.build_inner(false)
121 }
122}
123
124impl RawLinkLocalBlockingClientBuilder {
125 #[must_use]
127 pub const fn new(
128 endpoint: LinkLocalHttpEndpoint,
129 user_agent: UserAgent,
130 timeouts: RequestTimeouts,
131 ) -> Self {
132 Self {
133 endpoint,
134 user_agent,
135 timeouts,
136 }
137 }
138
139 pub fn build(self) -> Result<RawBlockingClient, BuildError> {
141 let settings = ClientSettings {
142 timeouts: self.timeouts,
143 };
144 configured_raw_client(
145 self.endpoint.into_inner(),
146 &self.user_agent,
147 settings,
148 false,
149 )
150 }
151}
152
153impl fmt::Debug for BlockingClientBuilder {
154 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
155 let mut debug = formatter.debug_struct("BlockingClientBuilder");
156 debug
157 .field("endpoint", &"[redacted]")
158 .field("credential", &"[redacted]")
159 .field("user_agent", &self.user_agent)
160 .field("timeouts", &self.timeouts);
161 debug.finish()
162 }
163}
164
165impl fmt::Debug for RawBlockingClientBuilder {
166 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
167 let mut debug = formatter.debug_struct("RawBlockingClientBuilder");
168 debug
169 .field("endpoint", &"[redacted]")
170 .field("user_agent", &self.user_agent)
171 .field("timeouts", &self.timeouts);
172 debug.finish()
173 }
174}
175
176impl fmt::Debug for RawLinkLocalBlockingClientBuilder {
177 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
178 formatter
179 .debug_struct("RawLinkLocalBlockingClientBuilder")
180 .field("endpoint", &"[redacted]")
181 .field("user_agent", &self.user_agent)
182 .field("timeouts", &self.timeouts)
183 .finish()
184 }
185}
186
187#[derive(Clone, Copy)]
188pub(super) struct ClientSettings {
189 pub(super) timeouts: RequestTimeouts,
190}
191
192pub(super) fn configured_raw_client(
193 endpoint: HttpsEndpoint,
194 user_agent: &UserAgent,
195 settings: ClientSettings,
196 https_only: bool,
197) -> Result<RawBlockingClient, BuildError> {
198 let tls_config = raw_tls_config(settings)?;
199 let client = RawHyperClient::new(
200 endpoint.clone(),
201 user_agent,
202 settings.timeouts,
203 tls_config,
204 https_only,
205 )?;
206 Ok(RawBlockingClient::new(client, endpoint))
207}
208
209#[cfg(not(feature = "blocking-rustls-webpki-roots"))]
210fn raw_tls_config(_settings: ClientSettings) -> Result<ClientConfig, BuildError> {
211 platform_client_config()
212}
213
214#[cfg(feature = "blocking-rustls-webpki-roots")]
215fn raw_tls_config(_settings: ClientSettings) -> Result<ClientConfig, BuildError> {
216 webpki_roots_client_config()
217}
218
219#[cfg(feature = "blocking-rustls-webpki-roots")]
220fn webpki_roots_client_config() -> Result<ClientConfig, BuildError> {
221 let provider = Arc::new(rustls::crypto::aws_lc_rs::default_provider());
222 let mut roots = RootCertStore::empty();
223 roots.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
224 Ok(ClientConfig::builder_with_provider(provider)
225 .with_safe_default_protocol_versions()
226 .map_err(|_| BuildError::WebPkiRootsProtocolConfigurationFailed)?
227 .with_root_certificates(roots)
228 .with_no_client_auth())
229}
230
231#[cfg(all(test, feature = "blocking-rustls-webpki-roots"))]
232pub(super) fn test_webpki_roots_configuration() -> Result<(usize, bool), BuildError> {
233 let config = webpki_roots_client_config()?;
234 Ok((webpki_roots::TLS_SERVER_ROOTS.len(), config.fips()))
235}