Skip to content

Commit 115c57a

Browse files
indutnyBridgeAR
authored andcommitted
deps: introduce llhttp
llhttp is modern, written in human-readable TypeScript, verifiable, and is very easy to maintain. See: https://github.com/indutny/llhttp PR-URL: #24059 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rod Vagg <rod@vagg.org> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent 13dee43 commit 115c57a

22 files changed

+7253
-77
lines changed

LICENSE

+26
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,32 @@ The externally maintained libraries used by Node.js are:
606606
n° 289016). Three clause BSD license.
607607
"""
608608

609+
- llhttp, located at deps/llhttp, is licensed as follows:
610+
"""
611+
This software is licensed under the MIT License.
612+
613+
Copyright Fedor Indutny, 2018.
614+
615+
Permission is hereby granted, free of charge, to any person obtaining a
616+
copy of this software and associated documentation files (the
617+
"Software"), to deal in the Software without restriction, including
618+
without limitation the rights to use, copy, modify, merge, publish,
619+
distribute, sublicense, and/or sell copies of the Software, and to permit
620+
persons to whom the Software is furnished to do so, subject to the
621+
following conditions:
622+
623+
The above copyright notice and this permission notice shall be included
624+
in all copies or substantial portions of the Software.
625+
626+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
627+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
628+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
629+
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
630+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
631+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
632+
USE OR OTHER DEALINGS IN THE SOFTWARE.
633+
"""
634+
609635
- OpenSSL, located at deps/openssl, is licensed as follows:
610636
"""
611637
Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved.

configure.py

+8
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@
182182
help='Use the specified path to system CA (PEM format) in addition to '
183183
'the OpenSSL supplied CA store or compiled-in Mozilla CA copy.')
184184

