puma 4.3.12 → 5.6.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +1526 -524
  3. data/LICENSE +23 -20
  4. data/README.md +120 -36
  5. data/bin/puma-wild +3 -9
  6. data/docs/architecture.md +63 -26
  7. data/docs/compile_options.md +21 -0
  8. data/docs/deployment.md +60 -69
  9. data/docs/fork_worker.md +33 -0
  10. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  11. data/docs/images/puma-connection-flow.png +0 -0
  12. data/docs/images/puma-general-arch.png +0 -0
  13. data/docs/jungle/README.md +9 -0
  14. data/{tools → docs}/jungle/rc.d/README.md +1 -1
  15. data/{tools → docs}/jungle/rc.d/puma +2 -2
  16. data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
  17. data/docs/kubernetes.md +66 -0
  18. data/docs/nginx.md +1 -1
  19. data/docs/plugins.md +15 -15
  20. data/docs/rails_dev_mode.md +28 -0
  21. data/docs/restart.md +46 -23
  22. data/docs/signals.md +13 -11
  23. data/docs/stats.md +142 -0
  24. data/docs/systemd.md +85 -128
  25. data/ext/puma_http11/PumaHttp11Service.java +2 -4
  26. data/ext/puma_http11/ext_help.h +1 -1
  27. data/ext/puma_http11/extconf.rb +44 -10
  28. data/ext/puma_http11/http11_parser.c +45 -47
  29. data/ext/puma_http11/http11_parser.h +1 -1
  30. data/ext/puma_http11/http11_parser.java.rl +1 -1
  31. data/ext/puma_http11/http11_parser.rl +1 -1
  32. data/ext/puma_http11/http11_parser_common.rl +0 -0
  33. data/ext/puma_http11/mini_ssl.c +225 -89
  34. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  35. data/ext/puma_http11/org/jruby/puma/Http11.java +5 -3
  36. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +3 -5
  37. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +109 -67
  38. data/ext/puma_http11/puma_http11.c +32 -51
  39. data/lib/puma/app/status.rb +50 -36
  40. data/lib/puma/binder.rb +225 -106
  41. data/lib/puma/cli.rb +24 -18
  42. data/lib/puma/client.rb +146 -84
  43. data/lib/puma/cluster/worker.rb +173 -0
  44. data/lib/puma/cluster/worker_handle.rb +94 -0
  45. data/lib/puma/cluster.rb +212 -220
  46. data/lib/puma/commonlogger.rb +2 -2
  47. data/lib/puma/configuration.rb +58 -49
  48. data/lib/puma/const.rb +22 -7
  49. data/lib/puma/control_cli.rb +99 -76
  50. data/lib/puma/detect.rb +29 -2
  51. data/lib/puma/dsl.rb +368 -96
  52. data/lib/puma/error_logger.rb +104 -0
  53. data/lib/puma/events.rb +55 -34
  54. data/lib/puma/io_buffer.rb +9 -2
  55. data/lib/puma/jruby_restart.rb +0 -58
  56. data/lib/puma/json_serialization.rb +96 -0
  57. data/lib/puma/launcher.rb +128 -46
  58. data/lib/puma/minissl/context_builder.rb +14 -9
  59. data/lib/puma/minissl.rb +137 -50
  60. data/lib/puma/null_io.rb +18 -1
  61. data/lib/puma/plugin/tmp_restart.rb +0 -0
  62. data/lib/puma/plugin.rb +3 -12
  63. data/lib/puma/queue_close.rb +26 -0
  64. data/lib/puma/rack/builder.rb +1 -5
  65. data/lib/puma/rack/urlmap.rb +0 -0
  66. data/lib/puma/rack_default.rb +0 -0
  67. data/lib/puma/reactor.rb +85 -369
  68. data/lib/puma/request.rb +489 -0
  69. data/lib/puma/runner.rb +46 -61
  70. data/lib/puma/server.rb +292 -763
  71. data/lib/puma/single.rb +9 -65
  72. data/lib/puma/state_file.rb +48 -8
  73. data/lib/puma/systemd.rb +46 -0
  74. data/lib/puma/thread_pool.rb +125 -57
  75. data/lib/puma/util.rb +32 -4
  76. data/lib/puma.rb +48 -0
  77. data/lib/rack/handler/puma.rb +2 -3
  78. data/lib/rack/version_restriction.rb +15 -0
  79. data/tools/{docker/Dockerfile → Dockerfile} +1 -1
  80. data/tools/trickletest.rb +0 -0
  81. metadata +29 -24
  82. data/docs/tcp_mode.md +0 -96
  83. data/ext/puma_http11/io_buffer.c +0 -155
  84. data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -72
  85. data/lib/puma/accept_nonblock.rb +0 -29
  86. data/lib/puma/tcp_logger.rb +0 -41
  87. data/tools/jungle/README.md +0 -19
  88. data/tools/jungle/init.d/README.md +0 -61
  89. data/tools/jungle/init.d/puma +0 -421
  90. data/tools/jungle/init.d/run-puma +0 -18
  91. data/tools/jungle/upstart/README.md +0 -61
  92. data/tools/jungle/upstart/puma-manager.conf +0 -31
  93. data/tools/jungle/upstart/puma.conf +0 -69
