@@ -90,18 +90,23 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
90
90
} ,
91
91
async server =>
92
92
{
93
+ var connection = await server . EstablishGenericConnectionAsync ( ) ;
93
94
try
94
95
{
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 ) ) } ) ;
96
100
}
97
101
// Client can respond by closing/aborting the underlying stream while we are still sending the headers, ignore these exceptions
98
102
catch ( IOException ex ) when ( ex . InnerException is SocketException se && se . SocketErrorCode == SocketError . Shutdown ) { }
99
103
#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 ) { }
101
105
#endif
102
106
finally
103
107
{
104
108
semaphore . Release ( ) ;
109
+ await connection . DisposeAsync ( ) ;
105
110
}
106
111
} ) ;
107
112
}
@@ -148,9 +153,13 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
148
153
headers . Add ( new HttpHeaderData ( $ "Custom-{ i } ", new string ( 'a' , 480 ) ) ) ;
149
154
}
150
155
156
+ var connection = await server . EstablishGenericConnectionAsync ( ) ;
151
157
try
152
158
{
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 ) ;
154
163
}
155
164
// Client can respond by closing/aborting the underlying stream while we are still sending the headers, ignore these exceptions
156
165
catch ( IOException ex ) when ( ex . InnerException is SocketException se && se . SocketErrorCode == SocketError . Shutdown ) { }
@@ -160,6 +169,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
160
169
finally
161
170
{
162
171
semaphore . Release ( ) ;
172
+ await connection . DisposeAsync ( ) ;
163
173
}
164
174
} ) ;
165
175
}
0 commit comments