

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在 Rust AWS 开发工具包中配置 HTTP 级别的设置
<a name="http"></a>

 适用于 Rust 的 AWS SDK 提供了内置 HTTP 功能，供您在代码中创建的 AWS 服务 客户端使用。

默认情况下，适用于 Rust 的 SDK 使用基于 `hyper`、`rustls` 和 `aws-lc-rs` 的 HTTPS 客户端。此客户端应该适用于大多数使用案例，而无需其他配置。
+ [https://docs.rs/hyper/latest/hyper/](https://docs.rs/hyper/latest/hyper/)是 Rust 的较低级别 HTTP 库，可以与一起使用 适用于 Rust 的 AWS SDK 来调用 API 服务。
+ [https://github.com/rustls/rustls](https://github.com/rustls/rustls) 是一个用 Rust 编写的现代 TLS 库，它为加密提供程序提供了内置选项。
+ [https://github.com/aws/aws-lc](https://github.com/aws/aws-lc) 是一个通用加密库，包含 TLS 和常见应用程序所需的算法。
+ [https://github.com/aws/aws-lc-rs](https://github.com/aws/aws-lc-rs) 是 Rust 中用于 `aws-lc` 库的惯用包装器。

如果您想选择其他 TLS 或加密提供程序，`aws-smithy-http-client` 提供了一些其他选项和配置。对于更高级的使用案例，我们鼓励您自带 HTTP 客户端实现或提交功能申请以供考虑。

## 选择替代 TLS 提供程序
<a name="tlsProviders"></a>

`aws-smithy-http-client` crate 提供了一些替代 TLS 提供程序。

提供以下提供程序：

**`rustls` 与 `aws-lc`**  
基于 [https://github.com/rustls/rustls](https://github.com/rustls/rustls) 的 TLS 提供程序，使用 [https://github.com/aws/aws-lc-rs](https://github.com/aws/aws-lc-rs) 进行加密。  
这是适用于 Rust 的 SDK 的默认 HTTP 行为。如果您想使用此选项，则无需在代码中执行任何其他操作。

**`s2n-tls`**  
基于 [https://github.com/aws/s2n-tls](https://github.com/aws/s2n-tls) 的 TLS 提供程序。

**`rustls` 与 `aws-lc-fips`**  
基于 [https://github.com/rustls/rustls](https://github.com/rustls/rustls) 的 TLS 提供程序，使用符合 FIPS 标准的 [https://github.com/aws/aws-lc-rs](https://github.com/aws/aws-lc-rs) 版本进行加密

**`rustls` 与 `ring`**  
基于 [https://github.com/rustls/rustls](https://github.com/rustls/rustls) 的 TLS 提供程序，使用 [https://github.com/briansmith/ring](https://github.com/briansmith/ring) 进行加密。

### 先决条件
<a name="prereqTls"></a>

使用 `aws-lc-rs` 或 `s2n-tls` 需要 C 编译器（Clang 或 GCC）来构建。对于某些平台，构建可能还需要 CMake。在任何平台上使用 “fips” 功能进行构建都需要 CMake 然后开始。有关更多信息，请参阅[适用于 Rust 的 AWS Libcrypto（`aws-lc-rs`）](https://github.com/aws/aws-lc-rs/blob/main/aws-lc-rs/README.md)存储库和构建说明。

### 如何使用替代 TLS 提供程序
<a name="s2nTls"></a>

`aws-smithy-http-client` crate 提供了其他 TLS 选项。要让您的 AWS 服务 客户端使用其他 TLS 提供程序，请使用 `aws_config` crate 中的加载器覆盖 `http_client`。HTTP 客户端既用于 AWS 服务 ，也用于凭证提供程序。

以下示例演示了如何使用 `s2n-tls` TLS 提供程序。但是，类似的方法也适用于其他提供程序。

要编译示例代码，请运行以下命令向项目添加依赖项：

```
cargo add aws-smithy-http-client -F s2n-tls
```

示例代码：

```
use aws_smithy_http_client::{tls, Builder};

#[tokio::main]
async fn main() {
    let http_client = Builder::new()
        .tls_provider(tls::Provider::S2nTls)
        .build_https();

    let sdk_config = aws_config::defaults(
        aws_config::BehaviorVersion::latest()
    )
    .http_client(http_client)
    .load()
    .await;

    // create client(s) using sdk_config
    // e.g. aws_sdk_s3::Client::new(&sdk_config);
}
```

## 启用 FIPS 支持
<a name="fipsTls"></a>

`aws-smithy-http-client` crate 提供了启用符合 FIPS 标准的加密实现的选项。要让您的 AWS 服务 客户使用符合 FIPS 标准的提供商，请`http_client`使用箱子中的加载器替换。`aws_config`HTTP 客户端既 AWS 服务 用于证书提供者，也用于凭证提供程序。

**注意**  
FIPS 支持需要在构建环境中添加其他依赖项。请参阅 `aws-lc` crate 的[构建](https://github.com/aws/aws-lc/blob/main/BUILDING.md)说明。

要编译示例代码，请运行以下命令向项目添加依赖项：

```
cargo add aws-smithy-http-client -F rustls-aws-lc-fips
```

以下示例代码可启用 FIPS 支持：

```
// file: main.rs
use aws_smithy_http_client::{
    tls::{self, rustls_provider::CryptoMode},
    Builder,
};

#[tokio::main]
async fn main() {
    let http_client = Builder::new()
        .tls_provider(tls::Provider::Rustls(CryptoMode::AwsLcFips))
        .build_https();

    let sdk_config = aws_config::defaults(
        aws_config::BehaviorVersion::latest()
    )
    .http_client(http_client)
    .load()
    .await;

    // create client(s) using sdk_config
    // e.g. aws_sdk_s3::Client::new(&sdk_config);
}
```

## 优先考虑后量子密钥交换
<a name="quantumTls"></a>

默认 TLS 提供程序基于使用 `aws-lc-rs` 的 `rustls`，支持 `X25519MLKEM768` 后量子密钥交换算法。要使 `X25519MLKEM768` 成为优先级最高的算法，您需要将 `rustls` 程序包添加到 crate 中并启用 `prefer-post-quantum` 功能标志。否则，它可用，但不是最高优先级。有关更多信息，请参阅`rustls`[文档](https://docs.rs/rustls/0.23.23/rustls/manual/_05_defaults/index.html#about-the-post-quantum-secure-key-exchange-x25519mlkem768)。

**注意**  
这将在未来版本中成为默认选项。

## 覆盖 DNS 解析器
<a name="overrideDns"></a>

 通过手动配置 HTTP 客户端，可以覆盖默认 DNS 解析器。

要编译示例代码，请运行以下命令向项目添加依赖项：

```
cargo add aws-smithy-http-client -F rustls-aws-lc
cargo add aws-smithy-runtime-api -F client
```

以下示例代码覆盖 DNS 解析器：

```
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};

/// A DNS resolver that returns a static IP address (127.0.0.1)
#[derive(Debug, Clone)]
struct StaticResolver;

impl ResolveDns for StaticResolver {
    fn resolve_dns<'a>(&'a self, _name: &'a str) -> DnsFuture<'a> {
        DnsFuture::ready(Ok(vec![IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))]))
    }
}

#[tokio::main]
async fn main() {
    let http_client = Builder::new()
        .tls_provider(tls::Provider::Rustls(CryptoMode::AwsLc))
        .build_with_resolver(StaticResolver);
    
    let sdk_config = aws_config::defaults(
        aws_config::BehaviorVersion::latest()
    )
    .http_client(http_client)
    .load()
    .await;
    
    // create client(s) using sdk_config
    // e.g. aws_sdk_s3::Client::new(&sdk_config);
}
```

**注意**  
默认情况下，亚马逊 Linux 2023 (AL2023) 不会在操作系统级别缓存 DNS。

## 自定义根 CA 证书
<a name="customizeCertificatesTls"></a>

默认情况下，TLS 提供程序会加载给定平台的系统原生根证书。要自定义此行为以加载自定义 CA 捆绑包，您可以使用自己的 `TrustStore` 配置 `TlsContext`。

要编译示例代码，请运行以下命令向项目添加依赖项：

```
cargo add aws-smithy-http-client -F rustls-aws-lc
```

以下示例结合使用了 `rustls` 和 `aws-lc`，但也适用于任何受支持的 TLS 提供程序：

```
use aws_smithy_http_client::{
    tls::{self, rustls_provider::CryptoMode},
    Builder
};
use std::fs;

/// read the PEM encoded root CA (bundle) and return a custom TLS context
fn tls_context_from_pem(filename: &str) -> tls::TlsContext {
    let pem_contents = fs::read(filename).unwrap();
    
    // Create a new empty trust store (this will not load platform native certificates)
    let trust_store = tls::TrustStore::empty()
        .with_pem_certificate(pem_contents.as_slice());
        
    tls::TlsContext::builder()
        .with_trust_store(trust_store)
        .build()
        .expect("valid TLS config")
}

#[tokio::main]
async fn main() {
    let http_client = Builder::new()
        .tls_provider(tls::Provider::Rustls(CryptoMode::AwsLc))
        .tls_context(tls_context_from_pem("my-custom-ca.pem"))
        .build_https();
    
    let sdk_config = aws_config::defaults(
        aws_config::BehaviorVersion::latest()
    )
    .http_client(http_client)
    .load()
    .await;
    
    // create client(s) using sdk_config
    // e.g. aws_sdk_s3::Client::new(&sdk_config);
}
```