Skip to content

cherry pick 3 pr from envoy-proxy#13

Closed
jue-yin wants to merge 2 commits intohigress-group:envoy-1.27from
jue-yin:dev-higress-mcp-sse-stateful-session-baseline
Closed

cherry pick 3 pr from envoy-proxy#13
jue-yin wants to merge 2 commits intohigress-group:envoy-1.27from
jue-yin:dev-higress-mcp-sse-stateful-session-baseline

Conversation

@jue-yin
Copy link
Copy Markdown

@jue-yin jue-yin commented Aug 24, 2025

cherry-pick from envoyproxy#39004 envoyproxy@eb0aa19 new feature stateful session envelope, aiming to cover MCP 250326 spec SSE

cherry-pick from envoyproxy#30573 envoyproxy@62f4a14#diff-c904f9b0d49cdd938ffaa952192372529415afa8602d7dc6acb904e61111d8a5 add strict mode to stateful session, return 503 when destination is not available

cherry-pick from envoyproxy#32093 envoyproxy@6354dcf support 0 ttl in cookie stateful sessiion to disable cookie expiration

…eful session envelope, aiming to cover MCP 250326 spec SSE

cherry-pick from envoyproxy#30573 envoyproxy@62f4a14#diff-c904f9b0d49cdd938ffaa952192372529415afa8602d7dc6acb904e61111d8a5 add strict mode to stateful session, return 503 when destination is not available

cherry-pick from envoyproxy#32093 envoyproxy@6354dcf support 0 ttl in cookie stateful sessiion to disable cookie expiration

Signed-off-by: 爵银 <jueyin.hsl@alibaba-inc.com>
Signed-off-by: 爵银 <jueyin.hsl@alibaba-inc.com>
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Aug 24, 2025

CLA assistant check
All committers have signed the CLA.

@jue-yin jue-yin changed the title Dev higress mcp sse stateful session baseline cherry pick 3 pr from envoy-proxy Aug 24, 2025
@lingma-agents
Copy link
Copy Markdown

lingma-agents bot commented Aug 24, 2025

实现状态会话的信封模式并增强严格模式支持

变更概述
  • 新功能

    • 新增了envelope类型的状态会话扩展,用于通过现有会话上下文跟踪会话状态。
    • 实现了EnvelopeSessionState消息定义和相关工厂类,支持在请求和响应中处理带有上游主机信息的会话头。
    • 添加了对状态会话严格模式的支持,当目标不可用时返回503错误。
  • 重构

    • 修改了SessionState接口中的onUpdate方法签名,以适应新的参数需求。
    • 更新了SessionStateFactory接口中的create方法签名,统一了参数传递方式。
  • 问题修复

    • 修复了Cookie状态会话中TTL为0时的处理逻辑,允许禁用Cookie过期时间。
    • 修复了在严格模式下,如果目标主机不存在则不应选择其他主机的问题。
  • 测试更新

    • 增加了针对新envelope状态会话扩展的集成测试配置。
    • 扩展了ClusterManagerImplTestHostUtilityTest,覆盖了新的严格模式逻辑和非存在主机场景。
    • 添加了FilterManagerTestRouterTest中的upstreamOverrideHost功能测试。
  • 配置调整

    • CODEOWNERS文件中添加了对envelope状态会话扩展的维护者信息。
    • 更新了api/BUILDapi/versioning/BUILD文件,包含了新的envelope协议包依赖。
    • extensions_build_config.bzlextensions_metadata.yaml中注册了新的envelope扩展。
  • 其他

    • 增加了Base64::encode的重载版本,支持absl::string_view输入。
    • 更新了StreamDecoderFilterCallbacks接口,添加了setUpstreamOverrideHostupstreamOverrideHost方法。
