http-parser用法

头文件说明:

解析类型定义:
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };

解析函数声明:
void http_parser_init(http_parser *parser, enum http_parser_type type);
void http_parser_settings_init(http_parser_settings *settings);
size_t http_parser_execute(http_parser *parser,
const http_parser_settings *settings, const char *data, size_t len);

说明:
http_parser_execute解析请求或应答报文,并返回实际解析的报文长度,此长度只代表解析一个完整报文扫描的长度,并不表示接收完整报文成功,完整报文的判断需要依赖on_message_complete回调。
如果发生错误,可以检查parser->http_errno的数值。

回调函数集合设定:
struct http_parser_settings {
http_cb on_message_begin; // 消息开始回调
http_data_cb on_url; // url回调
http_data_cb on_status; // 状态回调
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; // 消息结束回调
http_cb on_chunk_header; // 收到chunk响应回调,已接收的chunk数据长度保存在parser->content_length
http_cb on_chunk_complete; // chunk响应结束回调
};

回调函数定义:
typedef int (http_data_cb) (http_parser, const char at, size_t length);
typedef int (
http_cb) (http_parser*);

使用方法:
将源码中的http_parser.h和http_parser.c直接拷贝到工程目录下,随工程一起编译,同时支持windows及linux。

用法举例:

解析请求:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>

#include <string>
#include <map>
#include "http_parser.h"

// 用于解析的全局变量
bool bParsed = false;
std::map<std::string, std::string> mapHeadField;
std::string strUrl;
std::string strStatus;
std::string strBody;
std::string strFieldTmp;

// 用于解析的回调函数
int onMessageBegin(http_parser* pParser);
int onHeaderComplete(http_parser* pParser);
int onMessageComplete(http_parser* pParser);
int onURL(http_parser* pParser, const char *at, size_t length);
int onStatus(http_parser* pParser, const char *at, size_t length);
int onHeaderField(http_parser* pParser, const char *at, size_t length);
int onHeaderValue(http_parser* pParser, const char *at, size_t length);
int onBody(http_parser* pParser, const char *at, size_t length);


int main(int argc, char* argv[])
{
    // 待解析的请求报文
    std::string strHttpReq = "";
    strHttpReq += "POST /uploaddata HTTP/1.1\r\n";
    strHttpReq += "Host: 127.0.0.1:8080\r\n";
    strHttpReq += "Accept: */*\r\n";
    strHttpReq += "Content-Length: 70\r\n";
    strHttpReq += "Content-Type: application/json\r\n";
    strHttpReq += "\r\n";
    strHttpReq += "{\"DeviceID\":\"12345678\",\"LowPressure\":80,\"HighPressure\":120,\"Pulse\":90}";

    http_parser httpParser;
    http_parser_settings httpSettings;

    // 初使化解析器及回调函数
    http_parser_init(&httpParser, HTTP_REQUEST);
    http_parser_settings_init(&httpSettings);
    httpSettings.on_message_begin = onMessageBegin;
    httpSettings.on_headers_complete = onHeaderComplete;
    httpSettings.on_message_complete = onMessageComplete;
    httpSettings.on_url = onURL;
    httpSettings.on_status = onStatus;
    httpSettings.on_header_field = onHeaderField;
    httpSettings.on_header_value = onHeaderValue;
    httpSettings.on_body = onBody;

    // 解析请求
    int nParseBytes = http_parser_execute(&httpParser, &httpSettings, strHttpReq.data(), strHttpReq.size());
    printf("http_parser_execute => parsebytes:[%d] parseok:[%d] \n", nParseBytes, bParsed);

    // 解析成功,打印解析结果
    if (bParsed)
    {
        printf("url: [%s] \n", strUrl.c_str());
        printf("status: [%s] \n", strStatus.c_str());
        printf("heads: \n");
        for (std::map<std::string, std::string>::iterator iter = mapHeadField.begin(); iter != mapHeadField.end(); ++iter)
        {
            printf("\t %s : %s \n", iter->first.c_str(), iter->second.c_str());
        }
        printf("body: [%s] \n", strBody.c_str());
    }

    return 0;
}


