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];  /*每一个字段所在的位置偏离 总共七个字段*/
};


上一篇下一篇

猜你喜欢

热点阅读