http-parser用法

2023-05-16

头文件说明:

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

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

http-parser用法 的相关文章

随机推荐

  • git 使用命令创建新分支

    如何使用Git 命令创建一个新分支 使用场景 xff1a 本文主要详细介绍了如何使用git命令基于一个项目的master分支创建一个新的git分支 xff0c 并且推向远程仓库 xff0c 使其他开发人员能够功能使用该分支进行开发 操作步骤
  • go web gin框架实战1

    文章目录 go web gin框架实战1 参考资料2 demo3 demo运行4 demo解析 go web gin框架实战 1 参考资料 gin框架官方文档 链接 2 demo span class token keyword packa
  • Hadoop之MapReduce

    摘要 xff1a MapReduce是Hadoop的又一核心模块 xff0c 从MapReduce是什么 xff0c MapReduce能做什么以及MapReduce的工作机制三方面认识MapReduce 关键词 xff1a Hadoop
  • Linux常用命令

    摘要 xff1a 采用命令行模式操控Linux系统非常重要 本文总结Linux常用的命令 xff0c 包括命令的含义 xff0c 命令的用法以及命令的拓展 关键词 xff1a 命令行模式 Linux常用命令 给Linux系统下达命令 xff
  • Hadoop之HDFS文件操作

    摘要 xff1a Hadoop之HDFS文件操作常有两种方式 xff0c 命令行方式和JavaAPI方式 本文介绍如何利用这两种方式对HDFS文件进行操作 关键词 xff1a HDFS文件 命令行 Java API HDFS是一种分布式文件
  • R实战读书笔记四

    第三章 图形入门 本章概要 1 创建和保存图形 2 定义符号 线 颜色和坐标轴 3 文本标注 4 掌控图形维数 5 多幅图合在一起 本章所介绍内容概括如下 一图胜千字 xff0c 人们从视觉层更易获取和理解信息 图形工作 R具有非常强大的绘
  • R语言——数据分析的一把利剑

    R语言 xff0c 我把它称之为数据分析的一把利剑 为什么这么说呢 xff1f 先让我们看一下 xff0c 什么是数据分析 xff1f 所谓数据分析 xff0c 就是以商业目的为驱动 xff0c 所开展的获取数据 处理数据 分析数据 展示数
  • 【爱上Linux】第一课 Linux概述

    学习应该是快乐的事情 快乐的东西应该要分享开来 xff0c 人人都快乐 xff01 爱上Linux 第一课 Linux概述 在本课中 xff0c 和朋友们一起来思考这些问题 问题一 xff1a 谈Linux学习 xff1f 从四个方面来看
  • 链表的创建与遍历

    链表 xff0c 简而言之 xff0c 就是基于链式储存结构下的线性表 链表包括单向链表 双向链表以及循环链表 链表是一种很常用的数据结构 xff0c 其定义如下 xff1a 单向链表的定义 定义说明 xff1a 包括数据域和指针域 typ
  • Java异常机制

    Java异常 xff08 Exception xff09 又称例外 xff0c 是一种运行时错误 Java异常机制就是对于Java异常的处理方法 xff0c 使用Java异常机制能提升程序的容错性 xff0c 从而使程序更加健壮与安全 ja
  • Java序列化与反序列化

    Java序列化与反序列化是什么 xff1f 为什么需要序列化与反序列化 xff1f 如何实现Java序列化与反序列化 xff1f 本文围绕这些问题进行了探讨 1 Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程
  • Java语言中几个常用的包

    Java采用包结构来组织和管理类和接口文件 本文介绍Java语言类库中几个常用的包 xff0c 因为这几个包在软件开发与应用中经常需要用到 xff0c 其中有些包是必要的 若是离开它 xff0c 还真不能做事情了 第一个包 xff1a ja
  • 计算机网络

    Cname和A记录 CNAME和A记录 A记录 Address记录 xff0c 代表指向关系 www xx com 1 1 1 1 www yy com 2 2 2 2 CNAME cname 代表一种映射关系 www yy com www
  • AI芯片面试总结

    基础书籍有哪些 xff1f 重点章节以及概念 xff1f 计算机体系结构 量化研究方法 xff1b 计算机组成与设计 软硬件接口 xff1b deep learning 深度学习 xff1b python xff1b CMOS数字集成电路
  • Android的系统架构

    Android的系统架构采用了分层架构的思想 xff0c 如图1所示 从上层到底层共包括四层 xff0c 分别是应用程序程序层 应用框架层 系统库和Android运行时和Linux内核 图1 xff1a Android系统架构图 每层功能简
  • ensp实验一网络设备基本操作

    实验一 网络设备基本操作 一 实验目的 熟悉网络设备的基本配置 xff1b 掌握网络设备文件系统管理 xff1b 掌握设备的基本调试方法 二 实验学时及环境 1 实验学时 xff1a 2 2 操作系统 xff1a Windows 3 模拟环
  • sudo rosdep init出错 rosdepc update的解决方案

    https mp weixin qq com s VGs8oWdhHH6XsHcx21lN4Q 或者搜索 本文之后 xff0c 世上再无rosdep更新失败问题 xff01 如果有 小鱼就
  • pixhawk学习笔记---创建新的应用程序

    最近转到无人机领域的开发中 xff0c 感觉和以往搞android驱动差别比较大 xff0c 以前搞android驱动的时候网上的资料满天飞 xff0c 但是现在关于飞控相关的资料却少之又少 xff0c 一些资料都是从原理上入手 xff0c
  • 伽马贝塔函数

    在数理方程 概率论等学科经常遇到以下的含参变量的积分 xff0c 它们依次为第一类和第二类欧拉 xff08 Euler 1707 1783瑞士数学家 xff09 积分 xff0c 或依次称为贝塔 xff08 Bata xff09 函数和伽马
  • http-parser用法

    头文件说明 xff1a 解析类型定义 xff1a enum http parser type HTTP REQUEST HTTP RESPONSE HTTP BOTH 解析函数声明 xff1a void http parser init h