将消息处理器配置为允许重复的标头

您正在查看 Apigee Edge 文档。
请查看 Apigee X 文档

根据 HTTP 规范 RFC 7230 第 3.2.2 节:字段顺序,Apigee Edge 希望来自客户端的 HTTP 请求或来自后端服务器的 HTTP 响应不包含使用相同或不同值多次传递的相同标头,除非特定标头有例外并允许重复。

默认情况下,Apigee Edge 允许将重复数据和多个值传递给大多数 HTTP 标头。不过,它不允许标头中不允许存在重复和多个值中列出的某些标头。因此:

  • 如果客户端多次发送包含特定标头的 HTTP 请求或 HTTP 标头具有多个值(在 Apigee Edge 中不允许出现重复/多个值),您会收到错误代码 400 Bad Request protocol.http.DuplicateHeader
  • 同样,如果后端服务器多次发送包含特定标头的 HTTP 响应或 HTTP 标头的多个值(HTTP 标头中不允许存在重复或多个值),则您会收到 502 Bad Gateway 错误代码 protocol.http.DuplicateHeader

解决这些错误的推荐解决方案是,修复客户端应用和后端服务器,使其不发送重复的标头,并遵循 RFC 7230 第 3.2.2 节:字段顺序规范,如下面的问题排查指南中所述:

不过,在某些情况下,您可能需要添加例外情况,以在某些 HTTP 标头中包含重复项和多个值。在此类情况下,您可以通过在消息处理器级别设置属性 HTTPHeader.HEADER_NAME,为特定 HTTP 标头允许重复标头和多个值。

本文档提供了有关此属性的信息,说明了如何使此属性避免上述错误,并分享了关于此问题的最佳实践。

允许重复数据和多个值的 HTTP 标头属性

Apigee Edge 提供以下两个属性来控制 HTTP 标头允许重复值和多个值。请注意,您只能使用如何配置 Edge 中所述的令牌语法,在消息处理器中配置这些消息。

属性名称 说明 允许的值
HTTPHeader.ANY

此属性指示是否允许所有 HTTP 标头(包括客户端发送的 HTTP 请求中包含的自定义标头)或后端服务器发送到 Apigee Edge 的 HTTP 响应发送的重复值或多个值。

默认值

multivalued, allowDuplicate,

  1. blank:HTTP 标头不能出现重复和多个值。
  2. multiValued:将多值标头拆分为多个标头。HTTP 标头可以使用多个值,但不允许出现重复值。值 multiValued 已启用,这意味着 test-header=a,b 将转换为 test-header=atest-header=b.
  3. allowDuplicate:允许多个同名的(重复)HTTP 标头。
  4. multivalued, allowDuplicate:HTTP 标头允许使用多个值和重复项。

HTTPHeader.HEADER_NAME

此属性用于从 HTTPHeader.ANY 指定的内容替换特定标头的行为

同上。

标头不能包含重复值和多个值

如前所述,默认情况下,Apigee Edge 允许大部分 HTTP 标头具有重复值和多个值。这是因为,属性 HTTPHeader.ANY 配置了 multivalued, allowDuplicate.

已覆盖配置

对于某些特定头文件,可以使用以下方法之一覆盖默认配置:

  • HTTPHeader.HEADER_NAME=multivalued, allowDuplicate

    此配置不会更改默认行为。也就是说,特定标头可以具有重复项和多个值

    .
  • HTTPHeader.HEADER_NAME=

    此配置会更改默认行为。也就是说,特定标头不能有多个重复值

确定不允许存在重复和多个值的标头

本部分介绍了如何确定以下内容:

  • 您的 Apigee Edge 私有云设置中不允许具有重复值和多个值 的特定标头,并且
  • 使用现有配置的特定标头
  1. 在消息处理器机器上,在 /opt/apigee/edge-message-processor/conf 目录中搜索 HTTPHeader. 属性,如下所示:

    grep -ri "HTTPHeader." /opt/apigee/edge-message-processor/conf
    

    示例输出:

    # grep -ri "HTTPHeader" /opt/apigee/edge-message-processor/conf
    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.ANY=allowDuplicates, multiValued
    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Connection=allowDuplicates, multiValued
    … <snipped>
    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Host=
    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Expires=
    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Date=allowDuplicates
    …
    <snipped>
    
  2. 配置覆盖部分中所述,请注意上述示例输出中的以下信息:
    1. HTTP 标头 Connection 会被覆盖,但允许具有重复和多个值
    2. HTTP 标头 HostExpires 将被覆盖,不允许存在重复和多个值
    3. HTTP 标头 Date 会被覆盖,并且可以重复,但不得有多个值
    4. 本文档中显示的这里的所有头文件(ConnectionHostExpiresDate)在本文档中称为已存在配置的头文件。

