diff --git a/design/src/SUMMARY.md b/design/src/SUMMARY.md index ea3bcb65c96e13193c5bf110c8ecf3e8e4ea7995..34933fca19701ba90c9ba902bdf65d6b53ac0739 100644 --- a/design/src/SUMMARY.md +++ b/design/src/SUMMARY.md @@ -6,6 +6,7 @@ - [Transport](transport/overview.md) - [HTTP Operations](transport/operation.md) - [HTTP Middleware](transport/middleware.md) + - [TLS Connector](transport/connector.md) - [Smithy](./smithy/overview.md) - [Simple Shapes](./smithy/simple_shapes.md) diff --git a/design/src/transport/connector.md b/design/src/transport/connector.md index cadbcb6dd5fa2b07f1c48420a379a06e625b9294..edb50d4412d9fdf75f2740478b55019c09a8fd43 100644 --- a/design/src/transport/connector.md +++ b/design/src/transport/connector.md @@ -1,39 +1,7 @@ -The Smithy client provides a default TLS connector, but a custom one can be plugged in. -`rustls` is enabled with the feature flag `rustls`. +The Smithy client provides a default TLS connector, but a custom one can be +plugged in. `rustls` is enabled with the feature flag `rustls`. -The client had previously supported `native-tls`. You can use your custom connector like this. - -Create your connector: - -```rust -/// A `hyper` connector that uses the `native-tls` crate for TLS. To use this in a smithy client, -/// wrap it in a [hyper_ext::Adapter](crate::hyper_ext::Adapter). -pub type NativeTls = hyper_tls::HttpsConnector; - -pub fn native_tls() -> NativeTls { - let mut tls = hyper_tls::native_tls::TlsConnector::builder(); - let tls = tls - .min_protocol_version(Some(hyper_tls::native_tls::Protocol::Tlsv12)) - .build() - .unwrap_or_else(|e| panic!("Error while creating TLS connector: {}", e)); - let mut http = hyper::client::HttpConnector::new(); - http.enforce_http(false); - hyper_tls::HttpsConnector::from((http, tls.into())) -} -``` - -Plug the connector in the client: -```rust -let mut builder = hyper::client::Builder::default(); -builder.pool_max_idle_per_host(70); -let connector = aws_smithy_client::erase::DynConnector::new( - aws_smithy_client::hyper_ext::Adapter::builder() - .hyper_builder(builder) - .connector_settings(std::default::Default::default()) - .build(native_tls()), -); -let raw_client = aws_smithy_client::builder::Builder::new() - .connector(connector) - .middleware_fn(...) - .build_dyn(); -``` +The client had previously (prior to version 0.56.0) supported `native-tls`. You +can continue to use a client whose TLS implementation is backed by `native-tls` +by passing in a custom connector. Check out the `custom_connectors.rs` tests in +the `pokemon-service-tls` example crate. diff --git a/examples/pokemon-service-tls/Cargo.toml b/examples/pokemon-service-tls/Cargo.toml index e1c3b3a0824fad63399a9014921e2f18a5412b5b..9f11a904fc85fdb21f7cdf8d9ca5d6c316633f5c 100644 --- a/examples/pokemon-service-tls/Cargo.toml +++ b/examples/pokemon-service-tls/Cargo.toml @@ -26,8 +26,9 @@ pokemon-service-common = { path = "../pokemon-service-common/" } assert_cmd = "2.0" serial_test = "1.0.0" -# This dependency is only required for testing the `pokemon-service-tls` program. +# These dependencies are only required for testing the `pokemon-service-tls` program. hyper-rustls = { version = "0.24", features = ["http2"] } +hyper-tls = { version = "0.5" } # Local paths aws-smithy-client = { path = "../../rust-runtime/aws-smithy-client/", features = ["rustls"] } diff --git a/examples/pokemon-service-tls/tests/common/mod.rs b/examples/pokemon-service-tls/tests/common/mod.rs index c56c5fe59f92907c33e3b82cbe5b7b43ece2b6d9..0d69407cf73e420c115661e81a8f4967a8ef52c1 100644 --- a/examples/pokemon-service-tls/tests/common/mod.rs +++ b/examples/pokemon-service-tls/tests/common/mod.rs @@ -49,3 +49,33 @@ pub fn client_http2_only() -> Client { .build(); Client::from_conf(config) } + +/// A `hyper` connector that uses the `native-tls` crate for TLS. To use this in a smithy client, +/// wrap it in a [aws_smithy_client::hyper_ext::Adapter]. +pub type NativeTlsConnector = hyper_tls::HttpsConnector; + +fn native_tls_connector() -> NativeTlsConnector { + let cert = hyper_tls::native_tls::Certificate::from_pem( + std::fs::read_to_string(DEFAULT_TEST_CERT) + .expect("could not open certificate") + .as_bytes(), + ) + .expect("could not parse certificate"); + + let tls_connector = hyper_tls::native_tls::TlsConnector::builder() + .min_protocol_version(Some(hyper_tls::native_tls::Protocol::Tlsv12)) + .add_root_certificate(cert) + .build() + .unwrap_or_else(|e| panic!("error while creating TLS connector: {}", e)); + let mut http_connector = hyper::client::HttpConnector::new(); + http_connector.enforce_http(false); + hyper_tls::HttpsConnector::from((http_connector, tls_connector.into())) +} + +pub fn native_tls_client() -> Client { + let config = Config::builder() + .http_connector(Adapter::builder().build(native_tls_connector())) + .endpoint_url(format!("https://{DEFAULT_DOMAIN}:{DEFAULT_PORT}")) + .build(); + Client::from_conf(config) +} diff --git a/examples/pokemon-service-tls/tests/custom_connectors.rs b/examples/pokemon-service-tls/tests/custom_connectors.rs new file mode 100644 index 0000000000000000000000000000000000000000..12c82d55cbc4c7d634ea4688ed8f0cd15bd94cf4 --- /dev/null +++ b/examples/pokemon-service-tls/tests/custom_connectors.rs @@ -0,0 +1,29 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +pub mod common; + +use serial_test::serial; + +#[tokio::test] +#[serial] +// This test invokes an operation with a client that can only send HTTP2 requests and whose TLS +// implementation is backed by `rustls`. +async fn test_check_health_http2_rustls_connector() { + let _child = common::run_server().await; + let client = common::client_http2_only(); + + let _check_health = client.check_health().send().await.unwrap(); +} + +#[tokio::test] +#[serial] +// This test invokes an operation with a client whose TLS implementation is backed by `native_tls`. +async fn test_check_health_native_tls_connector() { + let _child = common::run_server().await; + let client = common::native_tls_client(); + + let _check_health = client.check_health().send().await.unwrap(); +} diff --git a/examples/pokemon-service-tls/tests/http2.rs b/examples/pokemon-service-tls/tests/http2.rs deleted file mode 100644 index 32c0fba08c7f7f457ed5f8852e2f513ad3548e94..0000000000000000000000000000000000000000 --- a/examples/pokemon-service-tls/tests/http2.rs +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -pub mod common; - -#[tokio::test] -async fn test_check_health_http2() { - let _child = common::run_server().await; - let client = common::client_http2_only(); - - let _check_health = client.check_health().send().await.unwrap(); -}