Skip to content

Commit

Permalink
Fix unwrapping of large payloads.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gregory Brail committed Sep 11, 2014
1 parent 7cdf809 commit 4dbf863
Showing 1 changed file with 49 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

Expand Down Expand Up @@ -443,43 +445,58 @@ private void deliverWriteBuffer(Context cx, boolean shutdown)

private boolean doUnwrap(Context cx)
{
QueuedChunk qc = incomingChunks.peek();
QueuedChunk qc = incomingChunks.poll();
ByteBuffer bb = (qc == null ? EMPTY : qc.buf);

SSLEngineResult result;
do {
if (log.isTraceEnabled()) {
log.trace("{} Unwrapping {}", id, bb);
}
do {
if (log.isTraceEnabled()) {
log.trace("{} Unwrapping {}", id, bb);
}

try {
result = engine.unwrap(bb, readBuf);
} catch (SSLException ssle) {
handleEncodingError(cx, qc, ssle);
if (qc != null) {
incomingChunks.remove();
try {
result = engine.unwrap(bb, readBuf);
} catch (SSLException ssle) {
handleEncodingError(cx, qc, ssle);
return false;
}
return false;
}

if (log.isTraceEnabled()) {
log.trace("unwrap result: {}", result);
}
if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) {
readBuf = Utils.doubleBuffer(readBuf);
if (log.isTraceEnabled()) {
log.trace("unwrap result: {}", result);
}
if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) {
// Retry with more space in the output buffer
readBuf = Utils.doubleBuffer(readBuf);
}
} while (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW);

if ((result.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW) && (qc != null)) {
// Deliver the write callback so that we get some more data
qc.deliverCallback(cx, this);
QueuedChunk nc = incomingChunks.poll();
if (nc == null) {
break;
}
nc.buf = Utils.catBuffers(qc.buf, nc.buf);
qc = nc;
bb = qc.buf;
} else {
break;
}
} while (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW);
} while (true);

boolean deliverShutdown = false;
if ((result.getStatus() == SSLEngineResult.Status.CLOSED) && !receivedShutdown) {
receivedShutdown = true;
deliverShutdown = true;
}

if ((qc != null) && !bb.hasRemaining()) {
incomingChunks.remove();
if (qc.callback != null) {
qc.callback.call(cx, this, this, ScriptRuntime.emptyArgs);
if (qc != null) {
if (qc.buf.hasRemaining()) {
incomingChunks.addFirst(qc);
} else {
qc.deliverCallback(cx, this);
}
}

Expand Down Expand Up @@ -823,14 +840,22 @@ public static Object getCurrentCipher(Context cx, Scriptable thisObj, Object[] a

static final class QueuedChunk
{
final ByteBuffer buf;
final Function callback;
ByteBuffer buf;
Function callback;
boolean shutdown;

QueuedChunk(ByteBuffer buf, Function callback)
{
this.buf = buf;
this.callback = callback;
}

void deliverCallback(Context cx, Scriptable scope)
{
if (callback != null) {
callback.call(cx, scope, scope, ScriptRuntime.emptyArgs);
callback = null;
}
}
}
}

0 comments on commit 4dbf863

Please sign in to comment.