Apigee Edge 的行为

下表介绍了当 Apigee Edge 以重复形式发送多个值时,Apigee Edge 的行为。当 HTTPHeader 属性在消息处理器上如何配置,示例如下:HTTPHeadertest-header 时。

请求 基于 conf/http.properties+HTTPHeader.test-header= 的值
<空白> allowDuplicate 多值 allowDuplicate、multiValued (DEFAULT)
test‑header=a,b test‑header=a,b test‑header=a,b

protocol.http.
DuplicateHeader

在内部,我们将 test-header=a,b 拆分为:

  • test-header=a
  • test-header=b

然后,系统会抛出 DuplicateHeader 错误。

test‑header=a,b

在内部,我们将 test-header=a,b 拆分为:

  • test-header=a
  • test-header=b

但系统会将原始表单发送到目标文件夹。

test‑header=a
test‑header=b
protocol.http.
DuplicateHeader
test‑header=a
test‑header=b
protocol.http.
DuplicateHeader
test‑header=a
test‑header=b

准备工作

在使用本文档中的步骤之前,请确保您了解如何按照 如何配置 Edge 中的说明为私有云上的 Edge 配置属性。

为标头配置 allowDuplicates 和多个值

HTTP 标头属性允许重复值和多个值中所述,属性值 HTTPHeader.ANY = allowDuplicates, multivalued 表示所有标头都可以在 Apigee Edge 中具有重复值。不过,某些标头会明确覆盖值,不允许使用 HTTPHeader.HEADER_NAME 属性为标头添加重复标头或多个值。

本部分介绍了如何根据如何配置 Edge 中的语法,使用消息处理程序中的属性 HTTPHeader.HEADER_NAME 为任何此类 HTTP 标头配置重复项和多个值。

在本部分中,我们将使用 Expires(和 myheader)作为示例标头,以允许使用重复项和多个值,如下所述:

  1. 使用以下命令确定属性 HTTPHeaderHEADER_NAME 的当前值,以确保其尚未启用以允许重复值和多个值:
    grep -ri "HTTPHeader.HEADER_NAME" /opt/apigee/edge-message-processor/conf
    

    例如,如果您尝试为 Expires 标头设置属性,则请在消息处理器上检查属性 HTTPHeader.Expires 令牌的当前值:

    grep -ri "HTTPHeader.Expires" /opt/apigee/edge-message-processor/conf
    

    以上命令的输出会生成以下结果之一:

    1. 此属性设置为空白,这意味着该值会被覆盖(这是一个具有现有配置的标头),以阻止出现重复的标头和多个值。也就是说,在 HTTP 请求或 HTTP 响应中,您不得向 Apigee 多次发送 Expires 标头。
    2. 特定属性没有命中,这意味着该值不会被覆盖(并且这个标头不是预先存在的配置)。这意味着作为 HTTP 请求或 HTTP 响应到 Apigee Edge 的一部分,特定标头可以多次发送(允许重复)。
    3. 该属性的值设为 allowDuplicates, multivalued,则表示该值已明确覆盖 (这是一个包含现有配置的标头)。这意味着作为 HTTP 请求或 HTTP 对 Apigee 响应的一部分,特定标头可以多次发送(允许重复)。

    搜索命令输出示例

    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Expires=
    

    上面的示例输出显示属性 HTTPHeader.Expires 设置为空白。这意味着该属性被覆盖不允许为标头 Expires 设置重复或多个值

  2. 如果您发现与特定标头对应的属性被明确覆盖,导致不允许出现重复值或多个值(如上面的示例输出所示),则必须执行以下步骤。如果未明确覆盖,请跳过本部分中的其余步骤。
  3. 修改。如果您还没有找到它,可以通过以下方式创建:
    /opt/apigee/customer/application/message-processor.properties
    

    例如,要使用 vi 打开文件,请输入以下命令:

    vi /opt/apigee/customer/application/message-processor.properties
    
  4. 添加如下格式的行:
    conf_http_HTTPHeader.Expires=allowDuplicates, multiValued
    
  5. 保存更改。
  6. 确保属性文件归 apigee 用户所有。 如果不是,请执行以下命令:

    chown apigee:apigee /opt/apigee/customer/application/message-processor.properties
    
  7. 重启消息处理器:

    /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
    

    如需在不影响流量的情况下重新启动,请参阅 滚动处理消息处理程序,避免对流量造成影响

  8. 如果您有多个消息处理器,请针对所有消息处理器重复上述步骤。

