}
@Override
public NextAction handleRead(final FilterChainContext ctx)
throws IOException {
final Connection connection = ctx.getConnection();
final SSLConnectionContext sslCtx = obtainSslConnectionContext(connection);
SSLEngine sslEngine = sslCtx.getSslEngine();
if (sslEngine != null && !isHandshaking(sslEngine)) {
return unwrapAll(ctx, sslCtx);
} else {
if (sslEngine == null) {
sslEngine = serverSSLEngineConfigurator.createSSLEngine();
sslEngine.beginHandshake();
sslCtx.configure(sslEngine);
notifyHandshakeStart(connection);
}
final Buffer buffer;
if (handshakeTimeoutMillis >= 0) {
buffer = doHandshakeSync(sslCtx, ctx, (Buffer) ctx.getMessage(),
handshakeTimeoutMillis);
} else {
buffer = makeInputRemainder(sslCtx, ctx,
doHandshakeStep(sslCtx, ctx, (Buffer) ctx.getMessage()));
}
final boolean hasRemaining = buffer != null && buffer.hasRemaining();
final boolean isHandshaking = isHandshaking(sslEngine);
if (!isHandshaking) {
notifyHandshakeComplete(connection, sslEngine);
final FilterChain connectionFilterChain = sslCtx.getNewConnectionFilterChain();
sslCtx.setNewConnectionFilterChain(null);
if (connectionFilterChain != null) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Applying new FilterChain after"
+ "SSLHandshake. Connection={0} filterchain={1}",
new Object[]{connection, connectionFilterChain});
}
connection.setProcessor(connectionFilterChain);
if (hasRemaining) {
NextAction suspendAction = ctx.getSuspendAction();
ctx.setMessage(buffer);
ctx.suspend();