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