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

【高并发服务器:HTTP应用】十五、HttpRequest请求模块 HttpResponse响应模块设计

在这里插入图片描述

文章目录

  • Ⅰ. `HttpRequest`请求模块设计
  • Ⅱ. 接口实现
  • Ⅲ. `HttpResponse`响应模块设计
  • Ⅳ. 接口实现

Ⅰ. HttpRequest请求模块设计

​ 这个模块是 HTTP 请求数据模块,用于存储 HTTP 的请求信息,然后按照 HTTP 请求格式进行解析,得到各个关键要素放到 Request 中,这样子能让 HTTP 请求的分析更加的方便!

其中成员变量,也就是要分析的内容无非就是请求报文中的要素,这些 成员变量我们将其设为公有属性,便于外界的直接访问,如下所示:

  • 请求方法
  • URL
    • 资源路径
    • 查询字符串(用哈希表存储各个键值对,方便查找)
  • 协议版本
  • 头部字段(用哈希表存储各个键值对,方便查找)
  • 正文
  • 此外我们还需要一个 std::smatch 成员变量,用来保存通过使用正则表达式进行解析后得到的数据。(比如资源路径中的数字等等……)

在这里插入图片描述

所以需要提供以下接口:

  1. 提供对查询字符串、头部字段的的插入和获取功能
  2. 长连接和短连接的判断
  3. 获取正文长度
class HttpRequest
{
public:std::string _method;  									   // 请求方法std::string _path;    									   // 资源路径std::unordered_map<std::string, std::string> _queryString; // 查询字符串std::string _version; 								       // 协议版本std::unordered_map<std::string, std::string> _header;      // 头部字段std::string _body;    									   // 请求正文std::smatch _matches; // 资源路径的正则提取数据
public:HttpRequest();// 插入头部字段void set_header(const std::string& key, const std::string& val);// 判断是否存在指定头部字段bool has_header(const std::string& key) const;// 获取指定头部字段的值std::string get_header_val(const std::string& key) const;// 插入查询字符串void set_queryString(const std::string& key, const std::string& val);// 判断是否存在指定查询字符串bool has_queryString(const std::string& key) const;// 获取指定查询字符串的值std::string get_queryString_val(const std::string& key) const;// 获取正文长度size_t get_body_length() const;// 判断是否为短连接bool is_short_connection() const;// 成员变量清理接口void reset();
};

Ⅱ. 接口实现

​ 接口并不难,这里就不细讲了,直接参考注释即可!

class HttpRequest
{
public:std::string _method;  									   // 请求方法std::string _path;    									   // 资源路径std::unordered_map<std::string, std::string> _queryString; // 查询字符串std::string _version; 								       // 协议版本std::unordered_map<std::string, std::string> _header;      // 头部字段std::string _body;    									   // 请求正文std::smatch _matches; // 资源路径的正则提取数据
public:HttpRequest(): _version("HTTP/1.1"){}// 插入头部字段void set_header(const std::string& key, const std::string& val) {  _header[key] = val; }// 判断是否存在指定头部字段bool has_header(const std::string& key) const{auto it = _header.find(key);if(it == _header.end())return false;return true;}// 获取指定头部字段的值std::string get_header_val(const std::string& key) const{auto it = _header.find(key);if(it == _header.end())return "";return it->second;}// 插入查询字符串void set_queryString(const std::string& key, const std::string& val) {  _queryString[key] = val; }// 判断是否存在指定查询字符串bool has_queryString(const std::string& key) const{auto it = _queryString.find(key);if(it == _queryString.end())return false;return true;}// 获取指定查询字符串的值std::string get_queryString_val(const std::string& key) const{auto it = _queryString.find(key);if(it == _queryString.end())return "";return it->second;}// 获取正文长度size_t get_body_length() const {// 通过头部字段中的Content-Length来获取,比如Content-Length: 1024\r\nbool ret = has_header("Content-Length");if(ret == false)return 0;return std::stol(get_header_val("Content-Length"));}// 判断是否为短连接bool is_short_connection() const{// 通过头部字段中的Connection来判断,如果是close表示短连接,keep-alive表示长连接bool ret = has_header("Connection");if(ret == false)return false;return get_header_val("Connection") == "close";}
public:// 成员变量清理接口void reset(){_method.clear();_path.clear();_queryString.clear();_version = "HTTP/1.1"; // 注意这里版本号不能清空,因为有地方可能会清理完之后还用到它,为空的话会导致内存错误_header.clear();_body.clear();// smatch比较特殊,它没有clear()接口,所以我们可以用一个空的smatch与其进行交换达到清空的效果std::smatch tmp;_matches.swap(tmp);}
};

Ⅲ. HttpResponse响应模块设计

​ 这个模块和上面的请求模块就是相反的,主要存储 HTTP 的响应信息,在进行业务处理的同时,让使用者向 Response 中填充响应要素,完毕后将其组织成为 HTTP 响应格式的数据,发送给客户端,这样子能让 HTTP 响应的过程操作变得简单!

