puma 5.0.2-java → 5.2.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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +667 -567
  3. data/README.md +51 -21
  4. data/bin/puma-wild +3 -9
  5. data/docs/compile_options.md +19 -0
  6. data/docs/deployment.md +6 -7
  7. data/docs/fork_worker.md +2 -0
  8. data/docs/jungle/README.md +0 -4
  9. data/docs/jungle/rc.d/puma +2 -2
  10. data/docs/kubernetes.md +66 -0
  11. data/docs/nginx.md +1 -1
  12. data/docs/plugins.md +1 -1
  13. data/docs/restart.md +46 -23
  14. data/docs/stats.md +142 -0
  15. data/docs/systemd.md +25 -3
  16. data/ext/puma_http11/ext_help.h +1 -1
  17. data/ext/puma_http11/extconf.rb +18 -5
  18. data/ext/puma_http11/http11_parser.c +45 -47
  19. data/ext/puma_http11/http11_parser.java.rl +1 -1
  20. data/ext/puma_http11/http11_parser.rl +1 -1
  21. data/ext/puma_http11/mini_ssl.c +199 -119
  22. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +5 -7
  23. data/ext/puma_http11/puma_http11.c +25 -12
  24. data/lib/puma.rb +2 -2
  25. data/lib/puma/app/status.rb +44 -46
  26. data/lib/puma/binder.rb +69 -25
  27. data/lib/puma/cli.rb +4 -0
  28. data/lib/puma/client.rb +26 -79
  29. data/lib/puma/cluster.rb +37 -202
  30. data/lib/puma/cluster/worker.rb +176 -0
  31. data/lib/puma/cluster/worker_handle.rb +86 -0
  32. data/lib/puma/configuration.rb +21 -8
  33. data/lib/puma/const.rb +11 -3
  34. data/lib/puma/control_cli.rb +73 -70
  35. data/lib/puma/dsl.rb +100 -22
  36. data/lib/puma/error_logger.rb +10 -3
  37. data/lib/puma/events.rb +18 -3
  38. data/lib/puma/json.rb +96 -0
  39. data/lib/puma/launcher.rb +57 -15
  40. data/lib/puma/minissl.rb +47 -16
  41. data/lib/puma/minissl/context_builder.rb +6 -0
  42. data/lib/puma/null_io.rb +4 -0
  43. data/lib/puma/puma_http11.jar +0 -0
  44. data/lib/puma/queue_close.rb +26 -0
  45. data/lib/puma/reactor.rb +85 -363
  46. data/lib/puma/request.rb +451 -0
  47. data/lib/puma/runner.rb +17 -23
  48. data/lib/puma/server.rb +164 -553
  49. data/lib/puma/single.rb +2 -2
  50. data/lib/puma/state_file.rb +5 -3
  51. data/lib/puma/systemd.rb +46 -0
  52. data/lib/puma/util.rb +11 -0
  53. metadata +11 -6
  54. data/docs/jungle/upstart/README.md +0 -61
  55. data/docs/jungle/upstart/puma-manager.conf +0 -31
  56. data/docs/jungle/upstart/puma.conf +0 -69
  57. data/lib/puma/accept_nonblock.rb +0 -29
@@ -58,7 +58,7 @@ public class Http11Parser {
58
58
  }%%
59
59
 
60
60
  /** Data **/
61
- %% write data;
61
+ %% write data noentry;
62
62
 
63
63
  public static interface ElementCB {
64
64
  public void call(Ruby runtime, RubyHash data, ByteList buffer, int at, int length);
@@ -81,7 +81,7 @@ static void snake_upcase_char(char *c)
81
81
  }%%
82
82
 
83
83
  /** Data **/
84
- %% write data;
84
+ %% write data noentry;
85
85
 
86
86
  int puma_parser_init(puma_parser *parser) {
87
87
  int cs = 0;
@@ -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;
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);
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
+ };
58
51
 
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,49 +177,73 @@ 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
- int min, ssl_options;
146
205
 
147
- 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
148
217
 
149
- ID sym_key = rb_intern("key");
150
- VALUE key = rb_funcall(mini_ssl_ctx, sym_key, 0);
218
+ TypedData_Get_Struct(self, SSL_CTX, &sslctx_type, ctx);
151
219
 
220
+ key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
152
221
  StringValue(key);
153
222
 
154
- ID sym_cert = rb_intern("cert");
155
- VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
156
-
223
+ cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
157
224
  StringValue(cert);
158
225
 
159
- ID sym_ca = rb_intern("ca");
160
- VALUE ca = rb_funcall(mini_ssl_ctx, sym_ca, 0);
161
-
162
- ID sym_verify_mode = rb_intern("verify_mode");
163
- VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
226
+ ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
164
227
 
165
- ID sym_ssl_cipher_filter = rb_intern("ssl_cipher_filter");
166
- VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
228
+ verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0);
167
229
 
168
- ID sym_no_tlsv1 = rb_intern("no_tlsv1");
169
- VALUE no_tlsv1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1, 0);
230
+ ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0);
170
231
 
171
- ID sym_no_tlsv1_1 = rb_intern("no_tlsv1_1");
172
- VALUE no_tlsv1_1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1_1, 0);
232
+ no_tlsv1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1"), 0);
173
233
 
174
- #ifdef HAVE_TLS_SERVER_METHOD
175
- ctx = SSL_CTX_new(TLS_server_method());
176
- #else
177
- ctx = SSL_CTX_new(SSLv23_server_method());
178
- #endif
179
- conn->ctx = ctx;
234
+ no_tlsv1_1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1_1"), 0);
180
235
 
181
236
  SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
182
237
  SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
183
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
+
184
247
  if (!NIL_P(ca)) {
185
248
  StringValue(ca);
186
249
  SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL);
@@ -198,7 +261,7 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
198
261
  else {
199
262
  min = TLS1_VERSION;
200
263
  }
201
-
264
+
202
265
  SSL_CTX_set_min_proto_version(ctx, min);
203
266
 
204
267
  SSL_CTX_set_options(ctx, ssl_options);
@@ -226,35 +289,45 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
226
289
  SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
227
290
  }
228
291
 
229
- DH *dh = get_dh1024();
292
+ dh = get_dh2048();
230
293
  SSL_CTX_set_tmp_dh(ctx, dh);
231
294
 
232
295
  #if OPENSSL_VERSION_NUMBER < 0x10002000L
233
296
  // Remove this case if OpenSSL 1.0.1 (now EOL) support is no
234
297
  // longer needed.
235
- EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
298
+ ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
236
299
  if (ecdh) {
237
300
  SSL_CTX_set_tmp_ecdh(ctx, ecdh);
238
301
  EC_KEY_free(ecdh);
239
302
  }
240
303
  #elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
241
- // Prior to OpenSSL 1.1.0, servers must manually enable server-side ECDH
242
- // negotiation.
243
304
  SSL_CTX_set_ecdh_auto(ctx, 1);
244
305
  #endif
245
306
 
246
- ssl = SSL_new(ctx);
247
- conn->ssl = ssl;
248
- SSL_set_app_data(ssl, NULL);
249
-
250
307
  if (NIL_P(verify_mode)) {
251
- /* SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); */
308
+ /* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */
252
309
  } else {
253
- SSL_set_verify(ssl, NUM2INT(verify_mode), engine_verify_callback);
310
+ SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
254
311
  }
312
+ // printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx));
313
+ rb_obj_freeze(self);
314
+ return self;
315
+ }
255
316
 
256
- 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);
257
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);
258
331
  SSL_set_accept_state(ssl);
259
332
  return obj;
260
333
  }
@@ -281,7 +354,7 @@ VALUE engine_inject(VALUE self, VALUE str) {
281
354
  ms_conn* conn;
282
355
  long used;
283
356
 
284
- Data_Get_Struct(self, ms_conn, conn);
357
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
285
358
 
286
359
  StringValue(str);
287
360
 
@@ -294,7 +367,7 @@ VALUE engine_inject(VALUE self, VALUE str) {
294
367
  return INT2FIX(used);
295
368
  }
296
369
 
297
- static VALUE eError;
370
+ NORETURN(void raise_error(SSL* ssl, int result));
298
371
 
299
372
  void raise_error(SSL* ssl, int result) {
300
373
  char buf[512];
@@ -318,8 +391,7 @@ void raise_error(SSL* ssl, int result) {
318
391
  } else {
319
392
  err = (int) ERR_get_error();
320
393
  ERR_error_string_n(err, buf, sizeof(buf));
321
- int errexp = err & mask;
322
- snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, errexp);
394
+ snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err & mask);
323
395
  }
324
396
  } else {
325
397
  snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err);
