12c593315Sopenharmony_ci# llhttp
22c593315Sopenharmony_ci[![CI](https://github.com/nodejs/llhttp/workflows/CI/badge.svg)](https://github.com/nodejs/llhttp/actions?query=workflow%3ACI)
32c593315Sopenharmony_ci
42c593315Sopenharmony_ciPort of [http_parser][0] to [llparse][1].
52c593315Sopenharmony_ci
62c593315Sopenharmony_ci## Why?
72c593315Sopenharmony_ci
82c593315Sopenharmony_ciLet's face it, [http_parser][0] is practically unmaintainable. Even
92c593315Sopenharmony_ciintroduction of a single new method results in a significant code churn.
102c593315Sopenharmony_ci
112c593315Sopenharmony_ciThis project aims to:
122c593315Sopenharmony_ci
132c593315Sopenharmony_ci* Make it maintainable
142c593315Sopenharmony_ci* Verifiable
152c593315Sopenharmony_ci* Improving benchmarks where possible
162c593315Sopenharmony_ci
172c593315Sopenharmony_ciMore details in [Fedor Indutny's talk at JSConf EU 2019](https://youtu.be/x3k_5Mi66sY)
182c593315Sopenharmony_ci
192c593315Sopenharmony_ci## How?
202c593315Sopenharmony_ci
212c593315Sopenharmony_ciOver time, different approaches for improving [http_parser][0]'s code base
222c593315Sopenharmony_ciwere tried. However, all of them failed due to resulting significant performance
232c593315Sopenharmony_cidegradation.
242c593315Sopenharmony_ci
252c593315Sopenharmony_ciThis project is a port of [http_parser][0] to TypeScript. [llparse][1] is used
262c593315Sopenharmony_cito generate the output C source file, which could be compiled and
272c593315Sopenharmony_cilinked with the embedder's program (like [Node.js][7]).
282c593315Sopenharmony_ci
292c593315Sopenharmony_ci## Performance
302c593315Sopenharmony_ci
312c593315Sopenharmony_ciSo far llhttp outperforms http_parser:
322c593315Sopenharmony_ci
332c593315Sopenharmony_ci|                 | input size |  bandwidth   |  reqs/sec  |   time  |
342c593315Sopenharmony_ci|:----------------|-----------:|-------------:|-----------:|--------:|
352c593315Sopenharmony_ci| **llhttp**      | 8192.00 mb | 1777.24 mb/s | 3583799.39 req/sec | 4.61 s |
362c593315Sopenharmony_ci| **http_parser** | 8192.00 mb | 694.66 mb/s | 1406180.33 req/sec | 11.79 s |
372c593315Sopenharmony_ci
382c593315Sopenharmony_cillhttp is faster by approximately **156%**.
392c593315Sopenharmony_ci
402c593315Sopenharmony_ci## Maintenance
412c593315Sopenharmony_ci
422c593315Sopenharmony_cillhttp project has about 1400 lines of TypeScript code describing the parser
432c593315Sopenharmony_ciitself and around 450 lines of C code and headers providing the helper methods.
442c593315Sopenharmony_ciThe whole [http_parser][0] is implemented in approximately 2500 lines of C, and
452c593315Sopenharmony_ci436 lines of headers.
462c593315Sopenharmony_ci
472c593315Sopenharmony_ciAll optimizations and multi-character matching in llhttp are generated
482c593315Sopenharmony_ciautomatically, and thus doesn't add any extra maintenance cost. On the contrary,
492c593315Sopenharmony_cimost of http_parser's code is hand-optimized and unrolled. Instead describing
502c593315Sopenharmony_ci"how" it should parse the HTTP requests/responses, a maintainer should
512c593315Sopenharmony_ciimplement the new features in [http_parser][0] cautiously, considering
522c593315Sopenharmony_cipossible performance degradation and manually optimizing the new code.
532c593315Sopenharmony_ci
542c593315Sopenharmony_ci## Verification
552c593315Sopenharmony_ci
562c593315Sopenharmony_ciThe state machine graph is encoded explicitly in llhttp. The [llparse][1]
572c593315Sopenharmony_ciautomatically checks the graph for absence of loops and correct reporting of the
582c593315Sopenharmony_ciinput ranges (spans) like header names and values. In the future, additional
592c593315Sopenharmony_cichecks could be performed to get even stricter verification of the llhttp.
602c593315Sopenharmony_ci
612c593315Sopenharmony_ci## Usage
622c593315Sopenharmony_ci
632c593315Sopenharmony_ci```C
642c593315Sopenharmony_ci#include "stdio.h"
652c593315Sopenharmony_ci#include "llhttp.h"
662c593315Sopenharmony_ci#include "string.h"
672c593315Sopenharmony_ci
682c593315Sopenharmony_ciint handle_on_message_complete(llhttp_t* parser) {
692c593315Sopenharmony_ci	fprintf(stdout, "Message completed!\n");
702c593315Sopenharmony_ci	return 0;
712c593315Sopenharmony_ci}
722c593315Sopenharmony_ci
732c593315Sopenharmony_ciint main() {
742c593315Sopenharmony_ci	llhttp_t parser;
752c593315Sopenharmony_ci	llhttp_settings_t settings;
762c593315Sopenharmony_ci
772c593315Sopenharmony_ci	/*Initialize user callbacks and settings */
782c593315Sopenharmony_ci	llhttp_settings_init(&settings);
792c593315Sopenharmony_ci
802c593315Sopenharmony_ci	/*Set user callback */
812c593315Sopenharmony_ci	settings.on_message_complete = handle_on_message_complete;
822c593315Sopenharmony_ci
832c593315Sopenharmony_ci	/*Initialize the parser in HTTP_BOTH mode, meaning that it will select between
842c593315Sopenharmony_ci	*HTTP_REQUEST and HTTP_RESPONSE parsing automatically while reading the first
852c593315Sopenharmony_ci	*input.
862c593315Sopenharmony_ci	*/
872c593315Sopenharmony_ci	llhttp_init(&parser, HTTP_BOTH, &settings);
882c593315Sopenharmony_ci
892c593315Sopenharmony_ci	/*Parse request! */
902c593315Sopenharmony_ci	const char* request = "GET / HTTP/1.1\r\n\r\n";
912c593315Sopenharmony_ci	int request_len = strlen(request);
922c593315Sopenharmony_ci
932c593315Sopenharmony_ci	enum llhttp_errno err = llhttp_execute(&parser, request, request_len);
942c593315Sopenharmony_ci	if (err == HPE_OK) {
952c593315Sopenharmony_ci		fprintf(stdout, "Successfully parsed!\n");
962c593315Sopenharmony_ci	} else {
972c593315Sopenharmony_ci		fprintf(stderr, "Parse error: %s %s\n", llhttp_errno_name(err), parser.reason);
982c593315Sopenharmony_ci	}
992c593315Sopenharmony_ci}
1002c593315Sopenharmony_ci```
1012c593315Sopenharmony_ciFor more information on API usage, please refer to [src/native/api.h](https://github.com/nodejs/llhttp/blob/main/src/native/api.h).
1022c593315Sopenharmony_ci
1032c593315Sopenharmony_ci## API
1042c593315Sopenharmony_ci
1052c593315Sopenharmony_ci### llhttp_settings_t
1062c593315Sopenharmony_ci
1072c593315Sopenharmony_ciThe settings object contains a list of callbacks that the parser will invoke.
1082c593315Sopenharmony_ci
1092c593315Sopenharmony_ciThe following callbacks can return `0` (proceed normally), `-1` (error) or `HPE_PAUSED` (pause the parser):
1102c593315Sopenharmony_ci
1112c593315Sopenharmony_ci* `on_message_begin`: Invoked when a new request/response starts.
1122c593315Sopenharmony_ci* `on_message_complete`: Invoked when a request/response has been completedly parsed.
1132c593315Sopenharmony_ci* `on_url_complete`: Invoked after the URL has been parsed.
1142c593315Sopenharmony_ci* `on_method_complete`: Invoked after the HTTP method has been parsed.
1152c593315Sopenharmony_ci* `on_version_complete`: Invoked after the HTTP version has been parsed.
1162c593315Sopenharmony_ci* `on_status_complete`: Invoked after the status code has been parsed.
1172c593315Sopenharmony_ci* `on_header_field_complete`: Invoked after a header name has been parsed.
1182c593315Sopenharmony_ci* `on_header_value_complete`: Invoked after a header value has been parsed.
1192c593315Sopenharmony_ci* `on_chunk_header`: Invoked after a new chunk is started. The current chunk length is stored in `parser->content_length`.
1202c593315Sopenharmony_ci* `on_chunk_extension_name_complete`: Invoked after a chunk extension name is started.
1212c593315Sopenharmony_ci* `on_chunk_extension_value_complete`: Invoked after a chunk extension value is started.
1222c593315Sopenharmony_ci* `on_chunk_complete`: Invoked after a new chunk is received. 
1232c593315Sopenharmony_ci* `on_reset`: Invoked after `on_message_complete` and before `on_message_begin` when a new message 
1242c593315Sopenharmony_ci   is received on the same parser. This is not invoked for the first message of the parser.
1252c593315Sopenharmony_ci
1262c593315Sopenharmony_ciThe following callbacks can return `0` (proceed normally), `-1` (error) or `HPE_USER` (error from the callback): 
1272c593315Sopenharmony_ci
1282c593315Sopenharmony_ci* `on_url`: Invoked when another character of the URL is received. 
1292c593315Sopenharmony_ci* `on_status`: Invoked when another character of the status is received.
1302c593315Sopenharmony_ci* `on_method`: Invoked when another character of the method is received. 
1312c593315Sopenharmony_ci   When parser is created with `HTTP_BOTH` and the input is a response, this also invoked for the sequence `HTTP/`
1322c593315Sopenharmony_ci   of the first message.
1332c593315Sopenharmony_ci* `on_version`: Invoked when another character of the version is received.
1342c593315Sopenharmony_ci* `on_header_field`: Invoked when another character of a header name is received.
1352c593315Sopenharmony_ci* `on_header_value`: Invoked when another character of a header value is received.
1362c593315Sopenharmony_ci* `on_chunk_extension_name`: Invoked when another character of a chunk extension name is received.
1372c593315Sopenharmony_ci* `on_chunk_extension_value`: Invoked when another character of a extension value is received.
1382c593315Sopenharmony_ci
1392c593315Sopenharmony_ciThe callback `on_headers_complete`, invoked when headers are completed, can return:
1402c593315Sopenharmony_ci
1412c593315Sopenharmony_ci* `0`: Proceed normally.
1422c593315Sopenharmony_ci* `1`: Assume that request/response has no body, and proceed to parsing the next message.
1432c593315Sopenharmony_ci* `2`: Assume absence of body (as above) and make `llhttp_execute()` return `HPE_PAUSED_UPGRADE`.
1442c593315Sopenharmony_ci* `-1`: Error
1452c593315Sopenharmony_ci* `HPE_PAUSED`: Pause the parser.
1462c593315Sopenharmony_ci
1472c593315Sopenharmony_ci### `void llhttp_init(llhttp_t* parser, llhttp_type_t type, const llhttp_settings_t* settings)`
1482c593315Sopenharmony_ci
1492c593315Sopenharmony_ciInitialize the parser with specific type and user settings.
1502c593315Sopenharmony_ci
1512c593315Sopenharmony_ci### `uint8_t llhttp_get_type(llhttp_t* parser)`
1522c593315Sopenharmony_ci
1532c593315Sopenharmony_ciReturns the type of the parser.
1542c593315Sopenharmony_ci
1552c593315Sopenharmony_ci### `uint8_t llhttp_get_http_major(llhttp_t* parser)`
1562c593315Sopenharmony_ci
1572c593315Sopenharmony_ciReturns the major version of the HTTP protocol of the current request/response.
1582c593315Sopenharmony_ci
1592c593315Sopenharmony_ci### `uint8_t llhttp_get_http_minor(llhttp_t* parser)`
1602c593315Sopenharmony_ci
1612c593315Sopenharmony_ciReturns the minor version of the HTTP protocol of the current request/response.
1622c593315Sopenharmony_ci
1632c593315Sopenharmony_ci### `uint8_t llhttp_get_method(llhttp_t* parser)`
1642c593315Sopenharmony_ci
1652c593315Sopenharmony_ciReturns the method of the current request.
1662c593315Sopenharmony_ci
1672c593315Sopenharmony_ci### `int llhttp_get_status_code(llhttp_t* parser)`
1682c593315Sopenharmony_ci
1692c593315Sopenharmony_ciReturns the method of the current response.
1702c593315Sopenharmony_ci
1712c593315Sopenharmony_ci### `uint8_t llhttp_get_upgrade(llhttp_t* parser)`
1722c593315Sopenharmony_ci
1732c593315Sopenharmony_ciReturns `1` if request includes the `Connection: upgrade` header.
1742c593315Sopenharmony_ci
1752c593315Sopenharmony_ci### `void llhttp_reset(llhttp_t* parser)`
1762c593315Sopenharmony_ci
1772c593315Sopenharmony_ciReset an already initialized parser back to the start state, preserving the 
1782c593315Sopenharmony_ciexisting parser type, callback settings, user data, and lenient flags.
1792c593315Sopenharmony_ci
1802c593315Sopenharmony_ci### `void llhttp_settings_init(llhttp_settings_t* settings)`
1812c593315Sopenharmony_ci
1822c593315Sopenharmony_ciInitialize the settings object.
1832c593315Sopenharmony_ci
1842c593315Sopenharmony_ci### `llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len)`
1852c593315Sopenharmony_ci
1862c593315Sopenharmony_ciParse full or partial request/response, invoking user callbacks along the way.
1872c593315Sopenharmony_ci
1882c593315Sopenharmony_ciIf any of `llhttp_data_cb` returns errno not equal to `HPE_OK` - the parsing interrupts, 
1892c593315Sopenharmony_ciand such errno is returned from `llhttp_execute()`. If `HPE_PAUSED` was used as a errno, 
1902c593315Sopenharmony_cithe execution can be resumed with `llhttp_resume()` call.
1912c593315Sopenharmony_ci
1922c593315Sopenharmony_ciIn a special case of CONNECT/Upgrade request/response `HPE_PAUSED_UPGRADE` is returned 
1932c593315Sopenharmony_ciafter fully parsing the request/response. If the user wishes to continue parsing, 
1942c593315Sopenharmony_cithey need to invoke `llhttp_resume_after_upgrade()`.
1952c593315Sopenharmony_ci
1962c593315Sopenharmony_ci**if this function ever returns a non-pause type error, it will continue to return 
1972c593315Sopenharmony_cithe same error upon each successive call up until `llhttp_init()` is called.**
1982c593315Sopenharmony_ci
1992c593315Sopenharmony_ci### `llhttp_errno_t llhttp_finish(llhttp_t* parser)`
2002c593315Sopenharmony_ci
2012c593315Sopenharmony_ciThis method should be called when the other side has no further bytes to
2022c593315Sopenharmony_cisend (e.g. shutdown of readable side of the TCP connection.)
2032c593315Sopenharmony_ci
2042c593315Sopenharmony_ciRequests without `Content-Length` and other messages might require treating
2052c593315Sopenharmony_ciall incoming bytes as the part of the body, up to the last byte of the
2062c593315Sopenharmony_ciconnection. 
2072c593315Sopenharmony_ci
2082c593315Sopenharmony_ciThis method will invoke `on_message_complete()` callback if the
2092c593315Sopenharmony_cirequest was terminated safely. Otherwise a error code would be returned.
2102c593315Sopenharmony_ci
2112c593315Sopenharmony_ci
2122c593315Sopenharmony_ci### `int llhttp_message_needs_eof(const llhttp_t* parser)`
2132c593315Sopenharmony_ci
2142c593315Sopenharmony_ciReturns `1` if the incoming message is parsed until the last byte, and has to be completed by calling `llhttp_finish()` on EOF.
2152c593315Sopenharmony_ci
2162c593315Sopenharmony_ci### `int llhttp_should_keep_alive(const llhttp_t* parser)`
2172c593315Sopenharmony_ci
2182c593315Sopenharmony_ciReturns `1` if there might be any other messages following the last that was
2192c593315Sopenharmony_cisuccessfully parsed.
2202c593315Sopenharmony_ci
2212c593315Sopenharmony_ci### `void llhttp_pause(llhttp_t* parser)`
2222c593315Sopenharmony_ci
2232c593315Sopenharmony_ciMake further calls of `llhttp_execute()` return `HPE_PAUSED` and set
2242c593315Sopenharmony_ciappropriate error reason.
2252c593315Sopenharmony_ci
2262c593315Sopenharmony_ci**Do not call this from user callbacks! User callbacks must return
2272c593315Sopenharmony_ci`HPE_PAUSED` if pausing is required.**
2282c593315Sopenharmony_ci
2292c593315Sopenharmony_ci### `void llhttp_resume(llhttp_t* parser)`
2302c593315Sopenharmony_ci
2312c593315Sopenharmony_ciMight be called to resume the execution after the pause in user's callback.
2322c593315Sopenharmony_ci
2332c593315Sopenharmony_ciSee `llhttp_execute()` above for details.
2342c593315Sopenharmony_ci
2352c593315Sopenharmony_ci**Call this only if `llhttp_execute()` returns `HPE_PAUSED`.**
2362c593315Sopenharmony_ci
2372c593315Sopenharmony_ci### `void llhttp_resume_after_upgrade(llhttp_t* parser)`
2382c593315Sopenharmony_ci
2392c593315Sopenharmony_ciMight be called to resume the execution after the pause in user's callback.
2402c593315Sopenharmony_ciSee `llhttp_execute()` above for details.
2412c593315Sopenharmony_ci
2422c593315Sopenharmony_ci**Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE`**
2432c593315Sopenharmony_ci
2442c593315Sopenharmony_ci### `llhttp_errno_t llhttp_get_errno(const llhttp_t* parser)`
2452c593315Sopenharmony_ci
2462c593315Sopenharmony_ciReturns the latest error.
2472c593315Sopenharmony_ci
2482c593315Sopenharmony_ci### `const char* llhttp_get_error_reason(const llhttp_t* parser)`
2492c593315Sopenharmony_ci
2502c593315Sopenharmony_ciReturns the verbal explanation of the latest returned error.
2512c593315Sopenharmony_ci
2522c593315Sopenharmony_ci**User callback should set error reason when returning the error. See
2532c593315Sopenharmony_ci`llhttp_set_error_reason()` for details.**
2542c593315Sopenharmony_ci
2552c593315Sopenharmony_ci### `void llhttp_set_error_reason(llhttp_t* parser, const char* reason)`
2562c593315Sopenharmony_ci
2572c593315Sopenharmony_ciAssign verbal description to the returned error. Must be called in user
2582c593315Sopenharmony_cicallbacks right before returning the errno.
2592c593315Sopenharmony_ci
2602c593315Sopenharmony_ci**`HPE_USER` error code might be useful in user callbacks.**
2612c593315Sopenharmony_ci
2622c593315Sopenharmony_ci### `const char* llhttp_get_error_pos(const llhttp_t* parser)`
2632c593315Sopenharmony_ci
2642c593315Sopenharmony_ciReturns the pointer to the last parsed byte before the returned error. The
2652c593315Sopenharmony_cipointer is relative to the `data` argument of `llhttp_execute()`.
2662c593315Sopenharmony_ci
2672c593315Sopenharmony_ci**This method might be useful for counting the number of parsed bytes.**
2682c593315Sopenharmony_ci
2692c593315Sopenharmony_ci### `const char* llhttp_errno_name(llhttp_errno_t err)`
2702c593315Sopenharmony_ci
2712c593315Sopenharmony_ciReturns textual name of error code.
2722c593315Sopenharmony_ci
2732c593315Sopenharmony_ci### `const char* llhttp_method_name(llhttp_method_t method)`
2742c593315Sopenharmony_ci
2752c593315Sopenharmony_ciReturns textual name of HTTP method.
2762c593315Sopenharmony_ci
2772c593315Sopenharmony_ci### `const char* llhttp_status_name(llhttp_status_t status)`
2782c593315Sopenharmony_ci
2792c593315Sopenharmony_ciReturns textual name of HTTP status.
2802c593315Sopenharmony_ci
2812c593315Sopenharmony_ci### `void llhttp_set_lenient_headers(llhttp_t* parser, int enabled)`
2822c593315Sopenharmony_ci
2832c593315Sopenharmony_ciEnables/disables lenient header value parsing (disabled by default).
2842c593315Sopenharmony_ciLenient parsing disables header value token checks, extending llhttp's
2852c593315Sopenharmony_ciprotocol support to highly non-compliant clients/server. 
2862c593315Sopenharmony_ci
2872c593315Sopenharmony_ciNo `HPE_INVALID_HEADER_TOKEN` will be raised for incorrect header values when
2882c593315Sopenharmony_cilenient parsing is "on".
2892c593315Sopenharmony_ci
2902c593315Sopenharmony_ci**Enabling this flag can pose a security issue since you will be exposed to request smuggling attacks. USE WITH CAUTION!**
2912c593315Sopenharmony_ci
2922c593315Sopenharmony_ci### `void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled)`
2932c593315Sopenharmony_ci
2942c593315Sopenharmony_ciEnables/disables lenient handling of conflicting `Transfer-Encoding` and
2952c593315Sopenharmony_ci`Content-Length` headers (disabled by default).
2962c593315Sopenharmony_ci
2972c593315Sopenharmony_ciNormally `llhttp` would error when `Transfer-Encoding` is present in
2982c593315Sopenharmony_ciconjunction with `Content-Length`. 
2992c593315Sopenharmony_ci
3002c593315Sopenharmony_ciThis error is important to prevent HTTP request smuggling, but may be less desirable
3012c593315Sopenharmony_cifor small number of cases involving legacy servers.
3022c593315Sopenharmony_ci
3032c593315Sopenharmony_ci**Enabling this flag can pose a security issue since you will be exposed to request smuggling attacks. USE WITH CAUTION!**
3042c593315Sopenharmony_ci
3052c593315Sopenharmony_ci### `void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled)`
3062c593315Sopenharmony_ci
3072c593315Sopenharmony_ciEnables/disables lenient handling of `Connection: close` and HTTP/1.0
3082c593315Sopenharmony_cirequests responses.
3092c593315Sopenharmony_ci
3102c593315Sopenharmony_ciNormally `llhttp` would error the HTTP request/response 
3112c593315Sopenharmony_ciafter the request/response with `Connection: close` and `Content-Length`. 
3122c593315Sopenharmony_ci
3132c593315Sopenharmony_ciThis is important to prevent cache poisoning attacks,
3142c593315Sopenharmony_cibut might interact badly with outdated and insecure clients. 
3152c593315Sopenharmony_ci
3162c593315Sopenharmony_ciWith this flag the extra request/response will be parsed normally.
3172c593315Sopenharmony_ci
3182c593315Sopenharmony_ci**Enabling this flag can pose a security issue since you will be exposed to poisoning attacks. USE WITH CAUTION!**
3192c593315Sopenharmony_ci
3202c593315Sopenharmony_ci### `void llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled)`
3212c593315Sopenharmony_ci
3222c593315Sopenharmony_ciEnables/disables lenient handling of `Transfer-Encoding` header.
3232c593315Sopenharmony_ci
3242c593315Sopenharmony_ciNormally `llhttp` would error when a `Transfer-Encoding` has `chunked` value
3252c593315Sopenharmony_ciand another value after it (either in a single header or in multiple
3262c593315Sopenharmony_ciheaders whose value are internally joined using `, `).
3272c593315Sopenharmony_ci
3282c593315Sopenharmony_ciThis is mandated by the spec to reliably determine request body size and thus
3292c593315Sopenharmony_ciavoid request smuggling.
3302c593315Sopenharmony_ci
3312c593315Sopenharmony_ciWith this flag the extra value will be parsed normally.
3322c593315Sopenharmony_ci
3332c593315Sopenharmony_ci**Enabling this flag can pose a security issue since you will be exposed to request smuggling attacks. USE WITH CAUTION!**
3342c593315Sopenharmony_ci
3352c593315Sopenharmony_ci### `void llhttp_set_lenient_version(llhttp_t* parser, int enabled)`
3362c593315Sopenharmony_ci
3372c593315Sopenharmony_ciEnables/disables lenient handling of HTTP version.
3382c593315Sopenharmony_ci
3392c593315Sopenharmony_ciNormally `llhttp` would error when the HTTP version in the request or status line
3402c593315Sopenharmony_ciis not `0.9`, `1.0`, `1.1` or `2.0`.
3412c593315Sopenharmony_ciWith this flag the extra value will be parsed normally.
3422c593315Sopenharmony_ci
3432c593315Sopenharmony_ci**Enabling this flag can pose a security issue since you will allow unsupported HTTP versions. USE WITH CAUTION!**
3442c593315Sopenharmony_ci
3452c593315Sopenharmony_ci### `void llhttp_set_lenient_data_after_close(llhttp_t* parser, int enabled)`
3462c593315Sopenharmony_ci
3472c593315Sopenharmony_ciEnables/disables lenient handling of additional data received after a message ends
3482c593315Sopenharmony_ciand keep-alive is disabled.
3492c593315Sopenharmony_ci
3502c593315Sopenharmony_ciNormally `llhttp` would error when additional unexpected data is received if the message
3512c593315Sopenharmony_cicontains the `Connection` header with `close` value.
3522c593315Sopenharmony_ciWith this flag the extra data will discarded without throwing an error.
3532c593315Sopenharmony_ci
3542c593315Sopenharmony_ci**Enabling this flag can pose a security issue since you will be exposed to poisoning attacks. USE WITH CAUTION!**
3552c593315Sopenharmony_ci
3562c593315Sopenharmony_ci### `void llhttp_set_lenient_optional_lf_after_cr(llhttp_t* parser, int enabled)`
3572c593315Sopenharmony_ci
3582c593315Sopenharmony_ciEnables/disables lenient handling of incomplete CRLF sequences.
3592c593315Sopenharmony_ci
3602c593315Sopenharmony_ciNormally `llhttp` would error when a CR is not followed by LF when terminating the
3612c593315Sopenharmony_cirequest line, the status line, the headers or a chunk header.
3622c593315Sopenharmony_ciWith this flag only a CR is required to terminate such sections.
3632c593315Sopenharmony_ci
3642c593315Sopenharmony_ci**Enabling this flag can pose a security issue since you will be exposed to request smuggling attacks. USE WITH CAUTION!**
3652c593315Sopenharmony_ci
3662c593315Sopenharmony_ci### `void llhttp_set_lenient_optional_crlf_after_chunk(llhttp_t* parser, int enabled)`
3672c593315Sopenharmony_ci
3682c593315Sopenharmony_ciEnables/disables lenient handling of chunks not separated via CRLF.
3692c593315Sopenharmony_ci
3702c593315Sopenharmony_ciNormally `llhttp` would error when after a chunk data a CRLF is missing before
3712c593315Sopenharmony_cistarting a new chunk.
3722c593315Sopenharmony_ciWith this flag the new chunk can start immediately after the previous one.
3732c593315Sopenharmony_ci
3742c593315Sopenharmony_ci**Enabling this flag can pose a security issue since you will be exposed to request smuggling attacks. USE WITH CAUTION!**
3752c593315Sopenharmony_ci
3762c593315Sopenharmony_ci## Build Instructions
3772c593315Sopenharmony_ci
3782c593315Sopenharmony_ciMake sure you have [Node.js](https://nodejs.org/), npm and npx installed. Then under project directory run:
3792c593315Sopenharmony_ci
3802c593315Sopenharmony_ci```sh
3812c593315Sopenharmony_cinpm install
3822c593315Sopenharmony_cimake
3832c593315Sopenharmony_ci```
3842c593315Sopenharmony_ci
3852c593315Sopenharmony_ci---
3862c593315Sopenharmony_ci
3872c593315Sopenharmony_ci### Bindings to other languages
3882c593315Sopenharmony_ci
3892c593315Sopenharmony_ci* Lua: [MunifTanjim/llhttp.lua][11]
3902c593315Sopenharmony_ci* Python: [pallas/pyllhttp][8]
3912c593315Sopenharmony_ci* Ruby: [metabahn/llhttp][9]
3922c593315Sopenharmony_ci* Rust: [JackLiar/rust-llhttp][10]
3932c593315Sopenharmony_ci
3942c593315Sopenharmony_ci### Using with CMake
3952c593315Sopenharmony_ci
3962c593315Sopenharmony_ciIf you want to use this library in a CMake project as a shared library, you can use the snippet below.
3972c593315Sopenharmony_ci
3982c593315Sopenharmony_ci```
3992c593315Sopenharmony_ciFetchContent_Declare(llhttp
4002c593315Sopenharmony_ci  URL "https://github.com/nodejs/llhttp/archive/refs/tags/release/v8.1.0.tar.gz")
4012c593315Sopenharmony_ci
4022c593315Sopenharmony_ciFetchContent_MakeAvailable(llhttp)
4032c593315Sopenharmony_ci
4042c593315Sopenharmony_ci# Link with the llhttp_shared target
4052c593315Sopenharmony_citarget_link_libraries(${EXAMPLE_PROJECT_NAME} ${PROJECT_LIBRARIES} llhttp_shared ${PROJECT_NAME})
4062c593315Sopenharmony_ci```
4072c593315Sopenharmony_ci
4082c593315Sopenharmony_ciIf you want to use this library in a CMake project as a static library, you can set some cache variables first.
4092c593315Sopenharmony_ci
4102c593315Sopenharmony_ci```
4112c593315Sopenharmony_ciFetchContent_Declare(llhttp
4122c593315Sopenharmony_ci  URL "https://github.com/nodejs/llhttp/archive/refs/tags/release/v8.1.0.tar.gz")
4132c593315Sopenharmony_ci
4142c593315Sopenharmony_ciset(BUILD_SHARED_LIBS OFF CACHE INTERNAL "")
4152c593315Sopenharmony_ciset(BUILD_STATIC_LIBS ON CACHE INTERNAL "")
4162c593315Sopenharmony_ciFetchContent_MakeAvailable(llhttp)
4172c593315Sopenharmony_ci
4182c593315Sopenharmony_ci# Link with the llhttp_static target
4192c593315Sopenharmony_citarget_link_libraries(${EXAMPLE_PROJECT_NAME} ${PROJECT_LIBRARIES} llhttp_static ${PROJECT_NAME})
4202c593315Sopenharmony_ci```
4212c593315Sopenharmony_ci
4222c593315Sopenharmony_ci_Note that using the git repo directly (e.g., via a git repo url and tag) will not work with FetchContent_Declare because [CMakeLists.txt](./CMakeLists.txt) requires string replacements (e.g., `_RELEASE_`) before it will build._
4232c593315Sopenharmony_ci
4242c593315Sopenharmony_ci## Building on Windows
4252c593315Sopenharmony_ci
4262c593315Sopenharmony_ci### Installation
4272c593315Sopenharmony_ci
4282c593315Sopenharmony_ci* `choco install git`
4292c593315Sopenharmony_ci* `choco install node`
4302c593315Sopenharmony_ci* `choco install llvm` (or install the `C++ Clang tools for Windows` optional package from the Visual Studio 2019 installer)
4312c593315Sopenharmony_ci* `choco install make` (or if you have MinGW, it comes bundled)
4322c593315Sopenharmony_ci
4332c593315Sopenharmony_ci1. Ensure that `Clang` and `make` are in your system path.
4342c593315Sopenharmony_ci2. Using Git Bash, clone the repo to your preferred location.
4352c593315Sopenharmony_ci3. Cd into the cloned directory and run `npm install`
4362c593315Sopenharmony_ci5. Run `make`
4372c593315Sopenharmony_ci6. Your `repo/build` directory should now have `libllhttp.a` and `libllhttp.so` static and dynamic libraries.
4382c593315Sopenharmony_ci7. When building your executable, you can link to these libraries. Make sure to set the build folder as an include path when building so you can reference the declarations in `repo/build/llhttp.h`.
4392c593315Sopenharmony_ci
4402c593315Sopenharmony_ci### A simple example on linking with the library:
4412c593315Sopenharmony_ci
4422c593315Sopenharmony_ciAssuming you have an executable `main.cpp` in your current working directory, you would run: `clang++ -Os -g3 -Wall -Wextra -Wno-unused-parameter -I/path/to/llhttp/build main.cpp /path/to/llhttp/build/libllhttp.a -o main.exe`.
4432c593315Sopenharmony_ci
4442c593315Sopenharmony_ciIf you are getting `unresolved external symbol` linker errors you are likely attempting to build `llhttp.c` without linking it with object files from `api.c` and `http.c`.
4452c593315Sopenharmony_ci
4462c593315Sopenharmony_ci#### LICENSE
4472c593315Sopenharmony_ci
4482c593315Sopenharmony_ciThis software is licensed under the MIT License.
4492c593315Sopenharmony_ci
4502c593315Sopenharmony_ciCopyright Fedor Indutny, 2018.
4512c593315Sopenharmony_ci
4522c593315Sopenharmony_ciPermission is hereby granted, free of charge, to any person obtaining a
4532c593315Sopenharmony_cicopy of this software and associated documentation files (the
4542c593315Sopenharmony_ci"Software"), to deal in the Software without restriction, including
4552c593315Sopenharmony_ciwithout limitation the rights to use, copy, modify, merge, publish,
4562c593315Sopenharmony_cidistribute, sublicense, and/or sell copies of the Software, and to permit
4572c593315Sopenharmony_cipersons to whom the Software is furnished to do so, subject to the
4582c593315Sopenharmony_cifollowing conditions:
4592c593315Sopenharmony_ci
4602c593315Sopenharmony_ciThe above copyright notice and this permission notice shall be included
4612c593315Sopenharmony_ciin all copies or substantial portions of the Software.
4622c593315Sopenharmony_ci
4632c593315Sopenharmony_ciTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
4642c593315Sopenharmony_ciOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
4652c593315Sopenharmony_ciMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
4662c593315Sopenharmony_ciNO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
4672c593315Sopenharmony_ciDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
4682c593315Sopenharmony_ciOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
4692c593315Sopenharmony_ciUSE OR OTHER DEALINGS IN THE SOFTWARE.
4702c593315Sopenharmony_ci
4712c593315Sopenharmony_ci[0]: https://github.com/nodejs/http-parser
4722c593315Sopenharmony_ci[1]: https://github.com/nodejs/llparse
4732c593315Sopenharmony_ci[2]: https://en.wikipedia.org/wiki/Register_allocation#Spilling
4742c593315Sopenharmony_ci[3]: https://en.wikipedia.org/wiki/Tail_call
4752c593315Sopenharmony_ci[4]: https://llvm.org/docs/LangRef.html
4762c593315Sopenharmony_ci[5]: https://llvm.org/docs/LangRef.html#call-instruction
4772c593315Sopenharmony_ci[6]: https://clang.llvm.org/
4782c593315Sopenharmony_ci[7]: https://github.com/nodejs/node
4792c593315Sopenharmony_ci[8]: https://github.com/pallas/pyllhttp
4802c593315Sopenharmony_ci[9]: https://github.com/metabahn/llhttp
4812c593315Sopenharmony_ci[10]: https://github.com/JackLiar/rust-llhttp
4822c593315Sopenharmony_ci[11]: https://github.com/MunifTanjim/llhttp.lua
483