1.简介
TeamTalk http解析实际上是利用了ngnix的http_parse解析库。
2.HTTP简介
-
请求报文
参考图解HTTP-上野宣 -
响应报文
参考图解HTTP-上野宣 -
URI格式
参考图解HTTP-上野宣
3.ngnix http_parse解析库
http_parse:存放一些用于管理的状态
struct http_parser {
/** PRIVATE **/
unsigned char type : 2; /* enum http_parser_type */
unsigned char flags : 6; /* F_* values from 'flags' enum; semi-public */
unsigned char state; /* enum state from http_parser.c */
unsigned char header_state; /* enum header_state from http_parser.c */
unsigned char index; /* index into current matcher */
uint32_t nread; /* # bytes read in various scenarios */
uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
/** READ-ONLY **/
unsigned short http_major;
unsigned short http_minor;
unsigned short status_code; /* responses only */
unsigned char method; /* requests only */
unsigned char http_errno : 7;
/* 1 = Upgrade header was present and the parser has exited because of that.
* 0 = No upgrade header present.
* Should be checked when http_parser_execute() returns in addition to
* error checking.
*/
unsigned char upgrade : 1;
/** PUBLIC **/
void *data; /* A pointer to get hook to the "connection" or "socket" object */
};
http_parser_settings:设置回调
typedef int (*http_data_cb)(http_parser*, const char *at, size_t length, void* obj);
typedef int (*http_cb)(http_parser*, void* obj);
struct http_parser_settings {
http_cb on_message_begin;
http_data_cb on_url;
http_cb on_status_complete;
http_data_cb on_header_field;
http_data_cb on_header_value;
http_cb on_headers_complete;
http_data_cb on_body;
http_cb on_message_complete;
void* object;
};
http_parse使用
void CHttpParserWrapper::ParseHttpContent(const char* buf, uint32_t len)
{
//1.初始化解析器
http_parser_init(&m_http_parser, HTTP_REQUEST);
//2.设置回调函数
memset(&m_settings, 0, sizeof(m_settings));
m_settings.on_url = OnUrl;
m_settings.on_header_field = OnHeaderField;
m_settings.on_header_value = OnHeaderValue;
m_settings.on_headers_complete = OnHeadersComplete;
m_settings.on_body = OnBody;
m_settings.on_message_complete = OnMessageComplete;
m_settings.object = this;
m_read_all = false;
m_read_referer = false;
m_read_forward_ip = false;
m_read_user_agent = false;
m_read_content_type = false;
m_read_content_len = false;
m_read_host = false;
m_total_length = 0;
m_url.clear();
m_body_content.clear();
m_referer.clear();
m_forward_ip.clear();
m_user_agent.clear();
m_content_type.clear();
m_content_len = 0;
m_host.clear();
//3. 开始执行解析器
http_parser_execute(&m_http_parser, &m_settings, buf, len);
}
4.CHttpParserWrapper
teamtalk为http_parse实现的一个包裹类。
-
void ParseHttpContent(const char* buf, uint32_t len):
http报文解析器 -
bool IsReadAll()/void SetReadAll():
消息解析完成标识;
http_parser解析会调用CALLBACK_NOTIFY(message_complete)实际调用了SetReadAll -
char* GetUrl():
获取url -
char* GetBodyContent():
获取http消息体
5.源码
- 链接:TeamTalk_BlueBling
- 测试demo: test_httpparser.cpp