int onMessageBegin(http_parser* pParser)
{
    printf("@onMessageBegin call \n");
    bParsed = false;
    return 0;
}
int onHeaderComplete(http_parser* pParser)
{
    printf("@onHeaderComplete call \n");
    return 0;
}
int onMessageComplete(http_parser* pParser)
{
    printf("@onMessageComplete call \n");
    bParsed = true;
    return 0;
}
int onURL(http_parser* pParser, const char *at, size_t length)
{
    printf("@onURL call, length:[%d] \n", length);
    strUrl.assign(at, length);
    printf("@onURL url:[%s] \n", strUrl.c_str());
    return 0;
}
int onStatus(http_parser* pParser, const char *at, size_t length)
{
    printf("@onStatus call, length:[%d] \n", length);
    strStatus.assign(at, length);
    printf("@onStatus status:[%s] \n", strStatus.c_str());
    return 0;
}
int onHeaderField(http_parser* pParser, const char *at, size_t length)
{
    printf("@onHeaderField call, length:[%d] \n", length);
    strFieldTmp.assign(at, length);
    printf("@onHeaderField field:[%s] \n", strFieldTmp.c_str());
    return 0;
}
int onHeaderValue(http_parser* pParser, const char *at, size_t length)
{
    printf("@onHeaderValue call, length:[%d] \n", length);
    std::string strValue(at, length);
    printf("@onHeaderValue value:[%s] \n", strValue.c_str());
    mapHeadField.insert( std::make_pair(strFieldTmp, strValue) );
    return 0;
}
int onBody(http_parser* pParser, const char *at, size_t length)
{
    printf("@onBody call, length:[%d] \n", length);
    printf("@onBody recv:[%s] \n", std::string(at, length).c_str());
    strBody.append(at, length);
    return 0;
}

执行输出如下:

