Skip to main content

aws_types/
sdk_config.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#![deny(missing_docs)]
7
8//! AWS Shared Config
9//!
10//! This module contains a shared configuration representation that is agnostic from a specific service.
11
12use crate::app_name::AppName;
13use crate::docs_for;
14use crate::endpoint_config::AccountIdEndpointMode;
15use crate::origin::Origin;
16use crate::region::{Region, SigningRegionSet};
17use crate::sdk_ua_metadata::FrameworkMetadata;
18use crate::service_config::LoadServiceConfig;
19use aws_credential_types::provider::token::SharedTokenProvider;
20pub use aws_credential_types::provider::SharedCredentialsProvider;
21use aws_smithy_async::rt::sleep::AsyncSleep;
22pub use aws_smithy_async::rt::sleep::SharedAsyncSleep;
23pub use aws_smithy_async::time::{SharedTimeSource, TimeSource};
24use aws_smithy_runtime_api::client::auth::AuthSchemePreference;
25use aws_smithy_runtime_api::client::behavior_version::BehaviorVersion;
26use aws_smithy_runtime_api::client::http::HttpClient;
27pub use aws_smithy_runtime_api::client::http::SharedHttpClient;
28use aws_smithy_runtime_api::client::identity::{ResolveCachedIdentity, SharedIdentityCache};
29pub use aws_smithy_runtime_api::client::stalled_stream_protection::StalledStreamProtectionConfig;
30use aws_smithy_runtime_api::shared::IntoShared;
31use aws_smithy_schema::protocol::SharedClientProtocol;
32pub use aws_smithy_types::checksum_config::{
33    RequestChecksumCalculation, ResponseChecksumValidation,
34};
35pub use aws_smithy_types::retry::RetryConfig;
36pub use aws_smithy_types::timeout::TimeoutConfig;
37use std::collections::HashMap;
38use std::sync::Arc;
39
40/// Unified docstrings to keep crates in sync. Not intended for public use
41pub mod unified_docs {
42    /// A macro that generates docs for selected fields of `SdkConfig`.
43    #[macro_export]
44    macro_rules! docs_for {
45        (use_fips) => {
46"When true, send this request to the FIPS-compliant regional endpoint.
47
48If no FIPS-compliant endpoint can be determined, dispatching the request will return an error."
49        };
50        (use_dual_stack) => {
51"When true, send this request to the dual-stack endpoint.
52
53If no dual-stack endpoint is available the request MAY return an error.
54
55**Note**: Some services do not offer dual-stack as a configurable parameter (e.g. Code Catalyst). For
56these services, this setting has no effect"
57        };
58        (time_source) => {
59"The time source use to use for this client.
60
61This only needs to be required for creating deterministic tests or platforms where `SystemTime::now()` is not supported."};
62        (disable_request_compression) => {
63"When `true`, disable request compression. Defaults to `false`.
64
65**Only some services support request compression.** For services
66that don't support request compression, this setting does nothing.
67" };
68        (disable_clock_skew_correction) => {
69"When `true`, disable clock skew correction. Defaults to `false`.
70
71Clock skew correction adjusts the request signing timestamp to compensate for drift between
72the client and service clocks. When disabled, the SDK signs with the local clock and does not
73retry clock-skew errors.
74" };
75        (request_min_compression_size_bytes) => {
76"The minimum size of request that should be compressed. Defaults to `10240` bytes.
77
78When a request body's size is lower than this, request compression will be skipped.
79This is useful for request bodies because, for small request bodies, compression may actually increase their size.
80
81**Only some services support request compression.** For services
82that don't support request compression, this setting does nothing.
83" };
84        (account_id_endpoint_mode) => {
85"Controls the account ID-based routing behavior.
86
87By default, the routing behavior is set to `preferred`.
88Customers can adjust this setting to other values to switch between different routing patterns or temporarily disable the feature.
89
90See the developer guide on [account-based endpoints](https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html)
91for more information.
92
93For services that do not use the account-based endpoints, this setting does nothing.
94" };
95        (auth_scheme_preference) => {
96"Set the auth scheme preference for an auth scheme resolver
97(typically the default auth scheme resolver).
98
99Each operation has a predefined order of auth schemes, as determined by the service,
100for auth scheme resolution. By using the auth scheme preference, customers
101can reorder the schemes resolved by the auth scheme resolver.
102
103The preference list is intended as a hint rather than a strict override.
104Any schemes not present in the originally resolved auth schemes will be ignored.
105" };
106        (sigv4a_signing_region_set) => {
107"Set the signing region set for SigV4a authentication.
108
109When using SigV4a (asymmetric) signing, this specifies which regions the request
110signature is valid for. Use `*` for a universal signature valid in all regions.
111" };
112    }
113}
114
115/// AWS Shared Configuration
116#[derive(Debug, Clone)]
117pub struct SdkConfig {
118    app_name: Option<AppName>,
119    framework_metadata: Vec<FrameworkMetadata>,
120    auth_scheme_preference: Option<AuthSchemePreference>,
121    sigv4a_signing_region_set: Option<SigningRegionSet>,
122    identity_cache: Option<SharedIdentityCache>,
123    credentials_provider: Option<SharedCredentialsProvider>,
124    token_provider: Option<SharedTokenProvider>,
125    region: Option<Region>,
126    account_id_endpoint_mode: Option<AccountIdEndpointMode>,
127    endpoint_url: Option<String>,
128    retry_config: Option<RetryConfig>,
129    sleep_impl: Option<SharedAsyncSleep>,
130    time_source: Option<SharedTimeSource>,
131    timeout_config: Option<TimeoutConfig>,
132    stalled_stream_protection_config: Option<StalledStreamProtectionConfig>,
133    http_client: Option<SharedHttpClient>,
134    use_fips: Option<bool>,
135    use_dual_stack: Option<bool>,
136    behavior_version: Option<BehaviorVersion>,
137    service_config: Option<Arc<dyn LoadServiceConfig>>,
138    config_origins: HashMap<&'static str, Origin>,
139    disable_request_compression: Option<bool>,
140    disable_clock_skew_correction: Option<bool>,
141    request_min_compression_size_bytes: Option<u32>,
142    request_checksum_calculation: Option<RequestChecksumCalculation>,
143    response_checksum_validation: Option<ResponseChecksumValidation>,
144    protocol: Option<SharedClientProtocol>,
145}
146
147/// Builder for AWS Shared Configuration
148///
149/// _Important:_ Using the `aws-config` crate to configure the SDK is preferred to invoking this
150/// builder directly. Using this builder directly won't pull in any AWS recommended default
151/// configuration values.
152#[derive(Debug, Default)]
153pub struct Builder {
154    app_name: Option<AppName>,
155    framework_metadata: Vec<FrameworkMetadata>,
156    auth_scheme_preference: Option<AuthSchemePreference>,
157    sigv4a_signing_region_set: Option<SigningRegionSet>,
158    identity_cache: Option<SharedIdentityCache>,
159    credentials_provider: Option<SharedCredentialsProvider>,
160    token_provider: Option<SharedTokenProvider>,
161    region: Option<Region>,
162    account_id_endpoint_mode: Option<AccountIdEndpointMode>,
163    endpoint_url: Option<String>,
164    retry_config: Option<RetryConfig>,
165    sleep_impl: Option<SharedAsyncSleep>,
166    time_source: Option<SharedTimeSource>,
167    timeout_config: Option<TimeoutConfig>,
168    stalled_stream_protection_config: Option<StalledStreamProtectionConfig>,
169    http_client: Option<SharedHttpClient>,
170    use_fips: Option<bool>,
171    use_dual_stack: Option<bool>,
172    behavior_version: Option<BehaviorVersion>,
173    service_config: Option<Arc<dyn LoadServiceConfig>>,
174    config_origins: HashMap<&'static str, Origin>,
175    disable_request_compression: Option<bool>,
176    disable_clock_skew_correction: Option<bool>,
177    request_min_compression_size_bytes: Option<u32>,
178    request_checksum_calculation: Option<RequestChecksumCalculation>,
179    response_checksum_validation: Option<ResponseChecksumValidation>,
180    protocol: Option<SharedClientProtocol>,
181}
182
183impl Builder {
184    /// Set the region for the builder
185    ///
186    /// # Examples
187    /// ```rust
188    /// use aws_types::SdkConfig;
189    /// use aws_types::region::Region;
190    /// let config = SdkConfig::builder().region(Region::new("us-east-1")).build();
191    /// ```
192    pub fn region(mut self, region: impl Into<Option<Region>>) -> Self {
193        self.set_region(region);
194        self
195    }
196
197    /// Set the region for the builder
198    ///
199    /// # Examples
200    /// ```rust
201    /// fn region_override() -> Option<Region> {
202    ///     // ...
203    ///     # None
204    /// }
205    /// use aws_types::SdkConfig;
206    /// use aws_types::region::Region;
207    /// let mut builder = SdkConfig::builder();
208    /// if let Some(region) = region_override() {
209    ///     builder.set_region(region);
210    /// }
211    /// let config = builder.build();
212    /// ```
213    pub fn set_region(&mut self, region: impl Into<Option<Region>>) -> &mut Self {
214        self.region = region.into();
215        self
216    }
217
218    #[doc = docs_for!(account_id_endpoint_mode)]
219    pub fn account_id_endpoint_mode(
220        mut self,
221        account_id_endpoint_mode: AccountIdEndpointMode,
222    ) -> Self {
223        self.set_account_id_endpoint_mode(Some(account_id_endpoint_mode));
224        self
225    }
226
227    #[doc = docs_for!(account_id_endpoint_mode)]
228    pub fn set_account_id_endpoint_mode(
229        &mut self,
230        account_id_endpoint_mode: Option<AccountIdEndpointMode>,
231    ) -> &mut Self {
232        self.account_id_endpoint_mode = account_id_endpoint_mode;
233        self
234    }
235
236    /// Set the endpoint URL to use when making requests.
237    /// # Examples
238    /// ```
239    /// use aws_types::SdkConfig;
240    /// let config = SdkConfig::builder().endpoint_url("http://localhost:8080").build();
241    /// ```
242    pub fn endpoint_url(mut self, endpoint_url: impl Into<String>) -> Self {
243        self.set_endpoint_url(Some(endpoint_url.into()));
244        self
245    }
246
247    /// Set the endpoint URL to use when making requests.
248    pub fn set_endpoint_url(&mut self, endpoint_url: Option<String>) -> &mut Self {
249        self.endpoint_url = endpoint_url;
250        self
251    }
252
253    /// Set the checksum calculation strategy to use when making requests.
254    /// # Examples
255    /// ```
256    /// use aws_types::SdkConfig;
257    /// use aws_smithy_types::checksum_config::RequestChecksumCalculation;
258    /// let config = SdkConfig::builder().request_checksum_calculation(RequestChecksumCalculation::WhenSupported).build();
259    /// ```
260    pub fn request_checksum_calculation(
261        mut self,
262        request_checksum_calculation: RequestChecksumCalculation,
263    ) -> Self {
264        self.set_request_checksum_calculation(Some(request_checksum_calculation));
265        self
266    }
267
268    /// Set the checksum calculation strategy to use when making requests.
269    pub fn set_request_checksum_calculation(
270        &mut self,
271        request_checksum_calculation: Option<RequestChecksumCalculation>,
272    ) -> &mut Self {
273        self.request_checksum_calculation = request_checksum_calculation;
274        self
275    }
276
277    /// Set the checksum calculation strategy to use for responses.
278    /// # Examples
279    /// ```
280    /// use aws_types::SdkConfig;
281    /// use aws_smithy_types::checksum_config::ResponseChecksumValidation;
282    /// let config = SdkConfig::builder().response_checksum_validation(ResponseChecksumValidation::WhenSupported).build();
283    /// ```
284    pub fn response_checksum_validation(
285        mut self,
286        response_checksum_validation: ResponseChecksumValidation,
287    ) -> Self {
288        self.set_response_checksum_validation(Some(response_checksum_validation));
289        self
290    }
291
292    /// Set the checksum calculation strategy to use for responses.
293    pub fn set_response_checksum_validation(
294        &mut self,
295        response_checksum_validation: Option<ResponseChecksumValidation>,
296    ) -> &mut Self {
297        self.response_checksum_validation = response_checksum_validation;
298        self
299    }
300
301    /// Set the retry_config for the builder
302    ///
303    /// _Note:_ Retries require a sleep implementation in order to work. When enabling retry, make
304    /// sure to set one with [Self::sleep_impl] or [Self::set_sleep_impl].
305    ///
306    /// # Examples
307    /// ```rust
308    /// use aws_types::SdkConfig;
309    /// use aws_smithy_types::retry::RetryConfig;
310    ///
311    /// let retry_config = RetryConfig::standard().with_max_attempts(5);
312    /// let config = SdkConfig::builder().retry_config(retry_config).build();
313    /// ```
314    pub fn retry_config(mut self, retry_config: RetryConfig) -> Self {
315        self.set_retry_config(Some(retry_config));
316        self
317    }
318
319    /// Set the retry_config for the builder
320    ///
321    /// _Note:_ Retries require a sleep implementation in order to work. When enabling retry, make
322    /// sure to set one with [Self::sleep_impl] or [Self::set_sleep_impl].
323    ///
324    /// # Examples
325    /// ```rust
326    /// use aws_types::sdk_config::{SdkConfig, Builder};
327    /// use aws_smithy_types::retry::RetryConfig;
328    ///
329    /// fn disable_retries(builder: &mut Builder) {
330    ///     let retry_config = RetryConfig::standard().with_max_attempts(1);
331    ///     builder.set_retry_config(Some(retry_config));
332    /// }
333    ///
334    /// let mut builder = SdkConfig::builder();
335    /// disable_retries(&mut builder);
336    /// ```
337    pub fn set_retry_config(&mut self, retry_config: Option<RetryConfig>) -> &mut Self {
338        self.retry_config = retry_config;
339        self
340    }
341
342    /// Set the [`TimeoutConfig`] for the builder
343    ///
344    /// _Note:_ Timeouts require a sleep implementation in order to work.
345    /// When enabling timeouts, be sure to set one with [Self::sleep_impl] or
346    /// [Self::set_sleep_impl].
347    ///
348    /// # Examples
349    ///
350    /// ```rust
351    /// # use std::time::Duration;
352    /// use aws_types::SdkConfig;
353    /// use aws_smithy_types::timeout::TimeoutConfig;
354    ///
355    /// let timeout_config = TimeoutConfig::builder()
356    ///     .operation_attempt_timeout(Duration::from_secs(2))
357    ///     .operation_timeout(Duration::from_secs(5))
358    ///     .build();
359    /// let config = SdkConfig::builder()
360    ///     .timeout_config(timeout_config)
361    ///     .build();
362    /// ```
363    pub fn timeout_config(mut self, timeout_config: TimeoutConfig) -> Self {
364        self.set_timeout_config(Some(timeout_config));
365        self
366    }
367
368    /// Set the [`TimeoutConfig`] for the builder
369    ///
370    /// _Note:_ Timeouts require a sleep implementation in order to work.
371    /// When enabling timeouts, be sure to set one with [Self::sleep_impl] or
372    /// [Self::set_sleep_impl].
373    ///
374    /// # Examples
375    /// ```rust
376    /// # use std::time::Duration;
377    /// use aws_types::sdk_config::{SdkConfig, Builder};
378    /// use aws_smithy_types::timeout::TimeoutConfig;
379    ///
380    /// fn set_preferred_timeouts(builder: &mut Builder) {
381    ///     let timeout_config = TimeoutConfig::builder()
382    ///         .operation_attempt_timeout(Duration::from_secs(2))
383    ///         .operation_timeout(Duration::from_secs(5))
384    ///         .build();
385    ///     builder.set_timeout_config(Some(timeout_config));
386    /// }
387    ///
388    /// let mut builder = SdkConfig::builder();
389    /// set_preferred_timeouts(&mut builder);
390    /// let config = builder.build();
391    /// ```
392    pub fn set_timeout_config(&mut self, timeout_config: Option<TimeoutConfig>) -> &mut Self {
393        self.timeout_config = timeout_config;
394        self
395    }
396
397    /// Set the sleep implementation for the builder.
398    ///
399    /// The sleep implementation is used to create timeout futures.
400    ///
401    /// _Note:_ If you're using the Tokio runtime, a `TokioSleep` implementation is available in
402    /// the `aws-smithy-async` crate.
403    ///
404    /// # Examples
405    ///
406    /// ```rust
407    /// use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep, Sleep};
408    /// use aws_types::SdkConfig;
409    ///
410    /// ##[derive(Debug)]
411    /// pub struct ForeverSleep;
412    ///
413    /// impl AsyncSleep for ForeverSleep {
414    ///     fn sleep(&self, duration: std::time::Duration) -> Sleep {
415    ///         Sleep::new(std::future::pending())
416    ///     }
417    /// }
418    ///
419    /// let sleep_impl = SharedAsyncSleep::new(ForeverSleep);
420    /// let config = SdkConfig::builder().sleep_impl(sleep_impl).build();
421    /// ```
422    pub fn sleep_impl(mut self, sleep_impl: impl AsyncSleep + 'static) -> Self {
423        self.set_sleep_impl(Some(sleep_impl.into_shared()));
424        self
425    }
426
427    /// Set the sleep implementation for the builder. The sleep implementation is used to create
428    /// timeout futures.
429    ///
430    /// _Note:_ If you're using the Tokio runtime, a `TokioSleep` implementation is available in
431    /// the `aws-smithy-async` crate.
432    ///
433    /// # Examples
434    /// ```rust
435    /// # use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep, Sleep};
436    /// # use aws_types::sdk_config::{Builder, SdkConfig};
437    /// #[derive(Debug)]
438    /// pub struct ForeverSleep;
439    ///
440    /// impl AsyncSleep for ForeverSleep {
441    ///     fn sleep(&self, duration: std::time::Duration) -> Sleep {
442    ///         Sleep::new(std::future::pending())
443    ///     }
444    /// }
445    ///
446    /// fn set_never_ending_sleep_impl(builder: &mut Builder) {
447    ///     let sleep_impl = SharedAsyncSleep::new(ForeverSleep);
448    ///     builder.set_sleep_impl(Some(sleep_impl));
449    /// }
450    ///
451    /// let mut builder = SdkConfig::builder();
452    /// set_never_ending_sleep_impl(&mut builder);
453    /// let config = builder.build();
454    /// ```
455    pub fn set_sleep_impl(&mut self, sleep_impl: Option<SharedAsyncSleep>) -> &mut Self {
456        self.sleep_impl = sleep_impl;
457        self
458    }
459
460    /// Set the identity cache for caching credentials and SSO tokens.
461    ///
462    /// The default identity cache will wait until the first request that requires authentication
463    /// to load an identity. Once the identity is loaded, it is cached until shortly before it
464    /// expires.
465    ///
466    /// # Examples
467    /// Disabling identity caching:
468    /// ```rust
469    /// # use aws_types::SdkConfig;
470    /// use aws_smithy_runtime::client::identity::IdentityCache;
471    /// let config = SdkConfig::builder()
472    ///     .identity_cache(IdentityCache::no_cache())
473    ///     .build();
474    /// ```
475    /// Changing settings on the default cache implementation:
476    /// ```rust
477    /// # use aws_types::SdkConfig;
478    /// use aws_smithy_runtime::client::identity::IdentityCache;
479    /// use std::time::Duration;
480    ///
481    /// let config = SdkConfig::builder()
482    ///     .identity_cache(
483    ///         IdentityCache::lazy()
484    ///             .load_timeout(Duration::from_secs(10))
485    ///             .build()
486    ///     )
487    ///     .build();
488    /// ```
489    pub fn identity_cache(mut self, cache: impl ResolveCachedIdentity + 'static) -> Self {
490        self.set_identity_cache(Some(cache.into_shared()));
491        self
492    }
493
494    /// Set the identity cache for caching credentials and SSO tokens.
495    ///
496    /// The default identity cache will wait until the first request that requires authentication
497    /// to load an identity. Once the identity is loaded, it is cached until shortly before it
498    /// expires.
499    ///
500    /// # Examples
501    /// ```rust
502    /// # use aws_types::SdkConfig;
503    /// use aws_smithy_runtime::client::identity::IdentityCache;
504    ///
505    /// fn override_identity_cache() -> bool {
506    ///   // ...
507    ///   # true
508    /// }
509    ///
510    /// let mut builder = SdkConfig::builder();
511    /// if override_identity_cache() {
512    ///     builder.set_identity_cache(Some(IdentityCache::lazy().build()));
513    /// }
514    /// let config = builder.build();
515    /// ```
516    pub fn set_identity_cache(&mut self, cache: Option<SharedIdentityCache>) -> &mut Self {
517        self.identity_cache = cache;
518        self
519    }
520
521    /// Set the credentials provider for the builder
522    ///
523    /// # Examples
524    /// ```rust
525    /// use aws_credential_types::provider::{ProvideCredentials, SharedCredentialsProvider};
526    /// use aws_types::SdkConfig;
527    /// fn make_provider() -> impl ProvideCredentials {
528    ///   // ...
529    ///   # use aws_credential_types::Credentials;
530    ///   # Credentials::new("test", "test", None, None, "example")
531    /// }
532    ///
533    /// let config = SdkConfig::builder()
534    ///     .credentials_provider(SharedCredentialsProvider::new(make_provider()))
535    ///     .build();
536    /// ```
537    pub fn credentials_provider(mut self, provider: SharedCredentialsProvider) -> Self {
538        self.set_credentials_provider(Some(provider));
539        self
540    }
541
542    /// Set the credentials provider for the builder
543    ///
544    /// # Examples
545    /// ```rust
546    /// use aws_credential_types::provider::{ProvideCredentials, SharedCredentialsProvider};
547    /// use aws_types::SdkConfig;
548    /// fn make_provider() -> impl ProvideCredentials {
549    ///   // ...
550    ///   # use aws_credential_types::Credentials;
551    ///   # Credentials::new("test", "test", None, None, "example")
552    /// }
553    ///
554    /// fn override_provider() -> bool {
555    ///   // ...
556    ///   # true
557    /// }
558    ///
559    /// let mut builder = SdkConfig::builder();
560    /// if override_provider() {
561    ///     builder.set_credentials_provider(Some(SharedCredentialsProvider::new(make_provider())));
562    /// }
563    /// let config = builder.build();
564    /// ```
565    pub fn set_credentials_provider(
566        &mut self,
567        provider: Option<SharedCredentialsProvider>,
568    ) -> &mut Self {
569        self.credentials_provider = provider;
570        self
571    }
572
573    /// Set the bearer auth token provider for the builder
574    ///
575    /// # Examples
576    /// ```rust
577    /// use aws_credential_types::provider::token::{ProvideToken, SharedTokenProvider};
578    /// use aws_types::SdkConfig;
579    ///
580    /// fn make_provider() -> impl ProvideToken {
581    ///   // ...
582    ///   # aws_credential_types::Token::new("example", None)
583    /// }
584    ///
585    /// let config = SdkConfig::builder()
586    ///     .token_provider(SharedTokenProvider::new(make_provider()))
587    ///     .build();
588    /// ```
589    pub fn token_provider(mut self, provider: SharedTokenProvider) -> Self {
590        self.set_token_provider(Some(provider));
591        self
592    }
593
594    /// Set the bearer auth token provider for the builder
595    ///
596    /// # Examples
597    /// ```rust
598    /// use aws_credential_types::provider::token::{ProvideToken, SharedTokenProvider};
599    /// use aws_types::SdkConfig;
600    ///
601    /// fn make_provider() -> impl ProvideToken {
602    ///   // ...
603    ///   # aws_credential_types::Token::new("example", None)
604    /// }
605    ///
606    /// fn override_provider() -> bool {
607    ///   // ...
608    ///   # true
609    /// }
610    ///
611    /// let mut builder = SdkConfig::builder();
612    /// if override_provider() {
613    ///     builder.set_token_provider(Some(SharedTokenProvider::new(make_provider())));
614    /// }
615    /// let config = builder.build();
616    /// ```
617    pub fn set_token_provider(&mut self, provider: Option<SharedTokenProvider>) -> &mut Self {
618        self.token_provider = provider;
619        self
620    }
621
622    /// Sets the name of the app that is using the client.
623    ///
624    /// This _optional_ name is used to identify the application in the user agent that
625    /// gets sent along with requests.
626    pub fn app_name(mut self, app_name: AppName) -> Self {
627        self.set_app_name(Some(app_name));
628        self
629    }
630
631    /// Sets the name of the app that is using the client.
632    ///
633    /// This _optional_ name is used to identify the application in the user agent that
634    /// gets sent along with requests.
635    pub fn set_app_name(&mut self, app_name: Option<AppName>) -> &mut Self {
636        self.app_name = app_name;
637        self
638    }
639
640    /// Appends framework metadata to the user agent.
641    ///
642    /// This _optional_ metadata identifies a software framework or third-party library that is
643    /// being used with the SDK. It is rendered into the user agent (as `lib/{name}/{version}`) so
644    /// that libraries built on top of the AWS SDK can self-identify in the requests they make.
645    /// Each call appends another entry rather than replacing previous ones.
646    ///
647    /// Entries are de-duplicated on `(name, version)`, rendered in first-seen order, and the total
648    /// number of unique entries included in the user agent is capped (currently at 10); additional
649    /// entries beyond the cap are dropped with a warning.
650    pub fn framework_metadata(mut self, framework_metadata: FrameworkMetadata) -> Self {
651        self.framework_metadata.push(framework_metadata);
652        self
653    }
654
655    /// Sets the framework metadata for the user agent, replacing any previously set entries.
656    ///
657    /// See [`Builder::framework_metadata`] for details on framework metadata.
658    pub fn set_framework_metadata(
659        &mut self,
660        framework_metadata: impl IntoIterator<Item = FrameworkMetadata>,
661    ) -> &mut Self {
662        self.framework_metadata = framework_metadata.into_iter().collect();
663        self
664    }
665
666    /// Sets the HTTP client to use when making requests.
667    ///
668    /// ## Examples
669    /// ```no_run
670    /// # #[cfg(feature = "examples")]
671    /// # fn example() {
672    /// use aws_types::sdk_config::{SdkConfig, TimeoutConfig};
673    /// use aws_smithy_runtime::client::http::hyper_014::HyperClientBuilder;
674    /// use std::time::Duration;
675    ///
676    /// // Create a connector that will be used to establish TLS connections
677    /// let tls_connector = hyper_rustls::HttpsConnectorBuilder::new()
678    ///     .with_webpki_roots()
679    ///     .https_only()
680    ///     .enable_http1()
681    ///     .enable_http2()
682    ///     .build();
683    /// // Create a HTTP client that uses the TLS connector. This client is
684    /// // responsible for creating and caching a HttpConnector when given HttpConnectorSettings.
685    /// // This hyper client will create HttpConnectors backed by hyper and the tls_connector.
686    /// let http_client = HyperClientBuilder::new().build(tls_connector);
687    /// let sdk_config = SdkConfig::builder()
688    ///     .http_client(http_client)
689    ///     // Connect/read timeouts are passed to the HTTP client when servicing a request
690    ///     .timeout_config(
691    ///         TimeoutConfig::builder()
692    ///             .connect_timeout(Duration::from_secs(5))
693    ///             .build()
694    ///     )
695    ///     .build();
696    /// # }
697    /// ```
698    pub fn http_client(mut self, http_client: impl HttpClient + 'static) -> Self {
699        self.set_http_client(Some(http_client.into_shared()));
700        self
701    }
702
703    /// Sets the HTTP client to use when making requests.
704    ///
705    /// ## Examples
706    /// ```no_run
707    /// # #[cfg(feature = "examples")]
708    /// # fn example() {
709    /// use aws_types::sdk_config::{Builder, SdkConfig, TimeoutConfig};
710    /// use aws_smithy_runtime::client::http::hyper_014::HyperClientBuilder;
711    /// use std::time::Duration;
712    ///
713    /// fn override_http_client(builder: &mut Builder) {
714    ///     // Create a connector that will be used to establish TLS connections
715    ///     let tls_connector = hyper_rustls::HttpsConnectorBuilder::new()
716    ///         .with_webpki_roots()
717    ///         .https_only()
718    ///         .enable_http1()
719    ///         .enable_http2()
720    ///         .build();
721    ///     // Create a HTTP client that uses the TLS connector. This client is
722    ///     // responsible for creating and caching a HttpConnector when given HttpConnectorSettings.
723    ///     // This hyper client will create HttpConnectors backed by hyper and the tls_connector.
724    ///     let http_client = HyperClientBuilder::new().build(tls_connector);
725    ///
726    ///     builder.set_http_client(Some(http_client));
727    /// }
728    ///
729    /// let mut builder = SdkConfig::builder();
730    /// override_http_client(&mut builder);
731    /// let config = builder.build();
732    /// # }
733    /// ```
734    pub fn set_http_client(&mut self, http_client: Option<SharedHttpClient>) -> &mut Self {
735        self.http_client = http_client;
736        self
737    }
738
739    /// Sets the client protocol to use for serialization and deserialization.
740    ///
741    /// This overrides the default protocol determined by the service model,
742    /// enabling runtime protocol selection.
743    ///
744    /// # Transport
745    ///
746    /// This setter is HTTP-specific. The whole pipeline — the `self.protocol`
747    /// field (typed `Option<SharedClientProtocol>`, which elides to the HTTP
748    /// specialization via [`SharedClientProtocol`]'s
749    /// default type parameters) and its `Storable` impl (keyed only to
750    /// `SharedClientProtocol<http::Request, http::Response>`) — commits to
751    /// HTTP. The `impl ClientProtocol + 'static` bound you see here is
752    /// consistent with that: it elides to
753    /// `impl ClientProtocol<http::Request, http::Response>`.
754    ///
755    /// `ClientProtocolInner` / `ClientProtocol<Req, Res>` /
756    /// `SharedClientProtocol<Req, Res>` are themselves transport-generic — a
757    /// user can write `impl ClientProtocol<MqttMessage, MqttMessage>` — but
758    /// such an impl cannot be passed here because it won't round-trip through
759    /// the HTTP-typed config-bag storage. A future non-HTTP transport would
760    /// ship its own dedicated setter (e.g., `mqtt_protocol(…)`) paired with
761    /// its own `Storable` newtype rather than generalizing this one.
762    pub fn protocol(
763        mut self,
764        protocol: impl aws_smithy_schema::protocol::ClientProtocol + 'static,
765    ) -> Self {
766        self.set_protocol(Some(SharedClientProtocol::new(protocol)));
767        self
768    }
769
770    /// Sets the client protocol to use for serialization and deserialization.
771    pub fn set_protocol(&mut self, protocol: Option<SharedClientProtocol>) -> &mut Self {
772        self.protocol = protocol;
773        self
774    }
775
776    #[doc = docs_for!(use_fips)]
777    pub fn use_fips(mut self, use_fips: bool) -> Self {
778        self.set_use_fips(Some(use_fips));
779        self
780    }
781
782    #[doc = docs_for!(use_fips)]
783    pub fn set_use_fips(&mut self, use_fips: Option<bool>) -> &mut Self {
784        self.use_fips = use_fips;
785        self
786    }
787
788    #[doc = docs_for!(use_dual_stack)]
789    pub fn use_dual_stack(mut self, use_dual_stack: bool) -> Self {
790        self.set_use_dual_stack(Some(use_dual_stack));
791        self
792    }
793
794    #[doc = docs_for!(use_dual_stack)]
795    pub fn set_use_dual_stack(&mut self, use_dual_stack: Option<bool>) -> &mut Self {
796        self.use_dual_stack = use_dual_stack;
797        self
798    }
799
800    #[doc = docs_for!(time_source)]
801    pub fn time_source(mut self, time_source: impl TimeSource + 'static) -> Self {
802        self.set_time_source(Some(SharedTimeSource::new(time_source)));
803        self
804    }
805
806    #[doc = docs_for!(time_source)]
807    pub fn set_time_source(&mut self, time_source: Option<SharedTimeSource>) -> &mut Self {
808        self.time_source = time_source;
809        self
810    }
811
812    #[doc = docs_for!(disable_request_compression)]
813    pub fn disable_request_compression(mut self, disable_request_compression: bool) -> Self {
814        self.set_disable_request_compression(Some(disable_request_compression));
815        self
816    }
817
818    #[doc = docs_for!(disable_request_compression)]
819    pub fn set_disable_request_compression(
820        &mut self,
821        disable_request_compression: Option<bool>,
822    ) -> &mut Self {
823        self.disable_request_compression = disable_request_compression;
824        self
825    }
826
827    #[doc = docs_for!(disable_clock_skew_correction)]
828    pub fn disable_clock_skew_correction(mut self, disable_clock_skew_correction: bool) -> Self {
829        self.set_disable_clock_skew_correction(Some(disable_clock_skew_correction));
830        self
831    }
832
833    #[doc = docs_for!(disable_clock_skew_correction)]
834    pub fn set_disable_clock_skew_correction(
835        &mut self,
836        disable_clock_skew_correction: Option<bool>,
837    ) -> &mut Self {
838        self.disable_clock_skew_correction = disable_clock_skew_correction;
839        self
840    }
841
842    #[doc = docs_for!(request_min_compression_size_bytes)]
843    pub fn request_min_compression_size_bytes(
844        mut self,
845        request_min_compression_size_bytes: u32,
846    ) -> Self {
847        self.set_request_min_compression_size_bytes(Some(request_min_compression_size_bytes));
848        self
849    }
850
851    #[doc = docs_for!(request_min_compression_size_bytes)]
852    pub fn set_request_min_compression_size_bytes(
853        &mut self,
854        request_min_compression_size_bytes: Option<u32>,
855    ) -> &mut Self {
856        self.request_min_compression_size_bytes = request_min_compression_size_bytes;
857        self
858    }
859
860    /// Sets the [`BehaviorVersion`] for the [`SdkConfig`]
861    pub fn behavior_version(mut self, behavior_version: BehaviorVersion) -> Self {
862        self.set_behavior_version(Some(behavior_version));
863        self
864    }
865
866    /// Sets the [`BehaviorVersion`] for the [`SdkConfig`]
867    pub fn set_behavior_version(&mut self, behavior_version: Option<BehaviorVersion>) -> &mut Self {
868        self.behavior_version = behavior_version;
869        self
870    }
871
872    /// Sets the service config provider for the [`SdkConfig`].
873    ///
874    /// This provider is used when creating a service-specific config from an
875    /// `SdkConfig` and provides access to config defined in the environment
876    /// which would otherwise be inaccessible.
877    pub fn service_config(mut self, service_config: impl LoadServiceConfig + 'static) -> Self {
878        self.set_service_config(Some(service_config));
879        self
880    }
881
882    /// Sets the service config provider for the [`SdkConfig`].
883    ///
884    /// This provider is used when creating a service-specific config from an
885    /// `SdkConfig` and provides access to config defined in the environment
886    /// which would otherwise be inaccessible.
887    pub fn set_service_config(
888        &mut self,
889        service_config: Option<impl LoadServiceConfig + 'static>,
890    ) -> &mut Self {
891        self.service_config = service_config.map(|it| Arc::new(it) as Arc<dyn LoadServiceConfig>);
892        self
893    }
894
895    #[doc = docs_for!(auth_scheme_preference)]
896    pub fn auth_scheme_preference(
897        mut self,
898        auth_scheme_preference: impl Into<AuthSchemePreference>,
899    ) -> Self {
900        self.set_auth_scheme_preference(Some(auth_scheme_preference));
901        self
902    }
903
904    #[doc = docs_for!(auth_scheme_preference)]
905    pub fn set_auth_scheme_preference(
906        &mut self,
907        auth_scheme_preference: Option<impl Into<AuthSchemePreference>>,
908    ) -> &mut Self {
909        self.auth_scheme_preference = auth_scheme_preference.map(|pref| pref.into());
910        self
911    }
912
913    #[doc = docs_for!(sigv4a_signing_region_set)]
914    pub fn sigv4a_signing_region_set(
915        mut self,
916        sigv4a_signing_region_set: impl Into<SigningRegionSet>,
917    ) -> Self {
918        self.set_sigv4a_signing_region_set(Some(sigv4a_signing_region_set));
919        self
920    }
921
922    #[doc = docs_for!(sigv4a_signing_region_set)]
923    pub fn set_sigv4a_signing_region_set(
924        &mut self,
925        sigv4a_signing_region_set: Option<impl Into<SigningRegionSet>>,
926    ) -> &mut Self {
927        self.sigv4a_signing_region_set = sigv4a_signing_region_set.map(|v| v.into());
928        self
929    }
930
931    /// Set the origin of a setting.
932    ///
933    /// This is used internally to understand how to merge config structs while
934    /// respecting precedence of origins.
935    pub fn insert_origin(&mut self, setting: &'static str, origin: Origin) {
936        self.config_origins.insert(setting, origin);
937    }
938
939    /// Build a [`SdkConfig`] from this builder.
940    pub fn build(self) -> SdkConfig {
941        SdkConfig {
942            app_name: self.app_name,
943            framework_metadata: self.framework_metadata,
944            auth_scheme_preference: self.auth_scheme_preference,
945            sigv4a_signing_region_set: self.sigv4a_signing_region_set,
946            identity_cache: self.identity_cache,
947            credentials_provider: self.credentials_provider,
948            token_provider: self.token_provider,
949            region: self.region,
950            account_id_endpoint_mode: self.account_id_endpoint_mode,
951            endpoint_url: self.endpoint_url,
952            retry_config: self.retry_config,
953            sleep_impl: self.sleep_impl,
954            timeout_config: self.timeout_config,
955            http_client: self.http_client,
956            use_fips: self.use_fips,
957            use_dual_stack: self.use_dual_stack,
958            time_source: self.time_source,
959            behavior_version: self.behavior_version,
960            stalled_stream_protection_config: self.stalled_stream_protection_config,
961            service_config: self.service_config,
962            config_origins: self.config_origins,
963            disable_request_compression: self.disable_request_compression,
964            disable_clock_skew_correction: self.disable_clock_skew_correction,
965            request_min_compression_size_bytes: self.request_min_compression_size_bytes,
966            request_checksum_calculation: self.request_checksum_calculation,
967            response_checksum_validation: self.response_checksum_validation,
968            protocol: self.protocol,
969        }
970    }
971}
972
973impl Builder {
974    /// Set the [`StalledStreamProtectionConfig`] to configure protection for stalled streams.
975    ///
976    /// This configures stalled stream protection. When enabled, download streams
977    /// that stall (stream no data) for longer than a configured grace period will return an error.
978    ///
979    /// _Note:_ Stalled stream protection requires both a sleep implementation and a time source
980    /// in order to work. When enabling stalled stream protection, make sure to set
981    /// - A sleep impl with [Self::sleep_impl] or [Self::set_sleep_impl].
982    /// - A time source with [Self::time_source] or [Self::set_time_source].
983    ///
984    /// # Examples
985    /// ```rust
986    /// use std::time::Duration;
987    /// use aws_types::SdkConfig;
988    /// pub use aws_smithy_runtime_api::client::stalled_stream_protection::StalledStreamProtectionConfig;
989    ///
990    /// let stalled_stream_protection_config = StalledStreamProtectionConfig::enabled()
991    ///     .grace_period(Duration::from_secs(1))
992    ///     .build();
993    /// let config = SdkConfig::builder()
994    ///     .stalled_stream_protection(stalled_stream_protection_config)
995    ///     .build();
996    /// ```
997    pub fn stalled_stream_protection(
998        mut self,
999        stalled_stream_protection_config: StalledStreamProtectionConfig,
1000    ) -> Self {
1001        self.set_stalled_stream_protection(Some(stalled_stream_protection_config));
1002        self
1003    }
1004
1005    /// Set the [`StalledStreamProtectionConfig`] to configure protection for stalled streams.
1006    ///
1007    /// This configures stalled stream protection. When enabled, download streams
1008    /// that stall (stream no data) for longer than a configured grace period will return an error.
1009    ///
1010    /// By default, streams that transmit less than one byte per-second for five seconds will
1011    /// be cancelled.
1012    ///
1013    /// _Note:_ Stalled stream protection requires both a sleep implementation and a time source
1014    /// in order to work. When enabling stalled stream protection, make sure to set
1015    /// - A sleep impl with [Self::sleep_impl] or [Self::set_sleep_impl].
1016    /// - A time source with [Self::time_source] or [Self::set_time_source].
1017    ///
1018    /// # Examples
1019    /// ```rust
1020    /// use std::time::Duration;
1021    /// use aws_types::sdk_config::{SdkConfig, Builder};
1022    /// pub use aws_smithy_runtime_api::client::stalled_stream_protection::StalledStreamProtectionConfig;
1023    ///
1024    /// fn set_stalled_stream_protection(builder: &mut Builder) {
1025    ///     let stalled_stream_protection_config = StalledStreamProtectionConfig::enabled()
1026    ///         .grace_period(Duration::from_secs(1))
1027    ///         .build();
1028    ///     builder.set_stalled_stream_protection(Some(stalled_stream_protection_config));
1029    /// }
1030    ///
1031    /// let mut builder = SdkConfig::builder();
1032    /// set_stalled_stream_protection(&mut builder);
1033    /// let config = builder.build();
1034    /// ```
1035    pub fn set_stalled_stream_protection(
1036        &mut self,
1037        stalled_stream_protection_config: Option<StalledStreamProtectionConfig>,
1038    ) -> &mut Self {
1039        self.stalled_stream_protection_config = stalled_stream_protection_config;
1040        self
1041    }
1042}
1043
1044impl SdkConfig {
1045    /// Configured region
1046    pub fn region(&self) -> Option<&Region> {
1047        self.region.as_ref()
1048    }
1049
1050    /// Configured account ID endpoint mode
1051    pub fn account_id_endpoint_mode(&self) -> Option<&AccountIdEndpointMode> {
1052        self.account_id_endpoint_mode.as_ref()
1053    }
1054
1055    /// Configured auth scheme preference
1056    pub fn auth_scheme_preference(&self) -> Option<&AuthSchemePreference> {
1057        self.auth_scheme_preference.as_ref()
1058    }
1059
1060    /// Configured SigV4a signing region set
1061    pub fn sigv4a_signing_region_set(&self) -> Option<&SigningRegionSet> {
1062        self.sigv4a_signing_region_set.as_ref()
1063    }
1064
1065    /// Configured endpoint URL
1066    pub fn endpoint_url(&self) -> Option<&str> {
1067        self.endpoint_url.as_deref()
1068    }
1069
1070    /// Configured retry config
1071    pub fn retry_config(&self) -> Option<&RetryConfig> {
1072        self.retry_config.as_ref()
1073    }
1074
1075    /// Configured timeout config
1076    pub fn timeout_config(&self) -> Option<&TimeoutConfig> {
1077        self.timeout_config.as_ref()
1078    }
1079
1080    /// Configured sleep implementation
1081    pub fn sleep_impl(&self) -> Option<SharedAsyncSleep> {
1082        self.sleep_impl.clone()
1083    }
1084
1085    /// Configured identity cache
1086    pub fn identity_cache(&self) -> Option<SharedIdentityCache> {
1087        self.identity_cache.clone()
1088    }
1089
1090    /// Configured credentials provider
1091    pub fn credentials_provider(&self) -> Option<SharedCredentialsProvider> {
1092        self.credentials_provider.clone()
1093    }
1094
1095    /// Configured bearer auth token provider
1096    pub fn token_provider(&self) -> Option<SharedTokenProvider> {
1097        self.token_provider.clone()
1098    }
1099
1100    /// Configured time source
1101    pub fn time_source(&self) -> Option<SharedTimeSource> {
1102        self.time_source.clone()
1103    }
1104
1105    /// Configured app name
1106    pub fn app_name(&self) -> Option<&AppName> {
1107        self.app_name.as_ref()
1108    }
1109
1110    /// Configured framework metadata
1111    pub fn framework_metadata(&self) -> &[FrameworkMetadata] {
1112        &self.framework_metadata
1113    }
1114
1115    /// Configured HTTP client
1116    pub fn http_client(&self) -> Option<SharedHttpClient> {
1117        self.http_client.clone()
1118    }
1119
1120    /// Configured client protocol for serialization and deserialization
1121    pub fn protocol(&self) -> Option<SharedClientProtocol> {
1122        self.protocol.clone()
1123    }
1124
1125    /// Use FIPS endpoints
1126    pub fn use_fips(&self) -> Option<bool> {
1127        self.use_fips
1128    }
1129
1130    /// Use dual-stack endpoint
1131    pub fn use_dual_stack(&self) -> Option<bool> {
1132        self.use_dual_stack
1133    }
1134
1135    /// When true, request compression is disabled.
1136    pub fn disable_request_compression(&self) -> Option<bool> {
1137        self.disable_request_compression
1138    }
1139
1140    /// When true, clock skew correction is disabled.
1141    pub fn disable_clock_skew_correction(&self) -> Option<bool> {
1142        self.disable_clock_skew_correction
1143    }
1144
1145    /// Configured checksum request behavior.
1146    pub fn request_checksum_calculation(&self) -> Option<RequestChecksumCalculation> {
1147        self.request_checksum_calculation
1148    }
1149
1150    /// Configured checksum response behavior.
1151    pub fn response_checksum_validation(&self) -> Option<ResponseChecksumValidation> {
1152        self.response_checksum_validation
1153    }
1154
1155    /// Configured minimum request compression size.
1156    pub fn request_min_compression_size_bytes(&self) -> Option<u32> {
1157        self.request_min_compression_size_bytes
1158    }
1159
1160    /// Configured stalled stream protection
1161    pub fn stalled_stream_protection(&self) -> Option<StalledStreamProtectionConfig> {
1162        self.stalled_stream_protection_config.clone()
1163    }
1164
1165    /// Behavior version configured for this client
1166    pub fn behavior_version(&self) -> Option<BehaviorVersion> {
1167        self.behavior_version
1168    }
1169
1170    /// Return an immutable reference to the service config provider configured for this client.
1171    pub fn service_config(&self) -> Option<&dyn LoadServiceConfig> {
1172        self.service_config.as_deref()
1173    }
1174
1175    /// Config builder
1176    ///
1177    /// _Important:_ Using the `aws-config` crate to configure the SDK is preferred to invoking this
1178    /// builder directly. Using this builder directly won't pull in any AWS recommended default
1179    /// configuration values.
1180    pub fn builder() -> Builder {
1181        Builder::default()
1182    }
1183
1184    /// Convert this [`SdkConfig`] into a [`Builder`] by cloning it first
1185    pub fn to_builder(&self) -> Builder {
1186        self.clone().into_builder()
1187    }
1188
1189    /// Get the origin of a setting.
1190    ///
1191    /// This is used internally to understand how to merge config structs while
1192    /// respecting precedence of origins.
1193    pub fn get_origin(&self, setting: &'static str) -> Origin {
1194        self.config_origins
1195            .get(setting)
1196            .cloned()
1197            .unwrap_or_default()
1198    }
1199
1200    /// Convert this [`SdkConfig`] back to a builder to enable modification
1201    pub fn into_builder(self) -> Builder {
1202        Builder {
1203            app_name: self.app_name,
1204            framework_metadata: self.framework_metadata,
1205            auth_scheme_preference: self.auth_scheme_preference,
1206            sigv4a_signing_region_set: self.sigv4a_signing_region_set,
1207            identity_cache: self.identity_cache,
1208            credentials_provider: self.credentials_provider,
1209            token_provider: self.token_provider,
1210            region: self.region,
1211            account_id_endpoint_mode: self.account_id_endpoint_mode,
1212            endpoint_url: self.endpoint_url,
1213            retry_config: self.retry_config,
1214            sleep_impl: self.sleep_impl,
1215            time_source: self.time_source,
1216            timeout_config: self.timeout_config,
1217            http_client: self.http_client,
1218            use_fips: self.use_fips,
1219            use_dual_stack: self.use_dual_stack,
1220            behavior_version: self.behavior_version,
1221            stalled_stream_protection_config: self.stalled_stream_protection_config,
1222            service_config: self.service_config,
1223            config_origins: self.config_origins,
1224            disable_request_compression: self.disable_request_compression,
1225            disable_clock_skew_correction: self.disable_clock_skew_correction,
1226            request_min_compression_size_bytes: self.request_min_compression_size_bytes,
1227            request_checksum_calculation: self.request_checksum_calculation,
1228            response_checksum_validation: self.response_checksum_validation,
1229            protocol: self.protocol,
1230        }
1231    }
1232}