拆开 Hical:一个 HTTP 请求从 socket 字节到路由分发的完整旅程
[Hical] 一个 HTTP 请求在 Hical 里经历了什么?从 socket 字节到路由分发 本专栏文章:拆开 Hical · 第 1 篇 用过 Web 框架的人很多,知道"一个请求怎么从 socket 字节变成 handler 参数"的人很少。大部分框架把这层封装得严严实实,你只要写 app.get("/", handler) 就行。 但这篇文章要干相反的事——把 Hical 的整个请求处理链路扒开看。读完你能回答:请求头为什么零堆分配、响应头怎么一次 async_write 发出去、ReadBufferPool 为什么是请求级 borrow 而不是连接级持有。 1. 大图:一个请求的完整旅程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 socket 上来了字节 │ ▼ readBuf = ReadBufferPool::acquire() ← 借一块 8KB 缓冲 │ ▼ picohttpparser 解析 → phr_header[64] ← 请求头解析到栈数组 │ ▼ 构造 NativeRequest (string_view) ← 零拷贝,指针指到 readBuf │ ▼ Router::dispatch(req) ──→ handler 协程 ← 你的业务代码 │ ▼ NativeResponse::serializeHeadTo(buf) ← 序列化到栈上 512 字节 │ ▼ async_write(socket, buf) ← 一次异步写 │ ▼ readBuf 还给 ReadBufferPool::return_() ← 归还 8KB 缓冲 下面每一步都拆开讲"为什么这样设计"。 ...