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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aff4f93cb1f2c3152326007aee5f704ea9f2267ebf962c921122c4d319cc9e78
4
- data.tar.gz: f11ab274aee5d1fa12f476310aef67af73ac42ab34f52b1b438b5544bc7d47db
3
+ metadata.gz: 1e15a0ef9a22a029ad2b29b6a173fa5eb9bc7cee0a7ec819bf0cb9be068e106b
4
+ data.tar.gz: 50b10fdfeaa7a752f1ce50bcb3f4ebb4e7b0eea75af978acd2c5fa467eed345a
5
5
  SHA512:
6
- metadata.gz: 5d06b0efaf980e518477b6550e1a379a1655f052ff8d1c762c9e28493809d28f0adb98776043ab58ab5113e157c010b8f373100c6649b278ec3ecf10577ba65c
7
- data.tar.gz: 21f6d35b7c2491677b9887b2fa68d25b44c5d500b894b0e8da49228383863e41bc826c58243283277fe7945f9950cd8ad4de6e31a63f927e4e3d2e7ad63fb3bc
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
@@ -33,5 +33,5 @@ parser << "GET / HTTP/1.1\r\n\r\n"
33
33
 
34
34
  # Reset the parser for the next request:
35
35
  #
36
- parser.finish
36
+ parser.reset
37
37
  ```
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(__VA_ARGS__); \
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, parser);
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
- HTTP_METHOD_MAP(HTTP_METHOD_GEN)
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, s);
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
- CALLBACK_MAYBE(s, on_url, s, p, endp - p);
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, s);
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
- CALLBACK_MAYBE(s, on_status, s, p, endp - p);
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, s);
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
- CALLBACK_MAYBE(s, on_header_field, s, p, endp - p);
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, s);
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
- CALLBACK_MAYBE(s, on_header_value, s, p, endp - p);
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, s);
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, s);
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, s);
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
- CALLBACK_MAYBE(s, on_body, s, p, endp - p);
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, s);
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, s);
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 llhttp__internal__c_test_lenient_flags(
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 llhttp__internal__c_test_lenient_flags_1(
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
- size_t need;
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
- size_t need;
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 s_n_llhttp__internal__n_invoke_test_lenient_flags_1;
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 s_n_llhttp__internal__n_closed;
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
- s_n_llhttp__internal__n_invoke_test_lenient_flags: {
6125
- switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) {
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 s_n_llhttp__internal__n_invoke_test_lenient_flags;
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
- s_n_llhttp__internal__n_invoke_test_lenient_flags_1: {
6392
- switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) {
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 = 0x16;
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 llhttp__internal__c_test_lenient_flags(
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 llhttp__internal__c_update_finish_2(
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 llhttp__internal__c_test_lenient_flags_1(
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
- size_t need;
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
- size_t need;
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 s_n_llhttp__internal__n_invoke_update_finish_2;
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 s_n_llhttp__internal__n_invoke_test_lenient_flags_1;
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
- s_n_llhttp__internal__n_invoke_update_finish_1: {
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
- s_n_llhttp__internal__n_invoke_update_finish_2: {
13338
- switch (llhttp__internal__c_update_finish_2(state, p, endp)) {
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
- s_n_llhttp__internal__n_invoke_test_lenient_flags: {
13451
- switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) {
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 s_n_llhttp__internal__n_invoke_test_lenient_flags;
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
- s_n_llhttp__internal__n_invoke_test_lenient_flags_1: {
13700
- switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) {
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 = 0x16;
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 4
27
+ #define LLHTTP_VERSION_MAJOR 6
28
28
  #define LLHTTP_VERSION_MINOR 0
29
- #define LLHTTP_VERSION_PATCH 0
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
- HPE_USER = 23
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, USER, USER) \
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
- XX(34, PRI, PRI) \
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
@@ -10,34 +10,43 @@
10
10
 
11
11
  static VALUE mLLHttp, cParser, eError;
12
12
 
13
- static ID rb_llhttp_callback_on_message_begin;
14
- static ID rb_llhttp_callback_on_url;
15
- static ID rb_llhttp_callback_on_status;
16
- static ID rb_llhttp_callback_on_header_field;
17
- static ID rb_llhttp_callback_on_header_value;
18
- static ID rb_llhttp_callback_on_headers_complete;
19
- static ID rb_llhttp_callback_on_body;
20
- static ID rb_llhttp_callback_on_message_complete;
21
- static ID rb_llhttp_callback_on_chunk_header;
22
- static ID rb_llhttp_callback_on_chunk_complete;
23
- static ID rb_llhttp_callback_on_url_complete;
24
- static ID rb_llhttp_callback_on_status_complete;
25
- static ID rb_llhttp_callback_on_header_field_complete;
26
- static ID rb_llhttp_callback_on_header_value_complete;
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
- if (parser) {
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
- llhttp_settings_init(settings);
40
- llhttp_init(parser, HTTP_BOTH, settings);
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
- return NUM2INT(rb_llhttp_callback_call((VALUE)parser->data, rb_llhttp_callback_on_message_begin));
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
- return NUM2INT(rb_llhttp_callback_call((VALUE)parser->data, rb_llhttp_callback_on_headers_complete));
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
- return NUM2INT(rb_llhttp_callback_call((VALUE)parser->data, rb_llhttp_callback_on_message_complete));
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
- return NUM2INT(rb_llhttp_callback_call((VALUE)parser->data, rb_llhttp_callback_on_chunk_header));
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
- rb_llhttp_data_callback_call((VALUE)parser->data, rb_llhttp_callback_on_url, data, length);
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
- rb_llhttp_data_callback_call((VALUE)parser->data, rb_llhttp_callback_on_status, data, length);
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
- rb_llhttp_data_callback_call((VALUE)parser->data, rb_llhttp_callback_on_header_field, data, length);
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
- rb_llhttp_data_callback_call((VALUE)parser->data, rb_llhttp_callback_on_header_value, data, length);
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
- rb_llhttp_data_callback_call((VALUE)parser->data, rb_llhttp_callback_on_body, data, length);
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
- rb_llhttp_callback_call((VALUE)parser->data, rb_llhttp_callback_on_chunk_complete);
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
- rb_llhttp_callback_call((VALUE)parser->data, rb_llhttp_callback_on_url_complete);
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
- rb_llhttp_callback_call((VALUE)parser->data, rb_llhttp_callback_on_status_complete);
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
- rb_llhttp_callback_call((VALUE)parser->data, rb_llhttp_callback_on_header_field_complete);
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
- rb_llhttp_callback_call((VALUE)parser->data, rb_llhttp_callback_on_header_value_complete);
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 = parser->settings;
213
-
214
- VALUE delegate = rb_iv_get(self, "@delegate");
215
-
216
- rb_llhttp_callback_on_message_begin = rb_intern("internal_on_message_begin");
217
- rb_llhttp_callback_on_headers_complete = rb_intern("internal_on_headers_complete");
218
- rb_llhttp_callback_on_message_complete = rb_intern("internal_on_message_complete");
219
- rb_llhttp_callback_on_chunk_header = rb_intern("internal_on_chunk_header");
220
- rb_llhttp_callback_on_url = rb_intern("on_url");
221
- rb_llhttp_callback_on_status = rb_intern("on_status");
222
- rb_llhttp_callback_on_header_field = rb_intern("on_header_field");
223
- rb_llhttp_callback_on_header_value = rb_intern("on_header_value");
224
- rb_llhttp_callback_on_body = rb_intern("on_body");
225
- rb_llhttp_callback_on_chunk_complete = rb_intern("on_chunk_complete");
226
- rb_llhttp_callback_on_url_complete = rb_intern("on_url_complete");
227
- rb_llhttp_callback_on_status_complete = rb_intern("on_status_complete");
228
- rb_llhttp_callback_on_header_field_complete = rb_intern("on_header_field_complete");
229
- rb_llhttp_callback_on_header_value_complete = rb_intern("on_header_value_complete");
230
-
231
- if (rb_respond_to(delegate, rb_intern("on_message_begin"))) {
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, rb_llhttp_callback_on_url)) {
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, rb_llhttp_callback_on_status)) {
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, rb_llhttp_callback_on_header_field)) {
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, rb_llhttp_callback_on_header_value)) {
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, rb_llhttp_callback_on_body)) {
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, rb_llhttp_callback_on_chunk_complete)) {
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, rb_llhttp_callback_on_url_complete)) {
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, rb_llhttp_callback_on_status_complete)) {
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, rb_llhttp_callback_on_header_field_complete)) {
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, rb_llhttp_callback_on_header_value_complete)) {
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*)delegate;
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
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LLHttp
4
- VERSION = "0.1.0"
4
+ VERSION = "0.5.0"
5
5
 
6
6
  # [public] LLHttp's current version.
7
7
  #
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.1.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-03-04 00:00:00.000000000 Z
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.5.0
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.4
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
Binary file