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"}] 

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
http-parser是一个解析HTTP消息的C库,可以用于解析HTTP请求和响应。它被广泛应用于HTTP服务器、代理、负载均衡器等网络应用程序中。 使用http-parser,您可以将HTTP消息解析成易于处理的结构体,以便在应用程序中进行进一步处理。例如,您可以使用http-parser来解析HTTP请求标头,并从中提取客户端的IP地址、请求方法、路径和查询参数等信息。 以下是使用http-parser的一些示例: 1. 解析HTTP请求: ```c #include "http_parser.h" int on_message_begin(http_parser* parser) { // HTTP message begin return 0; } int on_url(http_parser* parser, const char* at, size_t length) { // URL found return 0; } int on_header_field(http_parser* parser, const char* at, size_t length) { // HTTP header field found return 0; } int on_header_value(http_parser* parser, const char* at, size_t length) { // HTTP header value found return 0; } int on_headers_complete(http_parser* parser) { // HTTP headers complete return 0; } int on_body(http_parser* parser, const char* at, size_t length) { // HTTP body found return 0; } int on_message_complete(http_parser* parser) { // HTTP message complete return 0; } int main() { http_parser_settings settings; http_parser parser; char* request = "GET /index.html HTTP/1.1\r\nHost: example.com\r\n\r\n"; size_t request_len = strlen(request); http_parser_settings_init(&settings); settings.on_message_begin = on_message_begin; settings.on_url = on_url; settings.on_header_field = on_header_field; settings.on_header_value = on_header_value; settings.on_headers_complete = on_headers_complete; settings.on_body = on_body; settings.on_message_complete = on_message_complete; http_parser_init(&parser, HTTP_REQUEST); http_parser_execute(&parser, &settings, request, request_len); return 0; } ``` 2. 解析HTTP响应: ```c #include "http_parser.h" int on_message_begin(http_parser* parser) { // HTTP message begin return 0; } int on_status(http_parser* parser, const char* at, size_t length) { // HTTP status found return 0; } int on_header_field(http_parser* parser, const char* at, size_t length) { // HTTP header field found return 0; } int on_header_value(http_parser* parser, const char* at, size_t length) { // HTTP header value found return 0; } int on_headers_complete(http_parser* parser) { // HTTP headers complete return 0; } int on_body(http_parser* parser, const char* at, size_t length) { // HTTP body found return 0; } int on_message_complete(http_parser* parser) { // HTTP message complete return 0; } int main() { http_parser_settings settings; http_parser parser; char* response = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World!"; size_t response_len = strlen(response); http_parser_settings_init(&settings); settings.on_message_begin = on_message_begin; settings.on_status = on_status; settings.on_header_field = on_header_field; settings.on_header_value = on_header_value; settings.on_headers_complete = on_headers_complete; settings.on_body = on_body; settings.on_message_complete = on_message_complete; http_parser_init(&parser, HTTP_RESPONSE); http_parser_execute(&parser, &settings, response, response_len); return 0; } ``` 使用上述代码,将会对HTTP请求和响应进行解析,并在回调函数中打印出所找到的HTTP头信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值