@@ -334,7 +406,7 @@ VALUE engine_read(VALUE self) {
334
406
  char buf[512];
335
407
  int bytes, error;
336
408
 
337
- Data_Get_Struct(self, ms_conn, conn);
409
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
338
410
 
339
411
  ERR_clear_error();
340
412
 
@@ -361,7 +433,7 @@ VALUE engine_write(VALUE self, VALUE str) {
361
433
  ms_conn* conn;
362
434
  int bytes;
363
435
 
364
- Data_Get_Struct(self, ms_conn, conn);
436
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
365
437
 
366
438
  StringValue(str);
367
439
 
@@ -383,9 +455,11 @@ VALUE engine_extract(VALUE self) {
383
455
  ms_conn* conn;
384
456
  int bytes;
385
457
  size_t pending;
386
- 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];
387
461
 
388
- Data_Get_Struct(self, ms_conn, conn);
462
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
389
463
 
390
464
  pending = BIO_pending(conn->write);
391
465
  if(pending > 0) {
@@ -404,7 +478,7 @@ VALUE engine_shutdown(VALUE self) {
404
478
  ms_conn* conn;
405
479
  int ok;
406
480
 
407
- Data_Get_Struct(self, ms_conn, conn);
481
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
408
482
 
409
483
  ERR_clear_error();
410
484
 
@@ -419,7 +493,7 @@ VALUE engine_shutdown(VALUE self) {
419
493
  VALUE engine_init(VALUE self) {
420
494
  ms_conn* conn;
421
495
 
422
- Data_Get_Struct(self, ms_conn, conn);
496
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
423
497
 
424
498
  return SSL_in_init(conn->ssl) ? Qtrue : Qfalse;
425
499
  }
@@ -432,7 +506,7 @@ VALUE engine_peercert(VALUE self) {
432
506
  ms_cert_buf* cert_buf = NULL;
433
507
  VALUE rb_cert_buf;
434
508
 
435
- Data_Get_Struct(self, ms_conn, conn);
509
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
436
510
 
437
511
  cert = SSL_get_peer_certificate(conn->ssl);
438
512
  if(!cert) {
@@ -469,7 +543,7 @@ VALUE engine_peercert(VALUE self) {
469
543
  static VALUE
470
544
  engine_ssl_vers_st(VALUE self) {
471
545
  ms_conn* conn;
472
- Data_Get_Struct(self, ms_conn, conn);
546
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
473
547
  return rb_ary_new3(2, rb_str_new2(SSL_get_version(conn->ssl)), rb_str_new2(SSL_state_string(conn->ssl)));
474
548
  }
475
549
 
@@ -478,7 +552,7 @@ VALUE noop(VALUE self) {
478
552
  }
479
553
 
480
554
  void Init_mini_ssl(VALUE puma) {
481
- VALUE mod, eng;
555
+ VALUE mod, eng, sslctx;
482
556
 
483
557
  /* Fake operation for documentation (RDoc, YARD) */
484
558
  #if 0 == 1
@@ -492,6 +566,11 @@ void Init_mini_ssl(VALUE puma) {
492
566
 
493
567
  mod = rb_define_module_under(puma, "MiniSSL");
494
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
+
495
574
 
496
575
  // OpenSSL Build / Runtime/Load versions
497
576
 
@@ -504,27 +583,27 @@ void Init_mini_ssl(VALUE puma) {
504
583
  #else
505
584
  rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
506
585
  #endif
507
-
508
- #if defined(OPENSSL_NO_SSL3) || defined(OPENSSL_NO_SSL3_METHOD)
509
- /* True if SSL3 is not available */
510
- rb_define_const(mod, "OPENSSL_NO_SSL3", Qtrue);
511
- #else
512
- rb_define_const(mod, "OPENSSL_NO_SSL3", Qfalse);
513
- #endif
514
-
515
- #if defined(OPENSSL_NO_TLS1) || defined(OPENSSL_NO_TLS1_METHOD)
516
- /* True if TLS1 is not available */
517
- rb_define_const(mod, "OPENSSL_NO_TLS1", Qtrue);
518
- #else
519
- rb_define_const(mod, "OPENSSL_NO_TLS1", Qfalse);
520
- #endif
521
-
522
- #if defined(OPENSSL_NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1_METHOD)
523
- /* True if TLS1_1 is not available */
524
- rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qtrue);
525
- #else
526
- rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qfalse);
527
- #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
528
607
 
529
608
  rb_define_singleton_method(mod, "check", noop, 0);
530
609
 
@@ -550,9 +629,10 @@ void Init_mini_ssl(VALUE puma) {
550
629
 
551
630
  #else
552
631
 
632
+ NORETURN(VALUE raise_error(VALUE self));
633
+
553
634
  VALUE raise_error(VALUE self) {
554
635
  rb_raise(rb_eStandardError, "SSL not available in this build");
555
- return Qnil;
556
636
  }
557
637
 
558
638
  void Init_mini_ssl(VALUE puma) {