1 #ifndef INCLUDE_LLHTTP_H_ 2 #define INCLUDE_LLHTTP_H_ 3 4 #define LLHTTP_VERSION_MAJOR 2 5 #define LLHTTP_VERSION_MINOR 1 6 #define LLHTTP_VERSION_PATCH 6 7 8 #ifndef LLHTTP_STRICT_MODE 9 # define LLHTTP_STRICT_MODE 0 10 #endif 11 12 #ifndef INCLUDE_LLHTTP_ITSELF_H_ 13 #define INCLUDE_LLHTTP_ITSELF_H_ 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 #include <stdint.h> 19 20 typedef struct llhttp__internal_s llhttp__internal_t; 21 struct llhttp__internal_s { 22 int32_t _index; 23 void* _span_pos0; 24 void* _span_cb0; 25 int32_t error; 26 const char* reason; 27 const char* error_pos; 28 void* data; 29 void* _current; 30 uint64_t content_length; 31 uint8_t type; 32 uint8_t method; 33 uint8_t http_major; 34 uint8_t http_minor; 35 uint8_t header_state; 36 uint16_t flags; 37 uint8_t upgrade; 38 uint16_t status_code; 39 uint8_t finish; 40 void* settings; 41 }; 42 43 int llhttp__internal_init(llhttp__internal_t* s); 44 int llhttp__internal_execute(llhttp__internal_t* s, const char* p, const char* endp); 45 46 #ifdef __cplusplus 47 } /* extern "C" */ 48 #endif 49 #endif /* INCLUDE_LLHTTP_ITSELF_H_ */ 50 51 #ifndef LLLLHTTP_C_HEADERS_ 52 #define LLLLHTTP_C_HEADERS_ 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_CLOSED_CONNECTION = 5, 65 HPE_INVALID_METHOD = 6, 66 HPE_INVALID_URL = 7, 67 HPE_INVALID_CONSTANT = 8, 68 HPE_INVALID_VERSION = 9, 69 HPE_INVALID_HEADER_TOKEN = 10, 70 HPE_INVALID_CONTENT_LENGTH = 11, 71 HPE_INVALID_CHUNK_SIZE = 12, 72 HPE_INVALID_STATUS = 13, 73 HPE_INVALID_EOF_STATE = 14, 74 HPE_INVALID_TRANSFER_ENCODING = 15, 75 HPE_CB_MESSAGE_BEGIN = 16, 76 HPE_CB_HEADERS_COMPLETE = 17, 77 HPE_CB_MESSAGE_COMPLETE = 18, 78 HPE_CB_CHUNK_HEADER = 19, 79 HPE_CB_CHUNK_COMPLETE = 20, 80 HPE_PAUSED = 21, 81 HPE_PAUSED_UPGRADE = 22, 82 HPE_USER = 24 83 }; 84 typedef enum llhttp_errno llhttp_errno_t; 85 86 enum llhttp_flags { 87 F_CONNECTION_KEEP_ALIVE = 0x1, 88 F_CONNECTION_CLOSE = 0x2, 89 F_CONNECTION_UPGRADE = 0x4, 90 F_CHUNKED = 0x8, 91 F_UPGRADE = 0x10, 92 F_CONTENT_LENGTH = 0x20, 93 F_SKIPBODY = 0x40, 94 F_TRAILING = 0x80, 95 F_LENIENT = 0x100, 96 F_TRANSFER_ENCODING = 0x200 97 }; 98 typedef enum llhttp_flags llhttp_flags_t; 99 100 enum llhttp_type { 101 HTTP_BOTH = 0, 102 HTTP_REQUEST = 1, 103 HTTP_RESPONSE = 2 104 }; 105 typedef enum llhttp_type llhttp_type_t; 106 107 enum llhttp_finish { 108 HTTP_FINISH_SAFE = 0, 109 HTTP_FINISH_SAFE_WITH_CB = 1, 110 HTTP_FINISH_UNSAFE = 2 111 }; 112 typedef enum llhttp_finish llhttp_finish_t; 113 114 enum llhttp_method { 115 HTTP_DELETE = 0, 116 HTTP_GET = 1, 117 HTTP_HEAD = 2, 118 HTTP_POST = 3, 119 HTTP_PUT = 4, 120 HTTP_CONNECT = 5, 121 HTTP_OPTIONS = 6, 122 HTTP_TRACE = 7, 123 HTTP_COPY = 8, 124 HTTP_LOCK = 9, 125 HTTP_MKCOL = 10, 126 HTTP_MOVE = 11, 127 HTTP_PROPFIND = 12, 128 HTTP_PROPPATCH = 13, 129 HTTP_SEARCH = 14, 130 HTTP_UNLOCK = 15, 131 HTTP_BIND = 16, 132 HTTP_REBIND = 17, 133 HTTP_UNBIND = 18, 134 HTTP_ACL = 19, 135 HTTP_REPORT = 20, 136 HTTP_MKACTIVITY = 21, 137 HTTP_CHECKOUT = 22, 138 HTTP_MERGE = 23, 139 HTTP_MSEARCH = 24, 140 HTTP_NOTIFY = 25, 141 HTTP_SUBSCRIBE = 26, 142 HTTP_UNSUBSCRIBE = 27, 143 HTTP_PATCH = 28, 144 HTTP_PURGE = 29, 145 HTTP_MKCALENDAR = 30, 146 HTTP_LINK = 31, 147 HTTP_UNLINK = 32, 148 HTTP_SOURCE = 33, 149 HTTP_PRI = 34 150 }; 151 typedef enum llhttp_method llhttp_method_t; 152 153 #define HTTP_ERRNO_MAP(XX) \ 154 XX(0, OK, OK) \ 155 XX(1, INTERNAL, INTERNAL) \ 156 XX(2, STRICT, STRICT) \ 157 XX(25, CR_EXPECTED, CR_EXPECTED) \ 158 XX(3, LF_EXPECTED, LF_EXPECTED) \ 159 XX(4, UNEXPECTED_CONTENT_LENGTH, UNEXPECTED_CONTENT_LENGTH) \ 160 XX(5, CLOSED_CONNECTION, CLOSED_CONNECTION) \ 161 XX(6, INVALID_METHOD, INVALID_METHOD) \ 162 XX(7, INVALID_URL, INVALID_URL) \ 163 XX(8, INVALID_CONSTANT, INVALID_CONSTANT) \ 164 XX(9, INVALID_VERSION, INVALID_VERSION) \ 165 XX(10, INVALID_HEADER_TOKEN, INVALID_HEADER_TOKEN) \ 166 XX(11, INVALID_CONTENT_LENGTH, INVALID_CONTENT_LENGTH) \ 167 XX(12, INVALID_CHUNK_SIZE, INVALID_CHUNK_SIZE) \ 168 XX(13, INVALID_STATUS, INVALID_STATUS) \ 169 XX(14, INVALID_EOF_STATE, INVALID_EOF_STATE) \ 170 XX(15, INVALID_TRANSFER_ENCODING, INVALID_TRANSFER_ENCODING) \ 171 XX(16, CB_MESSAGE_BEGIN, CB_MESSAGE_BEGIN) \ 172 XX(17, CB_HEADERS_COMPLETE, CB_HEADERS_COMPLETE) \ 173 XX(18, CB_MESSAGE_COMPLETE, CB_MESSAGE_COMPLETE) \ 174 XX(19, CB_CHUNK_HEADER, CB_CHUNK_HEADER) \ 175 XX(20, CB_CHUNK_COMPLETE, CB_CHUNK_COMPLETE) \ 176 XX(21, PAUSED, PAUSED) \ 177 XX(22, PAUSED_UPGRADE, PAUSED_UPGRADE) \ 178 XX(24, USER, USER) \ 179 180 181 #define HTTP_METHOD_MAP(XX) \ 182 XX(0, DELETE, DELETE) \ 183 XX(1, GET, GET) \ 184 XX(2, HEAD, HEAD) \ 185 XX(3, POST, POST) \ 186 XX(4, PUT, PUT) \ 187 XX(5, CONNECT, CONNECT) \ 188 XX(6, OPTIONS, OPTIONS) \ 189 XX(7, TRACE, TRACE) \ 190 XX(8, COPY, COPY) \ 191 XX(9, LOCK, LOCK) \ 192 XX(10, MKCOL, MKCOL) \ 193 XX(11, MOVE, MOVE) \ 194 XX(12, PROPFIND, PROPFIND) \ 195 XX(13, PROPPATCH, PROPPATCH) \ 196 XX(14, SEARCH, SEARCH) \ 197 XX(15, UNLOCK, UNLOCK) \ 198 XX(16, BIND, BIND) \ 199 XX(17, REBIND, REBIND) \ 200 XX(18, UNBIND, UNBIND) \ 201 XX(19, ACL, ACL) \ 202 XX(20, REPORT, REPORT) \ 203 XX(21, MKACTIVITY, MKACTIVITY) \ 204 XX(22, CHECKOUT, CHECKOUT) \ 205 XX(23, MERGE, MERGE) \ 206 XX(24, MSEARCH, M-SEARCH) \ 207 XX(25, NOTIFY, NOTIFY) \ 208 XX(26, SUBSCRIBE, SUBSCRIBE) \ 209 XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ 210 XX(28, PATCH, PATCH) \ 211 XX(29, PURGE, PURGE) \ 212 XX(30, MKCALENDAR, MKCALENDAR) \ 213 XX(31, LINK, LINK) \ 214 XX(32, UNLINK, UNLINK) \ 215 XX(33, SOURCE, SOURCE) \ 216 XX(34, PRI, PRI) \ 217 218 219 220 #ifdef __cplusplus 221 } /* extern "C" */ 222 #endif 223 #endif /* LLLLHTTP_C_HEADERS_ */ 224 225 #ifndef INCLUDE_LLHTTP_API_H_ 226 #define INCLUDE_LLHTTP_API_H_ 227 #ifdef __cplusplus 228 extern "C" { 229 #endif 230 #include <stddef.h> 231 232 typedef llhttp__internal_t llhttp_t; 233 typedef struct llhttp_settings_s llhttp_settings_t; 234 235 typedef int (*llhttp_data_cb)(llhttp_t*, const char *at, size_t length); 236 typedef int (*llhttp_cb)(llhttp_t*); 237 238 struct llhttp_settings_s { 239 /* Possible return values 0, -1, `HPE_PAUSED` */ 240 llhttp_cb on_message_begin; 241 242 llhttp_data_cb on_url; 243 llhttp_data_cb on_status; 244 llhttp_data_cb on_header_field; 245 llhttp_data_cb on_header_value; 246 247 /* Possible return values: 248 * 0 - Proceed normally 249 * 1 - Assume that request/response has no body, and proceed to parsing the 250 * next message 251 * 2 - Assume absence of body (as above) and make `llhttp_execute()` return 252 * `HPE_PAUSED_UPGRADE` 253 * -1 - Error 254 * `HPE_PAUSED` 255 */ 256 llhttp_cb on_headers_complete; 257 258 llhttp_data_cb on_body; 259 260 /* Possible return values 0, -1, `HPE_PAUSED` */ 261 llhttp_cb on_message_complete; 262 263 /* When on_chunk_header is called, the current chunk length is stored 264 * in parser->content_length. 265 * Possible return values 0, -1, `HPE_PAUSED` 266 */ 267 llhttp_cb on_chunk_header; 268 llhttp_cb on_chunk_complete; 269 }; 270 271 /* Initialize the parser with specific type and user settings */ 272 void llhttp_init(llhttp_t* parser, llhttp_type_t type, 273 const llhttp_settings_t* settings); 274 275 /* Initialize the settings object */ 276 void llhttp_settings_init(llhttp_settings_t* settings); 277 278 /* Parse full or partial request/response, invoking user callbacks along the 279 * way. 280 * 281 * If any of `llhttp_data_cb` returns errno not equal to `HPE_OK` - the parsing 282 * interrupts, and such errno is returned from `llhttp_execute()`. If 283 * `HPE_PAUSED` was used as a errno, the execution can be resumed with 284 * `llhttp_resume()` call. 285 * 286 * In a special case of CONNECT/Upgrade request/response `HPE_PAUSED_UPGRADE` 287 * is returned after fully parsing the request/response. If the user wishes to 288 * continue parsing, they need to invoke `llhttp_resume_after_upgrade()`. 289 * 290 * NOTE: if this function ever returns a non-pause type error, it will continue 291 * to return the same error upon each successive call up until `llhttp_init()` 292 * is called. 293 */ 294 llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len); 295 296 /* This method should be called when the other side has no further bytes to 297 * send (e.g. shutdown of readable side of the TCP connection.) 298 * 299 * Requests without `Content-Length` and other messages might require treating 300 * all incoming bytes as the part of the body, up to the last byte of the 301 * connection. This method will invoke `on_message_complete()` callback if the 302 * request was terminated safely. Otherwise a error code would be returned. 303 */ 304 llhttp_errno_t llhttp_finish(llhttp_t* parser); 305 306 /* Returns `1` if the incoming message is parsed until the last byte, and has 307 * to be completed by calling `llhttp_finish()` on EOF 308 */ 309 int llhttp_message_needs_eof(const llhttp_t* parser); 310 311 /* Returns `1` if there might be any other messages following the last that was 312 * successfully parsed. 313 */ 314 int llhttp_should_keep_alive(const llhttp_t* parser); 315 316 /* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set 317 * appropriate error reason. 318 * 319 * Important: do not call this from user callbacks! User callbacks must return 320 * `HPE_PAUSED` if pausing is required. 321 */ 322 void llhttp_pause(llhttp_t* parser); 323 324 /* Might be called to resume the execution after the pause in user's callback. 325 * See `llhttp_execute()` above for details. 326 * 327 * Call this only if `llhttp_execute()` returns `HPE_PAUSED`. 328 */ 329 void llhttp_resume(llhttp_t* parser); 330 331 /* Might be called to resume the execution after the pause in user's callback. 332 * See `llhttp_execute()` above for details. 333 * 334 * Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE` 335 */ 336 void llhttp_resume_after_upgrade(llhttp_t* parser); 337 338 /* Returns the latest return error */ 339 llhttp_errno_t llhttp_get_errno(const llhttp_t* parser); 340 341 /* Returns the verbal explanation of the latest returned error. 342 * 343 * Note: User callback should set error reason when returning the error. See 344 * `llhttp_set_error_reason()` for details. 345 */ 346 const char* llhttp_get_error_reason(const llhttp_t* parser); 347 348 /* Assign verbal description to the returned error. Must be called in user 349 * callbacks right before returning the errno. 350 * 351 * Note: `HPE_USER` error code might be useful in user callbacks. 352 */ 353 void llhttp_set_error_reason(llhttp_t* parser, const char* reason); 354 355 /* Returns the pointer to the last parsed byte before the returned error. The 356 * pointer is relative to the `data` argument of `llhttp_execute()`. 357 * 358 * Note: this method might be useful for counting the number of parsed bytes. 359 */ 360 const char* llhttp_get_error_pos(const llhttp_t* parser); 361 362 /* Returns textual name of error code */ 363 const char* llhttp_errno_name(llhttp_errno_t err); 364 365 /* Returns textual name of HTTP method */ 366 const char* llhttp_method_name(llhttp_method_t method); 367 368 369 /* Enables/disables lenient header value parsing (disabled by default). 370 * 371 * Lenient parsing disables header value token checks, extending llhttp's 372 * protocol support to highly non-compliant clients/server. No 373 * `HPE_INVALID_HEADER_TOKEN` will be raised for incorrect header values when 374 * lenient parsing is "on". 375 * 376 * **(USE AT YOUR OWN RISK)** 377 */ 378 void llhttp_set_lenient(llhttp_t* parser, int enabled); 379 380 #ifdef __cplusplus 381 } /* extern "C" */ 382 #endif 383 #endif /* INCLUDE_LLHTTP_API_H_ */ 384 385 #endif /* INCLUDE_LLHTTP_H_ */ 386