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