当前位置: 首页 > news >正文

Muduo网络库实现 [十三] - HttpRequest模块

目录

设计思路 

成员设计

模块实现


设计思路 

首先我们要先知道HTTP的请求的流程是什么样子的,不然我们会学的很迷糊。对于HTTP请求如何到来以及去往哪里,我们应该很清楚的知道

HTTP请求在服务器系统中的传递流程是一个多层次的过程:

  1. 客户端发起请求 - 用户在浏览器或应用中发起HTTP请求
  2. 网络传输 - 请求通过网络传输到服务器
  3. 服务器接收 - 服务器的TCP/IP协议栈接收数据包并将其传递给操作系统
  4. 网络库接收 - 在muduo这样的网络库中,数据通过以下路径流动:
    • 操作系统的socket接口接收原始数据
    • 网络库的EventLoop检测到socket可读事件
    • TcpConnection将数据读入其内部Buffer
  5. HTTP解析 - 数据进入HTTP解析层:
    • TcpServer将连接和数据传递给HttpServer
    • HttpServer创建HttpContext对象处理每个连接
    • HttpContext从Buffer中读取数据并进行解析
    • 解析结果存储在HttpRequest对象中
  6. 应用处理 - 最终HttpRequest被传递给用户注册的回调函数进行业务逻辑处理

HttpRequest通常由HttpContext创建和填充,然后传递给处理HTTP请求的回调函数或处理器。它本质上是HTTP请求信息的容器,使服务器能够方便地访问和处理客户端的请求内容。

在整个HTTP处理流程中,HttpRequest的角色是保存从网络层解析出的HTTP请求信息,供应用层使用。

HTTP请求格式

成员设计

HTTP请求中的主要要素包括:

  1. 请求行:
    • 请求方法(GET、POST、PUT、DELETE等)
    • URL,包含:
      • 资源路径
      • 查询参数(键值对形式)
    • 协议版本(如HTTP/1.1)
  2. 请求头部:
    • 多个键值对格式的头部字段
    • 常见的如Content-Type、User-Agent、Host等
  3. 请求正文:
    • 根据Content-Length或Transfer-Encoding确定长度
    • 内容格式由Content-Type决定

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

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

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

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

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

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

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

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

然后如果是短连接的话,我们每次接收完也需要把数据给清除了。所以也需要个接口

模块实现

代码挺简单的,跟着思路走就很容易写出来的

class HttpRequest
{
public:
    string _method;  //存储请求方法
    string _path;    //存储资源路径
    string _version;  //存储协议版本
    string _body;    //存储正文
    unordered_map<string, string> _headers;   //存储请求头部
    unordered_map<string, string> _params;  //存储查询字符串
    smatch _matches; //资源路径正则提取
private:
    bool HasHeader(const sting &key) const  //给获取报文长度函数提供的
    {
        auto it = _headers.find(key);
        if(it == _headers.end())
        {
            return false;
        }
        return it->second;
    }
    string GetHeader(const sting &key) const //给获取报文长度函数提供的
    {
        auto it = _headers.find(key);
        if(it == _headers.end())
        {
            return "";
        }
        return it->second;
    }

public:
    HttpRequest()
    :_version("HTTP/1.1")
    {}

    void clear()//清空类数据
    {
        _method.clear();
        _path.clear();
        _version("HTTP/1.1");
        _body.clear();
        _headers.clear();
        _params.clear();
        smatch matches;
        _matches.swap(matches);
    }
    void SetHeader(const string &key, const string &val)//添加请求头部
    {
        _headers.insert(key, val);
    }
    void SetParam(const string &key, const string &val)//添加查询字符串
    {
        _params.insert(key, val);
    }
    size_t GetLength()//获取正文长度
    {
        bool ret = HasHeader("Content-Length");
        if(ret == false)
        {
            return 0;
        }
        string len = GetHeader("Content-Length");
        return stol(len);
    }
    //是否是短链接
    bool Close() const
    {
        if(HasHeader("Connection") == true && GetHeader("Connection") == "keep-alive");
        {
            return false;
        }
        return true;
    }
};
http://www.dtcms.com/a/111999.html

相关文章:

  • 【AI论文】AnimeGamer:基于下一游戏状态预测的无限动漫人生模拟
  • 解锁工业通信:Profibus DP到ModbusTCP网关指南!
  • 第十五届蓝桥杯大赛软件赛省赛Python 大学 C 组:3.数字诗意
  • 基于 jQuery 实现二级下拉框选择功能
  • 技巧:使用 ssh 设置隧道代理访问 github
  • 【C语言】字符串处理函数:strtok和strerror
  • Linux网络基础三
  • wireshark抓包分析数据怎么看 wireshark使用教程_wireshark怎么看(1)
  • 33--当网络变成“主题公园“:Portal认证的奇幻之旅
  • 根据时间自动切换深色和浅色主题 程序占用检测
  • R 列表:深入解析及其在数据分析中的应用
  • dify中配置使用Ktransformer模型
  • Python 字典
  • FreeRTOS:嵌入式实时操作系统的轻量化解决方案
  • WPF设计学习记录滴滴滴5
  • KMP 算法全解析:高效实现字符串匹配与模板题详解
  • golang 的encoding/json包
  • python爬虫:小程序逆向(需要的工具前期准备)
  • 蓝桥杯---最短路径问题bfs
  • 【数据结构】邻接表 vs 邻接矩阵:5大核心优势解析与稀疏图存储优化指南
  • 三部门新政力推智能家居 居然智家数智化转型迎利好东风
  • YUV转RGBA的操作
  • 图解AUTOSAR_SWS_LINTransceiverDriver
  • 【嵌入式学习5】PyQt5模块介绍、创建第一个窗口
  • Linux安装启动ssh服务器以及ssh的配置
  • Leetcode 15 -- 双指针
  • Mysql 中的 MyISAM 引擎
  • 第十五届蓝桥杯单片机省赛程序设计试题
  • CSS 3D变换,transform:translateZ()
  • 从小米汽车事故反思 LabVIEW 开发