Skip to content

Commit

Permalink
refactor hyper1 client builder to allow multiple TLS providers and ad…
Browse files Browse the repository at this point in the history
…d new config (#3914)

## Motivation and Context
Yet another follow up to:
#3866

## Description
* Refactor the hyper 1 implementation into multiple modules to make it
(slightly) easier to navigate (separating TLS, DNS, and timeout concerns
into new/separate modules)
* Refactors the hyper 1 implementation to allow for additional TLS
provider implementations (e.g. s2n). Before we just exposed a
`CryptoMode` but that is only applicable to rustls. I've swapped this
for a new `TlsProvider` concept
* Refactored how connectors are built. Before we were taking a TLS
connector and wrapping it (via `Connector`). But this is structurally
awkward since our `Connector` is analogous to hyper_utils'
[`HttpConnector`](https://docs.rs/hyper-util/latest/hyper_util/client/legacy/connect/struct.HttpConnector.html#)
(or supposed to be anyway). The updated structure forces our `Connector`
to build the `HttpConnector` (which is the lowest layer/TCP connector)
and then (if enabled) wrap it in TLS, and then finally wrap it with the
SDK timeouts.
```
// build function returns a connector that looks like this as far as layering goes:
Connector<TlsProviderSelected>.build() -> SdkTimeouts(TlsConnector(HttpConnector))
```

* Exposed additional builder setting for `TCP_NODELAY` (and defaulted it
to true).
* Exposed additional builder setting for binding to a specific NIC
* Fixed feature flags (powerset build was failing locally due to invalid
or misconfigured feature flag application)
* Renamed TLS feature flags to be associated with the underlying TLS lib
(e.g. `crypto-aws-lc` -> `rustls-aws-lc`)

**NOTE**: Apologies in advance, the diff didn't quite come out as I
wanted. `client.rs` replaced `hyper_1.rs` (several modules of
`hyper_1.rs` were split out into new modules). Everything in
`timeout.rs` and `dns.rs` did not change.

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
  • Loading branch information
aajtodd authored Nov 20, 2024
1 parent 83c606f commit 9833eb2
Show file tree
Hide file tree
Showing 22 changed files with 1,633 additions and 1,329 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class S3TestDependencies(private val codegenContext: ClientCodegenContext) : Lib
override fun section(section: LibRsSection): Writable =
writable {
addDependency(awsConfig(codegenContext.runtimeConfig).toDevDependency().withFeature("behavior-version-latest"))
addDependency(smithyHttpClient(codegenContext.runtimeConfig).toDevDependency().withFeature("crypto-ring"))
addDependency(smithyHttpClient(codegenContext.runtimeConfig).toDevDependency().withFeature("rustls-ring"))
addDependency(AsyncStd)
addDependency(BytesUtils.toDevDependency())
addDependency(FastRand.toDevDependency())
Expand Down
2 changes: 1 addition & 1 deletion aws/sdk/integration-tests/s3/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ aws-smithy-protocol-test = { path = "../../build/aws-sdk/sdk/aws-smithy-protocol
aws-smithy-runtime = { path = "../../build/aws-sdk/sdk/aws-smithy-runtime", features = ["test-util"] }
aws-smithy-runtime-api = { path = "../../build/aws-sdk/sdk/aws-smithy-runtime-api", features = ["test-util", "http-1x"] }
aws-smithy-types = { path = "../../build/aws-sdk/sdk/aws-smithy-types" }
aws-smithy-http-client = { path = "../../build/aws-sdk/sdk/aws-smithy-http-client", features = ["hyper-1", "crypto-ring", "test-util", "wire-mock"] }
aws-smithy-http-client = { path = "../../build/aws-sdk/sdk/aws-smithy-http-client", features = ["hyper-1", "rustls-ring", "test-util", "wire-mock"] }
aws-types = { path = "../../build/aws-sdk/sdk/aws-types" }
bytes = "1"
bytes-utils = "0.1.2"
Expand Down
9 changes: 6 additions & 3 deletions aws/sdk/integration-tests/s3/tests/hyper-10.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
* SPDX-License-Identifier: Apache-2.0
*/

use aws_smithy_http_client::hyper_1::CryptoMode;
use aws_smithy_http_client::tls;
use aws_smithy_runtime_api::client::behavior_version::BehaviorVersion;

#[tokio::test]
#[ignore]
async fn hyper_10_end_to_end() {
let http_client = aws_smithy_http_client::hyper_1::HyperClientBuilder::default()
.crypto_mode(CryptoMode::Ring)
let http_client = aws_smithy_http_client::Builder::new()
.tls_provider(tls::Provider::Rustls(
tls::rustls_provider::CryptoMode::Ring,
))
.build_https();

let conf = aws_config::defaults(BehaviorVersion::latest())
.http_client(http_client)
.load()
Expand Down
42 changes: 24 additions & 18 deletions rust-runtime/aws-smithy-http-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ hyper-014 = [
"dep:hyper-0-14",
]

# FIXME(hyper1) - rename feature
hyper-1 = [
"aws-smithy-runtime-api/http-1x",
"aws-smithy-types/http-body-1-x",
Expand All @@ -24,10 +25,11 @@ hyper-1 = [
"hyper-util?/client-legacy",
"dep:http-1x",
"dep:tower",
]

# FIXME - should not be needed in base http implementation, only for https and only for specific tls impl
"dep:rustls",
"dep:hyper-rustls",
default-tls = [
"hyper-1",
"rustls-aws-lc"
]

wire-mock = [
Expand Down Expand Up @@ -58,31 +60,30 @@ test-util = [
legacy-test-util = [
"test-util",
"dep:http-02x",
"aws-smithy-runtime-api/http-02x"
"aws-smithy-runtime-api/http-02x",
"aws-smithy-types/http-body-0-4-x",
]

legacy-tls-rustls = ["dep:legacy-hyper-rustls", "dep:legacy-rustls", "hyper-014"]
legacy-rustls-ring = ["dep:legacy-hyper-rustls", "dep:legacy-rustls", "hyper-014"]

# FIXME - s2n-tls option, distinguish between rustls and s2n
crypto-ring = ["dep:rustls", "rustls?/ring", "dep:hyper-rustls", "hyper-1"]
crypto-aws-lc = ["dep:rustls", "rustls?/aws_lc_rs", "dep:hyper-rustls", "hyper-1"]
crypto-aws-lc-fips = ["dep:rustls", "rustls?/fips", "dep:hyper-rustls", "hyper-1"]
rustls-ring = ["dep:rustls", "rustls?/ring", "dep:hyper-rustls", "hyper-1"]
rustls-aws-lc = ["dep:rustls", "rustls?/aws_lc_rs", "dep:hyper-rustls", "hyper-1"]
rustls-aws-lc-fips = ["dep:rustls", "rustls?/fips", "dep:hyper-rustls", "hyper-1"]

[dependencies]
aws-smithy-async = { path = "../aws-smithy-async" }
aws-smithy-runtime-api = { path = "../aws-smithy-runtime-api", features = ["client"] }
aws-smithy-types = { path = "../aws-smithy-types" }
aws-smithy-protocol-test = { path = "../aws-smithy-protocol-test", optional = true }
h2 = { version = "0.4", default-features = false }
# FIXME - do we need tokio enabled by default?
tokio = { version = "1.40", features = [] }
once_cell = "1.20.1"
pin-project-lite = "0.2.14"
tracing = "0.1"

# hyper 1.x stack
hyper = { version = "1", features = ["client", "http1", "http2"], optional = true }
hyper-util = { version = "0.1.7", optional = true }
hyper-util = { version = "0.1.7", features = ["http1", "http2"], optional = true }
http-1x = { package = "http", version = "1" , optional = true }
http-body-1x = { package = "http-body", version = "1", optional = true}
hyper-rustls = { version = "0.27", features = ["http2", "http1", "native-tokio", "tls12"], default-features = false, optional = true }
Expand Down Expand Up @@ -115,28 +116,33 @@ tokio = { version = "1", features = ["macros", "rt", "rt-multi-thread", "test-ut

[[example]]
name = "client-ring"
required-features = ["crypto-ring"]
required-features = ["rustls-ring"]
doc-scrape-examples = true

[[example]]
name = "client-aws-lc"
required-features = ["crypto-aws-lc", "crypto-aws-lc-fips"]
required-features = ["rustls-aws-lc", "rustls-aws-lc-fips"]
doc-scrape-examples = true

[[example]]
name = "custom-dns"
required-features = ["crypto-ring"]
required-features = ["rustls-ring"]
doc-scrape-examples = true

[package.metadata.smithy-rs-release-tooling]
stable = true

[package.metadata.docs.rs]
all-features = true
all-features = false
features = [
"hyper-1 ",
"wire-mock",
"test-util",
"rustls-ring",
"rustls-aws-lc",
]

targets = ["x86_64-unknown-linux-gnu"]
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
rustdoc-args = ["--cfg", "docsrs"]
# End of docs.rs metadata

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(crypto_unstable)'] }
17 changes: 10 additions & 7 deletions rust-runtime/aws-smithy-http-client/examples/client-aws-lc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@
* SPDX-License-Identifier: Apache-2.0
*/

use aws_smithy_http_client::hyper_1::{CryptoMode, HyperClientBuilder};
use aws_smithy_http_client::{
tls::{self, rustls_provider::CryptoMode},
Builder,
};

#[tokio::main]
async fn main() {
// feature = crypto-aws-lc
let _client = HyperClientBuilder::new()
.crypto_mode(CryptoMode::AwsLc)
// feature = rustls-aws-lc
let _client = Builder::new()
.tls_provider(tls::Provider::Rustls(CryptoMode::AwsLc))
.build_https();

// feature = crypto-aws-lc-fips
// feature = rustls-aws-lc-fips
// A FIPS client can also be created. Note that this has a more complex build environment required.
let _client = HyperClientBuilder::new()
.crypto_mode(CryptoMode::AwsLcFips)
let _client = Builder::new()
.tls_provider(tls::Provider::Rustls(CryptoMode::AwsLcFips))
.build_https();
}
9 changes: 6 additions & 3 deletions rust-runtime/aws-smithy-http-client/examples/client-ring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/

use aws_smithy_http_client::hyper_1::{CryptoMode, HyperClientBuilder};
use aws_smithy_http_client::{
tls::{self, rustls_provider::CryptoMode},
Builder,
};

fn main() {
let _client = HyperClientBuilder::new()
.crypto_mode(CryptoMode::Ring)
let _client = Builder::new()
.tls_provider(tls::Provider::Rustls(CryptoMode::Ring))
.build_https();
}
9 changes: 6 additions & 3 deletions rust-runtime/aws-smithy-http-client/examples/custom-dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
* SPDX-License-Identifier: Apache-2.0
*/

use aws_smithy_http_client::hyper_1::{CryptoMode, HyperClientBuilder};
use aws_smithy_http_client::{
tls::{self, rustls_provider::CryptoMode},
Builder,
};
use aws_smithy_runtime_api::client::dns::{DnsFuture, ResolveDns};
use std::net::{IpAddr, Ipv4Addr};

Expand All @@ -17,7 +20,7 @@ impl ResolveDns for StaticResolver {
}

fn main() {
let _client = HyperClientBuilder::new()
.crypto_mode(CryptoMode::Ring)
let _client = Builder::new()
.tls_provider(tls::Provider::Rustls(CryptoMode::Ring))
.build_with_resolver(StaticResolver);
}
Loading

0 comments on commit 9833eb2

Please sign in to comment.