Unverified Commit a1f06527 authored by Zelda Hessler's avatar Zelda Hessler Committed by GitHub
Browse files

HTTP Connectors Refactor pt.1 - Laying the groundwork (#1144)

* refactor: HttpSettings, HttpConnection location
update: replace timeout::Settings with TimeoutConfig
add: HttpConnector to aws_types::Config and Builder
refactor: divide default_provider.rs modules into separate files

* add: missing copyright headers

* add: missing http_connector accessor to Config

* remove: unused import

* update: undo changes to aws_config::connector module
remove: impl Default for HttpConnector

* update: CHANGELOG.next.toml
parent 6b4e2bae
Loading
Loading
Loading
Loading
+97 −0
Original line number Diff line number Diff line
@@ -11,6 +11,103 @@
# meta = { "breaking" = false, "tada" = false, "bug" = false }
# author = "rcoh"

[[aws-sdk-rust]]
message = "Several modules defined in the `aws_config` crate that used to be declared within another module's file have been moved to their own files. The moved modules are `sts`, `connector`, and `default_providers`. They still have the exact same import paths."
references = ["smithy-rs#1144"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "Velfi"

[[aws-sdk-rust]]
message = "The `aws_config::http_provider` module has been renamed to `aws_config::http_credential_provider` to better reflect its purpose."
references = ["smithy-rs#1144"]
meta = { "breaking" = true, "tada" = false, "bug" = false }
author = "Velfi"

[[aws-sdk-rust]]
message = """
Some APIs required that timeout configuration be specified with an `aws_smithy_client::timeout::Settings` struct while
others required an `aws_smithy_types::timeout::TimeoutConfig` struct. Both were equivalent. Now `aws_smithy_types::timeout::TimeoutConfig`
is used everywhere and `aws_smithy_client::timeout::Settings` has been removed. Here's how to migrate code your code that
depended on `timeout::Settings`:

The old way:
```rust
let timeout = timeout::Settings::new()
    .with_connect_timeout(Duration::from_secs(1))
    .with_read_timeout(Duration::from_secs(2));
```

The new way:
```rust
// This example is passing values, so they're wrapped in `Option::Some`. You can disable a timeout by passing `None`.
let timeout = TimeoutConfig::new()
    .with_connect_timeout(Some(Duration::from_secs(1)))
    .with_read_timeout(Some(Duration::from_secs(2)));
```
"""
references = ["smithy-rs#1144"]
meta = { "breaking" = true, "tada" = false, "bug" = false }
author = "Velfi"

[[smithy-rs]]
message = """
Some APIs required that timeout configuration be specified with an `aws_smithy_client::timeout::Settings` struct while
others required an `aws_smithy_types::timeout::TimeoutConfig` struct. Both were equivalent. Now `aws_smithy_types::timeout::TimeoutConfig`
is used everywhere and `aws_smithy_client::timeout::Settings` has been removed. Here's how to migrate code your code that
depended on `timeout::Settings`:

The old way:
```rust
let timeout = timeout::Settings::new()
    .with_connect_timeout(Duration::from_secs(1))
    .with_read_timeout(Duration::from_secs(2));
```

The new way:
```rust
// This example is passing values, so they're wrapped in `Option::Some`. You can disable a timeout by passing `None`.
let timeout = TimeoutConfig::new()
    .with_connect_timeout(Some(Duration::from_secs(1)))
    .with_read_timeout(Some(Duration::from_secs(2)));
```
"""
references = ["smithy-rs#1144"]
meta = { "breaking" = true, "tada" = false, "bug" = false }
author = "Velfi"

[[aws-sdk-rust]]
message = """
`MakeConnectorFn`, `HttpConnector`, and `HttpSettings` have been moved from `aws_config::provider_config` to
`aws_smithy_client::http_connector`. This is in preparation for a later update that will change how connectors are
created and configured.

If you were using these structs/enums, you can migrate your old code by importing them from their new location.
"""
references = ["smithy-rs#1144"]
meta = { "breaking" = true, "tada" = false, "bug" = false }
author = "Velfi"

[[smithy-rs]]
message = """
`MakeConnectorFn`, `HttpConnector`, and `HttpSettings` have been moved from `aws_config::provider_config` to
`aws_smithy_client::http_connector`. This is in preparation for a later update that will change how connectors are
created and configured.
"""
references = ["smithy-rs#1144"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "Velfi"

[[aws-sdk-rust]]
message = """
Along with moving `HttpConnector` to `aws_smithy_client`, the `HttpConnector::make_connector` method has been renamed to
`HttpConnector::connector`.

If you were using this method, you can migrate your old code by calling `connector` instead of `make_connector`.
"""
references = ["smithy-rs#1144"]
meta = { "breaking" = true, "tada" = false, "bug" = false }
author = "Velfi"

[[smithy-rs]]
message = "Refactor `Document` shape parser generation"
references = ["smithy-rs#1123"]
+60 −0
Original line number Diff line number Diff line
/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

//! Functionality related to creating new HTTP Connectors

use std::sync::Arc;

use aws_smithy_async::rt::sleep::AsyncSleep;
use aws_smithy_client::erase::DynConnector;
use aws_smithy_client::http_connector::HttpSettings;

// unused when all crate features are disabled
/// Unwrap an [`Option<DynConnector>`](aws_smithy_client::erase::DynConnector), and panic with a helpful error message if it's `None`
pub(crate) fn expect_connector(connector: Option<DynConnector>) -> DynConnector {
    connector.expect("A connector was not available. Either set a custom connector or enable the `rustls` and `native-tls` crate features.")
}

#[cfg(any(feature = "rustls", feature = "native-tls"))]
fn base(
    settings: &HttpSettings,
    sleep: Option<Arc<dyn AsyncSleep>>,
) -> aws_smithy_client::hyper_ext::Builder {
    let mut hyper =
        aws_smithy_client::hyper_ext::Adapter::builder().timeout(&settings.timeout_config);
    if let Some(sleep) = sleep {
        hyper = hyper.sleep_impl(sleep);
    }
    hyper
}

/// Given `HttpSettings` and an `AsyncSleep`, create a `DynConnector` from defaults depending on what cargo features are activated.
#[cfg(feature = "rustls")]
pub fn default_connector(
    settings: &HttpSettings,
    sleep: Option<Arc<dyn AsyncSleep>>,
) -> Option<DynConnector> {
    let hyper = base(settings, sleep).build(aws_smithy_client::conns::https());
    Some(DynConnector::new(hyper))
}

/// Given `HttpSettings` and an `AsyncSleep`, create a `DynConnector` from defaults depending on what cargo features are activated.
#[cfg(all(not(feature = "rustls"), feature = "native-tls"))]
pub fn default_connector(
    settings: &HttpSettings,
    sleep: Option<Arc<dyn AsyncSleep>>,
) -> Option<DynConnector> {
    let hyper = base(settings, sleep).build(aws_smithy_client::conns::native_tls());
    Some(DynConnector::new(hyper))
}

/// Given `HttpSettings` and an `AsyncSleep`, create a `DynConnector` from defaults depending on what cargo features are activated.
#[cfg(not(any(feature = "rustls", feature = "native-tls")))]
pub fn default_connector(
    _settings: &HttpSettings,
    _sleep: Option<Arc<dyn AsyncSleep>>,
) -> Option<DynConnector> {
    None
}
+5 −824

File changed.

Preview size limit exceeded, changes collapsed.

+95 −0
Original line number Diff line number Diff line
/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

use crate::environment::app_name::EnvironmentVariableAppNameProvider;
use crate::profile::app_name;
use crate::provider_config::ProviderConfig;
use aws_types::app_name::AppName;

/// Default App Name Provider chain
///
/// This provider will check the following sources in order:
/// 1. [Environment variables](EnvironmentVariableAppNameProvider)
/// 2. [Profile file](crate::profile::app_name::ProfileFileAppNameProvider)
pub fn default_provider() -> Builder {
    Builder::default()
}

/// Default provider builder for [`AppName`]
#[derive(Default)]
pub struct Builder {
    env_provider: EnvironmentVariableAppNameProvider,
    profile_file: app_name::Builder,
}

impl Builder {
    #[doc(hidden)]
    /// Configure the default chain
    ///
    /// Exposed for overriding the environment when unit-testing providers
    pub fn configure(mut self, configuration: &ProviderConfig) -> Self {
        self.env_provider = EnvironmentVariableAppNameProvider::new_with_env(configuration.env());
        self.profile_file = self.profile_file.configure(configuration);
        self
    }

    /// Override the profile name used by this provider
    pub fn profile_name(mut self, name: &str) -> Self {
        self.profile_file = self.profile_file.profile_name(name);
        self
    }

    /// Build an [`AppName`] from the default chain
    pub async fn app_name(self) -> Option<AppName> {
        self.env_provider
            .app_name()
            .or(self.profile_file.build().app_name().await)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::provider_config::ProviderConfig;
    use crate::test_case::no_traffic_connector;
    use aws_types::os_shim_internal::{Env, Fs};

    #[tokio::test]
    async fn prefer_env_to_profile() {
        let fs = Fs::from_slice(&[("test_config", "[default]\nsdk-ua-app-id = wrong")]);
        let env = Env::from_slice(&[
            ("AWS_CONFIG_FILE", "test_config"),
            ("AWS_SDK_UA_APP_ID", "correct"),
        ]);
        let app_name = Builder::default()
            .configure(
                &ProviderConfig::no_configuration()
                    .with_fs(fs)
                    .with_env(env)
                    .with_http_connector(no_traffic_connector()),
            )
            .app_name()
            .await;

        assert_eq!(Some(AppName::new("correct").unwrap()), app_name);
    }

    #[tokio::test]
    async fn load_from_profile() {
        let fs = Fs::from_slice(&[("test_config", "[default]\nsdk-ua-app-id = correct")]);
        let env = Env::from_slice(&[("AWS_CONFIG_FILE", "test_config")]);
        let app_name = Builder::default()
            .configure(
                &ProviderConfig::empty()
                    .with_fs(fs)
                    .with_env(env)
                    .with_http_connector(no_traffic_connector()),
            )
            .app_name()
            .await;

        assert_eq!(Some(AppName::new("correct").unwrap()), app_name);
    }
}
+441 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading