ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Fluent Bit 依赖库 nghttp2 详解:nghttp2_option_set_builtin_recv_extension_type 与 HTTP/2 扩展帧接收机制

Fluent Bit 依赖库 nghttp2 详解:nghttp2_option_set_builtin_recv_extension_type 与 HTTP/2 扩展帧接收机制 Fluent Bit 依赖库 nghttp2 详解nghttp2_option_set_builtin_recv_extension_type 与 HTTP/2 扩展帧接收机制【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit导读本文聚焦于 nghttp2 库Fluent Bit 内置的 HTTP/2 实现位于 lib/nghttp2-1.65.0中一个易被忽视却十分关键的配置接口nghttp2_option_set_builtin_recv_extension_type。该接口决定应用是否愿意使用内建处理器接收 HTTP/2 扩展帧是 Fluent Bit 通过in_http、in_opentelemetry、out_http等插件收发 HTTP/2 流量包括 OTLP/gRPC 与 H2C 场景时正确解析 ALTSVC、ORIGIN、PRIORITY_UPDATE 三类扩展帧的前提。读完本文你将掌握该函数的签名、合法参数约束、与用户自定义扩展帧回调的优先级关系以及其在 nghttp2 源码中的完整处理路径并能在自己的 C 语言应用中正确启用内建扩展帧解析。函数速览nghttp2_option_set_builtin_recv_extension_type的官方 API 文档见 lib/nghttp2-1.65.0/doc/nghttp2_option_set_builtin_recv_extension_type.rst其完整声明位于头文件 lib/nghttp2-1.65.0/lib/includes/nghttp2/nghttp2.h#include nghttp2/nghttp2.h void nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option, uint8_t type);参数与语义参数含义option指向nghttp2_option结构体的指针该结构体在调用nghttp2_session_client_new/nghttp2_session_server_new创建会话时传入用于一次性设定会话级行为type应用希望接收的扩展帧类型frame type取值范围必须严格大于 0x9否则函数静默无操作扩展帧extension frame是 HTTP/2 规范RFC 7540 第 4.1 节为可扩展性预留的帧类型通道任何类型编号大于 0x9即大于标准帧类型最大值的帧均属于扩展帧。nghttp2 的枚举定义在 nghttp2.h 中NGHTTP2_ALTSVC 0x0a, /* 10ALTSVC 帧 */ NGHTTP2_ORIGIN 0x0c, /* 12ORIGIN 帧 */ NGHTTP2_PRIORITY_UPDATE 0x10 /* 16RFC 9218 优先级更新帧 */关键行为可重复调用该函数可以多次调用每次为一个帧类型开启内建接收能力从而累积接收多种扩展帧。纯发送场景无需调用如果应用只发送扩展帧例如使用nghttp2_submit_altsvc、nghttp2_submit_origin提交则完全不需要调用此函数。与用户回调的优先级如果同一个帧类型同时传给nghttp2_option_set_builtin_recv_extension_type()和nghttp2_option_set_user_recv_extension_type()则后者用户自定义回调优先。内建接收器与用户接收器两种扩展帧处理路径nghttp2 为扩展帧提供了两种接收机制其选路逻辑是理解本函数价值的关键用户自定义路径通过nghttp2_option_set_user_recv_extension_type()注册类型配合nghttp2_on_extension_chunk_recv_callback分块收取 payload与nghttp2_unpack_extension_callback最终解包两个回调由应用自行解析。这种方式适合私有/自定义扩展帧协议。内建路径通过本文主角nghttp2_option_set_builtin_recv_extension_type()注册类型由库内部针对ALTSVC、ORIGIN、PRIORITY_UPDATE三种标准化扩展帧实现的内建解析器直接处理无需应用编写任何解析代码。两条路径的分流在 lib/nghttp2-1.65.0/lib/nghttp2_session.c 的接收处理中体现首先用check_ext_type_set(session-user_recv_ext_types, ...)检查是否命中用户注册的类型集合若命中则进入NGHTTP2_IB_READ_EXTENSION_PAYLOAD状态交给用户回调否则才落入内建switch分支按三种内建类型分别处理。源码实现位掩码与白名单参数校验与掩码设置nghttp2_option_set_builtin_recv_extension_type的实现位于 lib/nghttp2-1.65.0/lib/nghttp2_option.cvoid nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option, uint8_t type) { switch (type) { case NGHTTP2_ALTSVC: option-opt_set_mask | NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES; option-builtin_recv_ext_types | NGHTTP2_TYPEMASK_ALTSVC; return; case NGHTTP2_ORIGIN: option-opt_set_mask | NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES; option-builtin_recv_ext_types | NGHTTP2_TYPEMASK_ORIGIN; return; case NGHTTP2_PRIORITY_UPDATE: option-opt_set_mask | NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES; option-builtin_recv_ext_types | NGHTTP2_TYPEMASK_PRIORITY_UPDATE; return; default: return; } }与用户路径set_ext_type使用逐位数组ext_types[type / 8]记录任意类型不同内建路径使用32 位掩码builtin_recv_ext_types该字段定义于 lib/nghttp2-1.65.0/lib/nghttp2_option.h 与 lib/nghttp2-1.65.0/lib/nghttp2_session.h位定义见 nghttp2_session.hNGHTTP2_TYPEMASK_ALTSVC 1 0, NGHTTP2_TYPEMASK_ORIGIN 1 1, NGHTTP2_TYPEMASK_PRIORITY_UPDATE 1 2注意此处参数校验方式与文档描述一致——非法类型≤ 0x9 或不在三种内建类型之列走default分支直接返回不设置任何掩码位即静默无操作。掩码如何进入会话调用该函数时设置的掩码并不会立即生效而是在创建会话时由 lib/nghttp2-1.65.0/lib/nghttp2_session.c 统一复制(*session_ptr)-builtin_recv_ext_types option-builtin_recv_ext_types;因此必须在nghttp2_session_client_new/nghttp2_session_server_new之前完成全部 option 设置之后对 option 的修改不再影响已创建的会话。典型的完整启用流程nghttp2_option *option; nghttp2_option_new(option); /* 依次开启三种内建扩展帧的接收 */ nghttp2_option_set_builtin_recv_extension_type(option, NGHTTP2_ALTSVC); nghttp2_option_set_builtin_recv_extension_type(option, NGHTTP2_ORIGIN); nghttp2_option_set_builtin_recv_extension_type(option, NGHTTP2_PRIORITY_UPDATE); nghttp2_session *session; nghttp2_session_server_new(session, callbacks, user_data, option); nghttp2_option_del(option); /* option 复制完成后即可释放 */内建扩展帧的接收处理链路扩展帧在会话中如何被识别与分发可以通过 lib/nghttp2-1.65.0/lib/nghttp2_session.c 的接收状态机逐步还原ALTSVC0x0a若未注册NGHTTP2_TYPEMASK_ALTSVC或当前会话是服务端session-server帧被静默忽略进入NGHTTP2_IB_IGN_PAYLOAD否则校验 payload 长度至少 2 字节的 Origin-Len 字段随后读取 Origin 与 Alt-Svc 字段并存储到ext_frame_payload.altsvc最终通过nghttp2_on_altsvc_recv_callback通知应用。ALTSVC 帧用于服务器通告某资源可用的替代服务如 HTTP/3属于客户端方向的帧因此服务端收到后会被忽略。ORIGIN0x0c若未注册NGHTTP2_TYPEMASK_ORIGIN、或当前是服务端、或携带 stream_id / 未知 flag帧被忽略否则为 payload 分配缓冲区并进入NGHTTP2_IB_READ_ORIGIN_PAYLOAD状态解析出若干 Origin 条目并通过nghttp2_on_origin_recv_callback通知。ORIGIN 帧由服务器在连接建立初期发送用于声明其服务的源origin集合。PRIORITY_UPDATE0x10若未注册NGHTTP2_TYPEMASK_PRIORITY_UPDATE帧被忽略否则读取 Prioritized Stream ID 与优先级字段通过nghttp2_on_priority_update_recv_callback通知。该帧由 RFC 9218 定义用于在连接级动态更新流的优先级通常与SETTINGS_NO_RFC7540_PRIORITIES配合使用。与之对称的释放逻辑在 nghttp2_session.c内建路径下帧内存的回收同样以掩码位为判断条件——未开启对应内建接收位则直接break避免了对未初始化扩展帧结构的错误释放。与用户自定义接收器的选路优先级在接收状态机的入口处两种路径的优先级非常明确见 nghttp2_session.cif (check_ext_type_set(session-user_recv_ext_types, iframe-frame.hd.type)) { /* 用户路径转交 unpack_extension_callback 等回调 */ } else { /* 内建路径按 ALTSVC / ORIGIN / PRIORITY_UPDATE 分别处理 */ }因此如果应用同时通过两个函数注册了同一个帧类型例如都注册NGHTTP2_ALTSVC实际生效的是用户回调路径此时内建解析与对应的nghttp2_on_altsvc_recv_callback等内建回调不会被触发。这一后者优先的约定在 nghttp2.h 的函数注释中亦有明确说明。这也意味着内建路径适合开箱即用地接收标准化扩展帧而用户路径适合对同一帧实施自定义解析或支持私有扩展帧类型。在 Fluent Bit 中的落地场景Fluent Bit 将 nghttp2 作为内置 HTTP/2 引擎见 cmake/nghttp2.cmake服务于多个网络插件。与本文主题最相关的落地场景包括in_http/out_http支持 HTTP/2 明文h2c与 TLS 场景是 Fluent Bit 与上游 HTTP 服务交互的通用通道。in_opentelemetry/out_opentelemetryOTLP 协议默认基于 gRPC/HTTP/2 传输nghttp2 负责 HTTP/2 帧层的编解码。in_forward/out_forward等其余基于 HTTP 语义的插件在启用 HTTP/2 时同样依赖该层。在这些插件的 HTTP/2 连接处理中是否启用内建扩展帧接收决定了能否解析对端如负载均衡器或 CDN发来的 ALTSVC、ORIGIN、PRIORITY_UPDATE 帧。结合上文的状态机可知未调用本函数注册对应类型时这些帧会被当作未知扩展帧静默忽略NGHTTP2_IB_IGN_PAYLOAD对端通告的替代服务、源集合或优先级更新信息将不可见。若你的部署需要感知这些信号例如跟随 ALTSVC 通告切换到 HTTP/3或按 ORIGIN 列表做域校验就需要在会话创建前完成注册。边界条件与注意事项type ≤ 0x9 一律无效标准帧类型DATA0x0、HEADERS0x1、PRIORITY0x2、RST_STREAM0x3、SETTINGS0x4、PUSH_PROMISE0x5、PING0x6、GOAWAY0x7、WINDOW_UPDATE0x8、CONTINUATION0x9无法通过本函数注册函数会静默返回。仅支持三种标准化类型内建实现只接受NGHTTP2_ALTSVC、NGHTTP2_ORIGIN、NGHTTP2_PRIORITY_UPDATE三个枚举值见 nghttp2_option.c其他大于 0x9 的类型应使用nghttp2_option_set_user_recv_extension_type()走用户回调。必须在创建会话前调用掩码仅在nghttp2_session_*_new时从 option 复制nghttp2_session.c会话创建后的修改不会生效。接收方向性ALTSVC 帧内建解析仅对客户端会话生效服务端会话收到后会被忽略ORIGIN 帧同理仅对客户端生效。这与各帧的协议语义一致。内存安全内建路径下 ALTSVC/ORIGIN 帧的 payload 由库管理帧处理完成后由 nghttp2_frame_altsvc_free /nghttp2_frame_origin_free自动释放PRIORITY_UPDATE 因字段指向内部 sbuf不做单独释放见 nghttp2_session.c应用只需在回调中按需拷贝数据即可无需关心释放时机。参考与延伸阅读官方 API 文档nghttp2_option_set_builtin_recv_extension_type.rst姊妹接口nghttp2_option_set_user_recv_extension_type.rst头文件声明与注释lib/includes/nghttp2/nghttp2.h实现与位掩码lib/nghttp2_option.c、lib/nghttp2_option.h接收状态机与分发lib/nghttp2_session.c、lib/nghttp2_session.h会话测试用例tests/nghttp2_session_test.cnghttp2 编程指南doc/programmers-guide.rst【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表