puma 3.12.0 → 5.3.1

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.

Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +1413 -439
  3. data/LICENSE +23 -20
  4. data/README.md +131 -60
  5. data/bin/puma-wild +3 -9
  6. data/docs/architecture.md +24 -19
  7. data/docs/compile_options.md +19 -0
  8. data/docs/deployment.md +38 -13
  9. data/docs/fork_worker.md +33 -0
  10. data/docs/jungle/README.md +9 -0
  11. data/{tools → docs}/jungle/rc.d/README.md +1 -1
  12. data/{tools → docs}/jungle/rc.d/puma +2 -2
  13. data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
  14. data/docs/kubernetes.md +66 -0
  15. data/docs/nginx.md +1 -1
  16. data/docs/plugins.md +20 -10
  17. data/docs/rails_dev_mode.md +29 -0
  18. data/docs/restart.md +47 -22
  19. data/docs/signals.md +7 -6
  20. data/docs/stats.md +142 -0
  21. data/docs/systemd.md +48 -70
  22. data/ext/puma_http11/PumaHttp11Service.java +2 -2
  23. data/ext/puma_http11/ext_help.h +1 -1
  24. data/ext/puma_http11/extconf.rb +27 -0
  25. data/ext/puma_http11/http11_parser.c +84 -109
  26. data/ext/puma_http11/http11_parser.h +1 -1
  27. data/ext/puma_http11/http11_parser.java.rl +22 -38
  28. data/ext/puma_http11/http11_parser.rl +4 -2
  29. data/ext/puma_http11/http11_parser_common.rl +3 -3
  30. data/ext/puma_http11/mini_ssl.c +262 -87
  31. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  32. data/ext/puma_http11/org/jruby/puma/Http11.java +108 -116
  33. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +89 -106
  34. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +92 -22
  35. data/ext/puma_http11/puma_http11.c +34 -50
  36. data/lib/puma/app/status.rb +68 -49
  37. data/lib/puma/binder.rb +197 -144
  38. data/lib/puma/cli.rb +17 -15
  39. data/lib/puma/client.rb +257 -226
  40. data/lib/puma/cluster/worker.rb +176 -0
  41. data/lib/puma/cluster/worker_handle.rb +90 -0
  42. data/lib/puma/cluster.rb +223 -212
  43. data/lib/puma/commonlogger.rb +4 -2
  44. data/lib/puma/configuration.rb +58 -51
  45. data/lib/puma/const.rb +41 -19
  46. data/lib/puma/control_cli.rb +117 -73
  47. data/lib/puma/detect.rb +26 -3
  48. data/lib/puma/dsl.rb +531 -123
  49. data/lib/puma/error_logger.rb +104 -0
  50. data/lib/puma/events.rb +57 -31
  51. data/lib/puma/io_buffer.rb +9 -5
  52. data/lib/puma/jruby_restart.rb +2 -58
  53. data/lib/puma/json.rb +96 -0
  54. data/lib/puma/launcher.rb +182 -70
  55. data/lib/puma/minissl/context_builder.rb +79 -0
  56. data/lib/puma/minissl.rb +149 -48
  57. data/lib/puma/null_io.rb +15 -1
  58. data/lib/puma/plugin/tmp_restart.rb +2 -0
  59. data/lib/puma/plugin.rb +8 -12
  60. data/lib/puma/queue_close.rb +26 -0
  61. data/lib/puma/rack/builder.rb +4 -5
  62. data/lib/puma/rack/urlmap.rb +2 -0
  63. data/lib/puma/rack_default.rb +2 -0
  64. data/lib/puma/reactor.rb +87 -316
  65. data/lib/puma/request.rb +456 -0
  66. data/lib/puma/runner.rb +33 -52
  67. data/lib/puma/server.rb +288 -679
  68. data/lib/puma/single.rb +13 -67
  69. data/lib/puma/state_file.rb +10 -3
  70. data/lib/puma/systemd.rb +46 -0
  71. data/lib/puma/thread_pool.rb +131 -81
  72. data/lib/puma/util.rb +14 -6
  73. data/lib/puma.rb +54 -0
  74. data/lib/rack/handler/puma.rb +8 -6
  75. data/tools/Dockerfile +16 -0
  76. data/tools/trickletest.rb +0 -1
  77. metadata +45 -29
  78. data/ext/puma_http11/io_buffer.c +0 -155
  79. data/lib/puma/accept_nonblock.rb +0 -23
  80. data/lib/puma/compat.rb +0 -14
  81. data/lib/puma/convenient.rb +0 -23
  82. data/lib/puma/daemon_ext.rb +0 -31
  83. data/lib/puma/delegation.rb +0 -11
  84. data/lib/puma/java_io_buffer.rb +0 -45
  85. data/lib/puma/rack/backports/uri/common_193.rb +0 -33
  86. data/lib/puma/tcp_logger.rb +0 -39
  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,10 @@ 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
