Class SslHandler
- java.lang.Object
-
- org.jboss.netty.channel.SimpleChannelUpstreamHandler
-
- org.jboss.netty.handler.codec.frame.FrameDecoder
-
- org.jboss.netty.handler.ssl.SslHandler
-
- All Implemented Interfaces:
ChannelDownstreamHandler
,ChannelHandler
,ChannelUpstreamHandler
,LifeCycleAwareChannelHandler
public class SslHandler extends FrameDecoder implements ChannelDownstreamHandler
Adds SSL · TLS and StartTLS support to aChannel
. Please refer to the "SecureChat" example in the distribution or the web site for the detailed usage.Beginning the handshake
You must make sure not to write a message while the handshake is in progress unless you are renegotiating. You will be notified by the
ChannelFuture
which is returned by thehandshake()
method when the handshake process succeeds or fails.Handshake
If
isIssueHandshake()
isfalse
(default) you will need to take care of callinghandshake()
by your own. In most situations wereSslHandler
is used in 'client mode' you want to issue a handshake once the connection was established. ifsetIssueHandshake(boolean)
is set totrue
you don't need to worry about this as theSslHandler
will take care of it.Renegotiation
If
enableRenegotiation
istrue
(default) and the initial handshake has been done successfully, you can callhandshake()
to trigger the renegotiation.If
enableRenegotiation
isfalse
, an attempt to trigger renegotiation will result in the connection closure.Please note that TLS renegotiation had a security issue before. If your runtime environment did not fix it, please make sure to disable TLS renegotiation by calling
setEnableRenegotiation(boolean)
withfalse
. For more information, please refer to the following documents:Closing the session
To close the SSL session, the
close()
method should be called to send theclose_notify
message to the remote peer. One exception is when you close theChannel
-SslHandler
intercepts the close request and send theclose_notify
message before the channel closure automatically. Once the SSL session is closed, it is not reusable, and consequently you should create a newSslHandler
with a newSSLEngine
as explained in the following section.Restarting the session
To restart the SSL session, you must remove the existing closed
SslHandler
from theChannelPipeline
, insert a newSslHandler
with a newSSLEngine
into the pipeline, and start the handshake process as described in the first section.Implementing StartTLS
StartTLS is the communication pattern that secures the wire in the middle of the plaintext connection. Please note that it is different from SSL · TLS, that secures the wire from the beginning of the connection. Typically, StartTLS is composed of three steps:
- Client sends a StartTLS request to server.
- Server sends a StartTLS response to client.
- Client begins SSL handshake.
- create a new
SslHandler
instance withstartTls
flag set totrue
, - insert the
SslHandler
to theChannelPipeline
, and - write a StartTLS response.
SslHandler
before sending the StartTLS response. Otherwise the client can send begin SSL handshake beforeSslHandler
is inserted to theChannelPipeline
, causing data corruption.The client-side implementation is much simpler.
- Write a StartTLS request,
- wait for the StartTLS response,
- create a new
SslHandler
instance withstartTls
flag set tofalse
, - insert the
SslHandler
to theChannelPipeline
, and - Initiate SSL handshake by calling
handshake()
.
Known issues
Because of a known issue with the current implementation of the SslEngine that comes with Java it may be possible that you see blocked IO-Threads while a full GC is done.
So if you are affected you can workaround this problem by adjust the cache settings like shown below:
SslContext context = ...; context.getServerSessionContext().setSessionCacheSize(someSaneSize); context.getServerSessionContext().setSessionTime(someSameTimeout);
What values to use here depends on the nature of your application and should be set based on monitoring and debugging of it. For more details see #832 in our issue tracker.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static class
SslHandler.ClosingChannelFutureListener
private static class
SslHandler.PendingWrite
private class
SslHandler.SSLEngineInboundCloseFuture
-
Nested classes/interfaces inherited from interface org.jboss.netty.channel.ChannelHandler
ChannelHandler.Sharable
-
-
Field Summary
Fields Modifier and Type Field Description private SslBufferPool
bufferPool
private static java.util.concurrent.atomic.AtomicIntegerFieldUpdater<SslHandler>
CLOSED_OUTBOUND_AND_CHANNEL_UPDATER
private int
closedOutboundAndChannel
private boolean
closeOnSslException
private ChannelHandlerContext
ctx
private static SslBufferPool
defaultBufferPool
private static java.nio.ByteBuffer
EMPTY_BUFFER
private boolean
enableRenegotiation
private javax.net.ssl.SSLEngine
engine
private ChannelFuture
handshakeFuture
(package private) java.lang.Object
handshakeLock
private boolean
handshaken
private Timeout
handshakeTimeout
private long
handshakeTimeoutInMillis
private boolean
handshaking
private static java.util.regex.Pattern
IGNORABLE_CLASS_IN_STACK
private static java.util.regex.Pattern
IGNORABLE_ERROR_MESSAGE
(package private) int
ignoreClosedChannelException
(package private) java.lang.Object
ignoreClosedChannelExceptionLock
private boolean
issueHandshake
private static InternalLogger
logger
private int
packetLength
private java.util.Queue<MessageEvent>
pendingEncryptedWrites
private NonReentrantLock
pendingEncryptedWritesLock
private java.util.Queue<SslHandler.PendingWrite>
pendingUnencryptedWrites
private NonReentrantLock
pendingUnencryptedWritesLock
private static java.util.concurrent.atomic.AtomicIntegerFieldUpdater<SslHandler>
SENT_CLOSE_NOTIFY_UPDATER
private static java.util.concurrent.atomic.AtomicIntegerFieldUpdater<SslHandler>
SENT_FIRST_MESSAGE_UPDATER
private int
sentCloseNotify
private int
sentFirstMessage
private SslHandler.SSLEngineInboundCloseFuture
sslEngineCloseFuture
private boolean
startTls
private Timer
timer
private boolean
writeBeforeHandshakeDone
-
Fields inherited from class org.jboss.netty.handler.codec.frame.FrameDecoder
cumulation, DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS
-
-
Constructor Summary
Constructors Constructor Description SslHandler(javax.net.ssl.SSLEngine engine)
Creates a new instance.SslHandler(javax.net.ssl.SSLEngine engine, boolean startTls)
Creates a new instance.SslHandler(javax.net.ssl.SSLEngine engine, SslBufferPool bufferPool)
Creates a new instance.SslHandler(javax.net.ssl.SSLEngine engine, SslBufferPool bufferPool, boolean startTls)
Creates a new instance.SslHandler(javax.net.ssl.SSLEngine engine, SslBufferPool bufferPool, boolean startTls, Timer timer, long handshakeTimeoutInMillis)
Creates a new instance.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
afterRemove(ChannelHandlerContext ctx)
Fail all pending writes which we were not able to flush outvoid
beforeAdd(ChannelHandlerContext ctx)
private void
cancelHandshakeTimeout()
void
channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
Loop over all the pending writes and fail them.void
channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
Callshandshake()
once theChannel
is connectedvoid
channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e)
Invoked when aChannel
was disconnected from its remote peer.ChannelFuture
close()
Sends an SSLclose_notify
message to the specified channel and destroys the underlyingSSLEngine
.private void
closeEngine()
private void
closeOutboundAndChannel(ChannelHandlerContext context, ChannelStateEvent e)
protected java.lang.Object
decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer in)
Decodes the received packets so far into a frame.void
exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
Invoked when an exception was raised by an I/O thread or aChannelHandler
.private void
flushPendingEncryptedWrites(ChannelHandlerContext ctx)
boolean
getCloseOnSSLException()
static SslBufferPool
getDefaultBufferPool()
Returns the defaultSslBufferPool
used when no pool is specified in the constructor.private static int
getEncryptedPacketLength(ChannelBuffer buffer, int offset)
Return how much bytes can be read out of the encrypted data.javax.net.ssl.SSLEngine
getEngine()
Returns theSSLEngine
which is used by this handler.long
getHandshakeTimeout()
Return the timeout (in ms) after which theChannelFuture
ofhandshake()
will be failed, while a handshake is in progressprivate static short
getShort(ChannelBuffer buf, int offset)
Reads a big-endian short integer from the buffer.ChannelFuture
getSSLEngineInboundCloseFuture()
Return theChannelFuture
that will get notified if the inbound of theSSLEngine
will get closed.void
handleDownstream(ChannelHandlerContext context, ChannelEvent evt)
Handles the specified downstream event.private void
handleRenegotiation(javax.net.ssl.SSLEngineResult.HandshakeStatus handshakeStatus)
ChannelFuture
handshake()
Starts an SSL / TLS handshake for the specified channel.private boolean
ignoreException(java.lang.Throwable t)
Checks if the givenThrowable
can be ignore and just "swallowed" When an ssl connection is closed a close_notify message is sent.boolean
isEnableRenegotiation()
Returnstrue
if and only if TLS renegotiation is enabled.static boolean
isEncrypted(ChannelBuffer buffer)
Returnstrue
if the givenChannelBuffer
is encrypted.boolean
isIssueHandshake()
Returnstrue
if the automatic handshake is enabledprivate void
offerEncryptedWriteRequest(MessageEvent encryptedWrite)
private void
runDelegatedTasks()
Fetches all delegated tasks from theSSLEngine
and runs them immediately.void
setCloseOnSSLException(boolean closeOnSslException)
void
setEnableRenegotiation(boolean enableRenegotiation)
Enables or disables TLS renegotiation.private void
setHandshakeFailure(Channel channel, javax.net.ssl.SSLException cause)
private void
setHandshakeSuccess(Channel channel)
private boolean
setHandshakeSuccessIfStillHandshaking(Channel channel)
Works around some AndroidSSLEngine
implementations that skipSSLEngineResult.HandshakeStatus.FINISHED
and go straight intoSSLEngineResult.HandshakeStatus.NOT_HANDSHAKING
when handshake is finished.void
setIssueHandshake(boolean issueHandshake)
Enables or disables the automatic handshake once theChannel
is connected.private ChannelBuffer
unwrap(ChannelHandlerContext ctx, Channel channel, java.nio.ByteBuffer nioInNetBuf, int initialNettyOutAppBufCapacity, boolean mightNeedHandshake)
Unwraps inbound SSL records.private void
unwrapNonAppData(ChannelHandlerContext ctx, Channel channel, boolean mightNeedHandshake)
CallsSSLEngine.unwrap(ByteBuffer, ByteBuffer)
with an empty buffer to handle handshakes, etc.private void
wrap(ChannelHandlerContext context, Channel channel)
private ChannelFuture
wrapNonAppData(ChannelHandlerContext ctx, Channel channel)
-
Methods inherited from class org.jboss.netty.handler.codec.frame.FrameDecoder
actualReadableBytes, afterAdd, appendToCumulation, beforeRemove, cleanup, decodeLast, extractFrame, getMaxCumulationBufferCapacity, getMaxCumulationBufferComponents, internalBuffer, isUnfold, messageReceived, newCumulationBuffer, replace, setMaxCumulationBufferCapacity, setMaxCumulationBufferComponents, setUnfold, unfoldAndFireMessageReceived, updateCumulation
-
Methods inherited from class org.jboss.netty.channel.SimpleChannelUpstreamHandler
channelBound, channelInterestChanged, channelOpen, channelUnbound, childChannelClosed, childChannelOpen, handleUpstream, writeComplete
-
-
-
-
Field Detail
-
logger
private static final InternalLogger logger
-
EMPTY_BUFFER
private static final java.nio.ByteBuffer EMPTY_BUFFER
-
IGNORABLE_CLASS_IN_STACK
private static final java.util.regex.Pattern IGNORABLE_CLASS_IN_STACK
-
IGNORABLE_ERROR_MESSAGE
private static final java.util.regex.Pattern IGNORABLE_ERROR_MESSAGE
-
defaultBufferPool
private static SslBufferPool defaultBufferPool
-
ctx
private volatile ChannelHandlerContext ctx
-
engine
private final javax.net.ssl.SSLEngine engine
-
bufferPool
private final SslBufferPool bufferPool
-
startTls
private final boolean startTls
-
enableRenegotiation
private volatile boolean enableRenegotiation
-
handshakeLock
final java.lang.Object handshakeLock
-
handshaking
private boolean handshaking
-
handshaken
private volatile boolean handshaken
-
handshakeFuture
private volatile ChannelFuture handshakeFuture
-
sentFirstMessage
private volatile int sentFirstMessage
-
sentCloseNotify
private volatile int sentCloseNotify
-
closedOutboundAndChannel
private volatile int closedOutboundAndChannel
-
SENT_FIRST_MESSAGE_UPDATER
private static final java.util.concurrent.atomic.AtomicIntegerFieldUpdater<SslHandler> SENT_FIRST_MESSAGE_UPDATER
-
SENT_CLOSE_NOTIFY_UPDATER
private static final java.util.concurrent.atomic.AtomicIntegerFieldUpdater<SslHandler> SENT_CLOSE_NOTIFY_UPDATER
-
CLOSED_OUTBOUND_AND_CHANNEL_UPDATER
private static final java.util.concurrent.atomic.AtomicIntegerFieldUpdater<SslHandler> CLOSED_OUTBOUND_AND_CHANNEL_UPDATER
-
ignoreClosedChannelException
int ignoreClosedChannelException
-
ignoreClosedChannelExceptionLock
final java.lang.Object ignoreClosedChannelExceptionLock
-
pendingUnencryptedWrites
private final java.util.Queue<SslHandler.PendingWrite> pendingUnencryptedWrites
-
pendingUnencryptedWritesLock
private final NonReentrantLock pendingUnencryptedWritesLock
-
pendingEncryptedWrites
private final java.util.Queue<MessageEvent> pendingEncryptedWrites
-
pendingEncryptedWritesLock
private final NonReentrantLock pendingEncryptedWritesLock
-
issueHandshake
private volatile boolean issueHandshake
-
writeBeforeHandshakeDone
private volatile boolean writeBeforeHandshakeDone
-
sslEngineCloseFuture
private final SslHandler.SSLEngineInboundCloseFuture sslEngineCloseFuture
-
closeOnSslException
private boolean closeOnSslException
-
packetLength
private int packetLength
-
timer
private final Timer timer
-
handshakeTimeoutInMillis
private final long handshakeTimeoutInMillis
-
handshakeTimeout
private Timeout handshakeTimeout
-
-
Constructor Detail
-
SslHandler
public SslHandler(javax.net.ssl.SSLEngine engine)
Creates a new instance.- Parameters:
engine
- theSSLEngine
this handler will use
-
SslHandler
public SslHandler(javax.net.ssl.SSLEngine engine, SslBufferPool bufferPool)
Creates a new instance.- Parameters:
engine
- theSSLEngine
this handler will usebufferPool
- theSslBufferPool
where this handler will acquire the buffers required by theSSLEngine
-
SslHandler
public SslHandler(javax.net.ssl.SSLEngine engine, boolean startTls)
Creates a new instance.- Parameters:
engine
- theSSLEngine
this handler will usestartTls
-true
if the first write request shouldn't be encrypted by theSSLEngine
-
SslHandler
public SslHandler(javax.net.ssl.SSLEngine engine, SslBufferPool bufferPool, boolean startTls)
Creates a new instance.- Parameters:
engine
- theSSLEngine
this handler will usebufferPool
- theSslBufferPool
where this handler will acquire the buffers required by theSSLEngine
startTls
-true
if the first write request shouldn't be encrypted by theSSLEngine
-
SslHandler
public SslHandler(javax.net.ssl.SSLEngine engine, SslBufferPool bufferPool, boolean startTls, Timer timer, long handshakeTimeoutInMillis)
Creates a new instance.- Parameters:
engine
- theSSLEngine
this handler will usebufferPool
- theSslBufferPool
where this handler will acquire the buffers required by theSSLEngine
startTls
-true
if the first write request shouldn't be encrypted by theSSLEngine
timer
- theTimer
which will be used to process the timeout of thehandshake()
. Be aware that the givenTimer
will not get stopped automaticly, so it is up to you to cleanup once you not need it anymorehandshakeTimeoutInMillis
- the time in milliseconds after whic thehandshake()
will be failed, and so the future notified
-
-
Method Detail
-
getDefaultBufferPool
public static SslBufferPool getDefaultBufferPool()
Returns the defaultSslBufferPool
used when no pool is specified in the constructor.
-
getEngine
public javax.net.ssl.SSLEngine getEngine()
Returns theSSLEngine
which is used by this handler.
-
handshake
public ChannelFuture handshake()
Starts an SSL / TLS handshake for the specified channel.- Returns:
- a
ChannelFuture
which is notified when the handshake succeeds or fails.
-
close
public ChannelFuture close()
Sends an SSLclose_notify
message to the specified channel and destroys the underlyingSSLEngine
.
-
isEnableRenegotiation
public boolean isEnableRenegotiation()
Returnstrue
if and only if TLS renegotiation is enabled.
-
setEnableRenegotiation
public void setEnableRenegotiation(boolean enableRenegotiation)
Enables or disables TLS renegotiation.
-
setIssueHandshake
public void setIssueHandshake(boolean issueHandshake)
-
isIssueHandshake
public boolean isIssueHandshake()
Returnstrue
if the automatic handshake is enabled
-
getSSLEngineInboundCloseFuture
public ChannelFuture getSSLEngineInboundCloseFuture()
Return theChannelFuture
that will get notified if the inbound of theSSLEngine
will get closed. This method will return the sameChannelFuture
all the time. For more informations see the apidocs ofSSLEngine
-
getHandshakeTimeout
public long getHandshakeTimeout()
Return the timeout (in ms) after which theChannelFuture
ofhandshake()
will be failed, while a handshake is in progress
-
setCloseOnSSLException
public void setCloseOnSSLException(boolean closeOnSslException)
If set totrue
, theChannel
will automatically get closed one aSSLException
was caught. This is most times what you want, as after this its almost impossible to recover. Anyway the default isfalse
to not break compatibility with older releases. This will be changed totrue
in the next major release.
-
getCloseOnSSLException
public boolean getCloseOnSSLException()
-
handleDownstream
public void handleDownstream(ChannelHandlerContext context, ChannelEvent evt) throws java.lang.Exception
Description copied from interface:ChannelDownstreamHandler
Handles the specified downstream event.- Specified by:
handleDownstream
in interfaceChannelDownstreamHandler
- Parameters:
context
- the context object for this handlerevt
- the downstream event to process or intercept- Throws:
java.lang.Exception
-
cancelHandshakeTimeout
private void cancelHandshakeTimeout()
-
channelDisconnected
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws java.lang.Exception
Description copied from class:SimpleChannelUpstreamHandler
Invoked when aChannel
was disconnected from its remote peer.- Overrides:
channelDisconnected
in classFrameDecoder
- Throws:
java.lang.Exception
-
closeEngine
private void closeEngine()
-
exceptionCaught
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws java.lang.Exception
Description copied from class:SimpleChannelUpstreamHandler
Invoked when an exception was raised by an I/O thread or aChannelHandler
.- Overrides:
exceptionCaught
in classFrameDecoder
- Throws:
java.lang.Exception
-
ignoreException
private boolean ignoreException(java.lang.Throwable t)
Checks if the givenThrowable
can be ignore and just "swallowed" When an ssl connection is closed a close_notify message is sent. After that the peer also sends close_notify however, it's not mandatory to receive the close_notify. The party who sent the initial close_notify can close the connection immediately then the peer will get connection reset error.
-
isEncrypted
public static boolean isEncrypted(ChannelBuffer buffer)
Returnstrue
if the givenChannelBuffer
is encrypted. Be aware that this method will not increase the readerIndex of the givenChannelBuffer
.- Parameters:
buffer
- TheChannelBuffer
to read from. Be aware that it must have at least 5 bytes to read, otherwise it will throw anIllegalArgumentException
.- Returns:
- encrypted
true
if theChannelBuffer
is encrypted,false
otherwise. - Throws:
java.lang.IllegalArgumentException
- Is thrown if the givenChannelBuffer
has not at least 5 bytes to read.
-
getEncryptedPacketLength
private static int getEncryptedPacketLength(ChannelBuffer buffer, int offset)
Return how much bytes can be read out of the encrypted data. Be aware that this method will not increase the readerIndex of the givenChannelBuffer
.- Parameters:
buffer
- TheChannelBuffer
to read from. Be aware that it must have at least 5 bytes to read, otherwise it will throw anIllegalArgumentException
.- Returns:
- length
The length of the encrypted packet that is included in the buffer. This will
return
-1
if the givenChannelBuffer
is not encrypted at all. - Throws:
java.lang.IllegalArgumentException
- Is thrown if the givenChannelBuffer
has not at least 5 bytes to read.
-
decode
protected java.lang.Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer in) throws java.lang.Exception
Description copied from class:FrameDecoder
Decodes the received packets so far into a frame. If an sub-class wants to extract a frame out of the buffer it should use theFrameDecoder.extractFrame(ChannelBuffer, int, int)
method, to make optimizations easier later.- Specified by:
decode
in classFrameDecoder
- Parameters:
ctx
- the context of this handlerchannel
- the current channelin
- the cumulative buffer of received packets so far. Note that the buffer might be empty, which means you should not make an assumption that the buffer contains at least one byte in your decoder implementation.- Returns:
- the decoded frame if a full frame was received and decoded.
null
if there's not enough data in the buffer to decode a frame. - Throws:
java.lang.Exception
-
getShort
private static short getShort(ChannelBuffer buf, int offset)
Reads a big-endian short integer from the buffer. Please note that we do not useChannelBuffer.getShort(int)
because it might be a little-endian buffer.
-
wrap
private void wrap(ChannelHandlerContext context, Channel channel) throws javax.net.ssl.SSLException
- Throws:
javax.net.ssl.SSLException
-
offerEncryptedWriteRequest
private void offerEncryptedWriteRequest(MessageEvent encryptedWrite)
-
flushPendingEncryptedWrites
private void flushPendingEncryptedWrites(ChannelHandlerContext ctx)
-
wrapNonAppData
private ChannelFuture wrapNonAppData(ChannelHandlerContext ctx, Channel channel) throws javax.net.ssl.SSLException
- Throws:
javax.net.ssl.SSLException
-
unwrapNonAppData
private void unwrapNonAppData(ChannelHandlerContext ctx, Channel channel, boolean mightNeedHandshake) throws javax.net.ssl.SSLException
CallsSSLEngine.unwrap(ByteBuffer, ByteBuffer)
with an empty buffer to handle handshakes, etc.- Throws:
javax.net.ssl.SSLException
-
unwrap
private ChannelBuffer unwrap(ChannelHandlerContext ctx, Channel channel, java.nio.ByteBuffer nioInNetBuf, int initialNettyOutAppBufCapacity, boolean mightNeedHandshake) throws javax.net.ssl.SSLException
Unwraps inbound SSL records.- Throws:
javax.net.ssl.SSLException
-
handleRenegotiation
private void handleRenegotiation(javax.net.ssl.SSLEngineResult.HandshakeStatus handshakeStatus)
-
runDelegatedTasks
private void runDelegatedTasks()
Fetches all delegated tasks from theSSLEngine
and runs them immediately.
-
setHandshakeSuccessIfStillHandshaking
private boolean setHandshakeSuccessIfStillHandshaking(Channel channel)
Works around some AndroidSSLEngine
implementations that skipSSLEngineResult.HandshakeStatus.FINISHED
and go straight intoSSLEngineResult.HandshakeStatus.NOT_HANDSHAKING
when handshake is finished.- Returns:
true
if and only if the workaround has been applied and thushandshakeFuture
has been marked as success by this method
-
setHandshakeSuccess
private void setHandshakeSuccess(Channel channel)
-
setHandshakeFailure
private void setHandshakeFailure(Channel channel, javax.net.ssl.SSLException cause)
-
closeOutboundAndChannel
private void closeOutboundAndChannel(ChannelHandlerContext context, ChannelStateEvent e)
-
beforeAdd
public void beforeAdd(ChannelHandlerContext ctx) throws java.lang.Exception
- Specified by:
beforeAdd
in interfaceLifeCycleAwareChannelHandler
- Overrides:
beforeAdd
in classFrameDecoder
- Throws:
java.lang.Exception
-
afterRemove
public void afterRemove(ChannelHandlerContext ctx) throws java.lang.Exception
Fail all pending writes which we were not able to flush out- Specified by:
afterRemove
in interfaceLifeCycleAwareChannelHandler
- Overrides:
afterRemove
in classFrameDecoder
- Throws:
java.lang.Exception
-
channelConnected
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws java.lang.Exception
Callshandshake()
once theChannel
is connected- Overrides:
channelConnected
in classSimpleChannelUpstreamHandler
- Throws:
java.lang.Exception
-
channelClosed
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws java.lang.Exception
Loop over all the pending writes and fail them. See #305 for more details.- Overrides:
channelClosed
in classFrameDecoder
- Throws:
java.lang.Exception
-
-