puma 5.3.2 → 5.6.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +143 -8
- data/LICENSE +0 -0
- data/README.md +47 -6
- data/bin/puma-wild +0 -0
- data/docs/architecture.md +49 -16
- data/docs/compile_options.md +4 -2
- data/docs/deployment.md +53 -67
- data/docs/fork_worker.md +0 -0
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -0
- data/docs/jungle/README.md +0 -0
- data/docs/jungle/rc.d/README.md +0 -0
- data/docs/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +0 -0
- data/docs/nginx.md +0 -0
- data/docs/plugins.md +15 -15
- data/docs/rails_dev_mode.md +2 -3
- data/docs/restart.md +6 -6
- data/docs/signals.md +11 -10
- data/docs/stats.md +8 -8
- data/docs/systemd.md +64 -67
- data/ext/puma_http11/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/ext_help.h +0 -0
- data/ext/puma_http11/extconf.rb +28 -5
- data/ext/puma_http11/http11_parser.c +23 -10
- data/ext/puma_http11/http11_parser.h +0 -0
- data/ext/puma_http11/http11_parser.java.rl +0 -0
- data/ext/puma_http11/http11_parser.rl +0 -0
- data/ext/puma_http11/http11_parser_common.rl +1 -1
- data/ext/puma_http11/mini_ssl.c +69 -9
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +49 -47
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +28 -43
- data/ext/puma_http11/puma_http11.c +1 -1
- data/lib/puma/app/status.rb +4 -4
- data/lib/puma/binder.rb +50 -5
- data/lib/puma/cli.rb +14 -4
- data/lib/puma/client.rb +50 -9
- data/lib/puma/cluster/worker.rb +8 -18
- data/lib/puma/cluster/worker_handle.rb +4 -0
- data/lib/puma/cluster.rb +30 -24
- data/lib/puma/commonlogger.rb +0 -0
- data/lib/puma/configuration.rb +4 -1
- data/lib/puma/const.rb +4 -5
- data/lib/puma/control_cli.rb +1 -1
- data/lib/puma/detect.rb +8 -2
- data/lib/puma/dsl.rb +105 -11
- data/lib/puma/error_logger.rb +0 -0
- data/lib/puma/events.rb +0 -0
- data/lib/puma/io_buffer.rb +0 -0
- data/lib/puma/jruby_restart.rb +0 -0
- data/lib/puma/{json.rb → json_serialization.rb} +1 -1
- data/lib/puma/launcher.rb +4 -1
- data/lib/puma/minissl/context_builder.rb +8 -6
- data/lib/puma/minissl.rb +24 -23
- data/lib/puma/null_io.rb +0 -0
- data/lib/puma/plugin/tmp_restart.rb +0 -0
- data/lib/puma/plugin.rb +2 -2
- data/lib/puma/queue_close.rb +0 -0
- data/lib/puma/rack/builder.rb +1 -1
- data/lib/puma/rack/urlmap.rb +0 -0
- data/lib/puma/rack_default.rb +0 -0
- data/lib/puma/reactor.rb +0 -0
- data/lib/puma/request.rb +14 -9
- data/lib/puma/runner.rb +22 -8
- data/lib/puma/server.rb +32 -29
- data/lib/puma/single.rb +0 -0
- data/lib/puma/state_file.rb +41 -7
- data/lib/puma/systemd.rb +0 -0
- data/lib/puma/thread_pool.rb +7 -5
- data/lib/puma/util.rb +8 -1
- data/lib/puma.rb +2 -2
- data/lib/rack/handler/puma.rb +0 -0
- data/tools/Dockerfile +1 -1
- data/tools/trickletest.rb +0 -0
- metadata +7 -7
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -49,7 +49,8 @@ const rb_data_type_t engine_data_type = {
|
|
49
49
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
50
50
|
};
|
51
51
|
|
52
|
-
|
52
|
+
#ifndef HAVE_SSL_GET1_PEER_CERTIFICATE
|
53
|
+
DH *get_dh2048(void) {
|
53
54
|
/* `openssl dhparam -C 2048`
|
54
55
|
* -----BEGIN DH PARAMETERS-----
|
55
56
|
* MIIBCAKCAQEAjmh1uQHdTfxOyxEbKAV30fUfzqMDF/ChPzjfyzl2jcrqQMhrk76o
|
@@ -119,6 +120,7 @@ DH *get_dh2048() {
|
|
119
120
|
|
120
121
|
return dh;
|
121
122
|
}
|
123
|
+
#endif
|
122
124
|
|
123
125
|
static void
|
124
126
|
sslctx_free(void *ptr) {
|
@@ -208,8 +210,13 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
|
208
210
|
#endif
|
209
211
|
int ssl_options;
|
210
212
|
VALUE key, cert, ca, verify_mode, ssl_cipher_filter, no_tlsv1, no_tlsv1_1,
|
211
|
-
verification_flags;
|
213
|
+
verification_flags, session_id_bytes, cert_pem, key_pem;
|
214
|
+
#ifndef HAVE_SSL_GET1_PEER_CERTIFICATE
|
212
215
|
DH *dh;
|
216
|
+
#endif
|
217
|
+
BIO *bio;
|
218
|
+
X509 *x509;
|
219
|
+
EVP_PKEY *pkey;
|
213
220
|
|
214
221
|
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
215
222
|
EC_KEY *ecdh;
|
@@ -218,13 +225,15 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
|
218
225
|
TypedData_Get_Struct(self, SSL_CTX, &sslctx_type, ctx);
|
219
226
|
|
220
227
|
key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
|
221
|
-
StringValue(key);
|
222
228
|
|
223
229
|
cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
|
224
|
-
StringValue(cert);
|
225
230
|
|
226
231
|
ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
|
227
232
|
|
233
|
+
cert_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("cert_pem"), 0);
|
234
|
+
|
235
|
+
key_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("key_pem"), 0);
|
236
|
+
|
228
237
|
verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0);
|
229
238
|
|
230
239
|
ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0);
|
@@ -233,8 +242,31 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
|
233
242
|
|
234
243
|
no_tlsv1_1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1_1"), 0);
|
235
244
|
|
236
|
-
|
237
|
-
|
245
|
+
if (!NIL_P(cert)) {
|
246
|
+
StringValue(cert);
|
247
|
+
SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
|
248
|
+
}
|
249
|
+
|
250
|
+
if (!NIL_P(key)) {
|
251
|
+
StringValue(key);
|
252
|
+
SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
|
253
|
+
}
|
254
|
+
|
255
|
+
if (!NIL_P(cert_pem)) {
|
256
|
+
bio = BIO_new(BIO_s_mem());
|
257
|
+
BIO_puts(bio, RSTRING_PTR(cert_pem));
|
258
|
+
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
259
|
+
|
260
|
+
SSL_CTX_use_certificate(ctx, x509);
|
261
|
+
}
|
262
|
+
|
263
|
+
if (!NIL_P(key_pem)) {
|
264
|
+
bio = BIO_new(BIO_s_mem());
|
265
|
+
BIO_puts(bio, RSTRING_PTR(key_pem));
|
266
|
+
pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
267
|
+
|
268
|
+
SSL_CTX_use_PrivateKey(ctx, pkey);
|
269
|
+
}
|
238
270
|
|
239
271
|
verification_flags = rb_funcall(mini_ssl_ctx, rb_intern_const("verification_flags"), 0);
|
240
272
|
|
@@ -289,9 +321,6 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
|
289
321
|
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
290
322
|
}
|
291
323
|
|
292
|
-
dh = get_dh2048();
|
293
|
-
SSL_CTX_set_tmp_dh(ctx, dh);
|
294
|
-
|
295
324
|
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
296
325
|
// Remove this case if OpenSSL 1.0.1 (now EOL) support is no
|
297
326
|
// longer needed.
|
@@ -309,7 +338,31 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
|
309
338
|
} else {
|
310
339
|
SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
|
311
340
|
}
|
341
|
+
|
342
|
+
// Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
|
343
|
+
session_id_bytes = rb_funcall(
|
344
|
+
#ifdef HAVE_RANDOM_BYTES
|
345
|
+
rb_cRandom,
|
346
|
+
#else
|
347
|
+
rb_const_get(rb_cRandom, rb_intern_const("DEFAULT")),
|
348
|
+
#endif
|
349
|
+
rb_intern_const("bytes"),
|
350
|
+
1, ULL2NUM(SSL_MAX_SSL_SESSION_ID_LENGTH));
|
351
|
+
|
352
|
+
SSL_CTX_set_session_id_context(ctx,
|
353
|
+
(unsigned char *) RSTRING_PTR(session_id_bytes),
|
354
|
+
SSL_MAX_SSL_SESSION_ID_LENGTH);
|
355
|
+
|
312
356
|
// printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx));
|
357
|
+
|
358
|
+
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
359
|
+
// https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_dh_auto.html
|
360
|
+
SSL_CTX_set_dh_auto(ctx, 1);
|
361
|
+
#else
|
362
|
+
dh = get_dh2048();
|
363
|
+
SSL_CTX_set_tmp_dh(ctx, dh);
|
364
|
+
#endif
|
365
|
+
|
313
366
|
rb_obj_freeze(self);
|
314
367
|
return self;
|
315
368
|
}
|
@@ -508,7 +561,11 @@ VALUE engine_peercert(VALUE self) {
|
|
508
561
|
|
509
562
|
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
510
563
|
|
564
|
+
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
565
|
+
cert = SSL_get1_peer_certificate(conn->ssl);
|
566
|
+
#else
|
511
567
|
cert = SSL_get_peer_certificate(conn->ssl);
|
568
|
+
#endif
|
512
569
|
if(!cert) {
|
513
570
|
/*
|
514
571
|
* See if there was a failed certificate associated with this client.
|
@@ -565,7 +622,10 @@ void Init_mini_ssl(VALUE puma) {
|
|
565
622
|
ERR_load_crypto_strings();
|
566
623
|
|
567
624
|
mod = rb_define_module_under(puma, "MiniSSL");
|
625
|
+
|
568
626
|
eng = rb_define_class_under(mod, "Engine", rb_cObject);
|
627
|
+
rb_undef_alloc_func(eng);
|
628
|
+
|
569
629
|
sslctx = rb_define_class_under(mod, "SSLContext", rb_cObject);
|
570
630
|
rb_define_alloc_func(sslctx, sslctx_alloc);
|
571
631
|
rb_define_method(sslctx, "initialize", sslctx_initialize, 1);
|
File without changes
|
File without changes
|
@@ -34,9 +34,9 @@ private static short[] init__puma_parser_key_offsets_0()
|
|
34
34
|
{
|
35
35
|
return new short [] {
|
36
36
|
0, 0, 8, 17, 27, 29, 30, 31, 32, 33, 34, 36,
|
37
|
-
39, 41, 44, 45, 61, 62, 78,
|
38
|
-
|
39
|
-
|
37
|
+
39, 41, 44, 45, 61, 62, 78, 85, 91, 99, 107, 117,
|
38
|
+
125, 134, 142, 150, 159, 168, 177, 186, 195, 204, 213, 222,
|
39
|
+
231, 240, 249, 258, 267, 276, 285, 294, 303, 312, 313
|
40
40
|
};
|
41
41
|
}
|
42
42
|
|
@@ -52,26 +52,27 @@ private static char[] init__puma_parser_trans_keys_0()
|
|
52
52
|
46, 48, 57, 48, 57, 13, 48, 57, 10, 13, 33, 124,
|
53
53
|
126, 35, 39, 42, 43, 45, 46, 48, 57, 65, 90, 94,
|
54
54
|
122, 10, 33, 58, 124, 126, 35, 39, 42, 43, 45, 46,
|
55
|
-
48, 57, 65, 90, 94, 122, 13, 32,
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
63
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
64
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
65
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
66
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
67
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
68
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
69
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
70
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
71
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
72
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
73
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
74
|
-
65, 90, 32,
|
55
|
+
48, 57, 65, 90, 94, 122, 13, 32, 127, 0, 8, 10,
|
56
|
+
31, 13, 127, 0, 8, 10, 31, 32, 60, 62, 127, 0,
|
57
|
+
31, 34, 35, 32, 60, 62, 127, 0, 31, 34, 35, 43,
|
58
|
+
58, 45, 46, 48, 57, 65, 90, 97, 122, 32, 34, 35,
|
59
|
+
60, 62, 127, 0, 31, 32, 34, 35, 60, 62, 63, 127,
|
60
|
+
0, 31, 32, 34, 35, 60, 62, 127, 0, 31, 32, 34,
|
61
|
+
35, 60, 62, 127, 0, 31, 32, 36, 95, 45, 46, 48,
|
62
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
63
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
64
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
65
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
66
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
67
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
68
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
69
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
70
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
71
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
72
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
73
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
74
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
75
|
+
32, 0
|
75
76
|
};
|
76
77
|
}
|
77
78
|
|
@@ -82,7 +83,7 @@ private static byte[] init__puma_parser_single_lengths_0()
|
|
82
83
|
{
|
83
84
|
return new byte [] {
|
84
85
|
0, 2, 3, 4, 2, 1, 1, 1, 1, 1, 0, 1,
|
85
|
-
0, 1, 1, 4, 1, 4,
|
86
|
+
0, 1, 1, 4, 1, 4, 3, 2, 4, 4, 2, 6,
|
86
87
|
7, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
87
88
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0
|
88
89
|
};
|
@@ -95,7 +96,7 @@ private static byte[] init__puma_parser_range_lengths_0()
|
|
95
96
|
{
|
96
97
|
return new byte [] {
|
97
98
|
0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 1,
|
98
|
-
1, 1, 0, 6, 0, 6,
|
99
|
+
1, 1, 0, 6, 0, 6, 2, 2, 2, 2, 4, 1,
|
99
100
|
1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
100
101
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0
|
101
102
|
};
|
@@ -108,9 +109,9 @@ private static short[] init__puma_parser_index_offsets_0()
|
|
108
109
|
{
|
109
110
|
return new short [] {
|
110
111
|
0, 0, 6, 13, 21, 24, 26, 28, 30, 32, 34, 36,
|
111
|
-
39, 41, 44, 46, 57, 59, 70,
|
112
|
-
|
113
|
-
|
112
|
+
39, 41, 44, 46, 57, 59, 70, 76, 81, 88, 95, 102,
|
113
|
+
110, 119, 127, 135, 142, 149, 156, 163, 170, 177, 184, 191,
|
114
|
+
198, 205, 212, 219, 226, 233, 240, 247, 254, 261, 263
|
114
115
|
};
|
115
116
|
}
|
116
117
|
|
@@ -126,22 +127,23 @@ private static byte[] init__puma_parser_indicies_0()
|
|
126
127
|
16, 15, 1, 17, 1, 18, 17, 1, 19, 1, 20, 21,
|
127
128
|
21, 21, 21, 21, 21, 21, 21, 21, 1, 22, 1, 23,
|
128
129
|
24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27,
|
129
|
-
|
130
|
-
1, 1, 1, 1,
|
131
|
-
|
132
|
-
1,
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
63, 63, 1, 2, 1, 1,
|
130
|
+
1, 1, 1, 25, 29, 1, 1, 1, 28, 30, 1, 1,
|
131
|
+
1, 1, 1, 31, 32, 1, 1, 1, 1, 1, 33, 34,
|
132
|
+
35, 34, 34, 34, 34, 1, 8, 1, 9, 1, 1, 1,
|
133
|
+
1, 35, 36, 1, 38, 1, 1, 39, 1, 1, 37, 40,
|
134
|
+
1, 42, 1, 1, 1, 1, 41, 43, 1, 45, 1, 1,
|
135
|
+
1, 1, 44, 2, 46, 46, 46, 46, 46, 1, 2, 47,
|
136
|
+
47, 47, 47, 47, 1, 2, 48, 48, 48, 48, 48, 1,
|
137
|
+
2, 49, 49, 49, 49, 49, 1, 2, 50, 50, 50, 50,
|
138
|
+
50, 1, 2, 51, 51, 51, 51, 51, 1, 2, 52, 52,
|
139
|
+
52, 52, 52, 1, 2, 53, 53, 53, 53, 53, 1, 2,
|
140
|
+
54, 54, 54, 54, 54, 1, 2, 55, 55, 55, 55, 55,
|
141
|
+
1, 2, 56, 56, 56, 56, 56, 1, 2, 57, 57, 57,
|
142
|
+
57, 57, 1, 2, 58, 58, 58, 58, 58, 1, 2, 59,
|
143
|
+
59, 59, 59, 59, 1, 2, 60, 60, 60, 60, 60, 1,
|
144
|
+
2, 61, 61, 61, 61, 61, 1, 2, 62, 62, 62, 62,
|
145
|
+
62, 1, 2, 63, 63, 63, 63, 63, 1, 2, 1, 1,
|
146
|
+
0
|
145
147
|
};
|
146
148
|
}
|
147
149
|
|
@@ -210,7 +212,7 @@ static final int puma_parser_error = 0;
|
|
210
212
|
cs = 0;
|
211
213
|
|
212
214
|
|
213
|
-
// line
|
215
|
+
// line 216 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
214
216
|
{
|
215
217
|
cs = puma_parser_start;
|
216
218
|
}
|
@@ -242,7 +244,7 @@ static final int puma_parser_error = 0;
|
|
242
244
|
parser.buffer = buffer;
|
243
245
|
|
244
246
|
|
245
|
-
// line
|
247
|
+
// line 248 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
246
248
|
{
|
247
249
|
int _klen;
|
248
250
|
int _trans = 0;
|
@@ -398,7 +400,7 @@ case 1:
|
|
398
400
|
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
|
399
401
|
}
|
400
402
|
break;
|
401
|
-
// line
|
403
|
+
// line 404 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
402
404
|
}
|
403
405
|
}
|
404
406
|
}
|
@@ -6,6 +6,7 @@ import org.jruby.RubyModule;
|
|
6
6
|
import org.jruby.RubyObject;
|
7
7
|
import org.jruby.RubyString;
|
8
8
|
import org.jruby.anno.JRubyMethod;
|
9
|
+
import org.jruby.exceptions.RaiseException;
|
9
10
|
import org.jruby.javasupport.JavaEmbedUtils;
|
10
11
|
import org.jruby.runtime.Block;
|
11
12
|
import org.jruby.runtime.ObjectAllocator;
|
@@ -80,11 +81,11 @@ public class MiniSSL extends RubyObject {
|
|
80
81
|
/**
|
81
82
|
* Writes bytes to the buffer after ensuring there's room
|
82
83
|
*/
|
83
|
-
|
84
|
-
if (buffer.remaining() <
|
85
|
-
resize(buffer.limit() +
|
84
|
+
private void put(byte[] bytes, final int offset, final int length) {
|
85
|
+
if (buffer.remaining() < length) {
|
86
|
+
resize(buffer.limit() + length);
|
86
87
|
}
|
87
|
-
buffer.put(bytes);
|
88
|
+
buffer.put(bytes, offset, length);
|
88
89
|
}
|
89
90
|
|
90
91
|
/**
|
@@ -115,7 +116,7 @@ public class MiniSSL extends RubyObject {
|
|
115
116
|
|
116
117
|
buffer.get(bss);
|
117
118
|
buffer.clear();
|
118
|
-
return new ByteList(bss);
|
119
|
+
return new ByteList(bss, false);
|
119
120
|
}
|
120
121
|
|
121
122
|
@Override
|
@@ -174,8 +175,6 @@ public class MiniSSL extends RubyObject {
|
|
174
175
|
@JRubyMethod
|
175
176
|
public IRubyObject initialize(ThreadContext threadContext, IRubyObject miniSSLContext)
|
176
177
|
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
|
177
|
-
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
178
|
-
KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
|
179
178
|
|
180
179
|
String keystoreFile = miniSSLContext.callMethod(threadContext, "keystore").convertToString().asJavaString();
|
181
180
|
KeyManagerFactory kmf = keyManagerFactoryMap.get(keystoreFile);
|
@@ -230,14 +229,9 @@ public class MiniSSL extends RubyObject {
|
|
230
229
|
|
231
230
|
@JRubyMethod
|
232
231
|
public IRubyObject inject(IRubyObject arg) {
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
return this;
|
237
|
-
} catch (Exception e) {
|
238
|
-
e.printStackTrace();
|
239
|
-
throw new RuntimeException(e);
|
240
|
-
}
|
232
|
+
ByteList bytes = arg.convertToString().getByteList();
|
233
|
+
inboundNetData.put(bytes.unsafeBytes(), bytes.getBegin(), bytes.getRealSize());
|
234
|
+
return this;
|
241
235
|
}
|
242
236
|
|
243
237
|
private enum SSLOperation {
|
@@ -297,7 +291,7 @@ public class MiniSSL extends RubyObject {
|
|
297
291
|
}
|
298
292
|
|
299
293
|
@JRubyMethod
|
300
|
-
public IRubyObject read()
|
294
|
+
public IRubyObject read() {
|
301
295
|
try {
|
302
296
|
inboundNetData.flip();
|
303
297
|
|
@@ -342,55 +336,46 @@ public class MiniSSL extends RubyObject {
|
|
342
336
|
return getRuntime().getNil();
|
343
337
|
}
|
344
338
|
|
345
|
-
RubyString
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
throw
|
339
|
+
return RubyString.newString(getRuntime(), appDataByteList);
|
340
|
+
} catch (SSLException e) {
|
341
|
+
RaiseException re = getRuntime().newEOFError(e.getMessage());
|
342
|
+
re.initCause(e);
|
343
|
+
throw re;
|
350
344
|
}
|
351
345
|
}
|
352
346
|
|
353
347
|
@JRubyMethod
|
354
348
|
public IRubyObject write(IRubyObject arg) {
|
355
|
-
|
356
|
-
|
357
|
-
outboundAppData = new MiniSSLBuffer(bls);
|
349
|
+
byte[] bls = arg.convertToString().getBytes();
|
350
|
+
outboundAppData = new MiniSSLBuffer(bls);
|
358
351
|
|
359
|
-
|
360
|
-
} catch (Exception e) {
|
361
|
-
e.printStackTrace();
|
362
|
-
throw new RuntimeException(e);
|
363
|
-
}
|
352
|
+
return getRuntime().newFixnum(bls.length);
|
364
353
|
}
|
365
354
|
|
366
355
|
@JRubyMethod
|
367
|
-
public IRubyObject extract()
|
356
|
+
public IRubyObject extract(ThreadContext context) {
|
368
357
|
try {
|
369
358
|
ByteList dataByteList = outboundNetData.asByteList();
|
370
359
|
if (dataByteList != null) {
|
371
|
-
RubyString
|
372
|
-
str.setValue(dataByteList);
|
373
|
-
return str;
|
360
|
+
return RubyString.newString(context.runtime, dataByteList);
|
374
361
|
}
|
375
362
|
|
376
363
|
if (!outboundAppData.hasRemaining()) {
|
377
|
-
return
|
364
|
+
return context.nil;
|
378
365
|
}
|
379
366
|
|
380
367
|
outboundNetData.clear();
|
381
368
|
doOp(SSLOperation.WRAP, outboundAppData, outboundNetData);
|
382
369
|
dataByteList = outboundNetData.asByteList();
|
383
370
|
if (dataByteList == null) {
|
384
|
-
return
|
371
|
+
return context.nil;
|
385
372
|
}
|
386
373
|
|
387
|
-
RubyString
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
e.printStackTrace();
|
393
|
-
throw new RuntimeException(e);
|
374
|
+
return RubyString.newString(context.runtime, dataByteList);
|
375
|
+
} catch (SSLException e) {
|
376
|
+
RaiseException ex = context.runtime.newRuntimeError(e.toString());
|
377
|
+
ex.initCause(e);
|
378
|
+
throw ex;
|
394
379
|
}
|
395
380
|
}
|
396
381
|
|
@@ -398,7 +383,7 @@ public class MiniSSL extends RubyObject {
|
|
398
383
|
public IRubyObject peercert() throws CertificateEncodingException {
|
399
384
|
try {
|
400
385
|
return JavaEmbedUtils.javaToRuby(getRuntime(), engine.getSession().getPeerCertificates()[0].getEncoded());
|
401
|
-
} catch (SSLPeerUnverifiedException
|
386
|
+
} catch (SSLPeerUnverifiedException e) {
|
402
387
|
return getRuntime().getNil();
|
403
388
|
}
|
404
389
|
}
|
data/lib/puma/app/status.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'puma/
|
2
|
+
require 'puma/json_serialization'
|
3
3
|
|
4
4
|
module Puma
|
5
5
|
module App
|
@@ -46,17 +46,17 @@ module Puma
|
|
46
46
|
GC.start ; 200
|
47
47
|
|
48
48
|
when 'gc-stats'
|
49
|
-
Puma::
|
49
|
+
Puma::JSONSerialization.generate GC.stat
|
50
50
|
|
51
51
|
when 'stats'
|
52
|
-
Puma::
|
52
|
+
Puma::JSONSerialization.generate @launcher.stats
|
53
53
|
|
54
54
|
when 'thread-backtraces'
|
55
55
|
backtraces = []
|
56
56
|
@launcher.thread_status do |name, backtrace|
|
57
57
|
backtraces << { name: name, backtrace: backtrace }
|
58
58
|
end
|
59
|
-
Puma::
|
59
|
+
Puma::JSONSerialization.generate backtraces
|
60
60
|
|
61
61
|
else
|
62
62
|
return rack_response(404, "Unsupported action", 'text/plain')
|
data/lib/puma/binder.rb
CHANGED
@@ -30,6 +30,7 @@ module Puma
|
|
30
30
|
|
31
31
|
def initialize(events, conf = Configuration.new)
|
32
32
|
@events = events
|
33
|
+
@conf = conf
|
33
34
|
@listeners = []
|
34
35
|
@inherited_fds = {}
|
35
36
|
@activated_sockets = {}
|
@@ -41,6 +42,7 @@ module Puma
|
|
41
42
|
"rack.multithread".freeze => conf.options[:max_threads] > 1,
|
42
43
|
"rack.multiprocess".freeze => conf.options[:workers] >= 1,
|
43
44
|
"rack.run_once".freeze => false,
|
45
|
+
RACK_URL_SCHEME => conf.options[:rack_url_scheme],
|
44
46
|
"SCRIPT_NAME".freeze => ENV['SCRIPT_NAME'] || "",
|
45
47
|
|
46
48
|
# I'd like to set a default CONTENT_TYPE here but some things
|
@@ -56,6 +58,7 @@ module Puma
|
|
56
58
|
|
57
59
|
@envs = {}
|
58
60
|
@ios = []
|
61
|
+
localhost_authority
|
59
62
|
end
|
60
63
|
|
61
64
|
attr_reader :ios
|
@@ -95,6 +98,7 @@ module Puma
|
|
95
98
|
# @version 5.0.0
|
96
99
|
#
|
97
100
|
def create_activated_fds(env_hash)
|
101
|
+
@events.debug "ENV['LISTEN_FDS'] #{ENV['LISTEN_FDS'].inspect} env_hash['LISTEN_PID'] #{env_hash['LISTEN_PID'].inspect}"
|
98
102
|
return [] unless env_hash['LISTEN_FDS'] && env_hash['LISTEN_PID'].to_i == $$
|
99
103
|
env_hash['LISTEN_FDS'].to_i.times do |index|
|
100
104
|
sock = TCPServer.for_fd(socket_activation_fd(index))
|
@@ -164,9 +168,9 @@ module Puma
|
|
164
168
|
params = Util.parse_query uri.query
|
165
169
|
|
166
170
|
opt = params.key?('low_latency') && params['low_latency'] != 'false'
|
167
|
-
|
171
|
+
backlog = params.fetch('backlog', 1024).to_i
|
168
172
|
|
169
|
-
io = add_tcp_listener uri.host, uri.port, opt,
|
173
|
+
io = add_tcp_listener uri.host, uri.port, opt, backlog
|
170
174
|
|
171
175
|
@ios[ios_len..-1].each do |i|
|
172
176
|
addr = loc_addr_str i
|
@@ -188,7 +192,8 @@ module Puma
|
|
188
192
|
@unix_paths << path unless abstract
|
189
193
|
io = inherit_unix_listener path, fd
|
190
194
|
logger.log "* Inherited #{str}"
|
191
|
-
elsif sock = @activated_sockets.delete([ :unix, path ])
|
195
|
+
elsif sock = @activated_sockets.delete([ :unix, path ]) ||
|
196
|
+
@activated_sockets.delete([ :unix, File.realdirpath(path) ])
|
192
197
|
@unix_paths << path unless abstract || File.exist?(path)
|
193
198
|
io = inherit_unix_listener path, sock
|
194
199
|
logger.log "* Activated #{str}"
|
@@ -224,7 +229,25 @@ module Puma
|
|
224
229
|
raise "Puma compiled without SSL support" unless HAS_SSL
|
225
230
|
|
226
231
|
params = Util.parse_query uri.query
|
227
|
-
|
232
|
+
|
233
|
+
# If key and certs are not defined and localhost gem is required.
|
234
|
+
# localhost gem will be used for self signed
|
235
|
+
# Load localhost authority if not loaded.
|
236
|
+
if params.values_at('cert', 'key').all? { |v| v.to_s.empty? }
|
237
|
+
ctx = localhost_authority && localhost_authority_context
|
238
|
+
end
|
239
|
+
|
240
|
+
ctx ||=
|
241
|
+
begin
|
242
|
+
# Extract cert_pem and key_pem from options[:store] if present
|
243
|
+
['cert', 'key'].each do |v|
|
244
|
+
if params[v] && params[v].start_with?('store:')
|
245
|
+
index = Integer(params.delete(v).split('store:').last)
|
246
|
+
params["#{v}_pem"] = @conf.options[:store][index]
|
247
|
+
end
|
248
|
+
end
|
249
|
+
MiniSSL::ContextBuilder.new(params, @events).context
|
250
|
+
end
|
228
251
|
|
229
252
|
if fd = @inherited_fds.delete(str)
|
230
253
|
logger.log "* Inherited #{str}"
|
@@ -234,7 +257,8 @@ module Puma
|
|
234
257
|
logger.log "* Activated #{str}"
|
235
258
|
else
|
236
259
|
ios_len = @ios.length
|
237
|
-
|
260
|
+
backlog = params.fetch('backlog', 1024).to_i
|
261
|
+
io = add_ssl_listener uri.host, uri.port, ctx, optimize_for_latency = true, backlog
|
238
262
|
|
239
263
|
@ios[ios_len..-1].each do |i|
|
240
264
|
addr = loc_addr_str i
|
@@ -282,6 +306,22 @@ module Puma
|
|
282
306
|
end
|
283
307
|
end
|
284
308
|
|
309
|
+
def localhost_authority
|
310
|
+
@localhost_authority ||= Localhost::Authority.fetch if defined?(Localhost::Authority) && !Puma::IS_JRUBY
|
311
|
+
end
|
312
|
+
|
313
|
+
def localhost_authority_context
|
314
|
+
return unless localhost_authority
|
315
|
+
|
316
|
+
key_path, crt_path = if [:key_path, :certificate_path].all? { |m| localhost_authority.respond_to?(m) }
|
317
|
+
[localhost_authority.key_path, localhost_authority.certificate_path]
|
318
|
+
else
|
319
|
+
local_certificates_path = File.expand_path("~/.localhost")
|
320
|
+
[File.join(local_certificates_path, "localhost.key"), File.join(local_certificates_path, "localhost.crt")]
|
321
|
+
end
|
322
|
+
MiniSSL::ContextBuilder.new({ "key" => key_path, "cert" => crt_path }, @events).context
|
323
|
+
end
|
324
|
+
|
285
325
|
# Tell the server to listen on host +host+, port +port+.
|
286
326
|
# If +optimize_for_latency+ is true (the default) then clients connecting
|
287
327
|
# will be optimized for latency over throughput.
|
@@ -299,6 +339,7 @@ module Puma
|
|
299
339
|
|
300
340
|
host = host[1..-2] if host and host[0..0] == '['
|
301
341
|
tcp_server = TCPServer.new(host, port)
|
342
|
+
|
302
343
|
if optimize_for_latency
|
303
344
|
tcp_server.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
304
345
|
end
|
@@ -320,6 +361,8 @@ module Puma
|
|
320
361
|
optimize_for_latency=true, backlog=1024)
|
321
362
|
|
322
363
|
raise "Puma compiled without SSL support" unless HAS_SSL
|
364
|
+
# Puma will try to use local authority context if context is supplied nil
|
365
|
+
ctx ||= localhost_authority_context
|
323
366
|
|
324
367
|
if host == "localhost"
|
325
368
|
loopback_addresses.each do |addr|
|
@@ -347,6 +390,8 @@ module Puma
|
|
347
390
|
|
348
391
|
def inherit_ssl_listener(fd, ctx)
|
349
392
|
raise "Puma compiled without SSL support" unless HAS_SSL
|
393
|
+
# Puma will try to use local authority context if context is supplied nil
|
394
|
+
ctx ||= localhost_authority_context
|
350
395
|
|
351
396
|
s = fd.kind_of?(::TCPServer) ? fd : ::TCPServer.for_fd(fd)
|
352
397
|
|