puma 4.3.3 → 5.3.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.

Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +1348 -519
  3. data/LICENSE +23 -20
  4. data/README.md +74 -31
  5. data/bin/puma-wild +3 -9
  6. data/docs/architecture.md +24 -20
  7. data/docs/compile_options.md +19 -0
  8. data/docs/deployment.md +15 -10
  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 +2 -2
  17. data/docs/rails_dev_mode.md +29 -0
  18. data/docs/restart.md +46 -23
  19. data/docs/signals.md +7 -6
  20. data/docs/stats.md +142 -0
  21. data/docs/systemd.md +27 -67
  22. data/ext/puma_http11/PumaHttp11Service.java +2 -4
  23. data/ext/puma_http11/ext_help.h +1 -1
  24. data/ext/puma_http11/extconf.rb +22 -8
  25. data/ext/puma_http11/http11_parser.c +48 -48
  26. data/ext/puma_http11/http11_parser.h +1 -1
  27. data/ext/puma_http11/http11_parser.java.rl +1 -1
  28. data/ext/puma_http11/http11_parser.rl +4 -2
  29. data/ext/puma_http11/mini_ssl.c +211 -118
  30. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  31. data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
  32. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +5 -7
  33. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +77 -18
  34. data/ext/puma_http11/puma_http11.c +32 -50
  35. data/lib/puma.rb +46 -0
  36. data/lib/puma/app/status.rb +48 -35
  37. data/lib/puma/binder.rb +177 -103
  38. data/lib/puma/cli.rb +11 -15
  39. data/lib/puma/client.rb +83 -76
  40. data/lib/puma/cluster.rb +184 -198
  41. data/lib/puma/cluster/worker.rb +183 -0
  42. data/lib/puma/cluster/worker_handle.rb +90 -0
  43. data/lib/puma/commonlogger.rb +2 -2
  44. data/lib/puma/configuration.rb +55 -49
  45. data/lib/puma/const.rb +13 -5
  46. data/lib/puma/control_cli.rb +93 -76
  47. data/lib/puma/detect.rb +24 -3
  48. data/lib/puma/dsl.rb +266 -92
  49. data/lib/puma/error_logger.rb +104 -0
  50. data/lib/puma/events.rb +55 -34
  51. data/lib/puma/io_buffer.rb +9 -2
  52. data/lib/puma/jruby_restart.rb +0 -58
  53. data/lib/puma/json.rb +96 -0
  54. data/lib/puma/launcher.rb +113 -45
  55. data/lib/puma/minissl.rb +114 -33
  56. data/lib/puma/minissl/context_builder.rb +6 -3
  57. data/lib/puma/null_io.rb +13 -1
  58. data/lib/puma/plugin.rb +1 -10
  59. data/lib/puma/queue_close.rb +26 -0
  60. data/lib/puma/rack/builder.rb +0 -4
  61. data/lib/puma/reactor.rb +85 -369
  62. data/lib/puma/request.rb +467 -0
  63. data/lib/puma/runner.rb +29 -58
  64. data/lib/puma/server.rb +267 -698
  65. data/lib/puma/single.rb +9 -65
  66. data/lib/puma/state_file.rb +8 -3
  67. data/lib/puma/systemd.rb +46 -0
  68. data/lib/puma/thread_pool.rb +119 -53
  69. data/lib/puma/util.rb +12 -0
  70. data/lib/rack/handler/puma.rb +2 -3
  71. data/tools/{docker/Dockerfile → Dockerfile} +0 -0
  72. metadata +28 -24
  73. data/docs/tcp_mode.md +0 -96
  74. data/ext/puma_http11/io_buffer.c +0 -155
  75. data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -72
  76. data/lib/puma/accept_nonblock.rb +0 -29
  77. data/lib/puma/tcp_logger.rb +0 -41
  78. data/tools/jungle/README.md +0 -19
  79. data/tools/jungle/init.d/README.md +0 -61
  80. data/tools/jungle/init.d/puma +0 -421
  81. data/tools/jungle/init.d/run-puma +0 -18
  82. data/tools/jungle/upstart/README.md +0 -61
  83. data/tools/jungle/upstart/puma-manager.conf +0 -31
  84. data/tools/jungle/upstart/puma.conf +0 -69
