HTTP/1.1 标头大小写

在处理 HTTP/1.1 时,Envoy 会将标头键规范化为全小写。虽然这符合 HTTP/1.1 规范,但在实践中,这可能会导致迁移现有系统时出现问题,而这些系统可能依赖于特定的标头大小写。

为了支持这些用例,Envoy 允许配置标头的格式方案,这将使 Envoy 在序列化期间转换标头键。

要配置对响应标头的这种格式,请在http_protocol_options 中指定格式。要配置对上游请求标头的这种格式,请在集群的http_protocol_options 中指定格式,该格式位于extension_protocol_options 中。

目前 Envoy 支持两种相互排斥的标头键格式化程序类型

无状态格式化程序

无状态格式化程序在编码时运行,不依赖于任何关于标头的先前知识。这种格式化程序的一个示例是正确的大小写单词 格式化程序。当从非 HTTP/1 转换为 HTTP/1(在单个代理中或跨多个跃点)时,或者当由于内存需求增加而不需要有状态格式化时,这些格式化程序很有用。

有状态格式化程序

有状态格式化程序在解码时实例化,针对每个解码的标头调用,附加到标头映射,然后在编码期间可用,以在写入之前格式化标头。因此,它们遍历整个代理堆栈。这种格式化程序的一个示例是保留大小写格式化程序,它通过stateful_formatter 字段配置。以下是一个配置示例,它将在代理中保留 HTTP/1 标头大小写。

注意

当使用有状态格式化程序时,Envoy 或过滤器(例如 Lua 过滤器)内部添加的标头仍将小写。

static_resources:
  listeners:
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 443
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          http_protocol_options:
            header_key_format:
              stateful_formatter:
                name: preserve_case
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.http.header_formatters.preserve_case.v3.PreserveCaseFormatterConfig
          http_filters:
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
          route_config:
            virtual_hosts:
            - name: default
              domains: ["*"]
              routes:
              - match: {prefix: "/"}
                route:
                  cluster: service_foo
  clusters:
  - name: service_foo
    typed_extension_protocol_options:
      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
        "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
        explicit_http_config:
          http_protocol_options:
            header_key_format:
              stateful_formatter:
                name: preserve_case
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.http.header_formatters.preserve_case.v3.PreserveCaseFormatterConfig
    load_assignment:
      cluster_name: some_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 8080