@@ -2,12 +2,7 @@
2
2
 
3
3
  #include <ruby.h>
4
4
  #include <ruby/version.h>
5
-
6
- #if RUBY_API_VERSION_MAJOR == 1
7
- #include <rubyio.h>
8
- #else
9
5
  #include <ruby/io.h>
10
- #endif
11
6
 
12
7
  #ifdef HAVE_OPENSSL_BIO_H
13
8
 
@@ -33,7 +28,16 @@ typedef struct {
33
28
  int bytes;
34
29
  } ms_cert_buf;
35
30
 
36
- void engine_free(ms_conn* conn) {
31
+ VALUE eError;
32
+
33
+ NORETURN(void raise_file_error(const char* caller, const char *filename));
34
+
35
+ void raise_file_error(const char* caller, const char *filename) {
36
+ rb_raise(eError, "%s: error in file '%s': %s", caller, filename, ERR_error_string(ERR_get_error(), NULL));
37
+ }
38
+
39
+ void engine_free(void *ptr) {
40
+ ms_conn *conn = ptr;
37
41
  ms_cert_buf* cert_buf = (ms_cert_buf*)SSL_get_app_data(conn->ssl);
38
42
  if(cert_buf) {
39
43
  OPENSSL_free(cert_buf->buf);
@@ -45,23 +49,13 @@ void engine_free(ms_conn* conn) {
45
49
  free(conn);
46
50
  }
47
51
 
48
- ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
49
- ms_conn* conn;
50
-
51
- *obj = Data_Make_Struct(klass, ms_conn, 0, engine_free, conn);
52
-
53
- conn->read = BIO_new(BIO_s_mem());
54
- BIO_set_nbio(conn->read, 1);
55
-
56
- conn->write = BIO_new(BIO_s_mem());
57
- BIO_set_nbio(conn->write, 1);
58
-
59
- conn->ssl = 0;
60
- conn->ctx = 0;
61
-
62
- return conn;
63
- }
52
+ const rb_data_type_t engine_data_type = {
53
+ "MiniSSL/ENGINE",
54
+ { 0, engine_free, 0 },
55
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
56
+ };
64
57
 
58
+ #ifndef HAVE_SSL_CTX_SET_DH_AUTO
65
59
  DH *get_dh2048(void) {
66
60
  /* `openssl dhparam -C 2048`
67
61
  * -----BEGIN DH PARAMETERS-----
@@ -104,13 +98,13 @@ DH *get_dh2048(void) {
104
98
  static unsigned char dh2048_g[] = { 0x02 };
105
99
 
106
100
  DH *dh;
107
- #if !(OPENSSL_VERSION_NUMBER < 0x10100005L || defined(LIBRESSL_VERSION_NUMBER))
101
+ #if !(OPENSSL_VERSION_NUMBER < 0x10100005L)
108
102
  BIGNUM *p, *g;
109
103
  #endif
110
104
 
111
105
  dh = DH_new();
112
106
 
113
- #if OPENSSL_VERSION_NUMBER < 0x10100005L || defined(LIBRESSL_VERSION_NUMBER)
107
+ #if OPENSSL_VERSION_NUMBER < 0x10100005L
114
108
  dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
115
109
  dh->g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
116
110
 
@@ -132,6 +126,38 @@ DH *get_dh2048(void) {
132
126
 
133
127
  return dh;
134
128
  }
129
+ #endif
130
+
131
+ static void
132
+ sslctx_free(void *ptr) {
133
+ SSL_CTX *ctx = ptr;
134
+ SSL_CTX_free(ctx);
135
+ }
136
+
137
+ static const rb_data_type_t sslctx_type = {
138
+ "MiniSSL/SSLContext",
139
+ {
140
+ 0, sslctx_free,
141
+ },
142
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
143
+ };
144
+
145
+ ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
146
+ ms_conn* conn;
147
+
148
+ *obj = TypedData_Make_Struct(klass, ms_conn, &engine_data_type, conn);
149
+
150
+ conn->read = BIO_new(BIO_s_mem());
151
+ BIO_set_nbio(conn->read, 1);
152
+
153
+ conn->write = BIO_new(BIO_s_mem());
154
+ BIO_set_nbio(conn->write, 1);
155
+
156
+ conn->ssl = 0;
157
+ conn->ctx = 0;
158
+
159
+ return conn;
160
+ }
135
161
 
136
162
  static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
137
163
  X509* err_cert;
@@ -159,52 +185,118 @@ static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
159
185
  return preverify_ok;
160
186
  }
161
187
 
162
- VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
163
- VALUE obj, session_id_bytes;
188
+ static VALUE
189
+ sslctx_alloc(VALUE klass) {
190
+ SSL_CTX *ctx;
191
+ long mode = 0 |
192
+ SSL_MODE_ENABLE_PARTIAL_WRITE |
193
+ SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
194
+ SSL_MODE_RELEASE_BUFFERS;
195
+
196
+ #ifdef HAVE_TLS_SERVER_METHOD
197
+ ctx = SSL_CTX_new(TLS_method());
198
+ // printf("\nctx using TLS_method security_level %d\n", SSL_CTX_get_security_level(ctx));
199
+ #else
200
+ ctx = SSL_CTX_new(SSLv23_method());
201
+ #endif
202
+ if (!ctx) {
203
+ rb_raise(eError, "SSL_CTX_new");
204
+ }
205
+ SSL_CTX_set_mode(ctx, mode);
206
+
207
+ return TypedData_Wrap_Struct(klass, &sslctx_type, ctx);
208
+ }
209
+
210
+ VALUE
211
+ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
164
212
  SSL_CTX* ctx;
165
- SSL* ssl;
166
- int min, ssl_options;
167
213
 
168
- ms_conn* conn = engine_alloc(self, &obj);
214
+ #ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
215
+ int min;
216
+ #endif
217
+ int ssl_options;
218
+ VALUE key, cert, ca, verify_mode, ssl_cipher_filter, no_tlsv1, no_tlsv1_1,
219
+ verification_flags, session_id_bytes, cert_pem, key_pem;
220
+ #ifndef HAVE_SSL_CTX_SET_DH_AUTO
221
+ DH *dh;
222
+ #endif
223
+ BIO *bio;
224
+ X509 *x509;
225
+ EVP_PKEY *pkey;
169
226
 
170
- ID sym_key = rb_intern("key");
171
- VALUE key = rb_funcall(mini_ssl_ctx, sym_key, 0);
227
+ #if OPENSSL_VERSION_NUMBER < 0x10002000L
228
+ EC_KEY *ecdh;
229
+ #endif
172
230
 
173
- StringValue(key);
231
+ TypedData_Get_Struct(self, SSL_CTX, &sslctx_type, ctx);
174
232
 
175
- ID sym_cert = rb_intern("cert");
176
- VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
233
+ key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
177
234
 
178
- StringValue(cert);
235
+ cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
179
236
 
180
- ID sym_ca = rb_intern("ca");
181
- VALUE ca = rb_funcall(mini_ssl_ctx, sym_ca, 0);
237
+ ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
182
238
 
183
- ID sym_verify_mode = rb_intern("verify_mode");
184
- VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
239
+ cert_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("cert_pem"), 0);
185
240
 
186
- ID sym_ssl_cipher_filter = rb_intern("ssl_cipher_filter");
187
- VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
241
+ key_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("key_pem"), 0);
188
242
 
189
- ID sym_no_tlsv1 = rb_intern("no_tlsv1");
190
- VALUE no_tlsv1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1, 0);
243
+ verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0);
191
244
 
192
- ID sym_no_tlsv1_1 = rb_intern("no_tlsv1_1");
193
- VALUE no_tlsv1_1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1_1, 0);
245
+ ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0);
194
246
 
195
- #ifdef HAVE_TLS_SERVER_METHOD
196
- ctx = SSL_CTX_new(TLS_server_method());
197
- #else
198
- ctx = SSL_CTX_new(SSLv23_server_method());
199
- #endif
200
- conn->ctx = ctx;
247
+ no_tlsv1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1"), 0);
201
248
 
202
- SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
203
- SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
249
+ no_tlsv1_1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1_1"), 0);
250
+
251
+ if (!NIL_P(cert)) {
252
+ StringValue(cert);
253
+
254
+ if (SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert)) != 1) {
255
+ raise_file_error("SSL_CTX_use_certificate_chain_file", RSTRING_PTR(cert));
256
+ }
257
+ }
258
+
259
+ if (!NIL_P(key)) {
260
+ StringValue(key);
261
+
262
+ if (SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM) != 1) {
263
+ raise_file_error("SSL_CTX_use_PrivateKey_file", RSTRING_PTR(key));
264
+ }
265
+ }
266
+
267
+ if (!NIL_P(cert_pem)) {
268
+ bio = BIO_new(BIO_s_mem());
269
+ BIO_puts(bio, RSTRING_PTR(cert_pem));
270
+ x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
271
+
272
+ if (SSL_CTX_use_certificate(ctx, x509) != 1) {
273
+ raise_file_error("SSL_CTX_use_certificate", RSTRING_PTR(cert_pem));
274
+ }
275
+ }
276
+
277
+ if (!NIL_P(key_pem)) {
278
+ bio = BIO_new(BIO_s_mem());
279
+ BIO_puts(bio, RSTRING_PTR(key_pem));
280
+ pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
281
+
282
+ if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) {
283
+ raise_file_error("SSL_CTX_use_PrivateKey", RSTRING_PTR(key_pem));
284
+ }
285
+ }
286
+
287
+ verification_flags = rb_funcall(mini_ssl_ctx, rb_intern_const("verification_flags"), 0);
288
+
289
+ if (!NIL_P(verification_flags)) {
290
+ X509_VERIFY_PARAM *param = SSL_CTX_get0_param(ctx);
291
+ X509_VERIFY_PARAM_set_flags(param, NUM2INT(verification_flags));
292
+ SSL_CTX_set1_param(ctx, param);
293
+ }
204
294
 
205
295
  if (!NIL_P(ca)) {
206
296
  StringValue(ca);
207
- SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL);
297
+ if (SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL) != 1) {
298
+ raise_file_error("SSL_CTX_load_verify_locations", RSTRING_PTR(ca));
299
+ }
208
300
  }
209
301
 
210
302
  ssl_options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION;
@@ -247,6 +339,24 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
247
339
  SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
248
340
  }
249
341
 
342
+ #if OPENSSL_VERSION_NUMBER < 0x10002000L
343
+ // Remove this case if OpenSSL 1.0.1 (now EOL) support is no
344
+ // longer needed.
345
+ ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
346
+ if (ecdh) {
347
+ SSL_CTX_set_tmp_ecdh(ctx, ecdh);
348
+ EC_KEY_free(ecdh);
349
+ }
350
+ #elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
351
+ SSL_CTX_set_ecdh_auto(ctx, 1);
352
+ #endif
353
+
354
+ if (NIL_P(verify_mode)) {
355
+ /* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */
356
+ } else {
357
+ SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
358
+ }
359
+
250
360
  // Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
251
361
  session_id_bytes = rb_funcall(
252
362
  #ifdef HAVE_RANDOM_BYTES
@@ -261,35 +371,34 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
261
371
  (unsigned char *) RSTRING_PTR(session_id_bytes),
262
372
  SSL_MAX_SSL_SESSION_ID_LENGTH);
263
373
 
264
- DH *dh = get_dh2048();
265
- SSL_CTX_set_tmp_dh(ctx, dh);
374
+ // printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx));
266
375
 
267
- #if OPENSSL_VERSION_NUMBER < 0x10002000L
268
- // Remove this case if OpenSSL 1.0.1 (now EOL) support is no
269
- // longer needed.
270
- EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
271
- if (ecdh) {
272
- SSL_CTX_set_tmp_ecdh(ctx, ecdh);
273
- EC_KEY_free(ecdh);
274
- }
275
- #elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
276
- // Prior to OpenSSL 1.1.0, servers must manually enable server-side ECDH
277
- // negotiation.
278
- SSL_CTX_set_ecdh_auto(ctx, 1);
376
+ #ifdef HAVE_SSL_CTX_SET_DH_AUTO
377
+ // https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_dh_auto.html
378
+ SSL_CTX_set_dh_auto(ctx, 1);
379
+ #else
380
+ dh = get_dh2048();
381
+ SSL_CTX_set_tmp_dh(ctx, dh);
279
382
  #endif
280
383
 
384
+ rb_obj_freeze(self);
385
+ return self;
386
+ }
387
+
388
+ VALUE engine_init_server(VALUE self, VALUE sslctx) {
389
+ ms_conn* conn;
390
+ VALUE obj;
391
+ SSL_CTX* ctx;
392
+ SSL* ssl;
393
+
394
+ conn = engine_alloc(self, &obj);
395
+
396
+ TypedData_Get_Struct(sslctx, SSL_CTX, &sslctx_type, ctx);
397
+
281
398
  ssl = SSL_new(ctx);
282
399
  conn->ssl = ssl;
283
400
  SSL_set_app_data(ssl, NULL);
284
-
285
- if (NIL_P(verify_mode)) {
286
- /* SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); */
287
- } else {
288
- SSL_set_verify(ssl, NUM2INT(verify_mode), engine_verify_callback);
289
- }
290
-
291
401
  SSL_set_bio(ssl, conn->read, conn->write);
292
-
293
402
  SSL_set_accept_state(ssl);
294
403
  return obj;
295
404
  }
@@ -316,7 +425,7 @@ VALUE engine_inject(VALUE self, VALUE str) {
316
425
  ms_conn* conn;
317
426
  long used;
318
427
 
319
- Data_Get_Struct(self, ms_conn, conn);
428
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
320
429
 
321
430
  StringValue(str);
322
431
 
@@ -329,13 +438,14 @@ VALUE engine_inject(VALUE self, VALUE str) {
329
438
  return INT2FIX(used);
330
439
  }
331
440
 
332
- static VALUE eError;
441
+ NORETURN(void raise_error(SSL* ssl, int result));
333
442
 
334
443
  void raise_error(SSL* ssl, int result) {
335
444
  char buf[512];
336
445
  char msg[512];
337
446
  const char* err_str;
338
447
  int err = errno;
448
+ int mask = 4095;
339
449
  int ssl_err = SSL_get_error(ssl, result);
340
450
  int verify_err = (int) SSL_get_verify_result(ssl);
341
451
 
@@ -352,8 +462,7 @@ void raise_error(SSL* ssl, int result) {
352
462
  } else {
353
463
  err = (int) ERR_get_error();
354
464
  ERR_error_string_n(err, buf, sizeof(buf));
355
- snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err);
356
-
465
+ snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err & mask);
357
466
  }
358
467
  } else {
359
468
  snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err);
