http-parser 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,318 +1,318 @@
1
- /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
- *
3
- * Permission is hereby granted, free of charge, to any person obtaining a copy
4
- * of this software and associated documentation files (the "Software"), to
5
- * deal in the Software without restriction, including without limitation the
6
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
- * sell copies of the Software, and to permit persons to whom the Software is
8
- * furnished to do so, subject to the following conditions:
9
- *
10
- * The above copyright notice and this permission notice shall be included in
11
- * all copies or substantial portions of the Software.
12
- *
13
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19
- * IN THE SOFTWARE.
20
- */
21
- #ifndef http_parser_h
22
- #define http_parser_h
23
- #ifdef __cplusplus
24
- extern "C" {
25
- #endif
26
-
27
- /* Also update SONAME in the Makefile whenever you change these. */
28
- #define HTTP_PARSER_VERSION_MAJOR 2
29
- #define HTTP_PARSER_VERSION_MINOR 2
30
- #define HTTP_PARSER_VERSION_PATCH 0
31
-
32
- #include <sys/types.h>
33
- #if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600)
34
- #include <BaseTsd.h>
35
- #include <stddef.h>
36
- typedef __int8 int8_t;
37
- typedef unsigned __int8 uint8_t;
38
- typedef __int16 int16_t;
39
- typedef unsigned __int16 uint16_t;
40
- typedef __int32 int32_t;
41
- typedef unsigned __int32 uint32_t;
42
- typedef __int64 int64_t;
43
- typedef unsigned __int64 uint64_t;
44
- #else
45
- #include <stdint.h>
46
- #endif
47
-
48
- /* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
49
- * faster
50
- */
51
- #ifndef HTTP_PARSER_STRICT
52
- # define HTTP_PARSER_STRICT 1
53
- #endif
54
-
55
- /* Maximium header size allowed */
56
- #define HTTP_MAX_HEADER_SIZE (80*1024)
57
-
58
-
59
- typedef struct http_parser http_parser;
60
- typedef struct http_parser_settings http_parser_settings;
61
-
62
-
63
- /* Callbacks should return non-zero to indicate an error. The parser will
64
- * then halt execution.
65
- *
66
- * The one exception is on_headers_complete. In a HTTP_RESPONSE parser
67
- * returning '1' from on_headers_complete will tell the parser that it
68
- * should not expect a body. This is used when receiving a response to a
69
- * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
70
- * chunked' headers that indicate the presence of a body.
71
- *
72
- * http_data_cb does not return data chunks. It will be call arbitrarally
73
- * many times for each string. E.G. you might get 10 callbacks for "on_url"
74
- * each providing just a few characters more data.
75
- */
76
- typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
77
- typedef int (*http_cb) (http_parser*);
78
-
79
-
80
- /* Request Methods */
81
- #define HTTP_METHOD_MAP(XX) \
82
- XX(0, DELETE, DELETE) \
83
- XX(1, GET, GET) \
84
- XX(2, HEAD, HEAD) \
85
- XX(3, POST, POST) \
86
- XX(4, PUT, PUT) \
87
- /* pathological */ \
88
- XX(5, CONNECT, CONNECT) \
89
- XX(6, OPTIONS, OPTIONS) \
90
- XX(7, TRACE, TRACE) \
91
- /* webdav */ \
92
- XX(8, COPY, COPY) \
93
- XX(9, LOCK, LOCK) \
94
- XX(10, MKCOL, MKCOL) \
95
- XX(11, MOVE, MOVE) \
96
- XX(12, PROPFIND, PROPFIND) \
97
- XX(13, PROPPATCH, PROPPATCH) \
98
- XX(14, SEARCH, SEARCH) \
99
- XX(15, UNLOCK, UNLOCK) \
100
- /* subversion */ \
101
- XX(16, REPORT, REPORT) \
102
- XX(17, MKACTIVITY, MKACTIVITY) \
103
- XX(18, CHECKOUT, CHECKOUT) \
104
- XX(19, MERGE, MERGE) \
105
- /* upnp */ \
106
- XX(20, MSEARCH, M-SEARCH) \
107
- XX(21, NOTIFY, NOTIFY) \
108
- XX(22, SUBSCRIBE, SUBSCRIBE) \
109
- XX(23, UNSUBSCRIBE, UNSUBSCRIBE) \
110
- /* RFC-5789 */ \
111
- XX(24, PATCH, PATCH) \
112
- XX(25, PURGE, PURGE) \
113
-
114
- enum http_method
115
- {
116
- #define XX(num, name, string) HTTP_##name = num,
117
- HTTP_METHOD_MAP(XX)
118
- #undef XX
119
- };
120
-
121
-
122
- enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
123
-
124
-
125
- /* Flag values for http_parser.flags field */
126
- enum flags
127
- { F_CHUNKED = 1 << 0
128
- , F_CONNECTION_KEEP_ALIVE = 1 << 1
129
- , F_CONNECTION_CLOSE = 1 << 2
130
- , F_TRAILING = 1 << 3
131
- , F_UPGRADE = 1 << 4
132
- , F_SKIPBODY = 1 << 5
133
- };
134
-
135
-
136
- /* Map for errno-related constants
137
- *
138
- * The provided argument should be a macro that takes 2 arguments.
139
- */
140
- #define HTTP_ERRNO_MAP(XX) \
141
- /* No error */ \
142
- XX(OK, "success") \
143
- \
144
- /* Callback-related errors */ \
145
- XX(CB_message_begin, "the on_message_begin callback failed") \
146
- XX(CB_url, "the on_url callback failed") \
147
- XX(CB_header_field, "the on_header_field callback failed") \
148
- XX(CB_header_value, "the on_header_value callback failed") \
149
- XX(CB_headers_complete, "the on_headers_complete callback failed") \
150
- XX(CB_body, "the on_body callback failed") \
151
- XX(CB_message_complete, "the on_message_complete callback failed") \
152
- XX(CB_status, "the on_status callback failed") \
153
- \
154
- /* Parsing-related errors */ \
155
- XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
156
- XX(HEADER_OVERFLOW, \
157
- "too many header bytes seen; overflow detected") \
158
- XX(CLOSED_CONNECTION, \
159
- "data received after completed connection: close message") \
160
- XX(INVALID_VERSION, "invalid HTTP version") \
161
- XX(INVALID_STATUS, "invalid HTTP status code") \
162
- XX(INVALID_METHOD, "invalid HTTP method") \
163
- XX(INVALID_URL, "invalid URL") \
164
- XX(INVALID_HOST, "invalid host") \
165
- XX(INVALID_PORT, "invalid port") \
166
- XX(INVALID_PATH, "invalid path") \
167
- XX(INVALID_QUERY_STRING, "invalid query string") \
168
- XX(INVALID_FRAGMENT, "invalid fragment") \
169
- XX(LF_EXPECTED, "LF character expected") \
170
- XX(INVALID_HEADER_TOKEN, "invalid character in header") \
171
- XX(INVALID_CONTENT_LENGTH, \
172
- "invalid character in content-length header") \
173
- XX(INVALID_CHUNK_SIZE, \
174
- "invalid character in chunk size header") \
175
- XX(INVALID_CONSTANT, "invalid constant string") \
176
- XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
177
- XX(STRICT, "strict mode assertion failed") \
178
- XX(PAUSED, "parser is paused") \
179
- XX(UNKNOWN, "an unknown error occurred")
180
-
181
-
182
- /* Define HPE_* values for each errno value above */
183
- #define HTTP_ERRNO_GEN(n, s) HPE_##n,
184
- enum http_errno {
185
- HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
186
- };
187
- #undef HTTP_ERRNO_GEN
188
-
189
-
190
- /* Get an http_errno value from an http_parser */
191
- #define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
192
-
193
-
194
- struct http_parser {
195
- /** PRIVATE **/
196
- unsigned int type : 2; /* enum http_parser_type */
197
- unsigned int flags : 6; /* F_* values from 'flags' enum; semi-public */
198
- unsigned int state : 8; /* enum state from http_parser.c */
199
- unsigned int header_state : 8; /* enum header_state from http_parser.c */
200
- unsigned int index : 8; /* index into current matcher */
201
-
202
- uint32_t nread; /* # bytes read in various scenarios */
203
- uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
204
-
205
- /** READ-ONLY **/
206
- unsigned short http_major;
207
- unsigned short http_minor;
208
- unsigned int status_code : 16; /* responses only */
209
- unsigned int method : 8; /* requests only */
210
- unsigned int http_errno : 7;
211
-
212
- /* 1 = Upgrade header was present and the parser has exited because of that.
213
- * 0 = No upgrade header present.
214
- * Should be checked when http_parser_execute() returns in addition to
215
- * error checking.
216
- */
217
- unsigned int upgrade : 1;
218
-
219
- /** PUBLIC **/
220
- void *data; /* A pointer to get hook to the "connection" or "socket" object */
221
- };
222
-
223
-
224
- struct http_parser_settings {
225
- http_cb on_message_begin;
226
- http_data_cb on_url;
227
- http_data_cb on_status;
228
- http_data_cb on_header_field;
229
- http_data_cb on_header_value;
230
- http_cb on_headers_complete;
231
- http_data_cb on_body;
232
- http_cb on_message_complete;
233
- };
234
-
235
-
236
- enum http_parser_url_fields
237
- { UF_SCHEMA = 0
238
- , UF_HOST = 1
239
- , UF_PORT = 2
240
- , UF_PATH = 3
241
- , UF_QUERY = 4
242
- , UF_FRAGMENT = 5
243
- , UF_USERINFO = 6
244
- , UF_MAX = 7
245
- };
246
-
247
-
248
- /* Result structure for http_parser_parse_url().
249
- *
250
- * Callers should index into field_data[] with UF_* values iff field_set
251
- * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
252
- * because we probably have padding left over), we convert any port to
253
- * a uint16_t.
254
- */
255
- struct http_parser_url {
256
- uint16_t field_set; /* Bitmask of (1 << UF_*) values */
257
- uint16_t port; /* Converted UF_PORT string */
258
-
259
- struct {
260
- uint16_t off; /* Offset into buffer in which field starts */
261
- uint16_t len; /* Length of run in buffer */
262
- } field_data[UF_MAX];
263
- };
264
-
265
-
266
- /* Returns the library version. Bits 16-23 contain the major version number,
267
- * bits 8-15 the minor version number and bits 0-7 the patch level.
268
- * Usage example:
269
- *
270
- * unsigned long version = http_parser_version();
271
- * unsigned major = (version >> 16) & 255;
272
- * unsigned minor = (version >> 8) & 255;
273
- * unsigned patch = version & 255;
274
- * printf("http_parser v%u.%u.%u\n", major, minor, version);
275
- */
276
- unsigned long http_parser_version(void);
277
-
278
- void http_parser_init(http_parser *parser, enum http_parser_type type);
279
-
280
-
281
- size_t http_parser_execute(http_parser *parser,
282
- const http_parser_settings *settings,
283
- const char *data,
284
- size_t len);
285
-
286
-
287
- /* If http_should_keep_alive() in the on_headers_complete or
288
- * on_message_complete callback returns 0, then this should be
289
- * the last message on the connection.
290
- * If you are the server, respond with the "Connection: close" header.
291
- * If you are the client, close the connection.
292
- */
293
- int http_should_keep_alive(const http_parser *parser);
294
-
295
- /* Returns a string version of the HTTP method. */
296
- const char *http_method_str(enum http_method m);
297
-
298
- /* Return a string name of the given error */
299
- const char *http_errno_name(enum http_errno err);
300
-
301
- /* Return a string description of the given error */
302
- const char *http_errno_description(enum http_errno err);
303
-
304
- /* Parse a URL; return nonzero on failure */
305
- int http_parser_parse_url(const char *buf, size_t buflen,
306
- int is_connect,
307
- struct http_parser_url *u);
308
-
309
- /* Pause or un-pause the parser; a nonzero value pauses */
310
- void http_parser_pause(http_parser *parser, int paused);
311
-
312
- /* Checks if this is the final chunk of the body. */
313
- int http_body_is_final(const http_parser *parser);
314
-
315
- #ifdef __cplusplus
316
- }
317
- #endif
318
- #endif
1
+ /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to
5
+ * deal in the Software without restriction, including without limitation the
6
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ * sell copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in
11
+ * all copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19
+ * IN THE SOFTWARE.
20
+ */
21
+ #ifndef http_parser_h
22
+ #define http_parser_h
23
+ #ifdef __cplusplus
24
+ extern "C" {
25
+ #endif
26
+
27
+ /* Also update SONAME in the Makefile whenever you change these. */
28
+ #define HTTP_PARSER_VERSION_MAJOR 2
29
+ #define HTTP_PARSER_VERSION_MINOR 2
30
+ #define HTTP_PARSER_VERSION_PATCH 1
31
+
32
+ #include <sys/types.h>
33
+ #if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600)
34
+ #include <BaseTsd.h>
35
+ #include <stddef.h>
36
+ typedef __int8 int8_t;
37
+ typedef unsigned __int8 uint8_t;
38
+ typedef __int16 int16_t;
39
+ typedef unsigned __int16 uint16_t;
40
+ typedef __int32 int32_t;
41
+ typedef unsigned __int32 uint32_t;
42
+ typedef __int64 int64_t;
43
+ typedef unsigned __int64 uint64_t;
44
+ #else
45
+ #include <stdint.h>
46
+ #endif
47
+
48
+ /* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
49
+ * faster
50
+ */
51
+ #ifndef HTTP_PARSER_STRICT
52
+ # define HTTP_PARSER_STRICT 1
53
+ #endif
54
+
55
+ /* Maximium header size allowed */
56
+ #define HTTP_MAX_HEADER_SIZE (80*1024)
57
+
58
+
59
+ typedef struct http_parser http_parser;
60
+ typedef struct http_parser_settings http_parser_settings;
61
+
62
+
63
+ /* Callbacks should return non-zero to indicate an error. The parser will
64
+ * then halt execution.
65
+ *
66
+ * The one exception is on_headers_complete. In a HTTP_RESPONSE parser
67
+ * returning '1' from on_headers_complete will tell the parser that it
68
+ * should not expect a body. This is used when receiving a response to a
69
+ * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
70
+ * chunked' headers that indicate the presence of a body.
71
+ *
72
+ * http_data_cb does not return data chunks. It will be call arbitrarally
73
+ * many times for each string. E.G. you might get 10 callbacks for "on_url"
74
+ * each providing just a few characters more data.
75
+ */
76
+ typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
77
+ typedef int (*http_cb) (http_parser*);
78
+
79
+
80
+ /* Request Methods */
81
+ #define HTTP_METHOD_MAP(XX) \
82
+ XX(0, DELETE, DELETE) \
83
+ XX(1, GET, GET) \
84
+ XX(2, HEAD, HEAD) \
85
+ XX(3, POST, POST) \
86
+ XX(4, PUT, PUT) \
87
+ /* pathological */ \
88
+ XX(5, CONNECT, CONNECT) \
89
+ XX(6, OPTIONS, OPTIONS) \
90
+ XX(7, TRACE, TRACE) \
91
+ /* webdav */ \
92
+ XX(8, COPY, COPY) \
93
+ XX(9, LOCK, LOCK) \
94
+ XX(10, MKCOL, MKCOL) \
95
+ XX(11, MOVE, MOVE) \
96
+ XX(12, PROPFIND, PROPFIND) \
97
+ XX(13, PROPPATCH, PROPPATCH) \
98
+ XX(14, SEARCH, SEARCH) \
99
+ XX(15, UNLOCK, UNLOCK) \
100
+ /* subversion */ \
101
+ XX(16, REPORT, REPORT) \
102
+ XX(17, MKACTIVITY, MKACTIVITY) \
103
+ XX(18, CHECKOUT, CHECKOUT) \
104
+ XX(19, MERGE, MERGE) \
105
+ /* upnp */ \
106
+ XX(20, MSEARCH, M-SEARCH) \
107
+ XX(21, NOTIFY, NOTIFY) \
108
+ XX(22, SUBSCRIBE, SUBSCRIBE) \
109
+ XX(23, UNSUBSCRIBE, UNSUBSCRIBE) \
110
+ /* RFC-5789 */ \
111
+ XX(24, PATCH, PATCH) \
112
+ XX(25, PURGE, PURGE) \
113
+
114
+ enum http_method
115
+ {
116
+ #define XX(num, name, string) HTTP_##name = num,
117
+ HTTP_METHOD_MAP(XX)
118
+ #undef XX
119
+ };
120
+
121
+
122
+ enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
123
+
124
+
125
+ /* Flag values for http_parser.flags field */
126
+ enum flags
127
+ { F_CHUNKED = 1 << 0
128
+ , F_CONNECTION_KEEP_ALIVE = 1 << 1
129
+ , F_CONNECTION_CLOSE = 1 << 2
130
+ , F_TRAILING = 1 << 3
131
+ , F_UPGRADE = 1 << 4
132
+ , F_SKIPBODY = 1 << 5
133
+ };
134
+
135
+
136
+ /* Map for errno-related constants
137
+ *
138
+ * The provided argument should be a macro that takes 2 arguments.
139
+ */
140
+ #define HTTP_ERRNO_MAP(XX) \
141
+ /* No error */ \
142
+ XX(OK, "success") \
143
+ \
144
+ /* Callback-related errors */ \
145
+ XX(CB_message_begin, "the on_message_begin callback failed") \
146
+ XX(CB_url, "the on_url callback failed") \
147
+ XX(CB_header_field, "the on_header_field callback failed") \
148
+ XX(CB_header_value, "the on_header_value callback failed") \
149
+ XX(CB_headers_complete, "the on_headers_complete callback failed") \
150
+ XX(CB_body, "the on_body callback failed") \
151
+ XX(CB_message_complete, "the on_message_complete callback failed") \
152
+ XX(CB_status, "the on_status callback failed") \
153
+ \
154
+ /* Parsing-related errors */ \
155
+ XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
156
+ XX(HEADER_OVERFLOW, \
157
+ "too many header bytes seen; overflow detected") \
158
+ XX(CLOSED_CONNECTION, \
159
+ "data received after completed connection: close message") \
160
+ XX(INVALID_VERSION, "invalid HTTP version") \
161
+ XX(INVALID_STATUS, "invalid HTTP status code") \
162
+ XX(INVALID_METHOD, "invalid HTTP method") \
163
+ XX(INVALID_URL, "invalid URL") \
164
+ XX(INVALID_HOST, "invalid host") \
165
+ XX(INVALID_PORT, "invalid port") \
166
+ XX(INVALID_PATH, "invalid path") \
167
+ XX(INVALID_QUERY_STRING, "invalid query string") \
168
+ XX(INVALID_FRAGMENT, "invalid fragment") \
169
+ XX(LF_EXPECTED, "LF character expected") \
170
+ XX(INVALID_HEADER_TOKEN, "invalid character in header") \
171
+ XX(INVALID_CONTENT_LENGTH, \
172
+ "invalid character in content-length header") \
173
+ XX(INVALID_CHUNK_SIZE, \
174
+ "invalid character in chunk size header") \
175
+ XX(INVALID_CONSTANT, "invalid constant string") \
176
+ XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
177
+ XX(STRICT, "strict mode assertion failed") \
178
+ XX(PAUSED, "parser is paused") \
179
+ XX(UNKNOWN, "an unknown error occurred")
180
+
181
+
182
+ /* Define HPE_* values for each errno value above */
183
+ #define HTTP_ERRNO_GEN(n, s) HPE_##n,
184
+ enum http_errno {
185
+ HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
186
+ };
187
+ #undef HTTP_ERRNO_GEN
188
+
189
+
190
+ /* Get an http_errno value from an http_parser */
191
+ #define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
192
+
193
+
194
+ struct http_parser {
195
+ /** PRIVATE **/
196
+ unsigned int type : 2; /* enum http_parser_type */
197
+ unsigned int flags : 6; /* F_* values from 'flags' enum; semi-public */
198
+ unsigned int state : 8; /* enum state from http_parser.c */
199
+ unsigned int header_state : 8; /* enum header_state from http_parser.c */
200
+ unsigned int index : 8; /* index into current matcher */
201
+
202
+ uint32_t nread; /* # bytes read in various scenarios */
203
+ uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
204
+
205
+ /** READ-ONLY **/
206
+ unsigned short http_major;
207
+ unsigned short http_minor;
208
+ unsigned int status_code : 16; /* responses only */
209
+ unsigned int method : 8; /* requests only */
210
+ unsigned int http_errno : 7;
211
+
212
+ /* 1 = Upgrade header was present and the parser has exited because of that.
213
+ * 0 = No upgrade header present.
214
+ * Should be checked when http_parser_execute() returns in addition to
215
+ * error checking.
216
+ */
217
+ unsigned int upgrade : 1;
218
+
219
+ /** PUBLIC **/
220
+ void *data; /* A pointer to get hook to the "connection" or "socket" object */
221
+ };
222
+
223
+
224
+ struct http_parser_settings {
225
+ http_cb on_message_begin;
226
+ http_data_cb on_url;
227
+ http_data_cb on_status;
228
+ http_data_cb on_header_field;
229
+ http_data_cb on_header_value;
230
+ http_cb on_headers_complete;
231
+ http_data_cb on_body;
232
+ http_cb on_message_complete;
233
+ };
234
+
235
+
236
+ enum http_parser_url_fields
237
+ { UF_SCHEMA = 0
238
+ , UF_HOST = 1
239
+ , UF_PORT = 2
240
+ , UF_PATH = 3
241
+ , UF_QUERY = 4
242
+ , UF_FRAGMENT = 5
243
+ , UF_USERINFO = 6
244
+ , UF_MAX = 7
245
+ };
246
+
247
+
248
+ /* Result structure for http_parser_parse_url().
249
+ *
250
+ * Callers should index into field_data[] with UF_* values iff field_set
251
+ * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
252
+ * because we probably have padding left over), we convert any port to
253
+ * a uint16_t.
254
+ */
255
+ struct http_parser_url {
256
+ uint16_t field_set; /* Bitmask of (1 << UF_*) values */
257
+ uint16_t port; /* Converted UF_PORT string */
258
+
259
+ struct {
260
+ uint16_t off; /* Offset into buffer in which field starts */
261
+ uint16_t len; /* Length of run in buffer */
262
+ } field_data[UF_MAX];
263
+ };
264
+
265
+
266
+ /* Returns the library version. Bits 16-23 contain the major version number,
267
+ * bits 8-15 the minor version number and bits 0-7 the patch level.
268
+ * Usage example:
269
+ *
270
+ * unsigned long version = http_parser_version();
271
+ * unsigned major = (version >> 16) & 255;
272
+ * unsigned minor = (version >> 8) & 255;
273
+ * unsigned patch = version & 255;
274
+ * printf("http_parser v%u.%u.%u\n", major, minor, version);
275
+ */
276
+ unsigned long http_parser_version(void);
277
+
278
+ void http_parser_init(http_parser *parser, enum http_parser_type type);
279
+
280
+
281
+ size_t http_parser_execute(http_parser *parser,
282
+ const http_parser_settings *settings,
283
+ const char *data,
284
+ size_t len);
285
+
286
+
287
+ /* If http_should_keep_alive() in the on_headers_complete or
288
+ * on_message_complete callback returns 0, then this should be
289
+ * the last message on the connection.
290
+ * If you are the server, respond with the "Connection: close" header.
291
+ * If you are the client, close the connection.
292
+ */
293
+ int http_should_keep_alive(const http_parser *parser);
294
+
295
+ /* Returns a string version of the HTTP method. */
296
+ const char *http_method_str(enum http_method m);
297
+
298
+ /* Return a string name of the given error */
299
+ const char *http_errno_name(enum http_errno err);
300
+
301
+ /* Return a string description of the given error */
302
+ const char *http_errno_description(enum http_errno err);
303
+
304
+ /* Parse a URL; return nonzero on failure */
305
+ int http_parser_parse_url(const char *buf, size_t buflen,
306
+ int is_connect,
307
+ struct http_parser_url *u);
308
+
309
+ /* Pause or un-pause the parser; a nonzero value pauses */
310
+ void http_parser_pause(http_parser *parser, int paused);
311
+
312
+ /* Checks if this is the final chunk of the body. */
313
+ int http_body_is_final(const http_parser *parser);
314
+
315
+ #ifdef __cplusplus
316
+ }
317
+ #endif
318
+ #endif