@@ -29,8 +29,8 @@ typedef void (*field_cb)(struct puma_parser* hp,
29
29
 
30
30
  typedef struct puma_parser {
31
31
  int cs;
32
- size_t body_start;
33
32
  int content_len;
33
+ size_t body_start;
34
34
  size_t nread;
35
35
  size_t mark;
36
36
  size_t field_start;
@@ -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);
@@ -12,12 +12,14 @@
12
12
 
13
13
  /*
14
14
  * capitalizes all lower-case ASCII characters,
15
- * converts dashes to underscores.
15
+ * converts dashes to underscores, and underscores to commas.
16
16
  */
17
17
  static void snake_upcase_char(char *c)
18
18
  {
19
19
  if (*c >= 'a' && *c <= 'z')
20
20
  *c &= ~0x20;
21
+ else if (*c == '_')
22
+ *c = ',';
21
23
  else if (*c == '-')
22
24
  *c = '_';
23
25
  }
@@ -79,7 +81,7 @@ static void snake_upcase_char(char *c)
79
81
  }%%
80
82
 
81
83
  /** Data **/
82
- %% write data;
84
+ %% write data noentry;
83
85
 
84
86
  int puma_parser_init(puma_parser *parser) {
85
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);
58
-
59
- conn->ssl = 0;
60
- conn->ctx = 0;
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
+ };
61
51
 
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;
148
213
 
149
- ID sym_key = rb_intern("key");
150
- VALUE key = rb_funcall(mini_ssl_ctx, sym_key, 0);
214
+ #if OPENSSL_VERSION_NUMBER < 0x10002000L
215
+ EC_KEY *ecdh;
216
+ #endif
151
217
 
152
- StringValue(key);
218
+ TypedData_Get_Struct(self, SSL_CTX, &sslctx_type, ctx);
153
219
 
154
- ID sym_cert = rb_intern("cert");
155
- VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
220
+ key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
221
+ StringValue(key);
156
222
 
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,13 +367,14 @@ 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];
301
374
  char msg[512];
302
375
  const char* err_str;
303
376
  int err = errno;
377
+ int mask = 4095;
304
378
  int ssl_err = SSL_get_error(ssl, result);
305
379
  int verify_err = (int) SSL_get_verify_result(ssl);
306
380
 
@@ -317,8 +391,7 @@ void raise_error(SSL* ssl, int result) {
317
391
  } else {
318
392
  err = (int) ERR_get_error();
319
393
  ERR_error_string_n(err, buf, sizeof(buf));
320
- snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err);
321
-
394
+ snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err & mask);
322
395
  }
323
396
  } else {
324
397
  snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err);
