puma 3.12.2 → 4.2.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.
- checksums.yaml +4 -4
- data/History.md +106 -6
- data/README.md +91 -43
- data/docs/architecture.md +1 -0
- data/docs/deployment.md +24 -4
- 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/plugins.md +20 -10
- data/docs/restart.md +4 -2
- data/docs/systemd.md +27 -9
- data/ext/puma_http11/PumaHttp11Service.java +2 -0
- data/ext/puma_http11/extconf.rb +8 -0
- data/ext/puma_http11/http11_parser.c +37 -62
- data/ext/puma_http11/http11_parser_common.rl +3 -3
- data/ext/puma_http11/mini_ssl.c +78 -8
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +72 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +15 -4
- data/lib/puma.rb +8 -0
- data/lib/puma/accept_nonblock.rb +7 -1
- data/lib/puma/app/status.rb +35 -29
- data/lib/puma/binder.rb +39 -5
- data/lib/puma/cli.rb +4 -0
- data/lib/puma/client.rb +221 -199
- data/lib/puma/cluster.rb +53 -30
- data/lib/puma/configuration.rb +4 -3
- data/lib/puma/const.rb +22 -25
- data/lib/puma/control_cli.rb +21 -4
- data/lib/puma/dsl.rb +297 -75
- data/lib/puma/events.rb +4 -1
- data/lib/puma/io_buffer.rb +1 -6
- data/lib/puma/launcher.rb +95 -53
- data/lib/puma/minissl.rb +35 -17
- data/lib/puma/plugin.rb +5 -2
- data/lib/puma/plugin/tmp_restart.rb +2 -0
- data/lib/puma/rack/builder.rb +2 -0
- data/lib/puma/rack/urlmap.rb +2 -0
- data/lib/puma/rack_default.rb +2 -0
- data/lib/puma/reactor.rb +109 -57
- data/lib/puma/runner.rb +4 -3
- data/lib/puma/server.rb +59 -62
- data/lib/puma/single.rb +3 -3
- data/lib/puma/thread_pool.rb +14 -32
- data/lib/puma/util.rb +1 -6
- data/lib/rack/handler/puma.rb +3 -3
- data/tools/docker/Dockerfile +16 -0
- data/tools/jungle/init.d/puma +6 -6
- data/tools/trickletest.rb +0 -1
- metadata +20 -8
- data/lib/puma/compat.rb +0 -14
- data/lib/puma/daemon_ext.rb +0 -33
- data/lib/puma/delegation.rb +0 -13
- data/lib/puma/java_io_buffer.rb +0 -47
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
Binary file
|
Binary file
|
Binary file
|
data/docs/plugins.md
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
## Plugins
|
2
2
|
|
3
|
-
Puma 3.0 added support for plugins that can augment configuration and service
|
3
|
+
Puma 3.0 added support for plugins that can augment configuration and service
|
4
|
+
operations.
|
4
5
|
|
5
6
|
2 canonical plugins to look to aid in development of further plugins:
|
6
7
|
|
7
|
-
* [tmp\_restart](https://github.com/puma/puma/blob/master/lib/puma/plugin/tmp_restart.rb):
|
8
|
-
|
8
|
+
* [tmp\_restart](https://github.com/puma/puma/blob/master/lib/puma/plugin/tmp_restart.rb):
|
9
|
+
Restarts the server if the file `tmp/restart.txt` is touched
|
10
|
+
* [heroku](https://github.com/puma/puma-heroku/blob/master/lib/puma/plugin/heroku.rb):
|
11
|
+
Packages up the default configuration used by puma on Heroku
|
9
12
|
|
10
|
-
Plugins are activated in a puma configuration file (such as `config/puma.rb'`)
|
13
|
+
Plugins are activated in a puma configuration file (such as `config/puma.rb'`)
|
14
|
+
by adding `plugin "name"`, such as `plugin "heroku"`.
|
11
15
|
|
12
|
-
Plugins are activated based simply on path requirements so, activating the
|
16
|
+
Plugins are activated based simply on path requirements so, activating the
|
17
|
+
`heroku` plugin will simply be doing `require "puma/plugin/heroku"`. This
|
18
|
+
allows gems to provide multiple plugins (as well as unrelated gems to provide
|
19
|
+
puma plugins).
|
13
20
|
|
14
21
|
The `tmp_restart` plugin is bundled with puma, so it can always be used.
|
15
22
|
|
@@ -17,12 +24,15 @@ To use the `heroku` plugin, add `puma-heroku` to your Gemfile or install it.
|
|
17
24
|
|
18
25
|
### API
|
19
26
|
|
20
|
-
|
27
|
+
## Server-wide hooks
|
21
28
|
|
22
|
-
|
29
|
+
Plugins can use a couple of hooks at server level: `start` and `config`.
|
23
30
|
|
24
|
-
`
|
31
|
+
`start` runs when the server has started and allows the plugin to start other
|
32
|
+
functionality to augment puma.
|
25
33
|
|
26
|
-
|
34
|
+
`config` runs when the server is being configured and is passed a `Puma::DSL`
|
35
|
+
object that can be used to add additional configuration.
|
27
36
|
|
28
|
-
|
37
|
+
Any public methods in `Puma::Plugin` are the public API that any plugin may
|
38
|
+
use.
|
data/docs/restart.md
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
To perform a restart, there are 3 builtin mechanisms:
|
4
4
|
|
5
|
-
* Send the `puma` process the `SIGUSR2` signal
|
6
|
-
* Send the `puma` process the `SIGUSR1` signal (rolling restart, cluster mode only)
|
5
|
+
* Send the `puma` process the `SIGUSR2` signal (normal restart)
|
6
|
+
* Send the `puma` process the `SIGUSR1` signal (restart in phases (a "rolling restart"), cluster mode only)
|
7
7
|
* Use the status server and issue `/restart`
|
8
8
|
|
9
9
|
No code is shared between the current and restarted process, so it should be safe to issue a restart any place where you would manually stop Puma and start it again.
|
@@ -22,6 +22,8 @@ But again beware, upgrading an application sometimes involves upgrading the data
|
|
22
22
|
|
23
23
|
If you perform a lot of database migrations, you probably should not use phased restart and use a normal/hot restart instead (`pumactl restart`). That way, no code is shared while deploying (in that case, `preload_app!` might help for quicker deployment, see ["Clustered Mode" in the README](../README.md#clustered-mode)).
|
24
24
|
|
25
|
+
**Note**: Hot and phased restarts are only available on MRI, not on JRuby. They are also unavailable on Windows servers.
|
26
|
+
|
25
27
|
### Release Directory
|
26
28
|
|
27
29
|
If your symlink releases into a common working directory (i.e., `/current` from Capistrano), Puma won't pick up your new changes when running phased restarts without additional configuration. You should set your working directory within Puma's config to specify the directory it should use. This is a change from earlier versions of Puma (< 2.15) that would infer the directory for you.
|
data/docs/systemd.md
CHANGED
@@ -32,21 +32,26 @@ Type=simple
|
|
32
32
|
# Preferably configure a non-privileged user
|
33
33
|
# User=
|
34
34
|
|
35
|
-
# The path to the
|
36
|
-
# Also replace the "<
|
37
|
-
|
35
|
+
# The path to the your application code root directory.
|
36
|
+
# Also replace the "<YOUR_APP_PATH>" place holders below with this path.
|
37
|
+
# Example /home/username/myapp
|
38
|
+
WorkingDirectory=<YOUR_APP_PATH>
|
38
39
|
|
39
40
|
# Helpful for debugging socket activation, etc.
|
40
41
|
# Environment=PUMA_DEBUG=1
|
41
42
|
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
ExecStart
|
43
|
+
# SystemD will not run puma even if it is in your path. You must specify
|
44
|
+
# an absolute URL to puma. For example /usr/local/bin/puma
|
45
|
+
# Alternatively, create a binstub with `bundle binstubs puma --path ./sbin` in the WorkingDirectory
|
46
|
+
ExecStart=/<FULLPATH>/bin/puma -C <YOUR_APP_PATH>/puma.rb
|
47
|
+
|
48
|
+
# Variant: Rails start.
|
49
|
+
# ExecStart=/<FULLPATH>/bin/puma -C <YOUR_APP_PATH>/config/puma.rb ../config.ru
|
46
50
|
|
47
|
-
# Variant: Use config file with `bind` directives instead:
|
48
|
-
# ExecStart=<WD>/sbin/puma -C config.rb
|
49
51
|
# Variant: Use `bundle exec --keep-file-descriptors puma` instead of binstub
|
52
|
+
# Variant: Specify directives inline.
|
53
|
+
# ExecStart=/<FULLPATH>/puma -b tcp://0.0.0.0:9292 -b ssl://0.0.0.0:9293?key=key.pem&cert=cert.pem
|
54
|
+
|
50
55
|
|
51
56
|
Restart=always
|
52
57
|
|
@@ -66,6 +71,13 @@ listening sockets open across puma restarts and achieves graceful
|
|
66
71
|
restarts, including when upgraded puma, and is compatible with both
|
67
72
|
clustered mode and application preload.
|
68
73
|
|
74
|
+
**Note:** Any wrapper scripts which `exec`, or other indirections in
|
75
|
+
`ExecStart`, may result in activated socket file descriptors being closed
|
76
|
+
before they reach the puma master process. For example, if using `bundle exec`,
|
77
|
+
pass the `--keep-file-descriptors` flag. `bundle exec` can be avoided by using a
|
78
|
+
`puma` executable generated by `bundle binstubs puma`. This is tracked in
|
79
|
+
[#1499].
|
80
|
+
|
69
81
|
**Note:** Socket activation doesn't currently work on jruby. This is
|
70
82
|
tracked in [#1367].
|
71
83
|
|
@@ -247,6 +259,12 @@ PIDFile=
|
|
247
259
|
# reconsider if you actually need the forking config.
|
248
260
|
Restart=no
|
249
261
|
|
262
|
+
# `puma_ctl restart` wouldn't work without this. It's because `pumactl`
|
263
|
+
# changes PID on restart and systemd stops the service afterwards
|
264
|
+
# because of the PID change. This option prevents stopping after PID
|
265
|
+
# change.
|
266
|
+
RemainAfterExit=yes
|
267
|
+
|
250
268
|
[Install]
|
251
269
|
WantedBy=multi-user.target
|
252
270
|
~~~~
|
@@ -6,11 +6,13 @@ import org.jruby.Ruby;
|
|
6
6
|
import org.jruby.runtime.load.BasicLibraryService;
|
7
7
|
|
8
8
|
import org.jruby.puma.Http11;
|
9
|
+
import org.jruby.puma.IOBuffer;
|
9
10
|
import org.jruby.puma.MiniSSL;
|
10
11
|
|
11
12
|
public class PumaHttp11Service implements BasicLibraryService {
|
12
13
|
public boolean basicLoad(final Ruby runtime) throws IOException {
|
13
14
|
Http11.createHttp11(runtime);
|
15
|
+
IOBuffer.createIOBuffer(runtime);
|
14
16
|
MiniSSL.createMiniSSL(runtime);
|
15
17
|
return true;
|
16
18
|
}
|
data/ext/puma_http11/extconf.rb
CHANGED
@@ -9,6 +9,14 @@ unless ENV["DISABLE_SSL"]
|
|
9
9
|
%w'ssl ssleay32'.find {|ssl| have_library(ssl, 'SSL_CTX_new')}
|
10
10
|
|
11
11
|
have_header "openssl/bio.h"
|
12
|
+
|
13
|
+
# below is yes for 1.0.2 & later
|
14
|
+
have_func "DTLS_method" , "openssl/ssl.h"
|
15
|
+
|
16
|
+
# below are yes for 1.1.0 & later, may need to check func rather than macro
|
17
|
+
# with versions after 1.1.1
|
18
|
+
have_func "TLS_server_method" , "openssl/ssl.h"
|
19
|
+
have_macro "SSL_CTX_set_min_proto_version", "openssl/ssl.h"
|
12
20
|
end
|
13
21
|
end
|
14
22
|
|
@@ -38,7 +38,7 @@ static void snake_upcase_char(char *c)
|
|
38
38
|
|
39
39
|
#line 40 "ext/puma_http11/http11_parser.c"
|
40
40
|
static const int puma_parser_start = 1;
|
41
|
-
static const int puma_parser_first_final =
|
41
|
+
static const int puma_parser_first_final = 46;
|
42
42
|
static const int puma_parser_error = 0;
|
43
43
|
|
44
44
|
static const int puma_parser_en_main = 1;
|
@@ -117,17 +117,17 @@ case 2:
|
|
117
117
|
#line 118 "ext/puma_http11/http11_parser.c"
|
118
118
|
switch( (*p) ) {
|
119
119
|
case 32: goto tr2;
|
120
|
-
case 36: goto
|
121
|
-
case 95: goto
|
120
|
+
case 36: goto st27;
|
121
|
+
case 95: goto st27;
|
122
122
|
}
|
123
123
|
if ( (*p) < 48 ) {
|
124
124
|
if ( 45 <= (*p) && (*p) <= 46 )
|
125
|
-
goto
|
125
|
+
goto st27;
|
126
126
|
} else if ( (*p) > 57 ) {
|
127
127
|
if ( 65 <= (*p) && (*p) <= 90 )
|
128
|
-
goto
|
128
|
+
goto st27;
|
129
129
|
} else
|
130
|
-
goto
|
130
|
+
goto st27;
|
131
131
|
goto st0;
|
132
132
|
tr2:
|
133
133
|
#line 48 "ext/puma_http11/http11_parser.rl"
|
@@ -199,7 +199,7 @@ tr37:
|
|
199
199
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
200
200
|
}
|
201
201
|
goto st5;
|
202
|
-
|
202
|
+
tr41:
|
203
203
|
#line 58 "ext/puma_http11/http11_parser.rl"
|
204
204
|
{ MARK(query_start, p); }
|
205
205
|
#line 59 "ext/puma_http11/http11_parser.rl"
|
@@ -211,7 +211,7 @@ tr44:
|
|
211
211
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
212
212
|
}
|
213
213
|
goto st5;
|
214
|
-
|
214
|
+
tr44:
|
215
215
|
#line 59 "ext/puma_http11/http11_parser.rl"
|
216
216
|
{
|
217
217
|
parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p));
|
@@ -362,13 +362,13 @@ tr22:
|
|
362
362
|
{
|
363
363
|
parser->body_start = p - buffer + 1;
|
364
364
|
parser->header_done(parser, p + 1, pe - p - 1);
|
365
|
-
{p++; cs =
|
365
|
+
{p++; cs = 46; goto _out;}
|
366
366
|
}
|
367
|
-
goto
|
368
|
-
|
367
|
+
goto st46;
|
368
|
+
st46:
|
369
369
|
if ( ++p == pe )
|
370
|
-
goto
|
371
|
-
case
|
370
|
+
goto _test_eof46;
|
371
|
+
case 46:
|
372
372
|
#line 373 "ext/puma_http11/http11_parser.c"
|
373
373
|
goto st0;
|
374
374
|
tr21:
|
@@ -458,7 +458,7 @@ tr38:
|
|
458
458
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
459
459
|
}
|
460
460
|
goto st20;
|
461
|
-
|
461
|
+
tr42:
|
462
462
|
#line 58 "ext/puma_http11/http11_parser.rl"
|
463
463
|
{ MARK(query_start, p); }
|
464
464
|
#line 59 "ext/puma_http11/http11_parser.rl"
|
@@ -470,7 +470,7 @@ tr45:
|
|
470
470
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
471
471
|
}
|
472
472
|
goto st20;
|
473
|
-
|
473
|
+
tr45:
|
474
474
|
#line 59 "ext/puma_http11/http11_parser.rl"
|
475
475
|
{
|
476
476
|
parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p));
|
@@ -576,10 +576,9 @@ case 24:
|
|
576
576
|
case 32: goto tr37;
|
577
577
|
case 34: goto st0;
|
578
578
|
case 35: goto tr38;
|
579
|
-
case 59: goto tr39;
|
580
579
|
case 60: goto st0;
|
581
580
|
case 62: goto st0;
|
582
|
-
case 63: goto
|
581
|
+
case 63: goto tr39;
|
583
582
|
case 127: goto st0;
|
584
583
|
}
|
585
584
|
if ( 0 <= (*p) && (*p) <= 31 )
|
@@ -595,30 +594,27 @@ st25:
|
|
595
594
|
if ( ++p == pe )
|
596
595
|
goto _test_eof25;
|
597
596
|
case 25:
|
598
|
-
#line
|
597
|
+
#line 598 "ext/puma_http11/http11_parser.c"
|
599
598
|
switch( (*p) ) {
|
600
|
-
case 32: goto
|
599
|
+
case 32: goto tr41;
|
601
600
|
case 34: goto st0;
|
602
|
-
case 35: goto
|
601
|
+
case 35: goto tr42;
|
603
602
|
case 60: goto st0;
|
604
603
|
case 62: goto st0;
|
605
|
-
case 63: goto st26;
|
606
604
|
case 127: goto st0;
|
607
605
|
}
|
608
606
|
if ( 0 <= (*p) && (*p) <= 31 )
|
609
607
|
goto st0;
|
610
|
-
goto
|
608
|
+
goto tr40;
|
611
609
|
tr40:
|
612
|
-
#line
|
613
|
-
{
|
614
|
-
parser->request_path(parser, PTR_TO(mark), LEN(mark,p));
|
615
|
-
}
|
610
|
+
#line 58 "ext/puma_http11/http11_parser.rl"
|
611
|
+
{ MARK(query_start, p); }
|
616
612
|
goto st26;
|
617
613
|
st26:
|
618
614
|
if ( ++p == pe )
|
619
615
|
goto _test_eof26;
|
620
616
|
case 26:
|
621
|
-
#line
|
617
|
+
#line 618 "ext/puma_http11/http11_parser.c"
|
622
618
|
switch( (*p) ) {
|
623
619
|
case 32: goto tr44;
|
624
620
|
case 34: goto st0;
|
@@ -629,27 +625,25 @@ case 26:
|
|
629
625
|
}
|
630
626
|
if ( 0 <= (*p) && (*p) <= 31 )
|
631
627
|
goto st0;
|
632
|
-
goto
|
633
|
-
tr43:
|
634
|
-
#line 58 "ext/puma_http11/http11_parser.rl"
|
635
|
-
{ MARK(query_start, p); }
|
636
|
-
goto st27;
|
628
|
+
goto st26;
|
637
629
|
st27:
|
638
630
|
if ( ++p == pe )
|
639
631
|
goto _test_eof27;
|
640
632
|
case 27:
|
641
|
-
#line 642 "ext/puma_http11/http11_parser.c"
|
642
633
|
switch( (*p) ) {
|
643
|
-
case 32: goto
|
644
|
-
case
|
645
|
-
case
|
646
|
-
case 60: goto st0;
|
647
|
-
case 62: goto st0;
|
648
|
-
case 127: goto st0;
|
634
|
+
case 32: goto tr2;
|
635
|
+
case 36: goto st28;
|
636
|
+
case 95: goto st28;
|
649
637
|
}
|
650
|
-
if (
|
651
|
-
|
652
|
-
|
638
|
+
if ( (*p) < 48 ) {
|
639
|
+
if ( 45 <= (*p) && (*p) <= 46 )
|
640
|
+
goto st28;
|
641
|
+
} else if ( (*p) > 57 ) {
|
642
|
+
if ( 65 <= (*p) && (*p) <= 90 )
|
643
|
+
goto st28;
|
644
|
+
} else
|
645
|
+
goto st28;
|
646
|
+
goto st0;
|
653
647
|
st28:
|
654
648
|
if ( ++p == pe )
|
655
649
|
goto _test_eof28;
|
@@ -960,24 +954,6 @@ st45:
|
|
960
954
|
if ( ++p == pe )
|
961
955
|
goto _test_eof45;
|
962
956
|
case 45:
|
963
|
-
switch( (*p) ) {
|
964
|
-
case 32: goto tr2;
|
965
|
-
case 36: goto st46;
|
966
|
-
case 95: goto st46;
|
967
|
-
}
|
968
|
-
if ( (*p) < 48 ) {
|
969
|
-
if ( 45 <= (*p) && (*p) <= 46 )
|
970
|
-
goto st46;
|
971
|
-
} else if ( (*p) > 57 ) {
|
972
|
-
if ( 65 <= (*p) && (*p) <= 90 )
|
973
|
-
goto st46;
|
974
|
-
} else
|
975
|
-
goto st46;
|
976
|
-
goto st0;
|
977
|
-
st46:
|
978
|
-
if ( ++p == pe )
|
979
|
-
goto _test_eof46;
|
980
|
-
case 46:
|
981
957
|
if ( (*p) == 32 )
|
982
958
|
goto tr2;
|
983
959
|
goto st0;
|
@@ -997,7 +973,7 @@ case 46:
|
|
997
973
|
_test_eof14: cs = 14; goto _test_eof;
|
998
974
|
_test_eof15: cs = 15; goto _test_eof;
|
999
975
|
_test_eof16: cs = 16; goto _test_eof;
|
1000
|
-
|
976
|
+
_test_eof46: cs = 46; goto _test_eof;
|
1001
977
|
_test_eof17: cs = 17; goto _test_eof;
|
1002
978
|
_test_eof18: cs = 18; goto _test_eof;
|
1003
979
|
_test_eof19: cs = 19; goto _test_eof;
|
@@ -1027,7 +1003,6 @@ case 46:
|
|
1027
1003
|
_test_eof43: cs = 43; goto _test_eof;
|
1028
1004
|
_test_eof44: cs = 44; goto _test_eof;
|
1029
1005
|
_test_eof45: cs = 45; goto _test_eof;
|
1030
|
-
_test_eof46: cs = 46; goto _test_eof;
|
1031
1006
|
|
1032
1007
|
_test_eof: {}
|
1033
1008
|
_out: {}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
%%{
|
2
|
-
|
2
|
+
|
3
3
|
machine puma_parser_common;
|
4
4
|
|
5
5
|
#### HTTP PROTOCOL GRAMMAR
|
@@ -16,7 +16,7 @@
|
|
16
16
|
unreserved = (alpha | digit | safe | extra | national);
|
17
17
|
escape = ("%" xdigit xdigit);
|
18
18
|
uchar = (unreserved | escape | "%");
|
19
|
-
pchar = (uchar | ":" | "@" | "&" | "=" | "+");
|
19
|
+
pchar = (uchar | ":" | "@" | "&" | "=" | "+" | ";");
|
20
20
|
tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t");
|
21
21
|
|
22
22
|
# elements
|
@@ -30,7 +30,7 @@
|
|
30
30
|
query = ( uchar | reserved )* %query_string ;
|
31
31
|
param = ( pchar | "/" )* ;
|
32
32
|
params = ( param ( ";" param )* ) ;
|
33
|
-
rel_path = ( path? %request_path
|
33
|
+
rel_path = ( path? %request_path ) ("?" %start_query query)?;
|
34
34
|
absolute_path = ( "/"+ rel_path );
|
35
35
|
|
36
36
|
Request_URI = ( "*" | absolute_uri | absolute_path ) >mark %request_uri;
|
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -142,6 +142,7 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
142
142
|
VALUE obj;
|
143
143
|
SSL_CTX* ctx;
|
144
144
|
SSL* ssl;
|
145
|
+
int min, ssl_options;
|
145
146
|
|
146
147
|
ms_conn* conn = engine_alloc(self, &obj);
|
147
148
|
|
@@ -164,7 +165,17 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
164
165
|
ID sym_ssl_cipher_filter = rb_intern("ssl_cipher_filter");
|
165
166
|
VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
|
166
167
|
|
168
|
+
ID sym_no_tlsv1 = rb_intern("no_tlsv1");
|
169
|
+
VALUE no_tlsv1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1, 0);
|
170
|
+
|
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);
|
173
|
+
|
174
|
+
#ifdef HAVE_TLS_SERVER_METHOD
|
175
|
+
ctx = SSL_CTX_new(TLS_server_method());
|
176
|
+
#else
|
167
177
|
ctx = SSL_CTX_new(SSLv23_server_method());
|
178
|
+
#endif
|
168
179
|
conn->ctx = ctx;
|
169
180
|
|
170
181
|
SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
|
@@ -175,7 +186,36 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
175
186
|
SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL);
|
176
187
|
}
|
177
188
|
|
178
|
-
|
189
|
+
ssl_options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION;
|
190
|
+
|
191
|
+
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
192
|
+
if (RTEST(no_tlsv1_1)) {
|
193
|
+
min = TLS1_2_VERSION;
|
194
|
+
}
|
195
|
+
else if (RTEST(no_tlsv1)) {
|
196
|
+
min = TLS1_1_VERSION;
|
197
|
+
}
|
198
|
+
else {
|
199
|
+
min = TLS1_VERSION;
|
200
|
+
}
|
201
|
+
|
202
|
+
SSL_CTX_set_min_proto_version(ctx, min);
|
203
|
+
|
204
|
+
SSL_CTX_set_options(ctx, ssl_options);
|
205
|
+
|
206
|
+
#else
|
207
|
+
/* As of 1.0.2f, SSL_OP_SINGLE_DH_USE key use is always on */
|
208
|
+
ssl_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE;
|
209
|
+
|
210
|
+
if (RTEST(no_tlsv1)) {
|
211
|
+
ssl_options |= SSL_OP_NO_TLSv1;
|
212
|
+
}
|
213
|
+
if(RTEST(no_tlsv1_1)) {
|
214
|
+
ssl_options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
|
215
|
+
}
|
216
|
+
SSL_CTX_set_options(ctx, ssl_options);
|
217
|
+
#endif
|
218
|
+
|
179
219
|
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
|
180
220
|
|
181
221
|
if (!NIL_P(ssl_cipher_filter)) {
|
@@ -189,12 +229,18 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
189
229
|
DH *dh = get_dh1024();
|
190
230
|
SSL_CTX_set_tmp_dh(ctx, dh);
|
191
231
|
|
192
|
-
#
|
193
|
-
|
232
|
+
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
233
|
+
// Remove this case if OpenSSL 1.0.1 (now EOL) support is no
|
234
|
+
// longer needed.
|
235
|
+
EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
194
236
|
if (ecdh) {
|
195
237
|
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
|
196
238
|
EC_KEY_free(ecdh);
|
197
239
|
}
|
240
|
+
#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
|
+
SSL_CTX_set_ecdh_auto(ctx, 1);
|
198
244
|
#endif
|
199
245
|
|
200
246
|
ssl = SSL_new(ctx);
|
@@ -216,8 +262,11 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
216
262
|
VALUE engine_init_client(VALUE klass) {
|
217
263
|
VALUE obj;
|
218
264
|
ms_conn* conn = engine_alloc(klass, &obj);
|
219
|
-
|
265
|
+
#ifdef HAVE_DTLS_METHOD
|
266
|
+
conn->ctx = SSL_CTX_new(DTLS_method());
|
267
|
+
#else
|
220
268
|
conn->ctx = SSL_CTX_new(DTLSv1_method());
|
269
|
+
#endif
|
221
270
|
conn->ssl = SSL_new(conn->ctx);
|
222
271
|
SSL_set_app_data(conn->ssl, NULL);
|
223
272
|
SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
|
@@ -436,14 +485,35 @@ void Init_mini_ssl(VALUE puma) {
|
|
436
485
|
// OpenSSL Build / Runtime/Load versions
|
437
486
|
|
438
487
|
/* Version of OpenSSL that Puma was compiled with */
|
439
|
-
|
488
|
+
rb_define_const(mod, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
|
440
489
|
|
441
490
|
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
|
442
|
-
|
443
|
-
|
491
|
+
/* Version of OpenSSL that Puma loaded with */
|
492
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
|
444
493
|
#else
|
445
|
-
|
494
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
|
446
495
|
#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
|
447
517
|
|
448
518
|
rb_define_singleton_method(mod, "check", noop, 0);
|
449
519
|
|