如何在Envoy中反序列化Protobuf格式的自定义请求头
在Envoy中处理OpenResty生成的Protobuf请求头:Lua反序列化与非Lua方案
一、Envoy内嵌Lua中反序列化Protobuf请求头
要在Envoy的Lua代码里解析x-internal-state-bin头的Protobuf数据,按以下步骤操作:
编译.proto为Lua模块
用protoc搭配Lua生成插件(比如protoc-gen-lua或protoc-gen-lua53,匹配你的Lua版本),将目标.proto文件编译成Lua可加载的解析模块。执行命令:protoc --lua_out=./ your_proto_file.proto执行后会生成对应的
your_proto_file_pb.lua文件。在Envoy Lua脚本中加载模块并解析
把生成的Lua模块放到Envoy可访问的路径(比如配置的lua_code_cache对应目录),然后编写Lua代码:-- 加载生成的Protobuf解析模块 local internal_state_pb = require("your_proto_file_pb") function envoy_on_request(request_handle) -- 获取请求头的二进制数据 local state_bin = request_handle:headers():get("x-internal-state-bin") if not state_bin then return end -- 反序列化二进制数据为Protobuf结构体 local internal_state = internal_state_pb.InternalState() -- 若OpenResty端对Protobuf做了base64编码,需先解码(比如引入Lua base64库处理) internal_state:ParseFromString(state_bin) -- 访问解析后的字段示例 print("Parsed state ID: " .. internal_state.id) end注意:确保请求头的二进制数据未被额外编码(如base64),如果有编码操作,需在解析前先解码。
二、非Lua过滤器的解决方案
如果不想通过Lua处理,有两种实用替代方案:
1. 使用Envoy Protobuf Transformer过滤器
该过滤器可直接解析二进制Protobuf数据,并将解析后的字段存入请求metadata,后续其他过滤器或路由配置可直接引用这些元数据。
示例配置片段:
http_filters: - name: envoy.filters.http.protobuf_transformer typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.protobuf_transformer.v3.ProtobufTransformer proto_descriptor: "/path/to/your_proto_descriptor_set.pb" request_transform: extractors: - header_name: "x-internal-state-bin" message_type: "your.package.InternalState" metadata_namespace: "internal_state"
- 先通过
protoc --descriptor_set_out=your_proto_descriptor_set.pb your_proto_file.proto生成proto_descriptor所需的描述符文件。 - 解析后的数据会存入请求metadata的
internal_state命名空间,后续可通过metadata.internal_state.field_name引用字段。
2. 自定义C++过滤器
如果需要处理复杂业务逻辑或追求更高性能,可基于Envoy的C++ SDK编写自定义HTTP过滤器。在过滤器的decodeHeaders阶段读取x-internal-state-bin头的二进制数据,用Protobuf C库直接解析,再将结果存入请求的stream info或metadata供后续流程使用。该方案需要编写C代码并编译到Envoy中,适合定制化需求较强的场景。
内容的提问来源于stack exchange,提问作者meshkati
相关产品推荐
相关产品推荐

