400 请求错误 - DuplicateHeader

您正在查看的是 Apigee Edge 文档。
转到 Apigee X 文档
信息

问题

客户端应用收到 HTTP 状态代码 400 Bad Request(错误代码为 protocol.http.DuplicateHeader )作为 API 调用的响应。

错误消息

客户端应用会获得以下响应代码:

HTTP/1.1 400 Bad Request

此外,您可能还会看到类似于如下所示的错误消息:

{
   "fault":{
      "faultstring":"Duplicate Header \"Expires\"",
      "detail":{
         "errorcode":"protocol.http.DuplicateHeader"
      }
   }
}

可能的原因

如果禁止在 Apigee Edge 中具有重复项的特定 HTTP 标头在客户端发送到 Apigee Edge 的 HTTP 请求中多次出现具有相同或不同值,则会出现此错误。

根据 RFC 7230 第 3.2.2 节:字段顺序发件人不得在消息中生成多个具有相同字段名称的标头字段,除非相应标头字段的整个字段值被定义为以英文逗号分隔的列表 [即#(values)] 或标头字段是一个众所周知的例外情况。如果 Apigee Edge 在客户端发送的 HTTP 请求 中发现了一个不允许重复的特定标头,则会以 400 Bad Request 作为响应,错误代码为 protocol.http.DuplicateHeader

以下是导致此错误的可能原因:

原因 说明 适用的问题排查说明
请求中的标头重复 从客户端应用发送到 Apigee 的 HTTP 请求包含重复的标头。 Edge 公有云和私有云用户

常见诊断步骤

使用以下工具/技巧之一来诊断此错误:

API 监控

要使用 API Monitoring 诊断错误,请执行以下操作:

  1. 以拥有适当角色的用户身份 登录 Apigee Edge 界面
  2. 切换到您要调查问题的组织。

  3. 前往 Analyze > API Monitoring > Investigate 页面。
  4. 选择您发现错误的具体时间范围。
  5. 确保将“代理”过滤条件设置为全部
  6. 根据时间绘制故障代码
  7. 选择具有错误代码 protocol.http.DuplicateHeader 的单元格,如下所示:

  8. 错误代码 protocol.http.DuplicateHeader 的相关信息如下所示:

  9. 点击查看日志,然后展开失败请求所在的行。
  10. 日志窗口中,请注意以下详细信息:
    1. 状态代码400
    2. 错误来源apigee
    3. 错误代码protocol.http.DuplicateHeader
  11. 如果故障来源的值为 apigeeMP ,并且故障代码的值为 protocol.http.DuplicateHeader,则表示来自客户端的 HTTP 请求包含重复的标头。

跟踪工具

NGINX

如需使用 NGINX 访问日志诊断错误,请执行以下操作:

  1. 如果您是 Private Cloud 用户,则可以使用 NGINX 访问日志来确定有关 HTTP 400 错误的关键信息。
  2. 检查 NGINX 访问日志:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    其中:将 ORGENVPORT# 替换为实际值。

  3. 搜索以查看在特定持续时间内是否存在任何 400 错误(如果问题是在过去发生的),或者是否有任何请求仍然失败并显示 400
  4. 如果您确实发现 X-Apigee-fault-code protocol.http.DuplicateHeader 的值匹配的任何 400 错误,则确定 X-Apigee-fault-source 的值。

    NGINX 访问日志中的 400 错误示例

    NGINX Access 日志中的上述示例条目具有 X-Apigee- fault-codeX-Apigee-fault-source 的以下值:

    响应标头
    X-Apigee-fault-code protocol.http.DuplicateHeader
    X-Apigee-fault-source MP

原因:请求中存在重复的标头

诊断

  1. 按照常见诊断步骤中所述,使用 API Monitoring 或 NGINX 访问日志确定观察到的错误的故障代码故障来源
  2. 如果故障来源的值为 apigeeMP,则表示客户端应用向 Apigee 发送的请求包含重复的标头。
  3. 您可以使用以下方法之一确定作为请求的一部分多次发送的实际标头:

    错误消息

    使用错误消息

    1. 如果您有权访问从 Apigee Edge 收到的完整错误消息,请参阅 faultstringfaultstring 包含已发送多次的标头名称。

      示例错误消息:

      "faultstring":"Duplicate Header \"Expires\""
      
    2. 在上述错误消息中,您可以看到标头 Expires 被发送多次,如 faultstring 中所示。

    实际请求

    使用实际请求

    1. 如果您有权访问客户端应用发出的实际请求,请执行以下步骤:

      1. 验证请求中传递的标头列表。
      2. 如果您发现某个标头在请求中多次出现具有相同值或不同值,这就是导致此错误的原因。

      示例请求

      curl https://HOST_ALIAS/duplicateheadertest -v -H "Expires: Mon, 21 June 2021 07:28:00 GMT" -H "Expires: Mon, 21 June 2021 07:28:00 GMT"
      

      在上述示例中,标头 Expires 会发送多次。因此,此请求会失败,并显示 400 Bad Request 错误和错误代码:protocol.http.DuplicateHeader

    2. 或者,如果您有权访问客户端日志,则可以查看是否了解向 Apigee Edge 发出的实际请求的相关信息,并确定多次发送的标头。

分辨率

解决重复问题

方法 1 [推荐选项] 修复客户端应用,以免包含重复标头

  1. 分析特定客户端发送重复标头的原因。例如,在上述示例中为 Expires。验证 API 代理是否可以接受重复的标头。通常,根据 HTTP 规范 RFC7230 的规定,这种做法是不可取的。
  2. 如果您不希望发送重复的标头,请修改客户端应用,避免发送重复的标头。

    在上面讨论的示例中,请注意,标头 Expires 会以相同的值发送两次,这种情况是不可取的。您可以通过仅传递一次 Expires 标头来解决此问题,如下所示:

    curl https://HOST_ALIAS/duplicateheadertest -v -H "Expires: Mon, 21 June 2021 07:28:00 GMT"
    
  3. 如果可取且您希望允许使用重复的标头,请转到选项 2 使用 CwC 属性

CwC

选项 2 使用 CwC 属性

Apigee 提供了 CwC 属性 HTTPHeader.<HeaderName>,可让客户端应用和目标服务器向 Apigee Edge 中的 API 代理发送重复的标头。

CwC 媒体资源
HTTPHeader.<HeaderName> allowDuplicates,multivalued

例如,可以在消息处理器上设置以下属性,以允许标头 Expires 使用重复和多个值。

HTTPHeader.Expires=allowDuplicates, multiValued
  1. 如果您是 Private Cloud 用户,则可以按照 配置消息处理器以使用重复标头方法指南,配置该属性以防止 Apigee Edge 引发 400 Bad Request 错误,即使请求包含重复的标头也是如此。
  2. 如果您是公有云用户,请联系 Apigee Edge 支持团队,为您的组织配置此属性。

规范

根据以下 RFC 规范,Apigee 要求客户端应用不会在请求中发送重复的标头:

规范
RFC 7230,第 3.2.2 节:字段顺序
RFC 7230,第 3.2 节:标头字段

如果您仍然需要 Apigee 支持的任何帮助,请参阅必须收集诊断信息

必须收集的诊断信息

收集以下诊断信息,然后联系 Apigee Edge 支持团队

如果您是公有云用户,请提供以下信息:

  • 组织名称
  • 环境名称
  • API 代理名称
  • 完成用于重现 400 错误的 curl 命令
  • API 请求的跟踪文件

如果您是 Private Cloud 用户,请提供以下信息:

  • 观察到失败请求的完整错误消息
  • 环境名称
  • API 代理软件包
  • 完成您用于重现 400 错误的 curl 命令
  • API 请求的跟踪文件
  • NGINX 访问日志:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    其中:将 ORGENVPORT# 替换为实际值。

  • 消息处理器系统日志 /opt/apigee/var/log/edge-message-processor/logs/system.log