puma 7.1.0-java → 8.0.0-java

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +116 -0
  3. data/README.md +18 -11
  4. data/docs/5.0-Upgrade.md +98 -0
  5. data/docs/6.0-Upgrade.md +56 -0
  6. data/docs/7.0-Upgrade.md +52 -0
  7. data/docs/8.0-Upgrade.md +100 -0
  8. data/docs/deployment.md +58 -23
  9. data/docs/grpc.md +62 -0
  10. data/docs/images/favicon.svg +1 -0
  11. data/docs/images/running-puma.svg +1 -0
  12. data/docs/images/standard-logo.svg +1 -0
  13. data/docs/jungle/README.md +1 -1
  14. data/docs/kubernetes.md +3 -10
  15. data/docs/plugins.md +2 -2
  16. data/docs/signals.md +10 -10
  17. data/docs/stats.md +1 -1
  18. data/docs/systemd.md +3 -3
  19. data/ext/puma_http11/http11_parser.java.rl +51 -65
  20. data/ext/puma_http11/org/jruby/puma/EnvKey.java +241 -0
  21. data/ext/puma_http11/org/jruby/puma/Http11.java +168 -104
  22. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +71 -85
  23. data/ext/puma_http11/puma_http11.c +101 -109
  24. data/lib/puma/app/status.rb +10 -2
  25. data/lib/puma/cli.rb +1 -1
  26. data/lib/puma/client.rb +90 -66
  27. data/lib/puma/client_env.rb +171 -0
  28. data/lib/puma/cluster/worker.rb +10 -9
  29. data/lib/puma/cluster.rb +3 -4
  30. data/lib/puma/configuration.rb +85 -16
  31. data/lib/puma/const.rb +2 -2
  32. data/lib/puma/control_cli.rb +1 -1
  33. data/lib/puma/detect.rb +11 -0
  34. data/lib/puma/dsl.rb +90 -14
  35. data/lib/puma/launcher.rb +7 -7
  36. data/lib/puma/puma_http11.jar +0 -0
  37. data/lib/puma/reactor.rb +3 -12
  38. data/lib/puma/{request.rb → response.rb} +25 -194
  39. data/lib/puma/runner.rb +1 -1
  40. data/lib/puma/server.rb +72 -37
  41. data/lib/puma/server_plugin_control.rb +32 -0
  42. data/lib/puma/single.rb +2 -2
  43. data/lib/puma/thread_pool.rb +129 -23
  44. data/lib/rack/handler/puma.rb +1 -1
  45. data/tools/Dockerfile +13 -5
  46. metadata +17 -7
  47. data/ext/puma_http11/ext_help.h +0 -15
@@ -4,6 +4,7 @@ package org.jruby.puma;
4
4
 
5
5
  import org.jruby.Ruby;
6
6
  import org.jruby.RubyHash;
7
+ import org.jruby.RubyString;
7
8
  import org.jruby.util.ByteList;
8
9
 