变更文件
文件路径 变更说明
CODEOWNERS 添加了对新envelope状态会话扩展的维护者信息。
api/BUILD 在构建配置中添加了对envelope状态会话协议包的依赖。
api/​envoy/​extensions/​filters/​http/​stateful_​session/​v3/​stateful_​session.​proto 添加了strict字段以启用严格模式,当目标不可用时返回503。
api/​envoy/​extensions/​http/​stateful_​session/​envelope/​v3/​envelope.​proto 定义了新的EnvelopeSessionState消息,用于通过头信息跟踪会话状态。
api/​envoy/​type/​http/​v3/​cookie.​proto 更新了Cookie的TTL描述,明确设置为0s时禁用Cookie过期。
api/versioning/BUILD 在版本控制构建配置中添加了envelope状态会话协议包。
envoy/http/filter.h 添加了setUpstreamOverrideHost和upstreamOverrideHost方法到StreamDecoderFilterCallbacks接口。
envoy/http/stateful_session.h 更新了SessionState和SessionStateFactory接口方法签名。
envoy/​upstream/​load_​balancer.​h 定义了OverrideHost类型,用于表示覆盖主机及其严格模式。
source/​common/​common/​base64.​cc 添加了Base64编码的absl::string_view重载版本。
source/common/common/base64.h 声明了新的Base64编码函数,支持absl::string_view输入。
source/​common/​http/​async_​client_​impl.​h 实现了setUpstreamOverrideHost和upstreamOverrideHost的空方法。
source/​common/​http/​filter_​manager.​cc 实现了ActiveStreamDecoderFilter中的主机覆盖方法。
source/​common/​http/​filter_​manager.​h 在FilterManager中添加了对上游主机覆盖的支持。
source/​common/​upstream/​cluster_​manager_​impl.​cc 在集群管理器中添加了对严格模式主机选择的检查。
source/​common/​upstream/​host_​utility.​cc 实现了allowLBChooseHost函数,用于控制负载均衡器是否可以选择主机。
source/​common/​upstream/​host_​utility.​h 声明了allowLBChooseHost函数。
source/​extensions/​common/​wasm/​context.​cc 更新了WASM上下文中的主机覆盖设置,支持严格模式。
source/​extensions/​common/​wasm/​context.​h 包含了StringPairs类型定义。
source/​extensions/​extensions_​build_​config.​bzl 在扩展构建配置中注册了envelope状态会话扩展。
source/​extensions/​extensions_​metadata.​yaml 在扩展元数据中添加了envelope状态会话扩展的信息。
source/​extensions/​filters/​http/​stateful_​session/​stateful_​session.​cc 实现了状态会话过滤器,支持严格模式和主机覆盖。
source/​extensions/​filters/​http/​stateful_​session/​stateful_​session.​h 更新了状态会话配置类,添加了严格模式支持。
source/​extensions/​http/​stateful_​session/​cookie/​cookie.​cc 更新了Cookie会话状态的更新逻辑,支持TTL为0的情况。
source/​extensions/​http/​stateful_​session/​cookie/​cookie.​h 更新了Cookie会话状态工厂的创建方法签名。
source/​extensions/​http/​stateful_​session/​envelope/​BUILD 创建了envelope状态会话扩展的构建配置。
source/​extensions/​http/​stateful_​session/​envelope/​config.​cc 实现了envelope会话状态工厂的配置类。
source/​extensions/​http/​stateful_​session/​envelope/​config.​h 声明了envelope会话状态工厂配置类。
source/​extensions/​http/​stateful_​session/​envelope/​envelope.​cc 实现了envelope会话状态的处理逻辑,包括请求和响应的处理。
source/​extensions/​http/​stateful_​session/​envelope/​envelope.​h 声明了envelope会话状态工厂和会话状态实现类。
source/​extensions/​http/​stateful_​session/​header/​header.​cc 更新了头会话状态的更新逻辑。
source/​extensions/​http/​stateful_​session/​header/​header.​h 更新了头会话状态工厂的创建方法签名。
test/​common/​http/​filter_​manager_​test.​cc 添加了对setUpstreamOverrideHost和upstreamOverrideHost方法的测试。
test/​common/​router/​router_​test.​cc 添加了对路由中主机覆盖功能的测试。
test/​common/​upstream/​cluster_​manager_​impl_​test.​cc 扩展了集群管理器测试,覆盖了严格模式和非存在主机场景。
test/​common/​upstream/​host_​utility_​test.​cc 更新了主机工具测试,覆盖了严格模式和不同健康状态的主机。
test/​extensions/​filters/​http/​stateful_​session/​BUILD 在测试构建配置中添加了对envelope扩展的支持。
test/​extensions/​filters/​http/​stateful_​session/​stateful_​session_​integration_​test.​cc 添加了针对envelope状态会话扩展的集成测试。
时序图
sequenceDiagram
    participant Client as HTTP客户端
    participant Proxy as Envoy代理
    participant Upstream as 上游服务器
    Client->>Proxy: 发送初始请求
    Proxy->>Upstream: 转发请求
    Upstream->>Proxy: 返回带会话上下文的响应
    Proxy->>Client: 返回编码后的会话上下文
    Client->>Proxy: 发送后续请求(带会话上下文)
    Proxy->>Upstream: 解码会话上下文并转发到指定主机