+ void engine_free(void *ptr) {
34
+ ms_conn *conn = ptr;
37
35
  ms_cert_buf* cert_buf = (ms_cert_buf*)SSL_get_app_data(conn->ssl);
38
36
  if(cert_buf) {
39
37
  OPENSSL_free(cert_buf->buf);
@@ -45,61 +43,71 @@ void engine_free(ms_conn* conn) {
45
43
  free(conn);
46
44
  }
47
45
 
48
- ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
49
- ms_conn* conn;
46
+ const rb_data_type_t engine_data_type = {
47
+ "MiniSSL/ENGINE",
48
+ { 0, engine_free, 0 },
49
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
50
+ };
50
51
 
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
- }
64
-
65
- DH *get_dh1024() {
66
- /* `openssl dhparam 1024 -C`
52
+ DH *get_dh2048() {
53
+ /* `openssl dhparam -C 2048`
67
54
  * -----BEGIN DH PARAMETERS-----
68
- * MIGHAoGBALPwcEv0OstmQCZdfHw0N5r+07lmXMxkpQacy1blwj0LUqC+Divp6pBk
69
- * usTJ9W2/dOYr1X7zi6yXNLp4oLzc/31PUL3D9q8CpGS7vPz5gijKSw9BwCTT5z9+
70
- * KF9v46qw8XqT5HHV87sWFlGQcVFq+pEkA2kPikkKZ/X/CCcpCAV7AgEC
55
+ * MIIBCAKCAQEAjmh1uQHdTfxOyxEbKAV30fUfzqMDF/ChPzjfyzl2jcrqQMhrk76o
56
+ * 2NPNXqxHwsddMZ1RzvU8/jl+uhRuPWjXCFZbhET4N1vrviZM3VJhV8PPHuiVOACO
57
+ * y32jFd+Szx4bo2cXSK83hJ6jRd+0asP1awWjz9/06dFkrILCXMIfQLo0D8rqmppn
58
+ * EfDDAwuudCpM9kcDmBRAm9JsKbQ6gzZWjkc5+QWSaQofojIHbjvj3xzguaCJn+oQ
59
+ * vHWM+hsAnaOgEwCyeZ3xqs+/5lwSbkE/tqJW98cEZGygBUVo9jxZRZx6KOfjpdrb
60
+ * yenO9LJr/qtyrZB31WJbqxI0m0AKTAO8UwIBAg==
71
61
  * -----END DH PARAMETERS-----
72
62
  */
73
- static unsigned char dh1024_p[] = {
74
- 0xB3,0xF0,0x70,0x4B,0xF4,0x3A,0xCB,0x66,0x40,0x26,0x5D,0x7C,
75
- 0x7C,0x34,0x37,0x9A,0xFE,0xD3,0xB9,0x66,0x5C,0xCC,0x64,0xA5,
76
- 0x06,0x9C,0xCB,0x56,0xE5,0xC2,0x3D,0x0B,0x52,0xA0,0xBE,0x0E,
77
- 0x2B,0xE9,0xEA,0x90,0x64,0xBA,0xC4,0xC9,0xF5,0x6D,0xBF,0x74,
78
- 0xE6,0x2B,0xD5,0x7E,0xF3,0x8B,0xAC,0x97,0x34,0xBA,0x78,0xA0,
79
- 0xBC,0xDC,0xFF,0x7D,0x4F,0x50,0xBD,0xC3,0xF6,0xAF,0x02,0xA4,
80
- 0x64,0xBB,0xBC,0xFC,0xF9,0x82,0x28,0xCA,0x4B,0x0F,0x41,0xC0,
81
- 0x24,0xD3,0xE7,0x3F,0x7E,0x28,0x5F,0x6F,0xE3,0xAA,0xB0,0xF1,
82
- 0x7A,0x93,0xE4,0x71,0xD5,0xF3,0xBB,0x16,0x16,0x51,0x90,0x71,
83
- 0x51,0x6A,0xFA,0x91,0x24,0x03,0x69,0x0F,0x8A,0x49,0x0A,0x67,
84
- 0xF5,0xFF,0x08,0x27,0x29,0x08,0x05,0x7B
63
+ static unsigned char dh2048_p[] = {
64
+ 0x8E, 0x68, 0x75, 0xB9, 0x01, 0xDD, 0x4D, 0xFC, 0x4E, 0xCB,
65
+ 0x11, 0x1B, 0x28, 0x05, 0x77, 0xD1, 0xF5, 0x1F, 0xCE, 0xA3,
66
+ 0x03, 0x17, 0xF0, 0xA1, 0x3F, 0x38, 0xDF, 0xCB, 0x39, 0x76,
67
+ 0x8D, 0xCA, 0xEA, 0x40, 0xC8, 0x6B, 0x93, 0xBE, 0xA8, 0xD8,
68
+ 0xD3, 0xCD, 0x5E, 0xAC, 0x47, 0xC2, 0xC7, 0x5D, 0x31, 0x9D,
69
+ 0x51, 0xCE, 0xF5, 0x3C, 0xFE, 0x39, 0x7E, 0xBA, 0x14, 0x6E,
70
+ 0x3D, 0x68, 0xD7, 0x08, 0x56, 0x5B, 0x84, 0x44, 0xF8, 0x37,
71
+ 0x5B, 0xEB, 0xBE, 0x26, 0x4C, 0xDD, 0x52, 0x61, 0x57, 0xC3,
72
+ 0xCF, 0x1E, 0xE8, 0x95, 0x38, 0x00, 0x8E, 0xCB, 0x7D, 0xA3,
73
+ 0x15, 0xDF, 0x92, 0xCF, 0x1E, 0x1B, 0xA3, 0x67, 0x17, 0x48,
74
+ 0xAF, 0x37, 0x84, 0x9E, 0xA3, 0x45, 0xDF, 0xB4, 0x6A, 0xC3,
75
+ 0xF5, 0x6B, 0x05, 0xA3, 0xCF, 0xDF, 0xF4, 0xE9, 0xD1, 0x64,
76
+ 0xAC, 0x82, 0xC2, 0x5C, 0xC2, 0x1F, 0x40, 0xBA, 0x34, 0x0F,
77
+ 0xCA, 0xEA, 0x9A, 0x9A, 0x67, 0x11, 0xF0, 0xC3, 0x03, 0x0B,
78
+ 0xAE, 0x74, 0x2A, 0x4C, 0xF6, 0x47, 0x03, 0x98, 0x14, 0x40,
79
+ 0x9B, 0xD2, 0x6C, 0x29, 0xB4, 0x3A, 0x83, 0x36, 0x56, 0x8E,
80
+ 0x47, 0x39, 0xF9, 0x05, 0x92, 0x69, 0x0A, 0x1F, 0xA2, 0x32,
81
+ 0x07, 0x6E, 0x3B, 0xE3, 0xDF, 0x1C, 0xE0, 0xB9, 0xA0, 0x89,
82
+ 0x9F, 0xEA, 0x10, 0xBC, 0x75, 0x8C, 0xFA, 0x1B, 0x00, 0x9D,
83
+ 0xA3, 0xA0, 0x13, 0x00, 0xB2, 0x79, 0x9D, 0xF1, 0xAA, 0xCF,
84
+ 0xBF, 0xE6, 0x5C, 0x12, 0x6E, 0x41, 0x3F, 0xB6, 0xA2, 0x56,
85
+ 0xF7, 0xC7, 0x04, 0x64, 0x6C, 0xA0, 0x05, 0x45, 0x68, 0xF6,
86
+ 0x3C, 0x59, 0x45, 0x9C, 0x7A, 0x28, 0xE7, 0xE3, 0xA5, 0xDA,
87
+ 0xDB, 0xC9, 0xE9, 0xCE, 0xF4, 0xB2, 0x6B, 0xFE, 0xAB, 0x72,
88
+ 0xAD, 0x90, 0x77, 0xD5, 0x62, 0x5B, 0xAB, 0x12, 0x34, 0x9B,
89
+ 0x40, 0x0A, 0x4C, 0x03, 0xBC, 0x53
85
90
  };
86
- static unsigned char dh1024_g[] = { 0x02 };
91
+ static unsigned char dh2048_g[] = { 0x02 };
87
92
 
88
93
  DH *dh;
94
+ #if !(OPENSSL_VERSION_NUMBER < 0x10100005L || defined(LIBRESSL_VERSION_NUMBER))
95
+ BIGNUM *p, *g;
96
+ #endif
97
+
89
98
  dh = DH_new();
90
99
 
91
100
  #if OPENSSL_VERSION_NUMBER < 0x10100005L || defined(LIBRESSL_VERSION_NUMBER)
92
- dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
93
- dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
101
+ dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
102
+ dh->g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
94
103
 
95
104
  if ((dh->p == NULL) || (dh->g == NULL)) {
96
105
  DH_free(dh);
97
106
  return NULL;
98
107
  }
99
108
  #else
100
- BIGNUM *p, *g;
101
- p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
102
- g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
109
+ p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
110
+ g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
103
111
 
104
112
  if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) {
105
113
  DH_free(dh);
@@ -112,6 +120,37 @@ DH *get_dh1024() {
112
120
  return dh;
113
121
  }
114
122
 
123
+ static void
124
+ sslctx_free(void *ptr) {
125
+ SSL_CTX *ctx = ptr;
126
+ SSL_CTX_free(ctx);
127
+ }
128
+
129
+ static const rb_data_type_t sslctx_type = {
130
+ "MiniSSL/SSLContext",
131
+ {
132
+ 0, sslctx_free,
133
+ },
134
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
135
+ };
136
+
137
+ ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
138
+ ms_conn* conn;
139
+
140
+ *obj = TypedData_Make_Struct(klass, ms_conn, &engine_data_type, conn);
141
+
142
+ conn->read = BIO_new(BIO_s_mem());
143
+ BIO_set_nbio(conn->read, 1);
144
+
145
+ conn->write = BIO_new(BIO_s_mem());
146
+ BIO_set_nbio(conn->write, 1);
147
+
148
+ conn->ssl = 0;
149
+ conn->ctx = 0;
150
+
151
+ return conn;
152
+ }
153
+
115
154
  static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
116
155
  X509* err_cert;
117
156
  SSL* ssl;
@@ -138,44 +177,108 @@ static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
138
177
  return preverify_ok;
139
178
  }
140
179
 
141
- VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
142
- VALUE obj;
180
+ static VALUE
181
+ sslctx_alloc(VALUE klass) {
182
+ SSL_CTX *ctx;
183
+ long mode = 0 |
184
+ SSL_MODE_ENABLE_PARTIAL_WRITE |
185
+ SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
186
+ SSL_MODE_RELEASE_BUFFERS;
187
+
188
+ #ifdef HAVE_TLS_SERVER_METHOD
189
+ ctx = SSL_CTX_new(TLS_method());
190
+ // printf("\nctx using TLS_method security_level %d\n", SSL_CTX_get_security_level(ctx));
191
+ #else
192
+ ctx = SSL_CTX_new(SSLv23_method());
193
+ #endif
194
+ if (!ctx) {
195
+ rb_raise(eError, "SSL_CTX_new");
196
+ }
197
+ SSL_CTX_set_mode(ctx, mode);
198
+
199
+ return TypedData_Wrap_Struct(klass, &sslctx_type, ctx);
200
+ }
201
+
202
+ VALUE
203
+ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
143
204
  SSL_CTX* ctx;
144
- SSL* ssl;
145
205
 
146
- ms_conn* conn = engine_alloc(self, &obj);
206
+ #ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
207
+ int min;
208
+ #endif
209
+ int ssl_options;
210
+ VALUE key, cert, ca, verify_mode, ssl_cipher_filter, no_tlsv1, no_tlsv1_1,
211
+ verification_flags;
212
+ DH *dh;
213
+
214
+ #if OPENSSL_VERSION_NUMBER < 0x10002000L
215
+ EC_KEY *ecdh;
216
+ #endif
147
217
 
148
- ID sym_key = rb_intern("key");
149
- VALUE key = rb_funcall(mini_ssl_ctx, sym_key, 0);
218
+ TypedData_Get_Struct(self, SSL_CTX, &sslctx_type, ctx);
150
219
 
220
+ key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
151
221
  StringValue(key);
152
222
 
153
- ID sym_cert = rb_intern("cert");
154
- VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
155
-
223
+ cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
156
224
  StringValue(cert);
157
225
 
158
- ID sym_ca = rb_intern("ca");
159
- VALUE ca = rb_funcall(mini_ssl_ctx, sym_ca, 0);
226
+ ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
160
227
 
161
- ID sym_verify_mode = rb_intern("verify_mode");
162
- VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
228
+ verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0);
163
229
 