验证标头是否已配置为重复和多个值

本部分介绍了如何验证特定标头的属性 HTTPHeader.HEADER_NAME 是否已成功更新,以允许在消息处理器上进行重复。

我们将使用 Expires 作为示例标头,并检查相应的属性 HTTPHeader.Expires 是否已更新。

即使您使用令牌 conf_http_HTTPHeader.Expires 更新消息处理器中的值,也需要验证是否已使用新值设置实际属性 HTTPHeader.Expires

  1. 在消息处理器机器上,在/opt/apigee/edge-message-processor/conf目录中搜索属性 HTTPHeader.HEADER_NAME 并检查其是否已设置为新值,如下所示:
    grep -ri "HTTPHeader.HEADER_NAME" /opt/apigee/edge-message-processor/conf
    

    例如,如果您要检查属性 HTTPHeader.Expires 是否设置了新值,请运行以下命令:

    grep -ri "HTTPHeader.Expires" /opt/apigee/edge-message-processor/conf
    
  2. 如果已在消息处理器上成功为 HTTPHeader.HEADER_NAME 设置新值,则上述命令会在 http.properties 文件中显示新值。
  3. 配置 allowDuplicatesmultiValued 后,上述命令中的示例结果如下所示:

    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Expires=allowDuplicates, multiValued
    
  4. 请注意,在上面的示例输出中,属性 HTTPHeader.Expires 已设置为 http.properties 中的新值 allowDuplicates, multiValued。这表示允许在消息处理器中配置 HTTPHeader 中重复和多个值的行为。
  5. 如果您仍然看到属性 HTTPHeader.HEADER_NAME 的旧值,请确认您已正确执行为标头配置 allowDuplicates 和多个值中列出的所有步骤。 如果您错过了任何步骤,请再次正确重复所有步骤。

    确保您的代理按预期运行,尤其是在具有用于获取和设置代理中的标头的功能逻辑时。

  6. 如果您仍无法修改此媒体资源,请联系 Apigee Edge 支持团队

为标头停用 allowDuplicates

本部分介绍了如何根据如何配置 Edge 中所述的语法,将消息 HTTPHeader.{Headername} 属性配置为在消息处理器中针对特定 HTTP 标头不允许存在重复值和多个值

