使用http parser解析URL

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

用C语言编写http应用,解析URL是一个繁琐的事儿。前几天使用http_parser实现httpclient,发现里面提供了一个解析URL的方法http_parser_parse_url,用起来相当方便。

http_parser_parse_url通过分析URL字符串,把port、host、path、schema之类的信息保存在一个结构体http_parser_url中。通过看头文件和源码,发现这个结构体仅仅是记录了URL中各部分信息的起始位置、长度,没有做任何内存拷贝,效率上看还是不错的。目前支持SCHEMA、PORT、HOST、PATH、QUERY、USERINFO、FRAGMENT七种信息的提取。

http_parser_url定义如下:

struct http_parser_url {  uint16_t field_set;           /* Bitmask of (1 << UF_*) values */  uint16_t port;                /* Converted UF_PORT string */  struct {    uint16_t off;               /* Offset into buffer in which field starts */    uint16_t len;               /* Length of run in buffer */  } field_data[UF_MAX];};

其中,field_set成员用于检测解析到了哪种信息(使用位与操作),field_data存放相应的URL信息在原始URL中的起始位置和长度。

http_parser_parse_url()方法的原型:

int http_parser_parse_url(const char *buf, size_t buflen,                          int is_connect,                          struct http_parser_url *u);

需要说明的是is_connect参数,当传1时,http_parser_parse_url方法将进行严格检验,如果URL中没有port、schema将导致http_parser_parse_url方法失败,返回非0值。一般给is_connect方法传0即可。

下面是我使用的一段代码:

static int parse_url(struct http_client * httpc, const char *url){    struct http_parser_url u;    if(0 == http_parser_parse_url(url, strlen(url), 0, &u))    {        if(u.field_set & (1 << UF_PORT))        {            httpc->port = u.port;        }        else        {            httpc->port = 80;        }                if(httpc->host) free(httpc->host);        if(u.field_set & (1 << UF_HOST) )        {            httpc->host = (char*)malloc(u.field_data[UF_HOST].len+1);            strncpy(httpc->host, url+u.field_data[UF_HOST].off, u.field_data[UF_HOST].len);            httpc->host[u.field_data[UF_HOST].len] = 0;        }        if(httpc->path) free(httpc->path);        if(u.field_set & (1 << UF_PATH))        {            httpc->path = (char*)malloc(u.field_data[UF_PATH].len+1);            strncpy(httpc->path, url+u.field_data[UF_PATH].off, u.field_data[UF_PATH].len);            httpc->path[u.field_data[UF_PATH].len] = 0;        }        return 0;    }    return -1;}

上面的代码是我实现的http_client中的一部分,仅供参考。


           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow
这里写图片描述
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、付费专栏及课程。

余额充值