Http-Parser URL 的解析
2019-09-29 本文已影响0人
霡霂976447044
HttpParser是Nodejs下的一个项目,使用C语言编写。
它不需要任何第三方库就可以运行,代码文件少。
1. 编译安装
git clone https://github.com/nodejs/http-parser.git
cd http-parser
make
sudo make install
sudo ldconfig
安装好之后可以在/usr/local/lib
上找得到所编译安装的库文件。
2. URL 解析
/*
author: baloneo
file: 01-test-url.c
compile: gcc 01-test-url.c -lhttp_parser -o 01-test-url
run: ./01-test-url
*/
#include "http_parser.h"
#include <stdio.h>
#include <string.h>
void
dump_url (const char *url, const struct http_parser_url *u)
{
unsigned int i;
printf("\tfield_set: 0x%x, port: %u\n", u->field_set, u->port);
for (i = 0; i < UF_MAX; i++) {
if ((u->field_set & (1 << i)) == 0) {
printf("\tfield_data[%u]: unset\n", i);
continue;
}
printf("\tfield_data[%u]: off: %u len: %u part: \"%.*s\n\"",
i,
u->field_data[i].off,
u->field_data[i].len,
u->field_data[i].len,
url + u->field_data[i].off);
}
}
void main() {
printf("hello world\n");
char *url = "http://www.baidu.com:8000/users?username=zhangsan#bar";
struct http_parser_url u;
int err = http_parser_parse_url(url, strlen(url), 0, &u);
if(err == 0){
dump_url(url, &u);
printf("field_set=%d\n", u.field_set);
printf("port=%d\n", u.port);
}
printf("%.*s\n", 3, url+2);
printf("%.*s\n", 3, url);
}
结果:
hello world
field_set: 0x3f, port: 8000
field_data[0]: off: 0 len: 4 part: "http
" field_data[1]: off: 7 len: 16 part: "www.baiduddd.com
" field_data[2]: off: 24 len: 4 part: "8000
" field_data[3]: off: 28 len: 6 part: "/users
" field_data[4]: off: 35 len: 17 part: "username=zhangsan
" field_data[5]: off: 53 len: 3 part: "bar
" field_data[6]: unset
field_set=63
port=8000
tp:
htt
URL由一下几部分组成
URI_syntax_diagram.png
http-parser把url解析出来的放在一个http_parser_url的结构体上,这个结构体维护了常用的port和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; /* 相对于url的偏离位置 */
uint16_t len; /* 本字段的长度*/
} field_data[UF_MAX]; /*每一个字段所在的位置偏离 总共七个字段*/
};
- printf(
%.*s
) 可以输出指定长度的字符串。