164
- ID sym_ssl_cipher_filter = rb_intern("ssl_cipher_filter");
165
- VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
230
+ ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0);
166
231
 
167
- ctx = SSL_CTX_new(SSLv23_server_method());
168
- conn->ctx = ctx;
232
+ no_tlsv1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1"), 0);
233
+
234
+ no_tlsv1_1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1_1"), 0);
169
235
 
170
236
  SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
171
237
  SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
172
238
 
239
+ verification_flags = rb_funcall(mini_ssl_ctx, rb_intern_const("verification_flags"), 0);
240
+
241
+ if (!NIL_P(verification_flags)) {
242
+ X509_VERIFY_PARAM *param = SSL_CTX_get0_param(ctx);
243
+ X509_VERIFY_PARAM_set_flags(param, NUM2INT(verification_flags));
244
+ SSL_CTX_set1_param(ctx, param);
245
+ }
246
+
173
247
  if (!NIL_P(ca)) {
174
248
  StringValue(ca);
175
249
  SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL);
176
250
  }
177
251
 
178
- SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION);
252
+ ssl_options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION;
253
+
254
+ #ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
255
+ if (RTEST(no_tlsv1_1)) {
256
+ min = TLS1_2_VERSION;
257
+ }
258
+ else if (RTEST(no_tlsv1)) {
259
+ min = TLS1_1_VERSION;
260
+ }
261
+ else {
262
+ min = TLS1_VERSION;
263
+ }
264
+
265
+ SSL_CTX_set_min_proto_version(ctx, min);
266
+
267
+ SSL_CTX_set_options(ctx, ssl_options);
268
+
269
+ #else
270
+ /* As of 1.0.2f, SSL_OP_SINGLE_DH_USE key use is always on */
271
+ ssl_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE;
272
+
273
+ if (RTEST(no_tlsv1)) {
274
+ ssl_options |= SSL_OP_NO_TLSv1;
275
+ }
276
+ if(RTEST(no_tlsv1_1)) {
277
+ ssl_options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
278
+ }
279
+ SSL_CTX_set_options(ctx, ssl_options);
280
+ #endif
281
+
179
282
  SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
