2525using  Microsoft . Extensions . Hosting ; 
2626using  Microsoft . Extensions . Logging ; 
2727using  Moq ; 
28+ using  static  Microsoft . AspNetCore . Server . Kestrel . InMemory . FunctionalTests . TestTransport . InMemoryTransportConnection ; 
2829
2930namespace  InMemory . FunctionalTests ; 
3031
@@ -50,6 +51,59 @@ public Task OnTlsClientHelloAsync_ValidData_MultipleSegments(int id, List<byte[]
5051    public  Task  OnTlsClientHelloAsync_InvalidData_MultipleSegments ( int  id ,  List < byte [ ] >  packets ,  bool  nextMiddlewareInvoked ) 
5152        =>  RunTlsClientHelloCallbackTest_WithMultipleSegments ( id ,  packets ,  nextMiddlewareInvoked ,  tlsClientHelloCallbackExpected :  false ) ; 
5253
54+     [ Fact ] 
55+     public  async  Task  RunTlsClientHelloCallbackTest_DeterministinglyReads ( ) 
56+     { 
57+         var  serviceContext  =  new  TestServiceContext ( LoggerFactory ) ; 
58+         var  logger  =  LoggerFactory . CreateLogger < InMemoryTransportConnection > ( ) ; 
59+         var  memoryPool  =  serviceContext . MemoryPoolFactory ( ) ; 
60+         var  transportConnection  =  new  InMemoryTransportConnection ( memoryPool ,  logger ) ; 
61+ 
62+         var  nextMiddlewareInvoked  =  false ; 
63+         var  tlsClientHelloCallbackInvoked  =  false ; 
64+ 
65+         var  middleware  =  new  TlsListenerMiddleware ( 
66+             next :  ctx => 
67+             { 
68+                 nextMiddlewareInvoked  =  true ; 
69+                 var  readResult  =  ctx . Transport . Input . ReadAsync ( ) ; 
70+                 Assert . Equal ( 6 ,  readResult . Result . Buffer . Length ) ; 
71+ 
72+                 return  Task . CompletedTask ; 
73+             } , 
74+             tlsClientHelloBytesCallback :  ( ctx ,  data )  => 
75+             { 
76+                 tlsClientHelloCallbackInvoked  =  true ; 
77+             } 
78+         ) ; 
79+ 
80+         await  transportConnection . Input . WriteAsync ( new  byte [ 1 ]  {  0x16  } ) ; 
81+         var  middlewareTask  =  Task . Run ( ( )  =>  middleware . OnTlsClientHelloAsync ( transportConnection ) ) ; 
82+         await  Task . Delay ( TimeSpan . FromMilliseconds ( 25 ) ) ; 
83+ 
84+         await  transportConnection . Input . WriteAsync ( new  byte [ 2 ]  {  0x03 ,  0x01  } ) ; 
85+         await  Task . Delay ( TimeSpan . FromMilliseconds ( 25 ) ) ; 
86+ 
87+         await  transportConnection . Input . WriteAsync ( new  byte [ 2 ]  {  0x00 ,  0x20  } ) ; 
88+         await  Task . Delay ( TimeSpan . FromMilliseconds ( 25 ) ) ; 
89+ 
90+         // not correct TLS client hello byte; 
91+         // meaning we will not invoke the callback and advance request processing 
92+         await  transportConnection . Input . WriteAsync ( new  byte [ 1 ]  {  0x15  } ) ; 
93+         await  Task . Delay ( TimeSpan . FromMilliseconds ( 25 ) ) ; 
94+ 
95+         await  transportConnection . Input . CompleteAsync ( ) ; 
96+ 
97+         // ensuring that we have read only 5 times (ReadAsync() is called 5 times) 
98+         var  observableTransport  =  transportConnection . Transport  as  ObservableDuplexPipe ; 
99+         Assert . NotNull ( observableTransport ) ; 
100+         Assert . Equal ( 5 ,  observableTransport . ReadAsyncCounter ) ; 
101+ 
102+         await  middlewareTask ; 
103+         Assert . True ( nextMiddlewareInvoked ) ; 
104+         Assert . False ( tlsClientHelloCallbackInvoked ) ; 
105+     } 
106+ 
53107    private  async  Task  RunTlsClientHelloCallbackTest_WithMultipleSegments ( 
54108        int  id , 
55109        List < byte [ ] >  packets , 
0 commit comments