Loading

💡 小贴士

与 lingma-agents 交流的方式

📜 直接回复评论
直接回复本条评论,lingma-agents 将自动处理您的请求。例如:

  • 在当前代码中添加详细的注释说明。

  • 请详细介绍一下你说的 LRU 改造方案,并使用伪代码加以说明。

📜 在代码行处标记
在文件的特定位置创建评论并 @lingma-agents。例如:

  • @lingma-agents 分析这个方法的性能瓶颈并提供优化建议。

  • @lingma-agents 对这个方法生成优化代码。

📜 在讨论中提问
在任何讨论中 @lingma-agents 来获取帮助。例如:

  • @lingma-agents 请总结上述讨论并提出解决方案。

  • @lingma-agents 请根据讨论内容生成优化代码。

Copy link
Copy Markdown

@lingma-agents lingma-agents bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔎 代码评审报告

🎯 评审意见概览
严重度 数量 说明
🔴 Blocker 0 阻断性问题,需立即修复。例如:系统崩溃、关键功能不可用或严重安全漏洞。
🟠 Critical 0 严重问题,高优先级修复。例如:核心功能异常或性能瓶颈影响用户体验。
🟡 Major 0 主要问题,建议修复。例如:非核心功能缺陷或代码维护性较差。
🟢 Minor 1 次要问题,酬情优化。例如:代码格式不规范或注释缺失。

总计: 1 个问题

📋 评审意见详情
💡 代码实现建议
以下是文件级别的代码建议,聚焦于代码的可读性、可维护性和潜在问题。
📄 test/common/upstream/host_utility_test.cc (1 💬)
🚀 架构设计建议
以下是对代码架构和设计的综合分析,聚焦于跨文件交互、系统一致性和潜在优化空间。
🔍1. 新增的严格模式可能影响负载均衡行为一致性

StatefulSession 过滤器中引入了 strict 模式,当设置为 true 时,如果请求的目标主机不可用则返回 503。这种变更会影响负载均衡器的行为,可能导致在某些部署场景下服务的可用性下降。建议评估该模式对现有部署的影响,并确保文档清晰说明其行为差异。

📌 关键代码

// If set to True, the HTTP request must be routed to the requested destination.
  // If the requested destination is not available, Envoy returns 503. Defaults to False.
  bool strict = 2;
decoder_callbacks_->setUpstreamOverrideHost(
        std::make_pair(upstream_address.value(), config->isStrict()));

⚠️ 潜在风险

可能导致服务在部分主机不可用时整体不可访问,降低系统容错能力

🔍2. 新引入的 Envelope 状态会话机制缺乏充分的安全性和健壮性验证

新增的 EnvelopeSessionState 通过编码上游主机地址和原始值到头部中,这种方式可能存在安全风险,例如头部注入或信息泄露。此外,解析逻辑较为复杂,容易出现边界条件处理不当的问题。建议增加针对恶意输入和异常情况的测试,并审查其在高负载下的性能表现。

📌 关键代码

void EnvelopeSessionStateFactory::SessionStateImpl::onUpdate(
    absl::string_view host_address, Envoy::Http::ResponseHeaderMap& headers) {
  const auto upstream_value_header = headers.get(factory_.name_);
  if (upstream_value_header.size() != 1) {
    ENVOY_LOG(trace, "Header {} not exist or occurs multiple times", factory_.name_);
    return;
  }
  const std::string new_header =
      absl::StrCat(Envoy::Base64::encode(host_address), ";", OriginUpstreamValuePartFlag,
                   Envoy::Base64::encode(upstream_value_header[0]->value().getStringView()));
  headers.setReferenceKey(factory_.name_, new_header);
}