180
283
 
181
284
  if (!NIL_P(ssl_cipher_filter)) {
@@ -186,29 +289,45 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
186
289
  SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
187
290
  }
188
291
 
189
- DH *dh = get_dh1024();
292
+ dh = get_dh2048();
190
293
  SSL_CTX_set_tmp_dh(ctx, dh);
191
294
 
192
- #ifndef OPENSSL_NO_ECDH
193
- EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1);
295
+ #if OPENSSL_VERSION_NUMBER < 0x10002000L
296
+ // Remove this case if OpenSSL 1.0.1 (now EOL) support is no
297
+ // longer needed.
298
+ ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
194
299
  if (ecdh) {
195
300
  SSL_CTX_set_tmp_ecdh(ctx, ecdh);
196
301
  EC_KEY_free(ecdh);
197
302
  }
303
+ #elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
304
+ SSL_CTX_set_ecdh_auto(ctx, 1);
198
305
  #endif
199
306
 
200
- ssl = SSL_new(ctx);
201
- conn->ssl = ssl;
202
- SSL_set_app_data(ssl, NULL);
203
-
204
307
  if (NIL_P(verify_mode)) {
205
- /* SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); */
308
+ /* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */
206
309
  } else {
207
- SSL_set_verify(ssl, NUM2INT(verify_mode), engine_verify_callback);
310
+ SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
208
311
  }
