1 | |
2 | #ifndef INCLUDE_LLHTTP_H_ |
3 | #define INCLUDE_LLHTTP_H_ |
4 | |
5 | #define LLHTTP_VERSION_MAJOR 9 |
6 | #define LLHTTP_VERSION_MINOR 1 |
7 | #define LLHTTP_VERSION_PATCH 3 |
8 | |
9 | #ifndef INCLUDE_LLHTTP_ITSELF_H_ |
10 | #define INCLUDE_LLHTTP_ITSELF_H_ |
11 | #ifdef __cplusplus |
12 | extern "C" { |
13 | #endif |
14 | |
15 | #include <stdint.h> |
16 | |
17 | typedef struct llhttp__internal_s llhttp__internal_t; |
18 | struct llhttp__internal_s { |
19 | int32_t _index; |
20 | void* _span_pos0; |
21 | void* _span_cb0; |
22 | int32_t error; |
23 | const char* reason; |
24 | const char* error_pos; |
25 | void* data; |
26 | void* _current; |
27 | uint64_t content_length; |
28 | uint8_t type; |
29 | uint8_t method; |
30 | uint8_t http_major; |
31 | uint8_t http_minor; |
32 | uint8_t ; |
33 | uint16_t lenient_flags; |
34 | uint8_t upgrade; |
35 | uint8_t finish; |
36 | uint16_t flags; |
37 | uint16_t status_code; |
38 | uint8_t initial_message_completed; |
39 | void* settings; |
40 | }; |
41 | |
42 | int llhttp__internal_init(llhttp__internal_t* s); |
43 | int llhttp__internal_execute(llhttp__internal_t* s, const char* p, const char* endp); |
44 | |
45 | #ifdef __cplusplus |
46 | } /* extern "C" */ |
47 | #endif |
48 | #endif /* INCLUDE_LLHTTP_ITSELF_H_ */ |
49 | |
50 | |
51 | #ifndef LLLLHTTP_C_HEADERS_ |
52 | #define |
53 | #ifdef __cplusplus |
54 | extern "C" { |
55 | #endif |
56 | |
57 | enum llhttp_errno { |
58 | HPE_OK = 0, |
59 | HPE_INTERNAL = 1, |
60 | HPE_STRICT = 2, |
61 | HPE_CR_EXPECTED = 25, |
62 | HPE_LF_EXPECTED = 3, |
63 | HPE_UNEXPECTED_CONTENT_LENGTH = 4, |
64 | HPE_UNEXPECTED_SPACE = 30, |
65 | HPE_CLOSED_CONNECTION = 5, |
66 | HPE_INVALID_METHOD = 6, |
67 | HPE_INVALID_URL = 7, |
68 | HPE_INVALID_CONSTANT = 8, |
69 | HPE_INVALID_VERSION = 9, |
70 | = 10, |
71 | HPE_INVALID_CONTENT_LENGTH = 11, |
72 | HPE_INVALID_CHUNK_SIZE = 12, |
73 | HPE_INVALID_STATUS = 13, |
74 | HPE_INVALID_EOF_STATE = 14, |
75 | HPE_INVALID_TRANSFER_ENCODING = 15, |
76 | HPE_CB_MESSAGE_BEGIN = 16, |
77 | = 17, |
78 | HPE_CB_MESSAGE_COMPLETE = 18, |
79 | = 19, |
80 | HPE_CB_CHUNK_COMPLETE = 20, |
81 | HPE_PAUSED = 21, |
82 | HPE_PAUSED_UPGRADE = 22, |
83 | HPE_PAUSED_H2_UPGRADE = 23, |
84 | HPE_USER = 24, |
85 | HPE_CB_URL_COMPLETE = 26, |
86 | HPE_CB_STATUS_COMPLETE = 27, |
87 | HPE_CB_METHOD_COMPLETE = 32, |
88 | HPE_CB_VERSION_COMPLETE = 33, |
89 | = 28, |
90 | = 29, |
91 | HPE_CB_CHUNK_EXTENSION_NAME_COMPLETE = 34, |
92 | HPE_CB_CHUNK_EXTENSION_VALUE_COMPLETE = 35, |
93 | HPE_CB_RESET = 31 |
94 | }; |
95 | typedef enum llhttp_errno llhttp_errno_t; |
96 | |
97 | enum llhttp_flags { |
98 | F_CONNECTION_KEEP_ALIVE = 0x1, |
99 | F_CONNECTION_CLOSE = 0x2, |
100 | F_CONNECTION_UPGRADE = 0x4, |
101 | F_CHUNKED = 0x8, |
102 | F_UPGRADE = 0x10, |
103 | F_CONTENT_LENGTH = 0x20, |
104 | F_SKIPBODY = 0x40, |
105 | F_TRAILING = 0x80, |
106 | F_TRANSFER_ENCODING = 0x200 |
107 | }; |
108 | typedef enum llhttp_flags llhttp_flags_t; |
109 | |
110 | enum llhttp_lenient_flags { |
111 | = 0x1, |
112 | LENIENT_CHUNKED_LENGTH = 0x2, |
113 | LENIENT_KEEP_ALIVE = 0x4, |
114 | LENIENT_TRANSFER_ENCODING = 0x8, |
115 | LENIENT_VERSION = 0x10, |
116 | LENIENT_DATA_AFTER_CLOSE = 0x20, |
117 | LENIENT_OPTIONAL_LF_AFTER_CR = 0x40, |
118 | LENIENT_OPTIONAL_CRLF_AFTER_CHUNK = 0x80, |
119 | LENIENT_OPTIONAL_CR_BEFORE_LF = 0x100, |
120 | LENIENT_SPACES_AFTER_CHUNK_SIZE = 0x200 |
121 | }; |
122 | typedef enum llhttp_lenient_flags llhttp_lenient_flags_t; |
123 | |
124 | enum llhttp_type { |
125 | HTTP_BOTH = 0, |
126 | HTTP_REQUEST = 1, |
127 | HTTP_RESPONSE = 2 |
128 | }; |
129 | typedef enum llhttp_type llhttp_type_t; |
130 | |
131 | enum llhttp_finish { |
132 | HTTP_FINISH_SAFE = 0, |
133 | HTTP_FINISH_SAFE_WITH_CB = 1, |
134 | HTTP_FINISH_UNSAFE = 2 |
135 | }; |
136 | typedef enum llhttp_finish llhttp_finish_t; |
137 | |
138 | enum llhttp_method { |
139 | HTTP_DELETE = 0, |
140 | HTTP_GET = 1, |
141 | HTTP_HEAD = 2, |
142 | HTTP_POST = 3, |
143 | HTTP_PUT = 4, |
144 | HTTP_CONNECT = 5, |
145 | HTTP_OPTIONS = 6, |
146 | HTTP_TRACE = 7, |
147 | HTTP_COPY = 8, |
148 | HTTP_LOCK = 9, |
149 | HTTP_MKCOL = 10, |
150 | HTTP_MOVE = 11, |
151 | HTTP_PROPFIND = 12, |
152 | HTTP_PROPPATCH = 13, |
153 | HTTP_SEARCH = 14, |
154 | HTTP_UNLOCK = 15, |
155 | HTTP_BIND = 16, |
156 | HTTP_REBIND = 17, |
157 | HTTP_UNBIND = 18, |
158 | HTTP_ACL = 19, |
159 | HTTP_REPORT = 20, |
160 | HTTP_MKACTIVITY = 21, |
161 | HTTP_CHECKOUT = 22, |
162 | HTTP_MERGE = 23, |
163 | HTTP_MSEARCH = 24, |
164 | HTTP_NOTIFY = 25, |
165 | HTTP_SUBSCRIBE = 26, |
166 | HTTP_UNSUBSCRIBE = 27, |
167 | HTTP_PATCH = 28, |
168 | HTTP_PURGE = 29, |
169 | HTTP_MKCALENDAR = 30, |
170 | HTTP_LINK = 31, |
171 | HTTP_UNLINK = 32, |
172 | HTTP_SOURCE = 33, |
173 | HTTP_PRI = 34, |
174 | HTTP_DESCRIBE = 35, |
175 | HTTP_ANNOUNCE = 36, |
176 | HTTP_SETUP = 37, |
177 | HTTP_PLAY = 38, |
178 | HTTP_PAUSE = 39, |
179 | HTTP_TEARDOWN = 40, |
180 | HTTP_GET_PARAMETER = 41, |
181 | HTTP_SET_PARAMETER = 42, |
182 | HTTP_REDIRECT = 43, |
183 | HTTP_RECORD = 44, |
184 | HTTP_FLUSH = 45 |
185 | }; |
186 | typedef enum llhttp_method llhttp_method_t; |
187 | |
188 | enum llhttp_status { |
189 | HTTP_STATUS_CONTINUE = 100, |
190 | HTTP_STATUS_SWITCHING_PROTOCOLS = 101, |
191 | HTTP_STATUS_PROCESSING = 102, |
192 | HTTP_STATUS_EARLY_HINTS = 103, |
193 | HTTP_STATUS_RESPONSE_IS_STALE = 110, |
194 | HTTP_STATUS_REVALIDATION_FAILED = 111, |
195 | HTTP_STATUS_DISCONNECTED_OPERATION = 112, |
196 | HTTP_STATUS_HEURISTIC_EXPIRATION = 113, |
197 | HTTP_STATUS_MISCELLANEOUS_WARNING = 199, |
198 | HTTP_STATUS_OK = 200, |
199 | HTTP_STATUS_CREATED = 201, |
200 | HTTP_STATUS_ACCEPTED = 202, |
201 | HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203, |
202 | HTTP_STATUS_NO_CONTENT = 204, |
203 | HTTP_STATUS_RESET_CONTENT = 205, |
204 | HTTP_STATUS_PARTIAL_CONTENT = 206, |
205 | HTTP_STATUS_MULTI_STATUS = 207, |
206 | HTTP_STATUS_ALREADY_REPORTED = 208, |
207 | HTTP_STATUS_TRANSFORMATION_APPLIED = 214, |
208 | HTTP_STATUS_IM_USED = 226, |
209 | HTTP_STATUS_MISCELLANEOUS_PERSISTENT_WARNING = 299, |
210 | HTTP_STATUS_MULTIPLE_CHOICES = 300, |
211 | HTTP_STATUS_MOVED_PERMANENTLY = 301, |
212 | HTTP_STATUS_FOUND = 302, |
213 | HTTP_STATUS_SEE_OTHER = 303, |
214 | HTTP_STATUS_NOT_MODIFIED = 304, |
215 | HTTP_STATUS_USE_PROXY = 305, |
216 | HTTP_STATUS_SWITCH_PROXY = 306, |
217 | HTTP_STATUS_TEMPORARY_REDIRECT = 307, |
218 | HTTP_STATUS_PERMANENT_REDIRECT = 308, |
219 | HTTP_STATUS_BAD_REQUEST = 400, |
220 | HTTP_STATUS_UNAUTHORIZED = 401, |
221 | HTTP_STATUS_PAYMENT_REQUIRED = 402, |
222 | HTTP_STATUS_FORBIDDEN = 403, |
223 | HTTP_STATUS_NOT_FOUND = 404, |
224 | HTTP_STATUS_METHOD_NOT_ALLOWED = 405, |
225 | HTTP_STATUS_NOT_ACCEPTABLE = 406, |
226 | HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407, |
227 | HTTP_STATUS_REQUEST_TIMEOUT = 408, |
228 | HTTP_STATUS_CONFLICT = 409, |
229 | HTTP_STATUS_GONE = 410, |
230 | HTTP_STATUS_LENGTH_REQUIRED = 411, |
231 | HTTP_STATUS_PRECONDITION_FAILED = 412, |
232 | HTTP_STATUS_PAYLOAD_TOO_LARGE = 413, |
233 | HTTP_STATUS_URI_TOO_LONG = 414, |
234 | HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415, |
235 | HTTP_STATUS_RANGE_NOT_SATISFIABLE = 416, |
236 | HTTP_STATUS_EXPECTATION_FAILED = 417, |
237 | HTTP_STATUS_IM_A_TEAPOT = 418, |
238 | HTTP_STATUS_PAGE_EXPIRED = 419, |
239 | HTTP_STATUS_ENHANCE_YOUR_CALM = 420, |
240 | HTTP_STATUS_MISDIRECTED_REQUEST = 421, |
241 | HTTP_STATUS_UNPROCESSABLE_ENTITY = 422, |
242 | HTTP_STATUS_LOCKED = 423, |
243 | HTTP_STATUS_FAILED_DEPENDENCY = 424, |
244 | HTTP_STATUS_TOO_EARLY = 425, |
245 | HTTP_STATUS_UPGRADE_REQUIRED = 426, |
246 | HTTP_STATUS_PRECONDITION_REQUIRED = 428, |
247 | HTTP_STATUS_TOO_MANY_REQUESTS = 429, |
248 | = 430, |
249 | = 431, |
250 | HTTP_STATUS_LOGIN_TIMEOUT = 440, |
251 | HTTP_STATUS_NO_RESPONSE = 444, |
252 | HTTP_STATUS_RETRY_WITH = 449, |
253 | HTTP_STATUS_BLOCKED_BY_PARENTAL_CONTROL = 450, |
254 | HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451, |
255 | HTTP_STATUS_CLIENT_CLOSED_LOAD_BALANCED_REQUEST = 460, |
256 | HTTP_STATUS_INVALID_X_FORWARDED_FOR = 463, |
257 | = 494, |
258 | HTTP_STATUS_SSL_CERTIFICATE_ERROR = 495, |
259 | HTTP_STATUS_SSL_CERTIFICATE_REQUIRED = 496, |
260 | HTTP_STATUS_HTTP_REQUEST_SENT_TO_HTTPS_PORT = 497, |
261 | HTTP_STATUS_INVALID_TOKEN = 498, |
262 | HTTP_STATUS_CLIENT_CLOSED_REQUEST = 499, |
263 | HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, |
264 | HTTP_STATUS_NOT_IMPLEMENTED = 501, |
265 | HTTP_STATUS_BAD_GATEWAY = 502, |
266 | HTTP_STATUS_SERVICE_UNAVAILABLE = 503, |
267 | HTTP_STATUS_GATEWAY_TIMEOUT = 504, |
268 | HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505, |
269 | HTTP_STATUS_VARIANT_ALSO_NEGOTIATES = 506, |
270 | HTTP_STATUS_INSUFFICIENT_STORAGE = 507, |
271 | HTTP_STATUS_LOOP_DETECTED = 508, |
272 | HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED = 509, |
273 | HTTP_STATUS_NOT_EXTENDED = 510, |
274 | HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511, |
275 | HTTP_STATUS_WEB_SERVER_UNKNOWN_ERROR = 520, |
276 | HTTP_STATUS_WEB_SERVER_IS_DOWN = 521, |
277 | HTTP_STATUS_CONNECTION_TIMEOUT = 522, |
278 | HTTP_STATUS_ORIGIN_IS_UNREACHABLE = 523, |
279 | HTTP_STATUS_TIMEOUT_OCCURED = 524, |
280 | HTTP_STATUS_SSL_HANDSHAKE_FAILED = 525, |
281 | HTTP_STATUS_INVALID_SSL_CERTIFICATE = 526, |
282 | HTTP_STATUS_RAILGUN_ERROR = 527, |
283 | HTTP_STATUS_SITE_IS_OVERLOADED = 529, |
284 | HTTP_STATUS_SITE_IS_FROZEN = 530, |
285 | HTTP_STATUS_IDENTITY_PROVIDER_AUTHENTICATION_ERROR = 561, |
286 | HTTP_STATUS_NETWORK_READ_TIMEOUT = 598, |
287 | HTTP_STATUS_NETWORK_CONNECT_TIMEOUT = 599 |
288 | }; |
289 | typedef enum llhttp_status llhttp_status_t; |
290 | |
291 | #define HTTP_ERRNO_MAP(XX) \ |
292 | XX(0, OK, OK) \ |
293 | XX(1, INTERNAL, INTERNAL) \ |
294 | XX(2, STRICT, STRICT) \ |
295 | XX(25, CR_EXPECTED, CR_EXPECTED) \ |
296 | XX(3, LF_EXPECTED, LF_EXPECTED) \ |
297 | XX(4, UNEXPECTED_CONTENT_LENGTH, UNEXPECTED_CONTENT_LENGTH) \ |
298 | XX(30, UNEXPECTED_SPACE, UNEXPECTED_SPACE) \ |
299 | XX(5, CLOSED_CONNECTION, CLOSED_CONNECTION) \ |
300 | XX(6, INVALID_METHOD, INVALID_METHOD) \ |
301 | XX(7, INVALID_URL, INVALID_URL) \ |
302 | XX(8, INVALID_CONSTANT, INVALID_CONSTANT) \ |
303 | XX(9, INVALID_VERSION, INVALID_VERSION) \ |
304 | XX(10, INVALID_HEADER_TOKEN, INVALID_HEADER_TOKEN) \ |
305 | XX(11, INVALID_CONTENT_LENGTH, INVALID_CONTENT_LENGTH) \ |
306 | XX(12, INVALID_CHUNK_SIZE, INVALID_CHUNK_SIZE) \ |
307 | XX(13, INVALID_STATUS, INVALID_STATUS) \ |
308 | XX(14, INVALID_EOF_STATE, INVALID_EOF_STATE) \ |
309 | XX(15, INVALID_TRANSFER_ENCODING, INVALID_TRANSFER_ENCODING) \ |
310 | XX(16, CB_MESSAGE_BEGIN, CB_MESSAGE_BEGIN) \ |
311 | XX(17, CB_HEADERS_COMPLETE, CB_HEADERS_COMPLETE) \ |
312 | XX(18, CB_MESSAGE_COMPLETE, CB_MESSAGE_COMPLETE) \ |
313 | XX(19, CB_CHUNK_HEADER, CB_CHUNK_HEADER) \ |
314 | XX(20, CB_CHUNK_COMPLETE, CB_CHUNK_COMPLETE) \ |
315 | XX(21, PAUSED, PAUSED) \ |
316 | XX(22, PAUSED_UPGRADE, PAUSED_UPGRADE) \ |
317 | XX(23, PAUSED_H2_UPGRADE, PAUSED_H2_UPGRADE) \ |
318 | XX(24, USER, USER) \ |
319 | XX(26, CB_URL_COMPLETE, CB_URL_COMPLETE) \ |
320 | XX(27, CB_STATUS_COMPLETE, CB_STATUS_COMPLETE) \ |
321 | XX(32, CB_METHOD_COMPLETE, CB_METHOD_COMPLETE) \ |
322 | XX(33, CB_VERSION_COMPLETE, CB_VERSION_COMPLETE) \ |
323 | XX(28, CB_HEADER_FIELD_COMPLETE, CB_HEADER_FIELD_COMPLETE) \ |
324 | XX(29, CB_HEADER_VALUE_COMPLETE, CB_HEADER_VALUE_COMPLETE) \ |
325 | XX(34, CB_CHUNK_EXTENSION_NAME_COMPLETE, CB_CHUNK_EXTENSION_NAME_COMPLETE) \ |
326 | XX(35, CB_CHUNK_EXTENSION_VALUE_COMPLETE, CB_CHUNK_EXTENSION_VALUE_COMPLETE) \ |
327 | XX(31, CB_RESET, CB_RESET) \ |
328 | |
329 | |
330 | #define HTTP_METHOD_MAP(XX) \ |
331 | XX(0, DELETE, DELETE) \ |
332 | XX(1, GET, GET) \ |
333 | XX(2, HEAD, HEAD) \ |
334 | XX(3, POST, POST) \ |
335 | XX(4, PUT, PUT) \ |
336 | XX(5, CONNECT, CONNECT) \ |
337 | XX(6, OPTIONS, OPTIONS) \ |
338 | XX(7, TRACE, TRACE) \ |
339 | XX(8, COPY, COPY) \ |
340 | XX(9, LOCK, LOCK) \ |
341 | XX(10, MKCOL, MKCOL) \ |
342 | XX(11, MOVE, MOVE) \ |
343 | XX(12, PROPFIND, PROPFIND) \ |
344 | XX(13, PROPPATCH, PROPPATCH) \ |
345 | XX(14, SEARCH, SEARCH) \ |
346 | XX(15, UNLOCK, UNLOCK) \ |
347 | XX(16, BIND, BIND) \ |
348 | XX(17, REBIND, REBIND) \ |
349 | XX(18, UNBIND, UNBIND) \ |
350 | XX(19, ACL, ACL) \ |
351 | XX(20, REPORT, REPORT) \ |
352 | XX(21, MKACTIVITY, MKACTIVITY) \ |
353 | XX(22, CHECKOUT, CHECKOUT) \ |
354 | XX(23, MERGE, MERGE) \ |
355 | XX(24, MSEARCH, M-SEARCH) \ |
356 | XX(25, NOTIFY, NOTIFY) \ |
357 | XX(26, SUBSCRIBE, SUBSCRIBE) \ |
358 | XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ |
359 | XX(28, PATCH, PATCH) \ |
360 | XX(29, PURGE, PURGE) \ |
361 | XX(30, MKCALENDAR, MKCALENDAR) \ |
362 | XX(31, LINK, LINK) \ |
363 | XX(32, UNLINK, UNLINK) \ |
364 | XX(33, SOURCE, SOURCE) \ |
365 | |
366 | |
367 | #define RTSP_METHOD_MAP(XX) \ |
368 | XX(1, GET, GET) \ |
369 | XX(3, POST, POST) \ |
370 | XX(6, OPTIONS, OPTIONS) \ |
371 | XX(35, DESCRIBE, DESCRIBE) \ |
372 | XX(36, ANNOUNCE, ANNOUNCE) \ |
373 | XX(37, SETUP, SETUP) \ |
374 | XX(38, PLAY, PLAY) \ |
375 | XX(39, PAUSE, PAUSE) \ |
376 | XX(40, TEARDOWN, TEARDOWN) \ |
377 | XX(41, GET_PARAMETER, GET_PARAMETER) \ |
378 | XX(42, SET_PARAMETER, SET_PARAMETER) \ |
379 | XX(43, REDIRECT, REDIRECT) \ |
380 | XX(44, RECORD, RECORD) \ |
381 | XX(45, FLUSH, FLUSH) \ |
382 | |
383 | |
384 | #define HTTP_ALL_METHOD_MAP(XX) \ |
385 | XX(0, DELETE, DELETE) \ |
386 | XX(1, GET, GET) \ |
387 | XX(2, HEAD, HEAD) \ |
388 | XX(3, POST, POST) \ |
389 | XX(4, PUT, PUT) \ |
390 | XX(5, CONNECT, CONNECT) \ |
391 | XX(6, OPTIONS, OPTIONS) \ |
392 | XX(7, TRACE, TRACE) \ |
393 | XX(8, COPY, COPY) \ |
394 | XX(9, LOCK, LOCK) \ |
395 | XX(10, MKCOL, MKCOL) \ |
396 | XX(11, MOVE, MOVE) \ |
397 | XX(12, PROPFIND, PROPFIND) \ |
398 | XX(13, PROPPATCH, PROPPATCH) \ |
399 | XX(14, SEARCH, SEARCH) \ |
400 | XX(15, UNLOCK, UNLOCK) \ |
401 | XX(16, BIND, BIND) \ |
402 | XX(17, REBIND, REBIND) \ |
403 | XX(18, UNBIND, UNBIND) \ |
404 | XX(19, ACL, ACL) \ |
405 | XX(20, REPORT, REPORT) \ |
406 | XX(21, MKACTIVITY, MKACTIVITY) \ |
407 | XX(22, CHECKOUT, CHECKOUT) \ |
408 | XX(23, MERGE, MERGE) \ |
409 | XX(24, MSEARCH, M-SEARCH) \ |
410 | XX(25, NOTIFY, NOTIFY) \ |
411 | XX(26, SUBSCRIBE, SUBSCRIBE) \ |
412 | XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ |
413 | XX(28, PATCH, PATCH) \ |
414 | XX(29, PURGE, PURGE) \ |
415 | XX(30, MKCALENDAR, MKCALENDAR) \ |
416 | XX(31, LINK, LINK) \ |
417 | XX(32, UNLINK, UNLINK) \ |
418 | XX(33, SOURCE, SOURCE) \ |
419 | XX(34, PRI, PRI) \ |
420 | XX(35, DESCRIBE, DESCRIBE) \ |
421 | XX(36, ANNOUNCE, ANNOUNCE) \ |
422 | XX(37, SETUP, SETUP) \ |
423 | XX(38, PLAY, PLAY) \ |
424 | XX(39, PAUSE, PAUSE) \ |
425 | XX(40, TEARDOWN, TEARDOWN) \ |
426 | XX(41, GET_PARAMETER, GET_PARAMETER) \ |
427 | XX(42, SET_PARAMETER, SET_PARAMETER) \ |
428 | XX(43, REDIRECT, REDIRECT) \ |
429 | XX(44, RECORD, RECORD) \ |
430 | XX(45, FLUSH, FLUSH) \ |
431 | |
432 | |
433 | #define HTTP_STATUS_MAP(XX) \ |
434 | XX(100, CONTINUE, CONTINUE) \ |
435 | XX(101, SWITCHING_PROTOCOLS, SWITCHING_PROTOCOLS) \ |
436 | XX(102, PROCESSING, PROCESSING) \ |
437 | XX(103, EARLY_HINTS, EARLY_HINTS) \ |
438 | XX(110, RESPONSE_IS_STALE, RESPONSE_IS_STALE) \ |
439 | XX(111, REVALIDATION_FAILED, REVALIDATION_FAILED) \ |
440 | XX(112, DISCONNECTED_OPERATION, DISCONNECTED_OPERATION) \ |
441 | XX(113, HEURISTIC_EXPIRATION, HEURISTIC_EXPIRATION) \ |
442 | XX(199, MISCELLANEOUS_WARNING, MISCELLANEOUS_WARNING) \ |
443 | XX(200, OK, OK) \ |
444 | XX(201, CREATED, CREATED) \ |
445 | XX(202, ACCEPTED, ACCEPTED) \ |
446 | XX(203, NON_AUTHORITATIVE_INFORMATION, NON_AUTHORITATIVE_INFORMATION) \ |
447 | XX(204, NO_CONTENT, NO_CONTENT) \ |
448 | XX(205, RESET_CONTENT, RESET_CONTENT) \ |
449 | XX(206, PARTIAL_CONTENT, PARTIAL_CONTENT) \ |
450 | XX(207, MULTI_STATUS, MULTI_STATUS) \ |
451 | XX(208, ALREADY_REPORTED, ALREADY_REPORTED) \ |
452 | XX(214, TRANSFORMATION_APPLIED, TRANSFORMATION_APPLIED) \ |
453 | XX(226, IM_USED, IM_USED) \ |
454 | XX(299, MISCELLANEOUS_PERSISTENT_WARNING, MISCELLANEOUS_PERSISTENT_WARNING) \ |
455 | XX(300, MULTIPLE_CHOICES, MULTIPLE_CHOICES) \ |
456 | XX(301, MOVED_PERMANENTLY, MOVED_PERMANENTLY) \ |
457 | XX(302, FOUND, FOUND) \ |
458 | XX(303, SEE_OTHER, SEE_OTHER) \ |
459 | XX(304, NOT_MODIFIED, NOT_MODIFIED) \ |
460 | XX(305, USE_PROXY, USE_PROXY) \ |
461 | XX(306, SWITCH_PROXY, SWITCH_PROXY) \ |
462 | XX(307, TEMPORARY_REDIRECT, TEMPORARY_REDIRECT) \ |
463 | XX(308, PERMANENT_REDIRECT, PERMANENT_REDIRECT) \ |
464 | XX(400, BAD_REQUEST, BAD_REQUEST) \ |
465 | XX(401, UNAUTHORIZED, UNAUTHORIZED) \ |
466 | XX(402, PAYMENT_REQUIRED, PAYMENT_REQUIRED) \ |
467 | XX(403, FORBIDDEN, FORBIDDEN) \ |
468 | XX(404, NOT_FOUND, NOT_FOUND) \ |
469 | XX(405, METHOD_NOT_ALLOWED, METHOD_NOT_ALLOWED) \ |
470 | XX(406, NOT_ACCEPTABLE, NOT_ACCEPTABLE) \ |
471 | XX(407, PROXY_AUTHENTICATION_REQUIRED, PROXY_AUTHENTICATION_REQUIRED) \ |
472 | XX(408, REQUEST_TIMEOUT, REQUEST_TIMEOUT) \ |
473 | XX(409, CONFLICT, CONFLICT) \ |
474 | XX(410, GONE, GONE) \ |
475 | XX(411, LENGTH_REQUIRED, LENGTH_REQUIRED) \ |
476 | XX(412, PRECONDITION_FAILED, PRECONDITION_FAILED) \ |
477 | XX(413, PAYLOAD_TOO_LARGE, PAYLOAD_TOO_LARGE) \ |
478 | XX(414, URI_TOO_LONG, URI_TOO_LONG) \ |
479 | XX(415, UNSUPPORTED_MEDIA_TYPE, UNSUPPORTED_MEDIA_TYPE) \ |
480 | XX(416, RANGE_NOT_SATISFIABLE, RANGE_NOT_SATISFIABLE) \ |
481 | XX(417, EXPECTATION_FAILED, EXPECTATION_FAILED) \ |
482 | XX(418, IM_A_TEAPOT, IM_A_TEAPOT) \ |
483 | XX(419, PAGE_EXPIRED, PAGE_EXPIRED) \ |
484 | XX(420, ENHANCE_YOUR_CALM, ENHANCE_YOUR_CALM) \ |
485 | XX(421, MISDIRECTED_REQUEST, MISDIRECTED_REQUEST) \ |
486 | XX(422, UNPROCESSABLE_ENTITY, UNPROCESSABLE_ENTITY) \ |
487 | XX(423, LOCKED, LOCKED) \ |
488 | XX(424, FAILED_DEPENDENCY, FAILED_DEPENDENCY) \ |
489 | XX(425, TOO_EARLY, TOO_EARLY) \ |
490 | XX(426, UPGRADE_REQUIRED, UPGRADE_REQUIRED) \ |
491 | XX(428, PRECONDITION_REQUIRED, PRECONDITION_REQUIRED) \ |
492 | XX(429, TOO_MANY_REQUESTS, TOO_MANY_REQUESTS) \ |
493 | XX(430, REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL, REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL) \ |
494 | XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, REQUEST_HEADER_FIELDS_TOO_LARGE) \ |
495 | XX(440, LOGIN_TIMEOUT, LOGIN_TIMEOUT) \ |
496 | XX(444, NO_RESPONSE, NO_RESPONSE) \ |
497 | XX(449, RETRY_WITH, RETRY_WITH) \ |
498 | XX(450, BLOCKED_BY_PARENTAL_CONTROL, BLOCKED_BY_PARENTAL_CONTROL) \ |
499 | XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, UNAVAILABLE_FOR_LEGAL_REASONS) \ |
500 | XX(460, CLIENT_CLOSED_LOAD_BALANCED_REQUEST, CLIENT_CLOSED_LOAD_BALANCED_REQUEST) \ |
501 | XX(463, INVALID_X_FORWARDED_FOR, INVALID_X_FORWARDED_FOR) \ |
502 | XX(494, REQUEST_HEADER_TOO_LARGE, REQUEST_HEADER_TOO_LARGE) \ |
503 | XX(495, SSL_CERTIFICATE_ERROR, SSL_CERTIFICATE_ERROR) \ |
504 | XX(496, SSL_CERTIFICATE_REQUIRED, SSL_CERTIFICATE_REQUIRED) \ |
505 | XX(497, HTTP_REQUEST_SENT_TO_HTTPS_PORT, HTTP_REQUEST_SENT_TO_HTTPS_PORT) \ |
506 | XX(498, INVALID_TOKEN, INVALID_TOKEN) \ |
507 | XX(499, CLIENT_CLOSED_REQUEST, CLIENT_CLOSED_REQUEST) \ |
508 | XX(500, INTERNAL_SERVER_ERROR, INTERNAL_SERVER_ERROR) \ |
509 | XX(501, NOT_IMPLEMENTED, NOT_IMPLEMENTED) \ |
510 | XX(502, BAD_GATEWAY, BAD_GATEWAY) \ |
511 | XX(503, SERVICE_UNAVAILABLE, SERVICE_UNAVAILABLE) \ |
512 | XX(504, GATEWAY_TIMEOUT, GATEWAY_TIMEOUT) \ |
513 | XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP_VERSION_NOT_SUPPORTED) \ |
514 | XX(506, VARIANT_ALSO_NEGOTIATES, VARIANT_ALSO_NEGOTIATES) \ |
515 | XX(507, INSUFFICIENT_STORAGE, INSUFFICIENT_STORAGE) \ |
516 | XX(508, LOOP_DETECTED, LOOP_DETECTED) \ |
517 | XX(509, BANDWIDTH_LIMIT_EXCEEDED, BANDWIDTH_LIMIT_EXCEEDED) \ |
518 | XX(510, NOT_EXTENDED, NOT_EXTENDED) \ |
519 | XX(511, NETWORK_AUTHENTICATION_REQUIRED, NETWORK_AUTHENTICATION_REQUIRED) \ |
520 | XX(520, WEB_SERVER_UNKNOWN_ERROR, WEB_SERVER_UNKNOWN_ERROR) \ |
521 | XX(521, WEB_SERVER_IS_DOWN, WEB_SERVER_IS_DOWN) \ |
522 | XX(522, CONNECTION_TIMEOUT, CONNECTION_TIMEOUT) \ |
523 | XX(523, ORIGIN_IS_UNREACHABLE, ORIGIN_IS_UNREACHABLE) \ |
524 | XX(524, TIMEOUT_OCCURED, TIMEOUT_OCCURED) \ |
525 | XX(525, SSL_HANDSHAKE_FAILED, SSL_HANDSHAKE_FAILED) \ |
526 | XX(526, INVALID_SSL_CERTIFICATE, INVALID_SSL_CERTIFICATE) \ |
527 | XX(527, RAILGUN_ERROR, RAILGUN_ERROR) \ |
528 | XX(529, SITE_IS_OVERLOADED, SITE_IS_OVERLOADED) \ |
529 | XX(530, SITE_IS_FROZEN, SITE_IS_FROZEN) \ |
530 | XX(561, IDENTITY_PROVIDER_AUTHENTICATION_ERROR, IDENTITY_PROVIDER_AUTHENTICATION_ERROR) \ |
531 | XX(598, NETWORK_READ_TIMEOUT, NETWORK_READ_TIMEOUT) \ |
532 | XX(599, NETWORK_CONNECT_TIMEOUT, NETWORK_CONNECT_TIMEOUT) \ |
533 | |
534 | |
535 | #ifdef __cplusplus |
536 | } /* extern "C" */ |
537 | #endif |
538 | #endif /* LLLLHTTP_C_HEADERS_ */ |
539 | |
540 | |
541 | #ifndef INCLUDE_LLHTTP_API_H_ |
542 | #define INCLUDE_LLHTTP_API_H_ |
543 | #ifdef __cplusplus |
544 | extern "C" { |
545 | #endif |
546 | #include <stddef.h> |
547 | |
548 | #if defined(__wasm__) |
549 | #define LLHTTP_EXPORT __attribute__((visibility("default"))) |
550 | #else |
551 | #define LLHTTP_EXPORT |
552 | #endif |
553 | |
554 | typedef llhttp__internal_t llhttp_t; |
555 | typedef struct llhttp_settings_s llhttp_settings_t; |
556 | |
557 | typedef int (*llhttp_data_cb)(llhttp_t*, const char *at, size_t length); |
558 | typedef int (*llhttp_cb)(llhttp_t*); |
559 | |
560 | struct llhttp_settings_s { |
561 | /* Possible return values 0, -1, `HPE_PAUSED` */ |
562 | llhttp_cb on_message_begin; |
563 | |
564 | /* Possible return values 0, -1, HPE_USER */ |
565 | llhttp_data_cb on_url; |
566 | llhttp_data_cb on_status; |
567 | llhttp_data_cb on_method; |
568 | llhttp_data_cb on_version; |
569 | llhttp_data_cb ; |
570 | llhttp_data_cb ; |
571 | llhttp_data_cb on_chunk_extension_name; |
572 | llhttp_data_cb on_chunk_extension_value; |
573 | |
574 | /* Possible return values: |
575 | * 0 - Proceed normally |
576 | * 1 - Assume that request/response has no body, and proceed to parsing the |
577 | * next message |
578 | * 2 - Assume absence of body (as above) and make `llhttp_execute()` return |
579 | * `HPE_PAUSED_UPGRADE` |
580 | * -1 - Error |
581 | * `HPE_PAUSED` |
582 | */ |
583 | llhttp_cb ; |
584 | |
585 | /* Possible return values 0, -1, HPE_USER */ |
586 | llhttp_data_cb on_body; |
587 | |
588 | /* Possible return values 0, -1, `HPE_PAUSED` */ |
589 | llhttp_cb on_message_complete; |
590 | llhttp_cb on_url_complete; |
591 | llhttp_cb on_status_complete; |
592 | llhttp_cb on_method_complete; |
593 | llhttp_cb on_version_complete; |
594 | llhttp_cb ; |
595 | llhttp_cb ; |
596 | llhttp_cb on_chunk_extension_name_complete; |
597 | llhttp_cb on_chunk_extension_value_complete; |
598 | |
599 | /* When on_chunk_header is called, the current chunk length is stored |
600 | * in parser->content_length. |
601 | * Possible return values 0, -1, `HPE_PAUSED` |
602 | */ |
603 | llhttp_cb ; |
604 | llhttp_cb on_chunk_complete; |
605 | llhttp_cb on_reset; |
606 | }; |
607 | |
608 | /* Initialize the parser with specific type and user settings. |
609 | * |
610 | * NOTE: lifetime of `settings` has to be at least the same as the lifetime of |
611 | * the `parser` here. In practice, `settings` has to be either a static |
612 | * variable or be allocated with `malloc`, `new`, etc. |
613 | */ |
614 | LLHTTP_EXPORT |
615 | void llhttp_init(llhttp_t* parser, llhttp_type_t type, |
616 | const llhttp_settings_t* settings); |
617 | |
618 | LLHTTP_EXPORT |
619 | llhttp_t* llhttp_alloc(llhttp_type_t type); |
620 | |
621 | LLHTTP_EXPORT |
622 | void llhttp_free(llhttp_t* parser); |
623 | |
624 | LLHTTP_EXPORT |
625 | uint8_t llhttp_get_type(llhttp_t* parser); |
626 | |
627 | LLHTTP_EXPORT |
628 | uint8_t llhttp_get_http_major(llhttp_t* parser); |
629 | |
630 | LLHTTP_EXPORT |
631 | uint8_t llhttp_get_http_minor(llhttp_t* parser); |
632 | |
633 | LLHTTP_EXPORT |
634 | uint8_t llhttp_get_method(llhttp_t* parser); |
635 | |
636 | LLHTTP_EXPORT |
637 | int llhttp_get_status_code(llhttp_t* parser); |
638 | |
639 | LLHTTP_EXPORT |
640 | uint8_t llhttp_get_upgrade(llhttp_t* parser); |
641 | |
642 | /* Reset an already initialized parser back to the start state, preserving the |
643 | * existing parser type, callback settings, user data, and lenient flags. |
644 | */ |
645 | LLHTTP_EXPORT |
646 | void llhttp_reset(llhttp_t* parser); |
647 | |
648 | /* Initialize the settings object */ |
649 | LLHTTP_EXPORT |
650 | void llhttp_settings_init(llhttp_settings_t* settings); |
651 | |
652 | /* Parse full or partial request/response, invoking user callbacks along the |
653 | * way. |
654 | * |
655 | * If any of `llhttp_data_cb` returns errno not equal to `HPE_OK` - the parsing |
656 | * interrupts, and such errno is returned from `llhttp_execute()`. If |
657 | * `HPE_PAUSED` was used as a errno, the execution can be resumed with |
658 | * `llhttp_resume()` call. |
659 | * |
660 | * In a special case of CONNECT/Upgrade request/response `HPE_PAUSED_UPGRADE` |
661 | * is returned after fully parsing the request/response. If the user wishes to |
662 | * continue parsing, they need to invoke `llhttp_resume_after_upgrade()`. |
663 | * |
664 | * NOTE: if this function ever returns a non-pause type error, it will continue |
665 | * to return the same error upon each successive call up until `llhttp_init()` |
666 | * is called. |
667 | */ |
668 | LLHTTP_EXPORT |
669 | llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len); |
670 | |
671 | /* This method should be called when the other side has no further bytes to |
672 | * send (e.g. shutdown of readable side of the TCP connection.) |
673 | * |
674 | * Requests without `Content-Length` and other messages might require treating |
675 | * all incoming bytes as the part of the body, up to the last byte of the |
676 | * connection. This method will invoke `on_message_complete()` callback if the |
677 | * request was terminated safely. Otherwise a error code would be returned. |
678 | */ |
679 | LLHTTP_EXPORT |
680 | llhttp_errno_t llhttp_finish(llhttp_t* parser); |
681 | |
682 | /* Returns `1` if the incoming message is parsed until the last byte, and has |
683 | * to be completed by calling `llhttp_finish()` on EOF |
684 | */ |
685 | LLHTTP_EXPORT |
686 | int llhttp_message_needs_eof(const llhttp_t* parser); |
687 | |
688 | /* Returns `1` if there might be any other messages following the last that was |
689 | * successfully parsed. |
690 | */ |
691 | LLHTTP_EXPORT |
692 | int llhttp_should_keep_alive(const llhttp_t* parser); |
693 | |
694 | /* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set |
695 | * appropriate error reason. |
696 | * |
697 | * Important: do not call this from user callbacks! User callbacks must return |
698 | * `HPE_PAUSED` if pausing is required. |
699 | */ |
700 | LLHTTP_EXPORT |
701 | void llhttp_pause(llhttp_t* parser); |
702 | |
703 | /* Might be called to resume the execution after the pause in user's callback. |
704 | * See `llhttp_execute()` above for details. |
705 | * |
706 | * Call this only if `llhttp_execute()` returns `HPE_PAUSED`. |
707 | */ |
708 | LLHTTP_EXPORT |
709 | void llhttp_resume(llhttp_t* parser); |
710 | |
711 | /* Might be called to resume the execution after the pause in user's callback. |
712 | * See `llhttp_execute()` above for details. |
713 | * |
714 | * Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE` |
715 | */ |
716 | LLHTTP_EXPORT |
717 | void llhttp_resume_after_upgrade(llhttp_t* parser); |
718 | |
719 | /* Returns the latest return error */ |
720 | LLHTTP_EXPORT |
721 | llhttp_errno_t llhttp_get_errno(const llhttp_t* parser); |
722 | |
723 | /* Returns the verbal explanation of the latest returned error. |
724 | * |
725 | * Note: User callback should set error reason when returning the error. See |
726 | * `llhttp_set_error_reason()` for details. |
727 | */ |
728 | LLHTTP_EXPORT |
729 | const char* llhttp_get_error_reason(const llhttp_t* parser); |
730 | |
731 | /* Assign verbal description to the returned error. Must be called in user |
732 | * callbacks right before returning the errno. |
733 | * |
734 | * Note: `HPE_USER` error code might be useful in user callbacks. |
735 | */ |
736 | LLHTTP_EXPORT |
737 | void llhttp_set_error_reason(llhttp_t* parser, const char* reason); |
738 | |
739 | /* Returns the pointer to the last parsed byte before the returned error. The |
740 | * pointer is relative to the `data` argument of `llhttp_execute()`. |
741 | * |
742 | * Note: this method might be useful for counting the number of parsed bytes. |
743 | */ |
744 | LLHTTP_EXPORT |
745 | const char* llhttp_get_error_pos(const llhttp_t* parser); |
746 | |
747 | /* Returns textual name of error code */ |
748 | LLHTTP_EXPORT |
749 | const char* llhttp_errno_name(llhttp_errno_t err); |
750 | |
751 | /* Returns textual name of HTTP method */ |
752 | LLHTTP_EXPORT |
753 | const char* llhttp_method_name(llhttp_method_t method); |
754 | |
755 | /* Returns textual name of HTTP status */ |
756 | LLHTTP_EXPORT |
757 | const char* llhttp_status_name(llhttp_status_t status); |
758 | |
759 | /* Enables/disables lenient header value parsing (disabled by default). |
760 | * |
761 | * Lenient parsing disables header value token checks, extending llhttp's |
762 | * protocol support to highly non-compliant clients/server. No |
763 | * `HPE_INVALID_HEADER_TOKEN` will be raised for incorrect header values when |
764 | * lenient parsing is "on". |
765 | * |
766 | * **Enabling this flag can pose a security issue since you will be exposed to |
767 | * request smuggling attacks. USE WITH CAUTION!** |
768 | */ |
769 | LLHTTP_EXPORT |
770 | void (llhttp_t* parser, int enabled); |
771 | |
772 | |
773 | /* Enables/disables lenient handling of conflicting `Transfer-Encoding` and |
774 | * `Content-Length` headers (disabled by default). |
775 | * |
776 | * Normally `llhttp` would error when `Transfer-Encoding` is present in |
777 | * conjunction with `Content-Length`. This error is important to prevent HTTP |
778 | * request smuggling, but may be less desirable for small number of cases |
779 | * involving legacy servers. |
780 | * |
781 | * **Enabling this flag can pose a security issue since you will be exposed to |
782 | * request smuggling attacks. USE WITH CAUTION!** |
783 | */ |
784 | LLHTTP_EXPORT |
785 | void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled); |
786 | |
787 | |
788 | /* Enables/disables lenient handling of `Connection: close` and HTTP/1.0 |
789 | * requests responses. |
790 | * |
791 | * Normally `llhttp` would error on (in strict mode) or discard (in loose mode) |
792 | * the HTTP request/response after the request/response with `Connection: close` |
793 | * and `Content-Length`. This is important to prevent cache poisoning attacks, |
794 | * but might interact badly with outdated and insecure clients. With this flag |
795 | * the extra request/response will be parsed normally. |
796 | * |
797 | * **Enabling this flag can pose a security issue since you will be exposed to |
798 | * poisoning attacks. USE WITH CAUTION!** |
799 | */ |
800 | LLHTTP_EXPORT |
801 | void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled); |
802 | |
803 | /* Enables/disables lenient handling of `Transfer-Encoding` header. |
804 | * |
805 | * Normally `llhttp` would error when a `Transfer-Encoding` has `chunked` value |
806 | * and another value after it (either in a single header or in multiple |
807 | * headers whose value are internally joined using `, `). |
808 | * This is mandated by the spec to reliably determine request body size and thus |
809 | * avoid request smuggling. |
810 | * With this flag the extra value will be parsed normally. |
811 | * |
812 | * **Enabling this flag can pose a security issue since you will be exposed to |
813 | * request smuggling attacks. USE WITH CAUTION!** |
814 | */ |
815 | LLHTTP_EXPORT |
816 | void llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled); |
817 | |
818 | /* Enables/disables lenient handling of HTTP version. |
819 | * |
820 | * Normally `llhttp` would error when the HTTP version in the request or status line |
821 | * is not `0.9`, `1.0`, `1.1` or `2.0`. |
822 | * With this flag the invalid value will be parsed normally. |
823 | * |
824 | * **Enabling this flag can pose a security issue since you will allow unsupported |
825 | * HTTP versions. USE WITH CAUTION!** |
826 | */ |
827 | LLHTTP_EXPORT |
828 | void llhttp_set_lenient_version(llhttp_t* parser, int enabled); |
829 | |
830 | /* Enables/disables lenient handling of additional data received after a message ends |
831 | * and keep-alive is disabled. |
832 | * |
833 | * Normally `llhttp` would error when additional unexpected data is received if the message |
834 | * contains the `Connection` header with `close` value. |
835 | * With this flag the extra data will discarded without throwing an error. |
836 | * |
837 | * **Enabling this flag can pose a security issue since you will be exposed to |
838 | * poisoning attacks. USE WITH CAUTION!** |
839 | */ |
840 | LLHTTP_EXPORT |
841 | void llhttp_set_lenient_data_after_close(llhttp_t* parser, int enabled); |
842 | |
843 | /* Enables/disables lenient handling of incomplete CRLF sequences. |
844 | * |
845 | * Normally `llhttp` would error when a CR is not followed by LF when terminating the |
846 | * request line, the status line, the headers or a chunk header. |
847 | * With this flag only a CR is required to terminate such sections. |
848 | * |
849 | * **Enabling this flag can pose a security issue since you will be exposed to |
850 | * request smuggling attacks. USE WITH CAUTION!** |
851 | */ |
852 | LLHTTP_EXPORT |
853 | void llhttp_set_lenient_optional_lf_after_cr(llhttp_t* parser, int enabled); |
854 | |
855 | /* |
856 | * Enables/disables lenient handling of line separators. |
857 | * |
858 | * Normally `llhttp` would error when a LF is not preceded by CR when terminating the |
859 | * request line, the status line, the headers, a chunk header or a chunk data. |
860 | * With this flag only a LF is required to terminate such sections. |
861 | * |
862 | * **Enabling this flag can pose a security issue since you will be exposed to |
863 | * request smuggling attacks. USE WITH CAUTION!** |
864 | */ |
865 | LLHTTP_EXPORT |
866 | void llhttp_set_lenient_optional_cr_before_lf(llhttp_t* parser, int enabled); |
867 | |
868 | /* Enables/disables lenient handling of chunks not separated via CRLF. |
869 | * |
870 | * Normally `llhttp` would error when after a chunk data a CRLF is missing before |
871 | * starting a new chunk. |
872 | * With this flag the new chunk can start immediately after the previous one. |
873 | * |
874 | * **Enabling this flag can pose a security issue since you will be exposed to |
875 | * request smuggling attacks. USE WITH CAUTION!** |
876 | */ |
877 | LLHTTP_EXPORT |
878 | void llhttp_set_lenient_optional_crlf_after_chunk(llhttp_t* parser, int enabled); |
879 | |
880 | /* Enables/disables lenient handling of spaces after chunk size. |
881 | * |
882 | * Normally `llhttp` would error when after a chunk size is followed by one or more |
883 | * spaces are present instead of a CRLF or `;`. |
884 | * With this flag this check is disabled. |
885 | * |
886 | * **Enabling this flag can pose a security issue since you will be exposed to |
887 | * request smuggling attacks. USE WITH CAUTION!** |
888 | */ |
889 | LLHTTP_EXPORT |
890 | void llhttp_set_lenient_spaces_after_chunk_size(llhttp_t* parser, int enabled); |
891 | |
892 | #ifdef __cplusplus |
893 | } /* extern "C" */ |
894 | #endif |
895 | #endif /* INCLUDE_LLHTTP_API_H_ */ |
896 | |
897 | |
898 | #endif /* INCLUDE_LLHTTP_H_ */ |
899 | |