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