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

Sylar服务器框架——Http模块

1、http.h

  • 定义了HttpMethod和HttpStatus
/* Request Methods */
#define HTTP_METHOD_MAP(XX)         \XX(0,  DELETE,      DELETE)       \XX(1,  GET,         GET)          \XX(2,  HEAD,        HEAD)         \XX(3,  POST,        POST)         \XX(4,  PUT,         PUT)          \
.../* Status Codes */
#define HTTP_STATUS_MAP(XX)                                                 \XX(100, CONTINUE,                        Continue)                        \XX(101, SWITCHING_PROTOCOLS,             Switching Protocols)             \XX(102, PROCESSING,                      Processing)                      \XX(200, OK,                              OK)                              \XX(201, CREATED,                         Created)                         \XX(202, ACCEPTED,                        Accepted)                        \XX(203, NON_AUTHORITATIVE_INFORMATION,   Non-Authoritative Information)   \
...
/*** @brief HTTP方法枚举*/
enum class HttpMethod {
#define XX(num, name, string) name = num,HTTP_METHOD_MAP(XX)
#undef XXINVALID_METHOD
};/*** @brief HTTP状态枚举*/
enum class HttpStatus {
#define XX(code, name, desc) name = code,HTTP_STATUS_MAP(XX)
#undef XX
};
  • HttpRequest和HttpResponse
    Http请求和响应的格式可以参考https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Messages
    HttpRequest和HttpResponse其实可以看成是容器,将请求消息和响应消息那一坨字符串,拆解开放在里面,这样就可以让机器去按照这些信息去做操作。
    对于HTTP请求,需要关注HTTP方法,请求路径和参数,HTTP版本,HTTP头部的key-value结构,Cookies,以及HTTP Body内容。
    对于HTTP响应,需要关注HTTP版本,响应状态码,响应字符串,响应头部的key-value结构,以及响应的Body内容。
    2、http_parser.h
    这个模块的作用就是将输入的字节流信息解析到HttpRequest和HttpResponse结构体中。这里是基于https://github.com/nodejs/http-parser实现的,采用了有限状态机算法,效率非常快。
  • HttpRequestParser
    当解析完相关项时就会执行相应的回调,将数据放到指定位置
void on_request_method(void *data, const char *at, size_t length) {HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);HttpMethod m = CharsToHttpMethod(at);if(m == HttpMethod::INVALID_METHOD) {SYLAR_LOG_WARN(g_logger) << "invalid http request method: "<< std::string(at, length);parser->setError(1000);return;}parser->getData()->setMethod(m);
}void on_request_uri(void *data, const char *at, size_t length) {
}void on_request_fragment(void *data, const char *at, size_t length) {//SYLAR_LOG_INFO(g_logger) << "on_request_fragment:" << std::string(at, length);HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);parser->getData()->setFragment(std::string(at, length));
}void on_request_path(void *data, const char *at, size_t length) {HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);parser->getData()->setPath(std::string(at, length));
}void on_request_query(void *data, const char *at, size_t length) {HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);parser->getData()->setQuery(std::string(at, length));
}void on_request_version(void *data, const char *at, size_t length) {HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);uint8_t v = 0;if(strncmp(at, "HTTP/1.1", length) == 0) {v = 0x11;} else if(strncmp(at, "HTTP/1.0", length) == 0) {v = 0x10;} else {SYLAR_LOG_WARN(g_logger) << "invalid http request version: "<< std::string(at, length);parser->setError(1001);return;}parser->getData()->setVersion(v);
}void on_request_header_done(void *data, const char *at, size_t length) {//HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);
}void on_request_http_field(void *data, const char *field, size_t flen,const char *value, size_t vlen) {HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);if(flen == 0) {SYLAR_LOG_WARN(g_logger) << "invalid http request field length == 0";//parser->setError(1002);return;}parser->getData()->setHeader(std::string(field, flen),std::string(value, vlen));
}
  • HttpResponseParser
