diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml
index 164719bb6d..cf15871921 100644
--- a/CHANGELOG.next.toml
+++ b/CHANGELOG.next.toml
@@ -92,6 +92,99 @@ references = ["smithy-rs#1923"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "ysaito1001"
+[[aws-sdk-rust]]
+message = """
+
+The HTTP connector used when making requests is now configurable through `SdkConfig`.
+
+```rust
+use std::time::Duration;
+use aws_smithy_client::{Client, hyper_ext};
+use aws_smithy_client::erase::DynConnector;
+use aws_smithy_client::http_connector::ConnectorSettings;
+use aws_types::SdkConfig;
+
+let https_connector = hyper_rustls::HttpsConnectorBuilder::new()
+ .with_webpki_roots()
+ .https_only()
+ .enable_http1()
+ .enable_http2()
+ .build();
+
+let smithy_connector = hyper_ext::Adapter::builder()
+ // Optionally set things like timeouts as well
+ .connector_settings(
+ ConnectorSettings::builder()
+ .connect_timeout(Duration::from_secs(5))
+ .build()
+ )
+ .build(https_connector);
+
+let sdk_config = aws_config::from_env()
+ .http_connector(smithy_connector)
+ .load()
+ .await;
+
+let client = Client::new(&sdk_config);
+
+// When sent, this operation will go through the custom smithy connector instead of
+// the default HTTP connector.
+let op = client
+ .get_object()
+ .bucket("some-test-bucket")
+ .key("test.txt")
+ .send()
+ .await
+ .unwrap();
+```
+
+
+"""
+references = ["smithy-rs#1225", "smithy-rs#1918"]
+meta = { "breaking" = false, "tada" = true, "bug" = false }
+author = "Velfi"
+
+[[aws-sdk-rust]]
+message = """
+`::Client::from_conf_conn` has been removed since it's now possible to configure the connection from the
+shared and service configs. To update your code, pass connections to the `http_connector` method during config creation.
+
+
+Example
+
+before:
+
+```rust
+ let conf = aws_sdk_sts::Config::builder()
+ // The builder has no defaults but setting other fields is omitted for brevity...
+ .build();
+ let (server, request) = capture_request(None);
+ let client = aws_sdk_sts::Client::from_conf_conn(conf, server);
+```
+
+after:
+
+```rust
+ let (server, request) = capture_request(None);
+ let conf = aws_sdk_sts::Config::builder()
+ // The builder has no defaults but setting other fields is omitted for brevity...
+ .http_connector(server)
+ .build();
+ let client = aws_sdk_sts::Client::from_conf(conf);
+```
+
+
+"""
+references = ["smithy-rs#1225", "smithy-rs#1918"]
+meta = { "breaking" = true, "tada" = false, "bug" = false }
+author = "Velfi"
+
+[[aws-sdk-rust]]
+message = "Add `to_vec` method to `aws_smithy_http::byte_stream::AggregatedBytes`."
+references = ["smithy-rs#1918"]
+meta = { "breaking" = false, "tada" = false, "bug" = false }
+author = "Velfi"
+
[[aws-sdk-rust]]
message = "Ability to add an inline policy or a list of policy ARNs to the `AssumeRoleProvider` builder."
references = ["aws-sdk-rust#641", "smithy-rs#1892"]
diff --git a/aws/SDK_CHANGELOG.next.json b/aws/SDK_CHANGELOG.next.json
index 9fb8b3ef9d..08ffbf6682 100644
--- a/aws/SDK_CHANGELOG.next.json
+++ b/aws/SDK_CHANGELOG.next.json
@@ -341,4 +341,4 @@
}
],
"aws-sdk-model": []
-}
\ No newline at end of file
+}
diff --git a/aws/rust-runtime/aws-config/Cargo.toml b/aws/rust-runtime/aws-config/Cargo.toml
index 2cafa33a75..5e6727da45 100644
--- a/aws/rust-runtime/aws-config/Cargo.toml
+++ b/aws/rust-runtime/aws-config/Cargo.toml
@@ -17,21 +17,20 @@ rt-tokio = ["aws-smithy-async/rt-tokio", "tokio/rt"]
default = ["client-hyper", "rustls", "rt-tokio"]
[dependencies]
-aws-sdk-sts = { path = "../../sdk/build/aws-sdk/sdk/sts", default-features = false }
+aws-http = { path = "../../sdk/build/aws-sdk/sdk/aws-http" }
aws-sdk-sso = { path = "../../sdk/build/aws-sdk/sdk/sso", default-features = false }
+aws-sdk-sts = { path = "../../sdk/build/aws-sdk/sdk/sts", default-features = false }
aws-smithy-async = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-async" }
aws-smithy-client = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-client", default-features = false }
+aws-smithy-http = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-http" }
+aws-smithy-http-tower = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-http-tower" }
+aws-smithy-json = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-json" }
aws-smithy-types = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-types" }
aws-types = { path = "../../sdk/build/aws-sdk/sdk/aws-types" }
+hyper = { version = "0.14.12", default-features = false }
time = { version = "0.3.4", features = ["parsing"] }
tokio = { version = "1.8.4", features = ["sync"] }
tracing = { version = "0.1" }
-hyper = { version = "0.14.12", default-features = false }
-
-aws-http = { path = "../../sdk/build/aws-sdk/sdk/aws-http" }
-aws-smithy-http = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-http" }
-aws-smithy-http-tower = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-http-tower" }
-aws-smithy-json = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-json" }
# implementation detail of SSO credential caching
ring = "0.16"
diff --git a/aws/rust-runtime/aws-config/external-types.toml b/aws/rust-runtime/aws-config/external-types.toml
index 3834902b6f..9c85536c88 100644
--- a/aws/rust-runtime/aws-config/external-types.toml
+++ b/aws/rust-runtime/aws-config/external-types.toml
@@ -12,6 +12,7 @@ allowed_external_types = [
"aws_smithy_client::http_connector::ConnectorSettings",
"aws_smithy_http::body::SdkBody",
"aws_smithy_http::result::SdkError",
+ "aws_smithy_http::endpoint",
"aws_smithy_types::retry",
"aws_smithy_types::retry::*",
"aws_smithy_types::timeout",
diff --git a/aws/rust-runtime/aws-config/src/lib.rs b/aws/rust-runtime/aws-config/src/lib.rs
index 6d4506fc4e..73a492bb26 100644
--- a/aws/rust-runtime/aws-config/src/lib.rs
+++ b/aws/rust-runtime/aws-config/src/lib.rs
@@ -91,6 +91,18 @@
//! # }
//! ```
+pub use aws_smithy_http::endpoint;
+// Re-export types from smithy-types
+pub use aws_smithy_types::retry;
+pub use aws_smithy_types::timeout;
+// Re-export types from aws-types
+pub use aws_types::{
+ app_name::{AppName, InvalidAppName},
+ SdkConfig,
+};
+/// Load default sources for all configuration with override support
+pub use loader::ConfigLoader;
+
#[allow(dead_code)]
const PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
@@ -132,16 +144,6 @@ pub mod connector;
pub mod credential_process;
-// Re-export types from smithy-types
-pub use aws_smithy_types::retry;
-pub use aws_smithy_types::timeout;
-
-// Re-export types from aws-types
-pub use aws_types::{
- app_name::{AppName, InvalidAppName},
- SdkConfig,
-};
-
/// Create an environment loader for AWS Configuration
///
/// # Examples
@@ -162,13 +164,9 @@ pub async fn load_from_env() -> aws_types::SdkConfig {
from_env().load().await
}
-/// Load default sources for all configuration with override support
-pub use loader::ConfigLoader;
-
mod loader {
use std::sync::Arc;
- use crate::connector::default_connector;
use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep};
use aws_smithy_client::http_connector::{ConnectorSettings, HttpConnector};
use aws_smithy_types::retry::RetryConfig;
@@ -178,6 +176,7 @@ mod loader {
use aws_types::endpoint::ResolveAwsEndpoint;
use aws_types::SdkConfig;
+ use crate::connector::default_connector;
use crate::default_provider::{app_name, credentials, region, retry_config, timeout_config};
use crate::meta::region::ProvideRegion;
use crate::provider_config::ProviderConfig;
@@ -222,11 +221,13 @@ mod loader {
///
/// # Examples
/// ```no_run
- /// # use aws_smithy_types::retry::RetryConfig;
/// # async fn create_config() {
- /// let config = aws_config::from_env()
- /// .retry_config(RetryConfig::standard().with_max_attempts(2))
- /// .load().await;
+ /// use aws_config::retry::RetryConfig;
+ ///
+ /// let config = aws_config::from_env()
+ /// .retry_config(RetryConfig::standard().with_max_attempts(2))
+ /// .load()
+ /// .await;
/// # }
/// ```
pub fn retry_config(mut self, retry_config: RetryConfig) -> Self {
@@ -242,16 +243,16 @@ mod loader {
/// ```no_run
/// # use std::time::Duration;
/// # async fn create_config() {
- /// use aws_smithy_types::timeout::TimeoutConfig;
+ /// use aws_config::timeout::TimeoutConfig;
///
- /// let config = aws_config::from_env()
- /// .timeout_config(
- /// TimeoutConfig::builder()
- /// .operation_timeout(Duration::from_secs(5))
- /// .build()
- /// )
- /// .load()
- /// .await;
+ /// let config = aws_config::from_env()
+ /// .timeout_config(
+ /// TimeoutConfig::builder()
+ /// .operation_timeout(Duration::from_secs(5))
+ /// .build()
+ /// )
+ /// .load()
+ /// .await;
/// # }
/// ```
pub fn timeout_config(mut self, timeout_config: TimeoutConfig) -> Self {
@@ -267,9 +268,41 @@ mod loader {
self
}
- /// Override the [`HttpConnector`] used to build [`SdkConfig`](aws_types::SdkConfig).
- pub fn http_connector(mut self, http_connector: HttpConnector) -> Self {
- self.http_connector = Some(http_connector);
+ /// Override the [`HttpConnector`] for this [`ConfigLoader`]. The connector will be used when
+ /// sending operations. This **does not set** the HTTP connector used by config providers.
+ /// To change that connector, use [ConfigLoader::configure].
+ ///
+ /// ## Examples
+ /// ```no_run
+ /// # #[cfg(feature = "client-hyper")]
+ /// # async fn create_config() {
+ /// use std::time::Duration;
+ /// use aws_smithy_client::{Client, hyper_ext};
+ /// use aws_smithy_client::erase::DynConnector;
+ /// use aws_smithy_client::http_connector::ConnectorSettings;
+ ///
+ /// let https_connector = hyper_rustls::HttpsConnectorBuilder::new()
+ /// .with_webpki_roots()
+ /// .https_only()
+ /// .enable_http1()
+ /// .enable_http2()
+ /// .build();
+ /// let smithy_connector = hyper_ext::Adapter::builder()
+ /// // Optionally set things like timeouts as well
+ /// .connector_settings(
+ /// ConnectorSettings::builder()
+ /// .connect_timeout(Duration::from_secs(5))
+ /// .build()
+ /// )
+ /// .build(https_connector);
+ /// let sdk_config = aws_config::from_env()
+ /// .http_connector(smithy_connector)
+ /// .load()
+ /// .await;
+ /// # }
+ /// ```
+ pub fn http_connector(mut self, http_connector: impl Into) -> Self {
+ self.http_connector = Some(http_connector.into());
self
}
@@ -308,11 +341,13 @@ mod loader {
///
/// Use a static endpoint for all services
/// ```no_run
- /// # async fn doc() {
- /// use aws_smithy_http::endpoint::Endpoint;
+ /// # async fn create_config() {
+ /// use aws_config::endpoint::Endpoint;
+ ///
/// let sdk_config = aws_config::from_env()
- /// .endpoint_resolver(Endpoint::immutable("http://localhost:1234".parse().expect("valid URI")))
- /// .load().await;
+ /// .endpoint_resolver(Endpoint::immutable("http://localhost:1234".parse().expect("valid URI")))
+ /// .load()
+ /// .await;
/// # }
pub fn endpoint_resolver(
mut self,
@@ -325,12 +360,14 @@ mod loader {
/// Set configuration for all sub-loaders (credentials, region etc.)
///
/// Update the `ProviderConfig` used for all nested loaders. This can be used to override
- /// the HTTPs connector used or to stub in an in memory `Env` or `Fs` for testing.
+ /// the HTTPs connector used by providers or to stub in an in memory `Env` or `Fs` for testing.
+ /// This **does not set** the HTTP connector used when sending operations. To change that
+ /// connector, use [ConfigLoader::http_connector].
///
/// # Examples
/// ```no_run
/// # #[cfg(feature = "hyper-client")]
- /// # async fn docs() {
+ /// # async fn create_config() {
/// use aws_config::provider_config::ProviderConfig;
/// let custom_https_connector = hyper_rustls::HttpsConnectorBuilder::new().
/// with_webpki_roots()
@@ -444,14 +481,15 @@ mod loader {
#[cfg(test)]
mod test {
- use crate::from_env;
- use crate::provider_config::ProviderConfig;
use aws_smithy_async::rt::sleep::TokioSleep;
use aws_smithy_client::erase::DynConnector;
use aws_smithy_client::never::NeverConnector;
use aws_types::credentials::ProvideCredentials;
use aws_types::os_shim_internal::Env;
+ use crate::from_env;
+ use crate::provider_config::ProviderConfig;
+
#[tokio::test]
async fn provider_config_used() {
let env = Env::from_slice(&[
diff --git a/aws/rust-runtime/aws-types/Cargo.toml b/aws/rust-runtime/aws-types/Cargo.toml
index 54b599ed29..755ccdba07 100644
--- a/aws/rust-runtime/aws-types/Cargo.toml
+++ b/aws/rust-runtime/aws-types/Cargo.toml
@@ -9,6 +9,8 @@ repository = "https://github.com/awslabs/smithy-rs"
[features]
hardcoded-credentials = []
+# This feature is to be used only for doc comments
+examples = ["aws-smithy-client/client-hyper", "aws-smithy-client/rustls", "hyper-rustls"]
[dependencies]
aws-smithy-async = { path = "../../../rust-runtime/aws-smithy-async" }
@@ -18,6 +20,10 @@ aws-smithy-http = { path = "../../../rust-runtime/aws-smithy-http" }
tracing = "0.1"
zeroize = "1"
http = "0.2.6"
+# cargo does not support optional test dependencies, so to completely disable rustls when
+# the native-tls feature is enabled, we need to add the webpki-roots feature here.
+# https://github.com/rust-lang/cargo/issues/1596
+hyper-rustls = { version = "0.23.0", optional = true, features = ["rustls-native-certs", "http2", "webpki-roots"] }
[dev-dependencies]
futures-util = "0.3.16"
diff --git a/aws/rust-runtime/aws-types/src/sdk_config.rs b/aws/rust-runtime/aws-types/src/sdk_config.rs
index 08849fe6ee..6fb916421a 100644
--- a/aws/rust-runtime/aws-types/src/sdk_config.rs
+++ b/aws/rust-runtime/aws-types/src/sdk_config.rs
@@ -359,15 +359,81 @@ impl Builder {
self
}
- /// Sets the HTTP connector that clients will use to make HTTP requests.
- pub fn http_connector(mut self, http_connector: HttpConnector) -> Self {
+ /// Sets the HTTP connector to use when making requests.
+ ///
+ /// ## Examples
+ /// ```no_run
+ /// # #[cfg(feature = "examples")]
+ /// # fn example() {
+ /// use std::time::Duration;
+ /// use aws_smithy_client::{Client, hyper_ext};
+ /// use aws_smithy_client::erase::DynConnector;
+ /// use aws_smithy_client::http_connector::ConnectorSettings;
+ /// use aws_types::SdkConfig;
+ ///
+ /// let https_connector = hyper_rustls::HttpsConnectorBuilder::new()
+ /// .with_webpki_roots()
+ /// .https_only()
+ /// .enable_http1()
+ /// .enable_http2()
+ /// .build();
+ /// let smithy_connector = hyper_ext::Adapter::builder()
+ /// // Optionally set things like timeouts as well
+ /// .connector_settings(
+ /// ConnectorSettings::builder()
+ /// .connect_timeout(Duration::from_secs(5))
+ /// .build()
+ /// )
+ /// .build(https_connector);
+ /// let sdk_config = SdkConfig::builder()
+ /// .http_connector(smithy_connector)
+ /// .build();
+ /// # }
+ /// ```
+ pub fn http_connector(mut self, http_connector: impl Into) -> Self {
self.set_http_connector(Some(http_connector));
self
}
- /// Sets the HTTP connector that clients will use to make HTTP requests.
- pub fn set_http_connector(&mut self, http_connector: Option) -> &mut Self {
- self.http_connector = http_connector;
+ /// Sets the HTTP connector to use when making requests.
+ ///
+ /// ## Examples
+ /// ```no_run
+ /// # #[cfg(feature = "examples")]
+ /// # fn example() {
+ /// use std::time::Duration;
+ /// use aws_smithy_client::hyper_ext;
+ /// use aws_smithy_client::http_connector::ConnectorSettings;
+ /// use aws_types::sdk_config::{SdkConfig, Builder};
+ ///
+ /// fn override_http_connector(builder: &mut Builder) {
+ /// let https_connector = hyper_rustls::HttpsConnectorBuilder::new()
+ /// .with_webpki_roots()
+ /// .https_only()
+ /// .enable_http1()
+ /// .enable_http2()
+ /// .build();
+ /// let smithy_connector = hyper_ext::Adapter::builder()
+ /// // Optionally set things like timeouts as well
+ /// .connector_settings(
+ /// ConnectorSettings::builder()
+ /// .connect_timeout(Duration::from_secs(5))
+ /// .build()
+ /// )
+ /// .build(https_connector);
+ /// builder.set_http_connector(Some(smithy_connector));
+ /// }
+ ///
+ /// let mut builder = SdkConfig::builder();
+ /// override_http_connector(&mut builder);
+ /// let config = builder.build();
+ /// # }
+ /// ```
+ pub fn set_http_connector(
+ &mut self,
+ http_connector: Option>,
+ ) -> &mut Self {
+ self.http_connector = http_connector.map(|inner| inner.into());
self
}
diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCodegenDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCodegenDecorator.kt
index aec623d221..8102ef579c 100644
--- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCodegenDecorator.kt
+++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCodegenDecorator.kt
@@ -35,6 +35,7 @@ val DECORATORS = listOf(
ServiceConfigDecorator(),
AwsPresigningDecorator(),
AwsReadmeDecorator(),
+ HttpConnectorDecorator(),
// Service specific decorators
ApiGatewayDecorator(),
diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt
index bbdb9d80a5..2f0ea31f26 100644
--- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt
+++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt
@@ -158,25 +158,7 @@ private class AwsFluentClientExtensions(types: Types) {
writer.rustBlockTemplate("impl Client", *codegenScope) {
rustTemplate(
"""
- /// Creates a client with the given service config and connector override.
- pub fn from_conf_conn(conf: crate::Config, conn: C) -> Self
- where
- C: #{SmithyConnector} + Send + 'static,
- E: Into<#{ConnectorError}>,
- {
- let retry_config = conf.retry_config().cloned().unwrap_or_else(#{RetryConfig}::disabled);
- let timeout_config = conf.timeout_config().cloned().unwrap_or_else(#{TimeoutConfig}::disabled);
- let mut builder = #{aws_smithy_client}::Builder::new()
- .connector(#{DynConnector}::new(conn))
- .middleware(#{DynMiddleware}::new(#{Middleware}::new()))
- .retry_config(retry_config.into())
- .operation_timeout_config(timeout_config.into());
- builder.set_sleep_impl(conf.sleep_impl());
- let client = builder.build();
- Self { handle: std::sync::Arc::new(Handle { client, conf }) }
- }
-
- /// Creates a new client from a shared config.
+ /// Creates a new client from an [SDK Config](#{aws_types}::sdk_config::SdkConfig).
##[cfg(any(feature = "rustls", feature = "native-tls"))]
pub fn new(sdk_config: {aws_types}::sdk_config::SdkConfig) -> Self {
Self::from_conf(sdk_config.into())
@@ -192,8 +174,26 @@ private class AwsFluentClientExtensions(types: Types) {
panic!("An async sleep implementation is required for retries or timeouts to work. \
Set the `sleep_impl` on the Config passed into this function to fix this panic.");
}
- let mut builder = #{aws_smithy_client}::Builder::new()
- .dyn_https_connector(#{ConnectorSettings}::from_timeout_config(&timeout_config))
+
+ let connector = conf.http_connector().and_then(|c| {
+ let timeout_config = conf
+ .timeout_config()
+ .cloned()
+ .unwrap_or_else(#{TimeoutConfig}::disabled);
+ let connector_settings = #{ConnectorSettings}::from_timeout_config(
+ &timeout_config,
+ );
+ c.connector(&connector_settings, conf.sleep_impl())
+ });
+
+ let builder = #{aws_smithy_client}::Builder::new();
+ let builder = match connector {
+ // Use provided connector
+ Some(c) => builder.connector(c),
+ // Use default connector based on enabled features
+ None => builder.dyn_https_connector(#{ConnectorSettings}::from_timeout_config(&timeout_config)),
+ };
+ let mut builder = builder
.middleware(#{DynMiddleware}::new(#{Middleware}::new()))
.retry_config(retry_config.into())
.operation_timeout_config(timeout_config.into());
diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsPresigningDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsPresigningDecorator.kt
index a65cb4fcae..e7d418e33f 100644
--- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsPresigningDecorator.kt
+++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsPresigningDecorator.kt
@@ -262,19 +262,19 @@ class AwsPresignedFluentBuilderMethod(
documentPresignedMethod(hasConfigArg = false)
rustBlockTemplate(
"""
- pub async fn presigned(
- self,
- presigning_config: #{PresigningConfig},
- ) -> Result<#{PresignedRequest}, #{SdkError}<#{OpError}>>
- """,
+ pub async fn presigned(
+ self,
+ presigning_config: #{PresigningConfig},
+ ) -> Result<#{PresignedRequest}, #{SdkError}<#{OpError}>>
+ """,
*codegenScope,
"OpError" to section.operationErrorType,
) {
rustTemplate(
"""
- let input = self.inner.build().map_err(|err| #{SdkError}::ConstructionFailure(err.into()))?;
- input.presigned(&self.handle.conf, presigning_config).await
- """,
+ let input = self.inner.build().map_err(|err| #{SdkError}::ConstructionFailure(err.into()))?;
+ input.presigned(&self.handle.conf, presigning_config).await
+ """,
*codegenScope,
)
}
diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpConnectorConfigCustomization.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpConnectorConfigCustomization.kt
new file mode 100644
index 0000000000..1957d5a208
--- /dev/null
+++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpConnectorConfigCustomization.kt
@@ -0,0 +1,155 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package software.amazon.smithy.rustsdk
+
+import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
+import software.amazon.smithy.rust.codegen.client.smithy.customize.RustCodegenDecorator
+import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
+import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
+import software.amazon.smithy.rust.codegen.client.smithy.generators.protocol.ClientProtocolGenerator
+import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency.Companion.SmithyClient
+import software.amazon.smithy.rust.codegen.core.rustlang.Writable
+import software.amazon.smithy.rust.codegen.core.rustlang.asType
+import software.amazon.smithy.rust.codegen.core.rustlang.rust
+import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
+import software.amazon.smithy.rust.codegen.core.rustlang.writable
+import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
+
+class HttpConnectorDecorator : RustCodegenDecorator {
+ override val name: String = "HttpConnectorDecorator"
+ override val order: Byte = 0
+
+ override fun supportsCodegenContext(clazz: Class): Boolean =
+ clazz.isAssignableFrom(ClientCodegenContext::class.java)
+
+ override fun configCustomizations(
+ codegenContext: ClientCodegenContext,
+ baseCustomizations: List,
+ ): List {
+ return baseCustomizations + HttpConnectorConfigCustomization(codegenContext)
+ }
+}
+
+class HttpConnectorConfigCustomization(
+ codegenContext: CodegenContext,
+) : ConfigCustomization() {
+ private val runtimeConfig = codegenContext.runtimeConfig
+ private val moduleUseName = codegenContext.moduleUseName()
+ private val codegenScope = arrayOf(
+ "HttpConnector" to SmithyClient(runtimeConfig).asType().member("http_connector::HttpConnector"),
+ )
+
+ override fun section(section: ServiceConfig): Writable {
+ return when (section) {
+ is ServiceConfig.ConfigStruct -> writable {
+ rustTemplate("http_connector: Option<#{HttpConnector}>,", *codegenScope)
+ }
+ is ServiceConfig.ConfigImpl -> writable {
+ rustTemplate(
+ """
+ /// Return an [`HttpConnector`](#{HttpConnector}) to use when making requests, if any.
+ pub fn http_connector(&self) -> Option<{HttpConnector}> {
+ self.http_connector.as_ref()
+ }
+ """,
+ *codegenScope,
+ )
+ }
+ is ServiceConfig.BuilderStruct -> writable {
+ rustTemplate("http_connector: Option<#{HttpConnector}>,", *codegenScope)
+ }
+ ServiceConfig.BuilderImpl -> writable {
+ rustTemplate(
+ """
+ /// Sets the HTTP connector to use when making requests.
+ ///
+ /// ## Examples
+ /// ```no_run
+ /// ## ##[cfg(test)]
+ /// ## mod tests {
+ /// ## ##[test]
+ /// ## fn example() {
+ /// use std::time::Duration;
+ /// use aws_smithy_client::{Client, hyper_ext};
+ /// use aws_smithy_client::erase::DynConnector;
+ /// use aws_smithy_client::http_connector::ConnectorSettings;
+ /// use $moduleUseName::config::Config;
+ ///
+ /// let https_connector = hyper_rustls::HttpsConnectorBuilder::new()
+ /// .with_webpki_roots()
+ /// .https_only()
+ /// .enable_http1()
+ /// .enable_http2()
+ /// .build();
+ /// let smithy_connector = hyper_ext::Adapter::builder()
+ /// // Optionally set things like timeouts as well
+ /// .connector_settings(
+ /// ConnectorSettings::builder()
+ /// .connect_timeout(Duration::from_secs(5))
+ /// .build()
+ /// )
+ /// .build(https_connector);
+ /// ## }
+ /// ## }
+ /// ```
+ pub fn http_connector(mut self, http_connector: impl Into<#{HttpConnector}>) -> Self {
+ self.http_connector = Some(http_connector.into());
+ self
+ }
+
+ /// Sets the HTTP connector to use when making requests.
+ ///
+ /// ## Examples
+ /// ```no_run
+ /// ## ##[cfg(test)]
+ /// ## mod tests {
+ /// ## ##[test]
+ /// ## fn example() {
+ /// use std::time::Duration;
+ /// use aws_smithy_client::hyper_ext;
+ /// use aws_smithy_client::http_connector::ConnectorSettings;
+ /// use crate::sdk_config::{SdkConfig, Builder};
+ /// use $moduleUseName::config::{Builder, Config};
+ ///
+ /// fn override_http_connector(builder: &mut Builder) {
+ /// let https_connector = hyper_rustls::HttpsConnectorBuilder::new()
+ /// .with_webpki_roots()
+ /// .https_only()
+ /// .enable_http1()
+ /// .enable_http2()
+ /// .build();
+ /// let smithy_connector = hyper_ext::Adapter::builder()
+ /// // Optionally set things like timeouts as well
+ /// .connector_settings(
+ /// ConnectorSettings::builder()
+ /// .connect_timeout(Duration::from_secs(5))
+ /// .build()
+ /// )
+ /// .build(https_connector);
+ /// builder.set_http_connector(Some(smithy_connector));
+ /// }
+ ///
+ /// let mut builder = $moduleUseName::Config::builder();
+ /// override_http_connector(&mut builder);
+ /// let config = builder.build();
+ /// ## }
+ /// ## }
+ /// ```
+ pub fn set_http_connector(&mut self, http_connector: Option>) -> &mut Self {
+ self.http_connector = http_connector.map(|inner| inner.into());
+ self
+ }
+ """,
+ *codegenScope,
+ )
+ }
+ is ServiceConfig.BuilderBuild -> writable {
+ rust("http_connector: self.http_connector,")
+ }
+ else -> emptySection
+ }
+ }
+}
diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SdkConfigDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SdkConfigDecorator.kt
index 5a4135429c..eb7630d6c1 100644
--- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SdkConfigDecorator.kt
+++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SdkConfigDecorator.kt
@@ -54,6 +54,7 @@ class SdkConfigDecorator : RustCodegenDecorator Config {
+fn stub_config(conn: impl Into) -> Config {
Config::builder()
.region(Region::new("us-east-1"))
.credentials_provider(Credentials::new("akid", "secret", None, None, "test"))
+ .http_connector(conn)
.build()
}
@@ -25,7 +29,7 @@ fn stub_config() -> Config {
#[tokio::test]
async fn paginators_pass_args() {
let (conn, request) = capture_request(None);
- let client = Client::from_conf_conn(stub_config(), conn);
+ let client = Client::from_conf(stub_config(conn));
let mut paginator = client
.scan()
.table_name("test-table")
@@ -88,7 +92,7 @@ async fn paginators_loop_until_completion() {
),
),
]);
- let client = Client::from_conf_conn(stub_config(), conn.clone());
+ let client = Client::from_conf(stub_config(conn.clone()));
let mut paginator = client
.scan()
.table_name("test-table")
@@ -150,7 +154,7 @@ async fn paginators_handle_errors() {
}"#,
),
)]);
- let client = Client::from_conf_conn(stub_config(), conn.clone());
+ let client = Client::from_conf(stub_config(conn.clone()));
let mut rows = client
.scan()
.table_name("test-table")
@@ -196,7 +200,7 @@ async fn paginators_stop_on_duplicate_token_by_default() {
mk_response(response),
),
]);
- let client = Client::from_conf_conn(stub_config(), conn.clone());
+ let client = Client::from_conf(stub_config(conn.clone()));
let mut rows = client
.scan()
.table_name("test-table")
@@ -255,7 +259,7 @@ async fn paginators_can_continue_on_duplicate_token() {
mk_response(response),
),
]);
- let client = Client::from_conf_conn(stub_config(), conn.clone());
+ let client = Client::from_conf(stub_config(conn.clone()));
let mut rows = client
.scan()
.table_name("test-table")
diff --git a/aws/sdk/integration-tests/dynamodb/tests/shared-config.rs b/aws/sdk/integration-tests/dynamodb/tests/shared-config.rs
index 7d57882e30..14f1b07299 100644
--- a/aws/sdk/integration-tests/dynamodb/tests/shared-config.rs
+++ b/aws/sdk/integration-tests/dynamodb/tests/shared-config.rs
@@ -12,11 +12,12 @@ async fn shared_config_testbed() {
let shared_config = aws_types::SdkConfig::builder()
.region(Region::new("us-east-4"))
.build();
+ let (conn, request) = aws_smithy_client::test_connection::capture_request(None);
let conf = aws_sdk_dynamodb::config::Builder::from(&shared_config)
.credentials_provider(Credentials::new("asdf", "asdf", None, None, "test"))
+ .http_connector(conn)
.build();
- let (conn, request) = aws_smithy_client::test_connection::capture_request(None);
- let svc = aws_sdk_dynamodb::Client::from_conf_conn(conf, conn);
+ let svc = aws_sdk_dynamodb::Client::from_conf(conf);
let _ = svc.list_tables().send().await;
assert_eq!(
request.expect_request().uri(),
diff --git a/aws/sdk/integration-tests/dynamodb/tests/timeouts.rs b/aws/sdk/integration-tests/dynamodb/tests/timeouts.rs
index 170822acc8..9a09673335 100644
--- a/aws/sdk/integration-tests/dynamodb/tests/timeouts.rs
+++ b/aws/sdk/integration-tests/dynamodb/tests/timeouts.rs
@@ -3,6 +3,9 @@
* SPDX-License-Identifier: Apache-2.0
*/
+use std::sync::Arc;
+use std::time::Duration;
+
use aws_sdk_dynamodb::types::SdkError;
use aws_smithy_async::rt::sleep::{AsyncSleep, Sleep};
use aws_smithy_client::never::NeverConnector;
@@ -11,8 +14,6 @@ use aws_smithy_types::timeout::TimeoutConfig;
use aws_types::credentials::SharedCredentialsProvider;
use aws_types::region::Region;
use aws_types::{Credentials, SdkConfig};
-use std::sync::Arc;
-use std::time::Duration;
#[derive(Debug, Clone)]
struct InstantSleep;
@@ -27,6 +28,7 @@ async fn api_call_timeout_retries() {
let conn = NeverConnector::new();
let conf = SdkConfig::builder()
.region(Region::new("us-east-2"))
+ .http_connector(conn.clone())
.credentials_provider(SharedCredentialsProvider::new(Credentials::new(
"stub", "stub", None, None, "test",
)))
@@ -38,10 +40,7 @@ async fn api_call_timeout_retries() {
.retry_config(RetryConfig::standard())
.sleep_impl(Arc::new(InstantSleep))
.build();
- let client = aws_sdk_dynamodb::Client::from_conf_conn(
- aws_sdk_dynamodb::Config::new(&conf),
- conn.clone(),
- );
+ let client = aws_sdk_dynamodb::Client::from_conf(aws_sdk_dynamodb::Config::new(&conf));
let resp = client
.list_tables()
.send()
@@ -64,6 +63,7 @@ async fn no_retries_on_operation_timeout() {
let conn = NeverConnector::new();
let conf = SdkConfig::builder()
.region(Region::new("us-east-2"))
+ .http_connector(conn.clone())
.credentials_provider(SharedCredentialsProvider::new(Credentials::new(
"stub", "stub", None, None, "test",
)))
@@ -75,10 +75,7 @@ async fn no_retries_on_operation_timeout() {
.retry_config(RetryConfig::standard())
.sleep_impl(Arc::new(InstantSleep))
.build();
- let client = aws_sdk_dynamodb::Client::from_conf_conn(
- aws_sdk_dynamodb::Config::new(&conf),
- conn.clone(),
- );
+ let client = aws_sdk_dynamodb::Client::from_conf(aws_sdk_dynamodb::Config::new(&conf));
let resp = client
.list_tables()
.send()
diff --git a/aws/sdk/integration-tests/ec2/tests/paginators.rs b/aws/sdk/integration-tests/ec2/tests/paginators.rs
index abb0746ae5..43fe53bce1 100644
--- a/aws/sdk/integration-tests/ec2/tests/paginators.rs
+++ b/aws/sdk/integration-tests/ec2/tests/paginators.rs
@@ -3,14 +3,17 @@
* SPDX-License-Identifier: Apache-2.0
*/
+use tokio_stream::StreamExt;
+
use aws_sdk_ec2::{model::InstanceType, Client, Config, Credentials, Region};
+use aws_smithy_client::http_connector::HttpConnector;
use aws_smithy_client::test_connection::TestConnection;
-use tokio_stream::StreamExt;
-fn stub_config() -> Config {
+fn stub_config(conn: impl Into) -> Config {
Config::builder()
.region(Region::new("us-east-1"))
.credentials_provider(Credentials::new("akid", "secret", None, None, "test"))
+ .http_connector(conn)
.build()
}
@@ -36,7 +39,7 @@ async fn paginators_handle_empty_tokens() {
.body(response)
.unwrap(),
)]);
- let client = Client::from_conf_conn(stub_config(), conn.clone());
+ let client = Client::from_conf(stub_config(conn.clone()));
let instance_type = InstanceType::from("g5.48xlarge");
let mut paginator = client
.describe_spot_price_history()
@@ -72,7 +75,7 @@ async fn paginators_handle_unset_tokens() {
.body(response)
.unwrap(),
)]);
- let client = Client::from_conf_conn(stub_config(), conn.clone());
+ let client = Client::from_conf(stub_config(conn.clone()));
let instance_type = InstanceType::from("g5.48xlarge");
let mut paginator = client
.describe_spot_price_history()
diff --git a/aws/sdk/integration-tests/glacier/tests/custom-headers.rs b/aws/sdk/integration-tests/glacier/tests/custom-headers.rs
index 15f6169c85..d336dd1855 100644
--- a/aws/sdk/integration-tests/glacier/tests/custom-headers.rs
+++ b/aws/sdk/integration-tests/glacier/tests/custom-headers.rs
@@ -14,9 +14,10 @@ async fn set_correct_headers() {
let conf = aws_sdk_glacier::Config::builder()
.region(Region::new("us-east-1"))
.credentials_provider(Credentials::new("key", "secret", None, None, "test"))
+ .http_connector(conn)
.build();
- let client = aws_sdk_glacier::Client::from_conf_conn(conf, conn);
+ let client = aws_sdk_glacier::Client::from_conf(conf);
let _resp = client
.upload_archive()
.vault_name("vault")
diff --git a/aws/sdk/integration-tests/kms/tests/integration.rs b/aws/sdk/integration-tests/kms/tests/integration.rs
index df04b3c569..c11e931b7b 100644
--- a/aws/sdk/integration-tests/kms/tests/integration.rs
+++ b/aws/sdk/integration-tests/kms/tests/integration.rs
@@ -43,8 +43,9 @@ async fn generate_random_cn() {
let conf = Config::builder()
.region(Region::new("cn-north-1"))
.credentials_provider(creds)
+ .http_connector(conn.clone())
.build();
- let client = kms::Client::from_conf_conn(conf, conn.clone());
+ let client = kms::Client::from_conf(conf);
let _ = client
.generate_random()
.number_of_bytes(64)
diff --git a/aws/sdk/integration-tests/s3/tests/alternative-async-runtime.rs b/aws/sdk/integration-tests/s3/tests/alternative-async-runtime.rs
index 1526a6d32a..8682bc7ace 100644
--- a/aws/sdk/integration-tests/s3/tests/alternative-async-runtime.rs
+++ b/aws/sdk/integration-tests/s3/tests/alternative-async-runtime.rs
@@ -82,11 +82,12 @@ async fn timeout_test(sleep_impl: Arc) -> Result<(), Box) -> Result<(), Box) -> Result<(), Box = CoreClient;
+use std::{
+ convert::Infallible,
+ time::{Duration, UNIX_EPOCH},
+};
/// Test connection for the movies IT
/// headers are signed with actual creds, at some point we could replace them with verifiable test
@@ -65,37 +52,43 @@ async fn test_checksum_on_streaming_response(
checksum_header_name: &'static str,
checksum_header_value: &'static str,
) -> GetObjectOutput {
- let creds = Credentials::new(
- "ANOTREAL",
- "notrealrnrELgWzOk3IfjzDKtFBhDby",
- Some("notarealsessiontoken".to_string()),
- None,
- "test",
- );
- let conf = aws_sdk_s3::Config::builder()
- .credentials_provider(creds)
- .region(Region::new("us-east-1"))
- .build();
let conn = new_checksum_validated_response_test_connection(
checksum_header_name,
checksum_header_value,
);
- let client = Client::new(conn.clone());
+ let sdk_config = SdkConfig::builder()
+ .credentials_provider(SharedCredentialsProvider::new(Credentials::new(
+ "ANOTREAL",
+ "notrealrnrELgWzOk3IfjzDKtFBhDby",
+ Some("notarealsessiontoken".to_string()),
+ None,
+ "test",
+ )))
+ .region(Region::new("us-east-1"))
+ .http_connector(conn.clone())
+ .build();
- let mut op = GetObject::builder()
+ let client = Client::new(&sdk_config);
+
+ let res = client
+ .get_object()
.bucket("some-test-bucket")
.key("test.txt")
.checksum_mode(aws_sdk_s3::model::ChecksumMode::Enabled)
- .build()
+ .customize()
+ .await
+ .unwrap()
+ .map_operation(|mut op| {
+ op.properties_mut()
+ .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
+ op.properties_mut().insert(AwsUserAgent::for_tests());
+
+ Result::Ok::<_, Infallible>(op)
+ })
.unwrap()
- .make_operation(&conf)
+ .send()
.await
.unwrap();
- op.properties_mut()
- .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
- op.properties_mut().insert(AwsUserAgent::for_tests());
-
- let res = client.call(op).await.unwrap();
conn.assert_requests_match(&[http::header::HeaderName::from_static("x-amz-checksum-mode")]);
@@ -164,21 +157,20 @@ async fn test_checksum_on_streaming_request<'a>(
expected_encoded_content_length: &'a str,
expected_aws_chunked_encoded_body: &'a str,
) {
- let creds = aws_sdk_s3::Credentials::new(
- "ANOTREAL",
- "notrealrnrELgWzOk3IfjzDKtFBhDby",
- Some("notarealsessiontoken".to_string()),
- None,
- "test",
- );
- let conf = aws_sdk_s3::Config::builder()
- .credentials_provider(creds)
- .region(aws_sdk_s3::Region::new("us-east-1"))
- .build();
let (conn, rcvr) = capture_request(None);
+ let sdk_config = SdkConfig::builder()
+ .credentials_provider(SharedCredentialsProvider::new(Credentials::new(
+ "ANOTREAL",
+ "notrealrnrELgWzOk3IfjzDKtFBhDby",
+ Some("notarealsessiontoken".to_string()),
+ None,
+ "test",
+ )))
+ .region(Region::new("us-east-1"))
+ .http_connector(conn.clone())
+ .build();
- let client: aws_smithy_client::Client<_, aws_sdk_s3::middleware::DefaultMiddleware> =
- aws_smithy_client::Client::new(conn.clone());
+ let client = Client::new(&sdk_config);
// ByteStreams created from a file are streaming and have a known size
let mut file = tempfile::NamedTempFile::new().unwrap();
@@ -192,23 +184,29 @@ async fn test_checksum_on_streaming_request<'a>(
.await
.unwrap();
- let mut op = PutObject::builder()
+ // The response from the fake connection won't return the expected XML but we don't care about
+ // that error in this test
+ let _ = client
+ .put_object()
.bucket("test-bucket")
.key("test.txt")
.body(body)
.checksum_algorithm(checksum_algorithm)
- .build()
+ .customize()
+ .await
+ .unwrap()
+ .map_operation(|mut op| {
+ op.properties_mut()
+ .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
+ op.properties_mut().insert(AwsUserAgent::for_tests());
+
+ Result::Ok::<_, Infallible>(op)
+ })
.unwrap()
- .make_operation(&conf)
+ .send()
.await
- .expect("failed to construct operation");
- op.properties_mut()
- .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
- op.properties_mut().insert(AwsUserAgent::for_tests());
+ .unwrap();
- // The response from the fake connection won't return the expected XML but we don't care about
- // that error in this test
- let _ = client.call(op).await;
let req = rcvr.expect_request();
let headers = req.headers();
diff --git a/aws/sdk/integration-tests/s3/tests/customizable-operation.rs b/aws/sdk/integration-tests/s3/tests/customizable-operation.rs
index b5ed6787d2..e68b07a8da 100644
--- a/aws/sdk/integration-tests/s3/tests/customizable-operation.rs
+++ b/aws/sdk/integration-tests/s3/tests/customizable-operation.rs
@@ -3,32 +3,31 @@
* SPDX-License-Identifier: Apache-2.0
*/
+use aws_config::SdkConfig;
use aws_http::user_agent::AwsUserAgent;
-use aws_sdk_s3::{Credentials, Region};
-use aws_smithy_async::rt::sleep::TokioSleep;
+use aws_sdk_s3::{Client, Credentials, Region};
use aws_smithy_client::test_connection::capture_request;
+use aws_types::credentials::SharedCredentialsProvider;
use std::convert::Infallible;
-use std::sync::Arc;
use std::time::{Duration, UNIX_EPOCH};
#[tokio::test]
-async fn test_s3_ops_are_customizable() -> Result<(), aws_sdk_s3::Error> {
- let creds = Credentials::new(
- "ANOTREAL",
- "notrealrnrELgWzOk3IfjzDKtFBhDby",
- Some("notarealsessiontoken".to_string()),
- None,
- "test",
- );
- let conf = aws_sdk_s3::Config::builder()
- .credentials_provider(creds)
+async fn test_s3_ops_are_customizable() {
+ let (conn, rcvr) = capture_request(None);
+ let sdk_config = SdkConfig::builder()
+ .credentials_provider(SharedCredentialsProvider::new(Credentials::new(
+ "ANOTREAL",
+ "notrealrnrELgWzOk3IfjzDKtFBhDby",
+ Some("notarealsessiontoken".to_string()),
+ None,
+ "test",
+ )))
.region(Region::new("us-east-1"))
- .sleep_impl(Arc::new(TokioSleep::new()))
+ .http_connector(conn.clone())
.build();
- let (conn, rcvr) = capture_request(None);
- let client = aws_sdk_s3::Client::from_conf_conn(conf, conn);
+ let client = Client::new(&sdk_config);
let op = client
.list_buckets()
@@ -70,6 +69,4 @@ async fn test_s3_ops_are_customizable() -> Result<(), aws_sdk_s3::Error> {
auth_header.to_str().unwrap(),
snapshot_signature
);
-
- Ok(())
}
diff --git a/aws/sdk/integration-tests/s3/tests/ignore-invalid-xml-body-root.rs b/aws/sdk/integration-tests/s3/tests/ignore-invalid-xml-body-root.rs
index 6c1f6db5c0..beabefea95 100644
--- a/aws/sdk/integration-tests/s3/tests/ignore-invalid-xml-body-root.rs
+++ b/aws/sdk/integration-tests/s3/tests/ignore-invalid-xml-body-root.rs
@@ -4,22 +4,19 @@
*/
use aws_http::user_agent::AwsUserAgent;
-use aws_sdk_s3::{
- middleware::DefaultMiddleware, model::ObjectAttributes, operation::GetObjectAttributes,
- Credentials, Region,
-};
-use aws_smithy_client::{test_connection::TestConnection, Client as CoreClient};
+use aws_sdk_s3::{model::ObjectAttributes, Client, Credentials, Region};
+use aws_smithy_client::test_connection::TestConnection;
use aws_smithy_http::body::SdkBody;
-use std::time::{Duration, UNIX_EPOCH};
-
-pub type Client = CoreClient;
+use aws_types::{credentials::SharedCredentialsProvider, SdkConfig};
+use std::{
+ convert::Infallible,
+ time::{Duration, UNIX_EPOCH},
+};
const RESPONSE_BODY_XML: &[u8] = b"\ne1AsOh9IyGCa4hLN+2Od7jlnP14=";
#[tokio::test]
async fn ignore_invalid_xml_body_root() {
- tracing_subscriber::fmt::init();
-
let conn = TestConnection::new(vec![
(http::Request::builder()
.header("x-amz-object-attributes", "Checksum")
@@ -45,35 +42,39 @@ async fn ignore_invalid_xml_body_root() {
.body(RESPONSE_BODY_XML)
.unwrap())
]);
- let creds = Credentials::new(
- "ANOTREAL",
- "notrealrnrELgWzOk3IfjzDKtFBhDby",
- Some("notarealsessiontoken".to_string()),
- None,
- "test",
- );
- let conf = aws_sdk_s3::Config::builder()
- .credentials_provider(creds)
+
+ let sdk_config = SdkConfig::builder()
+ .credentials_provider(SharedCredentialsProvider::new(Credentials::new(
+ "ANOTREAL",
+ "notrealrnrELgWzOk3IfjzDKtFBhDby",
+ Some("notarealsessiontoken".to_string()),
+ None,
+ "test",
+ )))
.region(Region::new("us-east-1"))
+ .http_connector(conn.clone())
.build();
- let client = Client::new(conn.clone());
+ let client = Client::new(&sdk_config);
- let mut op = GetObjectAttributes::builder()
+ let _ = client
+ .get_object_attributes()
.bucket("some-test-bucket")
.key("test.txt")
.object_attributes(ObjectAttributes::Checksum)
- .build()
+ .customize()
+ .await
+ .unwrap()
+ .map_operation(|mut op| {
+ op.properties_mut()
+ .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
+ op.properties_mut().insert(AwsUserAgent::for_tests());
+
+ Result::Ok::<_, Infallible>(op)
+ })
.unwrap()
- .make_operation(&conf)
+ .send()
.await
.unwrap();
- op.properties_mut()
- .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
- op.properties_mut().insert(AwsUserAgent::for_tests());
-
- let res = client.call(op).await.unwrap();
conn.assert_requests_match(&[]);
-
- println!("res: {:#?}", res)
}
diff --git a/aws/sdk/integration-tests/s3/tests/naughty-string-metadata.rs b/aws/sdk/integration-tests/s3/tests/naughty-string-metadata.rs
index 8b4e90c2e3..05259f9774 100644
--- a/aws/sdk/integration-tests/s3/tests/naughty-string-metadata.rs
+++ b/aws/sdk/integration-tests/s3/tests/naughty-string-metadata.rs
@@ -4,16 +4,14 @@
*/
use aws_http::user_agent::AwsUserAgent;
-use aws_sdk_s3::middleware::DefaultMiddleware;
-use aws_sdk_s3::operation::PutObject;
-use aws_sdk_s3::types::ByteStream;
-use aws_sdk_s3::{Credentials, Region};
+use aws_sdk_s3::{types::ByteStream, Client, Credentials, Region};
use aws_smithy_client::test_connection::capture_request;
-use aws_smithy_client::Client as CoreClient;
+use aws_types::{credentials::SharedCredentialsProvider, SdkConfig};
use http::HeaderValue;
-use std::time::UNIX_EPOCH;
-use tokio::time::Duration;
-pub type Client = CoreClient;
+use std::{
+ convert::Infallible,
+ time::{Duration, UNIX_EPOCH},
+};
const NAUGHTY_STRINGS: &str = include_str!("blns/blns.txt");
@@ -52,22 +50,23 @@ const NAUGHTY_STRINGS: &str = include_str!("blns/blns.txt");
// }
#[tokio::test]
-async fn test_s3_signer_with_naughty_string_metadata() -> Result<(), aws_sdk_s3::Error> {
- let creds = Credentials::new(
- "ANOTREAL",
- "notrealrnrELgWzOk3IfjzDKtFBhDby",
- Some("notarealsessiontoken".to_string()),
- None,
- "test",
- );
- let conf = aws_sdk_s3::Config::builder()
- .credentials_provider(creds)
+async fn test_s3_signer_with_naughty_string_metadata() {
+ let (conn, rcvr) = capture_request(None);
+ let sdk_config = SdkConfig::builder()
+ .credentials_provider(SharedCredentialsProvider::new(Credentials::new(
+ "ANOTREAL",
+ "notrealrnrELgWzOk3IfjzDKtFBhDby",
+ Some("notarealsessiontoken".to_string()),
+ None,
+ "test",
+ )))
.region(Region::new("us-east-1"))
+ .http_connector(conn.clone())
.build();
- let (conn, rcvr) = capture_request(None);
- let client = Client::new(conn.clone());
- let mut builder = PutObject::builder()
+ let client = Client::new(&sdk_config);
+ let mut builder = client
+ .put_object()
.bucket("test-bucket")
.key("text.txt")
.body(ByteStream::from_static(b"some test text"));
@@ -82,17 +81,21 @@ async fn test_s3_signer_with_naughty_string_metadata() -> Result<(), aws_sdk_s3:
}
}
- let mut op = builder
- .build()
+ let _ = builder
+ .customize()
+ .await
+ .unwrap()
+ .map_operation(|mut op| {
+ op.properties_mut()
+ .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
+ op.properties_mut().insert(AwsUserAgent::for_tests());
+
+ Result::Ok::<_, Infallible>(op)
+ })
.unwrap()
- .make_operation(&conf)
+ .send()
.await
.unwrap();
- op.properties_mut()
- .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
- op.properties_mut().insert(AwsUserAgent::for_tests());
-
- client.call(op).await.unwrap();
let expected_req = rcvr.expect_request();
let auth_header = expected_req
@@ -113,6 +116,4 @@ async fn test_s3_signer_with_naughty_string_metadata() -> Result<(), aws_sdk_s3:
auth_header.to_str().unwrap(),
snapshot_signature
);
-
- Ok(())
}
diff --git a/aws/sdk/integration-tests/s3/tests/query-strings-are-correctly-encoded.rs b/aws/sdk/integration-tests/s3/tests/query-strings-are-correctly-encoded.rs
index 8a898524e8..73584521e0 100644
--- a/aws/sdk/integration-tests/s3/tests/query-strings-are-correctly-encoded.rs
+++ b/aws/sdk/integration-tests/s3/tests/query-strings-are-correctly-encoded.rs
@@ -3,51 +3,53 @@
* SPDX-License-Identifier: Apache-2.0
*/
+use aws_config::SdkConfig;
use aws_http::user_agent::AwsUserAgent;
-use aws_sdk_s3::middleware::DefaultMiddleware;
-use aws_sdk_s3::operation::ListObjectsV2;
-use aws_sdk_s3::{Credentials, Region};
+use aws_sdk_s3::{Client, Credentials, Region};
use aws_smithy_client::test_connection::capture_request;
-use aws_smithy_client::Client as CoreClient;
+use aws_types::credentials::SharedCredentialsProvider;
+use std::convert::Infallible;
use std::time::{Duration, UNIX_EPOCH};
-pub type Client = CoreClient;
-
#[tokio::test]
-async fn test_s3_signer_query_string_with_all_valid_chars() -> Result<(), aws_sdk_s3::Error> {
- let creds = Credentials::new(
- "ANOTREAL",
- "notrealrnrELgWzOk3IfjzDKtFBhDby",
- Some("notarealsessiontoken".to_string()),
- None,
- "test",
- );
- let conf = aws_sdk_s3::Config::builder()
- .credentials_provider(creds)
+async fn test_s3_signer_query_string_with_all_valid_chars() {
+ let (conn, rcvr) = capture_request(None);
+ let sdk_config = SdkConfig::builder()
+ .credentials_provider(SharedCredentialsProvider::new(Credentials::new(
+ "ANOTREAL",
+ "notrealrnrELgWzOk3IfjzDKtFBhDby",
+ Some("notarealsessiontoken".to_string()),
+ None,
+ "test",
+ )))
.region(Region::new("us-east-1"))
+ .http_connector(conn.clone())
.build();
- let (conn, rcvr) = capture_request(None);
- let client = Client::new(conn.clone());
+ let client = Client::new(&sdk_config);
// Generate a string containing all printable ASCII chars
let prefix: String = (32u8..127).map(char::from).collect();
- let mut op = ListObjectsV2::builder()
+ // The response from the fake connection won't return the expected XML but we don't care about
+ // that error in this test
+ let _ = client
+ .list_objects_v2()
.bucket("test-bucket")
.prefix(&prefix)
- .build()
- .unwrap()
- .make_operation(&conf)
+ .customize()
.await
- .expect("failed to construct operation");
- op.properties_mut()
- .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
- op.properties_mut().insert(AwsUserAgent::for_tests());
+ .unwrap()
+ .map_operation(|mut op| {
+ op.properties_mut()
+ .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
+ op.properties_mut().insert(AwsUserAgent::for_tests());
- // The response from the fake connection won't return the expected XML but we don't care about
- // that error in this test
- let _ = client.call(op).await;
+ Result::Ok::<_, Infallible>(op)
+ })
+ .unwrap()
+ .send()
+ .await;
let expected_req = rcvr.expect_request();
let auth_header = expected_req
@@ -68,21 +70,19 @@ async fn test_s3_signer_query_string_with_all_valid_chars() -> Result<(), aws_sd
auth_header.to_str().unwrap(),
snapshot_signature
);
-
- Ok(())
}
// This test can help identify individual characters that break the signing of query strings. This
// test must be run against an actual bucket so we `ignore` it unless the runner specifically requests it
#[tokio::test]
#[ignore]
-async fn test_query_strings_are_correctly_encoded() -> Result<(), aws_sdk_s3::Error> {
+async fn test_query_strings_are_correctly_encoded() {
use aws_sdk_s3::error::{ListObjectsV2Error, ListObjectsV2ErrorKind};
use aws_smithy_http::result::SdkError;
tracing_subscriber::fmt::init();
let config = aws_config::load_from_env().await;
- let client = aws_sdk_s3::Client::new(&config);
+ let client = Client::new(&config);
let mut chars_that_break_signing = Vec::new();
let mut chars_that_break_uri_parsing = Vec::new();
@@ -128,41 +128,42 @@ async fn test_query_strings_are_correctly_encoded() -> Result<(), aws_sdk_s3::Er
&& chars_that_break_uri_parsing.is_empty()
&& chars_that_are_invalid_arguments.is_empty()
{
- Ok(())
- } else {
- fn char_transform(c: u8) -> String {
- format!("byte {}: {}\n", c, char::from(c))
- }
- if !chars_that_break_signing.is_empty() {
- tracing::error!(
- "The following characters caused a signature mismatch:\n{}(end)",
- chars_that_break_signing
- .clone()
- .into_iter()
- .map(char_transform)
- .collect::()
- );
- }
- if !chars_that_break_uri_parsing.is_empty() {
- tracing::error!(
- "The following characters caused a URI parse failure:\n{}(end)",
- chars_that_break_uri_parsing
- .clone()
- .into_iter()
- .map(char_transform)
- .collect::()
- );
- }
- if !chars_that_are_invalid_arguments.is_empty() {
- tracing::error!(
- "The following characters caused an \"Invalid Argument\" failure:\n{}(end)",
- chars_that_are_invalid_arguments
- .clone()
- .into_iter()
- .map(char_transform)
- .collect::()
- );
- }
- panic!("test failed, see logs for the problem chars")
+ return;
}
+
+ fn char_transform(c: u8) -> String {
+ format!("byte {}: {}\n", c, char::from(c))
+ }
+ if !chars_that_break_signing.is_empty() {
+ eprintln!(
+ "The following characters caused a signature mismatch:\n{}(end)",
+ chars_that_break_signing
+ .clone()
+ .into_iter()
+ .map(char_transform)
+ .collect::()
+ );
+ }
+ if !chars_that_break_uri_parsing.is_empty() {
+ eprintln!(
+ "The following characters caused a URI parse failure:\n{}(end)",
+ chars_that_break_uri_parsing
+ .clone()
+ .into_iter()
+ .map(char_transform)
+ .collect::()
+ );
+ }
+ if !chars_that_are_invalid_arguments.is_empty() {
+ eprintln!(
+ "The following characters caused an \"Invalid Argument\" failure:\n{}(end)",
+ chars_that_are_invalid_arguments
+ .clone()
+ .into_iter()
+ .map(char_transform)
+ .collect::()
+ );
+ }
+
+ panic!("test failed due to invalid characters")
}
diff --git a/aws/sdk/integration-tests/s3/tests/recursion-detection.rs b/aws/sdk/integration-tests/s3/tests/recursion-detection.rs
index 07a1f2eaed..fb7f70db5f 100644
--- a/aws/sdk/integration-tests/s3/tests/recursion-detection.rs
+++ b/aws/sdk/integration-tests/s3/tests/recursion-detection.rs
@@ -3,8 +3,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
-use aws_sdk_s3::{Credentials, Region};
+use aws_config::SdkConfig;
+use aws_sdk_s3::{Client, Credentials, Region};
use aws_smithy_client::test_connection::capture_request;
+use aws_types::credentials::SharedCredentialsProvider;
use http::HeaderValue;
#[tokio::test]
@@ -12,20 +14,19 @@ async fn recursion_detection_applied() {
std::env::set_var("AWS_LAMBDA_FUNCTION_NAME", "some-function");
std::env::set_var("_X_AMZN_TRACE_ID", "traceid");
let (conn, captured_request) = capture_request(None);
-
- let creds = Credentials::new(
- "ANOTREAL",
- "notrealrnrELgWzOk3IfjzDKtFBhDby",
- Some("notarealsessiontoken".to_string()),
- None,
- "test",
- );
- let conf = aws_sdk_s3::Config::builder()
- .credentials_provider(creds)
+ let sdk_config = SdkConfig::builder()
+ .credentials_provider(SharedCredentialsProvider::new(Credentials::new(
+ "ANOTREAL",
+ "notrealrnrELgWzOk3IfjzDKtFBhDby",
+ Some("notarealsessiontoken".to_string()),
+ None,
+ "test",
+ )))
.region(Region::new("us-east-1"))
+ .http_connector(conn.clone())
.build();
- let client = aws_sdk_s3::Client::from_conf_conn(conf, conn);
- let _response = client.list_objects_v2().bucket("test-bucket").send().await;
+ let client = Client::new(&sdk_config);
+ let _ = client.list_objects_v2().bucket("test-bucket").send().await;
assert_eq!(
captured_request
.expect_request()
diff --git a/aws/sdk/integration-tests/s3/tests/select-object-content.rs b/aws/sdk/integration-tests/s3/tests/select-object-content.rs
index d882b7644f..69e81c4948 100644
--- a/aws/sdk/integration-tests/s3/tests/select-object-content.rs
+++ b/aws/sdk/integration-tests/s3/tests/select-object-content.rs
@@ -3,28 +3,30 @@
* SPDX-License-Identifier: Apache-2.0
*/
+use aws_config::SdkConfig;
use aws_sdk_s3::model::{
CompressionType, CsvInput, CsvOutput, ExpressionType, FileHeaderInfo, InputSerialization,
OutputSerialization, SelectObjectContentEventStream,
};
-use aws_sdk_s3::{Client, Config, Credentials, Region};
+use aws_sdk_s3::{Client, Credentials, Region};
use aws_smithy_client::dvr::{Event, ReplayingConnection};
use aws_smithy_protocol_test::{assert_ok, validate_body, MediaType};
-use std::error::Error as StdError;
+use aws_types::credentials::SharedCredentialsProvider;
+use std::error::Error;
#[tokio::test]
async fn test_success() {
let events: Vec =
serde_json::from_str(include_str!("select-object-content.json")).unwrap();
let replayer = ReplayingConnection::new(events);
-
- let region = Region::from_static("us-east-2");
- let credentials = Credentials::new("test", "test", None, None, "test");
- let config = Config::builder()
- .region(region)
- .credentials_provider(credentials)
+ let sdk_config = SdkConfig::builder()
+ .region(Region::from_static("us-east-2"))
+ .credentials_provider(SharedCredentialsProvider::new(Credentials::new(
+ "test", "test", None, None, "test",
+ )))
+ .http_connector(replayer.clone())
.build();
- let client = Client::from_conf_conn(config, replayer.clone());
+ let client = Client::new(&sdk_config);
let mut output = client
.select_object_content()
@@ -88,7 +90,7 @@ async fn test_success() {
.unwrap();
}
-fn body_validator(expected_body: &[u8], actual_body: &[u8]) -> Result<(), Box> {
+fn body_validator(expected_body: &[u8], actual_body: &[u8]) -> Result<(), Box> {
let expected = std::str::from_utf8(expected_body).unwrap();
let actual = std::str::from_utf8(actual_body).unwrap();
assert_ok(validate_body(actual, expected, MediaType::Xml));
diff --git a/aws/sdk/integration-tests/s3/tests/signing-it.rs b/aws/sdk/integration-tests/s3/tests/signing-it.rs
index d72c093ade..45f200f6e3 100644
--- a/aws/sdk/integration-tests/s3/tests/signing-it.rs
+++ b/aws/sdk/integration-tests/s3/tests/signing-it.rs
@@ -3,29 +3,17 @@
* SPDX-License-Identifier: Apache-2.0
*/
+use aws_config::SdkConfig;
use aws_http::user_agent::AwsUserAgent;
-use aws_sdk_s3::middleware::DefaultMiddleware;
-use aws_sdk_s3::operation::ListObjectsV2;
-use aws_sdk_s3::{Credentials, Region};
+use aws_sdk_s3::{Client, Credentials, Region};
use aws_smithy_client::test_connection::TestConnection;
-use aws_smithy_client::Client as CoreClient;
use aws_smithy_http::body::SdkBody;
+use aws_types::credentials::SharedCredentialsProvider;
+use std::convert::Infallible;
use std::time::{Duration, UNIX_EPOCH};
-pub type Client = CoreClient;
#[tokio::test]
-async fn test_signer() -> Result<(), aws_sdk_s3::Error> {
- let creds = Credentials::new(
- "ANOTREAL",
- "notrealrnrELgWzOk3IfjzDKtFBhDby",
- Some("notarealsessiontoken".to_string()),
- None,
- "test",
- );
- let conf = aws_sdk_s3::Config::builder()
- .credentials_provider(creds)
- .region(Region::new("us-east-1"))
- .build();
+async fn test_signer() {
let conn = TestConnection::new(vec![(
http::Request::builder()
.header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20210618/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent, Signature=6233614b69271e15db079287874a654183916e509909b5719b00cd8d5f31299e")
@@ -34,20 +22,35 @@ async fn test_signer() -> Result<(), aws_sdk_s3::Error> {
.unwrap(),
http::Response::builder().status(200).body("").unwrap(),
)]);
- let client = Client::new(conn.clone());
- let mut op = ListObjectsV2::builder()
+ let sdk_config = SdkConfig::builder()
+ .credentials_provider(SharedCredentialsProvider::new(Credentials::new(
+ "ANOTREAL",
+ "notrealrnrELgWzOk3IfjzDKtFBhDby",
+ Some("notarealsessiontoken".to_string()),
+ None,
+ "test",
+ )))
+ .region(Region::new("us-east-1"))
+ .http_connector(conn.clone())
+ .build();
+ let client = Client::new(&sdk_config);
+ let _ = client
+ .list_objects_v2()
.bucket("test-bucket")
.prefix("prefix~")
- .build()
- .unwrap()
- .make_operation(&conf)
+ .customize()
.await
- .unwrap();
- op.properties_mut()
- .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
- op.properties_mut().insert(AwsUserAgent::for_tests());
+ .unwrap()
+ .map_operation(|mut op| {
+ op.properties_mut()
+ .insert(UNIX_EPOCH + Duration::from_secs(1624036048));
+ op.properties_mut().insert(AwsUserAgent::for_tests());
+
+ Result::Ok::<_, Infallible>(op)
+ })
+ .unwrap()
+ .send()
+ .await;
- client.call(op).await.expect_err("empty response");
conn.assert_requests_match(&[]);
- Ok(())
}
diff --git a/aws/sdk/integration-tests/s3/tests/streaming-response.rs b/aws/sdk/integration-tests/s3/tests/streaming-response.rs
index 6105fc6d7a..0b5d17a95b 100644
--- a/aws/sdk/integration-tests/s3/tests/streaming-response.rs
+++ b/aws/sdk/integration-tests/s3/tests/streaming-response.rs
@@ -3,7 +3,9 @@
* SPDX-License-Identifier: Apache-2.0
*/
-use aws_sdk_s3::{Credentials, Endpoint, Region};
+use aws_config::SdkConfig;
+use aws_sdk_s3::{Client, Credentials, Endpoint, Region};
+use aws_types::credentials::SharedCredentialsProvider;
use bytes::BytesMut;
use std::future::Future;
use std::net::SocketAddr;
@@ -21,23 +23,21 @@ async fn test_streaming_response_fails_when_eof_comes_before_content_length_reac
let (server, server_addr) = start_faulty_server().await;
let _ = tokio::spawn(server);
- let creds = Credentials::new(
- "ANOTREAL",
- "notrealrnrELgWzOk3IfjzDKtFBhDby",
- Some("notarealsessiontoken".to_string()),
- None,
- "test",
- );
-
- let conf = aws_sdk_s3::Config::builder()
- .credentials_provider(creds)
+ let sdk_config = SdkConfig::builder()
+ .credentials_provider(SharedCredentialsProvider::new(Credentials::new(
+ "ANOTREAL",
+ "notrealrnrELgWzOk3IfjzDKtFBhDby",
+ Some("notarealsessiontoken".to_string()),
+ None,
+ "test",
+ )))
.region(Region::new("us-east-1"))
.endpoint_resolver(Endpoint::immutable(
format!("http://{server_addr}").parse().expect("valid URI"),
))
.build();
- let client = aws_sdk_s3::client::Client::from_conf(conf);
+ let client = Client::new(&sdk_config);
// This will succeed b/c the head of the response is fine.
let res = client
diff --git a/aws/sdk/integration-tests/s3/tests/timeouts.rs b/aws/sdk/integration-tests/s3/tests/timeouts.rs
index f444c63c22..5a8cd08dba 100644
--- a/aws/sdk/integration-tests/s3/tests/timeouts.rs
+++ b/aws/sdk/integration-tests/s3/tests/timeouts.rs
@@ -8,14 +8,14 @@ use aws_sdk_s3::model::{
CompressionType, CsvInput, CsvOutput, ExpressionType, FileHeaderInfo, InputSerialization,
OutputSerialization,
};
-use aws_sdk_s3::{Client, Config, Credentials, Endpoint, Region};
+use aws_sdk_s3::{Client, Credentials, Endpoint, Region};
use aws_smithy_async::assert_elapsed;
-use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep, TokioSleep};
-use aws_smithy_client::never::NeverService;
-use aws_smithy_http::body::SdkBody;
-use aws_smithy_http::result::ConnectorError;
+use aws_smithy_async::rt::sleep::{default_async_sleep, TokioSleep};
+use aws_smithy_client::never::NeverConnector;
use aws_smithy_types::timeout::TimeoutConfig;
use aws_types::credentials::SharedCredentialsProvider;
+use std::future::Future;
+use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
use tokio::net::TcpListener;
@@ -23,21 +23,20 @@ use tokio::time::timeout;
#[tokio::test(start_paused = true)]
async fn test_timeout_service_ends_request_that_never_completes() {
- let conn: NeverService, http::Response, ConnectorError> =
- NeverService::new();
- let region = Region::from_static("us-east-2");
- let credentials = Credentials::new("test", "test", None, None, "test");
- let timeout_config = TimeoutConfig::builder()
- .operation_timeout(Duration::from_secs_f32(0.5))
- .build();
- let sleep_impl: Arc = Arc::new(TokioSleep::new());
- let config = Config::builder()
- .region(region)
- .credentials_provider(credentials)
- .timeout_config(timeout_config)
- .sleep_impl(sleep_impl)
+ let sdk_config = SdkConfig::builder()
+ .region(Region::from_static("us-east-2"))
+ .credentials_provider(SharedCredentialsProvider::new(Credentials::new(
+ "test", "test", None, None, "test",
+ )))
+ .http_connector(NeverConnector::new())
+ .timeout_config(
+ TimeoutConfig::builder()
+ .operation_timeout(Duration::from_secs_f32(0.5))
+ .build(),
+ )
+ .sleep_impl(Arc::new(TokioSleep::new()))
.build();
- let client = Client::from_conf_conn(config, conn.clone());
+ let client = Client::new(&sdk_config);
let now = tokio::time::Instant::now();
@@ -72,18 +71,29 @@ async fn test_timeout_service_ends_request_that_never_completes() {
#[tokio::test]
async fn test_read_timeout() {
- async fn run_server(mut shutdown_receiver: tokio::sync::oneshot::Receiver<()>) {
- let listener = TcpListener::bind("127.0.0.1:18103").await.unwrap();
- while shutdown_receiver.try_recv().is_err() {
- if let Ok(result) = timeout(Duration::from_millis(100), listener.accept()).await {
- if let Ok((_socket, _)) = result {
- tokio::time::sleep(Duration::from_millis(1000)).await;
+ async fn run_server(
+ mut shutdown_receiver: tokio::sync::oneshot::Receiver<()>,
+ ) -> (impl Future