deps: upgrade to npm 2.14.18
[platform/upstream/nodejs.git] / deps / http_parser / http_parser.c
1 /* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev
2  *
3  * Additional changes are licensed under the same terms as NGINX and
4  * copyright Joyent, Inc. and other Node contributors. All rights reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 #include "http_parser.h"
25 #include <assert.h>
26 #include <stddef.h>
27 #include <ctype.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <limits.h>
31
32 #ifndef ULLONG_MAX
33 # define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */
34 #endif
35
36 #ifndef MIN
37 # define MIN(a,b) ((a) < (b) ? (a) : (b))
38 #endif
39
40 #ifndef ARRAY_SIZE
41 # define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
42 #endif
43
44 #ifndef BIT_AT
45 # define BIT_AT(a, i)                                                \
46   (!!((unsigned int) (a)[(unsigned int) (i) >> 3] &                  \
47    (1 << ((unsigned int) (i) & 7))))
48 #endif
49
50 #ifndef ELEM_AT
51 # define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v))
52 #endif
53
54 #define SET_ERRNO(e)                                                 \
55 do {                                                                 \
56   parser->http_errno = (e);                                          \
57 } while(0)
58
59 #define CURRENT_STATE() p_state
60 #define UPDATE_STATE(V) p_state = (enum state) (V);
61 #define RETURN(V)                                                    \
62 do {                                                                 \
63   parser->state = CURRENT_STATE();                                   \
64   return (V);                                                        \
65 } while (0);
66 #define REEXECUTE()                                                  \
67   goto reexecute;                                                    \
68
69
70 #ifdef __GNUC__
71 # define LIKELY(X) __builtin_expect(!!(X), 1)
72 # define UNLIKELY(X) __builtin_expect(!!(X), 0)
73 #else
74 # define LIKELY(X) (X)
75 # define UNLIKELY(X) (X)
76 #endif
77
78
79 /* Run the notify callback FOR, returning ER if it fails */
80 #define CALLBACK_NOTIFY_(FOR, ER)                                    \
81 do {                                                                 \
82   assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \
83                                                                      \
84   if (LIKELY(settings->on_##FOR)) {                                  \
85     parser->state = CURRENT_STATE();                                 \
86     if (UNLIKELY(0 != settings->on_##FOR(parser))) {                 \
87       SET_ERRNO(HPE_CB_##FOR);                                       \
88     }                                                                \
89     UPDATE_STATE(parser->state);                                     \
90                                                                      \
91     /* We either errored above or got paused; get out */             \
92     if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) {             \
93       return (ER);                                                   \
94     }                                                                \
95   }                                                                  \
96 } while (0)
97
98 /* Run the notify callback FOR and consume the current byte */
99 #define CALLBACK_NOTIFY(FOR)            CALLBACK_NOTIFY_(FOR, p - data + 1)
100
101 /* Run the notify callback FOR and don't consume the current byte */
102 #define CALLBACK_NOTIFY_NOADVANCE(FOR)  CALLBACK_NOTIFY_(FOR, p - data)
103
104 /* Run data callback FOR with LEN bytes, returning ER if it fails */
105 #define CALLBACK_DATA_(FOR, LEN, ER)                                 \
106 do {                                                                 \
107   assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \
108                                                                      \
109   if (FOR##_mark) {                                                  \
110     if (LIKELY(settings->on_##FOR)) {                                \
111       parser->state = CURRENT_STATE();                               \
112       if (UNLIKELY(0 !=                                              \
113                    settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \
114         SET_ERRNO(HPE_CB_##FOR);                                     \
115       }                                                              \
116       UPDATE_STATE(parser->state);                                   \
117                                                                      \
118       /* We either errored above or got paused; get out */           \
119       if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) {           \
120         return (ER);                                                 \
121       }                                                              \
122     }                                                                \
123     FOR##_mark = NULL;                                               \
124   }                                                                  \
125 } while (0)
126   
127 /* Run the data callback FOR and consume the current byte */
128 #define CALLBACK_DATA(FOR)                                           \
129     CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)
130
131 /* Run the data callback FOR and don't consume the current byte */
132 #define CALLBACK_DATA_NOADVANCE(FOR)                                 \
133     CALLBACK_DATA_(FOR, p - FOR##_mark, p - data)
134
135 /* Set the mark FOR; non-destructive if mark is already set */
136 #define MARK(FOR)                                                    \
137 do {                                                                 \
138   if (!FOR##_mark) {                                                 \
139     FOR##_mark = p;                                                  \
140   }                                                                  \
141 } while (0)
142
143 /* Don't allow the total size of the HTTP headers (including the status
144  * line) to exceed HTTP_MAX_HEADER_SIZE.  This check is here to protect
145  * embedders against denial-of-service attacks where the attacker feeds
146  * us a never-ending header that the embedder keeps buffering.
147  *
148  * This check is arguably the responsibility of embedders but we're doing
149  * it on the embedder's behalf because most won't bother and this way we
150  * make the web a little safer.  HTTP_MAX_HEADER_SIZE is still far bigger
151  * than any reasonable request or response so this should never affect
152  * day-to-day operation.
153  */
154 #define COUNT_HEADER_SIZE(V)                                         \
155 do {                                                                 \
156   parser->nread += (V);                                              \
157   if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) {            \
158     SET_ERRNO(HPE_HEADER_OVERFLOW);                                  \
159     goto error;                                                      \
160   }                                                                  \
161 } while (0)
162
163
164 #define PROXY_CONNECTION "proxy-connection"
165 #define CONNECTION "connection"
166 #define CONTENT_LENGTH "content-length"
167 #define TRANSFER_ENCODING "transfer-encoding"
168 #define UPGRADE "upgrade"
169 #define CHUNKED "chunked"
170 #define KEEP_ALIVE "keep-alive"
171 #define CLOSE "close"
172
173
174 static const char *method_strings[] =
175   {
176 #define XX(num, name, string) #string,
177   HTTP_METHOD_MAP(XX)
178 #undef XX
179   };
180
181
182 /* Tokens as defined by rfc 2616. Also lowercases them.
183  *        token       = 1*<any CHAR except CTLs or separators>
184  *     separators     = "(" | ")" | "<" | ">" | "@"
185  *                    | "," | ";" | ":" | "\" | <">
186  *                    | "/" | "[" | "]" | "?" | "="
187  *                    | "{" | "}" | SP | HT
188  */
189 static const char tokens[256] = {
190 /*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */
191         0,       0,       0,       0,       0,       0,       0,       0,
192 /*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */
193         0,       0,       0,       0,       0,       0,       0,       0,
194 /*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */
195         0,       0,       0,       0,       0,       0,       0,       0,
196 /*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */
197         0,       0,       0,       0,       0,       0,       0,       0,
198 /*  32 sp    33  !    34  "    35  #    36  $    37  %    38  &    39  '  */
199         0,      '!',      0,      '#',     '$',     '%',     '&',    '\'',
200 /*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */
201         0,       0,      '*',     '+',      0,      '-',     '.',      0,
202 /*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */
203        '0',     '1',     '2',     '3',     '4',     '5',     '6',     '7',
204 /*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */
205        '8',     '9',      0,       0,       0,       0,       0,       0,
206 /*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */
207         0,      'a',     'b',     'c',     'd',     'e',     'f',     'g',
208 /*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */
209        'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',
210 /*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */
211        'p',     'q',     'r',     's',     't',     'u',     'v',     'w',
212 /*  88  X    89  Y    90  Z    91  [    92  \    93  ]    94  ^    95  _  */
213        'x',     'y',     'z',      0,       0,       0,      '^',     '_',
214 /*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */
215        '`',     'a',     'b',     'c',     'd',     'e',     'f',     'g',
216 /* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */
217        'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',
218 /* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */
219        'p',     'q',     'r',     's',     't',     'u',     'v',     'w',
220 /* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */
221        'x',     'y',     'z',      0,      '|',      0,      '~',       0 };
222
223
224 static const int8_t unhex[256] =
225   {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
226   ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
227   ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
228   , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
229   ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
230   ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
231   ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
232   ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
233   };
234
235
236 #if HTTP_PARSER_STRICT
237 # define T(v) 0
238 #else
239 # define T(v) v
240 #endif
241
242
243 static const uint8_t normal_url_char[32] = {
244 /*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */
245         0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
246 /*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */
247         0    | T(2)   |   0    |   0    | T(16)  |   0    |   0    |   0,
248 /*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */
249         0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
250 /*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */
251         0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
252 /*  32 sp    33  !    34  "    35  #    36  $    37  %    38  &    39  '  */
253         0    |   2    |   4    |   0    |   16   |   32   |   64   |  128,
254 /*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */
255         1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
256 /*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */
257         1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
258 /*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */
259         1    |   2    |   4    |   8    |   16   |   32   |   64   |   0,
260 /*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */
261         1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
262 /*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */
263         1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
264 /*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */
265         1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
266 /*  88  X    89  Y    90  Z    91  [    92  \    93  ]    94  ^    95  _  */
267         1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
268 /*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */
269         1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
270 /* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */
271         1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
272 /* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */
273         1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
274 /* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */
275         1    |   2    |   4    |   8    |   16   |   32   |   64   |   0, };
276
277 #undef T
278
279 enum state
280   { s_dead = 1 /* important that this is > 0 */
281
282   , s_start_req_or_res
283   , s_res_or_resp_H
284   , s_start_res
285   , s_res_H
286   , s_res_HT
287   , s_res_HTT
288   , s_res_HTTP
289   , s_res_first_http_major
290   , s_res_http_major
291   , s_res_first_http_minor
292   , s_res_http_minor
293   , s_res_first_status_code
294   , s_res_status_code
295   , s_res_status_start
296   , s_res_status
297   , s_res_line_almost_done
298
299   , s_start_req
300
301   , s_req_method
302   , s_req_spaces_before_url
303   , s_req_schema
304   , s_req_schema_slash
305   , s_req_schema_slash_slash
306   , s_req_server_start
307   , s_req_server
308   , s_req_server_with_at
309   , s_req_path
310   , s_req_query_string_start
311   , s_req_query_string
312   , s_req_fragment_start
313   , s_req_fragment
314   , s_req_http_start
315   , s_req_http_H
316   , s_req_http_HT
317   , s_req_http_HTT
318   , s_req_http_HTTP
319   , s_req_first_http_major
320   , s_req_http_major
321   , s_req_first_http_minor
322   , s_req_http_minor
323   , s_req_line_almost_done
324
325   , s_header_field_start
326   , s_header_field
327   , s_header_value_discard_ws
328   , s_header_value_discard_ws_almost_done
329   , s_header_value_discard_lws
330   , s_header_value_start
331   , s_header_value
332   , s_header_value_lws
333
334   , s_header_almost_done
335
336   , s_chunk_size_start
337   , s_chunk_size
338   , s_chunk_parameters
339   , s_chunk_size_almost_done
340
341   , s_headers_almost_done
342   , s_headers_done
343
344   /* Important: 's_headers_done' must be the last 'header' state. All
345    * states beyond this must be 'body' states. It is used for overflow
346    * checking. See the PARSING_HEADER() macro.
347    */
348
349   , s_chunk_data
350   , s_chunk_data_almost_done
351   , s_chunk_data_done
352
353   , s_body_identity
354   , s_body_identity_eof
355
356   , s_message_done
357   };
358
359
360 #define PARSING_HEADER(state) (state <= s_headers_done)
361
362
363 enum header_states
364   { h_general = 0
365   , h_C
366   , h_CO
367   , h_CON
368
369   , h_matching_connection
370   , h_matching_proxy_connection
371   , h_matching_content_length
372   , h_matching_transfer_encoding
373   , h_matching_upgrade
374
375   , h_connection
376   , h_content_length
377   , h_transfer_encoding
378   , h_upgrade
379
380   , h_matching_transfer_encoding_chunked
381   , h_matching_connection_token_start
382   , h_matching_connection_keep_alive
383   , h_matching_connection_close
384   , h_matching_connection_upgrade
385   , h_matching_connection_token
386
387   , h_transfer_encoding_chunked
388   , h_connection_keep_alive
389   , h_connection_close
390   , h_connection_upgrade
391   };
392
393 enum http_host_state
394   {
395     s_http_host_dead = 1
396   , s_http_userinfo_start
397   , s_http_userinfo
398   , s_http_host_start
399   , s_http_host_v6_start
400   , s_http_host
401   , s_http_host_v6
402   , s_http_host_v6_end
403   , s_http_host_port_start
404   , s_http_host_port
405 };
406
407 /* Macros for character classes; depends on strict-mode  */
408 #define CR                  '\r'
409 #define LF                  '\n'
410 #define LOWER(c)            (unsigned char)(c | 0x20)
411 #define IS_ALPHA(c)         (LOWER(c) >= 'a' && LOWER(c) <= 'z')
412 #define IS_NUM(c)           ((c) >= '0' && (c) <= '9')
413 #define IS_ALPHANUM(c)      (IS_ALPHA(c) || IS_NUM(c))
414 #define IS_HEX(c)           (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f'))
415 #define IS_MARK(c)          ((c) == '-' || (c) == '_' || (c) == '.' || \
416   (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \
417   (c) == ')')
418 #define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \
419   (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \
420   (c) == '$' || (c) == ',')
421
422 #define STRICT_TOKEN(c)     (tokens[(unsigned char)c])
423
424 #if HTTP_PARSER_STRICT
425 #define TOKEN(c)            (tokens[(unsigned char)c])
426 #define IS_URL_CHAR(c)      (BIT_AT(normal_url_char, (unsigned char)c))
427 #define IS_HOST_CHAR(c)     (IS_ALPHANUM(c) || (c) == '.' || (c) == '-')
428 #else
429 #define TOKEN(c)            ((c == ' ') ? ' ' : tokens[(unsigned char)c])
430 #define IS_URL_CHAR(c)                                                         \
431   (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80))
432 #define IS_HOST_CHAR(c)                                                        \
433   (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_')
434 #endif
435
436 /**
437  * Verify that a char is a valid visible (printable) US-ASCII
438  * character or %x80-FF
439  **/
440 #define IS_HEADER_CHAR(ch)                                                     \
441   (ch == CR || ch == LF || ch == 9 || ((unsigned char)ch > 31 && ch != 127))
442
443 #define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res)
444
445
446 #if HTTP_PARSER_STRICT
447 # define STRICT_CHECK(cond)                                          \
448 do {                                                                 \
449   if (cond) {                                                        \
450     SET_ERRNO(HPE_STRICT);                                           \
451     goto error;                                                      \
452   }                                                                  \
453 } while (0)
454 # define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead)
455 #else
456 # define STRICT_CHECK(cond)
457 # define NEW_MESSAGE() start_state
458 #endif
459
460
461 /* Map errno values to strings for human-readable output */
462 #define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s },
463 static struct {
464   const char *name;
465   const char *description;
466 } http_strerror_tab[] = {
467   HTTP_ERRNO_MAP(HTTP_STRERROR_GEN)
468 };
469 #undef HTTP_STRERROR_GEN
470
471 int http_message_needs_eof(const http_parser *parser);
472
473 /* Our URL parser.
474  *
475  * This is designed to be shared by http_parser_execute() for URL validation,
476  * hence it has a state transition + byte-for-byte interface. In addition, it
477  * is meant to be embedded in http_parser_parse_url(), which does the dirty
478  * work of turning state transitions URL components for its API.
479  *
480  * This function should only be invoked with non-space characters. It is
481  * assumed that the caller cares about (and can detect) the transition between
482  * URL and non-URL states by looking for these.
483  */
484 static enum state
485 parse_url_char(enum state s, const char ch)
486 {
487   if (ch == ' ' || ch == '\r' || ch == '\n') {
488     return s_dead;
489   }
490
491 #if HTTP_PARSER_STRICT
492   if (ch == '\t' || ch == '\f') {
493     return s_dead;
494   }
495 #endif
496
497   switch (s) {
498     case s_req_spaces_before_url:
499       /* Proxied requests are followed by scheme of an absolute URI (alpha).
500        * All methods except CONNECT are followed by '/' or '*'.
501        */
502
503       if (ch == '/' || ch == '*') {
504         return s_req_path;
505       }
506
507       if (IS_ALPHA(ch)) {
508         return s_req_schema;
509       }
510
511       break;
512
513     case s_req_schema:
514       if (IS_ALPHA(ch)) {
515         return s;
516       }
517
518       if (ch == ':') {
519         return s_req_schema_slash;
520       }
521
522       break;
523
524     case s_req_schema_slash:
525       if (ch == '/') {
526         return s_req_schema_slash_slash;
527       }
528
529       break;
530
531     case s_req_schema_slash_slash:
532       if (ch == '/') {
533         return s_req_server_start;
534       }
535
536       break;
537
538     case s_req_server_with_at:
539       if (ch == '@') {
540         return s_dead;
541       }
542
543     /* FALLTHROUGH */
544     case s_req_server_start:
545     case s_req_server:
546       if (ch == '/') {
547         return s_req_path;
548       }
549
550       if (ch == '?') {
551         return s_req_query_string_start;
552       }
553
554       if (ch == '@') {
555         return s_req_server_with_at;
556       }
557
558       if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') {
559         return s_req_server;
560       }
561
562       break;
563
564     case s_req_path:
565       if (IS_URL_CHAR(ch)) {
566         return s;
567       }
568
569       switch (ch) {
570         case '?':
571           return s_req_query_string_start;
572
573         case '#':
574           return s_req_fragment_start;
575       }
576
577       break;
578
579     case s_req_query_string_start:
580     case s_req_query_string:
581       if (IS_URL_CHAR(ch)) {
582         return s_req_query_string;
583       }
584
585       switch (ch) {
586         case '?':
587           /* allow extra '?' in query string */
588           return s_req_query_string;
589
590         case '#':
591           return s_req_fragment_start;
592       }
593
594       break;
595
596     case s_req_fragment_start:
597       if (IS_URL_CHAR(ch)) {
598         return s_req_fragment;
599       }
600
601       switch (ch) {
602         case '?':
603           return s_req_fragment;
604
605         case '#':
606           return s;
607       }
608
609       break;
610
611     case s_req_fragment:
612       if (IS_URL_CHAR(ch)) {
613         return s;
614       }
615
616       switch (ch) {
617         case '?':
618         case '#':
619           return s;
620       }
621
622       break;
623
624     default:
625       break;
626   }
627
628   /* We should never fall out of the switch above unless there's an error */
629   return s_dead;
630 }
631
632 size_t http_parser_execute (http_parser *parser,
633                             const http_parser_settings *settings,
634                             const char *data,
635                             size_t len)
636 {
637   char c, ch;
638   int8_t unhex_val;
639   const char *p = data;
640   const char *header_field_mark = 0;
641   const char *header_value_mark = 0;
642   const char *url_mark = 0;
643   const char *body_mark = 0;
644   const char *status_mark = 0;
645   enum state p_state = (enum state) parser->state;
646
647   const unsigned int lenient = parser->lenient_http_headers;
648
649   /* We're in an error state. Don't bother doing anything. */
650   if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
651     return 0;
652   }
653
654   if (len == 0) {
655     switch (CURRENT_STATE()) {
656       case s_body_identity_eof:
657         /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if
658          * we got paused.
659          */
660         CALLBACK_NOTIFY_NOADVANCE(message_complete);
661         return 0;
662
663       case s_dead:
664       case s_start_req_or_res:
665       case s_start_res:
666       case s_start_req:
667         return 0;
668
669       default:
670         SET_ERRNO(HPE_INVALID_EOF_STATE);
671         return 1;
672     }
673   }
674
675
676   if (CURRENT_STATE() == s_header_field)
677     header_field_mark = data;
678   if (CURRENT_STATE() == s_header_value)
679     header_value_mark = data;
680   switch (CURRENT_STATE()) {
681   case s_req_path:
682   case s_req_schema:
683   case s_req_schema_slash:
684   case s_req_schema_slash_slash:
685   case s_req_server_start:
686   case s_req_server:
687   case s_req_server_with_at:
688   case s_req_query_string_start:
689   case s_req_query_string:
690   case s_req_fragment_start:
691   case s_req_fragment:
692     url_mark = data;
693     break;
694   case s_res_status:
695     status_mark = data;
696     break;
697   default:
698     break;
699   }
700
701   for (p=data; p != data + len; p++) {
702     ch = *p;
703
704     if (PARSING_HEADER(CURRENT_STATE()))
705       COUNT_HEADER_SIZE(1);
706
707 reexecute:
708     switch (CURRENT_STATE()) {
709
710       case s_dead:
711         /* this state is used after a 'Connection: close' message
712          * the parser will error out if it reads another message
713          */
714         if (LIKELY(ch == CR || ch == LF))
715           break;
716
717         SET_ERRNO(HPE_CLOSED_CONNECTION);
718         goto error;
719
720       case s_start_req_or_res:
721       {
722         if (ch == CR || ch == LF)
723           break;
724         parser->flags = 0;
725         parser->content_length = ULLONG_MAX;
726
727         if (ch == 'H') {
728           UPDATE_STATE(s_res_or_resp_H);
729
730           CALLBACK_NOTIFY(message_begin);
731         } else {
732           parser->type = HTTP_REQUEST;
733           UPDATE_STATE(s_start_req);
734           REEXECUTE();
735         }
736
737         break;
738       }
739
740       case s_res_or_resp_H:
741         if (ch == 'T') {
742           parser->type = HTTP_RESPONSE;
743           UPDATE_STATE(s_res_HT);
744         } else {
745           if (UNLIKELY(ch != 'E')) {
746             SET_ERRNO(HPE_INVALID_CONSTANT);
747             goto error;
748           }
749
750           parser->type = HTTP_REQUEST;
751           parser->method = HTTP_HEAD;
752           parser->index = 2;
753           UPDATE_STATE(s_req_method);
754         }
755         break;
756
757       case s_start_res:
758       {
759         parser->flags = 0;
760         parser->content_length = ULLONG_MAX;
761
762         switch (ch) {
763           case 'H':
764             UPDATE_STATE(s_res_H);
765             break;
766
767           case CR:
768           case LF:
769             break;
770
771           default:
772             SET_ERRNO(HPE_INVALID_CONSTANT);
773             goto error;
774         }
775
776         CALLBACK_NOTIFY(message_begin);
777         break;
778       }
779
780       case s_res_H:
781         STRICT_CHECK(ch != 'T');
782         UPDATE_STATE(s_res_HT);
783         break;
784
785       case s_res_HT:
786         STRICT_CHECK(ch != 'T');
787         UPDATE_STATE(s_res_HTT);
788         break;
789
790       case s_res_HTT:
791         STRICT_CHECK(ch != 'P');
792         UPDATE_STATE(s_res_HTTP);
793         break;
794
795       case s_res_HTTP:
796         STRICT_CHECK(ch != '/');
797         UPDATE_STATE(s_res_first_http_major);
798         break;
799
800       case s_res_first_http_major:
801         if (UNLIKELY(ch < '0' || ch > '9')) {
802           SET_ERRNO(HPE_INVALID_VERSION);
803           goto error;
804         }
805
806         parser->http_major = ch - '0';
807         UPDATE_STATE(s_res_http_major);
808         break;
809
810       /* major HTTP version or dot */
811       case s_res_http_major:
812       {
813         if (ch == '.') {
814           UPDATE_STATE(s_res_first_http_minor);
815           break;
816         }
817
818         if (!IS_NUM(ch)) {
819           SET_ERRNO(HPE_INVALID_VERSION);
820           goto error;
821         }
822
823         parser->http_major *= 10;
824         parser->http_major += ch - '0';
825
826         if (UNLIKELY(parser->http_major > 999)) {
827           SET_ERRNO(HPE_INVALID_VERSION);
828           goto error;
829         }
830
831         break;
832       }
833
834       /* first digit of minor HTTP version */
835       case s_res_first_http_minor:
836         if (UNLIKELY(!IS_NUM(ch))) {
837           SET_ERRNO(HPE_INVALID_VERSION);
838           goto error;
839         }
840
841         parser->http_minor = ch - '0';
842         UPDATE_STATE(s_res_http_minor);
843         break;
844
845       /* minor HTTP version or end of request line */
846       case s_res_http_minor:
847       {
848         if (ch == ' ') {
849           UPDATE_STATE(s_res_first_status_code);
850           break;
851         }
852
853         if (UNLIKELY(!IS_NUM(ch))) {
854           SET_ERRNO(HPE_INVALID_VERSION);
855           goto error;
856         }
857
858         parser->http_minor *= 10;
859         parser->http_minor += ch - '0';
860
861         if (UNLIKELY(parser->http_minor > 999)) {
862           SET_ERRNO(HPE_INVALID_VERSION);
863           goto error;
864         }
865
866         break;
867       }
868
869       case s_res_first_status_code:
870       {
871         if (!IS_NUM(ch)) {
872           if (ch == ' ') {
873             break;
874           }
875
876           SET_ERRNO(HPE_INVALID_STATUS);
877           goto error;
878         }
879         parser->status_code = ch - '0';
880         UPDATE_STATE(s_res_status_code);
881         break;
882       }
883
884       case s_res_status_code:
885       {
886         if (!IS_NUM(ch)) {
887           switch (ch) {
888             case ' ':
889               UPDATE_STATE(s_res_status_start);
890               break;
891             case CR:
892               UPDATE_STATE(s_res_line_almost_done);
893               break;
894             case LF:
895               UPDATE_STATE(s_header_field_start);
896               break;
897             default:
898               SET_ERRNO(HPE_INVALID_STATUS);
899               goto error;
900           }
901           break;
902         }
903
904         parser->status_code *= 10;
905         parser->status_code += ch - '0';
906
907         if (UNLIKELY(parser->status_code > 999)) {
908           SET_ERRNO(HPE_INVALID_STATUS);
909           goto error;
910         }
911
912         break;
913       }
914
915       case s_res_status_start:
916       {
917         if (ch == CR) {
918           UPDATE_STATE(s_res_line_almost_done);
919           break;
920         }
921
922         if (ch == LF) {
923           UPDATE_STATE(s_header_field_start);
924           break;
925         }
926
927         MARK(status);
928         UPDATE_STATE(s_res_status);
929         parser->index = 0;
930         break;
931       }
932
933       case s_res_status:
934         if (ch == CR) {
935           UPDATE_STATE(s_res_line_almost_done);
936           CALLBACK_DATA(status);
937           break;
938         }
939
940         if (ch == LF) {
941           UPDATE_STATE(s_header_field_start);
942           CALLBACK_DATA(status);
943           break;
944         }
945
946         break;
947
948       case s_res_line_almost_done:
949         STRICT_CHECK(ch != LF);
950         UPDATE_STATE(s_header_field_start);
951         break;
952
953       case s_start_req:
954       {
955         if (ch == CR || ch == LF)
956           break;
957         parser->flags = 0;
958         parser->content_length = ULLONG_MAX;
959
960         if (UNLIKELY(!IS_ALPHA(ch))) {
961           SET_ERRNO(HPE_INVALID_METHOD);
962           goto error;
963         }
964
965         parser->method = (enum http_method) 0;
966         parser->index = 1;
967         switch (ch) {
968           case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break;
969           case 'D': parser->method = HTTP_DELETE; break;
970           case 'G': parser->method = HTTP_GET; break;
971           case 'H': parser->method = HTTP_HEAD; break;
972           case 'L': parser->method = HTTP_LOCK; break;
973           case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break;
974           case 'N': parser->method = HTTP_NOTIFY; break;
975           case 'O': parser->method = HTTP_OPTIONS; break;
976           case 'P': parser->method = HTTP_POST;
977             /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */
978             break;
979           case 'R': parser->method = HTTP_REPORT; break;
980           case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break;
981           case 'T': parser->method = HTTP_TRACE; break;
982           case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break;
983           default:
984             SET_ERRNO(HPE_INVALID_METHOD);
985             goto error;
986         }
987         UPDATE_STATE(s_req_method);
988
989         CALLBACK_NOTIFY(message_begin);
990
991         break;
992       }
993
994       case s_req_method:
995       {
996         const char *matcher;
997         if (UNLIKELY(ch == '\0')) {
998           SET_ERRNO(HPE_INVALID_METHOD);
999           goto error;
1000         }
1001
1002         matcher = method_strings[parser->method];
1003         if (ch == ' ' && matcher[parser->index] == '\0') {
1004           UPDATE_STATE(s_req_spaces_before_url);
1005         } else if (ch == matcher[parser->index]) {
1006           ; /* nada */
1007         } else if (parser->method == HTTP_CONNECT) {
1008           if (parser->index == 1 && ch == 'H') {
1009             parser->method = HTTP_CHECKOUT;
1010           } else if (parser->index == 2  && ch == 'P') {
1011             parser->method = HTTP_COPY;
1012           } else {
1013             SET_ERRNO(HPE_INVALID_METHOD);
1014             goto error;
1015           }
1016         } else if (parser->method == HTTP_MKCOL) {
1017           if (parser->index == 1 && ch == 'O') {
1018             parser->method = HTTP_MOVE;
1019           } else if (parser->index == 1 && ch == 'E') {
1020             parser->method = HTTP_MERGE;
1021           } else if (parser->index == 1 && ch == '-') {
1022             parser->method = HTTP_MSEARCH;
1023           } else if (parser->index == 2 && ch == 'A') {
1024             parser->method = HTTP_MKACTIVITY;
1025           } else if (parser->index == 3 && ch == 'A') {
1026             parser->method = HTTP_MKCALENDAR;
1027           } else {
1028             SET_ERRNO(HPE_INVALID_METHOD);
1029             goto error;
1030           }
1031         } else if (parser->method == HTTP_SUBSCRIBE) {
1032           if (parser->index == 1 && ch == 'E') {
1033             parser->method = HTTP_SEARCH;
1034           } else {
1035             SET_ERRNO(HPE_INVALID_METHOD);
1036             goto error;
1037           }
1038         } else if (parser->index == 1 && parser->method == HTTP_POST) {
1039           if (ch == 'R') {
1040             parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
1041           } else if (ch == 'U') {
1042             parser->method = HTTP_PUT; /* or HTTP_PURGE */
1043           } else if (ch == 'A') {
1044             parser->method = HTTP_PATCH;
1045           } else {
1046             SET_ERRNO(HPE_INVALID_METHOD);
1047             goto error;
1048           }
1049         } else if (parser->index == 2) {
1050           if (parser->method == HTTP_PUT) {
1051             if (ch == 'R') {
1052               parser->method = HTTP_PURGE;
1053             } else {
1054               SET_ERRNO(HPE_INVALID_METHOD);
1055               goto error;
1056             }
1057           } else if (parser->method == HTTP_UNLOCK) {
1058             if (ch == 'S') {
1059               parser->method = HTTP_UNSUBSCRIBE;
1060             } else {
1061               SET_ERRNO(HPE_INVALID_METHOD);
1062               goto error;
1063             }
1064           } else {
1065             SET_ERRNO(HPE_INVALID_METHOD);
1066             goto error;
1067           }
1068         } else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
1069           parser->method = HTTP_PROPPATCH;
1070         } else {
1071           SET_ERRNO(HPE_INVALID_METHOD);
1072           goto error;
1073         }
1074
1075         ++parser->index;
1076         break;
1077       }
1078
1079       case s_req_spaces_before_url:
1080       {
1081         if (ch == ' ') break;
1082
1083         MARK(url);
1084         if (parser->method == HTTP_CONNECT) {
1085           UPDATE_STATE(s_req_server_start);
1086         }
1087
1088         UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
1089         if (UNLIKELY(CURRENT_STATE() == s_dead)) {
1090           SET_ERRNO(HPE_INVALID_URL);
1091           goto error;
1092         }
1093
1094         break;
1095       }
1096
1097       case s_req_schema:
1098       case s_req_schema_slash:
1099       case s_req_schema_slash_slash:
1100       case s_req_server_start:
1101       {
1102         switch (ch) {
1103           /* No whitespace allowed here */
1104           case ' ':
1105           case CR:
1106           case LF:
1107             SET_ERRNO(HPE_INVALID_URL);
1108             goto error;
1109           default:
1110             UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
1111             if (UNLIKELY(CURRENT_STATE() == s_dead)) {
1112               SET_ERRNO(HPE_INVALID_URL);
1113               goto error;
1114             }
1115         }
1116
1117         break;
1118       }
1119
1120       case s_req_server:
1121       case s_req_server_with_at:
1122       case s_req_path:
1123       case s_req_query_string_start:
1124       case s_req_query_string:
1125       case s_req_fragment_start:
1126       case s_req_fragment:
1127       {
1128         switch (ch) {
1129           case ' ':
1130             UPDATE_STATE(s_req_http_start);
1131             CALLBACK_DATA(url);
1132             break;
1133           case CR:
1134           case LF:
1135             parser->http_major = 0;
1136             parser->http_minor = 9;
1137             UPDATE_STATE((ch == CR) ?
1138               s_req_line_almost_done :
1139               s_header_field_start);
1140             CALLBACK_DATA(url);
1141             break;
1142           default:
1143             UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
1144             if (UNLIKELY(CURRENT_STATE() == s_dead)) {
1145               SET_ERRNO(HPE_INVALID_URL);
1146               goto error;
1147             }
1148         }
1149         break;
1150       }
1151
1152       case s_req_http_start:
1153         switch (ch) {
1154           case 'H':
1155             UPDATE_STATE(s_req_http_H);
1156             break;
1157           case ' ':
1158             break;
1159           default:
1160             SET_ERRNO(HPE_INVALID_CONSTANT);
1161             goto error;
1162         }
1163         break;
1164
1165       case s_req_http_H:
1166         STRICT_CHECK(ch != 'T');
1167         UPDATE_STATE(s_req_http_HT);
1168         break;
1169
1170       case s_req_http_HT:
1171         STRICT_CHECK(ch != 'T');
1172         UPDATE_STATE(s_req_http_HTT);
1173         break;
1174
1175       case s_req_http_HTT:
1176         STRICT_CHECK(ch != 'P');
1177         UPDATE_STATE(s_req_http_HTTP);
1178         break;
1179
1180       case s_req_http_HTTP:
1181         STRICT_CHECK(ch != '/');
1182         UPDATE_STATE(s_req_first_http_major);
1183         break;
1184
1185       /* first digit of major HTTP version */
1186       case s_req_first_http_major:
1187         if (UNLIKELY(ch < '1' || ch > '9')) {
1188           SET_ERRNO(HPE_INVALID_VERSION);
1189           goto error;
1190         }
1191
1192         parser->http_major = ch - '0';
1193         UPDATE_STATE(s_req_http_major);
1194         break;
1195
1196       /* major HTTP version or dot */
1197       case s_req_http_major:
1198       {
1199         if (ch == '.') {
1200           UPDATE_STATE(s_req_first_http_minor);
1201           break;
1202         }
1203
1204         if (UNLIKELY(!IS_NUM(ch))) {
1205           SET_ERRNO(HPE_INVALID_VERSION);
1206           goto error;
1207         }
1208
1209         parser->http_major *= 10;
1210         parser->http_major += ch - '0';
1211
1212         if (UNLIKELY(parser->http_major > 999)) {
1213           SET_ERRNO(HPE_INVALID_VERSION);
1214           goto error;
1215         }
1216
1217         break;
1218       }
1219
1220       /* first digit of minor HTTP version */
1221       case s_req_first_http_minor:
1222         if (UNLIKELY(!IS_NUM(ch))) {
1223           SET_ERRNO(HPE_INVALID_VERSION);
1224           goto error;
1225         }
1226
1227         parser->http_minor = ch - '0';
1228         UPDATE_STATE(s_req_http_minor);
1229         break;
1230
1231       /* minor HTTP version or end of request line */
1232       case s_req_http_minor:
1233       {
1234         if (ch == CR) {
1235           UPDATE_STATE(s_req_line_almost_done);
1236           break;
1237         }
1238
1239         if (ch == LF) {
1240           UPDATE_STATE(s_header_field_start);
1241           break;
1242         }
1243
1244         /* XXX allow spaces after digit? */
1245
1246         if (UNLIKELY(!IS_NUM(ch))) {
1247           SET_ERRNO(HPE_INVALID_VERSION);
1248           goto error;
1249         }
1250
1251         parser->http_minor *= 10;
1252         parser->http_minor += ch - '0';
1253
1254         if (UNLIKELY(parser->http_minor > 999)) {
1255           SET_ERRNO(HPE_INVALID_VERSION);
1256           goto error;
1257         }
1258
1259         break;
1260       }
1261
1262       /* end of request line */
1263       case s_req_line_almost_done:
1264       {
1265         if (UNLIKELY(ch != LF)) {
1266           SET_ERRNO(HPE_LF_EXPECTED);
1267           goto error;
1268         }
1269
1270         UPDATE_STATE(s_header_field_start);
1271         break;
1272       }
1273
1274       case s_header_field_start:
1275       {
1276         if (ch == CR) {
1277           UPDATE_STATE(s_headers_almost_done);
1278           break;
1279         }
1280
1281         if (ch == LF) {
1282           /* they might be just sending \n instead of \r\n so this would be
1283            * the second \n to denote the end of headers*/
1284           UPDATE_STATE(s_headers_almost_done);
1285           REEXECUTE();
1286         }
1287
1288         c = TOKEN(ch);
1289
1290         if (UNLIKELY(!c)) {
1291           SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
1292           goto error;
1293         }
1294
1295         MARK(header_field);
1296
1297         parser->index = 0;
1298         UPDATE_STATE(s_header_field);
1299
1300         switch (c) {
1301           case 'c':
1302             parser->header_state = h_C;
1303             break;
1304
1305           case 'p':
1306             parser->header_state = h_matching_proxy_connection;
1307             break;
1308
1309           case 't':
1310             parser->header_state = h_matching_transfer_encoding;
1311             break;
1312
1313           case 'u':
1314             parser->header_state = h_matching_upgrade;
1315             break;
1316
1317           default:
1318             parser->header_state = h_general;
1319             break;
1320         }
1321         break;
1322       }
1323
1324       case s_header_field:
1325       {
1326         const char* start = p;
1327         for (; p != data + len; p++) {
1328           ch = *p;
1329           c = TOKEN(ch);
1330
1331           if (!c)
1332             break;
1333
1334           switch (parser->header_state) {
1335             case h_general:
1336               break;
1337
1338             case h_C:
1339               parser->index++;
1340               parser->header_state = (c == 'o' ? h_CO : h_general);
1341               break;
1342
1343             case h_CO:
1344               parser->index++;
1345               parser->header_state = (c == 'n' ? h_CON : h_general);
1346               break;
1347
1348             case h_CON:
1349               parser->index++;
1350               switch (c) {
1351                 case 'n':
1352                   parser->header_state = h_matching_connection;
1353                   break;
1354                 case 't':
1355                   parser->header_state = h_matching_content_length;
1356                   break;
1357                 default:
1358                   parser->header_state = h_general;
1359                   break;
1360               }
1361               break;
1362
1363             /* connection */
1364
1365             case h_matching_connection:
1366               parser->index++;
1367               if (parser->index > sizeof(CONNECTION)-1
1368                   || c != CONNECTION[parser->index]) {
1369                 parser->header_state = h_general;
1370               } else if (parser->index == sizeof(CONNECTION)-2) {
1371                 parser->header_state = h_connection;
1372               }
1373               break;
1374
1375             /* proxy-connection */
1376
1377             case h_matching_proxy_connection:
1378               parser->index++;
1379               if (parser->index > sizeof(PROXY_CONNECTION)-1
1380                   || c != PROXY_CONNECTION[parser->index]) {
1381                 parser->header_state = h_general;
1382               } else if (parser->index == sizeof(PROXY_CONNECTION)-2) {
1383                 parser->header_state = h_connection;
1384               }
1385               break;
1386
1387             /* content-length */
1388
1389             case h_matching_content_length:
1390               parser->index++;
1391               if (parser->index > sizeof(CONTENT_LENGTH)-1
1392                   || c != CONTENT_LENGTH[parser->index]) {
1393                 parser->header_state = h_general;
1394               } else if (parser->index == sizeof(CONTENT_LENGTH)-2) {
1395                 if (parser->flags & F_CONTENTLENGTH) {
1396                   SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH);
1397                   goto error;
1398                 }
1399                 parser->header_state = h_content_length;
1400                 parser->flags |= F_CONTENTLENGTH;
1401               }
1402               break;
1403
1404             /* transfer-encoding */
1405
1406             case h_matching_transfer_encoding:
1407               parser->index++;
1408               if (parser->index > sizeof(TRANSFER_ENCODING)-1
1409                   || c != TRANSFER_ENCODING[parser->index]) {
1410                 parser->header_state = h_general;
1411               } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
1412                 parser->header_state = h_transfer_encoding;
1413               }
1414               break;
1415
1416             /* upgrade */
1417
1418             case h_matching_upgrade:
1419               parser->index++;
1420               if (parser->index > sizeof(UPGRADE)-1
1421                   || c != UPGRADE[parser->index]) {
1422                 parser->header_state = h_general;
1423               } else if (parser->index == sizeof(UPGRADE)-2) {
1424                 parser->header_state = h_upgrade;
1425               }
1426               break;
1427
1428             case h_connection:
1429             case h_content_length:
1430             case h_transfer_encoding:
1431             case h_upgrade:
1432               if (ch != ' ') parser->header_state = h_general;
1433               break;
1434
1435             default:
1436               assert(0 && "Unknown header_state");
1437               break;
1438           }
1439         }
1440
1441         COUNT_HEADER_SIZE(p - start);
1442
1443         if (p == data + len) {
1444           --p;
1445           break;
1446         }
1447
1448         if (ch == ':') {
1449           UPDATE_STATE(s_header_value_discard_ws);
1450           CALLBACK_DATA(header_field);
1451           break;
1452         }
1453
1454         SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
1455         goto error;
1456       }
1457
1458       case s_header_value_discard_ws:
1459         if (ch == ' ' || ch == '\t') break;
1460
1461         if (ch == CR) {
1462           UPDATE_STATE(s_header_value_discard_ws_almost_done);
1463           break;
1464         }
1465
1466         if (ch == LF) {
1467           UPDATE_STATE(s_header_value_discard_lws);
1468           break;
1469         }
1470
1471         /* FALLTHROUGH */
1472
1473       case s_header_value_start:
1474       {
1475         MARK(header_value);
1476
1477         UPDATE_STATE(s_header_value);
1478         parser->index = 0;
1479
1480         c = LOWER(ch);
1481
1482         switch (parser->header_state) {
1483           case h_upgrade:
1484             parser->flags |= F_UPGRADE;
1485             parser->header_state = h_general;
1486             break;
1487
1488           case h_transfer_encoding:
1489             /* looking for 'Transfer-Encoding: chunked' */
1490             if ('c' == c) {
1491               parser->header_state = h_matching_transfer_encoding_chunked;
1492             } else {
1493               parser->header_state = h_general;
1494             }
1495             break;
1496
1497           case h_content_length:
1498             if (UNLIKELY(!IS_NUM(ch))) {
1499               SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
1500               goto error;
1501             }
1502
1503             parser->content_length = ch - '0';
1504             break;
1505
1506           case h_connection:
1507             /* looking for 'Connection: keep-alive' */
1508             if (c == 'k') {
1509               parser->header_state = h_matching_connection_keep_alive;
1510             /* looking for 'Connection: close' */
1511             } else if (c == 'c') {
1512               parser->header_state = h_matching_connection_close;
1513             } else if (c == 'u') {
1514               parser->header_state = h_matching_connection_upgrade;
1515             } else {
1516               parser->header_state = h_matching_connection_token;
1517             }
1518             break;
1519
1520           /* Multi-value `Connection` header */
1521           case h_matching_connection_token_start:
1522             break;
1523
1524           default:
1525             parser->header_state = h_general;
1526             break;
1527         }
1528         break;
1529       }
1530
1531       case s_header_value:
1532       {
1533         const char* start = p;
1534         enum header_states h_state = (enum header_states) parser->header_state;
1535         for (; p != data + len; p++) {
1536           ch = *p;
1537           if (ch == CR) {
1538             UPDATE_STATE(s_header_almost_done);
1539             parser->header_state = h_state;
1540             CALLBACK_DATA(header_value);
1541             break;
1542           }
1543
1544           if (ch == LF) {
1545             UPDATE_STATE(s_header_almost_done);
1546             COUNT_HEADER_SIZE(p - start);
1547             parser->header_state = h_state;
1548             CALLBACK_DATA_NOADVANCE(header_value);
1549             REEXECUTE();
1550           }
1551
1552           if (!lenient && !IS_HEADER_CHAR(ch)) {
1553             SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
1554             goto error;
1555           }
1556
1557           c = LOWER(ch);
1558
1559           switch (h_state) {
1560             case h_general:
1561             {
1562               const char* p_cr;
1563               const char* p_lf;
1564               size_t limit = data + len - p;
1565
1566               limit = MIN(limit, HTTP_MAX_HEADER_SIZE);
1567
1568               p_cr = (const char*) memchr(p, CR, limit);
1569               p_lf = (const char*) memchr(p, LF, limit);
1570               if (p_cr != NULL) {
1571                 if (p_lf != NULL && p_cr >= p_lf)
1572                   p = p_lf;
1573                 else
1574                   p = p_cr;
1575               } else if (UNLIKELY(p_lf != NULL)) {
1576                 p = p_lf;
1577               } else {
1578                 p = data + len;
1579               }
1580               --p;
1581
1582               break;
1583             }
1584
1585             case h_connection:
1586             case h_transfer_encoding:
1587               assert(0 && "Shouldn't get here.");
1588               break;
1589
1590             case h_content_length:
1591             {
1592               uint64_t t;
1593
1594               if (ch == ' ') break;
1595
1596               if (UNLIKELY(!IS_NUM(ch))) {
1597                 SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
1598                 parser->header_state = h_state;
1599                 goto error;
1600               }
1601
1602               t = parser->content_length;
1603               t *= 10;
1604               t += ch - '0';
1605
1606               /* Overflow? Test against a conservative limit for simplicity. */
1607               if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) {
1608                 SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
1609                 parser->header_state = h_state;
1610                 goto error;
1611               }
1612
1613               parser->content_length = t;
1614               break;
1615             }
1616
1617             /* Transfer-Encoding: chunked */
1618             case h_matching_transfer_encoding_chunked:
1619               parser->index++;
1620               if (parser->index > sizeof(CHUNKED)-1
1621                   || c != CHUNKED[parser->index]) {
1622                 h_state = h_general;
1623               } else if (parser->index == sizeof(CHUNKED)-2) {
1624                 h_state = h_transfer_encoding_chunked;
1625               }
1626               break;
1627
1628             case h_matching_connection_token_start:
1629               /* looking for 'Connection: keep-alive' */
1630               if (c == 'k') {
1631                 h_state = h_matching_connection_keep_alive;
1632               /* looking for 'Connection: close' */
1633               } else if (c == 'c') {
1634                 h_state = h_matching_connection_close;
1635               } else if (c == 'u') {
1636                 h_state = h_matching_connection_upgrade;
1637               } else if (STRICT_TOKEN(c)) {
1638                 h_state = h_matching_connection_token;
1639               } else if (c == ' ' || c == '\t') {
1640                 /* Skip lws */
1641               } else {
1642                 h_state = h_general;
1643               }
1644               break;
1645
1646             /* looking for 'Connection: keep-alive' */
1647             case h_matching_connection_keep_alive:
1648               parser->index++;
1649               if (parser->index > sizeof(KEEP_ALIVE)-1
1650                   || c != KEEP_ALIVE[parser->index]) {
1651                 h_state = h_matching_connection_token;
1652               } else if (parser->index == sizeof(KEEP_ALIVE)-2) {
1653                 h_state = h_connection_keep_alive;
1654               }
1655               break;
1656
1657             /* looking for 'Connection: close' */
1658             case h_matching_connection_close:
1659               parser->index++;
1660               if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) {
1661                 h_state = h_matching_connection_token;
1662               } else if (parser->index == sizeof(CLOSE)-2) {
1663                 h_state = h_connection_close;
1664               }
1665               break;
1666
1667             /* looking for 'Connection: upgrade' */
1668             case h_matching_connection_upgrade:
1669               parser->index++;
1670               if (parser->index > sizeof(UPGRADE) - 1 ||
1671                   c != UPGRADE[parser->index]) {
1672                 h_state = h_matching_connection_token;
1673               } else if (parser->index == sizeof(UPGRADE)-2) {
1674                 h_state = h_connection_upgrade;
1675               }
1676               break;
1677
1678             case h_matching_connection_token:
1679               if (ch == ',') {
1680                 h_state = h_matching_connection_token_start;
1681                 parser->index = 0;
1682               }
1683               break;
1684
1685             case h_transfer_encoding_chunked:
1686               if (ch != ' ') h_state = h_general;
1687               break;
1688
1689             case h_connection_keep_alive:
1690             case h_connection_close:
1691             case h_connection_upgrade:
1692               if (ch == ',') {
1693                 if (h_state == h_connection_keep_alive) {
1694                   parser->flags |= F_CONNECTION_KEEP_ALIVE;
1695                 } else if (h_state == h_connection_close) {
1696                   parser->flags |= F_CONNECTION_CLOSE;
1697                 } else if (h_state == h_connection_upgrade) {
1698                   parser->flags |= F_CONNECTION_UPGRADE;
1699                 }
1700                 h_state = h_matching_connection_token_start;
1701                 parser->index = 0;
1702               } else if (ch != ' ') {
1703                 h_state = h_matching_connection_token;
1704               }
1705               break;
1706
1707             default:
1708               UPDATE_STATE(s_header_value);
1709               h_state = h_general;
1710               break;
1711           }
1712         }
1713         parser->header_state = h_state;
1714
1715         COUNT_HEADER_SIZE(p - start);
1716
1717         if (p == data + len)
1718           --p;
1719         break;
1720       }
1721
1722       case s_header_almost_done:
1723       {
1724         if (UNLIKELY(ch != LF)) {
1725           SET_ERRNO(HPE_LF_EXPECTED);
1726           goto error;
1727         }
1728
1729         UPDATE_STATE(s_header_value_lws);
1730         break;
1731       }
1732
1733       case s_header_value_lws:
1734       {
1735         if (ch == ' ' || ch == '\t') {
1736           UPDATE_STATE(s_header_value_start);
1737           REEXECUTE();
1738         }
1739
1740         /* finished the header */
1741         switch (parser->header_state) {
1742           case h_connection_keep_alive:
1743             parser->flags |= F_CONNECTION_KEEP_ALIVE;
1744             break;
1745           case h_connection_close:
1746             parser->flags |= F_CONNECTION_CLOSE;
1747             break;
1748           case h_transfer_encoding_chunked:
1749             parser->flags |= F_CHUNKED;
1750             break;
1751           case h_connection_upgrade:
1752             parser->flags |= F_CONNECTION_UPGRADE;
1753             break;
1754           default:
1755             break;
1756         }
1757
1758         UPDATE_STATE(s_header_field_start);
1759         REEXECUTE();
1760       }
1761
1762       case s_header_value_discard_ws_almost_done:
1763       {
1764         STRICT_CHECK(ch != LF);
1765         UPDATE_STATE(s_header_value_discard_lws);
1766         break;
1767       }
1768
1769       case s_header_value_discard_lws:
1770       {
1771         if (ch == ' ' || ch == '\t') {
1772           UPDATE_STATE(s_header_value_discard_ws);
1773           break;
1774         } else {
1775           switch (parser->header_state) {
1776             case h_connection_keep_alive:
1777               parser->flags |= F_CONNECTION_KEEP_ALIVE;
1778               break;
1779             case h_connection_close:
1780               parser->flags |= F_CONNECTION_CLOSE;
1781               break;
1782             case h_connection_upgrade:
1783               parser->flags |= F_CONNECTION_UPGRADE;
1784               break;
1785             case h_transfer_encoding_chunked:
1786               parser->flags |= F_CHUNKED;
1787               break;
1788             default:
1789               break;
1790           }
1791
1792           /* header value was empty */
1793           MARK(header_value);
1794           UPDATE_STATE(s_header_field_start);
1795           CALLBACK_DATA_NOADVANCE(header_value);
1796           REEXECUTE();
1797         }
1798       }
1799
1800       case s_headers_almost_done:
1801       {
1802         STRICT_CHECK(ch != LF);
1803
1804         if (parser->flags & F_TRAILING) {
1805           /* End of a chunked request */
1806           UPDATE_STATE(s_message_done);
1807           CALLBACK_NOTIFY_NOADVANCE(chunk_complete);
1808           REEXECUTE();
1809         }
1810
1811         /* Cannot use chunked encoding and a content-length header together
1812            per the HTTP specification. */
1813         if ((parser->flags & F_CHUNKED) &&
1814             (parser->flags & F_CONTENTLENGTH)) {
1815           SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH);
1816           goto error;
1817         }
1818
1819         UPDATE_STATE(s_headers_done);
1820
1821         /* Set this here so that on_headers_complete() callbacks can see it */
1822         parser->upgrade =
1823           ((parser->flags & (F_UPGRADE | F_CONNECTION_UPGRADE)) ==
1824            (F_UPGRADE | F_CONNECTION_UPGRADE) ||
1825            parser->method == HTTP_CONNECT);
1826
1827         /* Here we call the headers_complete callback. This is somewhat
1828          * different than other callbacks because if the user returns 1, we
1829          * will interpret that as saying that this message has no body. This
1830          * is needed for the annoying case of recieving a response to a HEAD
1831          * request.
1832          *
1833          * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so
1834          * we have to simulate it by handling a change in errno below.
1835          */
1836         if (settings->on_headers_complete) {
1837           switch (settings->on_headers_complete(parser)) {
1838             case 0:
1839               break;
1840
1841             case 1:
1842               parser->flags |= F_SKIPBODY;
1843               break;
1844
1845             default:
1846               SET_ERRNO(HPE_CB_headers_complete);
1847               RETURN(p - data); /* Error */
1848           }
1849         }
1850
1851         if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
1852           RETURN(p - data);
1853         }
1854
1855         REEXECUTE();
1856       }
1857
1858       case s_headers_done:
1859       {
1860         STRICT_CHECK(ch != LF);
1861
1862         parser->nread = 0;
1863
1864         int hasBody = parser->flags & F_CHUNKED ||
1865           (parser->content_length > 0 && parser->content_length != ULLONG_MAX);
1866         if (parser->upgrade && (parser->method == HTTP_CONNECT ||
1867                                 (parser->flags & F_SKIPBODY) || !hasBody)) {
1868           /* Exit, the rest of the message is in a different protocol. */
1869           UPDATE_STATE(NEW_MESSAGE());
1870           CALLBACK_NOTIFY(message_complete);
1871           RETURN((p - data) + 1);
1872         }
1873
1874         if (parser->flags & F_SKIPBODY) {
1875           UPDATE_STATE(NEW_MESSAGE());
1876           CALLBACK_NOTIFY(message_complete);
1877         } else if (parser->flags & F_CHUNKED) {
1878           /* chunked encoding - ignore Content-Length header */
1879           UPDATE_STATE(s_chunk_size_start);
1880         } else {
1881           if (parser->content_length == 0) {
1882             /* Content-Length header given but zero: Content-Length: 0\r\n */
1883             UPDATE_STATE(NEW_MESSAGE());
1884             CALLBACK_NOTIFY(message_complete);
1885           } else if (parser->content_length != ULLONG_MAX) {
1886             /* Content-Length header given and non-zero */
1887             UPDATE_STATE(s_body_identity);
1888           } else {
1889             if (parser->type == HTTP_REQUEST ||
1890                 !http_message_needs_eof(parser)) {
1891               /* Assume content-length 0 - read the next */
1892               UPDATE_STATE(NEW_MESSAGE());
1893               CALLBACK_NOTIFY(message_complete);
1894             } else {
1895               /* Read body until EOF */
1896               UPDATE_STATE(s_body_identity_eof);
1897             }
1898           }
1899         }
1900
1901         break;
1902       }
1903
1904       case s_body_identity:
1905       {
1906         uint64_t to_read = MIN(parser->content_length,
1907                                (uint64_t) ((data + len) - p));
1908
1909         assert(parser->content_length != 0
1910             && parser->content_length != ULLONG_MAX);
1911
1912         /* The difference between advancing content_length and p is because
1913          * the latter will automaticaly advance on the next loop iteration.
1914          * Further, if content_length ends up at 0, we want to see the last
1915          * byte again for our message complete callback.
1916          */
1917         MARK(body);
1918         parser->content_length -= to_read;
1919         p += to_read - 1;
1920
1921         if (parser->content_length == 0) {
1922           UPDATE_STATE(s_message_done);
1923
1924           /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte.
1925            *
1926            * The alternative to doing this is to wait for the next byte to
1927            * trigger the data callback, just as in every other case. The
1928            * problem with this is that this makes it difficult for the test
1929            * harness to distinguish between complete-on-EOF and
1930            * complete-on-length. It's not clear that this distinction is
1931            * important for applications, but let's keep it for now.
1932            */
1933           CALLBACK_DATA_(body, p - body_mark + 1, p - data);
1934           REEXECUTE();
1935         }
1936
1937         break;
1938       }
1939
1940       /* read until EOF */
1941       case s_body_identity_eof:
1942         MARK(body);
1943         p = data + len - 1;
1944
1945         break;
1946
1947       case s_message_done:
1948         UPDATE_STATE(NEW_MESSAGE());
1949         CALLBACK_NOTIFY(message_complete);
1950         if (parser->upgrade) {
1951           /* Exit, the rest of the message is in a different protocol. */
1952           RETURN((p - data) + 1);
1953         }
1954         break;
1955
1956       case s_chunk_size_start:
1957       {
1958         assert(parser->nread == 1);
1959         assert(parser->flags & F_CHUNKED);
1960
1961         unhex_val = unhex[(unsigned char)ch];
1962         if (UNLIKELY(unhex_val == -1)) {
1963           SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
1964           goto error;
1965         }
1966
1967         parser->content_length = unhex_val;
1968         UPDATE_STATE(s_chunk_size);
1969         break;
1970       }
1971
1972       case s_chunk_size:
1973       {
1974         uint64_t t;
1975
1976         assert(parser->flags & F_CHUNKED);
1977
1978         if (ch == CR) {
1979           UPDATE_STATE(s_chunk_size_almost_done);
1980           break;
1981         }
1982
1983         unhex_val = unhex[(unsigned char)ch];
1984
1985         if (unhex_val == -1) {
1986           if (ch == ';' || ch == ' ') {
1987             UPDATE_STATE(s_chunk_parameters);
1988             break;
1989           }
1990
1991           SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
1992           goto error;
1993         }
1994
1995         t = parser->content_length;
1996         t *= 16;
1997         t += unhex_val;
1998
1999         /* Overflow? Test against a conservative limit for simplicity. */
2000         if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) {
2001           SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
2002           goto error;
2003         }
2004
2005         parser->content_length = t;
2006         break;
2007       }
2008
2009       case s_chunk_parameters:
2010       {
2011         assert(parser->flags & F_CHUNKED);
2012         /* just ignore this shit. TODO check for overflow */
2013         if (ch == CR) {
2014           UPDATE_STATE(s_chunk_size_almost_done);
2015           break;
2016         }
2017         break;
2018       }
2019
2020       case s_chunk_size_almost_done:
2021       {
2022         assert(parser->flags & F_CHUNKED);
2023         STRICT_CHECK(ch != LF);
2024
2025         parser->nread = 0;
2026
2027         if (parser->content_length == 0) {
2028           parser->flags |= F_TRAILING;
2029           UPDATE_STATE(s_header_field_start);
2030         } else {
2031           UPDATE_STATE(s_chunk_data);
2032         }
2033         CALLBACK_NOTIFY(chunk_header);
2034         break;
2035       }
2036
2037       case s_chunk_data:
2038       {
2039         uint64_t to_read = MIN(parser->content_length,
2040                                (uint64_t) ((data + len) - p));
2041
2042         assert(parser->flags & F_CHUNKED);
2043         assert(parser->content_length != 0
2044             && parser->content_length != ULLONG_MAX);
2045
2046         /* See the explanation in s_body_identity for why the content
2047          * length and data pointers are managed this way.
2048          */
2049         MARK(body);
2050         parser->content_length -= to_read;
2051         p += to_read - 1;
2052
2053         if (parser->content_length == 0) {
2054           UPDATE_STATE(s_chunk_data_almost_done);
2055         }
2056
2057         break;
2058       }
2059
2060       case s_chunk_data_almost_done:
2061         assert(parser->flags & F_CHUNKED);
2062         assert(parser->content_length == 0);
2063         STRICT_CHECK(ch != CR);
2064         UPDATE_STATE(s_chunk_data_done);
2065         CALLBACK_DATA(body);
2066         break;
2067
2068       case s_chunk_data_done:
2069         assert(parser->flags & F_CHUNKED);
2070         STRICT_CHECK(ch != LF);
2071         parser->nread = 0;
2072         UPDATE_STATE(s_chunk_size_start);
2073         CALLBACK_NOTIFY(chunk_complete);
2074         break;
2075
2076       default:
2077         assert(0 && "unhandled state");
2078         SET_ERRNO(HPE_INVALID_INTERNAL_STATE);
2079         goto error;
2080     }
2081   }
2082
2083   /* Run callbacks for any marks that we have leftover after we ran our of
2084    * bytes. There should be at most one of these set, so it's OK to invoke
2085    * them in series (unset marks will not result in callbacks).
2086    *
2087    * We use the NOADVANCE() variety of callbacks here because 'p' has already
2088    * overflowed 'data' and this allows us to correct for the off-by-one that
2089    * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p'
2090    * value that's in-bounds).
2091    */
2092
2093   assert(((header_field_mark ? 1 : 0) +
2094           (header_value_mark ? 1 : 0) +
2095           (url_mark ? 1 : 0)  +
2096           (body_mark ? 1 : 0) +
2097           (status_mark ? 1 : 0)) <= 1);
2098
2099   CALLBACK_DATA_NOADVANCE(header_field);
2100   CALLBACK_DATA_NOADVANCE(header_value);
2101   CALLBACK_DATA_NOADVANCE(url);
2102   CALLBACK_DATA_NOADVANCE(body);
2103   CALLBACK_DATA_NOADVANCE(status);
2104
2105   RETURN(len);
2106
2107 error:
2108   if (HTTP_PARSER_ERRNO(parser) == HPE_OK) {
2109     SET_ERRNO(HPE_UNKNOWN);
2110   }
2111
2112   RETURN(p - data);
2113 }
2114
2115
2116 /* Does the parser need to see an EOF to find the end of the message? */
2117 int
2118 http_message_needs_eof (const http_parser *parser)
2119 {
2120   if (parser->type == HTTP_REQUEST) {
2121     return 0;
2122   }
2123
2124   /* See RFC 2616 section 4.4 */
2125   if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
2126       parser->status_code == 204 ||     /* No Content */
2127       parser->status_code == 304 ||     /* Not Modified */
2128       parser->flags & F_SKIPBODY) {     /* response to a HEAD request */
2129     return 0;
2130   }
2131
2132   if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) {
2133     return 0;
2134   }
2135
2136   return 1;
2137 }
2138
2139
2140 int
2141 http_should_keep_alive (const http_parser *parser)
2142 {
2143   if (parser->http_major > 0 && parser->http_minor > 0) {
2144     /* HTTP/1.1 */
2145     if (parser->flags & F_CONNECTION_CLOSE) {
2146       return 0;
2147     }
2148   } else {
2149     /* HTTP/1.0 or earlier */
2150     if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) {
2151       return 0;
2152     }
2153   }
2154
2155   return !http_message_needs_eof(parser);
2156 }
2157
2158
2159 const char *
2160 http_method_str (enum http_method m)
2161 {
2162   return ELEM_AT(method_strings, m, "<unknown>");
2163 }
2164
2165
2166 void
2167 http_parser_init (http_parser *parser, enum http_parser_type t)
2168 {
2169   void *data = parser->data; /* preserve application data */
2170   memset(parser, 0, sizeof(*parser));
2171   parser->data = data;
2172   parser->type = t;
2173   parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res));
2174   parser->http_errno = HPE_OK;
2175 }
2176
2177 void
2178 http_parser_settings_init(http_parser_settings *settings)
2179 {
2180   memset(settings, 0, sizeof(*settings));
2181 }
2182
2183 const char *
2184 http_errno_name(enum http_errno err) {
2185   assert(((size_t) err) <
2186       (sizeof(http_strerror_tab) / sizeof(http_strerror_tab[0])));
2187   return http_strerror_tab[err].name;
2188 }
2189
2190 const char *
2191 http_errno_description(enum http_errno err) {
2192   assert(((size_t) err) <
2193       (sizeof(http_strerror_tab) / sizeof(http_strerror_tab[0])));
2194   return http_strerror_tab[err].description;
2195 }
2196
2197 static enum http_host_state
2198 http_parse_host_char(enum http_host_state s, const char ch) {
2199   switch(s) {
2200     case s_http_userinfo:
2201     case s_http_userinfo_start:
2202       if (ch == '@') {
2203         return s_http_host_start;
2204       }
2205
2206       if (IS_USERINFO_CHAR(ch)) {
2207         return s_http_userinfo;
2208       }
2209       break;
2210
2211     case s_http_host_start:
2212       if (ch == '[') {
2213         return s_http_host_v6_start;
2214       }
2215
2216       if (IS_HOST_CHAR(ch)) {
2217         return s_http_host;
2218       }
2219
2220       break;
2221
2222     case s_http_host:
2223       if (IS_HOST_CHAR(ch)) {
2224         return s_http_host;
2225       }
2226
2227     /* FALLTHROUGH */
2228     case s_http_host_v6_end:
2229       if (ch == ':') {
2230         return s_http_host_port_start;
2231       }
2232
2233       break;
2234
2235     case s_http_host_v6:
2236       if (ch == ']') {
2237         return s_http_host_v6_end;
2238       }
2239
2240     /* FALLTHROUGH */
2241     case s_http_host_v6_start:
2242       if (IS_HEX(ch) || ch == ':' || ch == '.') {
2243         return s_http_host_v6;
2244       }
2245
2246       break;
2247
2248     case s_http_host_port:
2249     case s_http_host_port_start:
2250       if (IS_NUM(ch)) {
2251         return s_http_host_port;
2252       }
2253
2254       break;
2255
2256     default:
2257       break;
2258   }
2259   return s_http_host_dead;
2260 }
2261
2262 static int
2263 http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
2264   enum http_host_state s;
2265
2266   const char *p;
2267   size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len;
2268
2269   u->field_data[UF_HOST].len = 0;
2270
2271   s = found_at ? s_http_userinfo_start : s_http_host_start;
2272
2273   for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) {
2274     enum http_host_state new_s = http_parse_host_char(s, *p);
2275
2276     if (new_s == s_http_host_dead) {
2277       return 1;
2278     }
2279
2280     switch(new_s) {
2281       case s_http_host:
2282         if (s != s_http_host) {
2283           u->field_data[UF_HOST].off = p - buf;
2284         }
2285         u->field_data[UF_HOST].len++;
2286         break;
2287
2288       case s_http_host_v6:
2289         if (s != s_http_host_v6) {
2290           u->field_data[UF_HOST].off = p - buf;
2291         }
2292         u->field_data[UF_HOST].len++;
2293         break;
2294
2295       case s_http_host_port:
2296         if (s != s_http_host_port) {
2297           u->field_data[UF_PORT].off = p - buf;
2298           u->field_data[UF_PORT].len = 0;
2299           u->field_set |= (1 << UF_PORT);
2300         }
2301         u->field_data[UF_PORT].len++;
2302         break;
2303
2304       case s_http_userinfo:
2305         if (s != s_http_userinfo) {
2306           u->field_data[UF_USERINFO].off = p - buf ;
2307           u->field_data[UF_USERINFO].len = 0;
2308           u->field_set |= (1 << UF_USERINFO);
2309         }
2310         u->field_data[UF_USERINFO].len++;
2311         break;
2312
2313       default:
2314         break;
2315     }
2316     s = new_s;
2317   }
2318
2319   /* Make sure we don't end somewhere unexpected */
2320   switch (s) {
2321     case s_http_host_start:
2322     case s_http_host_v6_start:
2323     case s_http_host_v6:
2324     case s_http_host_port_start:
2325     case s_http_userinfo:
2326     case s_http_userinfo_start:
2327       return 1;
2328     default:
2329       break;
2330   }
2331
2332   return 0;
2333 }
2334
2335 int
2336 http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
2337                       struct http_parser_url *u)
2338 {
2339   enum state s;
2340   const char *p;
2341   enum http_parser_url_fields uf, old_uf;
2342   int found_at = 0;
2343
2344   u->port = u->field_set = 0;
2345   s = is_connect ? s_req_server_start : s_req_spaces_before_url;
2346   old_uf = UF_MAX;
2347
2348   for (p = buf; p < buf + buflen; p++) {
2349     s = parse_url_char(s, *p);
2350
2351     /* Figure out the next field that we're operating on */
2352     switch (s) {
2353       case s_dead:
2354         return 1;
2355
2356       /* Skip delimeters */
2357       case s_req_schema_slash:
2358       case s_req_schema_slash_slash:
2359       case s_req_server_start:
2360       case s_req_query_string_start:
2361       case s_req_fragment_start:
2362         continue;
2363
2364       case s_req_schema:
2365         uf = UF_SCHEMA;
2366         break;
2367
2368       case s_req_server_with_at:
2369         found_at = 1;
2370
2371       /* FALLTROUGH */
2372       case s_req_server:
2373         uf = UF_HOST;
2374         break;
2375
2376       case s_req_path:
2377         uf = UF_PATH;
2378         break;
2379
2380       case s_req_query_string:
2381         uf = UF_QUERY;
2382         break;
2383
2384       case s_req_fragment:
2385         uf = UF_FRAGMENT;
2386         break;
2387
2388       default:
2389         assert(!"Unexpected state");
2390         return 1;
2391     }
2392
2393     /* Nothing's changed; soldier on */
2394     if (uf == old_uf) {
2395       u->field_data[uf].len++;
2396       continue;
2397     }
2398
2399     u->field_data[uf].off = p - buf;
2400     u->field_data[uf].len = 1;
2401
2402     u->field_set |= (1 << uf);
2403     old_uf = uf;
2404   }
2405
2406   /* host must be present if there is a schema */
2407   /* parsing http:///toto will fail */
2408   if ((u->field_set & ((1 << UF_SCHEMA) | (1 << UF_HOST))) != 0) {
2409     if (http_parse_host(buf, u, found_at) != 0) {
2410       return 1;
2411     }
2412   }
2413
2414   /* CONNECT requests can only contain "hostname:port" */
2415   if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) {
2416     return 1;
2417   }
2418
2419   if (u->field_set & (1 << UF_PORT)) {
2420     /* Don't bother with endp; we've already validated the string */
2421     unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10);
2422
2423     /* Ports have a max value of 2^16 */
2424     if (v > 0xffff) {
2425       return 1;
2426     }
2427
2428     u->port = (uint16_t) v;
2429   }
2430
2431   return 0;
2432 }
2433
2434 void
2435 http_parser_pause(http_parser *parser, int paused) {
2436   /* Users should only be pausing/unpausing a parser that is not in an error
2437    * state. In non-debug builds, there's not much that we can do about this
2438    * other than ignore it.
2439    */
2440   if (HTTP_PARSER_ERRNO(parser) == HPE_OK ||
2441       HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) {
2442     SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK);
2443   } else {
2444     assert(0 && "Attempting to pause parser in error state");
2445   }
2446 }
2447
2448 int
2449 http_body_is_final(const struct http_parser *parser) {
2450     return parser->state == s_message_done;
2451 }
2452
2453 unsigned long
2454 http_parser_version(void) {
2455   return HTTP_PARSER_VERSION_MAJOR * 0x10000 |
2456          HTTP_PARSER_VERSION_MINOR * 0x00100 |
2457          HTTP_PARSER_VERSION_PATCH * 0x00001;
2458 }