312
+ // printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx));
313
+ rb_obj_freeze(self);
314
+ return self;
315
+ }
209
316
 
210
- SSL_set_bio(ssl, conn->read, conn->write);
317
+ VALUE engine_init_server(VALUE self, VALUE sslctx) {
318
+ ms_conn* conn;
319
+ VALUE obj;
320
+ SSL_CTX* ctx;
321
+ SSL* ssl;
322
+
323
+ conn = engine_alloc(self, &obj);
211
324
 
325
+ TypedData_Get_Struct(sslctx, SSL_CTX, &sslctx_type, ctx);
326
+
327
+ ssl = SSL_new(ctx);
328
+ conn->ssl = ssl;
329
+ SSL_set_app_data(ssl, NULL);
330
+ SSL_set_bio(ssl, conn->read, conn->write);
212
331
  SSL_set_accept_state(ssl);
213
332
  return obj;
214
333
  }
@@ -216,8 +335,11 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
216
335
  VALUE engine_init_client(VALUE klass) {
217
336
  VALUE obj;
218
337
  ms_conn* conn = engine_alloc(klass, &obj);
219
-
338
+ #ifdef HAVE_DTLS_METHOD
339
+ conn->ctx = SSL_CTX_new(DTLS_method());
340
+ #else
220
341
  conn->ctx = SSL_CTX_new(DTLSv1_method());
342
+ #endif
221
343
  conn->ssl = SSL_new(conn->ctx);
222
344
  SSL_set_app_data(conn->ssl, NULL);
223
345
  SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
@@ -232,7 +354,7 @@ VALUE engine_inject(VALUE self, VALUE str) {
232
354
  ms_conn* conn;
233
355
  long used;
234
356
 
235
- Data_Get_Struct(self, ms_conn, conn);
357
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
236
358
 
237
359
  StringValue(str);
238
360
 
@@ -245,13 +367,14 @@ VALUE engine_inject(VALUE self, VALUE str) {
245
367
  return INT2FIX(used);
246
368
  }
247
369
 
248
- static VALUE eError;
370
+ NORETURN(void raise_error(SSL* ssl, int result));
249
371
 
250
372
  void raise_error(SSL* ssl, int result) {
251
373
  char buf[512];
252
374
  char msg[512];
253
375
  const char* err_str;
254
376
  int err = errno;
377
+ int mask = 4095;
255
378
  int ssl_err = SSL_get_error(ssl, result);
256
379
  int verify_err = (int) SSL_get_verify_result(ssl);
257
380
 
@@ -268,8 +391,7 @@ void raise_error(SSL* ssl, int result) {
268
391
  } else {
269
392
  err = (int) ERR_get_error();
270
393
  ERR_error_string_n(err, buf, sizeof(buf));
271
- snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err);
272
-
394
+ snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err & mask);
273
395
  }
274
396
  } else {
275
397
  snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err);
