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 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