

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

# coreHTTP 基本 S3 下载演示
<a name="core-http-s3-download-demo"></a>

**重要**  <a name="deprecation-message-demo"></a>
该演示托管在已弃用的 Amazon-FreeRTOS 存储库中。当您创建新项目时，我们建议[从此处开始](freertos-getting-started-modular.md)。如果您已经有一个基于现已弃用的 Amazon-FreeRTOS 存储库的 FreeRTOS 项目，请参阅 [Amazon-FreeRTOS Github 存储库迁移指南](github-repo-migration.md)。

## 简介
<a name="core-http-s3-download-demo-intro"></a>

此演示展示了如何使用[范围请求](https://tools.ietf.org/html/rfc7233)来从 Amazon S3 HTTP 服务器下载文件。当您使用 `HTTPClient_AddRangeHeader` 创建 HTTP 请求时，coreHTTP API 原生支持范围请求。对于微控制器环境，强烈建议使用范围要求。通过在不同的范围内下载大文件（而不是在单个请求中下载），可以在不阻塞网络套接字的情况下处理文件的各个部分。范围请求降低了丢弃数据包的风险（而丢弃的数据包要求在 TCP 连接上重新传输），因此可以改善设备的功耗。

此示例使用一个[网络传输接口](https://freertos.org/network-interface.html)，该接口使用 mbedTL 在运行 CoreHTTP 的 IoT 设备客户端与 Amazon S3 HTTP 服务器之间建立双向身份验证的连接。

**注意**  
要设置和运行 FreeRTOS 演示，请按照[开始使用 FreeRTOS](freertos-getting-started.md)中的步骤操作。

### 单线程与多线程
<a name="core-http-s3-download-demo-threads"></a>

coreHTTP 有两种使用模式，即*单线程*和*多线程*（多任务处理）。尽管本节中的演示在线程中运行 HTTP 库，但它实际上演示了如何在单线程环境中使用 coreHTTP（演示中只有一个任务使用 HTTP API）。尽管单线程应用程序必须重复调用 HTTP 库，但多线程应用程序可以在后台的代理（或进程守护程序）任务中发送 HTTP 请求。

## 源代码组织
<a name="core-http-s3-download-demo-source-code"></a>

演示项目已命名`http_demo_s3_download.c`，可以在`freertos/demos/coreHTTP/`目录和[ GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_download.c)网站上找到。

## 配置 Amazon S3 HTTP 服务器连接
<a name="core-http-s3-download-demo-configure-server"></a>

此演示使用预签名 URL 连接到 Amazon S3 HTTP 服务器并授权访问要下载的对象。Amazon S3 HTTP 服务器的 TLS 连接仅使用服务器身份验证。在应用程序级别，使用预签名 URL 查询中的参数对对象的访问进行身份验证。请按照以下步骤配置与 Amazon的连接。

1. 设置 Amazon 账户：

   1. 如果您还没有，请[创建并激活一个 Amazon 帐户](https://www.amazonaws.cn/premiumsupport/knowledge-center/create-and-activate-aws-account/)。

   1. 账户和权限是使用 Amazon Identity and Access Management (IAM) 设置的。您可以使用 IAM 来管理账户中各用户的权限。默认情况下，用户只有在根所有者授予权限后才拥有权限。

      1. 要向您的 Amazon 账户添加用户，请参阅 [IAM 用户指南](https://docs.amazonaws.cn/IAM/latest/UserGuide/)。

      1. 向您的 Amazon 账户授予访问FreeRTOS的权限， Amazon IoT 并添加以下政策：
         + 亚马逊 3 FullAccess

1. 按照*《Amazon Simple Storage Service 控制台用户指南》*的[如何创建 S3 存储桶](https://docs.amazonaws.cn/AmazonS3/latest/user-guide/create-bucket.html)中的步骤，在 S3 中创建一个存储桶。

1. 按照[如何将文件和文件夹上传至 S3 存储桶](https://docs.amazonaws.cn/AmazonS3/latest/user-guide/upload-objects.html)中的步骤，将文件上传到 S3。

1. 使用 `FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/presigned_url_generator/presigned_urls_gen.py` 中的脚本生成预签名 URL。有关使用说明，请参阅`FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/presigned_url_generator/README.md`。

## 功能
<a name="core-http-s3-download-demo-functionality"></a>

首先，该演示检索文件的大小。然后，它会在循环中按顺序请求每个字节范围，范围大小为 `democonfigRANGE_REQUEST_LENGTH`。

该演示的源代码可以在[GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_download.c)网站上找到。

### 连接到 Amazon S3 HTTP 服务器
<a name="core-http-s3-download-demo-connecting"></a>

函数 [ connectToServerWithBackoffRetries()](https://github.com/aws/amazon-freertos/blob/main/demos/common/http_demo_helpers/http_demo_utils.c#L131-L170) 尝试与 HTTP 服务器建立 TCP 连接。如果连接失败，则会在超时后重试。超时值呈指数级增长，直到达到最大尝试次数或最大超时值。如果在配置的尝试次数后仍无法建立与服务器的 TCP 连接，则 `connectToServerWithBackoffRetries()` 函数将返回失败状态。

`prvConnectToServer()` 函数演示如何仅使用服务器身份验证来建立与 Amazon S3 HTTP 服务器的连接。[它使用基于 mbedtls 的传输接口，该接口在 freeRTOS-\$1mbedtls.c 文件中实现。Plus/Source/Application-Protocols/network\$1transport/freertos\$1plus\$1tcp/using\$1mbedtls/using](https://github.com/FreeRTOS/FreeRTOS/blob/202012.00/FreeRTOS-Plus/Source/Application-Protocols/network_transport/freertos_plus_tcp/using_mbedtls/using_mbedtls.c)

的源代码`prvConnectToServer()`可以在上找到[ GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_download.c#L273-L333)。

### 创建范围请求
<a name="core-http-s3-download-demo-creating-range-request"></a>

API 函数 `HTTPClient_AddRangeHeader()` 支持将字节范围序列化为 HTTP 请求标头以构建范围请求。此演示使用范围请求来检索文件大小并请求文件的各个部分。

`prvGetS3ObjectFileSize()` 函数检索 S3 存储桶中文件的大小。`Connection: keep-alive` 标头已添加到 Amazon S3 的第一个请求中，以便在发送响应后保持连接畅通。目前，S3 HTTP 服务器不支持使用预签名 URL 的 HEAD 请求，因此请求第 0 个字节。文件的大小包含在响应的 `Content-Range` 标头字段中。服务器的预期响应为 `206 Partial Content`；收到任何其他响应状态代码均为错误。

的源代码`prvGetS3ObjectFileSize()`可以在上找到[ GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_download.c#L337-L502)。

检索文件大小后，此演示会为要下载的文件的每个字节范围创建一个新的范围请求。对于文件的每个部分，它都会使用 `HTTPClient_AddRangeHeader()`。

### 发送范围请求和接收响应
<a name="core-http-s3-download-demo-send-request"></a>

函数 `prvDownloadS3ObjectFile()` 循环发送范围请求，直到整个文件下载完成。API 函数 `HTTPClient_Send()` 同步发送请求并接收响应。当函数返回时，响应在 `xResponse` 中接收。然后验证状态代码是否为 `206 Partial Content`，并且目前已下载的字节数按 `Content-Length` 标头值递增。

的源代码`prvDownloadS3ObjectFile()`可以在上找到[ GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_download.c#L506-L651)。