@@ -284,7 +406,7 @@ VALUE engine_read(VALUE self) {
284
406
  char buf[512];
285
407
  int bytes, error;
286
408
 
287
- Data_Get_Struct(self, ms_conn, conn);
409
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
288
410
 
289
411
  ERR_clear_error();
290
412
 
@@ -311,7 +433,7 @@ VALUE engine_write(VALUE self, VALUE str) {
311
433
  ms_conn* conn;
312
434
  int bytes;
313
435
 
314
- Data_Get_Struct(self, ms_conn, conn);
436
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
315
437
 
316
438
  StringValue(str);
317
439
 
@@ -333,9 +455,11 @@ VALUE engine_extract(VALUE self) {
333
455
  ms_conn* conn;
334
456
  int bytes;
335
457
  size_t pending;
336
- char buf[512];
458
+ // https://www.openssl.org/docs/manmaster/man3/BIO_f_buffer.html
459
+ // crypto/bio/bf_buff.c DEFAULT_BUFFER_SIZE
460
+ char buf[4096];
337
461
 
338
- Data_Get_Struct(self, ms_conn, conn);
462
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
339
463
 
340
464
  pending = BIO_pending(conn->write);
341
465
  if(pending > 0) {
@@ -354,7 +478,7 @@ VALUE engine_shutdown(VALUE self) {
354
478
  ms_conn* conn;
355
479
  int ok;
356
480
 
357
- Data_Get_Struct(self, ms_conn, conn);
481
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
358
482
 
359
483
  ERR_clear_error();
360
484
 
@@ -369,7 +493,7 @@ VALUE engine_shutdown(VALUE self) {
369
493
  VALUE engine_init(VALUE self) {
370
494
  ms_conn* conn;
371
495
 
372
- Data_Get_Struct(self, ms_conn, conn);
496
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
373
497
 
374
498
  return SSL_in_init(conn->ssl) ? Qtrue : Qfalse;
375
499
  }
@@ -382,7 +506,7 @@ VALUE engine_peercert(VALUE self) {
382
506
  ms_cert_buf* cert_buf = NULL;
383
507
  VALUE rb_cert_buf;
384
508
 
385
- Data_Get_Struct(self, ms_conn, conn);
509
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
386
510
 
387
511
  cert = SSL_get_peer_certificate(conn->ssl);
388
512
  if(!cert) {
@@ -413,12 +537,22 @@ VALUE engine_peercert(VALUE self) {
413
537
  return rb_cert_buf;
414
538
  }
415
539
 
540
+ /* @see Puma::MiniSSL::Socket#ssl_version_state
541
+ * @version 5.0.0
542
+ */
543
+ static VALUE
544
+ engine_ssl_vers_st(VALUE self) {
545
+ ms_conn* conn;
546
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
547
+ return rb_ary_new3(2, rb_str_new2(SSL_get_version(conn->ssl)), rb_str_new2(SSL_state_string(conn->ssl)));
548
+ }
549
+
416
550
  VALUE noop(VALUE self) {
417
551
  return Qnil;
418
552
  }
419
553
 
420
554
  void Init_mini_ssl(VALUE puma) {
421
- VALUE mod, eng;
555
+ VALUE mod, eng, sslctx;
422
556
 
423
557
  /* Fake operation for documentation (RDoc, YARD) */
424
558
  #if 0 == 1
@@ -432,6 +566,44 @@ void Init_mini_ssl(VALUE puma) {
432
566
 
433
567
  mod = rb_define_module_under(puma, "MiniSSL");
434
568
  eng = rb_define_class_under(mod, "Engine", rb_cObject);
569
+ sslctx = rb_define_class_under(mod, "SSLContext", rb_cObject);
570
+ rb_define_alloc_func(sslctx, sslctx_alloc);
571
+ rb_define_method(sslctx, "initialize", sslctx_initialize, 1);
572
+ rb_undef_method(sslctx, "initialize_copy");
573
+
574
+
575
+ // OpenSSL Build / Runtime/Load versions
576
+
577
+ /* Version of OpenSSL that Puma was compiled with */
578
+ rb_define_const(mod, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
579
+
580
+ #if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
581
+ /* Version of OpenSSL that Puma loaded with */
582
+ rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
583
+ #else
584
+ rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
585
+ #endif
586
+
587
+ #if defined(OPENSSL_NO_SSL3) || defined(OPENSSL_NO_SSL3_METHOD)
588
+ /* True if SSL3 is not available */
589
+ rb_define_const(mod, "OPENSSL_NO_SSL3", Qtrue);
590
+ #else
591
+ rb_define_const(mod, "OPENSSL_NO_SSL3", Qfalse);
592
+ #endif
593
+
594
+ #if defined(OPENSSL_NO_TLS1) || defined(OPENSSL_NO_TLS1_METHOD)
595
+ /* True if TLS1 is not available */
596
+ rb_define_const(mod, "OPENSSL_NO_TLS1", Qtrue);
597
+ #else
598
+ rb_define_const(mod, "OPENSSL_NO_TLS1", Qfalse);
599
+ #endif
600
+
601
+ #if defined(OPENSSL_NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1_METHOD)
602
+ /* True if TLS1_1 is not available */
603
+ rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qtrue);
604
+ #else
605
+ rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qfalse);
606
+ #endif
435
607
 
436
608
  rb_define_singleton_method(mod, "check", noop, 0);
437
609
 
@@ -451,13 +623,16 @@ void Init_mini_ssl(VALUE puma) {
451
623
  rb_define_method(eng, "init?", engine_init, 0);
452
624
 
453
625
  rb_define_method(eng, "peercert", engine_peercert, 0);
626
+
627
+ rb_define_method(eng, "ssl_vers_st", engine_ssl_vers_st, 0);
454
628
  }
455
629
 
456
630
  #else
457
631
 
632
+ NORETURN(VALUE raise_error(VALUE self));
633
+
458
634
  VALUE raise_error(VALUE self) {
459
635
  rb_raise(rb_eStandardError, "SSL not available in this build");
460
- return Qnil;
461
636
  }
462
637
 
463
638
  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
+ }