Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eliminate logging overhead from JRuby SSL #761

Merged
merged 1 commit into from Aug 14, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
75 changes: 4 additions & 71 deletions ext/puma_http11/org/jruby/puma/MiniSSL.java
@@ -1,7 +1,6 @@
package org.jruby.puma;

import org.jruby.Ruby;
import org.jruby.RubyBoolean;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
Expand Down Expand Up @@ -39,9 +38,6 @@ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
}
};

// set to true to switch on our low-fi trace logging
private static boolean DEBUG = false;

public static void createMiniSSL(Ruby runtime) {
RubyModule mPuma = runtime.defineModule("Puma");
RubyModule ssl = mPuma.defineModuleUnder("MiniSSL");
Expand Down Expand Up @@ -170,12 +166,7 @@ public IRubyObject initialize(ThreadContext threadContext, IRubyObject miniSSLCo
public IRubyObject inject(IRubyObject arg) {
try {
byte[] bytes = arg.convertToString().getBytes();

log("Net Data post pre-inject: " + inboundNetData);
inboundNetData.put(bytes);
log("Net Data post post-inject: " + inboundNetData);

log("inject(): " + bytes.length + " encrypted bytes from request");
return this;
} catch (Exception e) {
e.printStackTrace();
Expand Down Expand Up @@ -205,17 +196,13 @@ private SSLEngineResult doOp(SSLOperation sslOp, MiniSSLBuffer src, MiniSSLBuffe

switch (res.getStatus()) {
case BUFFER_OVERFLOW:
log("SSLOp#doRun(): overflow");
log("SSLOp#doRun(): dst data at overflow: " + dst);
// increase the buffer size to accommodate the overflowing data
int newSize = Math.max(engine.getSession().getPacketBufferSize(), engine.getSession().getApplicationBufferSize());
dst.resize(newSize + dst.position());
// retry the operation
retryOp = true;
break;
case BUFFER_UNDERFLOW:
log("SSLOp#doRun(): underflow");
log("SSLOp#doRun(): src data at underflow: " + src);
// need to wait for more data to come in before we retry
retryOp = false;
break;
Expand Down Expand Up @@ -245,25 +232,18 @@ public IRubyObject read() throws Exception {
return getRuntime().getNil();
}

log("read(): inboundNetData prepped for read: " + inboundNetData);

MiniSSLBuffer inboundAppData = new MiniSSLBuffer(engine.getSession().getApplicationBufferSize());
SSLEngineResult res = doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData);
log("read(): after initial unwrap", engine, res);

log("read(): Net Data post unwrap: " + inboundNetData);
doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData);

HandshakeStatus handshakeStatus = engine.getHandshakeStatus();
boolean done = false;
while (!done) {
switch (handshakeStatus) {
case NEED_WRAP:
res = doOp(SSLOperation.WRAP, inboundAppData, outboundNetData);
log("read(): after handshake wrap", engine, res);
doOp(SSLOperation.WRAP, inboundAppData, outboundNetData);
break;
case NEED_UNWRAP:
res = doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData);
log("read(): after handshake unwrap", engine, res);
SSLEngineResult res = doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData);
if (res.getStatus() == Status.BUFFER_UNDERFLOW) {
// need more data before we can shake more hands
done = true;
Expand All @@ -276,13 +256,9 @@ public IRubyObject read() throws Exception {
}

if (inboundNetData.hasRemaining()) {
log("Net Data post pre-compact: " + inboundNetData);
inboundNetData.compact();
log("Net Data post post-compact: " + inboundNetData);
} else {
log("Net Data post pre-reset: " + inboundNetData);
inboundNetData.clear();
log("Net Data post post-reset: " + inboundNetData);
}

ByteList appDataByteList = inboundAppData.asByteList();
Expand All @@ -292,54 +268,15 @@ public IRubyObject read() throws Exception {

RubyString str = getRuntime().newString("");
str.setValue(appDataByteList);

logPlain("\n");
log("read(): begin dump of request data >>>>\n");
if (str.asJavaString().getBytes().length < 1000) {
logPlain(str.asJavaString() + "\n");
}
logPlain("Num bytes: " + str.asJavaString().getBytes().length + "\n");
log("read(): end dump of request data <<<<\n");
return str;
} catch (Exception e) {
if (DEBUG) {
e.printStackTrace();
}
throw getRuntime().newEOFError(e.getMessage());
}
}

private static void log(String str, SSLEngine engine, SSLEngineResult result) {
if (DEBUG) {
log(str + " " + result.getStatus() + "/" + engine.getHandshakeStatus() +
"---bytes consumed: " + result.bytesConsumed() +
", bytes produced: " + result.bytesProduced());
}
}

private static void log(String str) {
if (DEBUG) {
System.out.println("MiniSSL.java: " + str);
}
}

private static void logPlain(String str) {
if (DEBUG) {
System.out.println(str);
}
}

@JRubyMethod
public IRubyObject write(IRubyObject arg) {
try {
log("write(): begin dump of response data >>>>\n");
logPlain("\n");
if (arg.asJavaString().getBytes().length < 1000) {
logPlain(arg.asJavaString() + "\n");
}
logPlain("Num bytes: " + arg.asJavaString().getBytes().length + "\n");
log("write(): end dump of response data <<<<\n");

byte[] bls = arg.convertToString().getBytes();
outboundAppData = new MiniSSLBuffer(bls);

Expand All @@ -365,9 +302,7 @@ public IRubyObject extract() throws SSLException {
}

outboundNetData.clear();
SSLEngineResult res = doOp(SSLOperation.WRAP, outboundAppData, outboundNetData);
log("extract(): bytes consumed: " + res.bytesConsumed() + "\n");
log("extract(): bytes produced: " + res.bytesProduced() + "\n");
doOp(SSLOperation.WRAP, outboundAppData, outboundNetData);
dataByteList = outboundNetData.asByteList();
if (dataByteList == null) {
return getRuntime().getNil();
Expand All @@ -376,8 +311,6 @@ public IRubyObject extract() throws SSLException {
RubyString str = getRuntime().newString("");
str.setValue(dataByteList);

log("extract(): " + dataByteList.getRealSize() + " encrypted bytes for response");

return str;
} catch (Exception e) {
e.printStackTrace();
Expand Down