⚠️ 潜在风险

存在潜在的头部注入、信息泄露和拒绝服务攻击风险

🔍3. 多状态会话实现之间的代码重复和维护成本增加

新增的 EnvelopeSessionState 和已有的 CookieBasedSessionStateHeaderBasedSessionState 在功能上存在相似性,特别是在处理上游地址更新和解析方面。这导致了代码重复,增加了未来的维护成本。建议抽象出通用的状态处理逻辑,减少重复代码并提高可维护性。

📌 关键代码

⚠️ 潜在风险

增加未来修改和扩展的工作量,提高引入错误的可能性

🔍4. Base64 编码函数重载可能引发混淆和潜在错误

Base64 类中新增了接受 absl::string_view 参数的 encode 函数重载。虽然提供了便利,但可能会与现有的接受 const char* 和长度的版本造成混淆,尤其是在模板推导或隐式转换时。建议明确区分使用场景,并添加相应的测试用例以避免潜在错误。

📌 关键代码

std::string Base64::encode(absl::string_view input) { return encode(input.data(), input.length()); }
/**
   * Base64 encode an input char buffer with a given length.
   * @param input string to encode.
   */
  static std::string encode(absl::string_view input);

⚠️ 潜在风险

可能导致意外的类型转换或调用错误的重载函数,引起运行时错误

🔍5. HostUtility::allowLBChooseHost 逻辑与 strict 模式存在潜在冲突

HostUtility::allowLBChooseHost 函数根据 overrideHostToSelect 的 strict 标志决定是否允许负载均衡器选择主机。然而,其逻辑是返回 !override_host.value().second,即 strict 为 true 时不允许 LB 选择。这种设计可能与其他地方的 strict 行为不一致,建议统一语义并在文档中明确说明。

📌 关键代码

bool HostUtility::allowLBChooseHost(LoadBalancerContext* context) {
  if (context == nullptr) {
    return true;
  }
  auto override_host = context->overrideHostToSelect();
  if (!override_host.has_value()) {
    return true;
  }
  // Return opposite value to "strict" setting.
  return !override_host.value().second;
}

⚠️ 潜在风险

可能导致负载均衡行为不符合预期,影响服务路由的正确性

审查详情
📒 文件清单 (49 个文件)
新增: 10 个文件
📝 变更: 39 个文件

✅ 新增文件:

  • api/envoy/extensions/http/stateful_session/envelope/v3/BUILD
  • api/envoy/extensions/http/stateful_session/envelope/v3/envelope.proto
  • source/extensions/http/stateful_session/envelope/BUILD
  • source/extensions/http/stateful_session/envelope/config.cc
  • source/extensions/http/stateful_session/envelope/config.h
  • source/extensions/http/stateful_session/envelope/envelope.cc
  • source/extensions/http/stateful_session/envelope/envelope.h
  • test/extensions/http/stateful_session/envelope/BUILD
  • test/extensions/http/stateful_session/envelope/config_test.cc
  • test/extensions/http/stateful_session/envelope/envelope_test.cc

