jun-puma 1.0.1-java → 1.0.2-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/puma/puma_http11.jar +0 -0
- metadata +3 -81
- data/bin/puma-wild +0 -25
- data/docs/architecture.md +0 -74
- data/docs/compile_options.md +0 -55
- data/docs/deployment.md +0 -102
- data/docs/fork_worker.md +0 -31
- 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 +0 -9
- data/docs/jungle/rc.d/README.md +0 -74
- data/docs/jungle/rc.d/puma +0 -61
- data/docs/jungle/rc.d/puma.conf +0 -10
- data/docs/kubernetes.md +0 -78
- data/docs/nginx.md +0 -80
- data/docs/plugins.md +0 -38
- data/docs/rails_dev_mode.md +0 -28
- data/docs/restart.md +0 -64
- data/docs/signals.md +0 -98
- data/docs/stats.md +0 -142
- data/docs/systemd.md +0 -244
- data/docs/testing_benchmarks_local_files.md +0 -150
- data/docs/testing_test_rackup_ci_files.md +0 -36
- data/ext/puma_http11/PumaHttp11Service.java +0 -17
- data/ext/puma_http11/ext_help.h +0 -15
- data/ext/puma_http11/http11_parser.c +0 -1057
- data/ext/puma_http11/http11_parser.h +0 -65
- data/ext/puma_http11/http11_parser.java.rl +0 -145
- data/ext/puma_http11/http11_parser.rl +0 -149
- data/ext/puma_http11/http11_parser_common.rl +0 -54
- data/ext/puma_http11/mini_ssl.c +0 -832
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -15
- data/ext/puma_http11/org/jruby/puma/Http11.java +0 -226
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +0 -455
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +0 -508
- data/ext/puma_http11/puma_http11.c +0 -492
- data/lib/puma/app/status.rb +0 -96
- data/lib/puma/binder.rb +0 -501
- data/lib/puma/cli.rb +0 -243
- data/lib/puma/client.rb +0 -632
- data/lib/puma/cluster/worker.rb +0 -182
- data/lib/puma/cluster/worker_handle.rb +0 -97
- data/lib/puma/cluster.rb +0 -562
- data/lib/puma/commonlogger.rb +0 -115
- data/lib/puma/configuration.rb +0 -391
- data/lib/puma/const.rb +0 -289
- data/lib/puma/control_cli.rb +0 -316
- data/lib/puma/detect.rb +0 -45
- data/lib/puma/dsl.rb +0 -1204
- data/lib/puma/error_logger.rb +0 -113
- data/lib/puma/events.rb +0 -57
- data/lib/puma/io_buffer.rb +0 -46
- data/lib/puma/jruby_restart.rb +0 -27
- data/lib/puma/json_serialization.rb +0 -96
- data/lib/puma/launcher/bundle_pruner.rb +0 -104
- data/lib/puma/launcher.rb +0 -484
- data/lib/puma/log_writer.rb +0 -147
- data/lib/puma/minissl/context_builder.rb +0 -95
- data/lib/puma/minissl.rb +0 -458
- data/lib/puma/null_io.rb +0 -61
- data/lib/puma/plugin/systemd.rb +0 -90
- data/lib/puma/plugin/tmp_restart.rb +0 -36
- data/lib/puma/plugin.rb +0 -111
- data/lib/puma/rack/builder.rb +0 -297
- data/lib/puma/rack/urlmap.rb +0 -93
- data/lib/puma/rack_default.rb +0 -24
- data/lib/puma/reactor.rb +0 -125
- data/lib/puma/request.rb +0 -671
- data/lib/puma/runner.rb +0 -213
- data/lib/puma/sd_notify.rb +0 -149
- data/lib/puma/server.rb +0 -664
- data/lib/puma/single.rb +0 -69
- data/lib/puma/state_file.rb +0 -68
- data/lib/puma/thread_pool.rb +0 -434
- data/lib/puma/util.rb +0 -141
- data/lib/puma.rb +0 -78
- data/lib/rack/handler/puma.rb +0 -141
- data/tools/Dockerfile +0 -16
- data/tools/trickletest.rb +0 -44
@@ -1,508 +0,0 @@
|
|
1
|
-
package org.jruby.puma;
|
2
|
-
|
3
|
-
import org.jruby.Ruby;
|
4
|
-
import org.jruby.RubyArray;
|
5
|
-
import org.jruby.RubyClass;
|
6
|
-
import org.jruby.RubyModule;
|
7
|
-
import org.jruby.RubyObject;
|
8
|
-
import org.jruby.RubyString;
|
9
|
-
import org.jruby.anno.JRubyMethod;
|
10
|
-
import org.jruby.exceptions.RaiseException;
|
11
|
-
import org.jruby.javasupport.JavaEmbedUtils;
|
12
|
-
import org.jruby.runtime.Block;
|
13
|
-
import org.jruby.runtime.ObjectAllocator;
|
14
|
-
import org.jruby.runtime.ThreadContext;
|
15
|
-
import org.jruby.runtime.builtin.IRubyObject;
|
16
|
-
import org.jruby.util.ByteList;
|
17
|
-
|
18
|
-
import javax.net.ssl.KeyManagerFactory;
|
19
|
-
import javax.net.ssl.TrustManager;
|
20
|
-
import javax.net.ssl.TrustManagerFactory;
|
21
|
-
import javax.net.ssl.SSLContext;
|
22
|
-
import javax.net.ssl.SSLEngine;
|
23
|
-
import javax.net.ssl.SSLEngineResult;
|
24
|
-
import javax.net.ssl.SSLException;
|
25
|
-
import javax.net.ssl.SSLPeerUnverifiedException;
|
26
|
-
import javax.net.ssl.SSLSession;
|
27
|
-
import javax.net.ssl.X509TrustManager;
|
28
|
-
import java.io.FileInputStream;
|
29
|
-
import java.io.InputStream;
|
30
|
-
import java.io.IOException;
|
31
|
-
import java.nio.Buffer;
|
32
|
-
import java.nio.ByteBuffer;
|
33
|
-
import java.security.KeyManagementException;
|
34
|
-
import java.security.KeyStore;
|
35
|
-
import java.security.KeyStoreException;
|
36
|
-
import java.security.NoSuchAlgorithmException;
|
37
|
-
import java.security.UnrecoverableKeyException;
|
38
|
-
import java.security.cert.Certificate;
|
39
|
-
import java.security.cert.CertificateEncodingException;
|
40
|
-
import java.security.cert.CertificateException;
|
41
|
-
import java.security.cert.X509Certificate;
|
42
|
-
import java.util.concurrent.ConcurrentHashMap;
|
43
|
-
import java.util.Map;
|
44
|
-
import java.util.function.Supplier;
|
45
|
-
|
46
|
-
import static javax.net.ssl.SSLEngineResult.Status;
|
47
|
-
import static javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
48
|
-
|
49
|
-
public class MiniSSL extends RubyObject { // MiniSSL::Engine
|
50
|
-
private static ObjectAllocator ALLOCATOR = new ObjectAllocator() {
|
51
|
-
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
52
|
-
return new MiniSSL(runtime, klass);
|
53
|
-
}
|
54
|
-
};
|
55
|
-
|
56
|
-
public static void createMiniSSL(Ruby runtime) {
|
57
|
-
RubyModule mPuma = runtime.defineModule("Puma");
|
58
|
-
RubyModule ssl = mPuma.defineModuleUnder("MiniSSL");
|
59
|
-
|
60
|
-
// Puma::MiniSSL::SSLError
|
61
|
-
ssl.defineClassUnder("SSLError", runtime.getStandardError(), runtime.getStandardError().getAllocator());
|
62
|
-
|
63
|
-
RubyClass eng = ssl.defineClassUnder("Engine", runtime.getObject(), ALLOCATOR);
|
64
|
-
eng.defineAnnotatedMethods(MiniSSL.class);
|
65
|
-
}
|
66
|
-
|
67
|
-
/**
|
68
|
-
* Fairly transparent wrapper around {@link java.nio.ByteBuffer} which adds the enhancements we need
|
69
|
-
*/
|
70
|
-
private static class MiniSSLBuffer {
|
71
|
-
ByteBuffer buffer;
|
72
|
-
|
73
|
-
private MiniSSLBuffer(int capacity) { buffer = ByteBuffer.allocate(capacity); }
|
74
|
-
private MiniSSLBuffer(byte[] initialContents) { buffer = ByteBuffer.wrap(initialContents); }
|
75
|
-
|
76
|
-
public void clear() { buffer.clear(); }
|
77
|
-
public void compact() { buffer.compact(); }
|
78
|
-
public void flip() { ((Buffer) buffer).flip(); }
|
79
|
-
public boolean hasRemaining() { return buffer.hasRemaining(); }
|
80
|
-
public int position() { return buffer.position(); }
|
81
|
-
|
82
|
-
public ByteBuffer getRawBuffer() {
|
83
|
-
return buffer;
|
84
|
-
}
|
85
|
-
|
86
|
-
/**
|
87
|
-
* Writes bytes to the buffer after ensuring there's room
|
88
|
-
*/
|
89
|
-
private void put(byte[] bytes, final int offset, final int length) {
|
90
|
-
if (buffer.remaining() < length) {
|
91
|
-
resize(buffer.limit() + length);
|
92
|
-
}
|
93
|
-
buffer.put(bytes, offset, length);
|
94
|
-
}
|
95
|
-
|
96
|
-
/**
|
97
|
-
* Ensures that newCapacity bytes can be written to this buffer, only re-allocating if necessary
|
98
|
-
*/
|
99
|
-
public void resize(int newCapacity) {
|
100
|
-
if (newCapacity > buffer.capacity()) {
|
101
|
-
ByteBuffer dstTmp = ByteBuffer.allocate(newCapacity);
|
102
|
-
flip();
|
103
|
-
dstTmp.put(buffer);
|
104
|
-
buffer = dstTmp;
|
105
|
-
} else {
|
106
|
-
buffer.limit(newCapacity);
|
107
|
-
}
|
108
|
-
}
|
109
|
-
|
110
|
-
/**
|
111
|
-
* Drains the buffer to a ByteList, or returns null for an empty buffer
|
112
|
-
*/
|
113
|
-
public ByteList asByteList() {
|
114
|
-
flip();
|
115
|
-
if (!buffer.hasRemaining()) {
|
116
|
-
buffer.clear();
|
117
|
-
return null;
|
118
|
-
}
|
119
|
-
|
120
|
-
byte[] bss = new byte[buffer.limit()];
|
121
|
-
|
122
|
-
buffer.get(bss);
|
123
|
-
buffer.clear();
|
124
|
-
return new ByteList(bss, false);
|
125
|
-
}
|
126
|
-
|
127
|
-
@Override
|
128
|
-
public String toString() { return buffer.toString(); }
|
129
|
-
}
|
130
|
-
|
131
|
-
private SSLEngine engine;
|
132
|
-
private boolean closed;
|
133
|
-
private boolean handshake;
|
134
|
-
private MiniSSLBuffer inboundNetData;
|
135
|
-
private MiniSSLBuffer outboundAppData;
|
136
|
-
private MiniSSLBuffer outboundNetData;
|
137
|
-
|
138
|
-
public MiniSSL(Ruby runtime, RubyClass klass) {
|
139
|
-
super(runtime, klass);
|
140
|
-
}
|
141
|
-
|
142
|
-
private static Map<String, KeyManagerFactory> keyManagerFactoryMap = new ConcurrentHashMap<String, KeyManagerFactory>();
|
143
|
-
private static Map<String, TrustManagerFactory> trustManagerFactoryMap = new ConcurrentHashMap<String, TrustManagerFactory>();
|
144
|
-
|
145
|
-
@JRubyMethod(meta = true) // Engine.server
|
146
|
-
public static synchronized IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
|
147
|
-
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
|
148
|
-
// Create the KeyManagerFactory and TrustManagerFactory for this server
|
149
|
-
String keystoreFile = asStringValue(miniSSLContext.callMethod(context, "keystore"), null);
|
150
|
-
char[] keystorePass = asStringValue(miniSSLContext.callMethod(context, "keystore_pass"), null).toCharArray();
|
151
|
-
String keystoreType = asStringValue(miniSSLContext.callMethod(context, "keystore_type"), KeyStore::getDefaultType);
|
152
|
-
|
153
|
-
String truststoreFile;
|
154
|
-
char[] truststorePass;
|
155
|
-
String truststoreType;
|
156
|
-
IRubyObject truststore = miniSSLContext.callMethod(context, "truststore");
|
157
|
-
if (truststore.isNil()) {
|
158
|
-
truststoreFile = keystoreFile;
|
159
|
-
truststorePass = keystorePass;
|
160
|
-
truststoreType = keystoreType;
|
161
|
-
} else if (!isDefaultSymbol(context, truststore)) {
|
162
|
-
truststoreFile = truststore.convertToString().asJavaString();
|
163
|
-
IRubyObject pass = miniSSLContext.callMethod(context, "truststore_pass");
|
164
|
-
if (pass.isNil()) {
|
165
|
-
truststorePass = null;
|
166
|
-
} else {
|
167
|
-
truststorePass = asStringValue(pass, null).toCharArray();
|
168
|
-
}
|
169
|
-
truststoreType = asStringValue(miniSSLContext.callMethod(context, "truststore_type"), KeyStore::getDefaultType);
|
170
|
-
} else { // self.truststore = :default
|
171
|
-
truststoreFile = null;
|
172
|
-
truststorePass = null;
|
173
|
-
truststoreType = null;
|
174
|
-
}
|
175
|
-
|
176
|
-
KeyStore ks = KeyStore.getInstance(keystoreType);
|
177
|
-
InputStream is = new FileInputStream(keystoreFile);
|
178
|
-
try {
|
179
|
-
ks.load(is, keystorePass);
|
180
|
-
} finally {
|
181
|
-
is.close();
|
182
|
-
}
|
183
|
-
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
184
|
-
kmf.init(ks, keystorePass);
|
185
|
-
keyManagerFactoryMap.put(keystoreFile, kmf);
|
186
|
-
|
187
|
-
if (truststoreFile != null) {
|
188
|
-
KeyStore ts = KeyStore.getInstance(truststoreType);
|
189
|
-
is = new FileInputStream(truststoreFile);
|
190
|
-
try {
|
191
|
-
ts.load(is, truststorePass);
|
192
|
-
} finally {
|
193
|
-
is.close();
|
194
|
-
}
|
195
|
-
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
196
|
-
tmf.init(ts);
|
197
|
-
trustManagerFactoryMap.put(truststoreFile, tmf);
|
198
|
-
}
|
199
|
-
|
200
|
-
RubyClass klass = (RubyClass) recv;
|
201
|
-
return klass.newInstance(context, miniSSLContext, Block.NULL_BLOCK);
|
202
|
-
}
|
203
|
-
|
204
|
-
private static String asStringValue(IRubyObject value, Supplier<String> defaultValue) {
|
205
|
-
if (defaultValue != null && value.isNil()) return defaultValue.get();
|
206
|
-
return value.convertToString().asJavaString();
|
207
|
-
}
|
208
|
-
|
209
|
-
private static boolean isDefaultSymbol(ThreadContext context, IRubyObject truststore) {
|
210
|
-
return context.runtime.newSymbol("default").equals(truststore);
|
211
|
-
}
|
212
|
-
|
213
|
-
@JRubyMethod
|
214
|
-
public IRubyObject initialize(ThreadContext context, IRubyObject miniSSLContext)
|
215
|
-
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
|
216
|
-
|
217
|
-
String keystoreFile = miniSSLContext.callMethod(context, "keystore").convertToString().asJavaString();
|
218
|
-
KeyManagerFactory kmf = keyManagerFactoryMap.get(keystoreFile);
|
219
|
-
IRubyObject truststore = miniSSLContext.callMethod(context, "truststore");
|
220
|
-
String truststoreFile = isDefaultSymbol(context, truststore) ? "" : asStringValue(truststore, () -> keystoreFile);
|
221
|
-
TrustManagerFactory tmf = trustManagerFactoryMap.get(truststoreFile); // null if self.truststore = :default
|
222
|
-
if (kmf == null) {
|
223
|
-
throw new KeyStoreException("Could not find KeyManagerFactory for keystore: " + keystoreFile + " truststore: " + truststoreFile);
|
224
|
-
}
|
225
|
-
|
226
|
-
SSLContext sslCtx = SSLContext.getInstance("TLS");
|
227
|
-
|
228
|
-
sslCtx.init(kmf.getKeyManagers(), getTrustManagers(tmf), null);
|
229
|
-
closed = false;
|
230
|
-
handshake = false;
|
231
|
-
engine = sslCtx.createSSLEngine();
|
232
|
-
|
233
|
-
String[] enabledProtocols;
|
234
|
-
IRubyObject protocols = miniSSLContext.callMethod(context, "protocols");
|
235
|
-
if (protocols.isNil()) {
|
236
|
-
if (miniSSLContext.callMethod(context, "no_tlsv1").isTrue()) {
|
237
|
-
enabledProtocols = new String[] { "TLSv1.1", "TLSv1.2", "TLSv1.3" };
|
238
|
-
} else {
|
239
|
-
enabledProtocols = new String[] { "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" };
|
240
|
-
}
|
241
|
-
|
242
|
-
if (miniSSLContext.callMethod(context, "no_tlsv1_1").isTrue()) {
|
243
|
-
enabledProtocols = new String[] { "TLSv1.2", "TLSv1.3" };
|
244
|
-
}
|
245
|
-
} else if (protocols instanceof RubyArray) {
|
246
|
-
enabledProtocols = (String[]) ((RubyArray) protocols).toArray(new String[0]);
|
247
|
-
} else {
|
248
|
-
throw context.runtime.newTypeError(protocols, context.runtime.getArray());
|
249
|
-
}
|
250
|
-
engine.setEnabledProtocols(enabledProtocols);
|
251
|
-
|
252
|
-
engine.setUseClientMode(false);
|
253
|
-
|
254
|
-
long verify_mode = miniSSLContext.callMethod(context, "verify_mode").convertToInteger("to_i").getLongValue();
|
255
|
-
if ((verify_mode & 0x1) != 0) { // 'peer'
|
256
|
-
engine.setWantClientAuth(true);
|
257
|
-
}
|
258
|
-
if ((verify_mode & 0x2) != 0) { // 'force_peer'
|
259
|
-
engine.setNeedClientAuth(true);
|
260
|
-
}
|
261
|
-
|
262
|
-
IRubyObject cipher_suites = miniSSLContext.callMethod(context, "cipher_suites");
|
263
|
-
if (cipher_suites instanceof RubyArray) {
|
264
|
-
engine.setEnabledCipherSuites((String[]) ((RubyArray) cipher_suites).toArray(new String[0]));
|
265
|
-
} else if (!cipher_suites.isNil()) {
|
266
|
-
throw context.runtime.newTypeError(cipher_suites, context.runtime.getArray());
|
267
|
-
}
|
268
|
-
|
269
|
-
SSLSession session = engine.getSession();
|
270
|
-
inboundNetData = new MiniSSLBuffer(session.getPacketBufferSize());
|
271
|
-
outboundAppData = new MiniSSLBuffer(session.getApplicationBufferSize());
|
272
|
-
outboundAppData.flip();
|
273
|
-
outboundNetData = new MiniSSLBuffer(session.getPacketBufferSize());
|
274
|
-
|
275
|
-
return this;
|
276
|
-
}
|
277
|
-
|
278
|
-
private TrustManager[] getTrustManagers(TrustManagerFactory factory) {
|
279
|
-
if (factory == null) return null; // use JDK trust defaults
|
280
|
-
final TrustManager[] tms = factory.getTrustManagers();
|
281
|
-
if (tms != null) {
|
282
|
-
for (int i=0; i<tms.length; i++) {
|
283
|
-
final TrustManager tm = tms[i];
|
284
|
-
if (tm instanceof X509TrustManager) {
|
285
|
-
tms[i] = new TrustManagerWrapper((X509TrustManager) tm);
|
286
|
-
}
|
287
|
-
}
|
288
|
-
}
|
289
|
-
return tms;
|
290
|
-
}
|
291
|
-
|
292
|
-
private volatile transient X509Certificate lastCheckedCert0;
|
293
|
-
|
294
|
-
private class TrustManagerWrapper implements X509TrustManager {
|
295
|
-
|
296
|
-
private final X509TrustManager delegate;
|
297
|
-
|
298
|
-
TrustManagerWrapper(X509TrustManager delegate) {
|
299
|
-
this.delegate = delegate;
|
300
|
-
}
|
301
|
-
|
302
|
-
@Override
|
303
|
-
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
304
|
-
lastCheckedCert0 = chain.length > 0 ? chain[0] : null;
|
305
|
-
delegate.checkClientTrusted(chain, authType);
|
306
|
-
}
|
307
|
-
|
308
|
-
@Override
|
309
|
-
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
310
|
-
delegate.checkServerTrusted(chain, authType);
|
311
|
-
}
|
312
|
-
|
313
|
-
@Override
|
314
|
-
public X509Certificate[] getAcceptedIssuers() {
|
315
|
-
return delegate.getAcceptedIssuers();
|
316
|
-
}
|
317
|
-
|
318
|
-
}
|
319
|
-
|
320
|
-
@JRubyMethod
|
321
|
-
public IRubyObject inject(IRubyObject arg) {
|
322
|
-
ByteList bytes = arg.convertToString().getByteList();
|
323
|
-
inboundNetData.put(bytes.unsafeBytes(), bytes.getBegin(), bytes.getRealSize());
|
324
|
-
return this;
|
325
|
-
}
|
326
|
-
|
327
|
-
private enum SSLOperation {
|
328
|
-
WRAP,
|
329
|
-
UNWRAP
|
330
|
-
}
|
331
|
-
|
332
|
-
private SSLEngineResult doOp(SSLOperation sslOp, MiniSSLBuffer src, MiniSSLBuffer dst) throws SSLException {
|
333
|
-
SSLEngineResult res = null;
|
334
|
-
boolean retryOp = true;
|
335
|
-
while (retryOp) {
|
336
|
-
switch (sslOp) {
|
337
|
-
case WRAP:
|
338
|
-
res = engine.wrap(src.getRawBuffer(), dst.getRawBuffer());
|
339
|
-
break;
|
340
|
-
case UNWRAP:
|
341
|
-
res = engine.unwrap(src.getRawBuffer(), dst.getRawBuffer());
|
342
|
-
break;
|
343
|
-
default:
|
344
|
-
throw new AssertionError("Unknown SSLOperation: " + sslOp);
|
345
|
-
}
|
346
|
-
|
347
|
-
switch (res.getStatus()) {
|
348
|
-
case BUFFER_OVERFLOW:
|
349
|
-
// increase the buffer size to accommodate the overflowing data
|
350
|
-
int newSize = Math.max(engine.getSession().getPacketBufferSize(), engine.getSession().getApplicationBufferSize());
|
351
|
-
dst.resize(newSize + dst.position());
|
352
|
-
// retry the operation
|
353
|
-
retryOp = true;
|
354
|
-
break;
|
355
|
-
case BUFFER_UNDERFLOW:
|
356
|
-
// need to wait for more data to come in before we retry
|
357
|
-
retryOp = false;
|
358
|
-
break;
|
359
|
-
case CLOSED:
|
360
|
-
closed = true;
|
361
|
-
retryOp = false;
|
362
|
-
break;
|
363
|
-
default:
|
364
|
-
// other case is OK. We're done here.
|
365
|
-
retryOp = false;
|
366
|
-
}
|
367
|
-
if (res.getHandshakeStatus() == HandshakeStatus.FINISHED) {
|
368
|
-
handshake = true;
|
369
|
-
}
|
370
|
-
}
|
371
|
-
|
372
|
-
return res;
|
373
|
-
}
|
374
|
-
|
375
|
-
@JRubyMethod
|
376
|
-
public IRubyObject read() {
|
377
|
-
try {
|
378
|
-
inboundNetData.flip();
|
379
|
-
|
380
|
-
if(!inboundNetData.hasRemaining()) {
|
381
|
-
return getRuntime().getNil();
|
382
|
-
}
|
383
|
-
|
384
|
-
MiniSSLBuffer inboundAppData = new MiniSSLBuffer(engine.getSession().getApplicationBufferSize());
|
385
|
-
doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData);
|
386
|
-
|
387
|
-
HandshakeStatus handshakeStatus = engine.getHandshakeStatus();
|
388
|
-
boolean done = false;
|
389
|
-
while (!done) {
|
390
|
-
SSLEngineResult res;
|
391
|
-
switch (handshakeStatus) {
|
392
|
-
case NEED_WRAP:
|
393
|
-
res = doOp(SSLOperation.WRAP, inboundAppData, outboundNetData);
|
394
|
-
handshakeStatus = res.getHandshakeStatus();
|
395
|
-
break;
|
396
|
-
case NEED_UNWRAP:
|
397
|
-
res = doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData);
|
398
|
-
if (res.getStatus() == Status.BUFFER_UNDERFLOW) {
|
399
|
-
// need more data before we can shake more hands
|
400
|
-
done = true;
|
401
|
-
}
|
402
|
-
handshakeStatus = res.getHandshakeStatus();
|
403
|
-
break;
|
404
|
-
case NEED_TASK:
|
405
|
-
Runnable runnable;
|
406
|
-
while ((runnable = engine.getDelegatedTask()) != null) {
|
407
|
-
runnable.run();
|
408
|
-
}
|
409
|
-
handshakeStatus = engine.getHandshakeStatus();
|
410
|
-
break;
|
411
|
-
default:
|
412
|
-
done = true;
|
413
|
-
}
|
414
|
-
}
|
415
|
-
|
416
|
-
if (inboundNetData.hasRemaining()) {
|
417
|
-
inboundNetData.compact();
|
418
|
-
} else {
|
419
|
-
inboundNetData.clear();
|
420
|
-
}
|
421
|
-
|
422
|
-
ByteList appDataByteList = inboundAppData.asByteList();
|
423
|
-
if (appDataByteList == null) {
|
424
|
-
return getRuntime().getNil();
|
425
|
-
}
|
426
|
-
|
427
|
-
return RubyString.newString(getRuntime(), appDataByteList);
|
428
|
-
} catch (SSLException e) {
|
429
|
-
throw newSSLError(getRuntime(), e);
|
430
|
-
}
|
431
|
-
}
|
432
|
-
|
433
|
-
@JRubyMethod
|
434
|
-
public IRubyObject write(IRubyObject arg) {
|
435
|
-
byte[] bls = arg.convertToString().getBytes();
|
436
|
-
outboundAppData = new MiniSSLBuffer(bls);
|
437
|
-
|
438
|
-
return getRuntime().newFixnum(bls.length);
|
439
|
-
}
|
440
|
-
|
441
|
-
@JRubyMethod
|
442
|
-
public IRubyObject extract(ThreadContext context) {
|
443
|
-
try {
|
444
|
-
ByteList dataByteList = outboundNetData.asByteList();
|
445
|
-
if (dataByteList != null) {
|
446
|
-
return RubyString.newString(context.runtime, dataByteList);
|
447
|
-
}
|
448
|
-
|
449
|
-
if (!outboundAppData.hasRemaining()) {
|
450
|
-
return context.nil;
|
451
|
-
}
|
452
|
-
|
453
|
-
outboundNetData.clear();
|
454
|
-
doOp(SSLOperation.WRAP, outboundAppData, outboundNetData);
|
455
|
-
dataByteList = outboundNetData.asByteList();
|
456
|
-
if (dataByteList == null) {
|
457
|
-
return context.nil;
|
458
|
-
}
|
459
|
-
|
460
|
-
return RubyString.newString(context.runtime, dataByteList);
|
461
|
-
} catch (SSLException e) {
|
462
|
-
throw newSSLError(getRuntime(), e);
|
463
|
-
}
|
464
|
-
}
|
465
|
-
|
466
|
-
@JRubyMethod
|
467
|
-
public IRubyObject peercert(ThreadContext context) throws CertificateEncodingException {
|
468
|
-
Certificate peerCert;
|
469
|
-
try {
|
470
|
-
peerCert = engine.getSession().getPeerCertificates()[0];
|
471
|
-
} catch (SSLPeerUnverifiedException e) {
|
472
|
-
peerCert = lastCheckedCert0; // null if trust check did not happen
|
473
|
-
}
|
474
|
-
return peerCert == null ? context.nil : JavaEmbedUtils.javaToRuby(context.runtime, peerCert.getEncoded());
|
475
|
-
}
|
476
|
-
|
477
|
-
@JRubyMethod(name = "init?")
|
478
|
-
public IRubyObject isInit(ThreadContext context) {
|
479
|
-
return handshake ? getRuntime().getFalse() : getRuntime().getTrue();
|
480
|
-
}
|
481
|
-
|
482
|
-
@JRubyMethod
|
483
|
-
public IRubyObject shutdown() {
|
484
|
-
if (closed || engine.isInboundDone() && engine.isOutboundDone()) {
|
485
|
-
if (engine.isOutboundDone()) {
|
486
|
-
engine.closeOutbound();
|
487
|
-
}
|
488
|
-
return getRuntime().getTrue();
|
489
|
-
} else {
|
490
|
-
return getRuntime().getFalse();
|
491
|
-
}
|
492
|
-
}
|
493
|
-
|
494
|
-
private static RubyClass getSSLError(Ruby runtime) {
|
495
|
-
return (RubyClass) ((RubyModule) runtime.getModule("Puma").getConstantAt("MiniSSL")).getConstantAt("SSLError");
|
496
|
-
}
|
497
|
-
|
498
|
-
private static RaiseException newSSLError(Ruby runtime, SSLException cause) {
|
499
|
-
return newError(runtime, getSSLError(runtime), cause.toString(), cause);
|
500
|
-
}
|
501
|
-
|
502
|
-
private static RaiseException newError(Ruby runtime, RubyClass errorClass, String message, Throwable cause) {
|
503
|
-
RaiseException ex = new RaiseException(runtime, errorClass, message, true);
|
504
|
-
ex.initCause(cause);
|
505
|
-
return ex;
|
506
|
-
}
|
507
|
-
|
508
|
-
}
|