400 请求错误 - DuplicateHeader

您正在查看 Apigee Edge 文档。
前往 Apigee X 文档
info

问题

客户端应用收到 HTTP 状态代码 400 Bad Request,错误代码为 protocol.http.DuplicateHeader ,以此响应 API 调用。

出错提示

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

HTTP/1.1 400 Bad Request

此外,您可能会看到类似于以下内容的错误消息:

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

可能的原因

如果特定 HTTP 标头不允许在 Apigee Edge 中包含重复项,并且它作为客户端发送到 Apigee Edge 的 HTTP 请求的一部分出现相同或不同的值,则会出现此错误。

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

造成此错误的可能原因包括:

原因 说明 适用的问题排查说明
请求中存在重复的标头 客户端应用发送到 Apigee 的 HTTP 请求包含重复的标头。 Edge Public 和 Private Cloud 用户

常见诊断步骤

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

API 监控

如需使用 API 监控诊断错误,请执行以下操作:

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

  3. 依次前往分析 > API 监控 > 调查 页面。
  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 请求包含重复的标头。

Trace 工具

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. 如果您确实发现任何 400 错误,并且 X-Apigee-fault-code protocol.http.DuplicateHeader 的值匹配,请 确定 X-Apigee-fault-source 的值。

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

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

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

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

诊断

  1. 使用 API 监控或 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 provides a CwC property HTTPHeader.<HeaderName>,该属性允许客户端 应用和目标服务器向 Apigee Edge 中的 API 代理发送重复的标头。

CwC 属性
HTTPHeader.<HeaderName> allowDuplicates,multivalued

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

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

规范

Apigee 希望客户端应用根据以下 RFC 规范,不发送重复的标头作为请求的一部分:

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

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

必须收集的诊断信息

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

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

  • 组织名称
  • 环境名称
  • 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