puma-simon 3.7.1

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 (157) hide show
  1. checksums.yaml +7 -0
  2. data/.github/issue_template.md +20 -0
  3. data/.gitignore +18 -0
  4. data/.hoeignore +12 -0
  5. data/.travis.yml +29 -0
  6. data/DEPLOYMENT.md +91 -0
  7. data/Gemfile +12 -0
  8. data/History.md +1254 -0
  9. data/LICENSE +26 -0
  10. data/Manifest.txt +78 -0
  11. data/README.md +353 -0
  12. data/Rakefile +158 -0
  13. data/Release.md +9 -0
  14. data/bin/puma +10 -0
  15. data/bin/puma-wild +31 -0
  16. data/bin/pumactl +12 -0
  17. data/docs/nginx.md +80 -0
  18. data/docs/signals.md +43 -0
  19. data/docs/systemd.md +197 -0
  20. data/examples/CA/cacert.pem +23 -0
  21. data/examples/CA/newcerts/cert_1.pem +19 -0
  22. data/examples/CA/newcerts/cert_2.pem +19 -0
  23. data/examples/CA/private/cakeypair.pem +30 -0
  24. data/examples/CA/serial +1 -0
  25. data/examples/config.rb +200 -0
  26. data/examples/plugins/redis_stop_puma.rb +46 -0
  27. data/examples/puma/cert_puma.pem +19 -0
  28. data/examples/puma/client-certs/ca.crt +19 -0
  29. data/examples/puma/client-certs/ca.key +27 -0
  30. data/examples/puma/client-certs/client.crt +19 -0
  31. data/examples/puma/client-certs/client.key +27 -0
  32. data/examples/puma/client-certs/client_expired.crt +19 -0
  33. data/examples/puma/client-certs/client_expired.key +27 -0
  34. data/examples/puma/client-certs/client_unknown.crt +19 -0
  35. data/examples/puma/client-certs/client_unknown.key +27 -0
  36. data/examples/puma/client-certs/generate.rb +78 -0
  37. data/examples/puma/client-certs/keystore.jks +0 -0
  38. data/examples/puma/client-certs/server.crt +19 -0
  39. data/examples/puma/client-certs/server.key +27 -0
  40. data/examples/puma/client-certs/server.p12 +0 -0
  41. data/examples/puma/client-certs/unknown_ca.crt +19 -0
  42. data/examples/puma/client-certs/unknown_ca.key +27 -0
  43. data/examples/puma/csr_puma.pem +11 -0
  44. data/examples/puma/keystore.jks +0 -0
  45. data/examples/puma/puma_keypair.pem +15 -0
  46. data/examples/qc_config.rb +13 -0
  47. data/ext/puma_http11/PumaHttp11Service.java +17 -0
  48. data/ext/puma_http11/ext_help.h +15 -0
  49. data/ext/puma_http11/extconf.rb +15 -0
  50. data/ext/puma_http11/http11_parser.c +1069 -0
  51. data/ext/puma_http11/http11_parser.h +65 -0
  52. data/ext/puma_http11/http11_parser.java.rl +161 -0
  53. data/ext/puma_http11/http11_parser.rl +147 -0
  54. data/ext/puma_http11/http11_parser_common.rl +54 -0
  55. data/ext/puma_http11/io_buffer.c +155 -0
  56. data/ext/puma_http11/mini_ssl.c +457 -0
  57. data/ext/puma_http11/org/jruby/puma/Http11.java +234 -0
  58. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +473 -0
  59. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +339 -0
  60. data/ext/puma_http11/puma_http11.c +500 -0
  61. data/gemfiles/2.1-Gemfile +12 -0
  62. data/lib/puma.rb +15 -0
  63. data/lib/puma/accept_nonblock.rb +23 -0
  64. data/lib/puma/app/status.rb +66 -0
  65. data/lib/puma/binder.rb +402 -0
  66. data/lib/puma/cli.rb +220 -0
  67. data/lib/puma/client.rb +434 -0
  68. data/lib/puma/cluster.rb +510 -0
  69. data/lib/puma/commonlogger.rb +106 -0
  70. data/lib/puma/compat.rb +14 -0
  71. data/lib/puma/configuration.rb +364 -0
  72. data/lib/puma/const.rb +224 -0
  73. data/lib/puma/control_cli.rb +259 -0
  74. data/lib/puma/convenient.rb +23 -0
  75. data/lib/puma/daemon_ext.rb +31 -0
  76. data/lib/puma/delegation.rb +11 -0
  77. data/lib/puma/detect.rb +13 -0
  78. data/lib/puma/dsl.rb +486 -0
  79. data/lib/puma/events.rb +152 -0
  80. data/lib/puma/io_buffer.rb +7 -0
  81. data/lib/puma/java_io_buffer.rb +45 -0
  82. data/lib/puma/jruby_restart.rb +83 -0
  83. data/lib/puma/launcher.rb +410 -0
  84. data/lib/puma/minissl.rb +221 -0
  85. data/lib/puma/null_io.rb +42 -0
  86. data/lib/puma/plugin.rb +115 -0
  87. data/lib/puma/plugin/tmp_restart.rb +35 -0
  88. data/lib/puma/rack/backports/uri/common_193.rb +33 -0
  89. data/lib/puma/rack/builder.rb +298 -0
  90. data/lib/puma/rack/urlmap.rb +91 -0
  91. data/lib/puma/rack_default.rb +7 -0
  92. data/lib/puma/reactor.rb +210 -0
  93. data/lib/puma/runner.rb +171 -0
  94. data/lib/puma/server.rb +949 -0
  95. data/lib/puma/single.rb +112 -0
  96. data/lib/puma/state_file.rb +29 -0
  97. data/lib/puma/tcp_logger.rb +39 -0
  98. data/lib/puma/thread_pool.rb +297 -0
  99. data/lib/puma/util.rb +128 -0
  100. data/lib/rack/handler/puma.rb +78 -0
  101. data/puma.gemspec +52 -0
  102. data/test/ab_rs.rb +22 -0
  103. data/test/config.rb +2 -0
  104. data/test/config/app.rb +9 -0
  105. data/test/config/plugin.rb +1 -0
  106. data/test/config/settings.rb +2 -0
  107. data/test/config/state_file_testing_config.rb +14 -0
  108. data/test/hello-bind.ru +2 -0
  109. data/test/hello-delay.ru +3 -0
  110. data/test/hello-map.ru +3 -0
  111. data/test/hello-post.ru +4 -0
  112. data/test/hello-stuck.ru +1 -0
  113. data/test/hello-tcp.ru +5 -0
  114. data/test/hello.ru +1 -0
  115. data/test/hijack.ru +6 -0
  116. data/test/hijack2.ru +5 -0
  117. data/test/lobster.ru +4 -0
  118. data/test/shell/run.sh +24 -0
  119. data/test/shell/t1.rb +19 -0
  120. data/test/shell/t1_conf.rb +3 -0
  121. data/test/shell/t2.rb +17 -0
  122. data/test/shell/t2_conf.rb +6 -0
  123. data/test/shell/t3.rb +25 -0
  124. data/test/shell/t3_conf.rb +5 -0
  125. data/test/slow.ru +4 -0
  126. data/test/ssl_config.rb +4 -0
  127. data/test/test_app_status.rb +93 -0
  128. data/test/test_binder.rb +31 -0
  129. data/test/test_cli.rb +209 -0
  130. data/test/test_config.rb +95 -0
  131. data/test/test_events.rb +161 -0
  132. data/test/test_helper.rb +50 -0
  133. data/test/test_http10.rb +27 -0
  134. data/test/test_http11.rb +186 -0
  135. data/test/test_integration.rb +247 -0
  136. data/test/test_iobuffer.rb +39 -0
  137. data/test/test_minissl.rb +29 -0
  138. data/test/test_null_io.rb +49 -0
  139. data/test/test_persistent.rb +245 -0
  140. data/test/test_puma_server.rb +626 -0
  141. data/test/test_puma_server_ssl.rb +222 -0
  142. data/test/test_rack_handler.rb +57 -0
  143. data/test/test_rack_server.rb +138 -0
  144. data/test/test_tcp_logger.rb +39 -0
  145. data/test/test_tcp_rack.rb +36 -0
  146. data/test/test_thread_pool.rb +250 -0
  147. data/test/test_unix_socket.rb +35 -0
  148. data/test/test_web_server.rb +88 -0
  149. data/tools/jungle/README.md +9 -0
  150. data/tools/jungle/init.d/README.md +59 -0
  151. data/tools/jungle/init.d/puma +421 -0
  152. data/tools/jungle/init.d/run-puma +18 -0
  153. data/tools/jungle/upstart/README.md +61 -0
  154. data/tools/jungle/upstart/puma-manager.conf +31 -0
  155. data/tools/jungle/upstart/puma.conf +69 -0
  156. data/tools/trickletest.rb +45 -0
  157. metadata +297 -0