在本部分中,我们将使用 Expires(和 myheader)作为示例标头,以表明我们不希望它出现重复,如下所述:

  1. 使用以下命令确定属性 HTTPHeaderHEADER_NAME 的当前值,以确保其尚未停用,从而允许存在重复和多个值:
    grep -ri "HTTPHeader.HEADER_NAME" /opt/apigee/edge-message-processor/conf
    

    例如,如果您尝试为 Expires 标头设置属性,请在消息处理器上检查属性 HTTPHeader.Expires 令牌的当前值:

    grep -ri "HTTPHeader.Expires" /opt/apigee/edge-message-processor/conf
    

    以上命令的输出会产生以下结果之一:

    1. 此属性设置为空白,表示值 被覆盖为不允许重复标头和多个值。也就是说,在 HTTP 请求或 HTTP 响应中,您不得将 Expires 标头多次发送到 Apigee。
    2. 特定属性没有命中,这意味着该值不会被覆盖,并且不是包含现有配置的 NOT 标头。这意味着作为 HTTP 请求或 HTTP 响应到 Apigee Edge 的一部分,特定标头可以多次发送(允许重复)。
    3. 此属性的值为 allowDuplicates, multivalued,则表示该值被明确覆盖,该配置已经存在。 不过,这意味着具体标头可以作为 HTTP 请求或 HTTP 响应的一部分发送到 Apigee 多次(允许重复)。

    输出示例 1

    搜索命令的输出示例 1

    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Expires=allowDuplicates, multiValued
    

    示例输出显示,属性 HTTPHeader.Expires 设置为 allowDuplicates, multiValued。这意味着此属性将被覆盖,从而允许标头Expires重复或使用多个值

    输出示例 2

    搜索命令的示例命令和输出 2

    grep -ri "HTTPHeader.myheader" /opt/apigee/edge-message-processor/conf
    

    示例输出未显示任何输出,这意味着属性 HTTPHeader.myheader 默认设为 allowDuplicates, multiValued。 这也意味着,标头 myheader 属性不会被覆盖

  2. 如果您发现以下某种情况,请执行本部分中的其余步骤:
    1. 与上文中示例输出 1 中的标头(特定配置已存在的标头)相比,特定标头所对应的属性会被替换为允许重复的值
    2. 如上例输出示例 2 中所述,没有特定标头的媒体资源命中(不是有现有配置的标头)

    否则,请跳过本部分的其余步骤。

  3. 修改以下文件。如果该 ID 不存在,您可以创建它。
    /opt/apigee/customer/application/message-processor.properties
    

    例如,要使用 vi 打开文件,请输入以下命令:

    vi /opt/apigee/customer/application/message-processor.properties
    
  4. 将以下格式的代码行添加到属性文件中:

    现有配置

    情景 1:使用预先存在的配置的标题

    conf_http_HTTPHeader.Expires=
    

    不存在任何配置

    情形 2:不是使用原有配置的标题

    conf/http.properties+HTTPHeader.myheader=
    
  5. 保存更改。
  6. 确保属性文件归 apigee 用户所有。如果不是,请执行以下命令:
    chown apigee:apigee /opt/apigee/customer/application/message-processor.properties
    
  7. 重启消息处理器:
    /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
    

    如需在不影响流量的情况下重新启动,请参阅 滚动处理消息处理程序,避免对流量造成影响

  8. 如果您有多个消息处理器,请针对所有消息处理器重复上述步骤。

确认标头已配置为不允许出现重复和多个值

本部分介绍了如何验证特定标头的属性 HTTPHeader.HEADER_NAME 是否已成功更新,以允许消息处理程序中出现重复内容。

我们将使用 Expires(和 myheader)作为示例标头,并检查相应的属性 HTTPHeader.Expires(和 HTTPHeader.myheader)是否已更新。

  1. 在消息处理器机器上,搜索 /opt/apigee/edge-message- processor/conf 目录中的属性 HTTPHeader.HEADER_NAME,然后检查是否已使用新值设置,如下所示:

    grep -ri "HTTPHeader.HEADER_NAME" /opt/apigee/edge-message-processor/conf
    

    例如,如果您想检查是否使用新值设置了 HTTPHeader.Expires 属性,则可以运行以下命令:

    现有配置

    grep -ri "HTTPHeader.Expires" /opt/apigee/edge-message-processor/conf
    

    不存在任何配置

    grep -ri "HTTPHeader.myheader" /opt/apigee/edge-message-processor/conf
    
  2. 如果已在消息处理器上为 HTTPHeader.HEADER_NAME I 成功设置新的 HTTP 标头值,则上述命令会在 http.properties 文件中显示新值。
  3. 停用 allowDuplicates 后上述命令的示例结果如下:

    现有配置

    场景 1到期标题(包含现有配置的标头)

    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Expires=
    

    不存在任何配置

    场景 2:myheader 标头(非现有配置的标头)

    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.myheader=
    
  4. 请注意,在上面的示例输出中,属性 HTTPHeader.Expires(和 HTTPHeader.myheader)已设置为 http.properties 中的新值 {blank}。这表示不允许特定 HTTP 标头 Expires(和 myheader)允许重复值和多个值的行为已在消息处理器中成功停用。
  5. 如果您仍然看到属性 HTTPHeader.Expires (or HTTPHeader.myheader) 的旧值,请确认您已正确执行为标头配置 allowDuplicates 和多个值中列出的所有步骤。如果您遗漏了任何步骤,请再次正确重复所有步骤。

    确保您的代理按预期运行,尤其是在具有用于获取和设置代理中的标头的功能逻辑时。

  6. 如果您仍无法修改此媒体资源,请联系 Apigee Edge 支持团队