@@ -75,52 +75,60 @@ internal sealed partial class HttpConnectionPool
75
75
// Loop in case we get a 421 and need to send the request to a different authority.
76
76
while ( true )
77
77
{
78
- if ( ! TryGetHttp3Authority ( request , out HttpAuthority ? authority , out Exception ? reasonException ) )
78
+ HttpConnectionWaiter < Http3Connection ? > ? http3ConnectionWaiter = null ;
79
+ try
79
80
{
80
- if ( reasonException is null )
81
+ if ( ! TryGetHttp3Authority ( request , out HttpAuthority ? authority , out Exception ? reasonException ) )
81
82
{
82
- return null ;
83
+ if ( reasonException is null )
84
+ {
85
+ return null ;
86
+ }
87
+ ThrowGetVersionException ( request , 3 , reasonException ) ;
83
88
}
84
- ThrowGetVersionException ( request , 3 , reasonException ) ;
85
- }
86
89
87
- long queueStartingTimestamp = HttpTelemetry . Log . IsEnabled ( ) || Settings . _metrics ! . RequestsQueueDuration . Enabled ? Stopwatch . GetTimestamp ( ) : 0 ;
88
- Activity ? waitForConnectionActivity = ConnectionSetupDistributedTracing . StartWaitForConnectionActivity ( authority ) ;
90
+ long queueStartingTimestamp = HttpTelemetry . Log . IsEnabled ( ) || Settings . _metrics ! . RequestsQueueDuration . Enabled ? Stopwatch . GetTimestamp ( ) : 0 ;
91
+ Activity ? waitForConnectionActivity = ConnectionSetupDistributedTracing . StartWaitForConnectionActivity ( authority ) ;
89
92
90
- if ( ! TryGetPooledHttp3Connection ( request , out Http3Connection ? connection , out HttpConnectionWaiter < Http3Connection ? > ? http3ConnectionWaiter ) )
91
- {
92
- try
93
+ if ( ! TryGetPooledHttp3Connection ( request , out Http3Connection ? connection , out http3ConnectionWaiter ) )
93
94
{
94
- connection = await http3ConnectionWaiter . WaitWithCancellationAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
95
+ try
96
+ {
97
+ connection = await http3ConnectionWaiter . WaitWithCancellationAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
98
+ }
99
+ catch ( Exception ex )
100
+ {
101
+ ConnectionSetupDistributedTracing . ReportError ( waitForConnectionActivity , ex ) ;
102
+ waitForConnectionActivity ? . Stop ( ) ;
103
+ throw ;
104
+ }
95
105
}
96
- catch ( Exception ex )
106
+
107
+ // Request cannot be sent over H/3 connection, try downgrade or report failure.
108
+ // Note that if there's an H/3 suitable origin authority but is unavailable or blocked via Alt-Svc, exception is thrown instead.
109
+ if ( connection is null )
97
110
{
98
- ConnectionSetupDistributedTracing . ReportError ( waitForConnectionActivity , ex ) ;
99
- waitForConnectionActivity ? . Stop ( ) ;
100
- throw ;
111
+ return null ;
101
112
}
102
- }
103
113
104
- // Request cannot be sent over H/3 connection, try downgrade or report failure.
105
- // Note that if there's an H/3 suitable origin authority but is unavailable or blocked via Alt-Svc, exception is thrown instead.
106
- if ( connection is null )
107
- {
108
- return null ;
109
- }
114
+ HttpResponseMessage response = await connection . SendAsync ( request , queueStartingTimestamp , waitForConnectionActivity , cancellationToken ) . ConfigureAwait ( false ) ;
110
115
111
- HttpResponseMessage response = await connection . SendAsync ( request , queueStartingTimestamp , waitForConnectionActivity , cancellationToken ) . ConfigureAwait ( false ) ;
116
+ // If an Alt-Svc authority returns 421, it means it can't actually handle the request.
117
+ // An authority is supposed to be able to handle ALL requests to the origin, so this is a server bug.
118
+ // In this case, we blocklist the authority and retry the request at the origin.
119
+ if ( response . StatusCode == HttpStatusCode . MisdirectedRequest && connection . Authority != _originAuthority )
120
+ {
121
+ response . Dispose ( ) ;
122
+ BlocklistAuthority ( connection . Authority ) ;
123
+ continue ;
124
+ }
112
125
113
- // If an Alt-Svc authority returns 421, it means it can't actually handle the request.
114
- // An authority is supposed to be able to handle ALL requests to the origin, so this is a server bug.
115
- // In this case, we blocklist the authority and retry the request at the origin.
116
- if ( response . StatusCode == HttpStatusCode . MisdirectedRequest && connection . Authority != _originAuthority )
126
+ return response ;
127
+ }
128
+ finally
117
129
{
118
- response . Dispose ( ) ;
119
- BlocklistAuthority ( connection . Authority ) ;
120
- continue ;
130
+ http3ConnectionWaiter ? . CancelIfNecessary ( this , cancellationToken . IsCancellationRequested ) ;
121
131
}
122
-
123
- return response ;
124
132
}
125
133
}
126
134
@@ -253,8 +261,7 @@ private async Task InjectNewHttp3ConnectionAsync(RequestQueue<Http3Connection?>.
253
261
HttpAuthority ? authority = null ;
254
262
HttpConnectionWaiter < Http3Connection ? > waiter = queueItem . Waiter ;
255
263
256
- CancellationTokenSource cts = GetConnectTimeoutCancellationTokenSource ( ) ;
257
- waiter . ConnectionCancellationTokenSource = cts ;
264
+ CancellationTokenSource cts = GetConnectTimeoutCancellationTokenSource ( waiter ) ;
258
265
Activity ? connectionSetupActivity = null ;
259
266
try
260
267
{
0 commit comments