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, RawHyperClient, RequestTimeouts, UserAgent,
14};
15
16use super::{BlockingClient, RawBlockingClient};
17
18pub struct BlockingClientBuilder {
21 endpoint: HttpsEndpoint,
22 credential: BearerCredential,
23 user_agent: UserAgent,
24 timeouts: RequestTimeouts,
25}
26
27pub struct RawBlockingClientBuilder {
29 endpoint: HttpsEndpoint,
30 user_agent: UserAgent,
31 timeouts: RequestTimeouts,
32}
33
34impl BlockingClientBuilder {
35 #[must_use]
37 pub const fn new(
38 endpoint: HttpsEndpoint,
39 credential: BearerCredential,
40 user_agent: UserAgent,
41 timeouts: RequestTimeouts,
42 ) -> Self {
43 Self {
44 endpoint,
45 credential,
46 user_agent,
47 timeouts,
48 }
49 }
50
51 pub fn build(self) -> Result<BlockingClient, BuildError> {
53 self.build_inner(true)
54 }
55
56 fn build_inner(self, https_only: bool) -> Result<BlockingClient, BuildError> {
57 if !self.credential.scope.matches_endpoint(&self.endpoint) {
58 return Err(BuildError::CredentialEndpointMismatch);
59 }
60 let settings = ClientSettings {
61 timeouts: self.timeouts,
62 };
63 let client = configured_raw_client(
64 self.endpoint.clone(),
65 &self.user_agent,
66 settings,
67 https_only,
68 )?;
69 Ok(BlockingClient::new(
70 client,
71 self.endpoint,
72 self.credential,
73 !https_only,
74 ))
75 }
76
77 #[cfg(test)]
78 pub(super) fn build_for_loopback(self) -> Result<BlockingClient, BuildError> {
79 self.build_inner(false)
80 }
81}
82
83impl RawBlockingClientBuilder {
84 #[must_use]
86 pub const fn new(
87 endpoint: HttpsEndpoint,
88 user_agent: UserAgent,
89 timeouts: RequestTimeouts,
90 ) -> Self {
91 Self {
92 endpoint,
93 user_agent,
94 timeouts,
95 }
96 }
97
98 pub fn build(self) -> Result<RawBlockingClient, BuildError> {
100 self.build_inner(true)
101 }
102
103 fn build_inner(self, https_only: bool) -> Result<RawBlockingClient, BuildError> {
104 let settings = ClientSettings {
105 timeouts: self.timeouts,
106 };
107 configured_raw_client(self.endpoint, &self.user_agent, settings, https_only)
108 }
109
110 #[cfg(test)]
111 pub(super) fn build_for_loopback(self) -> Result<RawBlockingClient, BuildError> {
112 self.build_inner(false)
113 }
114}
115
116impl fmt::Debug for BlockingClientBuilder {
117 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
118 let mut debug = formatter.debug_struct("BlockingClientBuilder");
119 debug
120 .field("endpoint", &"[redacted]")
121 .field("credential", &"[redacted]")
122 .field("user_agent", &self.user_agent)
123 .field("timeouts", &self.timeouts);
124 debug.finish()
125 }
126}
127
128impl fmt::Debug for RawBlockingClientBuilder {
129 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
130 let mut debug = formatter.debug_struct("RawBlockingClientBuilder");
131 debug
132 .field("endpoint", &"[redacted]")
133 .field("user_agent", &self.user_agent)
134 .field("timeouts", &self.timeouts);
135 debug.finish()
136 }
137}
138
139#[derive(Clone, Copy)]
140pub(super) struct ClientSettings {
141 pub(super) timeouts: RequestTimeouts,
142}
143
144pub(super) fn configured_raw_client(
145 endpoint: HttpsEndpoint,
146 user_agent: &UserAgent,
147 settings: ClientSettings,
148 https_only: bool,
149) -> Result<RawBlockingClient, BuildError> {
150 let tls_config = raw_tls_config(settings)?;
151 let client = RawHyperClient::new(
152 endpoint.clone(),
153 user_agent,
154 settings.timeouts,
155 tls_config,
156 https_only,
157 )?;
158 Ok(RawBlockingClient::new(client, endpoint))
159}
160
161#[cfg(not(feature = "blocking-rustls-webpki-roots"))]
162fn raw_tls_config(_settings: ClientSettings) -> Result<ClientConfig, BuildError> {
163 platform_client_config()
164}
165
166#[cfg(feature = "blocking-rustls-webpki-roots")]
167fn raw_tls_config(_settings: ClientSettings) -> Result<ClientConfig, BuildError> {
168 webpki_roots_client_config()
169}
170
171#[cfg(feature = "blocking-rustls-webpki-roots")]
172fn webpki_roots_client_config() -> Result<ClientConfig, BuildError> {
173 let provider = Arc::new(rustls::crypto::aws_lc_rs::default_provider());
174 let mut roots = RootCertStore::empty();
175 roots.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
176 Ok(ClientConfig::builder_with_provider(provider)
177 .with_safe_default_protocol_versions()
178 .map_err(|_| BuildError::WebPkiRootsProtocolConfigurationFailed)?
179 .with_root_certificates(roots)
180 .with_no_client_auth())
181}
182
183#[cfg(all(test, feature = "blocking-rustls-webpki-roots"))]
184pub(super) fn test_webpki_roots_configuration() -> Result<(usize, bool), BuildError> {
185 let config = webpki_roots_client_config()?;
186 Ok((webpki_roots::TLS_SERVER_ROOTS.len(), config.fips()))
187}