@@ -0,0 +1,457 @@
1
+ #define RSTRING_NOT_MODIFIED 1
2
+
3
+ #include <ruby.h>
4
+ #include <ruby/version.h>
5
+
6
+ #if RUBY_API_VERSION_MAJOR == 1
7
+ #include <rubyio.h>
8
+ #else
9
+ #include <ruby/io.h>
10
+ #endif
11
+
12
+ #ifdef HAVE_OPENSSL_BIO_H
13
+
14
+ #include <openssl/bio.h>
15
+ #include <openssl/ssl.h>
16
+ #include <openssl/dh.h>
17
+ #include <openssl/err.h>
18
+ #include <openssl/x509.h>
19
+
20
+ #ifndef SSL_OP_NO_COMPRESSION
21
+ #define SSL_OP_NO_COMPRESSION 0
22
+ #endif
23
+
24
+ typedef struct {
25
+ BIO* read;
26
+ BIO* write;
27
+ SSL* ssl;
28
+ SSL_CTX* ctx;
29
+ } ms_conn;
30
+
31
+ typedef struct {
32
+ unsigned char* buf;
33
+ int bytes;
34
+ } ms_cert_buf;
35
+
36
+ void engine_free(ms_conn* conn) {
37
+ ms_cert_buf* cert_buf = (ms_cert_buf*)SSL_get_app_data(conn->ssl);
38
+ if(cert_buf) {
39
+ OPENSSL_free(cert_buf->buf);
40
+ free(cert_buf);
41
+ }
42
+ SSL_free(conn->ssl);
43
+ SSL_CTX_free(conn->ctx);
44
+
45
+ free(conn);
46
+ }
47
+
48
+ ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
49
+ ms_conn* conn;
50
+
51
+ *obj = Data_Make_Struct(klass, ms_conn, 0, engine_free, conn);
52
+
53
+ conn->read = BIO_new(BIO_s_mem());
54
+ BIO_set_nbio(conn->read, 1);
55
+
56
+ conn->write = BIO_new(BIO_s_mem());
57
+ BIO_set_nbio(conn->write, 1);
58
+
59
+ conn->ssl = 0;
60
+ conn->ctx = 0;
61
+
62
+ return conn;
63
+ }
64
+
65
+ DH *get_dh1024() {
66
+ /* `openssl dhparam 1024 -C`
67
+ * -----BEGIN DH PARAMETERS-----
68
+ * MIGHAoGBALPwcEv0OstmQCZdfHw0N5r+07lmXMxkpQacy1blwj0LUqC+Divp6pBk
69
+ * usTJ9W2/dOYr1X7zi6yXNLp4oLzc/31PUL3D9q8CpGS7vPz5gijKSw9BwCTT5z9+
70
+ * KF9v46qw8XqT5HHV87sWFlGQcVFq+pEkA2kPikkKZ/X/CCcpCAV7AgEC
71
+ * -----END DH PARAMETERS-----
72
+ */
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
85
+ };
86
+ static unsigned char dh1024_g[] = { 0x02 };
87
+
88
+ DH *dh;
89
+ dh = DH_new();
90
+
91
+ #if OPENSSL_VERSION_NUMBER < 0x10100005L
92
+ dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
93
+ dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
94
+
95
+ if ((dh->p == NULL) || (dh->g == NULL)) {
96
+ DH_free(dh);
97
+ return NULL;
98
+ }
99
+ #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);
103
+
104
+ if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) {
105
+ DH_free(dh);
106
+ BN_free(p);
107
+ BN_free(g);
108
+ return NULL;
109
+ }
110
+ #endif
111
+
112
+ return dh;
113
+ }
114
+
115
+ static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
116
+ X509* err_cert;
117
+ SSL* ssl;
118
+ int bytes;
119
+ unsigned char* buf = NULL;
120
+
121
+ if(!preverify_ok) {
122
+ err_cert = X509_STORE_CTX_get_current_cert(ctx);
123
+ if(err_cert) {
124
+ /*
125
+ * Save the failed certificate for inspection/logging.
126
+ */
127
+ bytes = i2d_X509(err_cert, &buf);
128
+ if(bytes > 0) {
129
+ ms_cert_buf* cert_buf = (ms_cert_buf*)malloc(sizeof(ms_cert_buf));
130
+ cert_buf->buf = buf;
131
+ cert_buf->bytes = bytes;
132
+ ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
133
+ SSL_set_app_data(ssl, cert_buf);
134
+ }
135
+ }
136
+ }
137
+
138
+ return preverify_ok;
139
+ }
140
+
141
+ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
142
+ VALUE obj;
143
+ SSL_CTX* ctx;
144
+ SSL* ssl;
145
+
146
+ ms_conn* conn = engine_alloc(self, &obj);
147
+
148
+ ID sym_key = rb_intern("key");
149
+ VALUE key = rb_funcall(mini_ssl_ctx, sym_key, 0);
150
+
151
+ StringValue(key);
152
+
153
+ ID sym_cert = rb_intern("cert");
154
+ VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
155
+
156
+ StringValue(cert);
157
+
158
+ ID sym_ca = rb_intern("ca");
159
+ VALUE ca = rb_funcall(mini_ssl_ctx, sym_ca, 0);
160
+
161
+ ID sym_verify_mode = rb_intern("verify_mode");
162
+ VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
163
+
164
+ ctx = SSL_CTX_new(SSLv23_server_method());
165
+ conn->ctx = ctx;
166
+
167
+ SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
168
+ SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
169
+
170
+ if (!NIL_P(ca)) {
171
+ StringValue(ca);
172
+ SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL);
173
+ }
174
+
175
+ 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);
176
+ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
177
+
178
+ SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
179
+
180
+ DH *dh = get_dh1024();
181
+ SSL_CTX_set_tmp_dh(ctx, dh);
182
+
183
+ #ifndef OPENSSL_NO_ECDH
184
+ EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1);
185
+ if (ecdh) {
186
+ SSL_CTX_set_tmp_ecdh(ctx, ecdh);
187
+ EC_KEY_free(ecdh);
188
+ }
189
+ #endif
190
+
191
+ ssl = SSL_new(ctx);
192
+ conn->ssl = ssl;
193
+ SSL_set_app_data(ssl, NULL);
194
+
195
+ if (NIL_P(verify_mode)) {
196
+ /* SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); */
197
+ } else {
198
+ SSL_set_verify(ssl, NUM2INT(verify_mode), engine_verify_callback);
199
+ }
200
+
201
+ SSL_set_bio(ssl, conn->read, conn->write);
202
+
203
+ SSL_set_accept_state(ssl);
204
+ return obj;
205
+ }
206
+
207
+ VALUE engine_init_client(VALUE klass) {
208
+ VALUE obj;
209
+ ms_conn* conn = engine_alloc(klass, &obj);
210
+
211
+ conn->ctx = SSL_CTX_new(DTLSv1_method());
212
+ conn->ssl = SSL_new(conn->ctx);
213
+ SSL_set_app_data(conn->ssl, NULL);
214
+ SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
215
+
216
+ SSL_set_bio(conn->ssl, conn->read, conn->write);
217
+
218
+ SSL_set_connect_state(conn->ssl);
219
+ return obj;
220
+ }
221
+
222
+ VALUE engine_inject(VALUE self, VALUE str) {
223
+ ms_conn* conn;
224
+ long used;
225
+
226
+ Data_Get_Struct(self, ms_conn, conn);
227
+
228
+ StringValue(str);
229
+
230
+ used = BIO_write(conn->read, RSTRING_PTR(str), (int)RSTRING_LEN(str));
231
+
232
+ if(used == 0 || used == -1) {
233
+ return Qfalse;
234
+ }
235
+
236
+ return INT2FIX(used);
237
+ }
238
+
239
+ static VALUE eError;
240
+
241
+ void raise_error(SSL* ssl, int result) {
242
+ char buf[512];
243
+ char msg[512];
244
+ const char* err_str;
245
+ int err = errno;
246
+ int ssl_err = SSL_get_error(ssl, result);
247
+ int verify_err = SSL_get_verify_result(ssl);
248
+
249
+ if(SSL_ERROR_SYSCALL == ssl_err) {
250
+ snprintf(msg, sizeof(msg), "System error: %s - %d", strerror(err), err);
251
+
252
+ } else if(SSL_ERROR_SSL == ssl_err) {
253
+ if(X509_V_OK != verify_err) {
254
+ err_str = X509_verify_cert_error_string(verify_err);
255
+ snprintf(msg, sizeof(msg),
256
+ "OpenSSL certificate verification error: %s - %d",
257
+ err_str, verify_err);
258
+
259
+ } else {
260
+ err = ERR_get_error();
261
+ ERR_error_string_n(err, buf, sizeof(buf));
262
+ snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err);
263
+
264
+ }
265
+ } else {
266
+ snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err);
267
+ }
268
+
269
+ ERR_clear_error();
270
+ rb_raise(eError, "%s", msg);
271
+ }
272
+
273
+ VALUE engine_read(VALUE self) {
274
+ ms_conn* conn;
275
+ char buf[512];
276
+ int bytes, error;
277
+
278
+ Data_Get_Struct(self, ms_conn, conn);
279
+
280
+ ERR_clear_error();
281
+
282
+ bytes = SSL_read(conn->ssl, (void*)buf, sizeof(buf));
283
+
284
+ if(bytes > 0) {
285
+ return rb_str_new(buf, bytes);
286
+ }
287
+
288
+ if(SSL_want_read(conn->ssl)) return Qnil;
289
+
290
+ error = SSL_get_error(conn->ssl, bytes);
291
+
292
+ if(error == SSL_ERROR_ZERO_RETURN) {
293
+ rb_eof_error();
294
+ } else {
295
+ raise_error(conn->ssl, bytes);
296
+ }
297
+
298
+ return Qnil;
299
+ }
300
+
301
+ VALUE engine_write(VALUE self, VALUE str) {
302
+ ms_conn* conn;
303
+ int bytes;
304
+
305
+ Data_Get_Struct(self, ms_conn, conn);
306
+
307
+ StringValue(str);
308
+
309
+ ERR_clear_error();
310
+
311
+ bytes = SSL_write(conn->ssl, (void*)RSTRING_PTR(str), (int)RSTRING_LEN(str));
312
+ if(bytes > 0) {
313
+ return INT2FIX(bytes);
314
+ }
315
+
316
+ if(SSL_want_write(conn->ssl)) return Qnil;
317
+
318
+ raise_error(conn->ssl, bytes);
319
+
320
+ return Qnil;
321
+ }
322
+
323
+ VALUE engine_extract(VALUE self) {
324
+ ms_conn* conn;
325
+ int bytes;
326
+ size_t pending;
327
+ char buf[512];
328
+
329
+ Data_Get_Struct(self, ms_conn, conn);
330
+
331
+ pending = BIO_pending(conn->write);
332
+ if(pending > 0) {
333
+ bytes = BIO_read(conn->write, buf, sizeof(buf));
334
+ if(bytes > 0) {
335
+ return rb_str_new(buf, bytes);
336
+ } else if(!BIO_should_retry(conn->write)) {
337
+ raise_error(conn->ssl, bytes);
338
+ }
339
+ }
340
+
341
+ return Qnil;
342
+ }
343
+
344
+ VALUE engine_shutdown(VALUE self) {
345
+ ms_conn* conn;
346
+ int ok;
347
+
348
+ Data_Get_Struct(self, ms_conn, conn);
349
+
350
+ ERR_clear_error();
351
+
352
+ ok = SSL_shutdown(conn->ssl);
353
+ if (ok == 0) {
354
+ return Qfalse;
355
+ }
356
+
357
+ return Qtrue;
358
+ }
359
+
360
+ VALUE engine_init(VALUE self) {
361
+ ms_conn* conn;
362
+
363
+ Data_Get_Struct(self, ms_conn, conn);
364
+
365
+ return SSL_in_init(conn->ssl) ? Qtrue : Qfalse;
366
+ }
367
+
368
+ VALUE engine_peercert(VALUE self) {
369
+ ms_conn* conn;
370
+ X509* cert;
371
+ int bytes;
372
+ unsigned char* buf = NULL;
373
+ ms_cert_buf* cert_buf = NULL;
374
+ VALUE rb_cert_buf;
375
+
376
+ Data_Get_Struct(self, ms_conn, conn);
377
+
378
+ cert = SSL_get_peer_certificate(conn->ssl);
379
+ if(!cert) {
380
+ /*
381
+ * See if there was a failed certificate associated with this client.
382
+ */
383
+ cert_buf = (ms_cert_buf*)SSL_get_app_data(conn->ssl);
384
+ if(!cert_buf) {
385
+ return Qnil;
386
+ }
387
+ buf = cert_buf->buf;
388
+ bytes = cert_buf->bytes;
389
+
390
+ } else {
391
+ bytes = i2d_X509(cert, &buf);
392
+ X509_free(cert);
393
+
394
+ if(bytes < 0) {
395
+ return Qnil;
396
+ }
397
+ }
398
+
399
+ rb_cert_buf = rb_str_new((const char*)(buf), bytes);
400
+ if(!cert_buf) {
401
+ OPENSSL_free(buf);
402
+ }
403
+
404
+ return rb_cert_buf;
405
+ }
406
+
407
+ VALUE noop(VALUE self) {
408
+ return Qnil;
409
+ }
410
+
411
+ void Init_mini_ssl(VALUE puma) {
412
+ VALUE mod, eng;
413
+
414
+ SSL_library_init();
415
+ OpenSSL_add_ssl_algorithms();
416
+ SSL_load_error_strings();
417
+ ERR_load_crypto_strings();
418
+
419
+ mod = rb_define_module_under(puma, "MiniSSL");
420
+ eng = rb_define_class_under(mod, "Engine", rb_cObject);
421
+
422
+ rb_define_singleton_method(mod, "check", noop, 0);
423
+
424
+ eError = rb_define_class_under(mod, "SSLError", rb_eStandardError);
425
+
426
+ rb_define_singleton_method(eng, "server", engine_init_server, 1);
427
+ rb_define_singleton_method(eng, "client", engine_init_client, 0);
428
+
429
+ rb_define_method(eng, "inject", engine_inject, 1);
430
+ rb_define_method(eng, "read", engine_read, 0);
431
+
432
+ rb_define_method(eng, "write", engine_write, 1);
433
+ rb_define_method(eng, "extract", engine_extract, 0);
434
+
435
+ rb_define_method(eng, "shutdown", engine_shutdown, 0);
436
+
437
+ rb_define_method(eng, "init?", engine_init, 0);
438
+
439
+ rb_define_method(eng, "peercert", engine_peercert, 0);
440
+ }
441
+
442
+ #else
443
+
444
+ VALUE raise_error(VALUE self) {
445
+ rb_raise(rb_eStandardError, "SSL not available in this build");
446
+ return Qnil;
447
+ }
448
+
449
+ void Init_mini_ssl(VALUE puma) {
450
+ VALUE mod, eng;
451
+
452
+ mod = rb_define_module_under(puma, "MiniSSL");
453
+ rb_define_class_under(mod, "SSLError", rb_eStandardError);
454
+
455
+ rb_define_singleton_method(mod, "check", raise_error, 0);
456
+ }
457
+ #endif