@onMessageBegin call 
@onURL call, length:[11] 
@onURL url:[/uploaddata] 
@onHeaderField call, length:[4] 
@onHeaderField field:[Host] 
@onHeaderValue call, length:[14] 
@onHeaderValue value:[127.0.0.1:8080] 
@onHeaderField call, length:[6] 
@onHeaderField field:[Accept] 
@onHeaderValue call, length:[3] 
@onHeaderValue value:[*/*] 
@onHeaderField call, length:[14] 
@onHeaderField field:[Content-Length] 
@onHeaderValue call, length:[2] 
@onHeaderValue value:[70] 
@onHeaderField call, length:[12] 
@onHeaderField field:[Content-Type] 
@onHeaderValue call, length:[16] 
@onHeaderValue value:[application/json] 
@onHeaderComplete call 
@onBody call, length:[70] 
@onBody recv:[{"DeviceID":"12345678","LowPressure":80,"HighPressure":120,"Pulse":90}] 
@onMessageComplete call 
http_parser_execute => parsebytes:[186] parseok:[1] 
url: [/uploaddata] 
status: [] 
heads: 
         Accept : */* 
         Content-Length : 70 
         Content-Type : application/json 
         Host : 127.0.0.1:8080 
body: [{"DeviceID":"12345678","LowPressure":80,"HighPressure":120,"Pulse":90}] 

解析响应:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>

#include <string>
#include <map>
#include "http_parser.h"

// 用于解析的全局变量
bool bParsed = false;
std::map<std::string, std::string> mapHeadField;
std::string strUrl;
std::string strStatus;
std::string strBody;
std::string strFieldTmp;

// 用于解析的回调函数
int onMessageBegin(http_parser* pParser);
int onHeaderComplete(http_parser* pParser);
int onMessageComplete(http_parser* pParser);
int onURL(http_parser* pParser, const char *at, size_t length);
int onStatus(http_parser* pParser, const char *at, size_t length);
int onHeaderField(http_parser* pParser, const char *at, size_t length);
int onHeaderValue(http_parser* pParser, const char *at, size_t length);
int onBody(http_parser* pParser, const char *at, size_t length);


int main(int argc, char* argv[])
{
    // 待解析的响应报文
    std::string strHttpRes = "";
    strHttpRes += "HTTP/1.1 200 OK\r\n";
    strHttpRes += "Cache-Control: private\r\n";
    strHttpRes += "Content-Type: application/json; charset=utf-8\r\n";
    strHttpRes += "Server: Microsoft-IIS/8.0\r\n";
    strHttpRes += "X-AspNetMvc-Version: 5.2\r\n";
    strHttpRes += "X-AspNet-Version: 4.0.30319\r\n";
    strHttpRes += "X-Powered-By: ASP.NET\r\n";
    strHttpRes += "Date: Sat, 24 Oct 2020 02:45:29 GMT\r\n";
    strHttpRes += "Content-Length: 30\r\n";
    strHttpRes += "\r\n";
    strHttpRes += "{\"State\":\"Success\",\"Msg\":\"OK\"}";

    http_parser httpParser;
    http_parser_settings httpSettings;

    // 初使化解析器及回调函数
    http_parser_init(&httpParser, HTTP_RESPONSE);
    http_parser_settings_init(&httpSettings);
    httpSettings.on_message_begin = onMessageBegin;
    httpSettings.on_headers_complete = onHeaderComplete;
    httpSettings.on_message_complete = onMessageComplete;
    httpSettings.on_url = onURL;
    httpSettings.on_status = onStatus;
    httpSettings.on_header_field = onHeaderField;
    httpSettings.on_header_value = onHeaderValue;
    httpSettings.on_body = onBody;

    // 解析响应
    int nParseBytes = http_parser_execute(&httpParser, &httpSettings, strHttpRes.data(), strHttpRes.size());
    printf("http_parser_execute => parsebytes:[%d] parseok:[%d] \n", nParseBytes, bParsed);

    // 解析成功,打印解析结果
    if (bParsed)
    {
        printf("url: [%s] \n", strUrl.c_str());
        printf("status: [%s] \n", strStatus.c_str());
        printf("heads: \n");
        for (std::map<std::string, std::string>::iterator iter = mapHeadField.begin(); iter != mapHeadField.end(); ++iter)
        {
            printf("\t %s : %s \n", iter->first.c_str(), iter->second.c_str());
        }
        printf("body: [%s] \n", strBody.c_str());
    }

    return 0;
}


int onMessageBegin(http_parser* pParser)
{
    printf("@onMessageBegin call \n");
    bParsed = false;
    return 0;
}
int onHeaderComplete(http_parser* pParser)
{
    printf("@onHeaderComplete call \n");
    return 0;
}
int onMessageComplete(http_parser* pParser)
{
    printf("@onMessageComplete call \n");
    bParsed = true;
    return 0;
}
int onURL(http_parser* pParser, const char *at, size_t length)
{
    printf("@onURL call, length:[%d] \n", length);
    strUrl.assign(at, length);
    printf("@onURL url:[%s] \n", strUrl.c_str());
    return 0;
}
int onStatus(http_parser* pParser, const char *at, size_t length)
{
    printf("@onStatus call, length:[%d] \n", length);
    strStatus.assign(at, length);
    printf("@onStatus status:[%s] \n", strStatus.c_str());
    return 0;
}
int onHeaderField(http_parser* pParser, const char *at, size_t length)
{
    printf("@onHeaderField call, length:[%d] \n", length);
    strFieldTmp.assign(at, length);
    printf("@onHeaderField field:[%s] \n", strFieldTmp.c_str());
    return 0;
}
int onHeaderValue(http_parser* pParser, const char *at, size_t length)
{
    printf("@onHeaderValue call, length:[%d] \n", length);
    std::string strValue(at, length);
    printf("@onHeaderValue value:[%s] \n", strValue.c_str());
    mapHeadField.insert( std::make_pair(strFieldTmp, strValue) );
    return 0;
}
int onBody(http_parser* pParser, const char *at, size_t length)
{
    printf("@onBody call, length:[%d] \n", length);
    printf("@onBody recv:[%s] \n", std::string(at, length).c_str());
    strBody.append(at, length);
    return 0;
}

执行输出如下:

@onMessageBegin call 
@onStatus call, length:[2] 
@onStatus status:[OK] 
@onHeaderField call, length:[13] 
@onHeaderField field:[Cache-Control] 
@onHeaderValue call, length:[7] 
@onHeaderValue value:[private] 
@onHeaderField call, length:[12] 
@onHeaderField field:[Content-Type] 
@onHeaderValue call, length:[31] 
@onHeaderValue value:[application/json; charset=utf-8] 
@onHeaderField call, length:[6] 
@onHeaderField field:[Server] 
@onHeaderValue call, length:[17] 
@onHeaderValue value:[Microsoft-IIS/8.0] 
@onHeaderField call, length:[19] 
@onHeaderField field:[X-AspNetMvc-Version] 
@onHeaderValue call, length:[3] 
@onHeaderValue value:[5.2] 
@onHeaderField call, length:[16] 
@onHeaderField field:[X-AspNet-Version] 
@onHeaderValue call, length:[9] 
@onHeaderValue value:[4.0.30319] 
@onHeaderField call, length:[12] 
@onHeaderField field:[X-Powered-By] 
@onHeaderValue call, length:[7] 
@onHeaderValue value:[ASP.NET] 
@onHeaderField call, length:[4] 
@onHeaderField field:[Date] 
@onHeaderValue call, length:[29] 
@onHeaderValue value:[Sat, 24 Oct 2020 02:45:29 GMT] 
@onHeaderField call, length:[14] 
@onHeaderField field:[Content-Length] 
@onHeaderValue call, length:[2] 
@onHeaderValue value:[30] 
@onHeaderComplete call 
@onBody call, length:[30] 
@onBody recv:[{"State":"Success","Msg":"OK"}] 
@onMessageComplete call 
http_parser_execute => parsebytes:[282] parseok:[1] 
url: [] 
status: [OK] 
heads: 
         Cache-Control : private 
         Content-Length : 30 
         Content-Type : application/json; charset=utf-8 
         Date : Sat, 24 Oct 2020 02:45:29 GMT 
         Server : Microsoft-IIS/8.0 
         X-AspNet-Version : 4.0.30319 
         X-AspNetMvc-Version : 5.2 
         X-Powered-By : ASP.NET 
body: [{"State":"Success","Msg":"OK"}] 

猜你喜欢

转载自blog.csdn.net/wangrenhaioylj/article/details/110981777