llhttp 0.1.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/README.md +1 -1
- data/ext/llhttp/api.c +112 -18
- data/ext/llhttp/llhttp.c +83 -28
- data/ext/llhttp/llhttp.h +131 -6
- data/ext/llhttp/llhttp_ext.c +117 -67
- data/lib/llhttp/parser.rb +4 -0
- data/lib/llhttp/version.rb +1 -1
- metadata +4 -10
- data/ext/x86_64-darwin/libllhttp-ext.bundle +0 -0
- data/ext/x86_64-darwin/llhttp/api.o +0 -0
- data/ext/x86_64-darwin/llhttp/http.o +0 -0
- data/ext/x86_64-darwin/llhttp/llhttp.o +0 -0
- data/ext/x86_64-darwin/llhttp/llhttp_ext.o +0 -0
- data/lib/llhttp_ext.bundle +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e15a0ef9a22a029ad2b29b6a173fa5eb9bc7cee0a7ec819bf0cb9be068e106b
|
4
|
+
data.tar.gz: 50b10fdfeaa7a752f1ce50bcb3f4ebb4e7b0eea75af978acd2c5fa467eed345a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38088c14fd79320cbd278dc305259636e1bed27358061eb94d2f99a859c0b0ce2d72976832b5026c861f98c57daf2782c8a00d1faf91d9898c9674e847a76455
|
7
|
+
data.tar.gz: 4e1be65888e3a2f9593c4208ae67c2cf9792d4779689755df882851817637e7b111a8e08caee4eb95509f38ced4119a48898744351f376ce941eb7f617ab03ef
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
## [v0.5.0](https://github.com/metabahn/llhttp/releases/tag/2021-09-21)
|
2
|
+
|
3
|
+
*released on 2021-09-21*
|
4
|
+
|
5
|
+
* `chg` [#26](https://github.com/metabahn/llhttp/pull/26) Refactor parser data to include all values ([bryanp](https://github.com/bryanp))
|
6
|
+
|
7
|
+
## [v0.4.0](https://github.com/metabahn/llhttp/releases/tag/2021-09-09)
|
8
|
+
|
9
|
+
*released on 2021-09-09*
|
10
|
+
|
11
|
+
* `add` [#25](https://github.com/metabahn/llhttp/pull/25) Add support for resetting the parser ([bryanp](https://github.com/bryanp))
|
12
|
+
* `chg` [#24](https://github.com/metabahn/llhttp/pull/24) Update mri to llhttp 6.0.5 ([bryanp](https://github.com/bryanp))
|
13
|
+
|
14
|
+
## [v0.3.0](https://github.com/metabahn/llhttp/releases/tag/2021-05-06)
|
15
|
+
|
16
|
+
*released on 2021-05-06*
|
17
|
+
|
18
|
+
* `chg` [#16](https://github.com/metabahn/llhttp/pull/16) Update mri to llhttp 6.0.1 ([bryanp](https://github.com/bryanp))
|
19
|
+
* `chg` [#18](https://github.com/metabahn/llhttp/pull/18) Drop support for Ruby 2.5 ([bryanp](https://github.com/bryanp))
|
20
|
+
|
21
|
+
## [v0.2.0](https://github.com/metabahn/llhttp/releases/tag/2021-04-06)
|
22
|
+
|
23
|
+
*released on 2021-04-06*
|
24
|
+
|
25
|
+
* `chg` [#15](https://github.com/metabahn/llhttp/pull/15) Update mri to llhttp 5.1.0 ([bryanp](https://github.com/bryanp))
|
26
|
+
|
1
27
|
## [v0.1.0](https://github.com/metabahn/llhttp/releases/tag/2021-03-03)
|
2
28
|
|
3
29
|
*released on 2021-03-03*
|
data/README.md
CHANGED
data/ext/llhttp/api.c
CHANGED
@@ -27,7 +27,7 @@
|
|
27
27
|
|
28
28
|
#include "llhttp.h"
|
29
29
|
|
30
|
-
#define CALLBACK_MAYBE(PARSER, NAME
|
30
|
+
#define CALLBACK_MAYBE(PARSER, NAME) \
|
31
31
|
do { \
|
32
32
|
const llhttp_settings_t* settings; \
|
33
33
|
settings = (const llhttp_settings_t*) (PARSER)->settings; \
|
@@ -35,7 +35,22 @@
|
|
35
35
|
err = 0; \
|
36
36
|
break; \
|
37
37
|
} \
|
38
|
-
err = settings->NAME(
|
38
|
+
err = settings->NAME((PARSER)); \
|
39
|
+
} while (0)
|
40
|
+
|
41
|
+
#define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN) \
|
42
|
+
do { \
|
43
|
+
const llhttp_settings_t* settings; \
|
44
|
+
settings = (const llhttp_settings_t*) (PARSER)->settings; \
|
45
|
+
if (settings == NULL || settings->NAME == NULL) { \
|
46
|
+
err = 0; \
|
47
|
+
break; \
|
48
|
+
} \
|
49
|
+
err = settings->NAME((PARSER), (START), (LEN)); \
|
50
|
+
if (err == -1) { \
|
51
|
+
err = HPE_USER; \
|
52
|
+
llhttp_set_error_reason((PARSER), "Span callback error in " #NAME); \
|
53
|
+
} \
|
39
54
|
} while (0)
|
40
55
|
|
41
56
|
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
|
@@ -47,6 +62,76 @@ void llhttp_init(llhttp_t* parser, llhttp_type_t type,
|
|
47
62
|
}
|
48
63
|
|
49
64
|
|
65
|
+
#if defined(__wasm__)
|
66
|
+
|
67
|
+
extern int wasm_on_message_begin(llhttp_t * p);
|
68
|
+
extern int wasm_on_url(llhttp_t* p, const char* at, size_t length);
|
69
|
+
extern int wasm_on_status(llhttp_t* p, const char* at, size_t length);
|
70
|
+
extern int wasm_on_header_field(llhttp_t* p, const char* at, size_t length);
|
71
|
+
extern int wasm_on_header_value(llhttp_t* p, const char* at, size_t length);
|
72
|
+
extern int wasm_on_headers_complete(llhttp_t * p, int status_code,
|
73
|
+
uint8_t upgrade, int should_keep_alive);
|
74
|
+
extern int wasm_on_body(llhttp_t* p, const char* at, size_t length);
|
75
|
+
extern int wasm_on_message_complete(llhttp_t * p);
|
76
|
+
|
77
|
+
static int wasm_on_headers_complete_wrap(llhttp_t* p) {
|
78
|
+
return wasm_on_headers_complete(p, p->status_code, p->upgrade,
|
79
|
+
llhttp_should_keep_alive(p));
|
80
|
+
}
|
81
|
+
|
82
|
+
const llhttp_settings_t wasm_settings = {
|
83
|
+
wasm_on_message_begin,
|
84
|
+
wasm_on_url,
|
85
|
+
wasm_on_status,
|
86
|
+
wasm_on_header_field,
|
87
|
+
wasm_on_header_value,
|
88
|
+
wasm_on_headers_complete_wrap,
|
89
|
+
wasm_on_body,
|
90
|
+
wasm_on_message_complete,
|
91
|
+
NULL,
|
92
|
+
NULL,
|
93
|
+
};
|
94
|
+
|
95
|
+
|
96
|
+
llhttp_t* llhttp_alloc(llhttp_type_t type) {
|
97
|
+
llhttp_t* parser = malloc(sizeof(llhttp_t));
|
98
|
+
llhttp_init(parser, type, &wasm_settings);
|
99
|
+
return parser;
|
100
|
+
}
|
101
|
+
|
102
|
+
void llhttp_free(llhttp_t* parser) {
|
103
|
+
free(parser);
|
104
|
+
}
|
105
|
+
|
106
|
+
/* Some getters required to get stuff from the parser */
|
107
|
+
|
108
|
+
uint8_t llhttp_get_type(llhttp_t* parser) {
|
109
|
+
return parser->type;
|
110
|
+
}
|
111
|
+
|
112
|
+
uint8_t llhttp_get_http_major(llhttp_t* parser) {
|
113
|
+
return parser->http_major;
|
114
|
+
}
|
115
|
+
|
116
|
+
uint8_t llhttp_get_http_minor(llhttp_t* parser) {
|
117
|
+
return parser->http_minor;
|
118
|
+
}
|
119
|
+
|
120
|
+
uint8_t llhttp_get_method(llhttp_t* parser) {
|
121
|
+
return parser->method;
|
122
|
+
}
|
123
|
+
|
124
|
+
int llhttp_get_status_code(llhttp_t* parser) {
|
125
|
+
return parser->status_code;
|
126
|
+
}
|
127
|
+
|
128
|
+
uint8_t llhttp_get_upgrade(llhttp_t* parser) {
|
129
|
+
return parser->upgrade;
|
130
|
+
}
|
131
|
+
|
132
|
+
#endif // defined(__wasm__)
|
133
|
+
|
134
|
+
|
50
135
|
void llhttp_reset(llhttp_t* parser) {
|
51
136
|
llhttp_type_t type = parser->type;
|
52
137
|
const llhttp_settings_t* settings = parser->settings;
|
@@ -82,7 +167,7 @@ llhttp_errno_t llhttp_finish(llhttp_t* parser) {
|
|
82
167
|
|
83
168
|
switch (parser->finish) {
|
84
169
|
case HTTP_FINISH_SAFE_WITH_CB:
|
85
|
-
CALLBACK_MAYBE(parser, on_message_complete
|
170
|
+
CALLBACK_MAYBE(parser, on_message_complete);
|
86
171
|
if (err != HPE_OK) return err;
|
87
172
|
|
88
173
|
/* FALLTHROUGH */
|
@@ -158,7 +243,7 @@ const char* llhttp_errno_name(llhttp_errno_t err) {
|
|
158
243
|
const char* llhttp_method_name(llhttp_method_t method) {
|
159
244
|
#define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
|
160
245
|
switch (method) {
|
161
|
-
|
246
|
+
HTTP_ALL_METHOD_MAP(HTTP_METHOD_GEN)
|
162
247
|
default: abort();
|
163
248
|
}
|
164
249
|
#undef HTTP_METHOD_GEN
|
@@ -173,6 +258,7 @@ void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) {
|
|
173
258
|
}
|
174
259
|
}
|
175
260
|
|
261
|
+
|
176
262
|
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
|
177
263
|
if (enabled) {
|
178
264
|
parser->lenient_flags |= LENIENT_CHUNKED_LENGTH;
|
@@ -182,103 +268,111 @@ void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
|
|
182
268
|
}
|
183
269
|
|
184
270
|
|
271
|
+
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
|
272
|
+
if (enabled) {
|
273
|
+
parser->lenient_flags |= LENIENT_KEEP_ALIVE;
|
274
|
+
} else {
|
275
|
+
parser->lenient_flags &= ~LENIENT_KEEP_ALIVE;
|
276
|
+
}
|
277
|
+
}
|
278
|
+
|
185
279
|
/* Callbacks */
|
186
280
|
|
187
281
|
|
188
282
|
int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
|
189
283
|
int err;
|
190
|
-
CALLBACK_MAYBE(s, on_message_begin
|
284
|
+
CALLBACK_MAYBE(s, on_message_begin);
|
191
285
|
return err;
|
192
286
|
}
|
193
287
|
|
194
288
|
|
195
289
|
int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
|
196
290
|
int err;
|
197
|
-
|
291
|
+
SPAN_CALLBACK_MAYBE(s, on_url, p, endp - p);
|
198
292
|
return err;
|
199
293
|
}
|
200
294
|
|
201
295
|
|
202
296
|
int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) {
|
203
297
|
int err;
|
204
|
-
CALLBACK_MAYBE(s, on_url_complete
|
298
|
+
CALLBACK_MAYBE(s, on_url_complete);
|
205
299
|
return err;
|
206
300
|
}
|
207
301
|
|
208
302
|
|
209
303
|
int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
|
210
304
|
int err;
|
211
|
-
|
305
|
+
SPAN_CALLBACK_MAYBE(s, on_status, p, endp - p);
|
212
306
|
return err;
|
213
307
|
}
|
214
308
|
|
215
309
|
|
216
310
|
int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp) {
|
217
311
|
int err;
|
218
|
-
CALLBACK_MAYBE(s, on_status_complete
|
312
|
+
CALLBACK_MAYBE(s, on_status_complete);
|
219
313
|
return err;
|
220
314
|
}
|
221
315
|
|
222
316
|
|
223
317
|
int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
|
224
318
|
int err;
|
225
|
-
|
319
|
+
SPAN_CALLBACK_MAYBE(s, on_header_field, p, endp - p);
|
226
320
|
return err;
|
227
321
|
}
|
228
322
|
|
229
323
|
|
230
324
|
int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp) {
|
231
325
|
int err;
|
232
|
-
CALLBACK_MAYBE(s, on_header_field_complete
|
326
|
+
CALLBACK_MAYBE(s, on_header_field_complete);
|
233
327
|
return err;
|
234
328
|
}
|
235
329
|
|
236
330
|
|
237
331
|
int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
|
238
332
|
int err;
|
239
|
-
|
333
|
+
SPAN_CALLBACK_MAYBE(s, on_header_value, p, endp - p);
|
240
334
|
return err;
|
241
335
|
}
|
242
336
|
|
243
337
|
|
244
338
|
int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp) {
|
245
339
|
int err;
|
246
|
-
CALLBACK_MAYBE(s, on_header_value_complete
|
340
|
+
CALLBACK_MAYBE(s, on_header_value_complete);
|
247
341
|
return err;
|
248
342
|
}
|
249
343
|
|
250
344
|
|
251
345
|
int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
|
252
346
|
int err;
|
253
|
-
CALLBACK_MAYBE(s, on_headers_complete
|
347
|
+
CALLBACK_MAYBE(s, on_headers_complete);
|
254
348
|
return err;
|
255
349
|
}
|
256
350
|
|
257
351
|
|
258
352
|
int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
|
259
353
|
int err;
|
260
|
-
CALLBACK_MAYBE(s, on_message_complete
|
354
|
+
CALLBACK_MAYBE(s, on_message_complete);
|
261
355
|
return err;
|
262
356
|
}
|
263
357
|
|
264
358
|
|
265
359
|
int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
|
266
360
|
int err;
|
267
|
-
|
361
|
+
SPAN_CALLBACK_MAYBE(s, on_body, p, endp - p);
|
268
362
|
return err;
|
269
363
|
}
|
270
364
|
|
271
365
|
|
272
366
|
int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
|
273
367
|
int err;
|
274
|
-
CALLBACK_MAYBE(s, on_chunk_header
|
368
|
+
CALLBACK_MAYBE(s, on_chunk_header);
|
275
369
|
return err;
|
276
370
|
}
|
277
371
|
|
278
372
|
|
279
373
|
int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
|
280
374
|
int err;
|
281
|
-
CALLBACK_MAYBE(s, on_chunk_complete
|
375
|
+
CALLBACK_MAYBE(s, on_chunk_complete);
|
282
376
|
return err;
|
283
377
|
}
|
284
378
|
|
data/ext/llhttp/llhttp.c
CHANGED
@@ -650,6 +650,13 @@ int llhttp__internal__c_update_finish_1(
|
|
650
650
|
return 0;
|
651
651
|
}
|
652
652
|
|
653
|
+
int llhttp__internal__c_test_lenient_flags(
|
654
|
+
llhttp__internal_t* state,
|
655
|
+
const unsigned char* p,
|
656
|
+
const unsigned char* endp) {
|
657
|
+
return (state->lenient_flags & 4) == 4;
|
658
|
+
}
|
659
|
+
|
653
660
|
int llhttp__internal__c_test_flags_1(
|
654
661
|
llhttp__internal_t* state,
|
655
662
|
const unsigned char* p,
|
@@ -657,7 +664,7 @@ int llhttp__internal__c_test_flags_1(
|
|
657
664
|
return (state->flags & 544) == 544;
|
658
665
|
}
|
659
666
|
|
660
|
-
int
|
667
|
+
int llhttp__internal__c_test_lenient_flags_1(
|
661
668
|
llhttp__internal_t* state,
|
662
669
|
const unsigned char* p,
|
663
670
|
const unsigned char* endp) {
|
@@ -825,7 +832,7 @@ int llhttp__internal__c_update_header_state_2(
|
|
825
832
|
return 0;
|
826
833
|
}
|
827
834
|
|
828
|
-
int
|
835
|
+
int llhttp__internal__c_test_lenient_flags_2(
|
829
836
|
llhttp__internal_t* state,
|
830
837
|
const unsigned char* p,
|
831
838
|
const unsigned char* endp) {
|
@@ -1119,7 +1126,7 @@ static llparse_state_t llhttp__internal__run(
|
|
1119
1126
|
case s_n_llhttp__internal__n_consume_content_length:
|
1120
1127
|
s_n_llhttp__internal__n_consume_content_length: {
|
1121
1128
|
size_t avail;
|
1122
|
-
|
1129
|
+
uint64_t need;
|
1123
1130
|
|
1124
1131
|
avail = endp - p;
|
1125
1132
|
need = state->content_length;
|
@@ -1474,7 +1481,7 @@ static llparse_state_t llhttp__internal__run(
|
|
1474
1481
|
case s_n_llhttp__internal__n_consume_content_length_1:
|
1475
1482
|
s_n_llhttp__internal__n_consume_content_length_1: {
|
1476
1483
|
size_t avail;
|
1477
|
-
|
1484
|
+
uint64_t need;
|
1478
1485
|
|
1479
1486
|
avail = endp - p;
|
1480
1487
|
need = state->content_length;
|
@@ -1684,7 +1691,7 @@ static llparse_state_t llhttp__internal__run(
|
|
1684
1691
|
goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_2;
|
1685
1692
|
}
|
1686
1693
|
default: {
|
1687
|
-
goto
|
1694
|
+
goto s_n_llhttp__internal__n_invoke_test_lenient_flags_2;
|
1688
1695
|
}
|
1689
1696
|
}
|
1690
1697
|
/* UNREACHABLE */;
|
@@ -5756,10 +5763,20 @@ static llparse_state_t llhttp__internal__run(
|
|
5756
5763
|
/* UNREACHABLE */;
|
5757
5764
|
abort();
|
5758
5765
|
}
|
5766
|
+
s_n_llhttp__internal__n_invoke_test_lenient_flags: {
|
5767
|
+
switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) {
|
5768
|
+
case 1:
|
5769
|
+
goto s_n_llhttp__internal__n_invoke_update_finish_2;
|
5770
|
+
default:
|
5771
|
+
goto s_n_llhttp__internal__n_closed;
|
5772
|
+
}
|
5773
|
+
/* UNREACHABLE */;
|
5774
|
+
abort();
|
5775
|
+
}
|
5759
5776
|
s_n_llhttp__internal__n_invoke_update_finish_1: {
|
5760
5777
|
switch (llhttp__internal__c_update_finish_1(state, p, endp)) {
|
5761
5778
|
default:
|
5762
|
-
goto
|
5779
|
+
goto s_n_llhttp__internal__n_invoke_test_lenient_flags;
|
5763
5780
|
}
|
5764
5781
|
/* UNREACHABLE */;
|
5765
5782
|
abort();
|
@@ -6121,8 +6138,8 @@ static llparse_state_t llhttp__internal__run(
|
|
6121
6138
|
/* UNREACHABLE */;
|
6122
6139
|
abort();
|
6123
6140
|
}
|
6124
|
-
|
6125
|
-
switch (
|
6141
|
+
s_n_llhttp__internal__n_invoke_test_lenient_flags_1: {
|
6142
|
+
switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) {
|
6126
6143
|
case 0:
|
6127
6144
|
goto s_n_llhttp__internal__n_error_15;
|
6128
6145
|
default:
|
@@ -6134,7 +6151,7 @@ static llparse_state_t llhttp__internal__run(
|
|
6134
6151
|
s_n_llhttp__internal__n_invoke_test_flags_1: {
|
6135
6152
|
switch (llhttp__internal__c_test_flags_1(state, p, endp)) {
|
6136
6153
|
case 1:
|
6137
|
-
goto
|
6154
|
+
goto s_n_llhttp__internal__n_invoke_test_lenient_flags_1;
|
6138
6155
|
default:
|
6139
6156
|
goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete;
|
6140
6157
|
}
|
@@ -6388,8 +6405,8 @@ static llparse_state_t llhttp__internal__run(
|
|
6388
6405
|
/* UNREACHABLE */;
|
6389
6406
|
abort();
|
6390
6407
|
}
|
6391
|
-
|
6392
|
-
switch (
|
6408
|
+
s_n_llhttp__internal__n_invoke_test_lenient_flags_2: {
|
6409
|
+
switch (llhttp__internal__c_test_lenient_flags_2(state, p, endp)) {
|
6393
6410
|
case 1:
|
6394
6411
|
goto s_n_llhttp__internal__n_header_value_lenient;
|
6395
6412
|
default:
|
@@ -6750,7 +6767,7 @@ static llparse_state_t llhttp__internal__run(
|
|
6750
6767
|
abort();
|
6751
6768
|
}
|
6752
6769
|
s_n_llhttp__internal__n_error_29: {
|
6753
|
-
state->error =
|
6770
|
+
state->error = 0x17;
|
6754
6771
|
state->reason = "Pause on PRI/Upgrade";
|
6755
6772
|
state->error_pos = (const char*) p;
|
6756
6773
|
state->_current = (void*) (intptr_t) s_error;
|
@@ -7929,6 +7946,7 @@ reset:
|
|
7929
7946
|
|
7930
7947
|
enum llparse_state_e {
|
7931
7948
|
s_error,
|
7949
|
+
s_n_llhttp__internal__n_closed,
|
7932
7950
|
s_n_llhttp__internal__n_invoke_llhttp__after_message_complete,
|
7933
7951
|
s_n_llhttp__internal__n_pause_1,
|
7934
7952
|
s_n_llhttp__internal__n_invoke_is_equal_upgrade,
|
@@ -8222,6 +8240,13 @@ int llhttp__internal__c_update_finish_1(
|
|
8222
8240
|
return 0;
|
8223
8241
|
}
|
8224
8242
|
|
8243
|
+
int llhttp__internal__c_test_lenient_flags(
|
8244
|
+
llhttp__internal_t* state,
|
8245
|
+
const unsigned char* p,
|
8246
|
+
const unsigned char* endp) {
|
8247
|
+
return (state->lenient_flags & 4) == 4;
|
8248
|
+
}
|
8249
|
+
|
8225
8250
|
int llhttp__internal__c_test_flags_1(
|
8226
8251
|
llhttp__internal_t* state,
|
8227
8252
|
const unsigned char* p,
|
@@ -8229,7 +8254,7 @@ int llhttp__internal__c_test_flags_1(
|
|
8229
8254
|
return (state->flags & 544) == 544;
|
8230
8255
|
}
|
8231
8256
|
|
8232
|
-
int
|
8257
|
+
int llhttp__internal__c_test_lenient_flags_1(
|
8233
8258
|
llhttp__internal_t* state,
|
8234
8259
|
const unsigned char* p,
|
8235
8260
|
const unsigned char* endp) {
|
@@ -8301,7 +8326,7 @@ int llhttp__internal__c_or_flags(
|
|
8301
8326
|
return 0;
|
8302
8327
|
}
|
8303
8328
|
|
8304
|
-
int
|
8329
|
+
int llhttp__internal__c_update_finish_3(
|
8305
8330
|
llhttp__internal_t* state,
|
8306
8331
|
const unsigned char* p,
|
8307
8332
|
const unsigned char* endp) {
|
@@ -8397,7 +8422,7 @@ int llhttp__internal__c_update_header_state_2(
|
|
8397
8422
|
return 0;
|
8398
8423
|
}
|
8399
8424
|
|
8400
|
-
int
|
8425
|
+
int llhttp__internal__c_test_lenient_flags_2(
|
8401
8426
|
llhttp__internal_t* state,
|
8402
8427
|
const unsigned char* p,
|
8403
8428
|
const unsigned char* endp) {
|
@@ -8597,9 +8622,21 @@ static llparse_state_t llhttp__internal__run(
|
|
8597
8622
|
const unsigned char* endp) {
|
8598
8623
|
int match;
|
8599
8624
|
switch ((llparse_state_t) (intptr_t) state->_current) {
|
8625
|
+
case s_n_llhttp__internal__n_closed:
|
8626
|
+
s_n_llhttp__internal__n_closed: {
|
8627
|
+
if (p == endp) {
|
8628
|
+
return s_n_llhttp__internal__n_closed;
|
8629
|
+
}
|
8630
|
+
p++;
|
8631
|
+
goto s_n_llhttp__internal__n_closed;
|
8632
|
+
/* UNREACHABLE */;
|
8633
|
+
abort();
|
8634
|
+
}
|
8600
8635
|
case s_n_llhttp__internal__n_invoke_llhttp__after_message_complete:
|
8601
8636
|
s_n_llhttp__internal__n_invoke_llhttp__after_message_complete: {
|
8602
8637
|
switch (llhttp__after_message_complete(state, p, endp)) {
|
8638
|
+
case 1:
|
8639
|
+
goto s_n_llhttp__internal__n_invoke_update_finish_2;
|
8603
8640
|
default:
|
8604
8641
|
goto s_n_llhttp__internal__n_invoke_update_finish_1;
|
8605
8642
|
}
|
@@ -8663,7 +8700,7 @@ static llparse_state_t llhttp__internal__run(
|
|
8663
8700
|
case s_n_llhttp__internal__n_consume_content_length:
|
8664
8701
|
s_n_llhttp__internal__n_consume_content_length: {
|
8665
8702
|
size_t avail;
|
8666
|
-
|
8703
|
+
uint64_t need;
|
8667
8704
|
|
8668
8705
|
avail = endp - p;
|
8669
8706
|
need = state->content_length;
|
@@ -9011,7 +9048,7 @@ static llparse_state_t llhttp__internal__run(
|
|
9011
9048
|
case s_n_llhttp__internal__n_consume_content_length_1:
|
9012
9049
|
s_n_llhttp__internal__n_consume_content_length_1: {
|
9013
9050
|
size_t avail;
|
9014
|
-
|
9051
|
+
uint64_t need;
|
9015
9052
|
|
9016
9053
|
avail = endp - p;
|
9017
9054
|
need = state->content_length;
|
@@ -9068,7 +9105,7 @@ static llparse_state_t llhttp__internal__run(
|
|
9068
9105
|
case 3:
|
9069
9106
|
goto s_n_llhttp__internal__n_span_start_llhttp__on_body_1;
|
9070
9107
|
case 4:
|
9071
|
-
goto
|
9108
|
+
goto s_n_llhttp__internal__n_invoke_update_finish_3;
|
9072
9109
|
case 5:
|
9073
9110
|
goto s_n_llhttp__internal__n_error_10;
|
9074
9111
|
default:
|
@@ -9207,7 +9244,7 @@ static llparse_state_t llhttp__internal__run(
|
|
9207
9244
|
goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_2;
|
9208
9245
|
}
|
9209
9246
|
default: {
|
9210
|
-
goto
|
9247
|
+
goto s_n_llhttp__internal__n_invoke_test_lenient_flags_2;
|
9211
9248
|
}
|
9212
9249
|
}
|
9213
9250
|
/* UNREACHABLE */;
|
@@ -13100,7 +13137,7 @@ static llparse_state_t llhttp__internal__run(
|
|
13100
13137
|
/* UNREACHABLE */;
|
13101
13138
|
abort();
|
13102
13139
|
}
|
13103
|
-
|
13140
|
+
s_n_llhttp__internal__n_invoke_update_finish_2: {
|
13104
13141
|
switch (llhttp__internal__c_update_finish_1(state, p, endp)) {
|
13105
13142
|
default:
|
13106
13143
|
goto s_n_llhttp__internal__n_start;
|
@@ -13108,6 +13145,24 @@ static llparse_state_t llhttp__internal__run(
|
|
13108
13145
|
/* UNREACHABLE */;
|
13109
13146
|
abort();
|
13110
13147
|
}
|
13148
|
+
s_n_llhttp__internal__n_invoke_test_lenient_flags: {
|
13149
|
+
switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) {
|
13150
|
+
case 1:
|
13151
|
+
goto s_n_llhttp__internal__n_invoke_update_finish_2;
|
13152
|
+
default:
|
13153
|
+
goto s_n_llhttp__internal__n_closed;
|
13154
|
+
}
|
13155
|
+
/* UNREACHABLE */;
|
13156
|
+
abort();
|
13157
|
+
}
|
13158
|
+
s_n_llhttp__internal__n_invoke_update_finish_1: {
|
13159
|
+
switch (llhttp__internal__c_update_finish_1(state, p, endp)) {
|
13160
|
+
default:
|
13161
|
+
goto s_n_llhttp__internal__n_invoke_test_lenient_flags;
|
13162
|
+
}
|
13163
|
+
/* UNREACHABLE */;
|
13164
|
+
abort();
|
13165
|
+
}
|
13111
13166
|
s_n_llhttp__internal__n_pause_5: {
|
13112
13167
|
state->error = 0x15;
|
13113
13168
|
state->reason = "on_message_complete pause";
|
@@ -13334,8 +13389,8 @@ static llparse_state_t llhttp__internal__run(
|
|
13334
13389
|
/* UNREACHABLE */;
|
13335
13390
|
abort();
|
13336
13391
|
}
|
13337
|
-
|
13338
|
-
switch (
|
13392
|
+
s_n_llhttp__internal__n_invoke_update_finish_3: {
|
13393
|
+
switch (llhttp__internal__c_update_finish_3(state, p, endp)) {
|
13339
13394
|
default:
|
13340
13395
|
goto s_n_llhttp__internal__n_span_start_llhttp__on_body_2;
|
13341
13396
|
}
|
@@ -13447,8 +13502,8 @@ static llparse_state_t llhttp__internal__run(
|
|
13447
13502
|
/* UNREACHABLE */;
|
13448
13503
|
abort();
|
13449
13504
|
}
|
13450
|
-
|
13451
|
-
switch (
|
13505
|
+
s_n_llhttp__internal__n_invoke_test_lenient_flags_1: {
|
13506
|
+
switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) {
|
13452
13507
|
case 0:
|
13453
13508
|
goto s_n_llhttp__internal__n_error_11;
|
13454
13509
|
default:
|
@@ -13460,7 +13515,7 @@ static llparse_state_t llhttp__internal__run(
|
|
13460
13515
|
s_n_llhttp__internal__n_invoke_test_flags_1: {
|
13461
13516
|
switch (llhttp__internal__c_test_flags_1(state, p, endp)) {
|
13462
13517
|
case 1:
|
13463
|
-
goto
|
13518
|
+
goto s_n_llhttp__internal__n_invoke_test_lenient_flags_1;
|
13464
13519
|
default:
|
13465
13520
|
goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete;
|
13466
13521
|
}
|
@@ -13696,8 +13751,8 @@ static llparse_state_t llhttp__internal__run(
|
|
13696
13751
|
/* UNREACHABLE */;
|
13697
13752
|
abort();
|
13698
13753
|
}
|
13699
|
-
|
13700
|
-
switch (
|
13754
|
+
s_n_llhttp__internal__n_invoke_test_lenient_flags_2: {
|
13755
|
+
switch (llhttp__internal__c_test_lenient_flags_2(state, p, endp)) {
|
13701
13756
|
case 1:
|
13702
13757
|
goto s_n_llhttp__internal__n_header_value_lenient;
|
13703
13758
|
default:
|
@@ -14058,7 +14113,7 @@ static llparse_state_t llhttp__internal__run(
|
|
14058
14113
|
abort();
|
14059
14114
|
}
|
14060
14115
|
s_n_llhttp__internal__n_error_23: {
|
14061
|
-
state->error =
|
14116
|
+
state->error = 0x17;
|
14062
14117
|
state->reason = "Pause on PRI/Upgrade";
|
14063
14118
|
state->error_pos = (const char*) p;
|
14064
14119
|
state->_current = (void*) (intptr_t) s_error;
|
data/ext/llhttp/llhttp.h
CHANGED
@@ -24,9 +24,9 @@
|
|
24
24
|
#ifndef INCLUDE_LLHTTP_H_
|
25
25
|
#define INCLUDE_LLHTTP_H_
|
26
26
|
|
27
|
-
#define LLHTTP_VERSION_MAJOR
|
27
|
+
#define LLHTTP_VERSION_MAJOR 6
|
28
28
|
#define LLHTTP_VERSION_MINOR 0
|
29
|
-
#define LLHTTP_VERSION_PATCH
|
29
|
+
#define LLHTTP_VERSION_PATCH 5
|
30
30
|
|
31
31
|
#ifndef LLHTTP_STRICT_MODE
|
32
32
|
# define LLHTTP_STRICT_MODE 0
|
@@ -102,7 +102,8 @@ enum llhttp_errno {
|
|
102
102
|
HPE_CB_CHUNK_COMPLETE = 20,
|
103
103
|
HPE_PAUSED = 21,
|
104
104
|
HPE_PAUSED_UPGRADE = 22,
|
105
|
-
|
105
|
+
HPE_PAUSED_H2_UPGRADE = 23,
|
106
|
+
HPE_USER = 24
|
106
107
|
};
|
107
108
|
typedef enum llhttp_errno llhttp_errno_t;
|
108
109
|
|
@@ -121,7 +122,8 @@ typedef enum llhttp_flags llhttp_flags_t;
|
|
121
122
|
|
122
123
|
enum llhttp_lenient_flags {
|
123
124
|
LENIENT_HEADERS = 0x1,
|
124
|
-
LENIENT_CHUNKED_LENGTH = 0x2
|
125
|
+
LENIENT_CHUNKED_LENGTH = 0x2,
|
126
|
+
LENIENT_KEEP_ALIVE = 0x4
|
125
127
|
};
|
126
128
|
typedef enum llhttp_lenient_flags llhttp_lenient_flags_t;
|
127
129
|
|
@@ -213,7 +215,8 @@ typedef enum llhttp_method llhttp_method_t;
|
|
213
215
|
XX(20, CB_CHUNK_COMPLETE, CB_CHUNK_COMPLETE) \
|
214
216
|
XX(21, PAUSED, PAUSED) \
|
215
217
|
XX(22, PAUSED_UPGRADE, PAUSED_UPGRADE) \
|
216
|
-
XX(23,
|
218
|
+
XX(23, PAUSED_H2_UPGRADE, PAUSED_H2_UPGRADE) \
|
219
|
+
XX(24, USER, USER) \
|
217
220
|
|
218
221
|
|
219
222
|
#define HTTP_METHOD_MAP(XX) \
|
@@ -251,7 +254,12 @@ typedef enum llhttp_method llhttp_method_t;
|
|
251
254
|
XX(31, LINK, LINK) \
|
252
255
|
XX(32, UNLINK, UNLINK) \
|
253
256
|
XX(33, SOURCE, SOURCE) \
|
254
|
-
|
257
|
+
|
258
|
+
|
259
|
+
#define RTSP_METHOD_MAP(XX) \
|
260
|
+
XX(1, GET, GET) \
|
261
|
+
XX(3, POST, POST) \
|
262
|
+
XX(6, OPTIONS, OPTIONS) \
|
255
263
|
XX(35, DESCRIBE, DESCRIBE) \
|
256
264
|
XX(36, ANNOUNCE, ANNOUNCE) \
|
257
265
|
XX(37, SETUP, SETUP) \
|
@@ -265,6 +273,54 @@ typedef enum llhttp_method llhttp_method_t;
|
|
265
273
|
XX(45, FLUSH, FLUSH) \
|
266
274
|
|
267
275
|
|
276
|
+
#define HTTP_ALL_METHOD_MAP(XX) \
|
277
|
+
XX(0, DELETE, DELETE) \
|
278
|
+
XX(1, GET, GET) \
|
279
|
+
XX(2, HEAD, HEAD) \
|
280
|
+
XX(3, POST, POST) \
|
281
|
+
XX(4, PUT, PUT) \
|
282
|
+
XX(5, CONNECT, CONNECT) \
|
283
|
+
XX(6, OPTIONS, OPTIONS) \
|
284
|
+
XX(7, TRACE, TRACE) \
|
285
|
+
XX(8, COPY, COPY) \
|
286
|
+
XX(9, LOCK, LOCK) \
|
287
|
+
XX(10, MKCOL, MKCOL) \
|
288
|
+
XX(11, MOVE, MOVE) \
|
289
|
+
XX(12, PROPFIND, PROPFIND) \
|
290
|
+
XX(13, PROPPATCH, PROPPATCH) \
|
291
|
+
XX(14, SEARCH, SEARCH) \
|
292
|
+
XX(15, UNLOCK, UNLOCK) \
|
293
|
+
XX(16, BIND, BIND) \
|
294
|
+
XX(17, REBIND, REBIND) \
|
295
|
+
XX(18, UNBIND, UNBIND) \
|
296
|
+
XX(19, ACL, ACL) \
|
297
|
+
XX(20, REPORT, REPORT) \
|
298
|
+
XX(21, MKACTIVITY, MKACTIVITY) \
|
299
|
+
XX(22, CHECKOUT, CHECKOUT) \
|
300
|
+
XX(23, MERGE, MERGE) \
|
301
|
+
XX(24, MSEARCH, M-SEARCH) \
|
302
|
+
XX(25, NOTIFY, NOTIFY) \
|
303
|
+
XX(26, SUBSCRIBE, SUBSCRIBE) \
|
304
|
+
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
|
305
|
+
XX(28, PATCH, PATCH) \
|
306
|
+
XX(29, PURGE, PURGE) \
|
307
|
+
XX(30, MKCALENDAR, MKCALENDAR) \
|
308
|
+
XX(31, LINK, LINK) \
|
309
|
+
XX(32, UNLINK, UNLINK) \
|
310
|
+
XX(33, SOURCE, SOURCE) \
|
311
|
+
XX(34, PRI, PRI) \
|
312
|
+
XX(35, DESCRIBE, DESCRIBE) \
|
313
|
+
XX(36, ANNOUNCE, ANNOUNCE) \
|
314
|
+
XX(37, SETUP, SETUP) \
|
315
|
+
XX(38, PLAY, PLAY) \
|
316
|
+
XX(39, PAUSE, PAUSE) \
|
317
|
+
XX(40, TEARDOWN, TEARDOWN) \
|
318
|
+
XX(41, GET_PARAMETER, GET_PARAMETER) \
|
319
|
+
XX(42, SET_PARAMETER, SET_PARAMETER) \
|
320
|
+
XX(43, REDIRECT, REDIRECT) \
|
321
|
+
XX(44, RECORD, RECORD) \
|
322
|
+
XX(45, FLUSH, FLUSH) \
|
323
|
+
|
268
324
|
|
269
325
|
#ifdef __cplusplus
|
270
326
|
} /* extern "C" */
|
@@ -278,6 +334,12 @@ extern "C" {
|
|
278
334
|
#endif
|
279
335
|
#include <stddef.h>
|
280
336
|
|
337
|
+
#if defined(__wasm__)
|
338
|
+
#define LLHTTP_EXPORT __attribute__((visibility("default")))
|
339
|
+
#else
|
340
|
+
#define LLHTTP_EXPORT
|
341
|
+
#endif
|
342
|
+
|
281
343
|
typedef llhttp__internal_t llhttp_t;
|
282
344
|
typedef struct llhttp_settings_s llhttp_settings_t;
|
283
345
|
|
@@ -288,6 +350,7 @@ struct llhttp_settings_s {
|
|
288
350
|
/* Possible return values 0, -1, `HPE_PAUSED` */
|
289
351
|
llhttp_cb on_message_begin;
|
290
352
|
|
353
|
+
/* Possible return values 0, -1, HPE_USER */
|
291
354
|
llhttp_data_cb on_url;
|
292
355
|
llhttp_data_cb on_status;
|
293
356
|
llhttp_data_cb on_header_field;
|
@@ -304,6 +367,7 @@ struct llhttp_settings_s {
|
|
304
367
|
*/
|
305
368
|
llhttp_cb on_headers_complete;
|
306
369
|
|
370
|
+
/* Possible return values 0, -1, HPE_USER */
|
307
371
|
llhttp_data_cb on_body;
|
308
372
|
|
309
373
|
/* Possible return values 0, -1, `HPE_PAUSED` */
|
@@ -316,6 +380,7 @@ struct llhttp_settings_s {
|
|
316
380
|
llhttp_cb on_chunk_header;
|
317
381
|
llhttp_cb on_chunk_complete;
|
318
382
|
|
383
|
+
/* Information-only callbacks, return value is ignored */
|
319
384
|
llhttp_cb on_url_complete;
|
320
385
|
llhttp_cb on_status_complete;
|
321
386
|
llhttp_cb on_header_field_complete;
|
@@ -328,15 +393,46 @@ struct llhttp_settings_s {
|
|
328
393
|
* the `parser` here. In practice, `settings` has to be either a static
|
329
394
|
* variable or be allocated with `malloc`, `new`, etc.
|
330
395
|
*/
|
396
|
+
LLHTTP_EXPORT
|
331
397
|
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
|
332
398
|
const llhttp_settings_t* settings);
|
333
399
|
|
400
|
+
#if defined(__wasm__)
|
401
|
+
|
402
|
+
LLHTTP_EXPORT
|
403
|
+
llhttp_t* llhttp_alloc(llhttp_type_t type);
|
404
|
+
|
405
|
+
LLHTTP_EXPORT
|
406
|
+
void llhttp_free(llhttp_t* parser);
|
407
|
+
|
408
|
+
LLHTTP_EXPORT
|
409
|
+
uint8_t llhttp_get_type(llhttp_t* parser);
|
410
|
+
|
411
|
+
LLHTTP_EXPORT
|
412
|
+
uint8_t llhttp_get_http_major(llhttp_t* parser);
|
413
|
+
|
414
|
+
LLHTTP_EXPORT
|
415
|
+
uint8_t llhttp_get_http_minor(llhttp_t* parser);
|
416
|
+
|
417
|
+
LLHTTP_EXPORT
|
418
|
+
uint8_t llhttp_get_method(llhttp_t* parser);
|
419
|
+
|
420
|
+
LLHTTP_EXPORT
|
421
|
+
int llhttp_get_status_code(llhttp_t* parser);
|
422
|
+
|
423
|
+
LLHTTP_EXPORT
|
424
|
+
uint8_t llhttp_get_upgrade(llhttp_t* parser);
|
425
|
+
|
426
|
+
#endif // defined(__wasm__)
|
427
|
+
|
334
428
|
/* Reset an already initialized parser back to the start state, preserving the
|
335
429
|
* existing parser type, callback settings, user data, and lenient flags.
|
336
430
|
*/
|
431
|
+
LLHTTP_EXPORT
|
337
432
|
void llhttp_reset(llhttp_t* parser);
|
338
433
|
|
339
434
|
/* Initialize the settings object */
|
435
|
+
LLHTTP_EXPORT
|
340
436
|
void llhttp_settings_init(llhttp_settings_t* settings);
|
341
437
|
|
342
438
|
/* Parse full or partial request/response, invoking user callbacks along the
|
@@ -355,6 +451,7 @@ void llhttp_settings_init(llhttp_settings_t* settings);
|
|
355
451
|
* to return the same error upon each successive call up until `llhttp_init()`
|
356
452
|
* is called.
|
357
453
|
*/
|
454
|
+
LLHTTP_EXPORT
|
358
455
|
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len);
|
359
456
|
|
360
457
|
/* This method should be called when the other side has no further bytes to
|
@@ -365,16 +462,19 @@ llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len);
|
|
365
462
|
* connection. This method will invoke `on_message_complete()` callback if the
|
366
463
|
* request was terminated safely. Otherwise a error code would be returned.
|
367
464
|
*/
|
465
|
+
LLHTTP_EXPORT
|
368
466
|
llhttp_errno_t llhttp_finish(llhttp_t* parser);
|
369
467
|
|
370
468
|
/* Returns `1` if the incoming message is parsed until the last byte, and has
|
371
469
|
* to be completed by calling `llhttp_finish()` on EOF
|
372
470
|
*/
|
471
|
+
LLHTTP_EXPORT
|
373
472
|
int llhttp_message_needs_eof(const llhttp_t* parser);
|
374
473
|
|
375
474
|
/* Returns `1` if there might be any other messages following the last that was
|
376
475
|
* successfully parsed.
|
377
476
|
*/
|
477
|
+
LLHTTP_EXPORT
|
378
478
|
int llhttp_should_keep_alive(const llhttp_t* parser);
|
379
479
|
|
380
480
|
/* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set
|
@@ -383,6 +483,7 @@ int llhttp_should_keep_alive(const llhttp_t* parser);
|
|
383
483
|
* Important: do not call this from user callbacks! User callbacks must return
|
384
484
|
* `HPE_PAUSED` if pausing is required.
|
385
485
|
*/
|
486
|
+
LLHTTP_EXPORT
|
386
487
|
void llhttp_pause(llhttp_t* parser);
|
387
488
|
|
388
489
|
/* Might be called to resume the execution after the pause in user's callback.
|
@@ -390,6 +491,7 @@ void llhttp_pause(llhttp_t* parser);
|
|
390
491
|
*
|
391
492
|
* Call this only if `llhttp_execute()` returns `HPE_PAUSED`.
|
392
493
|
*/
|
494
|
+
LLHTTP_EXPORT
|
393
495
|
void llhttp_resume(llhttp_t* parser);
|
394
496
|
|
395
497
|
/* Might be called to resume the execution after the pause in user's callback.
|
@@ -397,9 +499,11 @@ void llhttp_resume(llhttp_t* parser);
|
|
397
499
|
*
|
398
500
|
* Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE`
|
399
501
|
*/
|
502
|
+
LLHTTP_EXPORT
|
400
503
|
void llhttp_resume_after_upgrade(llhttp_t* parser);
|
401
504
|
|
402
505
|
/* Returns the latest return error */
|
506
|
+
LLHTTP_EXPORT
|
403
507
|
llhttp_errno_t llhttp_get_errno(const llhttp_t* parser);
|
404
508
|
|
405
509
|
/* Returns the verbal explanation of the latest returned error.
|
@@ -407,6 +511,7 @@ llhttp_errno_t llhttp_get_errno(const llhttp_t* parser);
|
|
407
511
|
* Note: User callback should set error reason when returning the error. See
|
408
512
|
* `llhttp_set_error_reason()` for details.
|
409
513
|
*/
|
514
|
+
LLHTTP_EXPORT
|
410
515
|
const char* llhttp_get_error_reason(const llhttp_t* parser);
|
411
516
|
|
412
517
|
/* Assign verbal description to the returned error. Must be called in user
|
@@ -414,6 +519,7 @@ const char* llhttp_get_error_reason(const llhttp_t* parser);
|
|
414
519
|
*
|
415
520
|
* Note: `HPE_USER` error code might be useful in user callbacks.
|
416
521
|
*/
|
522
|
+
LLHTTP_EXPORT
|
417
523
|
void llhttp_set_error_reason(llhttp_t* parser, const char* reason);
|
418
524
|
|
419
525
|
/* Returns the pointer to the last parsed byte before the returned error. The
|
@@ -421,12 +527,15 @@ void llhttp_set_error_reason(llhttp_t* parser, const char* reason);
|
|
421
527
|
*
|
422
528
|
* Note: this method might be useful for counting the number of parsed bytes.
|
423
529
|
*/
|
530
|
+
LLHTTP_EXPORT
|
424
531
|
const char* llhttp_get_error_pos(const llhttp_t* parser);
|
425
532
|
|
426
533
|
/* Returns textual name of error code */
|
534
|
+
LLHTTP_EXPORT
|
427
535
|
const char* llhttp_errno_name(llhttp_errno_t err);
|
428
536
|
|
429
537
|
/* Returns textual name of HTTP method */
|
538
|
+
LLHTTP_EXPORT
|
430
539
|
const char* llhttp_method_name(llhttp_method_t method);
|
431
540
|
|
432
541
|
|
@@ -439,6 +548,7 @@ const char* llhttp_method_name(llhttp_method_t method);
|
|
439
548
|
*
|
440
549
|
* **(USE AT YOUR OWN RISK)**
|
441
550
|
*/
|
551
|
+
LLHTTP_EXPORT
|
442
552
|
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
|
443
553
|
|
444
554
|
|
@@ -452,8 +562,23 @@ void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
|
|
452
562
|
*
|
453
563
|
* **(USE AT YOUR OWN RISK)**
|
454
564
|
*/
|
565
|
+
LLHTTP_EXPORT
|
455
566
|
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled);
|
456
567
|
|
568
|
+
|
569
|
+
/* Enables/disables lenient handling of `Connection: close` and HTTP/1.0
|
570
|
+
* requests responses.
|
571
|
+
*
|
572
|
+
* Normally `llhttp` would error on (in strict mode) or discard (in loose mode)
|
573
|
+
* the HTTP request/response after the request/response with `Connection: close`
|
574
|
+
* and `Content-Length`. This is important to prevent cache poisoning attacks,
|
575
|
+
* but might interact badly with outdated and insecure clients. With this flag
|
576
|
+
* the extra request/response will be parsed normally.
|
577
|
+
*
|
578
|
+
* **(USE AT YOUR OWN RISK)**
|
579
|
+
*/
|
580
|
+
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled);
|
581
|
+
|
457
582
|
#ifdef __cplusplus
|
458
583
|
} /* extern "C" */
|
459
584
|
#endif
|
data/ext/llhttp/llhttp_ext.c
CHANGED
@@ -10,34 +10,43 @@
|
|
10
10
|
|
11
11
|
static VALUE mLLHttp, cParser, eError;
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
13
|
+
typedef struct {
|
14
|
+
VALUE delegate;
|
15
|
+
ID on_message_begin;
|
16
|
+
ID on_url;
|
17
|
+
ID on_status;
|
18
|
+
ID on_header_field;
|
19
|
+
ID on_header_value;
|
20
|
+
ID on_headers_complete;
|
21
|
+
ID on_body;
|
22
|
+
ID on_message_complete;
|
23
|
+
ID on_chunk_header;
|
24
|
+
ID on_chunk_complete;
|
25
|
+
ID on_url_complete;
|
26
|
+
ID on_status_complete;
|
27
|
+
ID on_header_field_complete;
|
28
|
+
ID on_header_value_complete;
|
29
|
+
} rb_llhttp_parser_data;
|
27
30
|
|
28
31
|
static void rb_llhttp_free(llhttp_t *parser) {
|
29
|
-
|
32
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
33
|
+
|
34
|
+
// If `parserData` is not `0`, it (and settings) were initialized.
|
35
|
+
//
|
36
|
+
if (parserData != 0) {
|
37
|
+
free(parserData);
|
30
38
|
free(parser->settings);
|
31
|
-
free(parser);
|
32
39
|
}
|
40
|
+
|
41
|
+
free(parser);
|
33
42
|
}
|
34
43
|
|
35
44
|
VALUE rb_llhttp_allocate(VALUE klass) {
|
36
45
|
llhttp_t *parser = (llhttp_t *)malloc(sizeof(llhttp_t));
|
37
|
-
llhttp_settings_t *settings = (llhttp_settings_t *)malloc(sizeof(llhttp_settings_t));
|
38
46
|
|
39
|
-
|
40
|
-
|
47
|
+
// Set data to false so we know when the parser has been initialized.
|
48
|
+
//
|
49
|
+
parser->data = 0;
|
41
50
|
|
42
51
|
return Data_Wrap_Struct(klass, 0, rb_llhttp_free, parser);
|
43
52
|
}
|
@@ -51,77 +60,105 @@ void rb_llhttp_data_callback_call(VALUE delegate, ID method, char *data, size_t
|
|
51
60
|
}
|
52
61
|
|
53
62
|
int rb_llhttp_on_message_begin(llhttp_t *parser) {
|
54
|
-
|
63
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
64
|
+
|
65
|
+
return NUM2INT(rb_llhttp_callback_call(parserData->delegate, parserData->on_message_begin));
|
55
66
|
}
|
56
67
|
|
57
68
|
int rb_llhttp_on_headers_complete(llhttp_t *parser) {
|
58
|
-
|
69
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
70
|
+
|
71
|
+
return NUM2INT(rb_llhttp_callback_call(parserData->delegate, parserData->on_headers_complete));
|
59
72
|
}
|
60
73
|
|
61
74
|
int rb_llhttp_on_message_complete(llhttp_t *parser) {
|
62
|
-
|
75
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
76
|
+
|
77
|
+
return NUM2INT(rb_llhttp_callback_call(parserData->delegate, parserData->on_message_complete));
|
63
78
|
}
|
64
79
|
|
65
80
|
int rb_llhttp_on_chunk_header(llhttp_t *parser) {
|
66
|
-
|
81
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
82
|
+
|
83
|
+
return NUM2INT(rb_llhttp_callback_call(parserData->delegate, parserData->on_chunk_header));
|
67
84
|
}
|
68
85
|
|
69
86
|
int rb_llhttp_on_url(llhttp_t *parser, char *data, size_t length) {
|
70
|
-
|
87
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
88
|
+
|
89
|
+
rb_llhttp_data_callback_call(parserData->delegate, parserData->on_url, data, length);
|
71
90
|
|
72
91
|
return 0;
|
73
92
|
}
|
74
93
|
|
75
94
|
int rb_llhttp_on_status(llhttp_t *parser, char *data, size_t length) {
|
76
|
-
|
95
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
96
|
+
|
97
|
+
rb_llhttp_data_callback_call(parserData->delegate, parserData->on_status, data, length);
|
77
98
|
|
78
99
|
return 0;
|
79
100
|
}
|
80
101
|
|
81
102
|
int rb_llhttp_on_header_field(llhttp_t *parser, char *data, size_t length) {
|
82
|
-
|
103
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
104
|
+
|
105
|
+
rb_llhttp_data_callback_call(parserData->delegate, parserData->on_header_field, data, length);
|
83
106
|
|
84
107
|
return 0;
|
85
108
|
}
|
86
109
|
|
87
110
|
int rb_llhttp_on_header_value(llhttp_t *parser, char *data, size_t length) {
|
88
|
-
|
111
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
112
|
+
|
113
|
+
rb_llhttp_data_callback_call(parserData->delegate, parserData->on_header_value, data, length);
|
89
114
|
|
90
115
|
return 0;
|
91
116
|
}
|
92
117
|
|
93
118
|
int rb_llhttp_on_body(llhttp_t *parser, char *data, size_t length) {
|
94
|
-
|
119
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
120
|
+
|
121
|
+
rb_llhttp_data_callback_call(parserData->delegate, parserData->on_body, data, length);
|
95
122
|
|
96
123
|
return 0;
|
97
124
|
}
|
98
125
|
|
99
126
|
int rb_llhttp_on_chunk_complete(llhttp_t *parser) {
|
100
|
-
|
127
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
128
|
+
|
129
|
+
rb_llhttp_callback_call(parserData->delegate, parserData->on_chunk_complete);
|
101
130
|
|
102
131
|
return 0;
|
103
132
|
}
|
104
133
|
|
105
134
|
int rb_llhttp_on_url_complete(llhttp_t *parser) {
|
106
|
-
|
135
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
136
|
+
|
137
|
+
rb_llhttp_callback_call(parserData->delegate, parserData->on_url_complete);
|
107
138
|
|
108
139
|
return 0;
|
109
140
|
}
|
110
141
|
|
111
142
|
int rb_llhttp_on_status_complete(llhttp_t *parser) {
|
112
|
-
|
143
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
144
|
+
|
145
|
+
rb_llhttp_callback_call(parserData->delegate, parserData->on_status_complete);
|
113
146
|
|
114
147
|
return 0;
|
115
148
|
}
|
116
149
|
|
117
150
|
int rb_llhttp_on_header_field_complete(llhttp_t *parser) {
|
118
|
-
|
151
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
152
|
+
|
153
|
+
rb_llhttp_callback_call(parserData->delegate, parserData->on_header_field_complete);
|
119
154
|
|
120
155
|
return 0;
|
121
156
|
}
|
122
157
|
|
123
158
|
int rb_llhttp_on_header_value_complete(llhttp_t *parser) {
|
124
|
-
|
159
|
+
rb_llhttp_parser_data *parserData = (rb_llhttp_parser_data*) parser->data;
|
160
|
+
|
161
|
+
rb_llhttp_callback_call(parserData->delegate, parserData->on_header_value_complete);
|
125
162
|
|
126
163
|
return 0;
|
127
164
|
}
|
@@ -154,6 +191,16 @@ VALUE rb_llhttp_finish(VALUE self) {
|
|
154
191
|
return Qtrue;
|
155
192
|
}
|
156
193
|
|
194
|
+
VALUE rb_llhttp_reset(VALUE self) {
|
195
|
+
llhttp_t *parser;
|
196
|
+
|
197
|
+
Data_Get_Struct(self, llhttp_t, parser);
|
198
|
+
|
199
|
+
llhttp_reset(parser);
|
200
|
+
|
201
|
+
return Qtrue;
|
202
|
+
}
|
203
|
+
|
157
204
|
VALUE rb_llhttp_content_length(VALUE self) {
|
158
205
|
llhttp_t *parser;
|
159
206
|
|
@@ -209,84 +256,86 @@ static VALUE rb_llhttp_init(VALUE self, VALUE type) {
|
|
209
256
|
|
210
257
|
Data_Get_Struct(self, llhttp_t, parser);
|
211
258
|
|
212
|
-
llhttp_settings_t *settings =
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
259
|
+
llhttp_settings_t *settings = (llhttp_settings_t *)malloc(sizeof(llhttp_settings_t));
|
260
|
+
llhttp_settings_init(settings);
|
261
|
+
|
262
|
+
rb_llhttp_parser_data *parserData = malloc(sizeof(rb_llhttp_parser_data));
|
263
|
+
parserData->delegate = rb_iv_get(self, "@delegate");
|
264
|
+
|
265
|
+
parserData->on_message_begin = rb_intern("internal_on_message_begin");
|
266
|
+
parserData->on_headers_complete = rb_intern("internal_on_headers_complete");
|
267
|
+
parserData->on_message_complete = rb_intern("internal_on_message_complete");
|
268
|
+
parserData->on_chunk_header = rb_intern("internal_on_chunk_header");
|
269
|
+
parserData->on_url = rb_intern("on_url");
|
270
|
+
parserData->on_status = rb_intern("on_status");
|
271
|
+
parserData->on_header_field = rb_intern("on_header_field");
|
272
|
+
parserData->on_header_value = rb_intern("on_header_value");
|
273
|
+
parserData->on_body = rb_intern("on_body");
|
274
|
+
parserData->on_chunk_complete = rb_intern("on_chunk_complete");
|
275
|
+
parserData->on_url_complete = rb_intern("on_url_complete");
|
276
|
+
parserData->on_status_complete = rb_intern("on_status_complete");
|
277
|
+
parserData->on_header_field_complete = rb_intern("on_header_field_complete");
|
278
|
+
parserData->on_header_value_complete = rb_intern("on_header_value_complete");
|
279
|
+
|
280
|
+
if (rb_respond_to(parserData->delegate, rb_intern("on_message_begin"))) {
|
232
281
|
settings->on_message_begin = (llhttp_cb)rb_llhttp_on_message_begin;
|
233
282
|
}
|
234
283
|
|
235
|
-
if (rb_respond_to(delegate, rb_intern("on_headers_complete"))) {
|
284
|
+
if (rb_respond_to(parserData->delegate, rb_intern("on_headers_complete"))) {
|
236
285
|
settings->on_headers_complete = (llhttp_cb)rb_llhttp_on_headers_complete;
|
237
286
|
}
|
238
287
|
|
239
|
-
if (rb_respond_to(delegate, rb_intern("on_message_complete"))) {
|
288
|
+
if (rb_respond_to(parserData->delegate, rb_intern("on_message_complete"))) {
|
240
289
|
settings->on_message_complete = (llhttp_cb)rb_llhttp_on_message_complete;
|
241
290
|
}
|
242
291
|
|
243
|
-
if (rb_respond_to(delegate, rb_intern("on_chunk_header"))) {
|
292
|
+
if (rb_respond_to(parserData->delegate, rb_intern("on_chunk_header"))) {
|
244
293
|
settings->on_chunk_header = (llhttp_cb)rb_llhttp_on_chunk_header;
|
245
294
|
}
|
246
295
|
|
247
|
-
if (rb_respond_to(delegate,
|
296
|
+
if (rb_respond_to(parserData->delegate, parserData->on_url)) {
|
248
297
|
settings->on_url = (llhttp_data_cb)rb_llhttp_on_url;
|
249
298
|
}
|
250
299
|
|
251
|
-
if (rb_respond_to(delegate,
|
300
|
+
if (rb_respond_to(parserData->delegate, parserData->on_status)) {
|
252
301
|
settings->on_status = (llhttp_data_cb)rb_llhttp_on_status;
|
253
302
|
}
|
254
303
|
|
255
|
-
if (rb_respond_to(delegate,
|
304
|
+
if (rb_respond_to(parserData->delegate, parserData->on_header_field)) {
|
256
305
|
settings->on_header_field = (llhttp_data_cb)rb_llhttp_on_header_field;
|
257
306
|
}
|
258
307
|
|
259
|
-
if (rb_respond_to(delegate,
|
308
|
+
if (rb_respond_to(parserData->delegate, parserData->on_header_value)) {
|
260
309
|
settings->on_header_value = (llhttp_data_cb)rb_llhttp_on_header_value;
|
261
310
|
}
|
262
311
|
|
263
|
-
if (rb_respond_to(delegate,
|
312
|
+
if (rb_respond_to(parserData->delegate, parserData->on_body)) {
|
264
313
|
settings->on_body = (llhttp_data_cb)rb_llhttp_on_body;
|
265
314
|
}
|
266
315
|
|
267
|
-
if (rb_respond_to(delegate,
|
316
|
+
if (rb_respond_to(parserData->delegate, parserData->on_chunk_complete)) {
|
268
317
|
settings->on_chunk_complete = (llhttp_cb)rb_llhttp_on_chunk_complete;
|
269
318
|
}
|
270
319
|
|
271
|
-
if (rb_respond_to(delegate,
|
320
|
+
if (rb_respond_to(parserData->delegate, parserData->on_url_complete)) {
|
272
321
|
settings->on_url_complete = (llhttp_cb)rb_llhttp_on_url_complete;
|
273
322
|
}
|
274
323
|
|
275
|
-
if (rb_respond_to(delegate,
|
324
|
+
if (rb_respond_to(parserData->delegate, parserData->on_status_complete)) {
|
276
325
|
settings->on_status_complete = (llhttp_cb)rb_llhttp_on_status_complete;
|
277
326
|
}
|
278
327
|
|
279
|
-
if (rb_respond_to(delegate,
|
328
|
+
if (rb_respond_to(parserData->delegate, parserData->on_header_field_complete)) {
|
280
329
|
settings->on_header_field_complete = (llhttp_cb)rb_llhttp_on_header_field_complete;
|
281
330
|
}
|
282
331
|
|
283
|
-
if (rb_respond_to(delegate,
|
332
|
+
if (rb_respond_to(parserData->delegate, parserData->on_header_value_complete)) {
|
284
333
|
settings->on_header_value_complete = (llhttp_cb)rb_llhttp_on_header_value_complete;
|
285
334
|
}
|
286
335
|
|
287
336
|
llhttp_init(parser, FIX2INT(type), settings);
|
288
337
|
|
289
|
-
parser->data = (void*)
|
338
|
+
parser->data = (void*)parserData;
|
290
339
|
|
291
340
|
return Qtrue;
|
292
341
|
}
|
@@ -301,6 +350,7 @@ void Init_llhttp_ext(void) {
|
|
301
350
|
rb_define_method(cParser, "<<", rb_llhttp_parse, 1);
|
302
351
|
rb_define_method(cParser, "parse", rb_llhttp_parse, 1);
|
303
352
|
rb_define_method(cParser, "finish", rb_llhttp_finish, 0);
|
353
|
+
rb_define_method(cParser, "reset", rb_llhttp_reset, 0);
|
304
354
|
|
305
355
|
rb_define_method(cParser, "content_length", rb_llhttp_content_length, 0);
|
306
356
|
rb_define_method(cParser, "method_name", rb_llhttp_method_name, 0);
|
data/lib/llhttp/parser.rb
CHANGED
@@ -30,6 +30,10 @@ module LLHttp
|
|
30
30
|
#
|
31
31
|
# Call `LLHttp::Parser#finish` when processing is complete for the current request or response.
|
32
32
|
#
|
33
|
+
# Resetting
|
34
|
+
#
|
35
|
+
# Call `LLHttp::Parser#reset` to reset the parser for the next request or response.
|
36
|
+
#
|
33
37
|
class Parser
|
34
38
|
LLHTTP_TYPES = {both: 0, request: 1, response: 2}.freeze
|
35
39
|
|
data/lib/llhttp/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: llhttp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan Powell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby bindings for llhttp.
|
14
14
|
email: bryan@metabahn.com
|
@@ -26,17 +26,11 @@ files:
|
|
26
26
|
- ext/llhttp/llhttp.c
|
27
27
|
- ext/llhttp/llhttp.h
|
28
28
|
- ext/llhttp/llhttp_ext.c
|
29
|
-
- ext/x86_64-darwin/libllhttp-ext.bundle
|
30
|
-
- ext/x86_64-darwin/llhttp/api.o
|
31
|
-
- ext/x86_64-darwin/llhttp/http.o
|
32
|
-
- ext/x86_64-darwin/llhttp/llhttp.o
|
33
|
-
- ext/x86_64-darwin/llhttp/llhttp_ext.o
|
34
29
|
- lib/llhttp.rb
|
35
30
|
- lib/llhttp/delegate.rb
|
36
31
|
- lib/llhttp/error.rb
|
37
32
|
- lib/llhttp/parser.rb
|
38
33
|
- lib/llhttp/version.rb
|
39
|
-
- lib/llhttp_ext.bundle
|
40
34
|
homepage: https://github.com/metabahn/llhttp/
|
41
35
|
licenses:
|
42
36
|
- MPL-2.0
|
@@ -49,14 +43,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
43
|
requirements:
|
50
44
|
- - ">="
|
51
45
|
- !ruby/object:Gem::Version
|
52
|
-
version: 2.
|
46
|
+
version: 2.6.7
|
53
47
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
48
|
requirements:
|
55
49
|
- - ">="
|
56
50
|
- !ruby/object:Gem::Version
|
57
51
|
version: '0'
|
58
52
|
requirements: []
|
59
|
-
rubygems_version: 3.2.
|
53
|
+
rubygems_version: 3.2.22
|
60
54
|
signing_key:
|
61
55
|
specification_version: 4
|
62
56
|
summary: Ruby bindings for llhttp.
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/llhttp_ext.bundle
DELETED
Binary file
|