| 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 | |