

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

# 了解 HTTP 端点传输请求和响应规范
<a name="httpdeliveryrequestresponse"></a>

要使 Amazon Data Firehose 成功将数据传输到自定义 HTTP 端点，这些端点必须接受请求，并使用某些 Amazon Data Firehose 请求和响应格式发送响应。本节介绍 Amazon Data Firehose 服务发送到自定义 HTTP 端点的 HTTP 请求的格式规范，以及 Amazon Data Firehose 服务预期的 HTTP 响应的格式规范。在 Amazon Data Firehose 使请求超时之前，HTTP 端点有 3 分钟的时间响应请求。Amazon Data Firehose 将不符合正确格式的响应视为传输失败。

## 请求格式
<a name="requestformat"></a>

**路径和 URL 参数**  
由您直接配置为单个 URL 字段的一部分。Amazon Data Firehose 会按配置发送，无需修改。仅支持 https 目标。URL 限制在传输流配置期间应用。  
目前，HTTP 端点数据传输仅支持端口 443。

**HTTP 标头 X-Amz-Firehose-Protocol-版本**  
此标头用于指示请求/响应格式的版本。目前唯一的版本是 1.0。

**HTTP 标头- X-Amz-Firehose-Request-ID**  
此标头的值是一个不透明的 GUID，可用于调试和重复数据删除。如果可能的话，端点实现应记录这个标头的值，包括成功和失败的请求。在多次尝试同一请求时，请求 ID 保持不变。

**HTTP 标头 - Content-Type**  
Content-Type 标头的值始终为 `application/json`。

**HTTP 标头 - Content-Encoding**  
可以配置 Firehose 流，在发送请求时使用 GZIP 压缩正文。启用此压缩后，按照标准做法，Content-Encoding 标头的值将设置为 gzip。如果未启用压缩，则 Content-Encoding 标头就完全不存在。

**HTTP 标头 - Content-Length**  
按照标准方式使用。

**HTTP 标头- X-Amz-Firehose-Source-Arn:**  
以 ASCII 字符串格式表示的 Firehose 流的 ARN。ARN 对区域、 AWS 账户 ID 和直播名称进行编码。例如 `arn:aws:firehose:us-east-1:123456789:deliverystream/testStream`。

**HTTP 标头- X-Amz-Firehose-Access-Key**  
此标头包含 API 密钥或其他凭证。在创建或更新传输流时，您可以创建或更新 API 密钥（又称授权令牌）。Amazon Data Firehose 将访问密钥的大小限制为 4096 字节。Amazon Data Firehose 不会尝试以任何方式解释此密钥。配置的密钥将逐字复制到此标头的值中。但是，如果您使用 Secrets Manager 来配置密钥，则密钥必须遵循特定的 JSON 对象格式：`{"api_key": "..."}`。  
内容可以是任意的，可能表示 JWT 令牌或 ACCESS\$1KEY。如果端点需要多字段凭证（如用户名和密码），则应将所有字段的值以端点可理解的格式（JSON 或 CSV）一起存储在单个访问密钥中。如果原始内容是二进制的，则可以对此字段进行 base-64 编码。Amazon Data Firehose 不会修改对配置值的 and/or 编码，而是按原样使用内容。

**HTTP 标头- X-Amz-Firehose-Common-属性**  
此标头将与整个请求相关的公共属性（元数据）带 and/or 到请求中的所有记录。在创建 Firehose 流时直接配置。此属性的值被编码为具有以下架构的 JSON 对象：  

```
"$schema": http://json-schema.org/draft-07/schema#

properties:
  commonAttributes:
    type: object
    minProperties: 0
    maxProperties: 50
    patternProperties:
      "^.{1,256}$":
        type: string
        minLength: 0
        maxLength: 1024
```
示例如下：  

```
"commonAttributes": {
    "deployment -context": "pre-prod-gamma",
    "device-types": ""
  }
```

**正文 - 最大大小**  
最大正文大小由您配置，压缩前最大可达 64MiB。

**正文 - 架构**  
正文包含一个 JSON 文档，该文档具有以下 JSON 架构（用 YAML 编写）：  

```
"$schema": http://json-schema.org/draft-07/schema#

title: FirehoseCustomHttpsEndpointRequest
description: >
  The request body that the Firehose service sends to
  custom HTTPS endpoints.
type: object
properties:
  requestId:
    description: >
      Same as the value in the X-Amz-Firehose-Request-Id header,
      duplicated here for convenience.
    type: string
  timestamp:
    description: >
      The timestamp (milliseconds since epoch) at which the Firehose
      server generated this request.
    type: integer
  records:
    description: >
      The actual records of the Firehose stream, carrying 
      the customer data.
    type: array
    minItems: 1
    maxItems: 10000
    items:
      type: object
      properties:
        data:
          description: >
            The data of this record, in Base64. Note that empty
            records are permitted in Firehose. The maximum allowed
            size of the data, before Base64 encoding, is 1024000
            bytes; the maximum length of this field is therefore
            1365336 chars.
          type: string
          minLength: 0
          maxLength: 1365336

required:
  - requestId
  - records
```
示例如下：  

