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也就设计完了。这个模块主要还是用于保存请求中的要素,所以他的设计十分简单。

相关推荐
lida200315 分钟前
无人机救援系统简单解读
linux·无人机·openipc·wfb-ng
0725游广川1 小时前
cjson内存泄漏问题注意事项
服务器·json
TensorFlowGAN3 小时前
rhcsa、ce复习(每日编辑,复习完为止)
linux·es
Drscq4 小时前
How to migrate a CentOS 8 to Rocky Linux 8.10
linux·运维·centos
修心光4 小时前
CentOS配置iptables规则并使其永久生效
linux·运维·centos
加载中loading...4 小时前
Linux线程安全(二)条件变量实现线程同步
linux·运维·服务器·c语言·1024程序员节
安科瑞刘鸿鹏4 小时前
校园建筑用电安全监测装置 电气火灾监测预防设备功能介绍
运维·服务器·网络·嵌入式硬件·安全·能源
课堂随想4 小时前
【libGL error】Autodl云服务器配置ACT的conda虚拟环境生成训练数据时,遇到了libGL相关错误,涉及swrast_dri.so
运维·服务器·conda
画江湖Test5 小时前
SDK如何测试
服务器·sdk
well_fly7 小时前
Ubuntu特殊目录
linux·ubuntu