My Project
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
http_parser.h
Go to the documentation of this file.
1 /*
2 START OF LICENSE STUB
3  DeDOS: Declarative Dispersion-Oriented Software
4  Copyright (C) 2017 University of Pennsylvania, Georgetown University
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 END OF LICENSE STUB
19 */
20 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
21  *
22  * Permission is hereby granted, free of charge, to any person obtaining a copy
23  * of this software and associated documentation files (the "Software"), to
24  * deal in the Software without restriction, including without limitation the
25  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
26  * sell copies of the Software, and to permit persons to whom the Software is
27  * furnished to do so, subject to the following conditions:
28  *
29  * The above copyright notice and this permission notice shall be included in
30  * all copies or substantial portions of the Software.
31  *
32  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
37  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
38  * IN THE SOFTWARE.
39  */
40 #ifndef http_parser_h
41 #define http_parser_h
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /* Also update SONAME in the Makefile whenever you change these. */
47 #define HTTP_PARSER_VERSION_MAJOR 2
48 #define HTTP_PARSER_VERSION_MINOR 7
49 #define HTTP_PARSER_VERSION_PATCH 1
50 
51 #include <stddef.h>
52 #if defined(_WIN32) && !defined(__MINGW32__) && \
53  (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)
54 #include <BaseTsd.h>
55 typedef __int8 int8_t;
56 typedef unsigned __int8 uint8_t;
57 typedef __int16 int16_t;
58 typedef unsigned __int16 uint16_t;
59 typedef __int32 int32_t;
60 typedef unsigned __int32 uint32_t;
61 typedef __int64 int64_t;
62 typedef unsigned __int64 uint64_t;
63 #else
64 #include <stdint.h>
65 #endif
66 
67 /* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
68  * faster
69  */
70 #ifndef HTTP_PARSER_STRICT
71 # define HTTP_PARSER_STRICT 0
72 #endif
73 
74 /* Maximium header size allowed. If the macro is not defined
75  * before including this header then the default is used. To
76  * change the maximum header size, define the macro in the build
77  * environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove
78  * the effective limit on the size of the header, define the macro
79  * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff)
80  */
81 #ifndef HTTP_MAX_HEADER_SIZE
82 # define HTTP_MAX_HEADER_SIZE (80*1024)
83 #endif
84 
85 typedef struct http_parser http_parser;
87 
88 
89 /* Callbacks should return non-zero to indicate an error. The parser will
90  * then halt execution.
91  *
92  * The one exception is on_headers_complete. In a HTTP_RESPONSE parser
93  * returning '1' from on_headers_complete will tell the parser that it
94  * should not expect a body. This is used when receiving a response to a
95  * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
96  * chunked' headers that indicate the presence of a body.
97  *
98  * Returning `2` from on_headers_complete will tell parser that it should not
99  * expect neither a body nor any futher responses on this connection. This is
100  * useful for handling responses to a CONNECT request which may not contain
101  * `Upgrade` or `Connection: upgrade` headers.
102  *
103  * http_data_cb does not return data chunks. It will be called arbitrarily
104  * many times for each string. E.G. you might get 10 callbacks for "on_url"
105  * each providing just a few characters more data.
106  */
107 typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
108 typedef int (*http_cb) (http_parser*);
109 
110 
111 /* Status Codes */
112 #define HTTP_STATUS_MAP(XX) \
113  XX(100, CONTINUE, Continue) \
114  XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
115  XX(102, PROCESSING, Processing) \
116  XX(200, OK, OK) \
117  XX(201, CREATED, Created) \
118  XX(202, ACCEPTED, Accepted) \
119  XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \
120  XX(204, NO_CONTENT, No Content) \
121  XX(205, RESET_CONTENT, Reset Content) \
122  XX(206, PARTIAL_CONTENT, Partial Content) \
123  XX(207, MULTI_STATUS, Multi-Status) \
124  XX(208, ALREADY_REPORTED, Already Reported) \
125  XX(226, IM_USED, IM Used) \
126  XX(300, MULTIPLE_CHOICES, Multiple Choices) \
127  XX(301, MOVED_PERMANENTLY, Moved Permanently) \
128  XX(302, FOUND, Found) \
129  XX(303, SEE_OTHER, See Other) \
130  XX(304, NOT_MODIFIED, Not Modified) \
131  XX(305, USE_PROXY, Use Proxy) \
132  XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \
133  XX(308, PERMANENT_REDIRECT, Permanent Redirect) \
134  XX(400, BAD_REQUEST, Bad Request) \
135  XX(401, UNAUTHORIZED, Unauthorized) \
136  XX(402, PAYMENT_REQUIRED, Payment Required) \
137  XX(403, FORBIDDEN, Forbidden) \
138  XX(404, NOT_FOUND, Not Found) \
139  XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \
140  XX(406, NOT_ACCEPTABLE, Not Acceptable) \
141  XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \
142  XX(408, REQUEST_TIMEOUT, Request Timeout) \
143  XX(409, CONFLICT, Conflict) \
144  XX(410, GONE, Gone) \
145  XX(411, LENGTH_REQUIRED, Length Required) \
146  XX(412, PRECONDITION_FAILED, Precondition Failed) \
147  XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \
148  XX(414, URI_TOO_LONG, URI Too Long) \
149  XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \
150  XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \
151  XX(417, EXPECTATION_FAILED, Expectation Failed) \
152  XX(421, MISDIRECTED_REQUEST, Misdirected Request) \
153  XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \
154  XX(423, LOCKED, Locked) \
155  XX(424, FAILED_DEPENDENCY, Failed Dependency) \
156  XX(426, UPGRADE_REQUIRED, Upgrade Required) \
157  XX(428, PRECONDITION_REQUIRED, Precondition Required) \
158  XX(429, TOO_MANY_REQUESTS, Too Many Requests) \
159  XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
160  XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \
161  XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \
162  XX(501, NOT_IMPLEMENTED, Not Implemented) \
163  XX(502, BAD_GATEWAY, Bad Gateway) \
164  XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \
165  XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \
166  XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \
167  XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \
168  XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
169  XX(508, LOOP_DETECTED, Loop Detected) \
170  XX(510, NOT_EXTENDED, Not Extended) \
171  XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \
172 
174  {
175 #define XX(num, name, string) HTTP_STATUS_##name = num,
177 #undef XX
178  };
179 
180 
181 /* Request Methods */
182 #define HTTP_METHOD_MAP(XX) \
183  XX(0, DELETE, DELETE) \
184  XX(1, GET, GET) \
185  XX(2, HEAD, HEAD) \
186  XX(3, POST, POST) \
187  XX(4, PUT, PUT) \
188  /* pathological */ \
189  XX(5, CONNECT, CONNECT) \
190  XX(6, OPTIONS, OPTIONS) \
191  XX(7, TRACE, TRACE) \
192  /* WebDAV */ \
193  XX(8, COPY, COPY) \
194  XX(9, LOCK, LOCK) \
195  XX(10, MKCOL, MKCOL) \
196  XX(11, MOVE, MOVE) \
197  XX(12, PROPFIND, PROPFIND) \
198  XX(13, PROPPATCH, PROPPATCH) \
199  XX(14, SEARCH, SEARCH) \
200  XX(15, UNLOCK, UNLOCK) \
201  XX(16, BIND, BIND) \
202  XX(17, REBIND, REBIND) \
203  XX(18, UNBIND, UNBIND) \
204  XX(19, ACL, ACL) \
205  /* subversion */ \
206  XX(20, REPORT, REPORT) \
207  XX(21, MKACTIVITY, MKACTIVITY) \
208  XX(22, CHECKOUT, CHECKOUT) \
209  XX(23, MERGE, MERGE) \
210  /* upnp */ \
211  XX(24, MSEARCH, M-SEARCH) \
212  XX(25, NOTIFY, NOTIFY) \
213  XX(26, SUBSCRIBE, SUBSCRIBE) \
214  XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
215  /* RFC-5789 */ \
216  XX(28, PATCH, PATCH) \
217  XX(29, PURGE, PURGE) \
218  /* CalDAV */ \
219  XX(30, MKCALENDAR, MKCALENDAR) \
220  /* RFC-2068, section 19.6.1.2 */ \
221  XX(31, LINK, LINK) \
222  XX(32, UNLINK, UNLINK) \
224 enum http_method
225  {
226 #define XX(num, name, string) HTTP_##name = num,
228 #undef XX
229  };
231 
233 
235 /* Flag values for http_parser.flags field */
236 enum flags
237  { F_CHUNKED = 1 << 0
241  , F_TRAILING = 1 << 4
242  , F_UPGRADE = 1 << 5
243  , F_SKIPBODY = 1 << 6
244  , F_CONTENTLENGTH = 1 << 7
245  };
246 
247 
248 /* Map for errno-related constants
249  *
250  * The provided argument should be a macro that takes 2 arguments.
251  */
252 #define HTTP_ERRNO_MAP(XX) \
253  /* No error */ \
254  XX(OK, "success") \
255  \
256  /* Callback-related errors */ \
257  XX(CB_message_begin, "the on_message_begin callback failed") \
258  XX(CB_url, "the on_url callback failed") \
259  XX(CB_header_field, "the on_header_field callback failed") \
260  XX(CB_header_value, "the on_header_value callback failed") \
261  XX(CB_headers_complete, "the on_headers_complete callback failed") \
262  XX(CB_body, "the on_body callback failed") \
263  XX(CB_message_complete, "the on_message_complete callback failed") \
264  XX(CB_status, "the on_status callback failed") \
265  XX(CB_chunk_header, "the on_chunk_header callback failed") \
266  XX(CB_chunk_complete, "the on_chunk_complete callback failed") \
267  \
268  /* Parsing-related errors */ \
269  XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
270  XX(HEADER_OVERFLOW, \
271  "too many header bytes seen; overflow detected") \
272  XX(CLOSED_CONNECTION, \
273  "data received after completed connection: close message") \
274  XX(INVALID_VERSION, "invalid HTTP version") \
275  XX(INVALID_STATUS, "invalid HTTP status code") \
276  XX(INVALID_METHOD, "invalid HTTP method") \
277  XX(INVALID_URL, "invalid URL") \
278  XX(INVALID_HOST, "invalid host") \
279  XX(INVALID_PORT, "invalid port") \
280  XX(INVALID_PATH, "invalid path") \
281  XX(INVALID_QUERY_STRING, "invalid query string") \
282  XX(INVALID_FRAGMENT, "invalid fragment") \
283  XX(LF_EXPECTED, "LF character expected") \
284  XX(INVALID_HEADER_TOKEN, "invalid character in header") \
285  XX(INVALID_CONTENT_LENGTH, \
286  "invalid character in content-length header") \
287  XX(UNEXPECTED_CONTENT_LENGTH, \
288  "unexpected content-length header") \
289  XX(INVALID_CHUNK_SIZE, \
290  "invalid character in chunk size header") \
291  XX(INVALID_CONSTANT, "invalid constant string") \
292  XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
293  XX(STRICT, "strict mode assertion failed") \
294  XX(PAUSED, "parser is paused") \
295  XX(UNKNOWN, "an unknown error occurred")
296 
298 /* Define HPE_* values for each errno value above */
299 #define HTTP_ERRNO_GEN(n, s) HPE_##n,
300 enum http_errno {
302 };
303 #undef HTTP_ERRNO_GEN
305 
306 /* Get an http_errno value from an http_parser */
307 #define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
308 
310 struct http_parser {
312  unsigned int type : 2; /* enum http_parser_type */
313  unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */
314  unsigned int state : 7; /* enum state from http_parser.c */
315  unsigned int header_state : 7; /* enum header_state from http_parser.c */
316  unsigned int index : 7; /* index into current matcher */
317  unsigned int lenient_http_headers : 1;
318 
319  uint32_t nread; /* # bytes read in various scenarios */
320  uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
323  unsigned short http_major;
324  unsigned short http_minor;
325  unsigned int status_code : 16; /* responses only */
326  unsigned int method : 8; /* requests only */
327  unsigned int http_errno : 7;
328 
329  /* 1 = Upgrade header was present and the parser has exited because of that.
330  * 0 = No upgrade header present.
331  * Should be checked when http_parser_execute() returns in addition to
332  * error checking.
333  */
334  unsigned int upgrade : 1;
335 
337  void *data; /* A pointer to get hook to the "connection" or "socket" object */
338 };
350  /* When on_chunk_header is called, the current chunk length is stored
351  * in parser->content_length.
352  */
355 };
359  { UF_SCHEMA = 0
360  , UF_HOST = 1
361  , UF_PORT = 2
362  , UF_PATH = 3
363  , UF_QUERY = 4
364  , UF_FRAGMENT = 5
365  , UF_USERINFO = 6
366  , UF_MAX = 7
367  };
368 
369 
370 /* Result structure for http_parser_parse_url().
371  *
372  * Callers should index into field_data[] with UF_* values iff field_set
373  * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
374  * because we probably have padding left over), we convert any port to
375  * a uint16_t.
376  */
377 struct http_parser_url {
378  uint16_t field_set; /* Bitmask of (1 << UF_*) values */
379  uint16_t port; /* Converted UF_PORT string */
381  struct {
382  uint16_t off; /* Offset into buffer in which field starts */
383  uint16_t len; /* Length of run in buffer */
384  } field_data[UF_MAX];
385 };
386 
387 
388 /* Returns the library version. Bits 16-23 contain the major version number,
389  * bits 8-15 the minor version number and bits 0-7 the patch level.
390  * Usage example:
391  *
392  * unsigned long version = http_parser_version();
393  * unsigned major = (version >> 16) & 255;
394  * unsigned minor = (version >> 8) & 255;
395  * unsigned patch = version & 255;
396  * printf("http_parser v%u.%u.%u\n", major, minor, patch);
397  */
398 unsigned long http_parser_version(void);
399 
400 void http_parser_init(http_parser *parser, enum http_parser_type type);
401 
402 
403 /* Initialize http_parser_settings members to 0
404  */
406 
407 
408 /* Executes the parser. Returns number of parsed bytes. Sets
409  * `parser->http_errno` on error. */
410 size_t http_parser_execute(http_parser *parser,
411  const http_parser_settings *settings,
412  const char *data,
413  size_t len);
414 
415 
416 /* If http_should_keep_alive() in the on_headers_complete or
417  * on_message_complete callback returns 0, then this should be
418  * the last message on the connection.
419  * If you are the server, respond with the "Connection: close" header.
420  * If you are the client, close the connection.
421  */
422 int http_should_keep_alive(const http_parser *parser);
423 
424 /* Returns a string version of the HTTP method. */
425 const char *http_method_str(enum http_method m);
426 
427 /* Return a string name of the given error */
428 const char *http_errno_name(enum http_errno err);
429 
430 /* Return a string description of the given error */
431 const char *http_errno_description(enum http_errno err);
432 
433 /* Initialize all http_parser_url members to 0 */
434 void http_parser_url_init(struct http_parser_url *u);
435 
436 /* Parse a URL; return nonzero on failure */
437 int http_parser_parse_url(const char *buf, size_t buflen,
438  int is_connect,
439  struct http_parser_url *u);
440 
441 /* Pause or un-pause the parser; a nonzero value pauses */
442 void http_parser_pause(http_parser *parser, int paused);
443 
444 /* Checks if this is the final chunk of the body. */
445 int http_body_is_final(const http_parser *parser);
446 
447 #ifdef __cplusplus
448 }
449 #endif
450 #endif
uint32_t nread
Definition: http_parser.h:316
#define HTTP_ERRNO_MAP(XX)
Definition: http_parser.h:250
unsigned int method
Definition: http_parser.h:323
flags
Definition: http_parser.h:234
http_data_cb on_header_field
Definition: http_parser.h:342
http_cb on_headers_complete
Definition: http_parser.h:344
unsigned short http_minor
Definition: http_parser.h:321
const char * http_method_str(enum http_method m)
Definition: http_parser.c:2098
#define HTTP_METHOD_MAP(XX)
Definition: http_parser.h:181
uint16_t field_set
Definition: http_parser.h:375
void http_parser_pause(http_parser *parser, int paused)
Definition: http_parser.c:2407
unsigned char uint8_t
Definition: uthash.h:97
http_data_cb on_body
Definition: http_parser.h:345
unsigned int status_code
Definition: http_parser.h:322
unsigned int header_state
Definition: http_parser.h:312
http_data_cb on_url
Definition: http_parser.h:340
unsigned int index
Definition: http_parser.h:313
int(* http_cb)(http_parser *)
Definition: http_parser.h:108
#define XX(num, name, string)
Definition: http_parser.h:225
int(* http_data_cb)(http_parser *, const char *at, size_t length)
Definition: http_parser.h:107
unsigned int lenient_http_headers
Definition: http_parser.h:314
uint64_t content_length
Definition: http_parser.h:317
size_t http_parser_execute(http_parser *parser, const http_parser_settings *settings, const char *data, size_t len)
Definition: http_parser.c:653
http_data_cb on_status
Definition: http_parser.h:341
unsigned short http_major
READ-ONLY.
Definition: http_parser.h:320
#define HTTP_STATUS_MAP(XX)
Definition: http_parser.h:112
int http_parser_parse_url(const char *buf, size_t buflen, int is_connect, struct http_parser_url *u)
Definition: http_parser.c:2303
http_method
Definition: http_parser.h:223
http_parser_type
Definition: http_parser.h:230
http_data_cb on_header_value
Definition: http_parser.h:343
void http_parser_settings_init(http_parser_settings *settings)
Definition: http_parser.c:2116
#define HTTP_ERRNO_GEN(n, s)
Definition: http_parser.h:297
void http_parser_url_init(struct http_parser_url *u)
Definition: http_parser.c:2298
void * data
PUBLIC.
Definition: http_parser.h:334
http_errno
Definition: http_parser.h:298
http_status
Definition: http_parser.h:173
unsigned int upgrade
Definition: http_parser.h:331
const char * http_errno_name(enum http_errno err)
Definition: http_parser.c:2122
int http_should_keep_alive(const http_parser *parser)
Definition: http_parser.c:2079
unsigned int uint32_t
Definition: uthash.h:96
const char * http_errno_description(enum http_errno err)
Definition: http_parser.c:2128
int http_body_is_final(const http_parser *parser)
struct http_parser_url::@1 field_data[UF_MAX]
unsigned int type
PRIVATE.
Definition: http_parser.h:309
http_parser_url_fields
Definition: http_parser.h:355
state
Definition: http_parser.c:298
http_cb on_message_complete
Definition: http_parser.h:346
void http_parser_init(http_parser *parser, enum http_parser_type type)
Definition: http_parser.c:2105
unsigned long http_parser_version(void)
Definition: http_parser.c:2426