puma 3.8.2 → 4.3.12
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 +5 -5
- data/History.md +305 -0
- data/LICENSE +0 -0
- data/README.md +162 -224
- data/bin/puma-wild +0 -0
- data/docs/architecture.md +37 -0
- data/{DEPLOYMENT.md → 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/nginx.md +0 -0
- data/docs/plugins.md +38 -0
- data/docs/restart.md +41 -0
- data/docs/signals.md +56 -3
- data/docs/systemd.md +130 -37
- data/docs/tcp_mode.md +96 -0
- data/ext/puma_http11/PumaHttp11Service.java +2 -0
- data/ext/puma_http11/ext_help.h +0 -0
- data/ext/puma_http11/extconf.rb +21 -0
- data/ext/puma_http11/http11_parser.c +134 -144
- data/ext/puma_http11/http11_parser.h +0 -0
- data/ext/puma_http11/http11_parser.java.rl +21 -37
- data/ext/puma_http11/http11_parser.rl +12 -10
- data/ext/puma_http11/http11_parser_common.rl +4 -4
- data/ext/puma_http11/io_buffer.c +0 -0
- data/ext/puma_http11/mini_ssl.c +165 -34
- data/ext/puma_http11/org/jruby/puma/Http11.java +106 -114
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +85 -101
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +72 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +30 -6
- data/ext/puma_http11/puma_http11.c +3 -0
- data/lib/puma/accept_nonblock.rb +7 -1
- data/lib/puma/app/status.rb +42 -26
- data/lib/puma/binder.rb +57 -74
- data/lib/puma/cli.rb +26 -7
- data/lib/puma/client.rb +307 -191
- data/lib/puma/cluster.rb +78 -34
- data/lib/puma/commonlogger.rb +2 -0
- data/lib/puma/configuration.rb +24 -16
- data/lib/puma/const.rb +41 -20
- data/lib/puma/control_cli.rb +46 -19
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +329 -68
- data/lib/puma/events.rb +6 -2
- data/lib/puma/io_buffer.rb +3 -6
- data/lib/puma/jruby_restart.rb +2 -1
- data/lib/puma/launcher.rb +125 -61
- data/lib/puma/minissl/context_builder.rb +76 -0
- data/lib/puma/minissl.rb +85 -28
- data/lib/puma/null_io.rb +2 -0
- data/lib/puma/plugin/tmp_restart.rb +2 -1
- data/lib/puma/plugin.rb +7 -2
- data/lib/puma/rack/builder.rb +4 -1
- data/lib/puma/rack/urlmap.rb +2 -0
- data/lib/puma/rack_default.rb +2 -0
- data/lib/puma/reactor.rb +224 -34
- data/lib/puma/runner.rb +27 -6
- data/lib/puma/server.rb +212 -68
- data/lib/puma/single.rb +16 -5
- data/lib/puma/state_file.rb +2 -0
- data/lib/puma/tcp_logger.rb +2 -0
- data/lib/puma/thread_pool.rb +67 -36
- data/lib/puma/util.rb +2 -6
- data/lib/puma.rb +16 -0
- data/lib/rack/handler/puma.rb +16 -5
- data/tools/docker/Dockerfile +16 -0
- data/tools/jungle/README.md +12 -2
- data/tools/jungle/init.d/README.md +2 -0
- data/tools/jungle/init.d/puma +8 -8
- data/tools/jungle/init.d/run-puma +1 -1
- data/tools/jungle/rc.d/README.md +74 -0
- data/tools/jungle/rc.d/puma +61 -0
- data/tools/jungle/rc.d/puma.conf +10 -0
- data/tools/jungle/upstart/README.md +0 -0
- data/tools/jungle/upstart/puma-manager.conf +0 -0
- data/tools/jungle/upstart/puma.conf +0 -0
- data/tools/trickletest.rb +1 -2
- metadata +32 -93
- data/.github/issue_template.md +0 -20
- data/Gemfile +0 -12
- data/Manifest.txt +0 -78
- data/Rakefile +0 -158
- data/Release.md +0 -9
- data/gemfiles/2.1-Gemfile +0 -12
- data/lib/puma/compat.rb +0 -14
- data/lib/puma/convenient.rb +0 -23
- data/lib/puma/daemon_ext.rb +0 -31
- data/lib/puma/delegation.rb +0 -11
- data/lib/puma/java_io_buffer.rb +0 -45
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
- data/puma.gemspec +0 -52
@@ -1,5 +1,7 @@
|
|
1
1
|
package org.jruby.puma;
|
2
2
|
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyHash;
|
3
5
|
import org.jruby.util.ByteList;
|
4
6
|
|
5
7
|
public class Http11Parser {
|
@@ -19,44 +21,35 @@ public class Http11Parser {
|
|
19
21
|
}
|
20
22
|
|
21
23
|
action start_value { parser.mark = fpc; }
|
22
|
-
action write_value {
|
23
|
-
|
24
|
-
parser.http_field.call(parser.data, parser.field_start, parser.field_len, parser.mark, fpc-parser.mark);
|
25
|
-
}
|
24
|
+
action write_value {
|
25
|
+
Http11.http_field(runtime, parser.data, parser.buffer, parser.field_start, parser.field_len, parser.mark, fpc-parser.mark);
|
26
26
|
}
|
27
|
-
action request_method {
|
28
|
-
|
29
|
-
parser.request_method.call(parser.data, parser.mark, fpc-parser.mark);
|
27
|
+
action request_method {
|
28
|
+
Http11.request_method(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
|
30
29
|
}
|
31
|
-
action request_uri {
|
32
|
-
|
33
|
-
parser.request_uri.call(parser.data, parser.mark, fpc-parser.mark);
|
30
|
+
action request_uri {
|
31
|
+
Http11.request_uri(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
|
34
32
|
}
|
35
|
-
action fragment {
|
36
|
-
|
37
|
-
parser.fragment.call(parser.data, parser.mark, fpc-parser.mark);
|
33
|
+
action fragment {
|
34
|
+
Http11.fragment(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
|
38
35
|
}
|
39
36
|
|
40
37
|
action start_query {parser.query_start = fpc; }
|
41
|
-
action query_string {
|
42
|
-
|
43
|
-
parser.query_string.call(parser.data, parser.query_start, fpc-parser.query_start);
|
38
|
+
action query_string {
|
39
|
+
Http11.query_string(runtime, parser.data, parser.buffer, parser.query_start, fpc-parser.query_start);
|
44
40
|
}
|
45
41
|
|
46
|
-
action http_version {
|
47
|
-
|
48
|
-
parser.http_version.call(parser.data, parser.mark, fpc-parser.mark);
|
42
|
+
action http_version {
|
43
|
+
Http11.http_version(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
|
49
44
|
}
|
50
45
|
|
51
46
|
action request_path {
|
52
|
-
|
53
|
-
parser.request_path.call(parser.data, parser.mark, fpc-parser.mark);
|
47
|
+
Http11.request_path(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
|
54
48
|
}
|
55
49
|
|
56
50
|
action done {
|
57
|
-
parser.body_start = fpc + 1;
|
58
|
-
|
59
|
-
parser.header_done.call(parser.data, fpc + 1, pe - fpc - 1);
|
51
|
+
parser.body_start = fpc + 1;
|
52
|
+
http.header_done(runtime, parser.data, parser.buffer, fpc + 1, pe - fpc - 1);
|
60
53
|
fbreak;
|
61
54
|
}
|
62
55
|
|
@@ -68,11 +61,11 @@ public class Http11Parser {
|
|
68
61
|
%% write data;
|
69
62
|
|
70
63
|
public static interface ElementCB {
|
71
|
-
public void call(
|
64
|
+
public void call(Ruby runtime, RubyHash data, ByteList buffer, int at, int length);
|
72
65
|
}
|
73
66
|
|
74
67
|
public static interface FieldCB {
|
75
|
-
public void call(
|
68
|
+
public void call(Ruby runtime, RubyHash data, ByteList buffer, int field, int flen, int value, int vlen);
|
76
69
|
}
|
77
70
|
|
78
71
|
public static class HttpParser {
|
@@ -85,18 +78,9 @@ public class Http11Parser {
|
|
85
78
|
int field_len;
|
86
79
|
int query_start;
|
87
80
|
|
88
|
-
|
81
|
+
RubyHash data;
|
89
82
|
ByteList buffer;
|
90
83
|
|
91
|
-
public FieldCB http_field;
|
92
|
-
public ElementCB request_method;
|
93
|
-
public ElementCB request_uri;
|
94
|
-
public ElementCB fragment;
|
95
|
-
public ElementCB request_path;
|
96
|
-
public ElementCB query_string;
|
97
|
-
public ElementCB http_version;
|
98
|
-
public ElementCB header_done;
|
99
|
-
|
100
84
|
public void init() {
|
101
85
|
cs = 0;
|
102
86
|
|
@@ -113,7 +97,7 @@ public class Http11Parser {
|
|
113
97
|
|
114
98
|
public final HttpParser parser = new HttpParser();
|
115
99
|
|
116
|
-
public int execute(ByteList buffer, int off) {
|
100
|
+
public int execute(Ruby runtime, Http11 http, ByteList buffer, int off) {
|
117
101
|
int p, pe;
|
118
102
|
int cs = parser.cs;
|
119
103
|
int len = buffer.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
|
}
|
@@ -29,7 +31,7 @@ static void snake_upcase_char(char *c)
|
|
29
31
|
/** Machine **/
|
30
32
|
|
31
33
|
%%{
|
32
|
-
|
34
|
+
|
33
35
|
machine puma_parser;
|
34
36
|
|
35
37
|
action mark { MARK(mark, fpc); }
|
@@ -37,7 +39,7 @@ static void snake_upcase_char(char *c)
|
|
37
39
|
|
38
40
|
action start_field { MARK(field_start, fpc); }
|
39
41
|
action snake_upcase_field { snake_upcase_char((char *)fpc); }
|
40
|
-
action write_field {
|
42
|
+
action write_field {
|
41
43
|
parser->field_len = LEN(field_start, fpc);
|
42
44
|
}
|
43
45
|
|
@@ -45,10 +47,10 @@ static void snake_upcase_char(char *c)
|
|
45
47
|
action write_value {
|
46
48
|
parser->http_field(parser, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, fpc));
|
47
49
|
}
|
48
|
-
action request_method {
|
50
|
+
action request_method {
|
49
51
|
parser->request_method(parser, PTR_TO(mark), LEN(mark, fpc));
|
50
52
|
}
|
51
|
-
action request_uri {
|
53
|
+
action request_uri {
|
52
54
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, fpc));
|
53
55
|
}
|
54
56
|
action fragment {
|
@@ -56,11 +58,11 @@ static void snake_upcase_char(char *c)
|
|
56
58
|
}
|
57
59
|
|
58
60
|
action start_query { MARK(query_start, fpc); }
|
59
|
-
action query_string {
|
61
|
+
action query_string {
|
60
62
|
parser->query_string(parser, PTR_TO(query_start), LEN(query_start, fpc));
|
61
63
|
}
|
62
64
|
|
63
|
-
action http_version {
|
65
|
+
action http_version {
|
64
66
|
parser->http_version(parser, PTR_TO(mark), LEN(mark, fpc));
|
65
67
|
}
|
66
68
|
|
@@ -68,8 +70,8 @@ static void snake_upcase_char(char *c)
|
|
68
70
|
parser->request_path(parser, PTR_TO(mark), LEN(mark,fpc));
|
69
71
|
}
|
70
72
|
|
71
|
-
action done {
|
72
|
-
parser->body_start = fpc - buffer + 1;
|
73
|
+
action done {
|
74
|
+
parser->body_start = fpc - buffer + 1;
|
73
75
|
parser->header_done(parser, fpc + 1, pe - fpc - 1);
|
74
76
|
fbreak;
|
75
77
|
}
|
@@ -109,7 +111,7 @@ size_t puma_parser_execute(puma_parser *parser, const char *buffer, size_t len,
|
|
109
111
|
pe = buffer+len;
|
110
112
|
|
111
113
|
/* assert(*pe == '\0' && "pointer does not end on NUL"); */
|
112
|
-
assert(pe - p == len - off && "pointers aren't same distance");
|
114
|
+
assert((size_t) (pe - p) == len - off && "pointers aren't same distance");
|
113
115
|
|
114
116
|
%% write exec;
|
115
117
|
|
@@ -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;
|
@@ -43,7 +43,7 @@
|
|
43
43
|
|
44
44
|
field_name = ( token -- ":" )+ >start_field $snake_upcase_field %write_field;
|
45
45
|
|
46
|
-
field_value = any* >start_value %write_value;
|
46
|
+
field_value = ( (any -- CTL) | "\t" )* >start_value %write_value;
|
47
47
|
|
48
48
|
message_header = field_name ":" " "* field_value :> CRLF;
|
49
49
|
|
data/ext/puma_http11/io_buffer.c
CHANGED
File without changes
|
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -62,44 +62,65 @@ ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
|
|
62
62
|
return conn;
|
63
63
|
}
|
64
64
|
|
65
|
-
DH *
|
66
|
-
/* `openssl dhparam
|
65
|
+
DH *get_dh2048(void) {
|
66
|
+
/* `openssl dhparam -C 2048`
|
67
67
|
* -----BEGIN DH PARAMETERS-----
|
68
|
-
*
|
69
|
-
*
|
70
|
-
*
|
68
|
+
* MIIBCAKCAQEAjmh1uQHdTfxOyxEbKAV30fUfzqMDF/ChPzjfyzl2jcrqQMhrk76o
|
69
|
+
* 2NPNXqxHwsddMZ1RzvU8/jl+uhRuPWjXCFZbhET4N1vrviZM3VJhV8PPHuiVOACO
|
70
|
+
* y32jFd+Szx4bo2cXSK83hJ6jRd+0asP1awWjz9/06dFkrILCXMIfQLo0D8rqmppn
|
71
|
+
* EfDDAwuudCpM9kcDmBRAm9JsKbQ6gzZWjkc5+QWSaQofojIHbjvj3xzguaCJn+oQ
|
72
|
+
* vHWM+hsAnaOgEwCyeZ3xqs+/5lwSbkE/tqJW98cEZGygBUVo9jxZRZx6KOfjpdrb
|
73
|
+
* yenO9LJr/qtyrZB31WJbqxI0m0AKTAO8UwIBAg==
|
71
74
|
* -----END DH PARAMETERS-----
|
72
75
|
*/
|
73
|
-
static unsigned char
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
76
|
+
static unsigned char dh2048_p[] = {
|
77
|
+
0x8E, 0x68, 0x75, 0xB9, 0x01, 0xDD, 0x4D, 0xFC, 0x4E, 0xCB,
|
78
|
+
0x11, 0x1B, 0x28, 0x05, 0x77, 0xD1, 0xF5, 0x1F, 0xCE, 0xA3,
|
79
|
+
0x03, 0x17, 0xF0, 0xA1, 0x3F, 0x38, 0xDF, 0xCB, 0x39, 0x76,
|
80
|
+
0x8D, 0xCA, 0xEA, 0x40, 0xC8, 0x6B, 0x93, 0xBE, 0xA8, 0xD8,
|
81
|
+
0xD3, 0xCD, 0x5E, 0xAC, 0x47, 0xC2, 0xC7, 0x5D, 0x31, 0x9D,
|
82
|
+
0x51, 0xCE, 0xF5, 0x3C, 0xFE, 0x39, 0x7E, 0xBA, 0x14, 0x6E,
|
83
|
+
0x3D, 0x68, 0xD7, 0x08, 0x56, 0x5B, 0x84, 0x44, 0xF8, 0x37,
|
84
|
+
0x5B, 0xEB, 0xBE, 0x26, 0x4C, 0xDD, 0x52, 0x61, 0x57, 0xC3,
|
85
|
+
0xCF, 0x1E, 0xE8, 0x95, 0x38, 0x00, 0x8E, 0xCB, 0x7D, 0xA3,
|
86
|
+
0x15, 0xDF, 0x92, 0xCF, 0x1E, 0x1B, 0xA3, 0x67, 0x17, 0x48,
|
87
|
+
0xAF, 0x37, 0x84, 0x9E, 0xA3, 0x45, 0xDF, 0xB4, 0x6A, 0xC3,
|
88
|
+
0xF5, 0x6B, 0x05, 0xA3, 0xCF, 0xDF, 0xF4, 0xE9, 0xD1, 0x64,
|
89
|
+
0xAC, 0x82, 0xC2, 0x5C, 0xC2, 0x1F, 0x40, 0xBA, 0x34, 0x0F,
|
90
|
+
0xCA, 0xEA, 0x9A, 0x9A, 0x67, 0x11, 0xF0, 0xC3, 0x03, 0x0B,
|
91
|
+
0xAE, 0x74, 0x2A, 0x4C, 0xF6, 0x47, 0x03, 0x98, 0x14, 0x40,
|
92
|
+
0x9B, 0xD2, 0x6C, 0x29, 0xB4, 0x3A, 0x83, 0x36, 0x56, 0x8E,
|
93
|
+
0x47, 0x39, 0xF9, 0x05, 0x92, 0x69, 0x0A, 0x1F, 0xA2, 0x32,
|
94
|
+
0x07, 0x6E, 0x3B, 0xE3, 0xDF, 0x1C, 0xE0, 0xB9, 0xA0, 0x89,
|
95
|
+
0x9F, 0xEA, 0x10, 0xBC, 0x75, 0x8C, 0xFA, 0x1B, 0x00, 0x9D,
|
96
|
+
0xA3, 0xA0, 0x13, 0x00, 0xB2, 0x79, 0x9D, 0xF1, 0xAA, 0xCF,
|
97
|
+
0xBF, 0xE6, 0x5C, 0x12, 0x6E, 0x41, 0x3F, 0xB6, 0xA2, 0x56,
|
98
|
+
0xF7, 0xC7, 0x04, 0x64, 0x6C, 0xA0, 0x05, 0x45, 0x68, 0xF6,
|
99
|
+
0x3C, 0x59, 0x45, 0x9C, 0x7A, 0x28, 0xE7, 0xE3, 0xA5, 0xDA,
|
100
|
+
0xDB, 0xC9, 0xE9, 0xCE, 0xF4, 0xB2, 0x6B, 0xFE, 0xAB, 0x72,
|
101
|
+
0xAD, 0x90, 0x77, 0xD5, 0x62, 0x5B, 0xAB, 0x12, 0x34, 0x9B,
|
102
|
+
0x40, 0x0A, 0x4C, 0x03, 0xBC, 0x53
|
85
103
|
};
|
86
|
-
static unsigned char
|
104
|
+
static unsigned char dh2048_g[] = { 0x02 };
|
87
105
|
|
88
106
|
DH *dh;
|
107
|
+
#if !(OPENSSL_VERSION_NUMBER < 0x10100005L || defined(LIBRESSL_VERSION_NUMBER))
|
108
|
+
BIGNUM *p, *g;
|
109
|
+
#endif
|
110
|
+
|
89
111
|
dh = DH_new();
|
90
112
|
|
91
|
-
#if OPENSSL_VERSION_NUMBER < 0x10100005L
|
92
|
-
dh->p = BN_bin2bn(
|
93
|
-
dh->g = BN_bin2bn(
|
113
|
+
#if OPENSSL_VERSION_NUMBER < 0x10100005L || defined(LIBRESSL_VERSION_NUMBER)
|
114
|
+
dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
|
115
|
+
dh->g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
|
94
116
|
|
95
117
|
if ((dh->p == NULL) || (dh->g == NULL)) {
|
96
118
|
DH_free(dh);
|
97
119
|
return NULL;
|
98
120
|
}
|
99
121
|
#else
|
100
|
-
|
101
|
-
|
102
|
-
g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
|
122
|
+
p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
|
123
|
+
g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
|
103
124
|
|
104
125
|
if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) {
|
105
126
|
DH_free(dh);
|
@@ -139,9 +160,10 @@ static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
|
|
139
160
|
}
|
140
161
|
|
141
162
|
VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
142
|
-
VALUE obj;
|
163
|
+
VALUE obj, session_id_bytes;
|
143
164
|
SSL_CTX* ctx;
|
144
165
|
SSL* ssl;
|
166
|
+
int min, ssl_options;
|
145
167
|
|
146
168
|
ms_conn* conn = engine_alloc(self, &obj);
|
147
169
|
|
@@ -161,7 +183,20 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
161
183
|
ID sym_verify_mode = rb_intern("verify_mode");
|
162
184
|
VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
|
163
185
|
|
186
|
+
ID sym_ssl_cipher_filter = rb_intern("ssl_cipher_filter");
|
187
|
+
VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
|
188
|
+
|
189
|
+
ID sym_no_tlsv1 = rb_intern("no_tlsv1");
|
190
|
+
VALUE no_tlsv1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1, 0);
|
191
|
+
|
192
|
+
ID sym_no_tlsv1_1 = rb_intern("no_tlsv1_1");
|
193
|
+
VALUE no_tlsv1_1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1_1, 0);
|
194
|
+
|
195
|
+
#ifdef HAVE_TLS_SERVER_METHOD
|
196
|
+
ctx = SSL_CTX_new(TLS_server_method());
|
197
|
+
#else
|
164
198
|
ctx = SSL_CTX_new(SSLv23_server_method());
|
199
|
+
#endif
|
165
200
|
conn->ctx = ctx;
|
166
201
|
|
167
202
|
SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
|
@@ -172,20 +207,75 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
172
207
|
SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL);
|
173
208
|
}
|
174
209
|
|
175
|
-
|
210
|
+
ssl_options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION;
|
211
|
+
|
212
|
+
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
213
|
+
if (RTEST(no_tlsv1_1)) {
|
214
|
+
min = TLS1_2_VERSION;
|
215
|
+
}
|
216
|
+
else if (RTEST(no_tlsv1)) {
|
217
|
+
min = TLS1_1_VERSION;
|
218
|
+
}
|
219
|
+
else {
|
220
|
+
min = TLS1_VERSION;
|
221
|
+
}
|
222
|
+
|
223
|
+
SSL_CTX_set_min_proto_version(ctx, min);
|
224
|
+
|
225
|
+
SSL_CTX_set_options(ctx, ssl_options);
|
226
|
+
|
227
|
+
#else
|
228
|
+
/* As of 1.0.2f, SSL_OP_SINGLE_DH_USE key use is always on */
|
229
|
+
ssl_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE;
|
230
|
+
|
231
|
+
if (RTEST(no_tlsv1)) {
|
232
|
+
ssl_options |= SSL_OP_NO_TLSv1;
|
233
|
+
}
|
234
|
+
if(RTEST(no_tlsv1_1)) {
|
235
|
+
ssl_options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
|
236
|
+
}
|
237
|
+
SSL_CTX_set_options(ctx, ssl_options);
|
238
|
+
#endif
|
239
|
+
|
176
240
|
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
|
177
241
|
|
178
|
-
|
242
|
+
if (!NIL_P(ssl_cipher_filter)) {
|
243
|
+
StringValue(ssl_cipher_filter);
|
244
|
+
SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(ssl_cipher_filter));
|
245
|
+
}
|
246
|
+
else {
|
247
|
+
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
248
|
+
}
|
179
249
|
|
180
|
-
|
250
|
+
// Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
|
251
|
+
session_id_bytes = rb_funcall(
|
252
|
+
#ifdef HAVE_RANDOM_BYTES
|
253
|
+
rb_cRandom,
|
254
|
+
#else
|
255
|
+
rb_const_get(rb_cRandom, rb_intern_const("DEFAULT")),
|
256
|
+
#endif
|
257
|
+
rb_intern_const("bytes"),
|
258
|
+
1, ULL2NUM(SSL_MAX_SSL_SESSION_ID_LENGTH));
|
259
|
+
|
260
|
+
SSL_CTX_set_session_id_context(ctx,
|
261
|
+
(unsigned char *) RSTRING_PTR(session_id_bytes),
|
262
|
+
SSL_MAX_SSL_SESSION_ID_LENGTH);
|
263
|
+
|
264
|
+
DH *dh = get_dh2048();
|
181
265
|
SSL_CTX_set_tmp_dh(ctx, dh);
|
182
266
|
|
183
|
-
#
|
184
|
-
|
267
|
+
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
268
|
+
// Remove this case if OpenSSL 1.0.1 (now EOL) support is no
|
269
|
+
// longer needed.
|
270
|
+
EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
185
271
|
if (ecdh) {
|
186
272
|
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
|
187
273
|
EC_KEY_free(ecdh);
|
188
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);
|
189
279
|
#endif
|
190
280
|
|
191
281
|
ssl = SSL_new(ctx);
|
@@ -207,8 +297,11 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
207
297
|
VALUE engine_init_client(VALUE klass) {
|
208
298
|
VALUE obj;
|
209
299
|
ms_conn* conn = engine_alloc(klass, &obj);
|
210
|
-
|
300
|
+
#ifdef HAVE_DTLS_METHOD
|
301
|
+
conn->ctx = SSL_CTX_new(DTLS_method());
|
302
|
+
#else
|
211
303
|
conn->ctx = SSL_CTX_new(DTLSv1_method());
|
304
|
+
#endif
|
212
305
|
conn->ssl = SSL_new(conn->ctx);
|
213
306
|
SSL_set_app_data(conn->ssl, NULL);
|
214
307
|
SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
|
@@ -244,7 +337,7 @@ void raise_error(SSL* ssl, int result) {
|
|
244
337
|
const char* err_str;
|
245
338
|
int err = errno;
|
246
339
|
int ssl_err = SSL_get_error(ssl, result);
|
247
|
-
int verify_err = SSL_get_verify_result(ssl);
|
340
|
+
int verify_err = (int) SSL_get_verify_result(ssl);
|
248
341
|
|
249
342
|
if(SSL_ERROR_SYSCALL == ssl_err) {
|
250
343
|
snprintf(msg, sizeof(msg), "System error: %s - %d", strerror(err), err);
|
@@ -257,7 +350,7 @@ void raise_error(SSL* ssl, int result) {
|
|
257
350
|
err_str, verify_err);
|
258
351
|
|
259
352
|
} else {
|
260
|
-
err = ERR_get_error();
|
353
|
+
err = (int) ERR_get_error();
|
261
354
|
ERR_error_string_n(err, buf, sizeof(buf));
|
262
355
|
snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err);
|
263
356
|
|
@@ -411,6 +504,11 @@ VALUE noop(VALUE self) {
|
|
411
504
|
void Init_mini_ssl(VALUE puma) {
|
412
505
|
VALUE mod, eng;
|
413
506
|
|
507
|
+
/* Fake operation for documentation (RDoc, YARD) */
|
508
|
+
#if 0 == 1
|
509
|
+
puma = rb_define_module("Puma");
|
510
|
+
#endif
|
511
|
+
|
414
512
|
SSL_library_init();
|
415
513
|
OpenSSL_add_ssl_algorithms();
|
416
514
|
SSL_load_error_strings();
|
@@ -419,6 +517,39 @@ void Init_mini_ssl(VALUE puma) {
|
|
419
517
|
mod = rb_define_module_under(puma, "MiniSSL");
|
420
518
|
eng = rb_define_class_under(mod, "Engine", rb_cObject);
|
421
519
|
|
520
|
+
// OpenSSL Build / Runtime/Load versions
|
521
|
+
|
522
|
+
/* Version of OpenSSL that Puma was compiled with */
|
523
|
+
rb_define_const(mod, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
|
524
|
+
|
525
|
+
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
|
526
|
+
/* Version of OpenSSL that Puma loaded with */
|
527
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
|
528
|
+
#else
|
529
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
|
530
|
+
#endif
|
531
|
+
|
532
|
+
#if defined(OPENSSL_NO_SSL3) || defined(OPENSSL_NO_SSL3_METHOD)
|
533
|
+
/* True if SSL3 is not available */
|
534
|
+
rb_define_const(mod, "OPENSSL_NO_SSL3", Qtrue);
|
535
|
+
#else
|
536
|
+
rb_define_const(mod, "OPENSSL_NO_SSL3", Qfalse);
|
537
|
+
#endif
|
538
|
+
|
539
|
+
#if defined(OPENSSL_NO_TLS1) || defined(OPENSSL_NO_TLS1_METHOD)
|
540
|
+
/* True if TLS1 is not available */
|
541
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1", Qtrue);
|
542
|
+
#else
|
543
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1", Qfalse);
|
544
|
+
#endif
|
545
|
+
|
546
|
+
#if defined(OPENSSL_NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1_METHOD)
|
547
|
+
/* True if TLS1_1 is not available */
|
548
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qtrue);
|
549
|
+
#else
|
550
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qfalse);
|
551
|
+
#endif
|
552
|
+
|
422
553
|
rb_define_singleton_method(mod, "check", noop, 0);
|
423
554
|
|
424
555
|
eError = rb_define_class_under(mod, "SSLError", rb_eStandardError);
|
@@ -447,7 +578,7 @@ VALUE raise_error(VALUE self) {
|
|
447
578
|
}
|
448
579
|
|
449
580
|
void Init_mini_ssl(VALUE puma) {
|
450
|
-
VALUE mod
|
581
|
+
VALUE mod;
|
451
582
|
|
452
583
|
mod = rb_define_module_under(puma, "MiniSSL");
|
453
584
|
rb_define_class_under(mod, "SSLError", rb_eStandardError);
|