ext/llhttp/llhttp.h in llhttp-0.0.3 vs ext/llhttp/llhttp.h in llhttp-0.1.0

- old
+ new

@@ -22,14 +22,18 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef INCLUDE_LLHTTP_H_ #define INCLUDE_LLHTTP_H_ -#define LLHTTP_VERSION_MAJOR 1 -#define LLHTTP_VERSION_MINOR 1 -#define LLHTTP_VERSION_PATCH 1 +#define LLHTTP_VERSION_MAJOR 4 +#define LLHTTP_VERSION_MINOR 0 +#define LLHTTP_VERSION_PATCH 0 +#ifndef LLHTTP_STRICT_MODE +# define LLHTTP_STRICT_MODE 0 +#endif + #ifndef INCLUDE_LLHTTP_ITSELF_H_ #define INCLUDE_LLHTTP_ITSELF_H_ #ifdef __cplusplus extern "C" { #endif @@ -50,14 +54,15 @@ uint8_t type; uint8_t method; uint8_t http_major; uint8_t http_minor; uint8_t header_state; - uint8_t flags; + uint8_t lenient_flags; uint8_t upgrade; - uint16_t status_code; uint8_t finish; + uint16_t flags; + uint16_t status_code; void* settings; }; int llhttp__internal_init(llhttp__internal_t* s); int llhttp__internal_execute(llhttp__internal_t* s, const char* p, const char* endp); @@ -87,18 +92,19 @@ HPE_INVALID_HEADER_TOKEN = 10, HPE_INVALID_CONTENT_LENGTH = 11, HPE_INVALID_CHUNK_SIZE = 12, HPE_INVALID_STATUS = 13, HPE_INVALID_EOF_STATE = 14, - HPE_CB_MESSAGE_BEGIN = 15, - HPE_CB_HEADERS_COMPLETE = 16, - HPE_CB_MESSAGE_COMPLETE = 17, - HPE_CB_CHUNK_HEADER = 18, - HPE_CB_CHUNK_COMPLETE = 19, - HPE_PAUSED = 20, - HPE_PAUSED_UPGRADE = 21, - HPE_USER = 22 + HPE_INVALID_TRANSFER_ENCODING = 15, + HPE_CB_MESSAGE_BEGIN = 16, + HPE_CB_HEADERS_COMPLETE = 17, + HPE_CB_MESSAGE_COMPLETE = 18, + HPE_CB_CHUNK_HEADER = 19, + HPE_CB_CHUNK_COMPLETE = 20, + HPE_PAUSED = 21, + HPE_PAUSED_UPGRADE = 22, + HPE_USER = 23 }; typedef enum llhttp_errno llhttp_errno_t; enum llhttp_flags { F_CONNECTION_KEEP_ALIVE = 0x1, @@ -106,14 +112,21 @@ F_CONNECTION_UPGRADE = 0x4, F_CHUNKED = 0x8, F_UPGRADE = 0x10, F_CONTENT_LENGTH = 0x20, F_SKIPBODY = 0x40, - F_TRAILING = 0x80 + F_TRAILING = 0x80, + F_TRANSFER_ENCODING = 0x200 }; typedef enum llhttp_flags llhttp_flags_t; +enum llhttp_lenient_flags { + LENIENT_HEADERS = 0x1, + LENIENT_CHUNKED_LENGTH = 0x2 +}; +typedef enum llhttp_lenient_flags llhttp_lenient_flags_t; + enum llhttp_type { HTTP_BOTH = 0, HTTP_REQUEST = 1, HTTP_RESPONSE = 2 }; @@ -158,11 +171,23 @@ HTTP_PATCH = 28, HTTP_PURGE = 29, HTTP_MKCALENDAR = 30, HTTP_LINK = 31, HTTP_UNLINK = 32, - HTTP_SOURCE = 33 + HTTP_SOURCE = 33, + HTTP_PRI = 34, + HTTP_DESCRIBE = 35, + HTTP_ANNOUNCE = 36, + HTTP_SETUP = 37, + HTTP_PLAY = 38, + HTTP_PAUSE = 39, + HTTP_TEARDOWN = 40, + HTTP_GET_PARAMETER = 41, + HTTP_SET_PARAMETER = 42, + HTTP_REDIRECT = 43, + HTTP_RECORD = 44, + HTTP_FLUSH = 45 }; typedef enum llhttp_method llhttp_method_t; #define HTTP_ERRNO_MAP(XX) \ XX(0, OK, OK) \ @@ -178,18 +203,19 @@ XX(10, INVALID_HEADER_TOKEN, INVALID_HEADER_TOKEN) \ XX(11, INVALID_CONTENT_LENGTH, INVALID_CONTENT_LENGTH) \ XX(12, INVALID_CHUNK_SIZE, INVALID_CHUNK_SIZE) \ XX(13, INVALID_STATUS, INVALID_STATUS) \ XX(14, INVALID_EOF_STATE, INVALID_EOF_STATE) \ - XX(15, CB_MESSAGE_BEGIN, CB_MESSAGE_BEGIN) \ - XX(16, CB_HEADERS_COMPLETE, CB_HEADERS_COMPLETE) \ - XX(17, CB_MESSAGE_COMPLETE, CB_MESSAGE_COMPLETE) \ - XX(18, CB_CHUNK_HEADER, CB_CHUNK_HEADER) \ - XX(19, CB_CHUNK_COMPLETE, CB_CHUNK_COMPLETE) \ - XX(20, PAUSED, PAUSED) \ - XX(21, PAUSED_UPGRADE, PAUSED_UPGRADE) \ - XX(22, USER, USER) \ + XX(15, INVALID_TRANSFER_ENCODING, INVALID_TRANSFER_ENCODING) \ + XX(16, CB_MESSAGE_BEGIN, CB_MESSAGE_BEGIN) \ + XX(17, CB_HEADERS_COMPLETE, CB_HEADERS_COMPLETE) \ + XX(18, CB_MESSAGE_COMPLETE, CB_MESSAGE_COMPLETE) \ + XX(19, CB_CHUNK_HEADER, CB_CHUNK_HEADER) \ + XX(20, CB_CHUNK_COMPLETE, CB_CHUNK_COMPLETE) \ + XX(21, PAUSED, PAUSED) \ + XX(22, PAUSED_UPGRADE, PAUSED_UPGRADE) \ + XX(23, USER, USER) \ #define HTTP_METHOD_MAP(XX) \ XX(0, DELETE, DELETE) \ XX(1, GET, GET) \ @@ -223,10 +249,22 @@ XX(29, PURGE, PURGE) \ XX(30, MKCALENDAR, MKCALENDAR) \ XX(31, LINK, LINK) \ XX(32, UNLINK, UNLINK) \ XX(33, SOURCE, SOURCE) \ + XX(34, PRI, PRI) \ + XX(35, DESCRIBE, DESCRIBE) \ + XX(36, ANNOUNCE, ANNOUNCE) \ + XX(37, SETUP, SETUP) \ + XX(38, PLAY, PLAY) \ + XX(39, PAUSE, PAUSE) \ + XX(40, TEARDOWN, TEARDOWN) \ + XX(41, GET_PARAMETER, GET_PARAMETER) \ + XX(42, SET_PARAMETER, SET_PARAMETER) \ + XX(43, REDIRECT, REDIRECT) \ + XX(44, RECORD, RECORD) \ + XX(45, FLUSH, FLUSH) \ #ifdef __cplusplus } /* extern "C" */ @@ -275,16 +313,31 @@ * in parser->content_length. * Possible return values 0, -1, `HPE_PAUSED` */ llhttp_cb on_chunk_header; llhttp_cb on_chunk_complete; + + llhttp_cb on_url_complete; + llhttp_cb on_status_complete; + llhttp_cb on_header_field_complete; + llhttp_cb on_header_value_complete; }; -/* Initialize the parser with specific type and user settings */ +/* Initialize the parser with specific type and user settings. + * + * NOTE: lifetime of `settings` has to be at least the same as the lifetime of + * the `parser` here. In practice, `settings` has to be either a static + * variable or be allocated with `malloc`, `new`, etc. + */ void llhttp_init(llhttp_t* parser, llhttp_type_t type, const llhttp_settings_t* settings); +/* Reset an already initialized parser back to the start state, preserving the + * existing parser type, callback settings, user data, and lenient flags. + */ +void llhttp_reset(llhttp_t* parser); + /* Initialize the settings object */ void llhttp_settings_init(llhttp_settings_t* settings); /* Parse full or partial request/response, invoking user callbacks along the * way. @@ -298,11 +351,11 @@ * is returned after fully parsing the request/response. If the user wishes to * continue parsing, they need to invoke `llhttp_resume_after_upgrade()`. * * NOTE: if this function ever returns a non-pause type error, it will continue * to return the same error upon each successive call up until `llhttp_init()` - * call. + * is called. */ llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len); /* This method should be called when the other side has no further bytes to * send (e.g. shutdown of readable side of the TCP connection.) @@ -318,11 +371,11 @@ * to be completed by calling `llhttp_finish()` on EOF */ int llhttp_message_needs_eof(const llhttp_t* parser); /* Returns `1` if there might be any other messages following the last that was - * successfuly parsed. + * successfully parsed. */ int llhttp_should_keep_alive(const llhttp_t* parser); /* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set * appropriate error reason. @@ -373,9 +426,34 @@ /* Returns textual name of error code */ const char* llhttp_errno_name(llhttp_errno_t err); /* Returns textual name of HTTP method */ const char* llhttp_method_name(llhttp_method_t method); + + +/* Enables/disables lenient header value parsing (disabled by default). + * + * Lenient parsing disables header value token checks, extending llhttp's + * protocol support to highly non-compliant clients/server. No + * `HPE_INVALID_HEADER_TOKEN` will be raised for incorrect header values when + * lenient parsing is "on". + * + * **(USE AT YOUR OWN RISK)** + */ +void llhttp_set_lenient_headers(llhttp_t* parser, int enabled); + + +/* Enables/disables lenient handling of conflicting `Transfer-Encoding` and + * `Content-Length` headers (disabled by default). + * + * Normally `llhttp` would error when `Transfer-Encoding` is present in + * conjunction with `Content-Length`. This error is important to prevent HTTP + * request smuggling, but may be less desirable for small number of cases + * involving legacy servers. + * + * **(USE AT YOUR OWN RISK)** + */ +void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* INCLUDE_LLHTTP_API_H_ */