9
10
  public class Http11Parser {
@@ -11,12 +12,12 @@ public class Http11Parser {
11
12
  /** Machine **/
12
13
 
13
14
 
14
- // line 58 "ext/puma_http11/http11_parser.java.rl"
15
+ // line 59 "ext/puma_http11/http11_parser.java.rl"
15
16
 
16
17
 
17
18
  /** Data **/
18
19
 
19
- // line 20 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
20
+ // line 21 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
20
21
  private static byte[] init__puma_parser_actions_0()
21
22
  {
22
23
  return new byte [] {
@@ -185,66 +186,51 @@ static final int puma_parser_first_final = 46;
185
186
  static final int puma_parser_error = 0;
186
187
 
187
188
 
188
- // line 62 "ext/puma_http11/http11_parser.java.rl"
189
+ // line 63 "ext/puma_http11/http11_parser.java.rl"
189
190
 
190
- public static interface ElementCB {
191
- public void call(Ruby runtime, RubyHash data, ByteList buffer, int at, int length);
192
- }
193
-
194
- public static interface FieldCB {
195
- public void call(Ruby runtime, RubyHash data, ByteList buffer, int field, int flen, int value, int vlen);
196
- }
197
-
198
- public static class HttpParser {
199
- int cs;
200
- int body_start;
201
- int content_len;
202
- int nread;
203
- int mark;
204
- int field_start;
205
- int field_len;
206
- int query_start;
191
+ int cs;
192
+ int body_start;
193
+ int nread;
194
+ int mark;
195
+ int field_start;
196
+ int field_len;
197
+ int query_start;
207
198
 
208
- RubyHash data;
209
- ByteList buffer;
199
+ RubyHash data;
200
+ byte[] buffer;
210
201
 
211
- public void init() {
212
- cs = 0;
202
+ public void init() {
213
203
 
214
-
215
- // line 216 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
204
+
205
+ // line 206 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
216
206
  {
217
207
  cs = puma_parser_start;
218
208
  }
219
209
 
220
- // line 88 "ext/puma_http11/http11_parser.java.rl"
210
+ // line 78 "ext/puma_http11/http11_parser.java.rl"
221
211
 
222
- body_start = 0;
223
- content_len = 0;
224
- mark = 0;
225
- nread = 0;
226
- field_len = 0;
227
- field_start = 0;
228
- }
212
+ body_start = 0;
213
+ mark = 0;
214
+ nread = 0;
215
+ field_len = 0;
216
+ field_start = 0;
229
217
  }
230
218
 
231
- public final HttpParser parser = new HttpParser();
232
-
233
219
  public int execute(Ruby runtime, Http11 http, ByteList buffer, int off) {
234
220
  int p, pe;
235
- int cs = parser.cs;
221
+ int cs = this.cs;
236
222
  int len = buffer.length();
223
+ int beg = buffer.begin();
224
+ RubyString[] envStrings = http.envStrings;
237
225
  assert off<=len : "offset past end of buffer";
238
226
 
239
- p = off;
240
- pe = len;
241
- // get a copy of the bytes, since it may not start at 0
242
- // FIXME: figure out how to just use the bytes in-place
243
- byte[] data = buffer.bytes();
244
- parser.buffer = buffer;
227
+ p = beg + off;
228
+ pe = beg + len;
229
+ byte[] data = buffer.unsafeBytes();
230
+ this.buffer = data;
245
231
 
246
232
 
247
- // line 248 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
233
+ // line 234 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
248
234
  {
249
235
  int _klen;
250
236
  int _trans = 0;
@@ -325,82 +311,82 @@ case 1:
325
311
  switch ( _puma_parser_actions[_acts++] )
326
312
  {
327
313
  case 0:
328
- // line 15 "ext/puma_http11/http11_parser.java.rl"
329
- {parser.mark = p; }
314
+ // line 16 "ext/puma_http11/http11_parser.java.rl"
315
+ {this.mark = p; }
330
316
  break;
331
317
  case 1:
332
- // line 17 "ext/puma_http11/http11_parser.java.rl"
333
- { parser.field_start = p; }
318
+ // line 18 "ext/puma_http11/http11_parser.java.rl"
319
+ { this.field_start = p; }
334
320
  break;
335
321
  case 2:
336
- // line 18 "ext/puma_http11/http11_parser.java.rl"
337
- { /* FIXME stub */ }
322
+ // line 19 "ext/puma_http11/http11_parser.java.rl"
323
+ { /* done lazily as needed */ }
338
324
  break;
339
325
  case 3:
340
- // line 19 "ext/puma_http11/http11_parser.java.rl"
326
+ // line 20 "ext/puma_http11/http11_parser.java.rl"
341
327
  {
342
- parser.field_len = p-parser.field_start;
328
+ this.field_len = p-this.field_start;
343
329
  }
344
330
  break;
345
331
  case 4:
346
- // line 23 "ext/puma_http11/http11_parser.java.rl"
347
- { parser.mark = p; }
332
+ // line 24 "ext/puma_http11/http11_parser.java.rl"
333
+ { this.mark = p; }
348
334
  break;
349
335
  case 5:
350
- // line 24 "ext/puma_http11/http11_parser.java.rl"
336
+ // line 25 "ext/puma_http11/http11_parser.java.rl"
351
337
  {
352
- Http11.http_field(runtime, parser.data, parser.buffer, parser.field_start, parser.field_len, parser.mark, p-parser.mark);
338
+ Http11.http_field(runtime, envStrings, this, p-this.mark);
353
339
  }
354
340
  break;
355
341
  case 6:
356
- // line 27 "ext/puma_http11/http11_parser.java.rl"
342
+ // line 28 "ext/puma_http11/http11_parser.java.rl"
357
343
  {
358
- Http11.request_method(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
344
+ Http11.request_method(runtime, envStrings, this, p-this.mark);
359
345
  }
360
346
  break;
361
347
  case 7:
362
- // line 30 "ext/puma_http11/http11_parser.java.rl"
348
+ // line 31 "ext/puma_http11/http11_parser.java.rl"
363
349
  {
364
- Http11.request_uri(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
350
+ Http11.request_uri(runtime, envStrings, this, p-this.mark);
365
351
  }
366
352
  break;
367
353
  case 8:
368
- // line 33 "ext/puma_http11/http11_parser.java.rl"
354
+ // line 34 "ext/puma_http11/http11_parser.java.rl"
369
355
  {
370
- Http11.fragment(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
356
+ Http11.fragment(runtime, envStrings, this, p-this.mark);
371
357
  }
372
358
  break;
373
359
  case 9:
374
- // line 37 "ext/puma_http11/http11_parser.java.rl"
375
- {parser.query_start = p; }
360
+ // line 38 "ext/puma_http11/http11_parser.java.rl"
361
+ {this.query_start = p; }
376
362
  break;
377
363
  case 10:
378
- // line 38 "ext/puma_http11/http11_parser.java.rl"
364
+ // line 39 "ext/puma_http11/http11_parser.java.rl"
379
365
  {
380
- Http11.query_string(runtime, parser.data, parser.buffer, parser.query_start, p-parser.query_start);
366
+ Http11.query_string(runtime, envStrings, this, p-this.query_start);
381
367
  }
382
368
  break;
383
369
  case 11:
384
- // line 42 "ext/puma_http11/http11_parser.java.rl"
370
+ // line 43 "ext/puma_http11/http11_parser.java.rl"
385
371
  {
386
- Http11.server_protocol(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
372
+ Http11.server_protocol(runtime, envStrings, this, p-this.mark);
387
373
  }
388
374
  break;
389
375
  case 12:
390
- // line 46 "ext/puma_http11/http11_parser.java.rl"
376
+ // line 47 "ext/puma_http11/http11_parser.java.rl"
391
377
  {
392
- Http11.request_path(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
378
+ Http11.request_path(runtime, envStrings, this, p-this.mark);
393
379
  }
394
380
  break;
395
381
  case 13:
396
- // line 50 "ext/puma_http11/http11_parser.java.rl"
382
+ // line 51 "ext/puma_http11/http11_parser.java.rl"
397
383
  {
398
- parser.body_start = p + 1;
399
- http.header_done(runtime, parser.data, parser.buffer, p + 1, pe - p - 1);
384
+ this.body_start = p + 1;
385
+ http.header_done(runtime, this, p + 1, pe - p - 1);
400
386
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
401
387
  }
402
388
  break;
403
- // line 404 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
389
+ // line 390 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
404
390
  }
405
391
  }
406
392
  }
@@ -420,19 +406,19 @@ case 5:
420
406
  break; }
421
407
  }
422
408
 
423
- // line 114 "ext/puma_http11/http11_parser.java.rl"
409
+ // line 100 "ext/puma_http11/http11_parser.java.rl"
424
410
 
425
- parser.cs = cs;
426
- parser.nread += (p - off);
411
+ this.cs = cs;
412
+ this.nread += (p - off);
427
413
 
428
414
  assert p <= pe : "buffer overflow after parsing execute";
429
- assert parser.nread <= len : "nread longer than length";
430
- assert parser.body_start <= len : "body starts after buffer end";
431
- assert parser.mark < len : "mark is after buffer end";
432
- assert parser.field_len <= len : "field has length longer than whole buffer";
433
- assert parser.field_start < len : "field starts after buffer end";
415
+ assert this.nread <= len : "nread longer than length";
416
+ assert this.body_start <= len : "body starts after buffer end";
417
+ assert this.mark < len : "mark is after buffer end";
418
+ assert this.field_len <= len : "field has length longer than whole buffer";
419
+ assert this.field_start < len : "field starts after buffer end";
434
420
 
435
- return parser.nread;
421
+ return this.nread;
436
422
  }
437
423
 
438
424
  public int finish() {
@@ -446,10 +432,10 @@ case 5:
446
432
  }
447
433
 
448
434
  public boolean has_error() {
449
- return parser.cs == puma_parser_error;
435
+ return this.cs == puma_parser_error;
450
436
  }
451
437
 
452
438
  public boolean is_finished() {
453
- return parser.cs == puma_parser_first_final;
439
+ return this.cs == puma_parser_first_final;
454
440
  }
455
441
  }
@@ -8,25 +8,12 @@
8
8
 
9
9
  #include "ruby.h"
10
10
  #include "ruby/encoding.h"
11
- #include "ext_help.h"
12
11
  #include <assert.h>
13
12
  #include <string.h>
14
13
  #include <ctype.h>
15
14
  #include "http11_parser.h"
16
15
 
17
- #ifndef MANAGED_STRINGS
18
-
19
- #ifndef RSTRING_PTR
20
- #define RSTRING_PTR(s) (RSTRING(s)->ptr)
21
- #endif
22
- #ifndef RSTRING_LEN
23
- #define RSTRING_LEN(s) (RSTRING(s)->len)
24
- #endif
25
-
26
- #define rb_extract_chars(e, sz) (*sz = RSTRING_LEN(e), RSTRING_PTR(e))
27
- #define rb_free_chars(e) /* nothing */
28
-
29
- #endif
16
+ #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
30
17
 
31
18
  static VALUE eHttpParserError;
32
19
 
@@ -51,8 +38,8 @@ static VALUE global_request_path;
51
38
  /** Defines global strings in the init method. */
52
39
  static inline void DEF_GLOBAL(VALUE *var, const char *cstr)
53
40
  {
54
- rb_global_variable(var);
55
- *var = rb_enc_interned_str_cstr(cstr, rb_utf8_encoding());
41
+ rb_global_variable(var);
42
+ *var = rb_enc_interned_str_cstr(cstr, rb_utf8_encoding());
56
43
  }
57
44
 
58
45
  /* Defines the maximum allowed lengths for various input elements.*/
@@ -77,10 +64,10 @@ DEF_MAX_LENGTH(QUERY_STRING, PUMA_QUERY_STRING_MAX_LENGTH);
77
64
  DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32)));
78
65
 
79
66
  struct common_field {
80
- const size_t len;
81
- const char *name;
67
+ const size_t len;
68
+ const char *name;
82
69
  int raw;
83
- VALUE value;
70
+ VALUE value;
84
71
  };
85
72
 
86
73
  /*
@@ -91,42 +78,42 @@ struct common_field {
91
78
  static struct common_field common_http_fields[] = {
92
79
  # define f(N) { (sizeof(N) - 1), N, 0, Qnil }
93
80
  # define fr(N) { (sizeof(N) - 1), N, 1, Qnil }
94
- f("ACCEPT"),
95
- f("ACCEPT_CHARSET"),
96
- f("ACCEPT_ENCODING"),
97
- f("ACCEPT_LANGUAGE"),
98
- f("ALLOW"),
99
- f("AUTHORIZATION"),
100
- f("CACHE_CONTROL"),
101
- f("CONNECTION"),
102
- f("CONTENT_ENCODING"),
103
- fr("CONTENT_LENGTH"),
104
- fr("CONTENT_TYPE"),
105
- f("COOKIE"),
106
- f("DATE"),
107
- f("EXPECT"),
108
- f("FROM"),
109
- f("HOST"),
110
- f("IF_MATCH"),
111
- f("IF_MODIFIED_SINCE"),
112
- f("IF_NONE_MATCH"),
113
- f("IF_RANGE"),
114
- f("IF_UNMODIFIED_SINCE"),
115
- f("KEEP_ALIVE"), /* Firefox sends this */
116
- f("MAX_FORWARDS"),
117
- f("PRAGMA"),
118
- f("PROXY_AUTHORIZATION"),
119
- f("RANGE"),
120
- f("REFERER"),
121
- f("TE"),
122
- f("TRAILER"),
123
- f("TRANSFER_ENCODING"),
124
- f("UPGRADE"),
125
- f("USER_AGENT"),
126
- f("VIA"),
127
- f("X_FORWARDED_FOR"), /* common for proxies */
128
- f("X_REAL_IP"), /* common for proxies */
129
- f("WARNING")
81
+ f("ACCEPT"),
82
+ f("ACCEPT_CHARSET"),
83
+ f("ACCEPT_ENCODING"),
84
+ f("ACCEPT_LANGUAGE"),
85
+ f("ALLOW"),
86
+ f("AUTHORIZATION"),
87
+ f("CACHE_CONTROL"),
88
+ f("CONNECTION"),
89
+ f("CONTENT_ENCODING"),
90
+ fr("CONTENT_LENGTH"),
91
+ fr("CONTENT_TYPE"),
92
+ f("COOKIE"),
93
+ f("DATE"),
94
+ f("EXPECT"),
95
+ f("FROM"),
96
+ f("HOST"),
97
+ f("IF_MATCH"),
98
+ f("IF_MODIFIED_SINCE"),
99
+ f("IF_NONE_MATCH"),
100
+ f("IF_RANGE"),
101
+ f("IF_UNMODIFIED_SINCE"),
102
+ f("KEEP_ALIVE"), /* Firefox sends this */
103
+ f("MAX_FORWARDS"),
104
+ f("PRAGMA"),
105
+ f("PROXY_AUTHORIZATION"),
106
+ f("RANGE"),
107
+ f("REFERER"),
108
+ f("TE"),
109
+ f("TRAILER"),
110
+ f("TRANSFER_ENCODING"),
111
+ f("UPGRADE"),
112
+ f("USER_AGENT"),
113
+ f("VIA"),
114
+ f("X_FORWARDED_FOR"), /* common for proxies */
115
+ f("X_REAL_IP"), /* common for proxies */
116
+ f("WARNING")
130
117
  # undef f
131
118
  };
132
119
 
@@ -140,10 +127,10 @@ static void init_common_fields(void)
140
127
  for(i = 0; i < ARRAY_SIZE(common_http_fields); cf++, i++) {
141
128
  rb_global_variable(&cf->value);
142
129
  if(cf->raw) {
143
- cf->value = rb_str_new(cf->name, cf->len);
130
+ cf->value = rb_enc_interned_str(cf->name, cf->len, rb_utf8_encoding());
144
131
  } else {
145
132
  memcpy(tmp + HTTP_PREFIX_LEN, cf->name, cf->len + 1);
146
- cf->value = rb_str_new(tmp, HTTP_PREFIX_LEN + cf->len);
133
+ cf->value = rb_enc_interned_str(tmp, HTTP_PREFIX_LEN + cf->len, rb_utf8_encoding());
147
134
  }
148
135
  }
149
136
  }
@@ -163,7 +150,7 @@ static int is_ows(const char c) {
163
150
  return c == ' ' || c == '\t';
164
151
  }
165
152
 
166
- void http_field(puma_parser* hp, const char *field, size_t flen,
153
+ static void http_field(puma_parser* hp, const char *field, size_t flen,
167
154
  const char *value, size_t vlen)
168
155
  {
169
156
  VALUE f = Qnil;
@@ -186,7 +173,7 @@ void http_field(puma_parser* hp, const char *field, size_t flen,
186
173
  memcpy(hp->buf, HTTP_PREFIX, HTTP_PREFIX_LEN);
187
174
  memcpy(hp->buf + HTTP_PREFIX_LEN, field, flen);
188
175
 
189
- f = rb_str_new(hp->buf, new_size);
176
+ f = rb_enc_interned_str(hp->buf, new_size, rb_utf8_encoding());
190
177
  }
191
178
 
192
179
  while (vlen > 0 && is_ows(value[vlen - 1])) vlen--;
@@ -208,7 +195,7 @@ void http_field(puma_parser* hp, const char *field, size_t flen,
208
195
  }
209
196
  }
210
197
 
211
- void request_method(puma_parser* hp, const char *at, size_t length)
198
+ static void request_method(puma_parser* hp, const char *at, size_t length)
212
199
  {
213
200
  VALUE val = Qnil;
214
201
 
@@ -216,7 +203,7 @@ void request_method(puma_parser* hp, const char *at, size_t length)
216
203
  rb_hash_aset(hp->request, global_request_method, val);
217
204
  }
218
205
 
219
- void request_uri(puma_parser* hp, const char *at, size_t length)
206
+ static void request_uri(puma_parser* hp, const char *at, size_t length)
220
207
  {
221
208
  VALUE val = Qnil;
222
209
 
@@ -226,7 +213,7 @@ void request_uri(puma_parser* hp, const char *at, size_t length)
226
213
  rb_hash_aset(hp->request, global_request_uri, val);
227
214
  }
228
215
 
229
- void fragment(puma_parser* hp, const char *at, size_t length)
216
+ static void fragment(puma_parser* hp, const char *at, size_t length)
230
217
  {
231
218
  VALUE val = Qnil;
232
219
 
@@ -236,7 +223,7 @@ void fragment(puma_parser* hp, const char *at, size_t length)
236
223
  rb_hash_aset(hp->request, global_fragment, val);
237
224
  }
238
225
 
239
- void request_path(puma_parser* hp, const char *at, size_t length)
226
+ static void request_path(puma_parser* hp, const char *at, size_t length)
240
227
  {
241
228
  VALUE val = Qnil;
242
229
 
@@ -246,7 +233,7 @@ void request_path(puma_parser* hp, const char *at, size_t length)
246
233
  rb_hash_aset(hp->request, global_request_path, val);
247
234
  }
248
235
 
249
- void query_string(puma_parser* hp, const char *at, size_t length)
236
+ static void query_string(puma_parser* hp, const char *at, size_t length)
250
237
  {
251
238
  VALUE val = Qnil;
252
239
 
@@ -256,7 +243,7 @@ void query_string(puma_parser* hp, const char *at, size_t length)
256
243
  rb_hash_aset(hp->request, global_query_string, val);
257
244
  }
258
245
 
259
- void server_protocol(puma_parser* hp, const char *at, size_t length)
246
+ static void server_protocol(puma_parser* hp, const char *at, size_t length)
260
247
  {
261
248
  VALUE val = rb_str_new(at, length);
262
249
  rb_hash_aset(hp->request, global_server_protocol, val);
@@ -265,36 +252,42 @@ void server_protocol(puma_parser* hp, const char *at, size_t length)
265
252
  /** Finalizes the request header to have a bunch of stuff that's
266
253
  needed. */
267
254
 
268
- void header_done(puma_parser* hp, const char *at, size_t length)
255
+ static void header_done(puma_parser* hp, const char *at, size_t length)
269
256
  {
270
257
  hp->body = rb_str_new(at, length);
271
258
  }
272
259
 
273
260
 
274
- void HttpParser_free(void *data) {
275
- TRACE();
261
+ static void HttpParser_mark(void *ptr) {
262
+ puma_parser *hp = ptr;
263
+ rb_gc_mark_movable(hp->request);
264
+ rb_gc_mark_movable(hp->body);
265
+ }
276
266
 
277
- if(data) {
278
- xfree(data);
279
- }
267
+ static size_t HttpParser_size(const void *ptr) {
268
+ return sizeof(puma_parser);
280
269
  }
281
270
 
282
- void HttpParser_mark(void *ptr) {
271
+ static void HttpParser_compact(void *ptr) {
283
272
  puma_parser *hp = ptr;
284
- if(hp->request) rb_gc_mark(hp->request);
285
- if(hp->body) rb_gc_mark(hp->body);
273
+ hp->request = rb_gc_location(hp->request);
274
+ hp->body = rb_gc_location(hp->body);
286
275
  }
287
276
 
288
- const rb_data_type_t HttpParser_data_type = {
289
- "HttpParser",
290
- { HttpParser_mark, HttpParser_free, 0 },
291
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
277
+ static const rb_data_type_t HttpParser_data_type = {
278
+ .wrap_struct_name = "Puma::HttpParser",
279
+ .function = {
280
+ .dmark = HttpParser_mark,
281
+ .dfree = RUBY_TYPED_DEFAULT_FREE,
282
+ .dsize = HttpParser_size,
283
+ .dcompact = HttpParser_compact,
284
+ },
285
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
292
286
  };
293
287
 
294
- VALUE HttpParser_alloc(VALUE klass)
288
+ static VALUE HttpParser_alloc(VALUE klass)
295
289
  {
296
290
  puma_parser *hp = ALLOC_N(puma_parser, 1);
297
- TRACE();
298
291
  hp->http_field = http_field;
299
292
  hp->request_method = request_method;
300
293
  hp->request_uri = request_uri;
@@ -310,16 +303,25 @@ VALUE HttpParser_alloc(VALUE klass)
310
303
  return TypedData_Wrap_Struct(klass, &HttpParser_data_type, hp);
311
304
  }
312
305
 
306
+ static inline puma_parser *HttpParser_unwrap(VALUE self)
307
+ {
308
+ puma_parser *http;
309
+ TypedData_Get_Struct(self, puma_parser, &HttpParser_data_type, http);
310
+ if (http == NULL) {
311
+ rb_raise(rb_eArgError, "%s", "NULL http_parser found");
312
+ }
313
+ return http;
314
+ }
315
+
313
316
  /**
314
317
  * call-seq:
315
318
  * parser.new -> parser
316
319
  *
317
320
  * Creates a new parser.
318
321
  */
319
- VALUE HttpParser_init(VALUE self)
322
+ static VALUE HttpParser_init(VALUE self)
320
323
  {
321
- puma_parser *http = NULL;
322
- DATA_GET(self, puma_parser, &HttpParser_data_type, http);
324
+ puma_parser *http = HttpParser_unwrap(self);
323
325
  puma_parser_init(http);
324
326
 
325
327
  return self;
@@ -333,10 +335,9 @@ VALUE HttpParser_init(VALUE self)
333
335
  * Resets the parser to it's initial state so that you can reuse it
334
336
  * rather than making new ones.
335
337
  */
336
- VALUE HttpParser_reset(VALUE self)
338
+ static VALUE HttpParser_reset(VALUE self)
337
339
  {
338
- puma_parser *http = NULL;
339
- DATA_GET(self, puma_parser, &HttpParser_data_type, http);
340
+ puma_parser *http = HttpParser_unwrap(self);
340
341
  puma_parser_init(http);
341
342
 
342
343
  return Qnil;
@@ -350,10 +351,9 @@ VALUE HttpParser_reset(VALUE self)
350
351
  * Finishes a parser early which could put in a "good" or bad state.
351
352
  * You should call reset after finish it or bad things will happen.
352
353
  */
353
- VALUE HttpParser_finish(VALUE self)
354
+ static VALUE HttpParser_finish(VALUE self)
354
355
  {
355
- puma_parser *http = NULL;
356
- DATA_GET(self, puma_parser, &HttpParser_data_type, http);
356
+ puma_parser *http = HttpParser_unwrap(self);
357
357
  puma_parser_finish(http);
358
358
 
359
359
  return puma_parser_is_finished(http) ? Qtrue : Qfalse;
@@ -377,26 +377,22 @@ VALUE HttpParser_finish(VALUE self)
377
377
  * the parsing from that position. It needs all of the original data as well
378
378
  * so you have to append to the data buffer as you read.
379
379
  */
380
- VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
380
+ static VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
381
381
  {
382
- puma_parser *http = NULL;
382
+ puma_parser *http = HttpParser_unwrap(self);
383
383
  int from = 0;
384
384
  char *dptr = NULL;
385
385
  long dlen = 0;
386
386
 
387
- DATA_GET(self, puma_parser, &HttpParser_data_type, http);
388
-
389
387
  from = FIX2INT(start);
390
- dptr = rb_extract_chars(data, &dlen);
388
+ RSTRING_GETMEM(data, dptr, dlen);
391
389
 
392
390
  if(from >= dlen) {
393
- rb_free_chars(dptr);
394
391
  rb_raise(eHttpParserError, "%s", "Requested start is after data buffer end.");
395
392
  } else {
396
393
  http->request = req_hash;
397
394
  puma_parser_execute(http, dptr, dlen, from);
398
395
 
399
- rb_free_chars(dptr);
400
396
  VALIDATE_MAX_LENGTH(puma_parser_nread(http), HEADER);
401
397
 
402
398
  if(puma_parser_has_error(http)) {
@@ -415,10 +411,9 @@ VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
415
411
  *
416
412
  * Tells you whether the parser is in an error state.
417
413
  */
418
- VALUE HttpParser_has_error(VALUE self)
414
+ static VALUE HttpParser_has_error(VALUE self)
419
415
  {
420
- puma_parser *http = NULL;
421
- DATA_GET(self, puma_parser, &HttpParser_data_type, http);
416
+ puma_parser *http = HttpParser_unwrap(self);
422
417
 
423
418
  return puma_parser_has_error(http) ? Qtrue : Qfalse;
424
419
  }
@@ -430,10 +425,9 @@ VALUE HttpParser_has_error(VALUE self)
430
425
  *
431
426
  * Tells you whether the parser is finished or not and in a good state.
432
427
  */
433
- VALUE HttpParser_is_finished(VALUE self)
428
+ static VALUE HttpParser_is_finished(VALUE self)
434
429
  {
435
- puma_parser *http = NULL;
436
- DATA_GET(self, puma_parser, &HttpParser_data_type, http);
430
+ puma_parser *http = HttpParser_unwrap(self);
437
431
 
438
432
  return puma_parser_is_finished(http) ? Qtrue : Qfalse;
439
433
  }
@@ -446,10 +440,9 @@ VALUE HttpParser_is_finished(VALUE self)
446
440
  * Returns the amount of data processed so far during this processing cycle. It is
447
441
  * set to 0 on initialize or reset calls and is incremented each time execute is called.
448
442
  */
449
- VALUE HttpParser_nread(VALUE self)
443
+ static VALUE HttpParser_nread(VALUE self)
450
444
  {
451
- puma_parser *http = NULL;
452
- DATA_GET(self, puma_parser, &HttpParser_data_type, http);
445
+ puma_parser *http = HttpParser_unwrap(self);
453
446
 
454
447
  return INT2FIX(http->nread);
455
448
  }
@@ -460,9 +453,8 @@ VALUE HttpParser_nread(VALUE self)
460
453
  *
461
454
  * If the request included a body, returns it.
462
455
  */
463
- VALUE HttpParser_body(VALUE self) {
464
- puma_parser *http = NULL;
465
- DATA_GET(self, puma_parser, &HttpParser_data_type, http);
456
+ static VALUE HttpParser_body(VALUE self) {
457
+ puma_parser *http = HttpParser_unwrap(self);
466
458
 
467
459
  return http->body;
468
460
  }
@@ -471,7 +463,7 @@ VALUE HttpParser_body(VALUE self) {
471
463
  void Init_mini_ssl(VALUE mod);
472
464
  #endif
473
465
 
474
- void Init_puma_http11(void)
466
+ RUBY_FUNC_EXPORTED void Init_puma_http11(void)
475
467
  {
476
468
  #ifdef HAVE_RB_EXT_RACTOR_SAFE
477
469
  rb_ext_ractor_safe(true);