puma 4.3.6 → 5.6.4
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 +1486 -518
- 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 +46 -9
- data/ext/puma_http11/http11_parser.c +68 -57
- 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 +1 -1
- data/ext/puma_http11/mini_ssl.c +275 -122
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +51 -51
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +105 -61
- data/ext/puma_http11/puma_http11.c +32 -51
- data/lib/puma/app/status.rb +47 -36
- data/lib/puma/binder.rb +225 -106
- data/lib/puma/cli.rb +24 -18
- data/lib/puma/client.rb +174 -91
- 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 +18 -9
- data/lib/puma/control_cli.rb +93 -76
- data/lib/puma/detect.rb +29 -2
- data/lib/puma/dsl.rb +364 -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 +117 -46
- data/lib/puma/minissl/context_builder.rb +14 -9
- data/lib/puma/minissl.rb +128 -46
- data/lib/puma/null_io.rb +13 -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 +472 -0
- data/lib/puma/runner.rb +46 -61
- data/lib/puma/server.rb +287 -743
- data/lib/puma/single.rb +9 -65
- data/lib/puma/state_file.rb +47 -8
- data/lib/puma/systemd.rb +46 -0
- data/lib/puma/thread_pool.rb +125 -57
- data/lib/puma/util.rb +20 -1
- data/lib/puma.rb +46 -0
- data/lib/rack/handler/puma.rb +2 -3
- data/tools/{docker/Dockerfile → Dockerfile} +1 -1
- data/tools/trickletest.rb +0 -0
- metadata +28 -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
@@ -34,9 +34,9 @@ private static short[] init__puma_parser_key_offsets_0()
|
|
34
34
|
{
|
35
35
|
return new short [] {
|
36
36
|
0, 0, 8, 17, 27, 29, 30, 31, 32, 33, 34, 36,
|
37
|
-
39, 41, 44, 45, 61, 62, 78,
|
38
|
-
|
39
|
-
|
37
|
+
39, 41, 44, 45, 61, 62, 78, 85, 91, 99, 107, 117,
|
38
|
+
125, 134, 142, 150, 159, 168, 177, 186, 195, 204, 213, 222,
|
39
|
+
231, 240, 249, 258, 267, 276, 285, 294, 303, 312, 313
|
40
40
|
};
|
41
41
|
}
|
42
42
|
|
@@ -52,26 +52,27 @@ private static char[] init__puma_parser_trans_keys_0()
|
|
52
52
|
46, 48, 57, 48, 57, 13, 48, 57, 10, 13, 33, 124,
|
53
53
|
126, 35, 39, 42, 43, 45, 46, 48, 57, 65, 90, 94,
|
54
54
|
122, 10, 33, 58, 124, 126, 35, 39, 42, 43, 45, 46,
|
55
|
-
48, 57, 65, 90, 94, 122, 13, 32,
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
63
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
64
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
65
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
66
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
67
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
68
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
69
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
70
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
71
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
72
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
73
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
74
|
-
65, 90, 32,
|
55
|
+
48, 57, 65, 90, 94, 122, 13, 32, 127, 0, 8, 10,
|
56
|
+
31, 13, 127, 0, 8, 10, 31, 32, 60, 62, 127, 0,
|
57
|
+
31, 34, 35, 32, 60, 62, 127, 0, 31, 34, 35, 43,
|
58
|
+
58, 45, 46, 48, 57, 65, 90, 97, 122, 32, 34, 35,
|
59
|
+
60, 62, 127, 0, 31, 32, 34, 35, 60, 62, 63, 127,
|
60
|
+
0, 31, 32, 34, 35, 60, 62, 127, 0, 31, 32, 34,
|
61
|
+
35, 60, 62, 127, 0, 31, 32, 36, 95, 45, 46, 48,
|
62
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
63
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
64
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
65
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
66
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
67
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
68
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
69
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
70
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
71
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
72
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
73
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
74
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
75
|
+
32, 0
|
75
76
|
};
|
76
77
|
}
|
77
78
|
|
@@ -82,7 +83,7 @@ private static byte[] init__puma_parser_single_lengths_0()
|
|
82
83
|
{
|
83
84
|
return new byte [] {
|
84
85
|
0, 2, 3, 4, 2, 1, 1, 1, 1, 1, 0, 1,
|
85
|
-
0, 1, 1, 4, 1, 4,
|
86
|
+
0, 1, 1, 4, 1, 4, 3, 2, 4, 4, 2, 6,
|
86
87
|
7, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
87
88
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0
|
88
89
|
};
|
@@ -95,7 +96,7 @@ private static byte[] init__puma_parser_range_lengths_0()
|
|
95
96
|
{
|
96
97
|
return new byte [] {
|
97
98
|
0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 1,
|
98
|
-
1, 1, 0, 6, 0, 6,
|
99
|
+
1, 1, 0, 6, 0, 6, 2, 2, 2, 2, 4, 1,
|
99
100
|
1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
100
101
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0
|
101
102
|
};
|
@@ -108,9 +109,9 @@ private static short[] init__puma_parser_index_offsets_0()
|
|
108
109
|
{
|
109
110
|
return new short [] {
|
110
111
|
0, 0, 6, 13, 21, 24, 26, 28, 30, 32, 34, 36,
|
111
|
-
39, 41, 44, 46, 57, 59, 70,
|
112
|
-
|
113
|
-
|
112
|
+
39, 41, 44, 46, 57, 59, 70, 76, 81, 88, 95, 102,
|
113
|
+
110, 119, 127, 135, 142, 149, 156, 163, 170, 177, 184, 191,
|
114
|
+
198, 205, 212, 219, 226, 233, 240, 247, 254, 261, 263
|
114
115
|
};
|
115
116
|
}
|
116
117
|
|
@@ -126,22 +127,23 @@ private static byte[] init__puma_parser_indicies_0()
|
|
126
127
|
16, 15, 1, 17, 1, 18, 17, 1, 19, 1, 20, 21,
|
127
128
|
21, 21, 21, 21, 21, 21, 21, 21, 1, 22, 1, 23,
|
128
129
|
24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27,
|
129
|
-
|
130
|
-
1, 1, 1, 1,
|
131
|
-
|
132
|
-
1,
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
63, 63, 1, 2, 1, 1,
|
130
|
+
1, 1, 1, 25, 29, 1, 1, 1, 28, 30, 1, 1,
|
131
|
+
1, 1, 1, 31, 32, 1, 1, 1, 1, 1, 33, 34,
|
132
|
+
35, 34, 34, 34, 34, 1, 8, 1, 9, 1, 1, 1,
|
133
|
+
1, 35, 36, 1, 38, 1, 1, 39, 1, 1, 37, 40,
|
134
|
+
1, 42, 1, 1, 1, 1, 41, 43, 1, 45, 1, 1,
|
135
|
+
1, 1, 44, 2, 46, 46, 46, 46, 46, 1, 2, 47,
|
136
|
+
47, 47, 47, 47, 1, 2, 48, 48, 48, 48, 48, 1,
|
137
|
+
2, 49, 49, 49, 49, 49, 1, 2, 50, 50, 50, 50,
|
138
|
+
50, 1, 2, 51, 51, 51, 51, 51, 1, 2, 52, 52,
|
139
|
+
52, 52, 52, 1, 2, 53, 53, 53, 53, 53, 1, 2,
|
140
|
+
54, 54, 54, 54, 54, 1, 2, 55, 55, 55, 55, 55,
|
141
|
+
1, 2, 56, 56, 56, 56, 56, 1, 2, 57, 57, 57,
|
142
|
+
57, 57, 1, 2, 58, 58, 58, 58, 58, 1, 2, 59,
|
143
|
+
59, 59, 59, 59, 1, 2, 60, 60, 60, 60, 60, 1,
|
144
|
+
2, 61, 61, 61, 61, 61, 1, 2, 62, 62, 62, 62,
|
145
|
+
62, 1, 2, 63, 63, 63, 63, 63, 1, 2, 1, 1,
|
146
|
+
0
|
145
147
|
};
|
146
148
|
}
|
147
149
|
|
@@ -182,8 +184,6 @@ static final int puma_parser_start = 1;
|
|
182
184
|
static final int puma_parser_first_final = 46;
|
183
185
|
static final int puma_parser_error = 0;
|
184
186
|
|
185
|
-
static final int puma_parser_en_main = 1;
|
186
|
-
|
187
187
|
|
188
188
|
// line 62 "ext/puma_http11/http11_parser.java.rl"
|
189
189
|
|
@@ -212,12 +212,12 @@ static final int puma_parser_en_main = 1;
|
|
212
212
|
cs = 0;
|
213
213
|
|
214
214
|
|
215
|
-
// line
|
215
|
+
// line 216 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
216
216
|
{
|
217
217
|
cs = puma_parser_start;
|
218
218
|
}
|
219
219
|
|
220
|
-
// line
|
220
|
+
// line 88 "ext/puma_http11/http11_parser.java.rl"
|
221
221
|
|
222
222
|
body_start = 0;
|
223
223
|
content_len = 0;
|
@@ -244,7 +244,7 @@ static final int puma_parser_en_main = 1;
|
|
244
244
|
parser.buffer = buffer;
|
245
245
|
|
246
246
|
|
247
|
-
// line
|
247
|
+
// line 248 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
248
248
|
{
|
249
249
|
int _klen;
|
250
250
|
int _trans = 0;
|
@@ -400,7 +400,7 @@ case 1:
|
|
400
400
|
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
|
401
401
|
}
|
402
402
|
break;
|
403
|
-
// line
|
403
|
+
// line 404 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
404
404
|
}
|
405
405
|
}
|
406
406
|
}
|
@@ -420,7 +420,7 @@ case 5:
|
|
420
420
|
break; }
|
421
421
|
}
|
422
422
|
|
423
|
-
// line
|
423
|
+
// line 114 "ext/puma_http11/http11_parser.java.rl"
|
424
424
|
|
425
425
|
parser.cs = cs;
|
426
426
|
parser.nread += (p - off);
|
@@ -6,6 +6,7 @@ import org.jruby.RubyModule;
|
|
6
6
|
import org.jruby.RubyObject;
|
7
7
|
import org.jruby.RubyString;
|
8
8
|
import org.jruby.anno.JRubyMethod;
|
9
|
+
import org.jruby.exceptions.RaiseException;
|
9
10
|
import org.jruby.javasupport.JavaEmbedUtils;
|
10
11
|
import org.jruby.runtime.Block;
|
11
12
|
import org.jruby.runtime.ObjectAllocator;
|
@@ -22,6 +23,7 @@ import javax.net.ssl.SSLException;
|
|
22
23
|
import javax.net.ssl.SSLPeerUnverifiedException;
|
23
24
|
import javax.net.ssl.SSLSession;
|
24
25
|
import java.io.FileInputStream;
|
26
|
+
import java.io.InputStream;
|
25
27
|
import java.io.IOException;
|
26
28
|
import java.nio.Buffer;
|
27
29
|
import java.nio.ByteBuffer;
|
@@ -32,6 +34,8 @@ import java.security.NoSuchAlgorithmException;
|
|
32
34
|
import java.security.UnrecoverableKeyException;
|
33
35
|
import java.security.cert.CertificateEncodingException;
|
34
36
|
import java.security.cert.CertificateException;
|
37
|
+
import java.util.concurrent.ConcurrentHashMap;
|
38
|
+
import java.util.Map;
|
35
39
|
|
36
40
|
import static javax.net.ssl.SSLEngineResult.Status;
|
37
41
|
import static javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
@@ -77,11 +81,11 @@ public class MiniSSL extends RubyObject {
|
|
77
81
|
/**
|
78
82
|
* Writes bytes to the buffer after ensuring there's room
|
79
83
|
*/
|
80
|
-
|
81
|
-
if (buffer.remaining() <
|
82
|
-
resize(buffer.limit() +
|
84
|
+
private void put(byte[] bytes, final int offset, final int length) {
|
85
|
+
if (buffer.remaining() < length) {
|
86
|
+
resize(buffer.limit() + length);
|
83
87
|
}
|
84
|
-
buffer.put(bytes);
|
88
|
+
buffer.put(bytes, offset, length);
|
85
89
|
}
|
86
90
|
|
87
91
|
/**
|
@@ -112,7 +116,7 @@ public class MiniSSL extends RubyObject {
|
|
112
116
|
|
113
117
|
buffer.get(bss);
|
114
118
|
buffer.clear();
|
115
|
-
return new ByteList(bss);
|
119
|
+
return new ByteList(bss, false);
|
116
120
|
}
|
117
121
|
|
118
122
|
@Override
|
@@ -120,6 +124,8 @@ public class MiniSSL extends RubyObject {
|
|
120
124
|
}
|
121
125
|
|
122
126
|
private SSLEngine engine;
|
127
|
+
private boolean closed;
|
128
|
+
private boolean handshake;
|
123
129
|
private MiniSSLBuffer inboundNetData;
|
124
130
|
private MiniSSLBuffer outboundAppData;
|
125
131
|
private MiniSSLBuffer outboundNetData;
|
@@ -128,10 +134,39 @@ public class MiniSSL extends RubyObject {
|
|
128
134
|
super(runtime, klass);
|
129
135
|
}
|
130
136
|
|
137
|
+
private static Map<String, KeyManagerFactory> keyManagerFactoryMap = new ConcurrentHashMap<String, KeyManagerFactory>();
|
138
|
+
private static Map<String, TrustManagerFactory> trustManagerFactoryMap = new ConcurrentHashMap<String, TrustManagerFactory>();
|
139
|
+
|
131
140
|
@JRubyMethod(meta = true)
|
132
|
-
public static IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
|
133
|
-
|
141
|
+
public static synchronized IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
|
142
|
+
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
|
143
|
+
// Create the KeyManagerFactory and TrustManagerFactory for this server
|
144
|
+
String keystoreFile = miniSSLContext.callMethod(context, "keystore").convertToString().asJavaString();
|
145
|
+
char[] password = miniSSLContext.callMethod(context, "keystore_pass").convertToString().asJavaString().toCharArray();
|
146
|
+
|
147
|
+
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
148
|
+
InputStream is = new FileInputStream(keystoreFile);
|
149
|
+
try {
|
150
|
+
ks.load(is, password);
|
151
|
+
} finally {
|
152
|
+
is.close();
|
153
|
+
}
|
154
|
+
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
155
|
+
kmf.init(ks, password);
|
156
|
+
keyManagerFactoryMap.put(keystoreFile, kmf);
|
157
|
+
|
158
|
+
KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
|
159
|
+
is = new FileInputStream(keystoreFile);
|
160
|
+
try {
|
161
|
+
ts.load(is, password);
|
162
|
+
} finally {
|
163
|
+
is.close();
|
164
|
+
}
|
165
|
+
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
166
|
+
tmf.init(ts);
|
167
|
+
trustManagerFactoryMap.put(keystoreFile, tmf);
|
134
168
|
|
169
|
+
RubyClass klass = (RubyClass) recv;
|
135
170
|
return klass.newInstance(context,
|
136
171
|
new IRubyObject[] { miniSSLContext },
|
137
172
|
Block.NULL_BLOCK);
|
@@ -139,24 +174,20 @@ public class MiniSSL extends RubyObject {
|
|
139
174
|
|
140
175
|
@JRubyMethod
|
141
176
|
public IRubyObject initialize(ThreadContext threadContext, IRubyObject miniSSLContext)
|
142
|
-
throws KeyStoreException,
|
143
|
-
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
144
|
-
KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
|
177
|
+
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
|
145
178
|
|
146
|
-
char[] password = miniSSLContext.callMethod(threadContext, "keystore_pass").convertToString().asJavaString().toCharArray();
|
147
179
|
String keystoreFile = miniSSLContext.callMethod(threadContext, "keystore").convertToString().asJavaString();
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
155
|
-
tmf.init(ts);
|
180
|
+
KeyManagerFactory kmf = keyManagerFactoryMap.get(keystoreFile);
|
181
|
+
TrustManagerFactory tmf = trustManagerFactoryMap.get(keystoreFile);
|
182
|
+
if(kmf == null || tmf == null) {
|
183
|
+
throw new KeyStoreException("Could not find KeyManagerFactory/TrustManagerFactory for keystore: " + keystoreFile);
|
184
|
+
}
|
156
185
|
|
157
186
|
SSLContext sslCtx = SSLContext.getInstance("TLS");
|
158
187
|
|
159
188
|
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
|
189
|
+
closed = false;
|
190
|
+
handshake = false;
|
160
191
|
engine = sslCtx.createSSLEngine();
|
161
192
|
|
162
193
|
String[] protocols;
|
@@ -173,7 +204,7 @@ public class MiniSSL extends RubyObject {
|
|
173
204
|
engine.setEnabledProtocols(protocols);
|
174
205
|
engine.setUseClientMode(false);
|
175
206
|
|
176
|
-
long verify_mode = miniSSLContext.callMethod(threadContext, "verify_mode").convertToInteger().getLongValue();
|
207
|
+
long verify_mode = miniSSLContext.callMethod(threadContext, "verify_mode").convertToInteger("to_i").getLongValue();
|
177
208
|
if ((verify_mode & 0x1) != 0) { // 'peer'
|
178
209
|
engine.setWantClientAuth(true);
|
179
210
|
}
|
@@ -198,14 +229,9 @@ public class MiniSSL extends RubyObject {
|
|
198
229
|
|
199
230
|
@JRubyMethod
|
200
231
|
public IRubyObject inject(IRubyObject arg) {
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
return this;
|
205
|
-
} catch (Exception e) {
|
206
|
-
e.printStackTrace();
|
207
|
-
throw new RuntimeException(e);
|
208
|
-
}
|
232
|
+
ByteList bytes = arg.convertToString().getByteList();
|
233
|
+
inboundNetData.put(bytes.unsafeBytes(), bytes.getBegin(), bytes.getRealSize());
|
234
|
+
return this;
|
209
235
|
}
|
210
236
|
|
211
237
|
private enum SSLOperation {
|
@@ -240,14 +266,21 @@ public class MiniSSL extends RubyObject {
|
|
240
266
|
// need to wait for more data to come in before we retry
|
241
267
|
retryOp = false;
|
242
268
|
break;
|
269
|
+
case CLOSED:
|
270
|
+
closed = true;
|
271
|
+
retryOp = false;
|
272
|
+
break;
|
243
273
|
default:
|
244
|
-
// other
|
274
|
+
// other case is OK. We're done here.
|
245
275
|
retryOp = false;
|
246
276
|
}
|
277
|
+
if (res.getHandshakeStatus() == HandshakeStatus.FINISHED) {
|
278
|
+
handshake = true;
|
279
|
+
}
|
247
280
|
}
|
248
281
|
|
249
282
|
// after each op, run any delegated tasks if needed
|
250
|
-
if(
|
283
|
+
if(res.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
|
251
284
|
Runnable runnable;
|
252
285
|
while ((runnable = engine.getDelegatedTask()) != null) {
|
253
286
|
runnable.run();
|
@@ -258,7 +291,7 @@ public class MiniSSL extends RubyObject {
|
|
258
291
|
}
|
259
292
|
|
260
293
|
@JRubyMethod
|
261
|
-
public IRubyObject read()
|
294
|
+
public IRubyObject read() {
|
262
295
|
try {
|
263
296
|
inboundNetData.flip();
|
264
297
|
|
@@ -271,13 +304,14 @@ public class MiniSSL extends RubyObject {
|
|
271
304
|
|
272
305
|
HandshakeStatus handshakeStatus = engine.getHandshakeStatus();
|
273
306
|
boolean done = false;
|
307
|
+
SSLEngineResult res = null;
|
274
308
|
while (!done) {
|
275
309
|
switch (handshakeStatus) {
|
276
310
|
case NEED_WRAP:
|
277
|
-
doOp(SSLOperation.WRAP, inboundAppData, outboundNetData);
|
311
|
+
res = doOp(SSLOperation.WRAP, inboundAppData, outboundNetData);
|
278
312
|
break;
|
279
313
|
case NEED_UNWRAP:
|
280
|
-
|
314
|
+
res = doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData);
|
281
315
|
if (res.getStatus() == Status.BUFFER_UNDERFLOW) {
|
282
316
|
// need more data before we can shake more hands
|
283
317
|
done = true;
|
@@ -286,7 +320,9 @@ public class MiniSSL extends RubyObject {
|
|
286
320
|
default:
|
287
321
|
done = true;
|
288
322
|
}
|
289
|
-
|
323
|
+
if (!done) {
|
324
|
+
handshakeStatus = res.getHandshakeStatus();
|
325
|
+
}
|
290
326
|
}
|
291
327
|
|
292
328
|
if (inboundNetData.hasRemaining()) {
|
@@ -300,55 +336,46 @@ public class MiniSSL extends RubyObject {
|
|
300
336
|
return getRuntime().getNil();
|
301
337
|
}
|
302
338
|
|
303
|
-
RubyString
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
throw
|
339
|
+
return RubyString.newString(getRuntime(), appDataByteList);
|
340
|
+
} catch (SSLException e) {
|
341
|
+
RaiseException re = getRuntime().newEOFError(e.getMessage());
|
342
|
+
re.initCause(e);
|
343
|
+
throw re;
|
308
344
|
}
|
309
345
|
}
|
310
346
|
|
311
347
|
@JRubyMethod
|
312
348
|
public IRubyObject write(IRubyObject arg) {
|
313
|
-
|
314
|
-
|
315
|
-
outboundAppData = new MiniSSLBuffer(bls);
|
349
|
+
byte[] bls = arg.convertToString().getBytes();
|
350
|
+
outboundAppData = new MiniSSLBuffer(bls);
|
316
351
|
|
317
|
-
|
318
|
-
} catch (Exception e) {
|
319
|
-
e.printStackTrace();
|
320
|
-
throw new RuntimeException(e);
|
321
|
-
}
|
352
|
+
return getRuntime().newFixnum(bls.length);
|
322
353
|
}
|
323
354
|
|
324
355
|
@JRubyMethod
|
325
|
-
public IRubyObject extract()
|
356
|
+
public IRubyObject extract(ThreadContext context) {
|
326
357
|
try {
|
327
358
|
ByteList dataByteList = outboundNetData.asByteList();
|
328
359
|
if (dataByteList != null) {
|
329
|
-
RubyString
|
330
|
-
str.setValue(dataByteList);
|
331
|
-
return str;
|
360
|
+
return RubyString.newString(context.runtime, dataByteList);
|
332
361
|
}
|
333
362
|
|
334
363
|
if (!outboundAppData.hasRemaining()) {
|
335
|
-
return
|
364
|
+
return context.nil;
|
336
365
|
}
|
337
366
|
|
338
367
|
outboundNetData.clear();
|
339
368
|
doOp(SSLOperation.WRAP, outboundAppData, outboundNetData);
|
340
369
|
dataByteList = outboundNetData.asByteList();
|
341
370
|
if (dataByteList == null) {
|
342
|
-
return
|
371
|
+
return context.nil;
|
343
372
|
}
|
344
373
|
|
345
|
-
RubyString
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
e.printStackTrace();
|
351
|
-
throw new RuntimeException(e);
|
374
|
+
return RubyString.newString(context.runtime, dataByteList);
|
375
|
+
} catch (SSLException e) {
|
376
|
+
RaiseException ex = context.runtime.newRuntimeError(e.toString());
|
377
|
+
ex.initCause(e);
|
378
|
+
throw ex;
|
352
379
|
}
|
353
380
|
}
|
354
381
|
|
@@ -356,8 +383,25 @@ public class MiniSSL extends RubyObject {
|
|
356
383
|
public IRubyObject peercert() throws CertificateEncodingException {
|
357
384
|
try {
|
358
385
|
return JavaEmbedUtils.javaToRuby(getRuntime(), engine.getSession().getPeerCertificates()[0].getEncoded());
|
359
|
-
} catch (SSLPeerUnverifiedException
|
386
|
+
} catch (SSLPeerUnverifiedException e) {
|
360
387
|
return getRuntime().getNil();
|
361
388
|
}
|
362
389
|
}
|
390
|
+
|
391
|
+
@JRubyMethod(name = "init?")
|
392
|
+
public IRubyObject isInit(ThreadContext context) {
|
393
|
+
return handshake ? getRuntime().getFalse() : getRuntime().getTrue();
|
394
|
+
}
|
395
|
+
|
396
|
+
@JRubyMethod
|
397
|
+
public IRubyObject shutdown() {
|
398
|
+
if (closed || engine.isInboundDone() && engine.isOutboundDone()) {
|
399
|
+
if (engine.isOutboundDone()) {
|
400
|
+
engine.closeOutbound();
|
401
|
+
}
|
402
|
+
return getRuntime().getTrue();
|
403
|
+
} else {
|
404
|
+
return getRuntime().getFalse();
|
405
|
+
}
|
406
|
+
}
|
363
407
|
}
|