HTTP/1.1 標頭大小寫

在處理 HTTP/1.1 時,Envoy 會將標頭鍵正規化為全部小寫。雖然這符合 HTTP/1.1 規範,但在實務上,當遷移可能依賴特定標頭大小寫的現有系統時,可能會導致問題。

為了支援這些用例,Envoy 允許設定標頭的格式化方案,這將使 Envoy 在序列化期間轉換標頭鍵。

若要在回應標頭上設定此格式化,請在http_protocol_options中指定格式。若要為上游請求標頭設定此格式化,請在叢集的extension_protocol_options中的http_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