HttpRequest模块 --- 存储http请求要素

目录

模块设计思想

模块代码实现


模块设计思想

HttpRequest模块是存储 Http请求要素的模块,同时他也需要提供接口用于外部进行设置要素。

那么Http请求中有哪些要素呢?

首先请求行中,有请求方法,url ,协议版本,而uel中又分为资源路径和参数,参数是kv的形式,所以我们需要使用一个map来保存

而头部字段中,都是一些kv格式的属性,我们也是使用一个map来保存

最后就是正文部分,正文部分是交给上层业务逻辑去处理的,我们只需要按照头部字段中的Content-Length提取出来就行了。

那么我们需要保存的就是 : 请求方法,资源路径,参数,协议版本,头部字段,正文 ,当然,由于可能会存在中间的处理过程,比如对请求行的解析,我们会使用正则表达式来进行,我们可以再存储一个 std::smatch 来保存正则提取出来的结果。

由于HttpRequest后续我们是交给 上下文模块来进行设置的,为了方便,我们就直接将成员设置为公有的了,便于直接访问。

同时,对于参数和头部字段,我们可以提供结构,用来插入kv形式的参数和头部字段,以及查询是否有某个参数或者头部字段。

再HttpRequest的头部字段中,有一个很重要的信息就是正文长度,我们可以提供一个接口用来获取正文长度。

最后再提供一个接口用于判断长短连接,长短连接后续我们会用到。

模块代码实现

按照上面的逻辑,我们的接口其实都很简单,所以我们也不一一讲解了。

复制代码
//保存http请求的各个要素
class HttpRequest   
{
public:
std::string _method; //请求方法
std::string _path;   //资源路径
std::unordered_map<std::string,std::string> _params;    //参数
std::string _version;   //协议版本
std::unordered_map<std::string,std::string> _headers;   //头部字段
std::string _body;      //正文
std::smatch _matches;   //请求行的正则匹配结果
uint64_t _length;       //正文长度

public:
    //添加参数
    void AddParam(const std::string& key , const std::string& val)
    {
        //如果已经存在该key,那么也直接更新
        _params[key] = val;
    }
    //判断是否有该参数
    bool HasParam(const std::string& key)const
    {
        auto it = _params.find(key);
        return it != _params.end();
    }
    //获取参数
    std::string GetParam(const std::string& key)const
    {
        auto it = _params.find(key);
        if(it == _params.end()) return "";  //返回空串
        return it->second;
    }
    //添加头部字段
    void AddHeader(const std::string& key , const std::string& val)
    {
        _headers[key]=val;
    }
    //判断是否有某个头部字段
    bool HasHeader(const std::string& key)const
    {
        auto it = _headers.find(key);
        return it != _headers.end();
    }
    //判断是不是短连接,如果是短连接那么返回一个响应之后就关闭连接了
    bool Close()const
    {
        //长短连接: Connection: close/keep-alive
        auto it = _headers.find("Connection");
        if(it == _headers.end() || it->second == "close") return true;
        return false;
    }
    //获取正文长度
    size_t ContentLength()const
    {
        auto it = _headers.find("Content-Length");
        if(it == _headers.end()) return 0;
        return std::stol(it->second);
    }
};

最后,我们会注意到,如果是长连接,那么意味着可能会收到第二个报文,那么我们需要将HttpRequest的内容先清空,再去解析第二个报文。(后续我们的HttpRequest是作为HttpContext的一部分的)。

所以我们再提供一个Reset接口用于重置内容。

复制代码
    void Reset()
    {
        _method.clear();
        _path.clear();
        _params.clear();
        _version.clear();
        _headers.clear();
        _body.clear();
        std::smatch tmp;
        _matches.swap(tmp); //由于smatch没有提供clear接口,所以我们使用swap来进行重置
        _body.clear();
    }

那么HttpRequest也就设计完了。这个模块主要还是用于保存请求中的要素,所以他的设计十分简单。

相关推荐
树℡独2 小时前
ns-3仿真之应用层(五)
服务器·网络·tcp/ip·ns3
嵩山小老虎3 小时前
Windows 10/11 安装 WSL2 并配置 VSCode 开发环境(C 语言 / Linux API 适用)
linux·windows·vscode
Fleshy数模3 小时前
CentOS7 安装配置 MySQL5.7 完整教程(本地虚拟机学习版)
linux·mysql·centos
a41324473 小时前
ubuntu 25 安装vllm
linux·服务器·ubuntu·vllm
Configure-Handler4 小时前
buildroot System configuration
java·服务器·数据库
津津有味道4 小时前
易语言TCP服务端接收刷卡数据并向客户端读卡器发送指令
服务器·网络协议·tcp·易语言
Fᴏʀ ʏ꯭ᴏ꯭ᴜ꯭.5 小时前
Keepalived VIP迁移邮件告警配置指南
运维·服务器·笔记
Genie cloud5 小时前
1Panel SSL证书申请完整教程
服务器·网络协议·云计算·ssl
一只自律的鸡5 小时前
【Linux驱动】bug处理 ens33找不到IP
linux·运维·bug
17(无规则自律)5 小时前
【CSAPP 读书笔记】第二章:信息的表示和处理
linux·嵌入式硬件·考研·高考