目录


手写http协议解析库

http协议的组成

http请求报文如下: https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/937fc897e6ce4d70bbdd58e30123fe3c~tplv-k3u1fbpfcp-watermark.image? https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/24f806c32db44631866e6df0381d1c5a~tplv-k3u1fbpfcp-watermark.image?

http响应报文如下: https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6ee6d2f97fb944099fa7bad0d9366d40~tplv-k3u1fbpfcp-watermark.image?

https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/869ed006c08d48719a7c2bf6a48b0a9b~tplv-k3u1fbpfcp-watermark.image?

状态机设计

请求报文解析 https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cd0472a8371a442584b37783b9a5b52f~tplv-k3u1fbpfcp-watermark.image?

响应报文解析 https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/70f56c79e0c14df3a439c2e56f4a5cd7~tplv-k3u1fbpfcp-watermark.image?

代码结构设计

  • 基础结构类:Response和Request,其中都包含一个Url类,用于解析得到路径和Query参数。
  • 工具类:HttpParser,HttpParser用于解析纯http报文然后得到对应的Response或Request,组合成字符串信息只需要调用Request或者Response对应的to_string()方法。

https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/276b51bccb68441abb2f7dd0cc3f3831~tplv-k3u1fbpfcp-watermark.image?

代码使用示例

对于head和body的设置均可通过直接调用head()和body()方法来设置,这个方法返回的是一个左值。

#include"http-parser/Parser.h"

int main(){
        http::Parser parser;
        auto req = parser.ToRequest(buffer);
        std::cout << req.to_string(); //根据request内容获取对应的http报文
        req.head()["dfasf"] = "fda"; //随意设置request的header
        req.body() = "fdsafsadf"; //设置request的body部分
        //request的特殊字段(GET的FORM和POST的form
        auto v = req.Query("test"); //获取第一个值
        auto v1 = req.PostQuery("test"); //获取post表单里的第一个query值
        req.PostMultiPart("test"); //返回form-data的键值(可以传入文件
        
        http::Response response;
        response.SetStatus(http::OK);
        response.SetContentType(http::ACCEPT_CONTENT_TYPE::T_JSON);
        response.SetConnection(false);
        response.body() = R"({"hello world!":2323})";
        auto response_text = response.to_string();

}