TrafficServer http2 代码分析
2021-03-14 14:29
标签:proc point ons remove 移除 oca 基金会 read scl TrafficServer 是Apache基金会的 HTTP/HTTP2 代理服务器。 TrafficServer 的 HTTP2 部分主要的代码在 : 10种Frame 的struct定义,解析/序列化函数,HeaderList转换函数,一些常量定义 Http2ClientSession 处理 io event 事件,解析 FrameHeader, 调用顺序: Http2ConnectionState,对应一个 HTTP2 连接,代码基本等价于 proxygen 的 HTTPSession,主要的成员变量: 主要的方法:各个 rcv_xxx_frame() 和 send_xxx_frame(0 还有发送各类 frame 的接口,send_data_frames()/send_headers_frame() / send_push_promise_frame() / send_rst_stream_frame() 等。 具体地: find_stream,然后检查stream的state是不是OPEN/HALF_CLOSE_LOCAL,去除 padding,处理END_STREAM flag,检查本端流量控制 window_size ,保存buffer,更新本地的window,发回 Connection 和 Stream Level 的WindowUpdate Frame。 find_stream/create_stream,处理padding,处理PRIORITY flag添加到 PriorityTree 里面,如果 Header Block 结束了(即有END_HEADERS FLAG),那就http2_decode_header_blocks() 做HPACK 解压缩,调用 Http2Stream 处理解析出的HeaderList find_stream,reprioritize,重新调整树。 parse检查收到的各个配置项,更新到client_settings中,并发送SETTINGS_ACK 包括 rcv_ping_frame rcv_goaway_frame: rcv_window_update_frame 比较简单,略。 类似 rcv_headers_frame 取了 DependencyTree的top(), send_a_data_frame send_headers_frame send_push_promise_frame send_rst_stream_frame send_settings_frame send_ping_frame send_goaway_frame send_window_update_frame 比较简单,就是检查字段合法性,序列化,然后发送。 对应实现HTTP2 的Stream,重要的成员变量有: Http2StreamState _state;//实现IDLE,OPEN,RESERVED,HALF_CLOSE等的切换。 DependencyTree::Node *priority_node;// Priority Tree中的节点指针。 Http2DependencyTree::Node 表示一个Stream,成员变量有: Http2DependencyTree 中有个 Node * root 指向 树的根节点。 Http2DependencyTree的主要方法有: Node *find(uint32_t id); Node *add(uint32_t parent_id, uint32_t id, uint32_t weight, bool exclusive, T t); void remove(Node *node); void reprioritize(uint32_t new_parent_id, uint32_t id, bool exclusive); Node *top(); void activate(Node *node); void deactivate(Node *node, uint32_t sent); void update(Node *node, uint32_t sent); 这里使用 Weighted Fair Queue (WFQ) Scheduling 来调度 Stream 之间的优先级。 Http2ConnectionState::send_data_frames_depends_on_priority() 实现 HPACK 压缩/解压缩 实现静态的 Huffman 表,接口简单,只有4个函数,, 是实现成 二叉树,相比proxygen估计效率会低一些。 TrafficServer http2 代码分析 标签:proc point ons remove 移除 oca 基金会 read scl 原文地址:https://www.cnblogs.com/windydays/p/12810658.html
1. trafficserver/proxy/http2/HTTP2.h, HTTP2.cc
2. trafficserver/proxy/http2/Http2ClientSession.h, Http2ClientSession.cc
Http2ClientSession::main_event_handler()
--> state_read_connection_preface()
--> state_start_frame_read()
--> state_process_frame_read() 解析出一个完整的Frame
--> do_complete_frame_read()
--> Http2ConnectionState::main_event_handler(HTTP2_SESSION_EVENT_RECV )
3. trafficserver/proxy/http2/Http2ConnectionState.h, Http2ConnectionState.cc
{
双链表
Http2ConnectionState::main_event_handler(HTTP2_SESSION_EVENT_RECV )里面,解析输入的各种 Frame
rcv_data_frame :
rcv_headers_frame:
rcv_priority_frame:
rcv_rst_stream_frame
rcv_settings_frame:
rcv_push_promise_frame 等
rcv_continuation_frame
send_data_frames_depends_on_priority
send_data_frames 等
4. trafficserver/proxy/http2/Http2Stream.h, Http2Stream.cc
5. trafficserver/proxy/http2/Http2DependencyTree.h, Http2DependencyTree.cc
{
bool actived; //是否有输出数据
bool queued; //是否在 actived 队列中
uint32_t id;
uint32_t weight;
uint32_t point; //queue中的节点按照这个 point 做优先级排序
Node *parent; //父节点
DLL
DFS 递归遍历树,查找一个Stream。
就是插入 parent 的 children 链表中,兼做 exclusive 处理。
从parent 的 queue 中移除自己,把自己的 queue 全转给 parent,把自己的 children 全转给 parent
重排优先级,就是移动节点
返回整个树中,point 最高的叶子节点。递归实现。
往上遍历,如果当前节点没有 在 parent 的 queue中,加入
从parent 的queue中去除自己。
中,是直接取了 树的 top() 节点,6. trafficserver/proxy/http2/HPACK.h, HPACK.cc
7. trafficserver/proxy/http2/HuffmanCodec.h, HuffmanCodec.cc
下一篇:http与https随笔
文章标题:TrafficServer http2 代码分析
文章链接:http://soscw.com/index.php/essay/64589.html