diff --git a/deps/http_parser/Makefile b/deps/http_parser/Makefile index dee994ea50..2b945c16b0 100644 --- a/deps/http_parser/Makefile +++ b/deps/http_parser/Makefile @@ -1,30 +1,32 @@ OPT_DEBUG=-O0 -g -Wall -Wextra -Werror -I. OPT_FAST=-O3 -DHTTP_PARSER_STRICT=0 -I. +CC?=gcc + test: test_g ./test_g 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 - gcc $(OPT_DEBUG) -c test.c -o $@ + $(CC) $(OPT_DEBUG) -c test.c -o $@ 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 - gcc $(OPT_DEBUG) -c http_parser.c -o $@ + $(CC) $(OPT_DEBUG) -c http_parser.c -o $@ test-valgrind: test_g valgrind ./test_g 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 - gcc $(OPT_FAST) http_parser.o test.c -o $@ + $(CC) $(OPT_FAST) http_parser.o test.c -o $@ test-run-timed: test_fast while(true) do time ./test_fast > /dev/null; done diff --git a/deps/http_parser/README.md b/deps/http_parser/README.md index 79aef0efb4..2ac56f87a7 100644 --- a/deps/http_parser/README.md +++ b/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 applications. It does not make any syscalls nor allocations, it does not 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). Features: diff --git a/deps/http_parser/http_parser.c b/deps/http_parser/http_parser.c index ac1b9d6fbf..c600ff19b2 100644 --- a/deps/http_parser/http_parser.c +++ b/deps/http_parser/http_parser.c @@ -1,7 +1,4 @@ /* Copyright 2009,2010 Ryan Dahl - * - * 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 * of this software and associated documentation files (the "Software"), to @@ -109,18 +106,44 @@ static const char *method_strings[] = }; -static const char lowcase[256] = - "\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" "0123456789\0\0\0\0\0\0" - "\0abcdefghijklmnopqrstuvwxyz\0\0\0\0_" - "\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\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\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; - - -static const int unhex[] = +/* ' ', '_', '-' and all alpha-numeric ascii characters are accepted by acceptable_header. + The 'A'-'Z' are lower-cased. */ +static const unsigned char acceptable_header[256] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 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, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 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, +/* 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 @@ -132,26 +155,39 @@ static const int unhex[] = }; - -static const uint32_t usual[] = { - 0xffffdbfe, /* 1111 1111 1111 1111 1101 1011 1111 1110 */ - - /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ - 0x7ffffff6, /* 0111 1111 1111 1111 1111 1111 1111 0110 */ - - /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ - 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ - - /* ~}| {zyx wvut srqp onml kjih gfed cba` */ - 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ - - 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ - 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ - 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ - 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ -}; - -#define USUAL(c) (usual[c >> 5] & (1 << (c & 0x1f))) +static const int normal_url_char[256] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 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, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 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, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0, 1, 1, 0, 1, 1, 1, 1, +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 1, 1, 1, 1, 1, 1, 1, 1, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + 1, 1, 1, 1, 1, 1, 1, 1, +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + 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, +/* 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 @@ -692,7 +728,7 @@ size_t http_parser_execute (http_parser *parser, case s_req_path: { - if (USUAL(ch)) break; + if (normal_url_char[(unsigned char)ch]) break; switch (ch) { case ' ': @@ -728,7 +764,7 @@ size_t http_parser_execute (http_parser *parser, case s_req_query_string_start: { - if (USUAL(ch)) { + if (normal_url_char[(unsigned char)ch]) { MARK(query_string); state = s_req_query_string; break; @@ -762,7 +798,7 @@ size_t http_parser_execute (http_parser *parser, case s_req_query_string: { - if (USUAL(ch)) break; + if (normal_url_char[(unsigned char)ch]) break; switch (ch) { case '?': @@ -797,7 +833,7 @@ size_t http_parser_execute (http_parser *parser, case s_req_fragment_start: { - if (USUAL(ch)) { + if (normal_url_char[(unsigned char)ch]) { MARK(fragment); state = s_req_fragment; break; @@ -832,7 +868,7 @@ size_t http_parser_execute (http_parser *parser, case s_req_fragment: { - if (USUAL(ch)) break; + if (normal_url_char[(unsigned char)ch]) break; switch (ch) { case ' ': @@ -1005,7 +1041,7 @@ size_t http_parser_execute (http_parser *parser, case s_header_field: { - c = lowcase[(unsigned char)ch]; + c = acceptable_header[(unsigned char)ch]; if (c) { switch (header_state) { @@ -1141,7 +1177,7 @@ size_t http_parser_execute (http_parser *parser, state = s_header_value; index = 0; - c = lowcase[(unsigned char)ch]; + c = acceptable_header[(unsigned char)ch]; if (!c) { if (ch == CR) { @@ -1202,7 +1238,7 @@ size_t http_parser_execute (http_parser *parser, case s_header_value: { - c = lowcase[(unsigned char)ch]; + c = acceptable_header[(unsigned char)ch]; if (!c) { if (ch == CR) { @@ -1548,4 +1584,5 @@ http_parser_init (http_parser *parser, enum http_parser_type t) parser->nread = 0; parser->upgrade = 0; parser->flags = 0; + parser->method = 0; } diff --git a/deps/http_parser/test.c b/deps/http_parser/test.c index 6971217296..af9f3bb431 100644 --- a/deps/http_parser/test.c +++ b/deps/http_parser/test.c @@ -1019,7 +1019,7 @@ parser_free () parser = NULL; } -inline size_t parse (const char *buf, size_t len) +size_t parse (const char *buf, size_t len) { size_t nparsed; currently_parsing_eof = (len == 0); @@ -1027,7 +1027,7 @@ inline size_t parse (const char *buf, size_t len) 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; currently_parsing_eof = (len == 0);