llhttp 0.1.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|