ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Envoy Custom Response 过滤器修复:`%LOCAL_REPLY_BODY%` 正确继承已有本地回复正文

Envoy Custom Response 过滤器修复:`%LOCAL_REPLY_BODY%` 正确继承已有本地回复正文 Envoy Custom Response 过滤器修复%LOCAL_REPLY_BODY%正确继承已有本地回复正文【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy导读本文围绕 changelogs/current/bug_fixes/http__custom-response-local-reply-body.rst 记录的 Envoy 修复展开Custom Response 过滤器的 Local Response Policy 在未配置自有body时body_format中的%LOCAL_REPLY_BODY%命令占位符如今能够拿到过滤器捕获到的原始本地回复正文。读完本文你将掌握该修复的触发条件、%LOCAL_REPLY_BODY%的取值优先级、相关配置字段的完整语义以及如何基于仓库源码与测试用例验证和运用这一行为。变更背景本地回复正文的丢失问题Custom Response 过滤器的职责Custom Response 过滤器扩展名envoy.filters.http.custom_response允许 Envoy 替换上游响应通过一棵匹配树matcher tree将原始响应按状态码、响应头、甚至原始请求头与某条 Custom Response Policy 匹配命中后由该策略改写响应。配置可在过滤器、虚拟主机或路由三个层级下发匹配时按从最具体到最不具体的顺序遍历直至找到匹配项详见 api/envoy/extensions/filters/http/custom_response/v3/custom_response.proto。其中 Local Response Policy扩展名envoy.http.custom_response.local_response_policy用于直接向客户端发送本地构造的响应其完整字段定义在 api/envoy/extensions/http/custom_response/local_response_policy/v3/local_response_policy.proto字段类型说明bodyconfig.core.v3.DataSource可选的本地回复正文可来自内联字符串、文件或环境变量会作为body_format中%LOCAL_REPLY_BODY%的输入body_formatconfig.core.v3.SubstitutionFormatString可选的正文格式化模板未配置时若配置了body则body内容原样作为正文不经过格式化status_codegoogle.protobuf.UInt32Value新的响应状态码校验规则为200 code 600未设置时沿用原始响应状态码response_headers_to_addrepeated HeaderValueOption追加、新增或覆盖响应头最多 1000 项preserve_response_code_detailsbool若设置保留 StreamInfo 上已有的response_code_detailsresponse_code_detailsstring用显式字符串替换response_code_details修复前的缺陷在 Envoy 中本地回复local reply是指由 Envoy 自身而非上游直接生成并发送给客户端的响应例如鉴权失败、限流、路由失败等场景。当本地回复在过滤器链中产生时onLocalReply回调会被触发回调参数LocalReplyData::body_中携带该本地回复的正文。修复前若 Local Response Policy 只配置了body_format未配置body%LOCAL_REPLY_BODY%占位符会被空字符串填充——因为策略内部的local_body_为空格式化时无法得知原始本地回复的正文是什么。这导致格式化后的响应丢失了本应保留的原始正文内容。修复原理onLocalReply 捕获 encodeHeaders 回填过滤器侧捕获本地回复正文Custom Response 过滤器本身是一个 Pass-Through 过滤器其关键逻辑在 source/extensions/filters/http/custom_response/custom_response_filter.h::Envoy::Http::LocalErrorStatus onLocalReply(const ::Envoy::Http::StreamFilterBase::LocalReplyData data) override { on_local_reply_called_ true; // LocalReplyData::body_ is valid only during this callback, so retain an owned copy for the // local response policy to use later in encodeHeaders(). local_reply_body_ std::string(data.body_); return ::Envoy::Http::LocalErrorStatus::Continue; } absl::string_view localReplyBody() const { return local_reply_body_; }关键点在于LocalReplyData::body_仅在回调期间有效因此过滤器拷贝一份自有副本local_reply_body_供后续encodeHeaders阶段使用。随后通过localReplyBody()暴露给策略读取。策略侧仅在有 formatter、无显式 body时回填Local Response Policy 的实现在 source/extensions/http/custom_response/local_response_policy/local_response_policy.cc。构造阶段策略读取配置若配置了body则通过Config::DataSource::read()读取内联/文件/环境变量并存入local_body_若配置了body_format则通过SubstitutionFormatStringUtils::fromProtoConfig()构建formatter_。在encodeHeaders中修复的核心逻辑为std::string body; // When body_format is configured without an explicit body, seed %LOCAL_REPLY_BODY% with the // body captured from the original local reply. Limiting this to the formatter path keeps an // explicit body authoritative, while policies with neither body nor body_format retain their // existing empty body behavior. if (formatter_ !local_body_.has_value()) { body std::string(custom_response_filter.localReplyBody()); } Envoy::Http::Code code getStatusCodeForLocalReply(headers); formatBody(...);formatBody随后执行格式化若local_body_有值则直接采用若存在formatter_则以{request_headers, response_headers, body}为上下文执行替换使%LOCAL_REPLY_BODY%得到正确的输入。取值优先级行为边界结合 local_response_policy.cc 与测试%LOCAL_REPLY_BODY%的取值遵循如下优先级策略显式配置了body%LOCAL_REPLY_BODY%展开为body的内容显式 body 具有权威性见下方测试未配置body、但配置了body_format且存在本地回复%LOCAL_REPLY_BODY%展开为过滤器捕获的原始本地回复正文body与body_format均未配置保持原有的空正文行为不变。配置示例场景一对已有本地回复做格式化包装修复后的典型用法仅配置body_format不对body做任何设置。当上游/过滤器链产生本地回复如 401时%LOCAL_REPLY_BODY%将展开为原始本地回复正文http_filters: - name: envoy.filters.http.custom_response typed_config: type: type.googleapis.com/envoy.extensions.filters.http.custom_response.v3.CustomResponse custom_response_matcher: matcher_list: matchers: - predicate: single_predicate: input: name: local_reply typed_config: type: type.googleapis.com/envoy.type.matcher.v3.HttpResponseLocalReplyMatchInput value_match: exact: true on_match: action: name: action typed_config: type: type.googleapis.com/envoy.extensions.http.custom_response.local_response_policy.v3.LocalResponsePolicy body_format: text_format_source: inline_string: formatted: %LOCAL_REPLY_BODY%场景二显式 body 覆盖原始本地回复同时配置body与body_format时body优先级更高# 伪代码示意完整结构同场景一 LocalResponsePolicy: body: inline_string: configured body body_format: text_format_source: inline_string: [%LOCAL_REPLY_BODY%]场景三自定义 JSON 本地响应自定义 4xx 响应并输出 JSON 格式字段级复用%LOCAL_REPLY_BODY%完整示例参考 custom_response.protohttp_filters: - name: envoy.filters.http.custom_response typed_config: type: type.googleapis.com/envoy.extensions.filters.http.custom_response.v3.CustomResponse custom_response_matcher: matcher_list: matchers: - predicate: single_predicate: input: name: 4xx_response typed_config: type: type.googleapis.com/envoy.type.matcher.v3.HttpResponseStatusCodeClassMatchInput value_match: exact: 4xx on_match: action: name: action typed_config: type: type.googleapis.com/envoy.extensions.http.custom_response.local_response_policy.v3.LocalResponsePolicy status_code: 499 body: inline_string: not allowed body_format: json_format: status: %RESPONSE_CODE% message: %LOCAL_REPLY_BODY% response_headers_to_add: - header: key: foo value: x-bar测试验证单测与集成测试单元测试test/extensions/filters/http/custom_response/custom_response_filter_test.cc 中与本次修复直接相关的用例ExistingLocalReplyBodyWithFormatter仅配置body_format: %LOCAL_REPLY_BODY%先触发onLocalReply本地回复正文为original body随后断言sendLocalReply收到的正文为original body——证明修复生效const ::Envoy::Http::StreamFilterBase::LocalReplyData local_reply_data{ ::Envoy::Http::Code::Unauthorized, std::nullopt, details, false, original body}; EXPECT_EQ(filter_-onLocalReply(local_reply_data), ::Envoy::Http::LocalErrorStatus::Continue); ... EXPECT_CALL(encoder_callbacks_, sendLocalReply(::Envoy::Http::Code::Unauthorized, original body, _, _, _));ConfiguredBodyTakesPrecedenceOverExistingLocalReplyBody同时配置body: configured body与body_format: [%LOCAL_REPLY_BODY%]即使已有本地回复正文original body最终正文仍为[configured body]——验证显式body的权威性。EmptyPolicyKeepsEmptyBodybody与body_format均未配置时正文保持为空——确认原有空正文行为未被破坏。集成测试test/extensions/filters/http/custom_response/custom_response_integration_test.cc 中的ExistingLocalReplyBodyWithFormatter用例通过真实 HTTP 请求验证端到端行为使用HttpResponseLocalReplyMatchInput匹配本地回复配置body_format: formatted: %LOCAL_REPLY_BODY%断言响应状态码为201、正文为formatted: Response body。修复的价值与适用边界价值本地回复正文如各过滤器生成的错误信息、鉴权提示等不再被%LOCAL_REPLY_BODY%静默丢弃可被统一包装进自定义格式文本或 JSON后返回客户端同时保持显式body的完全覆盖能力。边界修复仅作用于 Local Response Policy 的 formatter 路径若策略既无body也无body_format正文仍为空若策略配置了显式body则本地回复正文不会参与格式化。此外若响应并非本地回复未触发onLocalReplylocal_reply_body_为空%LOCAL_REPLY_BODY%相应展开为空字符串——请在依赖该占位符前确保业务场景确实经过本地回复路径。提示若需要针对已有本地回复精确构造自定义响应可同时组合HttpResponseLocalReplyMatchInput匹配输入与LocalResponsePolicy即可实现仅对本地回复生效的格式化策略这正是本次修复所覆盖的核心场景。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表