1use std::{num::NonZeroU32, time::Duration};
2
3use crate::{
4 Proxy,
5 client::{
6 conn::TcpConnectOptions,
7 layer::{recovery::Recoveries, timeout::TimeoutOptions},
8 },
9 redirect, retry,
10 tls::{CertStore, Identity, KeyLog, TlsVersion},
11};
12
13#[derive(Clone, Copy, Default, Eq, PartialEq)]
15pub enum HttpVersionPreference {
16 Http1,
18 Http2,
20 #[default]
22 All,
23}
24
25#[must_use]
29#[derive(Clone)]
30pub struct TransportConfigOptions {
31 pub(crate) connect_timeout: Option<Duration>,
32 pub(crate) connection_verbose: bool,
33 pub(crate) tcp_nodelay: bool,
34 pub(crate) tcp_reuse_address: bool,
35 pub(crate) tcp_keepalive: Option<Duration>,
36 pub(crate) tcp_keepalive_interval: Option<Duration>,
37 pub(crate) tcp_keepalive_retries: Option<u32>,
38 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
39 pub(crate) tcp_user_timeout: Option<Duration>,
40 pub(crate) tcp_send_buffer_size: Option<usize>,
41 pub(crate) tcp_recv_buffer_size: Option<usize>,
42 pub(crate) tcp_happy_eyeballs_timeout: Option<Duration>,
43 pub(crate) tcp_connect_options: TcpConnectOptions,
44}
45
46impl Default for TransportConfigOptions {
47 fn default() -> Self {
48 Self {
49 connect_timeout: None,
50 connection_verbose: false,
51 tcp_nodelay: true,
52 tcp_reuse_address: false,
53 tcp_keepalive: Some(Duration::from_secs(15)),
54 tcp_keepalive_interval: Some(Duration::from_secs(15)),
55 tcp_keepalive_retries: Some(3),
56 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
57 tcp_user_timeout: Some(Duration::from_secs(30)),
58 tcp_send_buffer_size: None,
59 tcp_recv_buffer_size: None,
60 tcp_happy_eyeballs_timeout: Some(Duration::from_millis(300)),
61 tcp_connect_options: TcpConnectOptions::default(),
62 }
63 }
64}
65
66impl TransportConfigOptions {
67 pub fn new() -> Self {
69 Self::default()
70 }
71
72 pub fn connect_timeout<D>(mut self, timeout: D) -> Self
74 where
75 D: Into<Option<Duration>>,
76 {
77 self.connect_timeout = timeout.into();
78 self
79 }
80
81 pub fn connection_verbose(mut self, verbose: bool) -> Self {
83 self.connection_verbose = verbose;
84 self
85 }
86
87 pub fn tcp_nodelay(mut self, enabled: bool) -> Self {
89 self.tcp_nodelay = enabled;
90 self
91 }
92
93 pub fn tcp_reuse_address(mut self, enabled: bool) -> Self {
95 self.tcp_reuse_address = enabled;
96 self
97 }
98
99 pub fn tcp_keepalive<D>(mut self, value: D) -> Self
101 where
102 D: Into<Option<Duration>>,
103 {
104 self.tcp_keepalive = value.into();
105 self
106 }
107
108 pub fn tcp_keepalive_interval<D>(mut self, value: D) -> Self
110 where
111 D: Into<Option<Duration>>,
112 {
113 self.tcp_keepalive_interval = value.into();
114 self
115 }
116
117 pub fn tcp_keepalive_retries<C>(mut self, retries: C) -> Self
119 where
120 C: Into<Option<u32>>,
121 {
122 self.tcp_keepalive_retries = retries.into();
123 self
124 }
125
126 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
128 #[cfg_attr(
129 docsrs,
130 doc(cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux")))
131 )]
132 pub fn tcp_user_timeout<D>(mut self, value: D) -> Self
133 where
134 D: Into<Option<Duration>>,
135 {
136 self.tcp_user_timeout = value.into();
137 self
138 }
139
140 pub fn tcp_send_buffer_size<S>(mut self, size: S) -> Self
142 where
143 S: Into<Option<usize>>,
144 {
145 self.tcp_send_buffer_size = size.into();
146 self
147 }
148
149 pub fn tcp_recv_buffer_size<S>(mut self, size: S) -> Self
151 where
152 S: Into<Option<usize>>,
153 {
154 self.tcp_recv_buffer_size = size.into();
155 self
156 }
157
158 pub fn tcp_happy_eyeballs_timeout<D>(mut self, value: D) -> Self
160 where
161 D: Into<Option<Duration>>,
162 {
163 self.tcp_happy_eyeballs_timeout = value.into();
164 self
165 }
166
167 pub fn tcp_connect_options(mut self, options: TcpConnectOptions) -> Self {
169 self.tcp_connect_options = options;
170 self
171 }
172}
173
174#[must_use]
176#[derive(Clone)]
177pub struct PoolConfigOptions {
178 pub(crate) idle_timeout: Option<Duration>,
179 pub(crate) max_idle_per_host: usize,
180 pub(crate) max_size: Option<NonZeroU32>,
181}
182
183impl Default for PoolConfigOptions {
184 fn default() -> Self {
185 Self {
186 idle_timeout: Some(Duration::from_secs(90)),
187 max_idle_per_host: usize::MAX,
188 max_size: None,
189 }
190 }
191}
192
193impl PoolConfigOptions {
194 pub fn new() -> Self {
196 Self::default()
197 }
198
199 pub fn idle_timeout<D>(mut self, value: D) -> Self
201 where
202 D: Into<Option<Duration>>,
203 {
204 self.idle_timeout = value.into();
205 self
206 }
207
208 pub fn max_idle_per_host(mut self, max: usize) -> Self {
210 self.max_idle_per_host = max;
211 self
212 }
213
214 pub fn max_size(mut self, max: Option<u32>) -> Self {
216 self.max_size = max.and_then(NonZeroU32::new);
217 self
218 }
219}
220
221#[must_use]
223#[derive(Clone)]
224pub struct TlsConfigOptions {
225 pub(crate) keylog: Option<KeyLog>,
226 pub(crate) tls_info: bool,
227 pub(crate) tls_sni: bool,
228 pub(crate) verify_hostname: bool,
229 pub(crate) identity: Option<Identity>,
230 pub(crate) cert_store: CertStore,
231 pub(crate) cert_verification: bool,
232 pub(crate) min_version: Option<TlsVersion>,
233 pub(crate) max_version: Option<TlsVersion>,
234}
235
236impl Default for TlsConfigOptions {
237 fn default() -> Self {
238 Self {
239 keylog: None,
240 tls_info: false,
241 tls_sni: true,
242 verify_hostname: true,
243 identity: None,
244 cert_store: CertStore::default(),
245 cert_verification: true,
246 min_version: None,
247 max_version: None,
248 }
249 }
250}
251
252impl TlsConfigOptions {
253 pub fn new() -> Self {
255 Self::default()
256 }
257
258 pub fn identity(mut self, identity: Identity) -> Self {
260 self.identity = Some(identity);
261 self
262 }
263
264 pub fn cert_store(mut self, store: CertStore) -> Self {
266 self.cert_store = store;
267 self
268 }
269
270 pub fn cert_verification(mut self, enabled: bool) -> Self {
272 self.cert_verification = enabled;
273 self
274 }
275
276 pub fn verify_hostname(mut self, enabled: bool) -> Self {
278 self.verify_hostname = enabled;
279 self
280 }
281
282 pub fn tls_sni(mut self, enabled: bool) -> Self {
284 self.tls_sni = enabled;
285 self
286 }
287
288 pub fn tls_info(mut self, enabled: bool) -> Self {
290 self.tls_info = enabled;
291 self
292 }
293
294 pub fn keylog(mut self, keylog: KeyLog) -> Self {
296 self.keylog = Some(keylog);
297 self
298 }
299
300 pub fn min_tls_version(mut self, version: TlsVersion) -> Self {
302 self.min_version = Some(version);
303 self
304 }
305
306 pub fn max_tls_version(mut self, version: TlsVersion) -> Self {
308 self.max_version = Some(version);
309 self
310 }
311}
312
313#[must_use]
315#[derive(Clone)]
316pub struct ProtocolConfigOptions {
317 pub(crate) http_version_preference: HttpVersionPreference,
318 pub(crate) https_only: bool,
319 pub(crate) retry_policy: retry::Policy,
320 pub(crate) redirect_policy: redirect::Policy,
321 pub(crate) referer: bool,
322 pub(crate) timeout_options: TimeoutOptions,
323 pub(crate) recoveries: Recoveries,
324}
325
326impl Default for ProtocolConfigOptions {
327 fn default() -> Self {
328 Self {
329 http_version_preference: HttpVersionPreference::All,
330 https_only: false,
331 retry_policy: retry::Policy::default(),
332 redirect_policy: redirect::Policy::none(),
333 referer: true,
334 timeout_options: TimeoutOptions::default(),
335 recoveries: Recoveries::new(),
336 }
337 }
338}
339
340impl ProtocolConfigOptions {
341 pub fn new() -> Self {
343 Self::default()
344 }
345
346 pub fn http_version_preference(mut self, preference: HttpVersionPreference) -> Self {
348 self.http_version_preference = preference;
349 self
350 }
351
352 pub fn https_only(mut self, enabled: bool) -> Self {
354 self.https_only = enabled;
355 self
356 }
357
358 pub fn retry_policy(mut self, policy: retry::Policy) -> Self {
360 self.retry_policy = policy;
361 self
362 }
363
364 pub fn redirect_policy(mut self, policy: redirect::Policy) -> Self {
366 self.redirect_policy = policy;
367 self
368 }
369
370 pub fn referer(mut self, enabled: bool) -> Self {
372 self.referer = enabled;
373 self
374 }
375
376 pub fn timeout_options(mut self, options: TimeoutOptions) -> Self {
378 self.timeout_options = options;
379 self
380 }
381
382 pub fn recoveries(mut self, recoveries: Recoveries) -> Self {
384 self.recoveries = recoveries;
385 self
386 }
387}
388
389#[must_use]
391#[derive(Clone)]
392pub struct ProxyConfigOptions {
393 pub(crate) proxies: Vec<Proxy>,
394 pub(crate) auto_system_proxy: bool,
395}
396
397impl Default for ProxyConfigOptions {
398 fn default() -> Self {
399 Self::new()
400 }
401}
402
403impl ProxyConfigOptions {
404 pub fn new() -> Self {
406 Self {
407 proxies: Vec::new(),
408 auto_system_proxy: true,
409 }
410 }
411
412 pub fn system_proxy(mut self, enabled: bool) -> Self {
414 self.auto_system_proxy = enabled;
415 self
416 }
417
418 pub fn proxy(mut self, proxy: Proxy) -> Self {
420 self.proxies.push(proxy);
421 self.auto_system_proxy = false;
422 self
423 }
424
425 pub fn proxies<I>(mut self, proxies: I) -> Self
427 where
428 I: IntoIterator<Item = Proxy>,
429 {
430 self.proxies = proxies.into_iter().collect();
431 self.auto_system_proxy = false;
432 self
433 }
434
435 pub fn no_proxy(mut self) -> Self {
437 self.proxies.clear();
438 self.auto_system_proxy = false;
439 self
440 }
441}