@@ -333,7 +406,7 @@ VALUE engine_read(VALUE self) {
333
406
  char buf[512];
334
407
  int bytes, error;
335
408
 
336
- Data_Get_Struct(self, ms_conn, conn);
409
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
337
410
 
338
411
  ERR_clear_error();
339
412
 
@@ -360,7 +433,7 @@ VALUE engine_write(VALUE self, VALUE str) {
360
433
  ms_conn* conn;
361
434
  int bytes;
362
435
 
363
- Data_Get_Struct(self, ms_conn, conn);
436
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
364
437
 
365
438
  StringValue(str);
366
439
 
@@ -382,9 +455,11 @@ VALUE engine_extract(VALUE self) {
382
455
  ms_conn* conn;
383
456
  int bytes;
384
457
  size_t pending;
385
- 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];
386
461
 
387
- Data_Get_Struct(self, ms_conn, conn);
462
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
388
463
 
389
464
  pending = BIO_pending(conn->write);
390
465
  if(pending > 0) {
@@ -403,7 +478,7 @@ VALUE engine_shutdown(VALUE self) {
403
478
  ms_conn* conn;
404
479
  int ok;
405
480
 
406
- Data_Get_Struct(self, ms_conn, conn);
481
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
407
482
 
408
483
  ERR_clear_error();
409
484
 
@@ -418,7 +493,7 @@ VALUE engine_shutdown(VALUE self) {
418
493
  VALUE engine_init(VALUE self) {
419
494
  ms_conn* conn;
420
495
 
421
- Data_Get_Struct(self, ms_conn, conn);
496
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
422
497
 
423
498
  return SSL_in_init(conn->ssl) ? Qtrue : Qfalse;
424
499
  }
@@ -431,7 +506,7 @@ VALUE engine_peercert(VALUE self) {
431
506
  ms_cert_buf* cert_buf = NULL;
432
507
  VALUE rb_cert_buf;
433
508
 
434
- Data_Get_Struct(self, ms_conn, conn);
509
+ TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
435
510
 
436
511
  cert = SSL_get_peer_certificate(conn->ssl);
437
512
  if(!cert) {
@@ -462,12 +537,22 @@ VALUE engine_peercert(VALUE self) {
462
537
  return rb_cert_buf;
463
538
  }
464
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
+
465
550
  VALUE noop(VALUE self) {
466
551
  return Qnil;
467
552
  }
468
553
 
469
554
  void Init_mini_ssl(VALUE puma) {
470
- VALUE mod, eng;
555
+ VALUE mod, eng, sslctx;
471
556
 
472
557
  /* Fake operation for documentation (RDoc, YARD) */
473
558
  #if 0 == 1
@@ -481,6 +566,11 @@ void Init_mini_ssl(VALUE puma) {
481
566
 
482
567
  mod = rb_define_module_under(puma, "MiniSSL");
483
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
+
484
574
 
485
575
  // OpenSSL Build / Runtime/Load versions
486
576
 
@@ -493,27 +583,27 @@ void Init_mini_ssl(VALUE puma) {
493
583
  #else
494
584
  rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
495
585
  #endif
496
-
497
- #if defined(OPENSSL_NO_SSL3) || defined(OPENSSL_NO_SSL3_METHOD)
498
- /* True if SSL3 is not available */
499
- rb_define_const(mod, "OPENSSL_NO_SSL3", Qtrue);
500
- #else
501
- rb_define_const(mod, "OPENSSL_NO_SSL3", Qfalse);
502
- #endif
503
-
504
- #if defined(OPENSSL_NO_TLS1) || defined(OPENSSL_NO_TLS1_METHOD)
505
- /* True if TLS1 is not available */
506
- rb_define_const(mod, "OPENSSL_NO_TLS1", Qtrue);
507
- #else
508
- rb_define_const(mod, "OPENSSL_NO_TLS1", Qfalse);
509
- #endif
510
-
511
- #if defined(OPENSSL_NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1_METHOD)
512
- /* True if TLS1_1 is not available */
513
- rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qtrue);
514
- #else
515
- rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qfalse);
516
- #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
517
607
 
518
608
  rb_define_singleton_method(mod, "check", noop, 0);
519
609
 
@@ -533,13 +623,16 @@ void Init_mini_ssl(VALUE puma) {
533
623
  rb_define_method(eng, "init?", engine_init, 0);
534
624
 
535
625
  rb_define_method(eng, "peercert", engine_peercert, 0);
626
+
627
+ rb_define_method(eng, "ssl_vers_st", engine_ssl_vers_st, 0);
536
628
  }
537
629
 
538
630
  #else
539
631
 
632
+ NORETURN(VALUE raise_error(VALUE self));
633
+
540
634
  VALUE raise_error(VALUE self) {
541
635
  rb_raise(rb_eStandardError, "SSL not available in this build");
542
- return Qnil;
543
636
  }
544
637
 
545
638
  void Init_mini_ssl(VALUE puma) {