llhttp-ffi 0.1.0 → 0.4.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 +28 -2
- data/README.md +1 -1
- data/ext/llhttp/api.c +41 -20
- data/ext/llhttp/llhttp.c +4 -4
- data/ext/llhttp/llhttp.h +60 -4
- data/lib/llhttp/parser.rb +8 -2
- data/lib/llhttp/version.rb +1 -1
- data/lib/llhttp.rb +1 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c6af451609178568c6487f75fcece2bf8915e0bec6fd51a44761598382afa5de
|
4
|
+
data.tar.gz: 037b38718ded224ec48808f183b1bf9a5e8f65949eaf0fd64379657233521bd1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2947c990fdb5a4909d2c631e417bff9e9003b04d0f7fed674d01d7328f75dab2766d1ec4f3aa591267f94c3cf03be352d6aaebe176a49558703675ba3cc087b7
|
7
|
+
data.tar.gz: 5feb106a0e5f6e92cd1f63b506bc84af6add70565cc1f603a4cdb55ae7af2cbc71bf4f1a68df02b1238bdf25bf08e58255cbc010141817081986578d5b9d1645
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,32 @@
|
|
1
|
-
## v0.
|
1
|
+
## v0.4.0
|
2
2
|
|
3
|
-
*
|
3
|
+
*released on 2021-09-09*
|
4
|
+
|
5
|
+
* `add` [#25](https://github.com/metabahn/llhttp/pull/25) Add support for resetting the parser ([bryanp](https://github.com/bryanp))
|
6
|
+
* `chg` [#23](https://github.com/metabahn/llhttp/pull/23) Update ffi to llhttp 6.0.5 ([bryanp](https://github.com/bryanp))
|
7
|
+
|
8
|
+
## [v0.3.1](https://github.com/metabahn/llhttp/releases/tag/2021-06-25)
|
9
|
+
|
10
|
+
*released on 2021-06-25*
|
11
|
+
|
12
|
+
* `fix` [#22](https://github.com/metabahn/llhttp/pull/22) Fix call to ffi free ([bryanp](https://github.com/bryanp))
|
13
|
+
|
14
|
+
## [v0.3.0](https://github.com/metabahn/llhttp/releases/tag/2021-05-13)
|
15
|
+
|
16
|
+
*released on 2021-05-13*
|
17
|
+
|
18
|
+
* `chg` [#19](https://github.com/metabahn/llhttp/pull/19) Add back support for Ruby 2.5 in ffi ([bryanp](https://github.com/bryanp))
|
19
|
+
|
20
|
+
## [v0.2.0](https://github.com/metabahn/llhttp/releases/tag/2021-05-06)
|
21
|
+
|
22
|
+
*released on 2021-05-06*
|
23
|
+
|
24
|
+
* `chg` [#17](https://github.com/metabahn/llhttp/pull/17) Update ffi to llhttp 6.0.1 ([bryanp](https://github.com/bryanp))
|
25
|
+
* `chg` [#18](https://github.com/metabahn/llhttp/pull/18) Drop support for Ruby 2.5 ([bryanp](https://github.com/bryanp))
|
26
|
+
|
27
|
+
## [v0.1.0](https://github.com/metabahn/llhttp/releases/tag/2021-04-06)
|
28
|
+
|
29
|
+
*released on 2021-04-06*
|
4
30
|
|
5
31
|
* `chg` [#14](https://github.com/metabahn/llhttp/pull/14) Update ffi to llhttp 5.1.0 ([bryanp](https://github.com/bryanp))
|
6
32
|
|
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,
|
@@ -54,17 +69,23 @@ extern int wasm_on_url(llhttp_t* p, const char* at, size_t length);
|
|
54
69
|
extern int wasm_on_status(llhttp_t* p, const char* at, size_t length);
|
55
70
|
extern int wasm_on_header_field(llhttp_t* p, const char* at, size_t length);
|
56
71
|
extern int wasm_on_header_value(llhttp_t* p, const char* at, size_t length);
|
57
|
-
extern int wasm_on_headers_complete(llhttp_t * p
|
72
|
+
extern int wasm_on_headers_complete(llhttp_t * p, int status_code,
|
73
|
+
uint8_t upgrade, int should_keep_alive);
|
58
74
|
extern int wasm_on_body(llhttp_t* p, const char* at, size_t length);
|
59
75
|
extern int wasm_on_message_complete(llhttp_t * p);
|
60
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
|
+
|
61
82
|
const llhttp_settings_t wasm_settings = {
|
62
83
|
wasm_on_message_begin,
|
63
84
|
wasm_on_url,
|
64
85
|
wasm_on_status,
|
65
86
|
wasm_on_header_field,
|
66
87
|
wasm_on_header_value,
|
67
|
-
|
88
|
+
wasm_on_headers_complete_wrap,
|
68
89
|
wasm_on_body,
|
69
90
|
wasm_on_message_complete,
|
70
91
|
NULL,
|
@@ -146,7 +167,7 @@ llhttp_errno_t llhttp_finish(llhttp_t* parser) {
|
|
146
167
|
|
147
168
|
switch (parser->finish) {
|
148
169
|
case HTTP_FINISH_SAFE_WITH_CB:
|
149
|
-
CALLBACK_MAYBE(parser, on_message_complete
|
170
|
+
CALLBACK_MAYBE(parser, on_message_complete);
|
150
171
|
if (err != HPE_OK) return err;
|
151
172
|
|
152
173
|
/* FALLTHROUGH */
|
@@ -222,7 +243,7 @@ const char* llhttp_errno_name(llhttp_errno_t err) {
|
|
222
243
|
const char* llhttp_method_name(llhttp_method_t method) {
|
223
244
|
#define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
|
224
245
|
switch (method) {
|
225
|
-
|
246
|
+
HTTP_ALL_METHOD_MAP(HTTP_METHOD_GEN)
|
226
247
|
default: abort();
|
227
248
|
}
|
228
249
|
#undef HTTP_METHOD_GEN
|
@@ -260,98 +281,98 @@ void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
|
|
260
281
|
|
261
282
|
int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
|
262
283
|
int err;
|
263
|
-
CALLBACK_MAYBE(s, on_message_begin
|
284
|
+
CALLBACK_MAYBE(s, on_message_begin);
|
264
285
|
return err;
|
265
286
|
}
|
266
287
|
|
267
288
|
|
268
289
|
int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
|
269
290
|
int err;
|
270
|
-
|
291
|
+
SPAN_CALLBACK_MAYBE(s, on_url, p, endp - p);
|
271
292
|
return err;
|
272
293
|
}
|
273
294
|
|
274
295
|
|
275
296
|
int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) {
|
276
297
|
int err;
|
277
|
-
CALLBACK_MAYBE(s, on_url_complete
|
298
|
+
CALLBACK_MAYBE(s, on_url_complete);
|
278
299
|
return err;
|
279
300
|
}
|
280
301
|
|
281
302
|
|
282
303
|
int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
|
283
304
|
int err;
|
284
|
-
|
305
|
+
SPAN_CALLBACK_MAYBE(s, on_status, p, endp - p);
|
285
306
|
return err;
|
286
307
|
}
|
287
308
|
|
288
309
|
|
289
310
|
int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp) {
|
290
311
|
int err;
|
291
|
-
CALLBACK_MAYBE(s, on_status_complete
|
312
|
+
CALLBACK_MAYBE(s, on_status_complete);
|
292
313
|
return err;
|
293
314
|
}
|
294
315
|
|
295
316
|
|
296
317
|
int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
|
297
318
|
int err;
|
298
|
-
|
319
|
+
SPAN_CALLBACK_MAYBE(s, on_header_field, p, endp - p);
|
299
320
|
return err;
|
300
321
|
}
|
301
322
|
|
302
323
|
|
303
324
|
int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp) {
|
304
325
|
int err;
|
305
|
-
CALLBACK_MAYBE(s, on_header_field_complete
|
326
|
+
CALLBACK_MAYBE(s, on_header_field_complete);
|
306
327
|
return err;
|
307
328
|
}
|
308
329
|
|
309
330
|
|
310
331
|
int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
|
311
332
|
int err;
|
312
|
-
|
333
|
+
SPAN_CALLBACK_MAYBE(s, on_header_value, p, endp - p);
|
313
334
|
return err;
|
314
335
|
}
|
315
336
|
|
316
337
|
|
317
338
|
int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp) {
|
318
339
|
int err;
|
319
|
-
CALLBACK_MAYBE(s, on_header_value_complete
|
340
|
+
CALLBACK_MAYBE(s, on_header_value_complete);
|
320
341
|
return err;
|
321
342
|
}
|
322
343
|
|
323
344
|
|
324
345
|
int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
|
325
346
|
int err;
|
326
|
-
CALLBACK_MAYBE(s, on_headers_complete
|
347
|
+
CALLBACK_MAYBE(s, on_headers_complete);
|
327
348
|
return err;
|
328
349
|
}
|
329
350
|
|
330
351
|
|
331
352
|
int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
|
332
353
|
int err;
|
333
|
-
CALLBACK_MAYBE(s, on_message_complete
|
354
|
+
CALLBACK_MAYBE(s, on_message_complete);
|
334
355
|
return err;
|
335
356
|
}
|
336
357
|
|
337
358
|
|
338
359
|
int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
|
339
360
|
int err;
|
340
|
-
|
361
|
+
SPAN_CALLBACK_MAYBE(s, on_body, p, endp - p);
|
341
362
|
return err;
|
342
363
|
}
|
343
364
|
|
344
365
|
|
345
366
|
int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
|
346
367
|
int err;
|
347
|
-
CALLBACK_MAYBE(s, on_chunk_header
|
368
|
+
CALLBACK_MAYBE(s, on_chunk_header);
|
348
369
|
return err;
|
349
370
|
}
|
350
371
|
|
351
372
|
|
352
373
|
int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
|
353
374
|
int err;
|
354
|
-
CALLBACK_MAYBE(s, on_chunk_complete
|
375
|
+
CALLBACK_MAYBE(s, on_chunk_complete);
|
355
376
|
return err;
|
356
377
|
}
|
357
378
|
|
data/ext/llhttp/llhttp.c
CHANGED
@@ -1126,7 +1126,7 @@ static llparse_state_t llhttp__internal__run(
|
|
1126
1126
|
case s_n_llhttp__internal__n_consume_content_length:
|
1127
1127
|
s_n_llhttp__internal__n_consume_content_length: {
|
1128
1128
|
size_t avail;
|
1129
|
-
|
1129
|
+
uint64_t need;
|
1130
1130
|
|
1131
1131
|
avail = endp - p;
|
1132
1132
|
need = state->content_length;
|
@@ -1481,7 +1481,7 @@ static llparse_state_t llhttp__internal__run(
|
|
1481
1481
|
case s_n_llhttp__internal__n_consume_content_length_1:
|
1482
1482
|
s_n_llhttp__internal__n_consume_content_length_1: {
|
1483
1483
|
size_t avail;
|
1484
|
-
|
1484
|
+
uint64_t need;
|
1485
1485
|
|
1486
1486
|
avail = endp - p;
|
1487
1487
|
need = state->content_length;
|
@@ -8700,7 +8700,7 @@ static llparse_state_t llhttp__internal__run(
|
|
8700
8700
|
case s_n_llhttp__internal__n_consume_content_length:
|
8701
8701
|
s_n_llhttp__internal__n_consume_content_length: {
|
8702
8702
|
size_t avail;
|
8703
|
-
|
8703
|
+
uint64_t need;
|
8704
8704
|
|
8705
8705
|
avail = endp - p;
|
8706
8706
|
need = state->content_length;
|
@@ -9048,7 +9048,7 @@ static llparse_state_t llhttp__internal__run(
|
|
9048
9048
|
case s_n_llhttp__internal__n_consume_content_length_1:
|
9049
9049
|
s_n_llhttp__internal__n_consume_content_length_1: {
|
9050
9050
|
size_t avail;
|
9051
|
-
|
9051
|
+
uint64_t need;
|
9052
9052
|
|
9053
9053
|
avail = endp - p;
|
9054
9054
|
need = state->content_length;
|
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
|
28
|
-
#define LLHTTP_VERSION_MINOR
|
29
|
-
#define LLHTTP_VERSION_PATCH
|
27
|
+
#define LLHTTP_VERSION_MAJOR 6
|
28
|
+
#define LLHTTP_VERSION_MINOR 0
|
29
|
+
#define LLHTTP_VERSION_PATCH 5
|
30
30
|
|
31
31
|
#ifndef LLHTTP_STRICT_MODE
|
32
32
|
# define LLHTTP_STRICT_MODE 0
|
@@ -254,7 +254,12 @@ typedef enum llhttp_method llhttp_method_t;
|
|
254
254
|
XX(31, LINK, LINK) \
|
255
255
|
XX(32, UNLINK, UNLINK) \
|
256
256
|
XX(33, SOURCE, SOURCE) \
|
257
|
-
|
257
|
+
|
258
|
+
|
259
|
+
#define RTSP_METHOD_MAP(XX) \
|
260
|
+
XX(1, GET, GET) \
|
261
|
+
XX(3, POST, POST) \
|
262
|
+
XX(6, OPTIONS, OPTIONS) \
|
258
263
|
XX(35, DESCRIBE, DESCRIBE) \
|
259
264
|
XX(36, ANNOUNCE, ANNOUNCE) \
|
260
265
|
XX(37, SETUP, SETUP) \
|
@@ -268,6 +273,54 @@ typedef enum llhttp_method llhttp_method_t;
|
|
268
273
|
XX(45, FLUSH, FLUSH) \
|
269
274
|
|
270
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
|
+
|
271
324
|
|
272
325
|
#ifdef __cplusplus
|
273
326
|
} /* extern "C" */
|
@@ -297,6 +350,7 @@ struct llhttp_settings_s {
|
|
297
350
|
/* Possible return values 0, -1, `HPE_PAUSED` */
|
298
351
|
llhttp_cb on_message_begin;
|
299
352
|
|
353
|
+
/* Possible return values 0, -1, HPE_USER */
|
300
354
|
llhttp_data_cb on_url;
|
301
355
|
llhttp_data_cb on_status;
|
302
356
|
llhttp_data_cb on_header_field;
|
@@ -313,6 +367,7 @@ struct llhttp_settings_s {
|
|
313
367
|
*/
|
314
368
|
llhttp_cb on_headers_complete;
|
315
369
|
|
370
|
+
/* Possible return values 0, -1, HPE_USER */
|
316
371
|
llhttp_data_cb on_body;
|
317
372
|
|
318
373
|
/* Possible return values 0, -1, `HPE_PAUSED` */
|
@@ -325,6 +380,7 @@ struct llhttp_settings_s {
|
|
325
380
|
llhttp_cb on_chunk_header;
|
326
381
|
llhttp_cb on_chunk_complete;
|
327
382
|
|
383
|
+
/* Information-only callbacks, return value is ignored */
|
328
384
|
llhttp_cb on_url_complete;
|
329
385
|
llhttp_cb on_status_complete;
|
330
386
|
llhttp_cb on_header_field_complete;
|
data/lib/llhttp/parser.rb
CHANGED
@@ -117,12 +117,18 @@ module LLHttp
|
|
117
117
|
LLHttp.llhttp_should_keep_alive(@pointer) == 1
|
118
118
|
end
|
119
119
|
|
120
|
-
# [public]
|
120
|
+
# [public] Tells the parser we are finished.
|
121
121
|
#
|
122
122
|
def finish
|
123
123
|
LLHttp.llhttp_finish(@pointer)
|
124
124
|
end
|
125
125
|
|
126
|
+
# [public] Get ready to parse the next request/response.
|
127
|
+
#
|
128
|
+
def reset
|
129
|
+
LLHttp.llhttp_reset(@pointer)
|
130
|
+
end
|
131
|
+
|
126
132
|
CALLBACKS.each do |callback|
|
127
133
|
class_eval(
|
128
134
|
<<~RB, __FILE__, __LINE__ + 1
|
@@ -152,7 +158,7 @@ module LLHttp
|
|
152
158
|
end
|
153
159
|
|
154
160
|
def self.free(pointer)
|
155
|
-
proc { LLHttp.
|
161
|
+
proc { LLHttp.rb_llhttp_free(pointer) }
|
156
162
|
end
|
157
163
|
end
|
158
164
|
end
|
data/lib/llhttp/version.rb
CHANGED
data/lib/llhttp.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: llhttp-ffi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.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-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi-compiler
|
@@ -79,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '0'
|
81
81
|
requirements: []
|
82
|
-
rubygems_version: 3.2.
|
82
|
+
rubygems_version: 3.2.15
|
83
83
|
signing_key:
|
84
84
|
specification_version: 4
|
85
85
|
summary: Ruby FFI bindings for llhttp.
|