@@ -90,18 +90,23 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
9090 } ,
9191 async server =>
9292 {
93+ var connection = await server . EstablishGenericConnectionAsync ( ) ;
9394 try
9495 {
95- await server . HandleRequestAsync ( headers : new [ ] { new HttpHeaderData ( "Foo" , new string ( 'a' , handler . MaxResponseHeadersLength * 1024 ) ) } ) ;
96+ // Do not use HandleRequestAsync. It sends GO_AWAY before sending the response, making client close the connection right after the stream abort.
97+ // QUIC is based on UDP and packet ordering is not preserved, so the connection close might race with the expected stream error in H/3 case.
98+ await connection . ReadRequestDataAsync ( ) ;
99+ await connection . SendResponseAsync ( headers : new [ ] { new HttpHeaderData ( "Foo" , new string ( 'a' , handler . MaxResponseHeadersLength * 1024 ) ) } ) ;
96100 }
97101 // Client can respond by closing/aborting the underlying stream while we are still sending the headers, ignore these exceptions
98102 catch ( IOException ex ) when ( ex . InnerException is SocketException se && se . SocketErrorCode == SocketError . Shutdown ) { }
99103#if ! WINHTTPHANDLER_TEST
100- catch ( QuicException ex ) when ( ex . QuicError == QuicError . StreamAborted && ex . ApplicationErrorCode == Http3ExcessiveLoad ) { }
104+ catch ( QuicException ex ) when ( ex . QuicError == QuicError . StreamAborted && ex . ApplicationErrorCode == Http3ExcessiveLoad ) { }
101105#endif
102106 finally
103107 {
104108 semaphore . Release ( ) ;
109+ await connection . DisposeAsync ( ) ;
105110 }
106111 } ) ;
107112 }
@@ -148,9 +153,13 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
148153 headers . Add ( new HttpHeaderData ( $ "Custom-{ i } ", new string ( 'a' , 480 ) ) ) ;
149154 }
150155
156+ var connection = await server . EstablishGenericConnectionAsync ( ) ;
151157 try
152158 {
153- await server . HandleRequestAsync ( headers : headers ) ;
159+ // Do not use HandleRequestAsync. It sends GO_AWAY before sending the response, making client close the connection right after the stream abort.
160+ // QUIC is based on UDP and packet ordering is not preserved, so the connection close might race with the expected stream error in H/3 case.
161+ await connection . ReadRequestDataAsync ( ) ;
162+ await connection . SendResponseAsync ( headers : headers ) ;
154163 }
155164 // Client can respond by closing/aborting the underlying stream while we are still sending the headers, ignore these exceptions
156165 catch ( IOException ex ) when ( ex . InnerException is SocketException se && se . SocketErrorCode == SocketError . Shutdown ) { }
@@ -160,6 +169,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
160169 finally
161170 {
162171 semaphore . Release ( ) ;
172+ await connection . DisposeAsync ( ) ;
163173 }
164174 } ) ;
165175 }
0 commit comments