@@ -368,7 +477,7 @@ VALUE engine_read(VALUE self) {
368
477
  char buf[512];
369
478
  int bytes, error;
370
479
 
371
- Data_Get_Struct(self, ms_conn, conn);
480
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
372
481
 
373
482
  ERR_clear_error();
374
483
 
@@ -395,7 +504,7 @@ VALUE engine_write(VALUE self, VALUE str) {
395
504
  ms_conn* conn;
396
505
  int bytes;
397
506
 
398
- Data_Get_Struct(self, ms_conn, conn);
507
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
399
508
 
400
509
  StringValue(str);
401
510
 
@@ -417,9 +526,11 @@ VALUE engine_extract(VALUE self) {
417
526
  ms_conn* conn;
418
527
  int bytes;
419
528
  size_t pending;
420
- char buf[512];
529
+ // https://www.openssl.org/docs/manmaster/man3/BIO_f_buffer.html
530
+ // crypto/bio/bf_buff.c DEFAULT_BUFFER_SIZE
531
+ char buf[4096];
421
532
 
422
- Data_Get_Struct(self, ms_conn, conn);
533
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
423
534
 
424
535
  pending = BIO_pending(conn->write);
425
536
  if(pending > 0) {
@@ -438,7 +549,7 @@ VALUE engine_shutdown(VALUE self) {
438
549
  ms_conn* conn;
439
550
  int ok;
440
551
 
441
- Data_Get_Struct(self, ms_conn, conn);
552
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
442
553
 
443
554
  ERR_clear_error();
444
555
 
@@ -453,7 +564,7 @@ VALUE engine_shutdown(VALUE self) {
453
564
  VALUE engine_init(VALUE self) {
454
565
  ms_conn* conn;
455
566
 
456
- Data_Get_Struct(self, ms_conn, conn);
567
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
457
568
 
458
569
  return SSL_in_init(conn->ssl) ? Qtrue : Qfalse;
459
570
  }
@@ -466,9 +577,13 @@ VALUE engine_peercert(VALUE self) {
466
577
  ms_cert_buf* cert_buf = NULL;
467
578
  VALUE rb_cert_buf;
468
579
 
469
- Data_Get_Struct(self, ms_conn, conn);
580
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
470
581
 
582
+ #ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
583
+ cert = SSL_get1_peer_certificate(conn->ssl);
584
+ #else
471
585
  cert = SSL_get_peer_certificate(conn->ssl);
586
+ #endif
472
587
  if(!cert) {
473
588
  /*
474
589
  * See if there was a failed certificate associated with this client.
@@ -497,12 +612,22 @@ VALUE engine_peercert(VALUE self) {
497
612
  return rb_cert_buf;
498
613
  }
499
614
 
615
+ /* @see Puma::MiniSSL::Socket#ssl_version_state
616
+ * @version 5.0.0
617
+ */
618
+ static VALUE
619
+ engine_ssl_vers_st(VALUE self) {
620
+ ms_conn* conn;
621
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
622
+ return rb_ary_new3(2, rb_str_new2(SSL_get_version(conn->ssl)), rb_str_new2(SSL_state_string(conn->ssl)));
623
+ }
624
+
500
625
  VALUE noop(VALUE self) {
501
626
  return Qnil;
502
627
  }
503
628
 
504
629
  void Init_mini_ssl(VALUE puma) {
505
- VALUE mod, eng;
630
+ VALUE mod, eng, sslctx;
506
631
 
507
632
  /* Fake operation for documentation (RDoc, YARD) */
508
633
  #if 0 == 1
@@ -515,7 +640,15 @@ void Init_mini_ssl(VALUE puma) {
515
640
  ERR_load_crypto_strings();
516
641
 
517
642
  mod = rb_define_module_under(puma, "MiniSSL");
643
+
518
644
  eng = rb_define_class_under(mod, "Engine", rb_cObject);
645
+ rb_undef_alloc_func(eng);
646
+
647
+ sslctx = rb_define_class_under(mod, "SSLContext", rb_cObject);
648
+ rb_define_alloc_func(sslctx, sslctx_alloc);
649
+ rb_define_method(sslctx, "initialize", sslctx_initialize, 1);
650
+ rb_undef_method(sslctx, "initialize_copy");
651
+
519
652
 
520
653
  // OpenSSL Build / Runtime/Load versions
521
654
 
@@ -568,13 +701,16 @@ void Init_mini_ssl(VALUE puma) {
568
701
  rb_define_method(eng, "init?", engine_init, 0);
569
702
 
570
703
  rb_define_method(eng, "peercert", engine_peercert, 0);
704
+
705
+ rb_define_method(eng, "ssl_vers_st", engine_ssl_vers_st, 0);
571
706
  }
572
707
 
573
708
  #else
574
709
 
710
+ NORETURN(VALUE raise_error(VALUE self));
711
+
575
712
  VALUE raise_error(VALUE self) {
576
713
  rb_raise(rb_eStandardError, "SSL not available in this build");
577
- return Qnil;
578
714
  }
579
715
 
580
716
  void Init_mini_ssl(VALUE puma) {
@@ -0,0 +1,15 @@
1
+ package puma;
2
+
3
+ import java.io.IOException;
4
+
5
+ import org.jruby.Ruby;
6
+ import org.jruby.runtime.load.BasicLibraryService;
7
+
8
+ import org.jruby.puma.Http11;
9
+
10
+ public class PumaHttp11Service implements BasicLibraryService {
11
+ public boolean basicLoad(final Ruby runtime) throws IOException {
12
+ Http11.createHttp11(runtime);
13
+ return true;
14
+ }
15
+ }
@@ -30,8 +30,8 @@ public class Http11 extends RubyObject {
30
30
  public final static String MAX_REQUEST_URI_LENGTH_ERR = "HTTP element REQUEST_URI is longer than the 12288 allowed length.";
31
31
  public final static int MAX_FRAGMENT_LENGTH = 1024;
32
32
  public final static String MAX_FRAGMENT_LENGTH_ERR = "HTTP element REQUEST_PATH is longer than the 1024 allowed length.";
33
- public final static int MAX_REQUEST_PATH_LENGTH = 2048;
34
- public final static String MAX_REQUEST_PATH_LENGTH_ERR = "HTTP element REQUEST_PATH is longer than the 2048 allowed length.";
33
+ public final static int MAX_REQUEST_PATH_LENGTH = 8192;
34
+ public final static String MAX_REQUEST_PATH_LENGTH_ERR = "HTTP element REQUEST_PATH is longer than the 8192 allowed length.";
35
35
  public final static int MAX_QUERY_STRING_LENGTH = 1024 * 10;
36
36
  public final static String MAX_QUERY_STRING_LENGTH_ERR = "HTTP element QUERY_STRING is longer than the 10240 allowed length.";
37
37
  public final static int MAX_HEADER_LENGTH = 1024 * (80 + 32);
@@ -99,6 +99,8 @@ public class Http11 extends RubyObject {
99
99
  int bite = b.get(i) & 0xFF;
100
100
  if(bite == '-') {
101
101
  b.set(i, (byte)'_');
102
+ } else if(bite == '_') {
103
+ b.set(i, (byte)',');
102
104
  } else {
103
105
  b.set(i, (byte)Character.toUpperCase(bite));
104
106
  }
@@ -197,7 +199,7 @@ public class Http11 extends RubyObject {
197
199
  validateMaxLength(runtime, parser.nread,MAX_HEADER_LENGTH, MAX_HEADER_LENGTH_ERR);
198
200
 
199
201
  if(hp.has_error()) {
200
- throw newHTTPParserError(runtime, "Invalid HTTP format, parsing fails.");
202
+ throw newHTTPParserError(runtime, "Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?");
201
203
  } else {
202
204
  return runtime.newFixnum(parser.nread);
203
205
  }
@@ -184,8 +184,6 @@ static final int puma_parser_start = 1;
184
184
  static final int puma_parser_first_final = 46;
185
185
  static final int puma_parser_error = 0;
186
186
 
187
- static final int puma_parser_en_main = 1;
188
-
189
187
 
190
188
  // line 62 "ext/puma_http11/http11_parser.java.rl"
191
189
 
@@ -214,7 +212,7 @@ static final int puma_parser_en_main = 1;
214
212
  cs = 0;
215
213
 
216
214
 
217
- // line 218 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
215
+ // line 216 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
218
216
  {
219
217
  cs = puma_parser_start;
220
218
  }
@@ -246,7 +244,7 @@ static final int puma_parser_en_main = 1;
246
244
  parser.buffer = buffer;
247
245
 
248
246
 
249
- // line 250 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
247
+ // line 248 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
250
248
  {
251
249
  int _klen;
252
250
  int _trans = 0;
@@ -402,7 +400,7 @@ case 1:
402
400
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
403
401
  }
404
402
  break;
405
- // line 406 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
403
+ // line 404 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
406
404
  }
407
405
  }
408
406
  }