@@ -717,6 +717,17 @@ private static void WinHttpStatusCallback(
717
717
}
718
718
719
719
state . RequestMessage . RequestUri = redirectUri ;
720
+
721
+ // Redirection to a new uri may require a new connection through a potentially different proxy.
722
+ // If so, we will need to respond to additional 407 proxy auth demands and re-attach any
723
+ // proxy credentials. The ProcessResponse() method looks at the state.LastStatusCode
724
+ // before attaching proxy credentials and marking the HTTP request to be re-submitted.
725
+ // So we need to reset the LastStatusCode remembered. Otherwise, it will see additional 407
726
+ // responses as an indication that proxy auth failed and won't retry the HTTP request.
727
+ if ( state . LastStatusCode == HttpStatusCode . ProxyAuthenticationRequired )
728
+ {
729
+ state . LastStatusCode = 0 ;
730
+ }
720
731
721
732
// For security reasons, we drop the server credential if it is a
722
733
// NetworkCredential. But we allow credentials in a CredentialCache
@@ -1147,14 +1158,13 @@ private async void StartRequest(object obj)
1147
1158
1148
1159
uint proxyAuthScheme = 0 ;
1149
1160
uint serverAuthScheme = 0 ;
1150
- HttpStatusCode lastStatusCode = 0 ;
1151
1161
bool retryRequest = false ;
1152
1162
1153
1163
do
1154
1164
{
1155
1165
state . CancellationToken . ThrowIfCancellationRequested ( ) ;
1156
1166
1157
- PreAuthenticateRequest ( state , requestHandle , proxyAuthScheme , ref lastStatusCode ) ;
1167
+ PreAuthenticateRequest ( state , requestHandle , proxyAuthScheme ) ;
1158
1168
1159
1169
// Send a request.
1160
1170
if ( ! Interop . WinHttp . WinHttpSendRequest (
@@ -1211,7 +1221,6 @@ await state.RequestMessage.Content.CopyToAsync(
1211
1221
requestHandle ,
1212
1222
ref proxyAuthScheme ,
1213
1223
ref serverAuthScheme ,
1214
- ref lastStatusCode ,
1215
1224
out retryRequest ) ;
1216
1225
}
1217
1226
} while ( retryRequest ) ;
@@ -1276,7 +1285,6 @@ private void ProcessResponse(
1276
1285
SafeWinHttpHandle requestHandle ,
1277
1286
ref uint proxyAuthScheme ,
1278
1287
ref uint serverAuthScheme ,
1279
- ref HttpStatusCode lastStatusCode ,
1280
1288
out bool retryRequest )
1281
1289
{
1282
1290
retryRequest = false ;
@@ -1293,14 +1301,14 @@ private void ProcessResponse(
1293
1301
switch ( statusCode )
1294
1302
{
1295
1303
case HttpStatusCode . Unauthorized :
1296
- if ( state . ServerCredentials == null || lastStatusCode == HttpStatusCode . Unauthorized )
1304
+ if ( state . ServerCredentials == null || state . LastStatusCode == HttpStatusCode . Unauthorized )
1297
1305
{
1298
1306
// Either we don't have server credentials or we already tried
1299
1307
// to set the credentials and it failed before.
1300
1308
// So we will let the 401 be the final status code returned.
1301
1309
break ;
1302
1310
}
1303
- lastStatusCode = statusCode ;
1311
+ state . LastStatusCode = statusCode ;
1304
1312
1305
1313
// Determine authorization scheme to use. We ignore the firstScheme
1306
1314
// parameter which is included in the supportedSchemes flags already.
@@ -1337,12 +1345,12 @@ private void ProcessResponse(
1337
1345
break ;
1338
1346
1339
1347
case HttpStatusCode . ProxyAuthenticationRequired :
1340
- if ( lastStatusCode == HttpStatusCode . ProxyAuthenticationRequired )
1348
+ if ( state . LastStatusCode == HttpStatusCode . ProxyAuthenticationRequired )
1341
1349
{
1342
1350
// We tried already to set the credentials.
1343
1351
break ;
1344
1352
}
1345
- lastStatusCode = statusCode ;
1353
+ state . LastStatusCode = statusCode ;
1346
1354
1347
1355
// Determine authorization scheme to use. We ignore the firstScheme
1348
1356
// parameter which is included in the supportedSchemes flags already.
@@ -1381,8 +1389,7 @@ private void ProcessResponse(
1381
1389
private void PreAuthenticateRequest (
1382
1390
RequestState state ,
1383
1391
SafeWinHttpHandle requestHandle ,
1384
- uint proxyAuthScheme ,
1385
- ref HttpStatusCode lastStatusCode )
1392
+ uint proxyAuthScheme )
1386
1393
{
1387
1394
// Set proxy credentials if we have them.
1388
1395
// If a proxy authentication challenge was responded to, reset
@@ -1416,7 +1423,7 @@ private void PreAuthenticateRequest(
1416
1423
state . RequestMessage . RequestUri ,
1417
1424
authScheme ,
1418
1425
Interop . WinHttp . WINHTTP_AUTH_TARGET_SERVER ) ;
1419
- lastStatusCode = HttpStatusCode . Unauthorized ; // Remember we already set the creds.
1426
+ state . LastStatusCode = HttpStatusCode . Unauthorized ; // Remember we already set the creds.
1420
1427
}
1421
1428
}
1422
1429
}
@@ -2151,6 +2158,8 @@ public Func<
2151
2158
public IWebProxy Proxy { get ; set ; }
2152
2159
2153
2160
public ICredentials ServerCredentials { get ; set ; }
2161
+
2162
+ public HttpStatusCode LastStatusCode { get ; set ; }
2154
2163
}
2155
2164
}
2156
2165
}
0 commit comments