```
{
  "requestId": "ed4acda5-034f-9f42-bba1-f29aea6d7d8f",
  "timestamp": 1578090901599
  "records": [
    {
      "data": "aGVsbG8="
    },
    {
      "data": "aGVsbG8gd29ybGQ="
    }
  ]
}
```

## 响应格式
<a name="responseformat"></a>

**出错时的默认行为**  
如果响应不符合以下要求，Firehose 服务器会将其视为无正文的 500 状态代码。

**状态代码**  
HTTP 状态代码必须在 2XX、4XX 或 5XX 范围内。  
Amazon Data Firehose 服务器不遵循重定向（3XX 状态代码）。只有响应代码 200 才被视为成功将记录传输到 HTTP/EP。响应代码 413（超出大小）被视为永久失败，并且记录批次不会发送到错误存储桶（如果已配置）。所有其他响应代码均被视为可重试的错误，并受到稍后介绍的回退重试算法的约束。

**标头 - 内容类型**  
唯一可接受的内容类型是 application/json。

**HTTP 标头 - Content-Encoding**  
不得使用 Content-Encoding。正文必须是未压缩状态。

**HTTP 标头 - Content-Length**  
如果响应有正文，则必须有 Content-Length 标头。

**正文 - 最大大小**  
响应正文的大小必须小于等于 1MiB。  

```
"$schema": http://json-schema.org/draft-07/schema#

title: FirehoseCustomHttpsEndpointResponse

description: >
  The response body that the Firehose service sends to
  custom HTTPS endpoints.
type: object
properties:
  requestId:
    description: >
      Must match the requestId in the request.
    type: string
  
  timestamp:
    description: >
      The timestamp (milliseconds since epoch) at which the
      server processed this request.
    type: integer
   
  errorMessage:
    description: >
      For failed requests, a message explaining the failure.
      If a request fails after exhausting all retries, the last 
      Instance of the error message is copied to error output
      S3 bucket if configured.
    type: string
    minLength: 0
    maxLength: 8192
required:
  - requestId
  - timestamp
```
示例如下：  

```
Failure Case (HTTP Response Code 4xx or 5xx)
{
  "requestId": "ed4acda5-034f-9f42-bba1-f29aea6d7d8f",
  "timestamp": "1578090903599",
  "errorMessage": "Unable to deliver records due to unknown error."
}
Success case (HTTP Response Code 200)
{
  "requestId": "ed4acda5-034f-9f42-bba1-f29aea6d7d8f",
  "timestamp": 1578090903599
}
```

**错误响应处理**  
在所有错误情况下，Amazon Data Firehose 服务器都会使用指数回退算法重新尝试传输同一批记录。重试使用抖动系数为 (15%) 的初始退缩时间（1 秒）进行恢复，随后的每次重试都使用带有抖动的公式（initial-backoff-time \$1（乘数 (2) ^ retry\$1count））进行恢复。回退时间的最大间隔限制为 2 分钟。例如，在第 n 次重试时，回退时间为 = M MAX(120, 2^n) \$1 random(0.85, 1.15)。  
上式中指定的参数可能会发生变化。有关指数退避算法中使用的确切初始退缩时间、最大退避时间、乘数和抖动百分比，请参阅 Fi AWS rehose 文档。  
在随后的每次重试中，传送记录的访问密钥 and/or 目标可能会根据更新后的 Firehose 流配置而发生变化。Amazon Data Firehose 服务尽力在重试中使用相同的请求 ID。最后一项功能可用于 HTTP 端点服务器进行重复数据删除。如果在允许的最长时间后仍未传输请求（基于 Firehose 流配置），则可以根据流配置选择将该批记录传输到错误存储桶。

## 示例
<a name="examples"></a>

 CWLog 来源请求的示例。

```
{
  "requestId": "ed4acda5-034f-9f42-bba1-f29aea6d7d8f",
  "timestamp": 1578090901599,
  "records": [
   {
    "data": {
      "messageType": "DATA_MESSAGE",
      "owner": "123456789012",
      "logGroup": "log_group_name",
      "logStream": "log_stream_name",
      "subscriptionFilters": [
        "subscription_filter_name"
      ],
      "logEvents": [
        {
          "id": "0123456789012345678901234567890123456789012345",
          "timestamp": 1510109208016,
          "message": "log message 1"
        },
        {
          "id": "0123456789012345678901234567890123456789012345",
          "timestamp": 1510109208017,
          "message": "log message 2"
        }
      ]
    }
   }
  ]
}
```