Back to VNotes

HTTP / Parser

HTTP 状态机草图

一个最小 HTTP 服务器也需要清楚地区分读取、解析、生成响应和写回这几个阶段。

状态拆分

可以把连接状态拆成 READING、PARSING、WRITING、CLOSING。读取阶段只负责收集字节,解析阶段判断请求是否完整,写阶段按偏移发送响应。

请求边界

HTTP/1.1 的头部以空行结束,也就是 CRLF CRLF。对静态文件服务器来说,先支持 GET 和 HEAD 就足够。请求体可以暂时不处理,但要明确返回 405 或 501。

响应生成

响应生成需要关注状态码、Content-Type、Content-Length 和 Connection。静态文件路径必须做规范化,避免 ../ 穿出资源目录。

read buffer -> parse request line -> map resource -> build headers -> send file/body

可维护性

不要把 socket 读写、HTTP 解析、文件读取全部堆在一个函数里。即使是小项目,也可以保持 Request、Response、Connection 三个概念。

状态机拆分建议

不要让一个函数同时负责读 socket、解析 HTTP、读文件和发送响应。即使项目规模很小,也可以把连接状态拆成读取、解析、响应生成、写回和关闭。

READING -> PARSING -> BUILD_RESPONSE -> WRITING -> CLOSING

路径安全

静态文件服务器一定要处理路径规范化。用户请求的路径不能直接拼接到资源目录,否则 ../ 可能访问到资源目录之外的文件。安全做法是解析成绝对路径后确认它仍然位于资源根目录内部。