Skip to content

Commit 6e17bc9

Browse files
Lukasaglbrntt
andauthored
Update LLHTTP and apply patch to support C++ interop (#3216)
### Motivation C++ interop support in Xcode has started to dislike the header files from llhttp. While a bug has been filed upstream at nodejs/llparse#71 it doesn't seem as though there is any movement on that fix upstream. As a result, we need to apply a patch. To keep the code maintainable, we'd like to apply that patch in an automated fashion, so we should do so by amending the "update and patch" script. Along the way, we should update LLHTTP to the latest code. ### Modifications The modifications are split into separate commits. 1. Modify the script to fix some bugs that have crept in. 2. Run the script to update LLHTTP to latest, without the patch. 3. Fix up the tests to account for the fact that we get some different errors from LLHTTP now. 4. Apply the patch suggested by @postmechanical in #3093 5. Re-run the script, which only applies the patch ### Result C++ interop should be working again. Resolves #3093. --------- Co-authored-by: George Barnett <[email protected]>
1 parent 6615a44 commit 6e17bc9

File tree

10 files changed

+2288
-1122
lines changed

10 files changed

+2288
-1122
lines changed

.licenseignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Dockerfile
3232
**/Dockerfile
3333
Snippets/*
3434
Sources/CNIOAtomics/src/cpp_magic.h
35-
Sources/CNIOLLHTTP/LICENSE-MIT
35+
Sources/CNIOLLHTTP/LICENSE
3636
Sources/CNIOLLHTTP/c_nio_api.c
3737
Sources/CNIOLLHTTP/c_nio_http.c
3838
Sources/CNIOLLHTTP/c_nio_llhttp.c
File renamed without changes.

Sources/CNIOLLHTTP/c_nio_api.c

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,29 +60,14 @@ static int wasm_on_headers_complete_wrap(llhttp_t* p) {
6060
}
6161

6262
const llhttp_settings_t wasm_settings = {
63-
wasm_on_message_begin,
64-
wasm_on_url,
65-
wasm_on_status,
66-
NULL,
67-
NULL,
68-
wasm_on_header_field,
69-
wasm_on_header_value,
70-
NULL,
71-
NULL,
72-
wasm_on_headers_complete_wrap,
73-
wasm_on_body,
74-
wasm_on_message_complete,
75-
NULL,
76-
NULL,
77-
NULL,
78-
NULL,
79-
NULL,
80-
NULL,
81-
NULL,
82-
NULL,
83-
NULL,
84-
NULL,
85-
NULL,
63+
.on_message_begin = wasm_on_message_begin,
64+
.on_url = wasm_on_url,
65+
.on_status = wasm_on_status,
66+
.on_header_field = wasm_on_header_field,
67+
.on_header_value = wasm_on_header_value,
68+
.on_headers_complete = wasm_on_headers_complete_wrap,
69+
.on_body = wasm_on_body,
70+
.on_message_complete = wasm_on_message_complete,
8671
};
8772

8873

@@ -129,7 +114,7 @@ void c_nio_llhttp_reset(llhttp_t* parser) {
129114
llhttp_type_t type = parser->type;
130115
const llhttp_settings_t* settings = parser->settings;
131116
void* data = parser->data;
132-
uint8_t lenient_flags = parser->lenient_flags;
117+
uint16_t lenient_flags = parser->lenient_flags;
133118

134119
c_nio_llhttp__internal_init(parser);
135120

@@ -318,6 +303,22 @@ void c_nio_llhttp_set_lenient_optional_crlf_after_chunk(llhttp_t* parser, int en
318303
}
319304
}
320305

306+
void c_nio_llhttp_set_lenient_optional_cr_before_lf(llhttp_t* parser, int enabled) {
307+
if (enabled) {
308+
parser->lenient_flags |= LENIENT_OPTIONAL_CR_BEFORE_LF;
309+
} else {
310+
parser->lenient_flags &= ~LENIENT_OPTIONAL_CR_BEFORE_LF;
311+
}
312+
}
313+
314+
void c_nio_llhttp_set_lenient_spaces_after_chunk_size(llhttp_t* parser, int enabled) {
315+
if (enabled) {
316+
parser->lenient_flags |= LENIENT_SPACES_AFTER_CHUNK_SIZE;
317+
} else {
318+
parser->lenient_flags &= ~LENIENT_SPACES_AFTER_CHUNK_SIZE;
319+
}
320+
}
321+
321322
/* Callbacks */
322323

323324

@@ -328,6 +329,20 @@ int c_nio_llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp)
328329
}
329330

330331

332+
int c_nio_llhttp__on_protocol(llhttp_t* s, const char* p, const char* endp) {
333+
int err;
334+
SPAN_CALLBACK_MAYBE(s, on_protocol, p, endp - p);
335+
return err;
336+
}
337+
338+
339+
int c_nio_llhttp__on_protocol_complete(llhttp_t* s, const char* p, const char* endp) {
340+
int err;
341+
CALLBACK_MAYBE(s, on_protocol_complete);
342+
return err;
343+
}
344+
345+
331346
int c_nio_llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
332347
int err;
333348
SPAN_CALLBACK_MAYBE(s, on_url, p, endp - p);

Sources/CNIOLLHTTP/c_nio_http.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,33 @@ int c_nio_llhttp__after_headers_complete(llhttp_t* parser, const char* p,
4242
int hasBody;
4343

4444
hasBody = parser->flags & F_CHUNKED || parser->content_length > 0;
45-
if (parser->upgrade && (parser->method == HTTP_CONNECT ||
46-
(parser->flags & F_SKIPBODY) || !hasBody)) {
45+
if (
46+
(parser->upgrade && (parser->method == HTTP_CONNECT ||
47+
(parser->flags & F_SKIPBODY) || !hasBody)) ||
48+
/* See RFC 2616 section 4.4 - 1xx e.g. Continue */
49+
(parser->type == HTTP_RESPONSE && parser->status_code == 101)
50+
) {
4751
/* Exit, the rest of the message is in a different protocol. */
4852
return 1;
4953
}
5054

51-
if (parser->flags & F_SKIPBODY) {
55+
if (parser->type == HTTP_RESPONSE && parser->status_code == 100) {
56+
/* No body, restart as the message is complete */
57+
return 0;
58+
}
59+
60+
/* See RFC 2616 section 4.4 */
61+
if (
62+
parser->flags & F_SKIPBODY || /* response to a HEAD request */
63+
(
64+
parser->type == HTTP_RESPONSE && (
65+
parser->status_code == 102 || /* Processing */
66+
parser->status_code == 103 || /* Early Hints */
67+
parser->status_code == 204 || /* No Content */
68+
parser->status_code == 304 /* Not Modified */
69+
)
70+
)
71+
) {
5272
return 0;
5373
} else if (parser->flags & F_CHUNKED) {
5474
/* chunked encoding - ignore Content-Length header, prepare for a chunk */

0 commit comments

Comments
 (0)