void on_response_reason(void *data, const char *at, size_t length) {HttpResponseParser* parser = static_cast<HttpResponseParser*>(data);parser->getData()->setReason(std::string(at, length));
}void on_response_status(void *data, const char *at, size_t length) {HttpResponseParser* parser = static_cast<HttpResponseParser*>(data);HttpStatus status = (HttpStatus)(atoi(at));parser->getData()->setStatus(status);
}void on_response_chunk(void *data, const char *at, size_t length) {
}void on_response_version(void *data, const char *at, size_t length) {HttpResponseParser* parser = static_cast<HttpResponseParser*>(data);uint8_t v = 0;if(strncmp(at, "HTTP/1.1", length) == 0) {v = 0x11;} else if(strncmp(at, "HTTP/1.0", length) == 0) {v = 0x10;} else {SYLAR_LOG_WARN(g_logger) << "invalid http response version: "<< std::string(at, length);parser->setError(1001);return;}parser->getData()->setVersion(v);
}void on_response_header_done(void *data, const char *at, size_t length) {
}void on_response_last_chunk(void *data, const char *at, size_t length) {
}void on_response_http_field(void *data, const char *field, size_t flen,const char *value, size_t vlen) {HttpResponseParser* parser = static_cast<HttpResponseParser*>(data);if(flen == 0) {SYLAR_LOG_WARN(g_logger) << "invalid http response field length == 0";//parser->setError(1002);return;}parser->getData()->setHeader(std::string(field, flen),std::string(value, vlen));
}

3、http_session.h

  • 继承自SocketStream,实现了在套接字流上读取HTTP请求与发送HTTP响应的功能,在读取HTTP请求时需要借助HTTP解析器,以便于将套接字流上的内容解析成HTTP请求。 从每个请求的通信套接字读到请求数据,利用parser将流数据转换成自己定义的结构体由该模块完成。解析完后,会由servlet执行相关操作,把信息封装在HttpResponse,由该模块通过通信套接字传给客户端。
    4、servlet.h
  • 提供HTTP请求路径到处理类的映射,用于规范化的HTTP消息处理流程。HTTP Servlet包括两部分,第一部分是Servlet对象,每个Servlet对象表示一种处理HTTP消息的方法,第二部分是ServletDispatch,它包含一个请求路径到Servlet对象的映射,用于指定一个请求路径该用哪个Servlet来处理。
    /*** @brief 处理请求* @param[in] request HTTP请求* @param[in] response HTTP响应* @param[in] session HTTP连接* @return 是否处理成功*/virtual int32_t handle(sylar::http::HttpRequest::ptr request, sylar::http::HttpResponse::ptr response, sylar::http::HttpSession::ptr session) = 0;

5、http_server.h

  • 继承自TcpServer,重载handleClient方法,将accept后得到的客户端套接字封装成HttpSession结构,以便于接收和发送HTTP消息。
void HttpServer::handleClient(Socket::ptr client) {SYLAR_LOG_DEBUG(g_logger) << "handleClient " << *client;HttpSession::ptr session(new HttpSession(client));do {auto req = session->recvRequest();if(!req) {SYLAR_LOG_DEBUG(g_logger) << "recv http request fail, errno="<< errno << " errstr=" << strerror(errno)<< " cliet:" << *client << " keep_alive=" << m_isKeepalive;break;}HttpResponse::ptr rsp(new HttpResponse(req->getVersion(),req->isClose() || !m_isKeepalive));rsp->setHeader("Server", getName());m_dispatch->handle(req, rsp, session);session->sendResponse(rsp);if(!m_isKeepalive || req->isClose()) {break;}} while(true);session->close();
}

6、http_connection

  • 用于发起GET/POST等请求并获取响应,支持设置超时,keep-alive,支持连接池。HTTP服务端的业务模型是接收请求→ 发送响应,而HTTP客户端的业务模型是发送请求→ 接收响应。
  • 关于连接池,是指提前预备好一系列已接建立连接的socket,这样,在发起请求时,可以直接从中选择一个进行通信,而不用重复创建套接字→ 发起connect→ 发起请求 的流程。
  • 连接池与发起请求时的keep-alive参数有关,如果使用连接池来发起GET/POST请求,在未设置keep-alive时,连接池并没有什么卵用。

相关文章:

Sylar服务器框架——Http模块

1、http.h 定义了HttpMethod和HttpStatus /* Request Methods */ #define HTTP_METHOD_MAP(XX) \XX(0, DELETE, DELETE) \XX(1, GET, GET) \XX(2, HEAD, HEAD) \XX(3, POST, POST) \XX(4, PUT, …...

7km远距离WiFi实时图传模块,无人机海上无线传输方案,飞睿智能WiFi MESH自组网技术

在浩瀚无垠的海洋上&#xff0c;无人机正在开启一场前所未有的技术创新。它们不再只是天空的舞者&#xff0c;更是海洋的守望者&#xff0c;为我们带来前所未有的视野和数据。而这一切的背后&#xff0c;都离不开一项创新性的技术——飞睿智能远距离WiFi实时图传模块与无线Mesh…...

2024年上半年网络工程师下午真题及答案解析

试题一(20分) 某高校网络拓扑如下图所示&#xff0c;两校区核心&#xff08;CORE-1、CORE-2&#xff09;&#xff0c;出口防火墙&#xff08;NGFW-1、NGFW-2&#xff09;通过校区间光缆互联&#xff0c;配置OSPF实现全校路由收敛&#xff0c;两校区相距40km。两校区默认由本地…...

Jmeter下载、安装及配置

1 Jmeter介绍 Jmeter是进行负载测试的工具&#xff0c;可以在任何支持Java虚拟机环境的平台上运行&#xff0c;比如Windows、Linux、Mac。 Jmeter模拟一组用户向目标服务器发送请求&#xff0c;并统计目标服务器的性能信息&#xff0c;比如CPU、memory usage。 2 Jmeter下载 …...

掌握高效实用的VS调试技巧

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 1.编程常见的错误 1.1编译型错误 编程编译型错误是指在编译代码时发现的错误。编译器在编译过程中会检查代码是否符合语法规范和语义要求&#xff0c;如果发现错误会产生编译错误。 直接看错误提示信息&#xff08;双击&#…...

实验2 字符及字符串输入输出与分支程序设计实验

字符及字符串输入输出 从键盘输入两个一位十进制数&#xff0c;计算这两个数之和&#xff0c;并将结果在屏幕上显示出来。 分支程序设计 从键盘输入一字符&#xff0c;判断该字符是小写字母、大写字母、数字或者其他字符。若输入为小写字母&#xff0c;显示“You Input a Lo…...

docker容器间网络仿真工具-pumba

docker-tc&pumba docker-tc:docker-tc项目仓库 pumba:pumba项目仓库 这两个项目理论上都可以实现对容器间的网络环境进行各种模拟干预&#xff0c;包括延迟&#xff0c;丢包&#xff0c;带宽限制等。 但是我在实际使用时&#xff0c;发现docker-tc这个工具在进行网络进行模…...

A36 STM32_HAL库函数 之PCD通用驱动 -- B -- 所有函数的介绍及使用

A36 STM32_HAL库函数 之PCD通用驱动 -- B -- 所有函数的介绍及使用 1 该驱动函数预览1.11 HAL_PCD_SOFCallback1.12 HAL_PCD_ResetCallback1.13 HAL_PCD_SuspendCallback1.14 HAL_PCD_ResumeCallback1.15 HAL_PCD_ISOOUTIncompleteCallback1.16 HAL_PCD_ISOINIncompleteCallbac…...

vue2 + element三级菜单实现模板

需求&#xff1a; 需要一个含有三级菜单的结构模板&#xff0c;用于业务快速开发。 解决&#xff1a; sidebar.vue <template><el-menu :default-active"defaultActive" class"el-menu-vertical-demo" active-text-color"#ffd04b"&…...

vue H5页面video 视频流自动播放, 解决ios不能自动播放问题

视频组件 <videostyle"width: 100%; height: 100%;object-fit: fill"class"player"refplayer_big_boxcontrolspreloadautoplay //自动播放muted //是否静音playsinline"true"x5-playsinline""webkit-playsinline"tru…...

自闭症儿童:探索症状背后的多彩内心世界

在星启帆自闭症康复中心&#xff0c;我们每天与一群独特而珍贵的孩子相遇——他们&#xff0c;是自闭症谱系障碍的患儿。自闭症&#xff0c;这一复杂的神经发育障碍&#xff0c;以其多样化的症状表现&#xff0c;为每个孩子的生活轨迹绘上了不同的色彩。 自闭症孩子的症状各异…...

在Centos7上安装PostgreSQL16的详细步骤

文章目录 环境一、准备二、postgresql下载方法一&#xff1a;wget下载方法二&#xff1a;下载压缩包解压 三、创建用户组、用户四、创建数据主目录五、配置环境变量六、initdb初使化数据库七、配置服务八、设置开机自启动九、设置防火墙十、启动数据库服务 环境 CPU: 4 核心或以…...

MySQL 图形化界面

填完信息之后&#xff0c;圆圈处可以验证是否可以连接数据库 展示所有数据库&#xff08;因为有的可能连上&#xff0c;却没有数据库显示&#xff09;...

【人工智能】GPT-5的即将到来:从高中生进化到,,,博士生?

GPT-5的即将到来&#xff1a;从高中生进化到,博士生&#xff1f; 随着近月GPT-4o的出世&#xff0c;OpenAI也在进行一系列的采访和介绍接下来的展望和目标。 在6月22日的采访中&#xff0c;美国达特茅斯工程学院公布了OpenAI首席技术官米拉穆拉蒂的访谈内容。穆拉蒂确认&#…...

【收录率高丨投稿范围广 | 往届均已EI检索】第四届光学与通信技术国际学术会议(ICOCT 2024,8月9-11)

欢迎参加第四届光学与通信技术国际学术会议&#xff08;ICOCT 2024&#xff09;&#xff0c;该会议将于2024年8月9-11日在南京举办。自2021年首次会议以来&#xff0c;ICOCT已经发展成为光学和通信领域较有影响力的国际会议之一&#xff0c;聚焦最前沿的技术进展与未来发展趋势…...

小阿轩yx-LVS负载均衡群集

小阿轩yx-LVS负载均衡群集 构建群集服务器—通过整合多台服务器使用 LVS 达到服务器的高可用和负载均衡并以同一个 IP 地址对外提供相同的服务 LVS 群集应用基础 群集称呼来自英文单词“Cluster”在服务器领域则表示大量服务器的集合体&#xff0c;区分单个服务器 Cluster …...

CPP知识点记录总结

1、类的const成员函数 const成员函数的const 实际修饰的是该成员函数隐含的this指针&#xff0c;表明在该成员函数中不能对类的任何成员进行修改。 class A {void fun() const {// 常成员函数&#xff0c;在函数名后用const修饰} } 一文带你入门C类和对象【十万字详解&#…...

Spring源码(一) 如何阅读 Spring 源码

学习 Spring 的源码&#xff0c;也可以通过 SpringBoot 搭环境。 不管是什么源码&#xff0c;最好写个 demo&#xff0c;跑起来&#xff0c;然后从常用的类和方法入手&#xff0c;跟踪调试。 配置对象 新建一个 SpringBoot 的项目&#xff0c; 详情见&#xff1a; https://b…...

【代码随想录训练营】【Day 63】【单调栈-2】| Leetcode 42, 84

【代码随想录训练营】【Day 63】【单调栈-2】| Leetcode 42, 84 需强化知识点 单调栈强化 题目 42. 接雨水 注意 python 数组反序用法 result [::-1] class Solution:def trap(self, height: List[int]) -> int:# n len(height)# leftMax, rightMax [0] * n, [0] * …...

CTF常用sql注入(一)联合注入和宽字节

0x01 前言 给自己总结一下sql注入的常用姿势吧&#xff0c;记录一下学习 0x02 联合 联合注入的关键词是union SQL的union联合注入原理是联合两个表进行注入攻击&#xff0c;使用union select关键词来进行联合查询。 那么为什么我们在题目中一般是只写一个呢 因为 $sql &quo…...

薄冰英语语法学习--冠词1

冠词有2个,the 和 a /an the 叫定冠词 常用形容一类事务、特指&#xff08;加强&#xff09;、放在转有名词前面。 就这3个 定冠词 1. 定冠词特指某个&#xff08;某些&#xff09;人或某个&#xff08;某些&#xff09;事物 Many people came here to visit the old cast…...

基于Java中的SSM框架实现野生动物公益保护系统项目【项目源码+论文说明】计算机毕业设计

基于Java中的SSM框架实现野生动物公益保护系统演示 摘要 本系统按照网站系统设计的基本流程&#xff0c;遵循系统开发生命周期法和结构化方法&#xff0c;基于Java语言设计并实现了野生动物公益保护系统。该系统基于浏览器/服务器模式&#xff0c;采用JSP技术&#xff0c;后台…...

c->c++(二):class

本文主要探讨C类的相关知识。 构造和析构函数 构造函数(可多个)&#xff1a;对象产生时调用初始化class属性、分配class内部需要的动态内存 析构函数&#xff08;一个&#xff09;&#xff1a;对对象消亡时调用回收分配动态内存 C提供默认构造和析构,…...

11 UDP的可靠传输协议QUIC

1.如何做到可靠性传输 2.UDP与TCP,我们如何选择 3.UDP如何可靠,KCP协议在哪些方面有优势 4.KCP协议精讲(重点讲解 5.OUIC时代是否已经到来 UDP如何做到可靠传输 ACK机制重传机制 重传策略序号机制(后发的包可能先到) 3 2 1-> 2 3 1重排机制 2 3 1-> 3 2 1窗口机制 流…...

14-20 Vision Transformer用AI的画笔描绘新世界

概述 毫无疑问,目前最受关注且不断发展的最重要的主题之一是使用人工智能生成图像、视频和文本。大型语言模型 (LLM) 已展示出其在文本生成方面的卓越能力。它们在文本生成方面的许多问题已得到解决。然而,LLM 面临的一个主要挑战是它们有时会产生幻觉反应。 最近推出的新模…...

LVS FILTER UNUSED OPTION

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 过滤一些版图与spice网表对不上的器件。 一般后端遇不到这个问题,因为通常是需要写到网表中的decap没有写出来造成的,如下图。...

Python后端面试题

1. 文件操作w和r的区别 在Python中&#xff0c;文件操作模式中的w和r都表示对文件的读写操作&#xff0c;但它们在打开文件时的行为有所不同&#xff1a; r模式&#xff1a; 读写&#xff1a;这种模式允许你同时读取和写入文件。文件必须已经存在&#xff0c;否则会抛出一个Fi…...

docker打包 arm32v7/debian 问题总结

1.架构不同 我的宿主是x86 ,但是打包的是arm架构 安装qemu sudo apt-get install binfmt-support qemu qemu-user-static 然后使用buildx打包 docker buildx build --no-cache --platform linux/arm/v7 -t tdc_post:1.0.1 . --load 保存tar docker save -o tdc_post.tar tdc_p…...

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(二十)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 30 节&#xff09; P30《29.数据持久化-用户首选项》 实现数据持久化在harmonyOS中有很多种方式&#xff0c;比较常见的是以下两…...

Vuetify3:监听当前手机还是电脑

我们在开发的时候&#xff0c;实现根据移动设备或PC设备来改编一些交互样式&#xff0c;这个时候我们需要监听宽度&#xff0c;在Vuetify3中可我们可以参考 ​​​​显示 & 平台配合监听即可在窗口缩小的时候判断出手机还是电脑 <template><v-app><div v-if…...