​ 其实响应内容不需要包括响应报文中的全部要素(因为有些是可以通过工具类模块获取的,或者是 http 协议本身自带的),只需要下面几个关键的:

  • 状态码
  • 头部字段
  • 响应正文
  • 重定向信息(是否进行重定向的标志,重定向的路径)

在这里插入图片描述

所以需要提供以下接口:

  1. 头部字段的新增、查询和获取
  2. 长短连接的判断与设置
  3. 正文的设置
  4. 重定向的设置
class HttpResponse
{
public:int _status;                                          // 状态码std::string _body;                                    // 响应正文std::unordered_map<std::string, std::string> _header; // 头部字段bool _is_redirect;          // 是否重定向的标志std::string _redirect_path; // 重定向路径
public:HttpResponse();// 成员变量清理接口void reset();// 插入头部字段void set_header(const std::string& key, const std::string& val);// 判断是否存在指定头部字段bool has_header(const std::string& key) const;// 获取指定头部字段的值std::string get_header_val(const std::string& key) const;// 设置响应正文void set_content(const std::string& body, const std::string& type = "text/html");// 设置重定向信息void set_redirect(const std::string& url, int status = 302);// 判断是否为短连接bool is_short_connection() const;
};

Ⅳ. 接口实现

​ 接口有些甚至和请求模块是一样的,比较简单,这里也不细讲了,具体参考代码!

class HttpResponse
{
public:int _status;                                          // 状态码std::string _body;                                    // 响应正文std::unordered_map<std::string, std::string> _header; // 头部字段bool _is_redirect;          // 是否重定向的标志std::string _redirect_path; // 重定向路径
public:HttpResponse(int status = 200): _is_redirect(false), _status(status){}// 成员变量清理接口void reset(){_status = 200;_is_redirect = false;_body.clear();_header.clear();_redirect_path.clear();}// 插入头部字段void set_header(const std::string& key, const std::string& val) {  _header[key] = val; }// 判断是否存在指定头部字段bool has_header(const std::string& key) const {auto it = _header.find(key);if(it == _header.end())return false;return true;}// 获取指定头部字段的值std::string get_header_val(const std::string& key) const {auto it = _header.find(key);if(it == _header.end())return "";return it->second;}// 设置响应正文void set_content(const std::string& body, const std::string& type = "text/html"){_body = body;set_header("Content-Type", type);}// 设置重定向信息void set_redirect(const std::string& url, int status = 302){_status = status;_is_redirect = true;_redirect_path = url;}// 判断是否为短连接bool is_short_connection() const {// 通过头部字段中的Connection来判断,如果是close表示短连接,keep-alive表示长连接bool ret = has_header("Connection");if(ret == false)return 0;return get_header_val("Connection") == "close";}
};

在这里插入图片描述

http://www.dtcms.com/a/573113.html

相关文章:

  • 两台服务器 NFS 共享目录实战
  • 在服务器已有目录中部署 Git 仓库
  • 宝塔Linux部署 一个基于uni-app 系统指南
  • PostgreSQL 索引
  • Ubuntu20.04配置使用evo工具
  • 远程连接银河麒麟服务器-xrdp方式
  • 做阿里巴巴网站图片大全wordpress添加固定结尾
  • k8s集群搭建(七)-------- 微服务间的调用
  • 华为HCIP网络工程师认证—网络参考模型
  • 商务网站建设策略网站设计 原型图
  • 告别 Class 组件:拥抱 React Hooks 带来的函数式新范式
  • 21、【Ubuntu】【远程开发】技术方案分析:虚拟专用网络(补充)
  • 中山网站制作建设通讯员队伍建设与网站新闻管理
  • 论文阅读:《Hypergraph Motif Representation Learning》
  • 快速了解搭建网站流程——全栈网站搭建指南
  • pdf图片提取器pyqt6版本实现
  • 基于Layui Vue Admin + Spring Boot 3.x 的企业级前后端分离管理系统
  • Apache SeaTunnel 支持 Metalake 开发了!避免任务配置敏感信息暴露
  • 2025年Java面试题及详细解答(MySQL篇)
  • 深入理解 Spring Boot 中的数据库连接池:原理、选型与最佳实践
  • 网站建设实训的目的重庆 新闻发布会
  • Android Init 系列专题【篇六:reboot shutdown】
  • 建设部网站查造价师学院网站建设流程图
  • 人工智能学习中深度学习之python基础之 装饰器(精讲)
  • KP2203LGA宽电压输出PWM驱动控制器芯片典型应用
  • 关闭 macOS 屏幕捕捉 在录制或截图时显示的「录制指示浮窗」。
  • 技术变革:为何C#与.NET是未来的开发方向
  • 借助Redis实现Token黑名单机制
  • 缓存机制:Redis集成
  • 做网站要先申请域名吗搭建网站的英语