185+
parser.add_option('--experimental-http-parser',
186+
action='store_true',
187+
dest='experimental_http_parser',
188+
help='use llhttp instead of http_parser')
189+
185190
shared_optgroup.add_option('--shared-http-parser',
186191
action='store_true',
187192
dest='shared_http_parser',
@@ -1106,6 +1111,9 @@ def configure_node(o):
11061111
else:
11071112
o['variables']['node_target_type'] = 'executable'
11081113

1114+
o['variables']['node_experimental_http_parser'] = \
1115+
b(options.experimental_http_parser)
1116+
11091117
def configure_library(lib, output):
11101118
shared_lib = 'shared_' + lib
11111119
output['variables']['node_' + shared_lib] = b(getattr(options, shared_lib))

deps/llhttp/LICENSE-MIT

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
This software is licensed under the MIT License.
2+
3+
Copyright Fedor Indutny, 2018.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a
6+
copy of this software and associated documentation files (the
7+
"Software"), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to permit
10+
persons to whom the Software is furnished to do so, subject to the
11+
following conditions:
12+
13+
The above copyright notice and this permission notice shall be included
14+
in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
19+
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
20+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22+
USE OR OTHER DEALINGS IN THE SOFTWARE.

deps/llhttp/README.md

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# llhttp
2+
[![Build Status](https://secure.travis-ci.org/indutny/llhttp.svg)](http://travis-ci.org/indutny/llhttp)
3+
4+
Port of [http_parser][0] to [llparse][1].
5+
6+
## Why?
7+
8+
Let's face it, [http_parser][0] is practically unmaintainable. Even
9+
introduction of a single new method results in a significant code churn.
10+
11+
This project aims to:
12+
13+
* Make it maintainable
14+
* Verifiable
15+
* Improving benchmarks where possible
16+
17+
## How?
18+
19+
Over time, different approaches for improving [http_parser][0]'s code base
20+
were tried. However, all of them failed due to resulting significant performance
21+
degradation.
22+
23+
This project is a port of [http_parser][0] to TypeScript. [llparse][1] is used
24+
to generate the output C and/or bitcode artifacts, which could be compiled and
25+
linked with the embedder's program (like [Node.js][7]).
26+
27+
## Peformance
28+
29+
So far llhttp outperforms http_parser:
30+
31+
| | input size | bandwidth | reqs/sec | time |
32+
|:----------------|-----------:|-------------:|-----------:|--------:|
33+
| **llhttp** _(C)_ | 8192.00 mb | 1497.88 mb/s | 3020458.87 ops/sec | 5.47 s |
34+
| **llhttp** _(bitcode)_ | 8192.00 mb | 1131.75 mb/s | 2282171.24 ops/sec | 7.24 s |
35+
| **http_parser** | 8192.00 mb | 694.66 mb/s | 1406180.33 req/sec | 11.79 s |
36+
37+
llhttp is faster by approximately **116%**.
38+
39+
## Maintenance
40+
41+
llhttp project has about 1400 lines of TypeScript code describing the parser
42+
itself and around 450 lines of C code and headers providing the helper methods.
43+
The whole [http_parser][0] is implemented in approximately 2500 lines of C, and
44+
436 lines of headers.
45+
46+
All optimizations and multi-character matching in llhttp are generated
47+
automatically, and thus doesn't add any extra maintenance cost. On the contrary,
48+
most of http_parser's code is hand-optimized and unrolled. Instead describing
49+
"how" it should parse the HTTP requests/responses, a maintainer should
50+
implement the new features in [http_parser][0] cautiously, considering
51+
possible performance degradation and manually optimizing the new code.
52+
53+
## Verification
54+
55+
The state machine graph is encoded explicitly in llhttp. The [llparse][1]
56+
automatically checks the graph for absence of loops and correct reporting of the
57+
input ranges (spans) like header names and values. In the future, additional
58+
checks could be performed to get even stricter verification of the llhttp.
59+
60+
## Usage
61+
62+
```C
63+
#include "llhttp.h"
64+
65+
llhttp_t parser;
66+
llhttp_settings_t settings;
67+
68+
/* Initialize user callbacks and settings */
69+
llhttp_settings_init(&settings);
70+
71+
/* Set user callback */
72+
settings.on_message_complete = handle_on_message_complete;
73+
74+
/* Initialize the parser in HTTP_BOTH mode, meaning that it will select between
75+
* HTTP_REQUEST and HTTP_RESPONSE parsing automatically while reading the first
76+
* input.
77+
*/
78+
llhttp_init(&parser, HTTP_BOTH, &settings);
79+
80+
/* Use `llhttp_set_type(&parser, HTTP_REQUEST);` to override the mode */
81+
82+
/* Parse request! */
83+
const char* request = "GET / HTTP/1.1\r\n\r\n";
84+
int request_len = strlen(request);
85+
86+
enum llhttp_errno err = llhttp_execute(&parser, request, request_len);
87+
if (err == HPE_OK) {
88+
/* Successfully parsed! */
89+
} else {
90+
fprintf(stderr, "Parse error: %s %s\n", llhttp_errno_name(err),
91+
parser.reason);
92+
}
93+
```
94+
95+
---
96+
97+
#### LICENSE
98+
99+
This software is licensed under the MIT License.
100+
101+
Copyright Fedor Indutny, 2018.
102+
103+
Permission is hereby granted, free of charge, to any person obtaining a
104+
copy of this software and associated documentation files (the
105+
"Software"), to deal in the Software without restriction, including
106+
without limitation the rights to use, copy, modify, merge, publish,
107+
distribute, sublicense, and/or sell copies of the Software, and to permit
108+
persons to whom the Software is furnished to do so, subject to the
109+
following conditions:
110+
111+
The above copyright notice and this permission notice shall be included
112+
in all copies or substantial portions of the Software.
113+
114+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
115+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
116+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
117+
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
118+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
119+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
120+
USE OR OTHER DEALINGS IN THE SOFTWARE.
121+
122+
[0]: https://github.com/nodejs/http-parser
123+
[1]: https://github.com/indutny/llparse
124+
[2]: https://en.wikipedia.org/wiki/Register_allocation#Spilling
125+
[3]: https://en.wikipedia.org/wiki/Tail_call
126+
[4]: https://llvm.org/docs/LangRef.html
127+
[5]: https://llvm.org/docs/LangRef.html#call-instruction
128+
[6]: https://clang.llvm.org/
129+
[7]: https://github.com/nodejs/node

deps/llhttp/common.gypi

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
'target_defaults': {
3+
'default_configuration': 'Debug',
4+
'configurations': {
5+
# TODO: hoist these out and put them somewhere common, because
6+
# RuntimeLibrary MUST MATCH across the entire project
7+
'Debug': {
8+
'defines': [ 'DEBUG', '_DEBUG' ],
9+
'cflags': [ '-Wall', '-Wextra', '-O0', '-g', '-ftrapv' ],
10+
'msvs_settings': {
11+
'VCCLCompilerTool': {
12+
'RuntimeLibrary': 1, # static debug
13+
},
14+
},
15+
},
16+
'Release': {
17+
'defines': [ 'NDEBUG' ],
18+
'cflags': [ '-Wall', '-Wextra', '-O3' ],
19+
'msvs_settings': {
20+
'VCCLCompilerTool': {
21+
'RuntimeLibrary': 0, # static release
22+
},
23+
},
24+
}
25+
},
26+
'msvs_settings': {
27+
'VCCLCompilerTool': {
28+
# Compile as C++. llhttp.c is actually C99, but C++ is
29+
# close enough in this case.
30+
'CompileAs': 2,
31+
},
32+
'VCLibrarianTool': {
33+
},
34+
'VCLinkerTool': {
35+
'GenerateDebugInformation': 'true',
36+
},
37+
},
38+
'conditions': [
39+
['OS == "win"', {
40+
'defines': [
41+
'WIN32'
42+
],
43+
}]
44+
],
45+
},
46+
}

0 commit comments

Comments
 (0)