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