@@ -61,6 +61,7 @@ import akka.util.ByteString
61
61
62
62
import TLSActor ._
63
63
64
+ private var unwrapPutBackCounter : Int = 0
64
65
protected val outputBunch = new OutputBunch (outputCount = 2 , self, this )
65
66
outputBunch.markAllOutputs()
66
67
@@ -354,6 +355,7 @@ import akka.util.ByteString
354
355
355
356
def flushToUser (): Unit = {
356
357
if (tracing) log.debug(" flushToUser" )
358
+ if (unwrapPutBackCounter > 0 ) unwrapPutBackCounter = 0
357
359
userOutBuffer.flip()
358
360
if (userOutBuffer.hasRemaining) {
359
361
val bs = ByteString (userOutBuffer)
@@ -408,7 +410,17 @@ import akka.util.ByteString
408
410
case OK =>
409
411
result.getHandshakeStatus match {
410
412
case NEED_WRAP =>
411
- flushToUser()
413
+ // https://github.com/akka/akka/issues/29922
414
+ // A second workaround for an infinite loop we have not been able to reproduce/isolate,
415
+ // if you see this, and can reproduce consistently, please report back to the Akka team
416
+ // with a reproducer or details about the client causing it
417
+ unwrapPutBackCounter += 1
418
+ if (unwrapPutBackCounter > 1000 ) {
419
+ throw new IllegalStateException (
420
+ s " Stuck in unwrap loop, bailing out, last handshake status [ $lastHandshakeStatus], " +
421
+ s " remaining= ${transportInBuffer.remaining}, out= ${userOutBuffer.position()}, " +
422
+ " (https://github.com/akka/akka/issues/29922)" )
423
+ }
412
424
transportInChoppingBlock.putBack(transportInBuffer)
413
425
case FINISHED =>
414
426
flushToUser()
@@ -480,7 +492,6 @@ import akka.util.ByteString
480
492
pump()
481
493
}
482
494
483
- // FIXME: what happens if this actor dies unexpectedly?
484
495
override def postStop (): Unit = {
485
496
if (tracing) log.debug(" postStop" )
486
497
super .postStop()
0 commit comments