头文件说明:

解析类型定义:
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"}] 

http-parser用法相关推荐

  1. 【Python】Parser 用法-通俗易懂!

    目录 1 前言 2.使用方法 2.1 实例化ArgumentParser 2.2 使用add_argument函数添加参数 2.3 add_argument() 方法定义如何解析命令行参数 2.4 使 ...

  2. python的parse用法_Python 里边的parser用法

    2011-8-23 Python 里边的parser用法 15.5. optparse - Parser for command line options http://docs.python.org ...

  3. java lobo使用_[持续更新]Cobra:Java HTML parser用法详解

    Cobra主页:http://lobobrowser.org/ Cobra API:http://lobobrowser.org/cobra-api/index.html 使用Cobra(已经安装JR ...

  4. parser.add_argument()用法

    最近开始读论文代码了,遇到一个.名字叫option的py文件,打开一看,清一色的parser.add_argument(),看得是一脸懵逼....十脸懵逼.仔细看了一遍,知道里面大概是一些网络的参数和 ...

  5. 【Python】「argparse基本用法」及「jupyter中使用 args = parser.parse_args()并传参」

    主要是对该项目dgl/examples/pytorch/metapath2vec at master · dmlc/dgl · GitHub中代码的理解. 对于metapath2vec.py文件内容: ...

  6. Python Parser的用法

    import argparse# 1. 实例化ArgumentParser parser = argparse.ArgumentParser()## 2. 使用add_argument函数添加参数 # ...

  7. parser.add_argument 参数用法 包含metavar

    https://docs.python.org/zh-cn/3/library/argparse.html

  8. python命令行参数解析OptionParser类用法实例

    python命令行参数解析OptionParser类用法实例 本文实例讲述了python命令行参数解析OptionParser类的用法,分享给大家供大家参考. 具体代码如下:     from opt ...

  9. 终端输入参数:argparse和sys.argv[]的用法

    argparse的用法 fun_test.py的代码: #!/usr/bin/env python # -*- encoding: utf-8 -*- """ @Intr ...

  10. Java 中的 XML:Java 文档模型的用法

    Java 中的 XML:Java 文档模型的用法 英文原文 内容: 代码对比 DOM JDOM dom4j Electric XML XPP 结束语 下一次... 参考资料 关于作者 对本文的评价 相 ...

最新文章

  1. Python生产环境部署(fastcgi,uwsgi)
  2. 以服务的方式提供站点基础功能支持
  3. [H5表单]一些html5表单知识及EventUtil对象完善
  4. 使用事务码DBCO实现SAP链接外部数据库以及读取例程
  5. SpringCloud系列之服务消费Ribbon和Feign区别
  6. easyexcel获取所有sheet页名称_老板让我汇总多个sheet,我不会,同事却说使用PQ仅需2步搞定...
  7. Kubernetes探索学习005--Kubernetes的Controller模型和ReplicaSet伸缩
  8. 关于runc漏洞CVE-2019-5736的修复公告
  9. 整天做办公室的我们要注意饮食啊
  10. java.lang.NumberFormatException: Infinite or NaN原因之浮点类型除数为0
  11. android 透明度_Android智能视图翻转器
  12. font-awesome在Vue项目中的使用(npm使用)
  13. 论文查重颜色分别代表什么含义?
  14. kubernetes 架构及应用场景
  15. mac系统下修改usr/bin文件夹权限问题
  16. 扰动观察法怎么写matlab,扰动观察法
  17. Android 关于所谓的 深度睡眠 的问题
  18. 在同时使用label和input标签下下label绑定click事件执行两次的问题
  19. Teardrop原始套接字编程
  20. 微信小程序:拼多多推客开发

热门文章

  1. 自学C语言(14)循环语句总结(新)
  2. 呕心沥血总结的Python自动化测试面试题
  3. 群发短信平台哪个好?推荐阿里云短信平台
  4. TP5简单实现类似京东淘宝多级商品筛选功能。
  5. java excel导入 日期_java导入excel时处理日期格式(已验证ok)
  6. 满庭芳国色 高清剪图 桃红 下
  7. 在微信开发者工具中,使用WeUI前端美化框架,微信小程序
  8. pytorch GradScale 梯度缩放算子
  9. 哪款mac写python_新款Mac Pro有几个圈圈?写几行Python数一下
  10. html5调整文字段落之间的距离,css设置p段落上下间距距离