puma 4.3.12 → 5.6.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +1526 -524
- data/LICENSE +23 -20
- data/README.md +120 -36
- data/bin/puma-wild +3 -9
- data/docs/architecture.md +63 -26
- data/docs/compile_options.md +21 -0
- data/docs/deployment.md +60 -69
- data/docs/fork_worker.md +33 -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 +9 -0
- data/{tools → docs}/jungle/rc.d/README.md +1 -1
- data/{tools → docs}/jungle/rc.d/puma +2 -2
- data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +66 -0
- data/docs/nginx.md +1 -1
- data/docs/plugins.md +15 -15
- data/docs/rails_dev_mode.md +28 -0
- data/docs/restart.md +46 -23
- data/docs/signals.md +13 -11
- data/docs/stats.md +142 -0
- data/docs/systemd.md +85 -128
- data/ext/puma_http11/PumaHttp11Service.java +2 -4
- data/ext/puma_http11/ext_help.h +1 -1
- data/ext/puma_http11/extconf.rb +44 -10
- data/ext/puma_http11/http11_parser.c +45 -47
- data/ext/puma_http11/http11_parser.h +1 -1
- data/ext/puma_http11/http11_parser.java.rl +1 -1
- data/ext/puma_http11/http11_parser.rl +1 -1
- data/ext/puma_http11/http11_parser_common.rl +0 -0
- data/ext/puma_http11/mini_ssl.c +225 -89
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +5 -3
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +3 -5
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +109 -67
- data/ext/puma_http11/puma_http11.c +32 -51
- data/lib/puma/app/status.rb +50 -36
- data/lib/puma/binder.rb +225 -106
- data/lib/puma/cli.rb +24 -18
- data/lib/puma/client.rb +146 -84
- data/lib/puma/cluster/worker.rb +173 -0
- data/lib/puma/cluster/worker_handle.rb +94 -0
- data/lib/puma/cluster.rb +212 -220
- data/lib/puma/commonlogger.rb +2 -2
- data/lib/puma/configuration.rb +58 -49
- data/lib/puma/const.rb +22 -7
- data/lib/puma/control_cli.rb +99 -76
- data/lib/puma/detect.rb +29 -2
- data/lib/puma/dsl.rb +368 -96
- data/lib/puma/error_logger.rb +104 -0
- data/lib/puma/events.rb +55 -34
- data/lib/puma/io_buffer.rb +9 -2
- data/lib/puma/jruby_restart.rb +0 -58
- data/lib/puma/json_serialization.rb +96 -0
- data/lib/puma/launcher.rb +128 -46
- data/lib/puma/minissl/context_builder.rb +14 -9
- data/lib/puma/minissl.rb +137 -50
- data/lib/puma/null_io.rb +18 -1
- data/lib/puma/plugin/tmp_restart.rb +0 -0
- data/lib/puma/plugin.rb +3 -12
- data/lib/puma/queue_close.rb +26 -0
- data/lib/puma/rack/builder.rb +1 -5
- data/lib/puma/rack/urlmap.rb +0 -0
- data/lib/puma/rack_default.rb +0 -0
- data/lib/puma/reactor.rb +85 -369
- data/lib/puma/request.rb +489 -0
- data/lib/puma/runner.rb +46 -61
- data/lib/puma/server.rb +292 -763
- data/lib/puma/single.rb +9 -65
- data/lib/puma/state_file.rb +48 -8
- data/lib/puma/systemd.rb +46 -0
- data/lib/puma/thread_pool.rb +125 -57
- data/lib/puma/util.rb +32 -4
- data/lib/puma.rb +48 -0
- data/lib/rack/handler/puma.rb +2 -3
- data/lib/rack/version_restriction.rb +15 -0
- data/tools/{docker/Dockerfile → Dockerfile} +1 -1
- data/tools/trickletest.rb +0 -0
- metadata +29 -24
- data/docs/tcp_mode.md +0 -96
- data/ext/puma_http11/io_buffer.c +0 -155
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -72
- data/lib/puma/accept_nonblock.rb +0 -29
- data/lib/puma/tcp_logger.rb +0 -41
- data/tools/jungle/README.md +0 -19
- data/tools/jungle/init.d/README.md +0 -61
- data/tools/jungle/init.d/puma +0 -421
- data/tools/jungle/init.d/run-puma +0 -18
- data/tools/jungle/upstart/README.md +0 -61
- data/tools/jungle/upstart/puma-manager.conf +0 -31
- data/tools/jungle/upstart/puma.conf +0 -69
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -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,16 @@ typedef struct {
|
|
33
28
|
int bytes;
|
34
29
|
} ms_cert_buf;
|
35
30
|
|
36
|
-
|
31
|
+
VALUE eError;
|
32
|
+
|
33
|
+
NORETURN(void raise_file_error(const char* caller, const char *filename));
|
34
|
+
|
35
|
+
void raise_file_error(const char* caller, const char *filename) {
|
36
|
+
rb_raise(eError, "%s: error in file '%s': %s", caller, filename, ERR_error_string(ERR_get_error(), NULL));
|
37
|
+
}
|
38
|
+
|
39
|
+
void engine_free(void *ptr) {
|
40
|
+
ms_conn *conn = ptr;
|
37
41
|
ms_cert_buf* cert_buf = (ms_cert_buf*)SSL_get_app_data(conn->ssl);
|
38
42
|
if(cert_buf) {
|
39
43
|
OPENSSL_free(cert_buf->buf);
|
@@ -45,23 +49,13 @@ void engine_free(ms_conn* conn) {
|
|
45
49
|
free(conn);
|
46
50
|
}
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
}
|
52
|
+
const rb_data_type_t engine_data_type = {
|
53
|
+
"MiniSSL/ENGINE",
|
54
|
+
{ 0, engine_free, 0 },
|
55
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
56
|
+
};
|
64
57
|
|
58
|
+
#ifndef HAVE_SSL_CTX_SET_DH_AUTO
|
65
59
|
DH *get_dh2048(void) {
|
66
60
|
/* `openssl dhparam -C 2048`
|
67
61
|
* -----BEGIN DH PARAMETERS-----
|
@@ -104,13 +98,13 @@ DH *get_dh2048(void) {
|
|
104
98
|
static unsigned char dh2048_g[] = { 0x02 };
|
105
99
|
|
106
100
|
DH *dh;
|
107
|
-
#if !(OPENSSL_VERSION_NUMBER < 0x10100005L
|
101
|
+
#if !(OPENSSL_VERSION_NUMBER < 0x10100005L)
|
108
102
|
BIGNUM *p, *g;
|
109
103
|
#endif
|
110
104
|
|
111
105
|
dh = DH_new();
|
112
106
|
|
113
|
-
#if OPENSSL_VERSION_NUMBER < 0x10100005L
|
107
|
+
#if OPENSSL_VERSION_NUMBER < 0x10100005L
|
114
108
|
dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
|
115
109
|
dh->g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
|
116
110
|
|
@@ -132,6 +126,38 @@ DH *get_dh2048(void) {
|
|
132
126
|
|
133
127
|
return dh;
|
134
128
|
}
|
129
|
+
#endif
|
130
|
+
|
131
|
+
static void
|
132
|
+
sslctx_free(void *ptr) {
|
133
|
+
SSL_CTX *ctx = ptr;
|
134
|
+
SSL_CTX_free(ctx);
|
135
|
+
}
|
136
|
+
|
137
|
+
static const rb_data_type_t sslctx_type = {
|
138
|
+
"MiniSSL/SSLContext",
|
139
|
+
{
|
140
|
+
0, sslctx_free,
|
141
|
+
},
|
142
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
143
|
+
};
|
144
|
+
|
145
|
+
ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
|
146
|
+
ms_conn* conn;
|
147
|
+
|
148
|
+
*obj = TypedData_Make_Struct(klass, ms_conn, &engine_data_type, conn);
|
149
|
+
|
150
|
+
conn->read = BIO_new(BIO_s_mem());
|
151
|
+
BIO_set_nbio(conn->read, 1);
|
152
|
+
|
153
|
+
conn->write = BIO_new(BIO_s_mem());
|
154
|
+
BIO_set_nbio(conn->write, 1);
|
155
|
+
|
156
|
+
conn->ssl = 0;
|
157
|
+
conn->ctx = 0;
|
158
|
+
|
159
|
+
return conn;
|
160
|
+
}
|
135
161
|
|
136
162
|
static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
|
137
163
|
X509* err_cert;
|
@@ -159,52 +185,118 @@ static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
|
|
159
185
|
return preverify_ok;
|
160
186
|
}
|
161
187
|
|
162
|
-
|
163
|
-
|
188
|
+
static VALUE
|
189
|
+
sslctx_alloc(VALUE klass) {
|
190
|
+
SSL_CTX *ctx;
|
191
|
+
long mode = 0 |
|
192
|
+
SSL_MODE_ENABLE_PARTIAL_WRITE |
|
193
|
+
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
|
194
|
+
SSL_MODE_RELEASE_BUFFERS;
|
195
|
+
|
196
|
+
#ifdef HAVE_TLS_SERVER_METHOD
|
197
|
+
ctx = SSL_CTX_new(TLS_method());
|
198
|
+
// printf("\nctx using TLS_method security_level %d\n", SSL_CTX_get_security_level(ctx));
|
199
|
+
#else
|
200
|
+
ctx = SSL_CTX_new(SSLv23_method());
|
201
|
+
#endif
|
202
|
+
if (!ctx) {
|
203
|
+
rb_raise(eError, "SSL_CTX_new");
|
204
|
+
}
|
205
|
+
SSL_CTX_set_mode(ctx, mode);
|
206
|
+
|
207
|
+
return TypedData_Wrap_Struct(klass, &sslctx_type, ctx);
|
208
|
+
}
|
209
|
+
|
210
|
+
VALUE
|
211
|
+
sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
164
212
|
SSL_CTX* ctx;
|
165
|
-
SSL* ssl;
|
166
|
-
int min, ssl_options;
|
167
213
|
|
168
|
-
|
214
|
+
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
215
|
+
int min;
|
216
|
+
#endif
|
217
|
+
int ssl_options;
|
218
|
+
VALUE key, cert, ca, verify_mode, ssl_cipher_filter, no_tlsv1, no_tlsv1_1,
|
219
|
+
verification_flags, session_id_bytes, cert_pem, key_pem;
|
220
|
+
#ifndef HAVE_SSL_CTX_SET_DH_AUTO
|
221
|
+
DH *dh;
|
222
|
+
#endif
|
223
|
+
BIO *bio;
|
224
|
+
X509 *x509;
|
225
|
+
EVP_PKEY *pkey;
|
169
226
|
|
170
|
-
|
171
|
-
|
227
|
+
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
228
|
+
EC_KEY *ecdh;
|
229
|
+
#endif
|
172
230
|
|
173
|
-
|
231
|
+
TypedData_Get_Struct(self, SSL_CTX, &sslctx_type, ctx);
|
174
232
|
|
175
|
-
|
176
|
-
VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
|
233
|
+
key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
|
177
234
|
|
178
|
-
|
235
|
+
cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
|
179
236
|
|
180
|
-
|
181
|
-
VALUE ca = rb_funcall(mini_ssl_ctx, sym_ca, 0);
|
237
|
+
ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
|
182
238
|
|
183
|
-
|
184
|
-
VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
|
239
|
+
cert_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("cert_pem"), 0);
|
185
240
|
|
186
|
-
|
187
|
-
VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
|
241
|
+
key_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("key_pem"), 0);
|
188
242
|
|
189
|
-
|
190
|
-
VALUE no_tlsv1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1, 0);
|
243
|
+
verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0);
|
191
244
|
|
192
|
-
|
193
|
-
VALUE no_tlsv1_1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1_1, 0);
|
245
|
+
ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0);
|
194
246
|
|
195
|
-
|
196
|
-
ctx = SSL_CTX_new(TLS_server_method());
|
197
|
-
#else
|
198
|
-
ctx = SSL_CTX_new(SSLv23_server_method());
|
199
|
-
#endif
|
200
|
-
conn->ctx = ctx;
|
247
|
+
no_tlsv1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1"), 0);
|
201
248
|
|
202
|
-
|
203
|
-
|
249
|
+
no_tlsv1_1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1_1"), 0);
|
250
|
+
|
251
|
+
if (!NIL_P(cert)) {
|
252
|
+
StringValue(cert);
|
253
|
+
|
254
|
+
if (SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert)) != 1) {
|
255
|
+
raise_file_error("SSL_CTX_use_certificate_chain_file", RSTRING_PTR(cert));
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
if (!NIL_P(key)) {
|
260
|
+
StringValue(key);
|
261
|
+
|
262
|
+
if (SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM) != 1) {
|
263
|
+
raise_file_error("SSL_CTX_use_PrivateKey_file", RSTRING_PTR(key));
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
if (!NIL_P(cert_pem)) {
|
268
|
+
bio = BIO_new(BIO_s_mem());
|
269
|
+
BIO_puts(bio, RSTRING_PTR(cert_pem));
|
270
|
+
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
271
|
+
|
272
|
+
if (SSL_CTX_use_certificate(ctx, x509) != 1) {
|
273
|
+
raise_file_error("SSL_CTX_use_certificate", RSTRING_PTR(cert_pem));
|
274
|
+
}
|
275
|
+
}
|
276
|
+
|
277
|
+
if (!NIL_P(key_pem)) {
|
278
|
+
bio = BIO_new(BIO_s_mem());
|
279
|
+
BIO_puts(bio, RSTRING_PTR(key_pem));
|
280
|
+
pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
281
|
+
|
282
|
+
if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) {
|
283
|
+
raise_file_error("SSL_CTX_use_PrivateKey", RSTRING_PTR(key_pem));
|
284
|
+
}
|
285
|
+
}
|
286
|
+
|
287
|
+
verification_flags = rb_funcall(mini_ssl_ctx, rb_intern_const("verification_flags"), 0);
|
288
|
+
|
289
|
+
if (!NIL_P(verification_flags)) {
|
290
|
+
X509_VERIFY_PARAM *param = SSL_CTX_get0_param(ctx);
|
291
|
+
X509_VERIFY_PARAM_set_flags(param, NUM2INT(verification_flags));
|
292
|
+
SSL_CTX_set1_param(ctx, param);
|
293
|
+
}
|
204
294
|
|
205
295
|
if (!NIL_P(ca)) {
|
206
296
|
StringValue(ca);
|
207
|
-
SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL)
|
297
|
+
if (SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL) != 1) {
|
298
|
+
raise_file_error("SSL_CTX_load_verify_locations", RSTRING_PTR(ca));
|
299
|
+
}
|
208
300
|
}
|
209
301
|
|
210
302
|
ssl_options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION;
|
@@ -247,6 +339,24 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
247
339
|
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
248
340
|
}
|
249
341
|
|
342
|
+
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
343
|
+
// Remove this case if OpenSSL 1.0.1 (now EOL) support is no
|
344
|
+
// longer needed.
|
345
|
+
ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
346
|
+
if (ecdh) {
|
347
|
+
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
|
348
|
+
EC_KEY_free(ecdh);
|
349
|
+
}
|
350
|
+
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
351
|
+
SSL_CTX_set_ecdh_auto(ctx, 1);
|
352
|
+
#endif
|
353
|
+
|
354
|
+
if (NIL_P(verify_mode)) {
|
355
|
+
/* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */
|
356
|
+
} else {
|
357
|
+
SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
|
358
|
+
}
|
359
|
+
|
250
360
|
// Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
|
251
361
|
session_id_bytes = rb_funcall(
|
252
362
|
#ifdef HAVE_RANDOM_BYTES
|
@@ -261,35 +371,34 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
261
371
|
(unsigned char *) RSTRING_PTR(session_id_bytes),
|
262
372
|
SSL_MAX_SSL_SESSION_ID_LENGTH);
|
263
373
|
|
264
|
-
|
265
|
-
SSL_CTX_set_tmp_dh(ctx, dh);
|
374
|
+
// printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx));
|
266
375
|
|
267
|
-
#
|
268
|
-
//
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
EC_KEY_free(ecdh);
|
274
|
-
}
|
275
|
-
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
276
|
-
// Prior to OpenSSL 1.1.0, servers must manually enable server-side ECDH
|
277
|
-
// negotiation.
|
278
|
-
SSL_CTX_set_ecdh_auto(ctx, 1);
|
376
|
+
#ifdef HAVE_SSL_CTX_SET_DH_AUTO
|
377
|
+
// https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_dh_auto.html
|
378
|
+
SSL_CTX_set_dh_auto(ctx, 1);
|
379
|
+
#else
|
380
|
+
dh = get_dh2048();
|
381
|
+
SSL_CTX_set_tmp_dh(ctx, dh);
|
279
382
|
#endif
|
280
383
|
|
384
|
+
rb_obj_freeze(self);
|
385
|
+
return self;
|
386
|
+
}
|
387
|
+
|
388
|
+
VALUE engine_init_server(VALUE self, VALUE sslctx) {
|
389
|
+
ms_conn* conn;
|
390
|
+
VALUE obj;
|
391
|
+
SSL_CTX* ctx;
|
392
|
+
SSL* ssl;
|
393
|
+
|
394
|
+
conn = engine_alloc(self, &obj);
|
395
|
+
|
396
|
+
TypedData_Get_Struct(sslctx, SSL_CTX, &sslctx_type, ctx);
|
397
|
+
|
281
398
|
ssl = SSL_new(ctx);
|
282
399
|
conn->ssl = ssl;
|
283
400
|
SSL_set_app_data(ssl, NULL);
|
284
|
-
|
285
|
-
if (NIL_P(verify_mode)) {
|
286
|
-
/* SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); */
|
287
|
-
} else {
|
288
|
-
SSL_set_verify(ssl, NUM2INT(verify_mode), engine_verify_callback);
|
289
|
-
}
|
290
|
-
|
291
401
|
SSL_set_bio(ssl, conn->read, conn->write);
|
292
|
-
|
293
402
|
SSL_set_accept_state(ssl);
|
294
403
|
return obj;
|
295
404
|
}
|
@@ -316,7 +425,7 @@ VALUE engine_inject(VALUE self, VALUE str) {
|
|
316
425
|
ms_conn* conn;
|
317
426
|
long used;
|
318
427
|
|
319
|
-
|
428
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
320
429
|
|
321
430
|
StringValue(str);
|
322
431
|
|
@@ -329,13 +438,14 @@ VALUE engine_inject(VALUE self, VALUE str) {
|
|
329
438
|
return INT2FIX(used);
|
330
439
|
}
|
331
440
|
|
332
|
-
|
441
|
+
NORETURN(void raise_error(SSL* ssl, int result));
|
333
442
|
|
334
443
|
void raise_error(SSL* ssl, int result) {
|
335
444
|
char buf[512];
|
336
445
|
char msg[512];
|
337
446
|
const char* err_str;
|
338
447
|
int err = errno;
|
448
|
+
int mask = 4095;
|
339
449
|
int ssl_err = SSL_get_error(ssl, result);
|
340
450
|
int verify_err = (int) SSL_get_verify_result(ssl);
|
341
451
|
|
@@ -352,8 +462,7 @@ void raise_error(SSL* ssl, int result) {
|
|
352
462
|
} else {
|
353
463
|
err = (int) ERR_get_error();
|
354
464
|
ERR_error_string_n(err, buf, sizeof(buf));
|
355
|
-
snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err);
|
356
|
-
|
465
|
+
snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err & mask);
|
357
466
|
}
|
358
467
|
} else {
|
359
468
|
snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err);
|
@@ -368,7 +477,7 @@ VALUE engine_read(VALUE self) {
|
|
368
477
|
char buf[512];
|
369
478
|
int bytes, error;
|
370
479
|
|
371
|
-
|
480
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
372
481
|
|
373
482
|
ERR_clear_error();
|
374
483
|
|
@@ -395,7 +504,7 @@ VALUE engine_write(VALUE self, VALUE str) {
|
|
395
504
|
ms_conn* conn;
|
396
505
|
int bytes;
|
397
506
|
|
398
|
-
|
507
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
399
508
|
|
400
509
|
StringValue(str);
|
401
510
|
|
@@ -417,9 +526,11 @@ VALUE engine_extract(VALUE self) {
|
|
417
526
|
ms_conn* conn;
|
418
527
|
int bytes;
|
419
528
|
size_t pending;
|
420
|
-
|
529
|
+
// https://www.openssl.org/docs/manmaster/man3/BIO_f_buffer.html
|
530
|
+
// crypto/bio/bf_buff.c DEFAULT_BUFFER_SIZE
|
531
|
+
char buf[4096];
|
421
532
|
|
422
|
-
|
533
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
423
534
|
|
424
535
|
pending = BIO_pending(conn->write);
|
425
536
|
if(pending > 0) {
|
@@ -438,7 +549,7 @@ VALUE engine_shutdown(VALUE self) {
|
|
438
549
|
ms_conn* conn;
|
439
550
|
int ok;
|
440
551
|
|
441
|
-
|
552
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
442
553
|
|
443
554
|
ERR_clear_error();
|
444
555
|
|
@@ -453,7 +564,7 @@ VALUE engine_shutdown(VALUE self) {
|
|
453
564
|
VALUE engine_init(VALUE self) {
|
454
565
|
ms_conn* conn;
|
455
566
|
|
456
|
-
|
567
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
457
568
|
|
458
569
|
return SSL_in_init(conn->ssl) ? Qtrue : Qfalse;
|
459
570
|
}
|
@@ -466,9 +577,13 @@ VALUE engine_peercert(VALUE self) {
|
|
466
577
|
ms_cert_buf* cert_buf = NULL;
|
467
578
|
VALUE rb_cert_buf;
|
468
579
|
|
469
|
-
|
580
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
470
581
|
|
582
|
+
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
583
|
+
cert = SSL_get1_peer_certificate(conn->ssl);
|
584
|
+
#else
|
471
585
|
cert = SSL_get_peer_certificate(conn->ssl);
|
586
|
+
#endif
|
472
587
|
if(!cert) {
|
473
588
|
/*
|
474
589
|
* See if there was a failed certificate associated with this client.
|
@@ -497,12 +612,22 @@ VALUE engine_peercert(VALUE self) {
|
|
497
612
|
return rb_cert_buf;
|
498
613
|
}
|
499
614
|
|
615
|
+
/* @see Puma::MiniSSL::Socket#ssl_version_state
|
616
|
+
* @version 5.0.0
|
617
|
+
*/
|
618
|
+
static VALUE
|
619
|
+
engine_ssl_vers_st(VALUE self) {
|
620
|
+
ms_conn* conn;
|
621
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
622
|
+
return rb_ary_new3(2, rb_str_new2(SSL_get_version(conn->ssl)), rb_str_new2(SSL_state_string(conn->ssl)));
|
623
|
+
}
|
624
|
+
|
500
625
|
VALUE noop(VALUE self) {
|
501
626
|
return Qnil;
|
502
627
|
}
|
503
628
|
|
504
629
|
void Init_mini_ssl(VALUE puma) {
|
505
|
-
VALUE mod, eng;
|
630
|
+
VALUE mod, eng, sslctx;
|
506
631
|
|
507
632
|
/* Fake operation for documentation (RDoc, YARD) */
|
508
633
|
#if 0 == 1
|
@@ -515,7 +640,15 @@ void Init_mini_ssl(VALUE puma) {
|
|
515
640
|
ERR_load_crypto_strings();
|
516
641
|
|
517
642
|
mod = rb_define_module_under(puma, "MiniSSL");
|
643
|
+
|
518
644
|
eng = rb_define_class_under(mod, "Engine", rb_cObject);
|
645
|
+
rb_undef_alloc_func(eng);
|
646
|
+
|
647
|
+
sslctx = rb_define_class_under(mod, "SSLContext", rb_cObject);
|
648
|
+
rb_define_alloc_func(sslctx, sslctx_alloc);
|
649
|
+
rb_define_method(sslctx, "initialize", sslctx_initialize, 1);
|
650
|
+
rb_undef_method(sslctx, "initialize_copy");
|
651
|
+
|
519
652
|
|
520
653
|
// OpenSSL Build / Runtime/Load versions
|
521
654
|
|
@@ -568,13 +701,16 @@ void Init_mini_ssl(VALUE puma) {
|
|
568
701
|
rb_define_method(eng, "init?", engine_init, 0);
|
569
702
|
|
570
703
|
rb_define_method(eng, "peercert", engine_peercert, 0);
|
704
|
+
|
705
|
+
rb_define_method(eng, "ssl_vers_st", engine_ssl_vers_st, 0);
|
571
706
|
}
|
572
707
|
|
573
708
|
#else
|
574
709
|
|
710
|
+
NORETURN(VALUE raise_error(VALUE self));
|
711
|
+
|
575
712
|
VALUE raise_error(VALUE self) {
|
576
713
|
rb_raise(rb_eStandardError, "SSL not available in this build");
|
577
|
-
return Qnil;
|
578
714
|
}
|
579
715
|
|
580
716
|
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
|
+
}
|
@@ -30,8 +30,8 @@ public class Http11 extends RubyObject {
|
|
30
30
|
public final static String MAX_REQUEST_URI_LENGTH_ERR = "HTTP element REQUEST_URI is longer than the 12288 allowed length.";
|
31
31
|
public final static int MAX_FRAGMENT_LENGTH = 1024;
|
32
32
|
public final static String MAX_FRAGMENT_LENGTH_ERR = "HTTP element REQUEST_PATH is longer than the 1024 allowed length.";
|
33
|
-
public final static int MAX_REQUEST_PATH_LENGTH =
|
34
|
-
public final static String MAX_REQUEST_PATH_LENGTH_ERR = "HTTP element REQUEST_PATH is longer than the
|
33
|
+
public final static int MAX_REQUEST_PATH_LENGTH = 8192;
|
34
|
+
public final static String MAX_REQUEST_PATH_LENGTH_ERR = "HTTP element REQUEST_PATH is longer than the 8192 allowed length.";
|
35
35
|
public final static int MAX_QUERY_STRING_LENGTH = 1024 * 10;
|
36
36
|
public final static String MAX_QUERY_STRING_LENGTH_ERR = "HTTP element QUERY_STRING is longer than the 10240 allowed length.";
|
37
37
|
public final static int MAX_HEADER_LENGTH = 1024 * (80 + 32);
|
@@ -99,6 +99,8 @@ public class Http11 extends RubyObject {
|
|
99
99
|
int bite = b.get(i) & 0xFF;
|
100
100
|
if(bite == '-') {
|
101
101
|
b.set(i, (byte)'_');
|
102
|
+
} else if(bite == '_') {
|
103
|
+
b.set(i, (byte)',');
|
102
104
|
} else {
|
103
105
|
b.set(i, (byte)Character.toUpperCase(bite));
|
104
106
|
}
|
@@ -197,7 +199,7 @@ public class Http11 extends RubyObject {
|
|
197
199
|
validateMaxLength(runtime, parser.nread,MAX_HEADER_LENGTH, MAX_HEADER_LENGTH_ERR);
|
198
200
|
|
199
201
|
if(hp.has_error()) {
|
200
|
-
throw newHTTPParserError(runtime, "Invalid HTTP format, parsing fails.");
|
202
|
+
throw newHTTPParserError(runtime, "Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?");
|
201
203
|
} else {
|
202
204
|
return runtime.newFixnum(parser.nread);
|
203
205
|
}
|
@@ -184,8 +184,6 @@ static final int puma_parser_start = 1;
|
|
184
184
|
static final int puma_parser_first_final = 46;
|
185
185
|
static final int puma_parser_error = 0;
|
186
186
|
|
187
|
-
static final int puma_parser_en_main = 1;
|
188
|
-
|
189
187
|
|
190
188
|
// line 62 "ext/puma_http11/http11_parser.java.rl"
|
191
189
|
|
@@ -214,7 +212,7 @@ static final int puma_parser_en_main = 1;
|
|
214
212
|
cs = 0;
|
215
213
|
|
216
214
|
|
217
|
-
// line
|
215
|
+
// line 216 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
218
216
|
{
|
219
217
|
cs = puma_parser_start;
|
220
218
|
}
|
@@ -246,7 +244,7 @@ static final int puma_parser_en_main = 1;
|
|
246
244
|
parser.buffer = buffer;
|
247
245
|
|
248
246
|
|
249
|
-
// line
|
247
|
+
// line 248 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
250
248
|
{
|
251
249
|
int _klen;
|
252
250
|
int _trans = 0;
|
@@ -402,7 +400,7 @@ case 1:
|
|
402
400
|
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
|
403
401
|
}
|
404
402
|
break;
|
405
|
-
// line
|
403
|
+
// line 404 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
406
404
|
}
|
407
405
|
}
|
408
406
|
}
|