diff --git a/akka-stream/src/main/scala/akka/stream/impl/io/TLSActor.scala b/akka-stream/src/main/scala/akka/stream/impl/io/TLSActor.scala index 74c32f2b14..bf30a81edc 100644 --- a/akka-stream/src/main/scala/akka/stream/impl/io/TLSActor.scala +++ b/akka-stream/src/main/scala/akka/stream/impl/io/TLSActor.scala @@ -368,10 +368,20 @@ import akka.util.ByteString log.debug( s"wrap: status=${result.getStatus} handshake=$lastHandshakeStatus remaining=${userInBuffer.remaining} out=${transportOutBuffer .position()}") + if (lastHandshakeStatus == FINISHED) handshakeFinished() runDelegatedTasks() result.getStatus match { case OK => + // https://github.com/akka/akka/issues/29922 + // It seems to be possible to get the SSLEngine into a state where + // result.getStatus == OK && getHandshakeStatus == NEED_WRAP but + // it doesn't make any progress any more. + // + // We guard against this JDK bug by checking for reasonable invariants after the call to engine.wrap + if (!(transportOutBuffer.position() > 0 || lastHandshakeStatus != NEED_WRAP)) + throw new IllegalStateException("SSLEngine trying to loop NEED_WRAP without producing output") + flushToTransport() userInChoppingBlock.putBack(userInBuffer) case CLOSED =>