尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

高并发服务器day17

高并发服务器day17 HttpRequest 请求信息模块一、模块作用HttpRequest用于存储一次 HTTP 请求中的各项信息并提供请求头、查询参数、正文长度以及连接方式等常用操作接口。简单来说HTTP 请求解析完成后解析结果都会保存到HttpRequest对象中方便后续业务处理。二、HTTP 请求包含的信息一个完整的 HTTP 请求主要由以下三部分组成1. 请求行请求行包含请求方法URLHTTP 协议版本例如GET /search/1234?wordCenutf8 HTTP/1.1其中GET请求方法/search/1234资源路径wordCenutf8查询字符串HTTP/1.1协议版本URL 可以进一步拆分为两部分内容示例资源路径/search/1234查询字符串wordCenutf82. 请求头部请求头由多个键值对组成每一行表示一个头部字段key: value\r\nkey: value\r\n……例如Content-Length: 0\r\n请求头中通常会包含正文长度、连接方式等信息。3. 请求正文请求正文用于保存客户端提交的数据。例如客户端使用 POST 请求提交表单或 JSON 数据时这些数据通常保存在请求正文中。三、HttpRequest 保存的数据HttpRequest类主要保存以下请求信息成员变量作用_method保存请求方法例如 GET、POST_path保存请求的资源路径_version保存 HTTP 协议版本_body保存请求正文_matches保存正则表达式匹配结果_headers保存所有请求头字段_params保存 URL 查询参数其中std::smatch用于保存正则表达式的匹配结果。例如请求路径为/search/1234使用正则表达式匹配后可以将路径中的1234提取出来并保存在_matches中。四、HttpRequest 类结构class HttpRequest{public:std::string _method;std::string _path;std::string _version;std::string _body;std::smatch _matches; std::unordered_mapstd::string, std::string _headers; std::unordered_mapstd::string, std::string _params;public:void SetHeader(std::string key, std::string val);bool HasHeader(std::string key);std::string GetHeader(std::string key);void SetParam(std::string key, std::string val); bool HasParam(std::string key); std::string GetParam(std::string key); size_t ContentLength(); bool Close();};五、功能接口设计1. 请求头操作SetHeader()向请求头集合中插入一个头部字段。void SetHeader(std::string key, std::string val);例如Content-Type: application/json会以键值对的形式保存到_headers中。HasHeader()判断指定请求头是否存在。bool HasHeader(std::string key);GetHeader()获取指定请求头对应的值。std::string GetHeader(std::string key);2. 查询参数操作例如下面的 URL/search?wordCenutf8解析后可以得到参数名参数值wordCenutf8这些查询参数会保存在_params中。SetParam()插入一个查询参数。void SetParam(std::string key, std::string val);HasParam()判断指定查询参数是否存在。bool HasParam(std::string key);GetParam()获取指定查询参数的值。std::string GetParam(std::string key);3. 获取正文长度ContentLength()用于获取 HTTP 请求正文的长度。size_t ContentLength();通常通过读取请求头中的Content-Length字段得到正文长度。例如Content-Length: 100表示请求正文的长度为 100 字节。4. 判断连接方式Close()用于判断当前 HTTP 请求处理完成后是否需要关闭连接。bool Close();主要根据Connection请求头进行判断请求头含义Connection: close当前请求处理完成后关闭连接Connection: keep-alive保持连接继续处理后续请求因此该接口可以用于区分 HTTP 长连接和短连接。六、总结HttpRequest模块负责保存一次 HTTP 请求的完整信息包括请求方法资源路径查询字符串HTTP 协议版本请求头字段请求正文正则匹配结果同时提供请求头查询、查询参数查询、正文长度获取以及连接方式判断等接口为后续路由匹配和业务处理提供统一的请求数据对象。HttpResponse 模块设计一、模块作用HttpResponse模块用于统一存储一次 HTTP 响应所需的信息并提供简单的操作接口方便服务器构造响应内容。二、HTTP 响应信息响应信息作用响应状态码表示请求的处理结果例如成功、资源不存在等头部字段保存响应头中的键值对信息响应正文保存服务器返回给客户端的实际数据重定向信息记录是否需要重定向以及重定向的目标路径其中重定向信息通常包含两部分是否进行重定向的标志重定向后的目标路径。三、功能接口1. 成员访问为了便于服务器直接设置响应内容可以将部分响应信息设置为公有成员简化成员访问和数据修改。2. 头部字段操作提供响应头字段的相关接口包括新增头部字段查询指定头部字段获取指定头部字段的值。3. 响应正文设置提供正文设置接口用于保存需要返回给客户端的数据。4. 重定向设置提供重定向接口用于设置当前响应是否进行重定向重定向的目标路径。5. 长短连接判断根据 HTTP 请求或响应中的连接字段判断当前连接采用长连接响应完成后继续保持连接HTTP 请求接收上下文模块设计一、模块作用HTTP 请求接收上下文模块用于记录 HTTP 请求的接收状态和处理进度。在网络通信中一次接收到的数据不一定包含一条完整的 HTTP 请求。例如请求行、请求头和请求正文可能会分多次到达。因此服务器必须保存当前已经处理到的位置等待后续数据到达后继续处理。简单来说该模块解决的是本次数据没有接收完整时下次从哪里继续解析。二、为什么需要记录接收上下文TCP 是面向字节流的协议不会保证一次读取就得到完整的 HTTP 请求。一次读取可能出现以下情况只接收到部分请求行接收到请求行和部分请求头请求头已经完整但请求正文尚未接收完成一次读取中接收到完整请求解析过程中发现请求格式错误。因此每次处理完当前数据后都需要保存请求的接收状态避免下次重新解析已经处理过的数据。三、请求上下文中的核心信息请求上下文主要包含以下三个要素接收状态响应状态码已经接收并解析完成的请求信息。四、请求接收状态接收状态用于表示当前 HTTP 请求处理到了哪个阶段。表 1 HTTP 请求接收状态说明状态名称 含义接收请求行 当前正在接收并处理 HTTP 请求行接收请求头部 请求行已经解析完成正在接收请求头部接收请求正文 请求头已经解析完成正在接收请求正文接收数据完毕 一条完整的 HTTP 请求已经接收完成可以交给业务逻辑处理接收处理请求出错 请求接收或解析过程中出现错误其中“接收数据完毕”表示当前请求已经完整解析可以正式进入请求处理阶段。五、响应状态码在接收和解析 HTTP 请求的过程中可能出现不同类型的错误例如请求行格式错误请求头格式错误请求正文不完整请求内容不合法客户端没有访问权限。不同错误需要返回不同的 HTTP 响应状态码因此请求上下文还需要保存当前应返回的状态码。例如请求格式错误可以返回 400 Bad Request没有访问权限可以返回 403 Forbidden请求的资源不存在可以返回 404 Not Found。六、已经接收并处理的请求信息请求上下文内部需要保存一个 HTTP 请求对象用于记录已经解析完成的内容包括请求方法请求路径HTTP 协议版本请求头字段请求正文。当请求全部接收完成后服务器可以直接获取该请求对象并交给上层业务逻辑处理。七、模块需要提供的接口接收并处理请求数据该接口负责根据当前接收状态对缓冲区中的数据进行处理。整体处理顺序为接收请求行→ 解析请求行→ 接收请求头部→ 解析请求头部→ 接收请求正文→ 请求接收完成其中可以将处理过程拆分为以下几个内部步骤接收请求行从缓冲区中查找请求行结束标志解析请求行提取请求方法、请求路径和协议版本接收请求头部逐行读取请求头字段解析请求头部解析字段名称和字段值接收请求正文根据 Content-Length 等字段判断正文长度并读取数据。如果任何一个阶段发生错误就需要将接收状态修改为“接收处理请求出错”同时记录对应的响应状态码。返回解析完成的请求信息该接口用于获取已经解析完成的 HTTP 请求对象。当接收状态为“接收数据完毕”时上层服务器可以通过该接口取得请求信息并进行业务处理。返回响应状态码该接口用于获取当前上下文保存的响应状态码。当请求解析失败时服务器可以根据该状态码生成错误响应。返回接收解析状态该接口用于获取当前请求所处的接收阶段例如正在接收请求行正在接收请求头部正在接收请求正文请求接收完成请求处理出错。八、整体处理流程HTTP 请求接收上下文的完整处理流程如下客户端发送数据→ 服务器读取数据到接收缓冲区→ 请求上下文根据当前状态解析数据→ 数据不完整时保存当前处理状态→ 等待下一次数据到达→ 继续从上次位置解析→ 请求接收完整→ 返回解析完成的 HTTP 请求对象→ 交给上层业务模块处理如果解析过程中出现错误解析失败→ 修改接收状态→ 保存错误响应状态码→ 生成对应的 HTTP 错误响应九、总结HTTP 请求接收上下文模块本质上是一个请求解析状态管理器。它主要完成三项工作记录 HTTP 请求当前解析到了哪个阶段保存已经解析完成的请求数据在解析失败时记录对应的响应状态码。通过该模块即使一条 HTTP 请求被拆分成多次数据接收服务器仍然可以在下一次接收数据时继续解析而不需要从头重新处理。
返回列表