public void renegotiateNoRequest(HttpServerExchange exchange, SslClientAuthMode newAuthMode)
     throws IOException {
   AbstractServerConnection.ConduitState oldState = serverConnection.resetChannel();
   try {
     SslClientAuthMode sslClientAuthMode = channel.getOption(Options.SSL_CLIENT_AUTH_MODE);
     if (sslClientAuthMode == SslClientAuthMode.NOT_REQUESTED) {
       SslHandshakeWaiter waiter = new SslHandshakeWaiter();
       channel.getHandshakeSetter().set(waiter);
       // we use requested, to place nicely with other auth modes
       channel.setOption(Options.SSL_CLIENT_AUTH_MODE, newAuthMode);
       channel.getSslSession().invalidate();
       channel.startHandshake();
       serverConnection.getOriginalSinkConduit().flush();
       ByteBuffer buff = ByteBuffer.wrap(new byte[1]);
       while (!waiter.isDone() && serverConnection.isOpen()) {
         int read = serverConnection.getSourceChannel().read(buff);
         if (read != 0) {
           throw new SSLPeerUnverifiedException("");
         }
         if (!waiter.isDone()) {
           serverConnection.getSourceChannel().awaitReadable();
         }
       }
     }
   } finally {
     if (oldState != null) {
       serverConnection.restoreChannel(oldState);
     }
   }
 }
 @Override
 public Certificate[] getPeerCertificates()
     throws SSLPeerUnverifiedException, RenegotiationRequiredException {
   try {
     return channel.getSslSession().getPeerCertificates();
   } catch (SSLPeerUnverifiedException e) {
     try {
       SslClientAuthMode sslClientAuthMode = channel.getOption(Options.SSL_CLIENT_AUTH_MODE);
       if (sslClientAuthMode == SslClientAuthMode.NOT_REQUESTED) {
         throw new RenegotiationRequiredException();
       }
     } catch (IOException e1) {
       // ignore, will not actually happen
     }
     throw e;
   }
 }
 public void handleEvent(final ConnectedMessageChannel channel) {
   final Pooled<ByteBuffer> pooledReceiveBuffer = connection.allocate();
   try {
     final ByteBuffer receiveBuffer = pooledReceiveBuffer.getResource();
     int res = 0;
     try {
       res = channel.receive(receiveBuffer);
     } catch (IOException e) {
       connection.handleException(e);
       return;
     }
     if (res == -1) {
       connection.handleException(client.abruptClose(connection));
       return;
     }
     if (res == 0) {
       return;
     }
     client.tracef("Received %s", receiveBuffer);
     receiveBuffer.flip();
     final byte msgType = receiveBuffer.get();
     switch (msgType) {
       case Protocol.CONNECTION_ALIVE:
         {
           client.trace("Client received connection alive");
           return;
         }
       case Protocol.CONNECTION_CLOSE:
         {
           client.trace("Client received connection close request");
           connection.handleIncomingCloseRequest();
           return;
         }
       case Protocol.STARTTLS:
         {
           client.trace("Client received STARTTLS response");
           try {
             ((SslChannel) channel).startHandshake();
           } catch (IOException e) {
             connection.handleException(e, false);
             return;
           }
           sendCapRequest(serverName);
           return;
         }
       default:
         {
           client.unknownProtocolId(msgType);
           connection.handleException(client.invalidMessage(connection));
           return;
         }
     }
   } catch (BufferUnderflowException e) {
     connection.handleException(client.invalidMessage(connection));
     return;
   } catch (BufferOverflowException e) {
     connection.handleException(client.invalidMessage(connection));
     return;
   } finally {
     pooledReceiveBuffer.free();
   }
 }
 @Override
 public String getCipherSuite() {
   return channel.getSslSession().getCipherSuite();
 }
 @Override
 public byte[] getSessionId() {
   return channel.getSslSession().getId();
 }
 public void handleEvent(final ConnectedMessageChannel channel) {
   final Pooled<ByteBuffer> pooledReceiveBuffer = connection.allocate();
   try {
     final ByteBuffer receiveBuffer = pooledReceiveBuffer.getResource();
     synchronized (connection.getLock()) {
       int res;
       try {
         res = channel.receive(receiveBuffer);
       } catch (IOException e) {
         connection.handleException(e);
         return;
       }
       if (res == -1) {
         connection.handleException(client.abruptClose(connection));
         return;
       }
       if (res == 0) {
         return;
       }
     }
     client.tracef("Received %s", receiveBuffer);
     receiveBuffer.flip();
     final byte msgType = receiveBuffer.get();
     switch (msgType) {
       case Protocol.CONNECTION_ALIVE:
         {
           client.trace("Client received connection alive");
           connection.sendAliveResponse();
           return;
         }
       case Protocol.CONNECTION_ALIVE_ACK:
         {
           client.trace("Client received connection alive ack");
           return;
         }
       case Protocol.CONNECTION_CLOSE:
         {
           client.trace("Client received connection close request");
           connection.handlePreAuthCloseRequest();
           return;
         }
       case Protocol.STARTTLS:
         {
           client.trace("Client received STARTTLS response");
           Channel c = channel;
           for (; ; ) {
             if (c instanceof SslChannel) {
               try {
                 ((SslChannel) c).startHandshake();
               } catch (IOException e) {
                 connection.handleException(e, false);
                 return;
               }
               sendCapRequest(remoteServerName);
               return;
             } else if (c instanceof WrappedChannel) {
               c = ((WrappedChannel<?>) c).getChannel();
             } else {
               // this should never happen
               connection.handleException(
                   new IOException("Client starting STARTTLS but channel doesn't support SSL"));
               return;
             }
           }
         }
       default:
         {
           client.unknownProtocolId(msgType);
           connection.handleException(client.invalidMessage(connection));
           return;
         }
     }
   } catch (BufferUnderflowException | BufferOverflowException e) {
     connection.handleException(client.invalidMessage(connection));
     return;
   } finally {
     pooledReceiveBuffer.free();
   }
 }