@@ -61,7 +61,13 @@ struct HTTPRequestStateMachine {
61
61
/// A sub state for receiving a response. Stores whether the consumer has either signaled demand for more data or
62
62
/// is busy consuming the so far forwarded bytes
63
63
enum ConsumerControlState {
64
+ /// the state machine is in this state once it has passed down a request head or body part. If a read event
65
+ /// occurs while in this state, the readPending flag will be set true. If the consumer signals more demand
66
+ /// by invoking `forwardMoreBodyParts`, the state machine will forward the read event.
64
67
case downstreamIsConsuming( readPending: Bool )
68
+ /// the state machine is in this state once the consumer has signaled more demand by invoking
69
+ /// `forwardMoreBodyParts`. If a read event occurs in this state the read event will be forwarded
70
+ /// immediately.
65
71
case downstreamHasDemand
66
72
}
67
73
@@ -457,17 +463,20 @@ struct HTTPRequestStateMachine {
457
463
self . state = . finished
458
464
return . succeedRequest( . close)
459
465
460
- case . running( . endSent, . receivingBody( _, let streamState) ) :
461
- let finalAction : Action . FinalStreamAction
462
- switch streamState {
463
- case . downstreamIsConsuming( readPending: true ) :
464
- finalAction = . read
465
- case . downstreamIsConsuming( readPending: false ) , . downstreamHasDemand:
466
- finalAction = . none
467
- }
466
+ case . running( . endSent, . receivingBody( _, . downstreamIsConsuming( readPending: true ) ) ) :
467
+ // If we have a received a read event before, we must ensure that the read event
468
+ // eventually gets onto the channel pipeline again. The end of the request gives
469
+ // us an opportunity for this clean up task.
470
+ // It is very unlikely that we can see this in the real world. If we have swallowed
471
+ // a read event we don't expect to receive further data from the channel incl.
472
+ // response ends.
473
+ self . state = . finished
474
+ return . succeedRequest( . read)
468
475
476
+ case . running( . endSent, . receivingBody( _, . downstreamIsConsuming( readPending: false ) ) ) ,
477
+ . running( . endSent, . receivingBody( _, . downstreamHasDemand) ) :
469
478
self . state = . finished
470
- return . succeedRequest( finalAction )
479
+ return . succeedRequest( . none )
471
480
472
481
case . running( _, . endReceived) , . finished:
473
482
preconditionFailure ( " How can we receive a response end, if another one was already received. Invalid state: \( self . state) " )
0 commit comments