📝 变更文件:

  • CODEOWNERS
  • api/BUILD
  • api/envoy/extensions/filters/http/stateful_session/v3/stateful_session.proto
  • api/envoy/type/http/v3/cookie.proto
  • api/versioning/BUILD
  • envoy/http/filter.h
  • envoy/http/stateful_session.h
  • envoy/upstream/load_balancer.h
  • source/common/common/base64.cc
  • source/common/common/base64.h
  • source/common/http/async_client_impl.h
  • source/common/http/filter_manager.cc
  • source/common/http/filter_manager.h
  • source/common/runtime/runtime_features.cc
  • source/common/upstream/cluster_manager_impl.cc
  • source/common/upstream/host_utility.cc
  • source/common/upstream/host_utility.h
  • source/extensions/common/wasm/context.cc
  • source/extensions/common/wasm/context.h
  • source/extensions/extensions_build_config.bzl
  • source/extensions/extensions_metadata.yaml
  • source/extensions/filters/http/stateful_session/stateful_session.cc
  • source/extensions/filters/http/stateful_session/stateful_session.h
  • source/extensions/http/stateful_session/cookie/cookie.cc
  • source/extensions/http/stateful_session/cookie/cookie.h
  • source/extensions/http/stateful_session/header/header.cc
  • source/extensions/http/stateful_session/header/header.h
  • test/common/http/filter_manager_test.cc
  • test/common/router/router_test.cc
  • test/common/upstream/cluster_manager_impl_test.cc
  • test/common/upstream/host_utility_test.cc
  • test/extensions/filters/http/stateful_session/BUILD
  • test/extensions/filters/http/stateful_session/stateful_session_integration_test.cc
  • test/extensions/filters/http/stateful_session/stateful_session_test.cc
  • test/extensions/http/stateful_session/cookie/cookie_test.cc
  • test/extensions/http/stateful_session/header/header_test.cc
  • test/mocks/http/mocks.cc
  • test/mocks/http/mocks.h
  • test/mocks/http/stateful_session.h

💡 小贴士

与 lingma-agents 交流的方式

📜 直接回复评论
直接回复本条评论,lingma-agents 将自动处理您的请求。例如:

  • 在当前代码中添加详细的注释说明。

  • 请详细介绍一下你说的 LRU 改造方案,并使用伪代码加以说明。

📜 在代码行处标记
在文件的特定位置创建评论并 @lingma-agents。例如:

  • @lingma-agents 分析这个方法的性能瓶颈并提供优化建议。

  • @lingma-agents 对这个方法生成优化代码。

📜 在讨论中提问
在任何讨论中 @lingma-agents 来获取帮助。例如:

  • @lingma-agents 请总结上述讨论并提出解决方案。

  • @lingma-agents 请根据讨论内容生成优化代码。

Comment on lines +174 to +183
// Test overriding host in strict and non-strict mode.
for (const bool strict_mode : {false, true}) {
{
// The host map does not contain the expected host.
LoadBalancerContext::OverrideHost override_host{"1.2.3.4", strict_mode};
EXPECT_CALL(context, overrideHostToSelect())
.WillOnce(Return(absl::make_optional(override_host)));
auto host_map = std::make_shared<HostMap>();
EXPECT_EQ(nullptr, HostUtility::selectOverrideHost(host_map.get(), HealthyStatus, &context));
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

应确保在主机工具测试中正确验证严格模式下的主机选择。

🟢 Minor | 🧹 Code Smells

📋 问题详情

在主机工具测试中,SelectOverrideHostTest测试用例用于验证在严格模式下主机选择的行为。当前测试用例可能未完全覆盖所有情况,需要确保在所有情况下都能正确验证严格模式下的主机选择。

💡 解决方案

确保在主机工具测试中正确验证严格模式下的主机选择。

-  // Test overriding host in strict and non-strict mode.\n  for (const bool strict_mode : {false, true}) {\n    {\n      // The host map does not contain the expected host.\n      LoadBalancerContext::OverrideHost override_host{\"1.2.3.4\", strict_mode};\n      EXPECT_CALL(context, overrideHostToSelect())\n          .WillOnce(Return(absl::make_optional(override_host)));\n      auto host_map = std::make_shared<HostMap>();\n      EXPECT_EQ(nullptr, HostUtility::selectOverrideHost(host_map.get(), HealthyStatus, &context));\n    }
+  // Test overriding host in strict and non-strict mode.\n  for (const bool strict_mode : {false, true}) {\n    {\n      // The host map does not contain the expected host.\n      LoadBalancerContext::OverrideHost override_host{\"1.2.3.4\", strict_mode};\n      EXPECT_CALL(context, overrideHostToSelect())\n          .WillOnce(Return(absl::make_optional(override_host)));\n      auto host_map = std::make_shared<HostMap>();\n      EXPECT_EQ(nullptr, HostUtility::selectOverrideHost(host_map.get(), HealthyStatus, &context));\n    }

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

@johnlanni johnlanni closed this Aug 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants