Browse Source

Upgrade http-parser for clang compat

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
e59b3f0eb3
  1. 14
      deps/http_parser/Makefile
  2. 2
      deps/http_parser/README.md
  3. 123
      deps/http_parser/http_parser.c
  4. 4
      deps/http_parser/test.c

14
deps/http_parser/Makefile

@ -1,30 +1,32 @@
OPT_DEBUG=-O0 -g -Wall -Wextra -Werror -I. OPT_DEBUG=-O0 -g -Wall -Wextra -Werror -I.
OPT_FAST=-O3 -DHTTP_PARSER_STRICT=0 -I. OPT_FAST=-O3 -DHTTP_PARSER_STRICT=0 -I.
CC?=gcc
test: test_g test: test_g
./test_g ./test_g
test_g: http_parser_g.o test_g.o test_g: http_parser_g.o test_g.o
gcc $(OPT_DEBUG) http_parser_g.o test_g.o -o $@ $(CC) $(OPT_DEBUG) http_parser_g.o test_g.o -o $@
test_g.o: test.c http_parser.h Makefile test_g.o: test.c http_parser.h Makefile
gcc $(OPT_DEBUG) -c test.c -o $@ $(CC) $(OPT_DEBUG) -c test.c -o $@
test.o: test.c http_parser.h Makefile test.o: test.c http_parser.h Makefile
gcc $(OPT_FAST) -c test.c -o $@ $(CC) $(OPT_FAST) -c test.c -o $@
http_parser_g.o: http_parser.c http_parser.h Makefile http_parser_g.o: http_parser.c http_parser.h Makefile
gcc $(OPT_DEBUG) -c http_parser.c -o $@ $(CC) $(OPT_DEBUG) -c http_parser.c -o $@
test-valgrind: test_g test-valgrind: test_g
valgrind ./test_g valgrind ./test_g
http_parser.o: http_parser.c http_parser.h Makefile http_parser.o: http_parser.c http_parser.h Makefile
gcc $(OPT_FAST) -c http_parser.c $(CC) $(OPT_FAST) -c http_parser.c
test_fast: http_parser.o test.c http_parser.h test_fast: http_parser.o test.c http_parser.h
gcc $(OPT_FAST) http_parser.o test.c -o $@ $(CC) $(OPT_FAST) http_parser.o test.c -o $@
test-run-timed: test_fast test-run-timed: test_fast
while(true) do time ./test_fast > /dev/null; done while(true) do time ./test_fast > /dev/null; done

2
deps/http_parser/README.md

@ -5,7 +5,7 @@ This is a parser for HTTP messages written in C. It parses both requests and
responses. The parser is designed to be used in performance HTTP responses. The parser is designed to be used in performance HTTP
applications. It does not make any syscalls nor allocations, it does not applications. It does not make any syscalls nor allocations, it does not
buffer data, it can be interrupted at anytime. Depending on your buffer data, it can be interrupted at anytime. Depending on your
architecture, it only requires between 100 and 200 bytes of data per message architecture, it only requires about 40 bytes of data per message
stream (in a web server that is per connection). stream (in a web server that is per connection).
Features: Features:

123
deps/http_parser/http_parser.c

@ -1,7 +1,4 @@
/* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org> /* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
*
* Some parts of this source file were taken from NGINX
* (src/http/ngx_http_parser.c) copyright (C) 2002-2009 Igor Sysoev.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to * of this software and associated documentation files (the "Software"), to
@ -109,18 +106,44 @@ static const char *method_strings[] =
}; };
static const char lowcase[256] = /* ' ', '_', '-' and all alpha-numeric ascii characters are accepted by acceptable_header.
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" The 'A'-'Z' are lower-cased. */
" \0\0\0\0\0\0\0\0\0\0\0\0-\0\0" "0123456789\0\0\0\0\0\0" static const unsigned char acceptable_header[256] = {
"\0abcdefghijklmnopqrstuvwxyz\0\0\0\0_" /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
"\0abcdefghijklmnopqrstuvwxyz\0\0\0\0\0" 0, 0, 0, 0, 0, 0, 0, 0,
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 0, 0, 0, 0, 0, 0, 0, 0,
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 0, 0, 0, 0, 0, 0, 0, 0,
/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
0, 0, 0, 0, 0, 0, 0, 0,
static const int unhex[] = /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
' ', 0, 0, 0, 0, 0, 0, 0,
/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
0, 0, 0, 0, 0, '-', 0, 0,
/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
'0', '1', '2', '3', '4', '5', '6', '7',
/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
'8', '9', 0, 0, 0, 0, 0, 0,
/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */
'x', 'y', 'z', 0, 0, 0, 0, '_',
/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
'x', 'y', 'z', 0, 0, 0, 0, 0 };
static const int unhex[256] =
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
@ -132,26 +155,39 @@ static const int unhex[] =
}; };
static const int normal_url_char[256] = {
static const uint32_t usual[] = { /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
0xffffdbfe, /* 1111 1111 1111 1111 1101 1011 1111 1110 */ 0, 0, 0, 0, 0, 0, 0, 0,
/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ 0, 0, 0, 0, 0, 0, 0, 0,
0x7ffffff6, /* 0111 1111 1111 1111 1111 1111 1111 0110 */ /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */
0, 0, 0, 0, 0, 0, 0, 0,
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0, 0, 0, 0, 0, 0, 0, 0,
/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
/* ~}| {zyx wvut srqp onml kjih gfed cba` */ 0, 1, 1, 0, 1, 1, 1, 1,
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
1, 1, 1, 1, 1, 1, 1, 1,
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 1, 1, 1, 1, 1, 1, 1, 1,
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 1, 1, 1, 1, 1, 1, 1, 0,
}; /* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */
1, 1, 1, 1, 1, 1, 1, 1,
#define USUAL(c) (usual[c >> 5] & (1 << (c & 0x1f))) /* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */
1, 1, 1, 1, 1, 1, 1, 1,
/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */
1, 1, 1, 1, 1, 1, 1, 1,
/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */
1, 1, 1, 1, 1, 1, 1, 1,
/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */
1, 1, 1, 1, 1, 1, 1, 1,
/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */
1, 1, 1, 1, 1, 1, 1, 1,
/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
1, 1, 1, 1, 1, 1, 1, 1,
/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
1, 1, 1, 1, 1, 1, 1, 0 };
enum state enum state
@ -692,7 +728,7 @@ size_t http_parser_execute (http_parser *parser,
case s_req_path: case s_req_path:
{ {
if (USUAL(ch)) break; if (normal_url_char[(unsigned char)ch]) break;
switch (ch) { switch (ch) {
case ' ': case ' ':
@ -728,7 +764,7 @@ size_t http_parser_execute (http_parser *parser,
case s_req_query_string_start: case s_req_query_string_start:
{ {
if (USUAL(ch)) { if (normal_url_char[(unsigned char)ch]) {
MARK(query_string); MARK(query_string);
state = s_req_query_string; state = s_req_query_string;
break; break;
@ -762,7 +798,7 @@ size_t http_parser_execute (http_parser *parser,
case s_req_query_string: case s_req_query_string:
{ {
if (USUAL(ch)) break; if (normal_url_char[(unsigned char)ch]) break;
switch (ch) { switch (ch) {
case '?': case '?':
@ -797,7 +833,7 @@ size_t http_parser_execute (http_parser *parser,
case s_req_fragment_start: case s_req_fragment_start:
{ {
if (USUAL(ch)) { if (normal_url_char[(unsigned char)ch]) {
MARK(fragment); MARK(fragment);
state = s_req_fragment; state = s_req_fragment;
break; break;
@ -832,7 +868,7 @@ size_t http_parser_execute (http_parser *parser,
case s_req_fragment: case s_req_fragment:
{ {
if (USUAL(ch)) break; if (normal_url_char[(unsigned char)ch]) break;
switch (ch) { switch (ch) {
case ' ': case ' ':
@ -1005,7 +1041,7 @@ size_t http_parser_execute (http_parser *parser,
case s_header_field: case s_header_field:
{ {
c = lowcase[(unsigned char)ch]; c = acceptable_header[(unsigned char)ch];
if (c) { if (c) {
switch (header_state) { switch (header_state) {
@ -1141,7 +1177,7 @@ size_t http_parser_execute (http_parser *parser,
state = s_header_value; state = s_header_value;
index = 0; index = 0;
c = lowcase[(unsigned char)ch]; c = acceptable_header[(unsigned char)ch];
if (!c) { if (!c) {
if (ch == CR) { if (ch == CR) {
@ -1202,7 +1238,7 @@ size_t http_parser_execute (http_parser *parser,
case s_header_value: case s_header_value:
{ {
c = lowcase[(unsigned char)ch]; c = acceptable_header[(unsigned char)ch];
if (!c) { if (!c) {
if (ch == CR) { if (ch == CR) {
@ -1548,4 +1584,5 @@ http_parser_init (http_parser *parser, enum http_parser_type t)
parser->nread = 0; parser->nread = 0;
parser->upgrade = 0; parser->upgrade = 0;
parser->flags = 0; parser->flags = 0;
parser->method = 0;
} }

4
deps/http_parser/test.c

@ -1019,7 +1019,7 @@ parser_free ()
parser = NULL; parser = NULL;
} }
inline size_t parse (const char *buf, size_t len) size_t parse (const char *buf, size_t len)
{ {
size_t nparsed; size_t nparsed;
currently_parsing_eof = (len == 0); currently_parsing_eof = (len == 0);
@ -1027,7 +1027,7 @@ inline size_t parse (const char *buf, size_t len)
return nparsed; return nparsed;
} }
inline size_t parse_count_body (const char *buf, size_t len) size_t parse_count_body (const char *buf, size_t len)
{ {
size_t nparsed; size_t nparsed;
currently_parsing_eof = (len == 0); currently_parsing_eof = (len == 0);

Loading…
Cancel
Save