对于http服务器,http request的解析是比较麻烦的,由于我们的重点并不在这上面,所以这一部分不打算自己编写,而是使用开源的http-parser库,下面我们将使用该库来构建项目中处理http的类。
HTTP Parser简介
http-parser是一个用C编写的HTTP消息解析器,可以解析HTTP请求或者回应消息。
这个解析器常常在高性能的HTTP应用中使用。
在解析的过程中,它不会调用任何系统调用,不会在HEAP上申请内存,不会缓存数据,并且可以在任意时刻打断解析过程,而不会产生任何影响。
对于每个HTTP消息(在WEB服务器中就是每个请求),它只需要40字节的内存占用(解析器本身的基本数据结构)。
特性:
无第三方依赖
可以处理持久消息(keep-alive)
支持解码chunk编码的消息
支持Upgrade协议升级(如无例外就是WebSocket)
可以防御缓冲区溢出攻击
解析器可以处理以下类型的HTTP消息:
头部的字段和值
Content-Length
请求方法
响应的状态码
Transfer-Encoding
HTTP版本
请求的URL
消息主体
Github链接:
https://github.com/nodejs/http-parser
下面我们将根据它提供的接口来编写我们自己的类。
准备工作
首先,我们根据上一节所讲的http知识,定义我们的http request和response结构体:
typedef std::map<std::string, std::string> header_t;
typedef header_t::iterator header_iter_t;
struct HttpRequest
{
std::string http_method;
std::string http_url;
//std::string http_version;
header_t http_headers;
std::string http_header_field; //field is waiting for value while parsing
std::string http_body;
};
struct HttpResponse
{
//std::string http_version;
int http_code;
std::string http_phrase;
header_t http_headers;
std::string http_body;
std::string GetResponse();
void ResetResponse();
};
几点说明:
- 我们先假定http_version为HTTP/1.1,所以暂时不对该字段进行处理;
- http_header_field是在使用http-parser用来暂存header的field的;
- GetResponse()函数利用数据成员生成并返回一则response消息字符串(可直接用于发送给客户端)