From b653491a9feb62f84a3ab5738ebbadc4bbf7db71 Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Thu, 11 Dec 2014 17:48:45 +0900 Subject: [PATCH] Make SslHandler work when autoRead is turned off Related: #2958 Motivation: SslHandler currently does not issue a read() request when it is handshaking. It makes a connection with autoRead off stall, because a user's read() request can be used to read the handshake response which is invisible to the user. Modifications: - SslHandler now issues a read() request when: - the current handshake is in progress and channelReadComplete() is invoked - the current handshake is complete and a user issued a read() request during handshake - Rename flushedBeforeHandshakeDone to flushedBeforeHandshake for consistency with the new variable 'readDuringHandshake' Result: SslHandler should work regardless whether autoRead is on or off. --- .../java/io/netty/handler/ssl/SslHandler.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java index 3b683ff1e0..fc444d13a1 100644 --- a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java +++ b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java @@ -204,7 +204,8 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH private final boolean startTls; private boolean sentFirstMessage; - private boolean flushedBeforeHandshakeDone; + private boolean flushedBeforeHandshake; + private boolean readDuringHandshake; private PendingWriteQueue pendingUnencryptedWrites; private final LazyChannelPromise handshakePromise = new LazyChannelPromise(); @@ -404,7 +405,11 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH } @Override - public void read(ChannelHandlerContext ctx) { + public void read(ChannelHandlerContext ctx) throws Exception { + if (!handshakePromise.isDone()) { + readDuringHandshake = true; + } + ctx.read(); } @@ -427,7 +432,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH pendingUnencryptedWrites.add(Unpooled.EMPTY_BUFFER, ctx.voidPromise()); } if (!handshakePromise.isDone()) { - flushedBeforeHandshakeDone = true; + flushedBeforeHandshake = true; } wrap(ctx, false); ctx.flush(); @@ -884,7 +889,13 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH needsFlush = false; ctx.flush(); } - super.channelReadComplete(ctx); + + // If handshake is not finished yet, we need more data. + if (!handshakePromise.isDone() && !ctx.channel().config().isAutoRead()) { + ctx.read(); + } + + ctx.fireChannelReadComplete(); } /** @@ -948,11 +959,11 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH wrapLater = true; continue; } - if (flushedBeforeHandshakeDone) { + if (flushedBeforeHandshake) { // We need to call wrap(...) in case there was a flush done before the handshake completed. // // See https://github.com/netty/netty/pull/2437 - flushedBeforeHandshakeDone = false; + flushedBeforeHandshake = false; wrapLater = true; } @@ -1105,6 +1116,11 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH } ctx.fireUserEventTriggered(SslHandshakeCompletionEvent.SUCCESS); } + + if (readDuringHandshake && !ctx.channel().config().isAutoRead()) { + readDuringHandshake = false; + ctx.read(); + } } /**