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

相关推荐
сокол13 分钟前
【网安-Web渗透测试-靶场系列】AWD-Platform(ctf-hub)
linux·服务器·ubuntu·网络安全·docker
utf8mb4安全女神44 分钟前
Linux系统服务相关命令【定时任务设置】【任务进程管理】【防火墙区域应用】
linux·运维·服务器
L、2183 小时前
昇腾NPU性能调优Checklist——从“能跑“到“跑得快“的20步
服务器·人工智能·深度学习
不吃土豆的马铃薯4 小时前
Spdlog 进阶:日志基本控制、日志格式控制、异步记录器
linux·服务器·开发语言·前端·c++
疯狂成瘾者4 小时前
常见的 Linux 版本
linux·运维·服务器
szxinmai主板定制专家4 小时前
基于ZYNQ MPSOC图像采集与压缩系统总体设计方案
linux·arm开发·人工智能·嵌入式硬件·fpga开发
GOTXX4 小时前
SenseNova U1 实战体验:API 调用 + OpenClaw 接入全流程
服务器·网络·人工智能·语言模型
liulilittle4 小时前
TCP UCP:基于卡尔曼滤波的BBR增强型拥塞控制算法
linux·网络·c++·tcp/ip·算法·c·通讯
xingyuzhisuan5 小时前
GPU服务器集群搭建指南——选型、部署、优化+避坑全解析
运维·服务器·人工智能·gpu算力
tianrun12345 小时前
Ubuntu 24.04 安装 Fcitx5 + Rime + 搜狗词库(替代 IBus 与 Linux 搜狗输入法)
linux·运维·ubuntu