public override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (_preAuthenticate) { TrySetBasicAuthToken(request); } HttpResponseMessage response = await _innerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false); if (!_preAuthenticate && response.StatusCode == HttpStatusCode.Unauthorized) { HttpHeaderValueCollection <AuthenticationHeaderValue> authenticateValues = response.Headers.WwwAuthenticate; foreach (AuthenticationHeaderValue h in authenticateValues) { // We only support Basic auth, ignore others if (h.Scheme == Basic) { if (!TrySetBasicAuthToken(request)) { break; } response.Dispose(); response = await _innerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false); break; } } } return(response); }
public override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // Add cookies to request, if any string cookieHeader = _cookieContainer.GetCookieHeader(request.RequestUri); if (!string.IsNullOrEmpty(cookieHeader)) { request.Headers.Add(HttpKnownHeaderNames.Cookie, cookieHeader); } HttpResponseMessage response = await _innerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false); // Handle Set-Cookie IEnumerable <string> setCookies; if (response.Headers.TryGetValues(HttpKnownHeaderNames.SetCookie, out setCookies)) { foreach (string setCookie in setCookies) { _cookieContainer.SetCookies(response.RequestMessage.RequestUri, setCookie); } } return(response); }
public async Task SendAsync_DelegatesToInnerHandler() { // Arrange HttpRequestMessage request = null; var cancellationToken = default(CancellationToken); HttpMessageHandler innerHandler = new LambdaHttpMessageHandler( (r, c) => { request = r; cancellationToken = c; return(Task.FromResult <HttpResponseMessage>(null)); } ); HttpMessageHandler handler = CreateProductUnderTest(innerHandler); var expectedCancellationToken = new CancellationToken(true); using (var expectedRequest = CreateRequestWithContext()) { // Act var result = await handler.SendAsync(expectedRequest, expectedCancellationToken); // Assert Assert.Same(expectedRequest, request); Assert.Equal(expectedCancellationToken, cancellationToken); Assert.Null(result); } }
public async Task SendAsync_IfExceptionHandlerHandlesException_ReturnsResponse() { // Arrange IExceptionLogger exceptionLogger = CreateStubExceptionLogger(); using (HttpResponseMessage expectedResponse = CreateResponse()) { Mock <IExceptionHandler> exceptionHandlerMock = new Mock <IExceptionHandler>(MockBehavior.Strict); exceptionHandlerMock .Setup(h => h.HandleAsync(It.IsAny <ExceptionHandlerContext>(), It.IsAny <CancellationToken>())) .Callback <ExceptionHandlerContext, CancellationToken>((c, i) => c.Result = new ResponseMessageResult(expectedResponse)) .Returns(Task.FromResult(0)); IExceptionHandler exceptionHandler = exceptionHandlerMock.Object; using (HttpRequestMessage request = CreateRequestWithRouteData()) using (HttpConfiguration configuration = new HttpConfiguration()) using (HttpMessageHandler product = CreateProductUnderTest(configuration, exceptionLogger, exceptionHandler)) { configuration.Services.Replace(typeof(IHttpControllerSelector), CreateThrowingControllerSelector(CreateException())); CancellationToken cancellationToken = CreateCancellationToken(); // Act HttpResponseMessage response = await product.SendAsync(request, cancellationToken); // Assert Assert.Same(expectedResponse, response); } } }
public void SendAsync_SetsCurrentPrincipalToAnonymous_BeforeCallingInnerHandler() { // Arrange IPrincipal principalServiceCurrentPrincipal = null; IHostPrincipalService principalService = CreateSpyPrincipalService((p) => { principalServiceCurrentPrincipal = p; }); IPrincipal principalBeforeInnerHandler = null; HttpMessageHandler inner = new LambdaHttpMessageHandler((ignore1, ignore2) => { principalBeforeInnerHandler = principalServiceCurrentPrincipal; return(Task.FromResult <HttpResponseMessage>(null)); }); HttpMessageHandler handler = CreateProductUnderTest(principalService, inner); using (HttpRequestMessage request = new HttpRequestMessage()) { // Act handler.SendAsync(request, CancellationToken.None); } // Assert Assert.NotNull(principalBeforeInnerHandler); IIdentity identity = principalBeforeInnerHandler.Identity; Assert.NotNull(identity); Assert.False(identity.IsAuthenticated); Assert.Null(identity.Name); Assert.Null(identity.AuthenticationType); }
public void SendAsync_DelegatesToInnerHandler() { // Arrange IHostPrincipalService principalService = CreateStubPrincipalService(); HttpRequestMessage request = null; CancellationToken cancellationToken = default(CancellationToken); Task <HttpResponseMessage> expectedResult = new Task <HttpResponseMessage>(() => null); HttpMessageHandler innerHandler = new LambdaHttpMessageHandler((r, c) => { request = r; cancellationToken = c; return(expectedResult); }); HttpMessageHandler handler = CreateProductUnderTest(principalService, innerHandler); CancellationToken expectedCancellationToken = new CancellationToken(true); using (HttpRequestMessage expectedRequest = new HttpRequestMessage()) { // Act Task <HttpResponseMessage> result = handler.SendAsync(expectedRequest, expectedCancellationToken); // Assert Assert.Same(expectedRequest, request); Assert.Equal(expectedCancellationToken, cancellationToken); Assert.Same(expectedResult, result); } }
public void SendAsync_LeavesAuthenticationChallenges_WhenExistingAuthenticationTypesIsNonEmpty() { // Arrange IHostPrincipalService principalService = CreateStubPrincipalService(); HttpMessageHandler inner = CreateStubHandler(); HttpMessageHandler handler = CreateProductUnderTest(principalService, inner); IOwinContext context = CreateOwinContext(); IAuthenticationManager authenticationManager = context.Authentication; AuthenticationProperties extraWrapper = new AuthenticationProperties(); string[] expectedAuthenticationTypes = new string[] { "Existing" }; IDictionary <string, string> expectedExtra = extraWrapper.Dictionary; authenticationManager.AuthenticationResponseChallenge = new AuthenticationResponseChallenge( expectedAuthenticationTypes, extraWrapper); using (HttpRequestMessage request = CreateRequestWithOwinContext(context)) { // Act HttpResponseMessage ignore = handler.SendAsync(request, CancellationToken.None).Result; } // Assert AuthenticationResponseChallenge challenge = authenticationManager.AuthenticationResponseChallenge; Assert.NotNull(challenge); Assert.Same(expectedAuthenticationTypes, challenge.AuthenticationTypes); AuthenticationProperties actualExtraWrapper = challenge.Properties; Assert.NotNull(actualExtraWrapper); Assert.Same(expectedExtra, actualExtraWrapper.Dictionary); }
public void SendAsync_DelegatesToInnerHandler() { // Arrange IHostPrincipalService principalService = CreateStubPrincipalService(); HttpRequestMessage request = null; CancellationToken cancellationToken = default(CancellationToken); IOwinContext context = CreateOwinContext(); using (HttpResponseMessage expectedResponse = new HttpResponseMessage()) { HttpMessageHandler innerHandler = new LambdaHttpMessageHandler((r, c) => { request = r; cancellationToken = c; return(Task.FromResult(expectedResponse)); }); HttpMessageHandler handler = CreateProductUnderTest(principalService, innerHandler); CancellationToken expectedCancellationToken = new CancellationToken(true); using (HttpRequestMessage expectedRequest = CreateRequestWithOwinContext(context)) { // Act HttpResponseMessage response = handler.SendAsync(expectedRequest, expectedCancellationToken).Result; // Assert Assert.Same(expectedRequest, request); Assert.Equal(expectedCancellationToken, cancellationToken); Assert.Same(expectedResponse, response); } } }
public void SendAsync_SetsCurrentPrincipalToAnonymous_BeforeCallingInnerHandler() { // Arrange IPrincipal requestContextPrincipal = null; Mock <HttpRequestContext> requestContextMock = new Mock <HttpRequestContext>(); requestContextMock .SetupSet(c => c.Principal = It.IsAny <IPrincipal>()) .Callback <IPrincipal>((value) => requestContextPrincipal = value); IPrincipal principalBeforeInnerHandler = null; HttpMessageHandler inner = new LambdaHttpMessageHandler((ignore1, ignore2) => { principalBeforeInnerHandler = requestContextPrincipal; return(Task.FromResult <HttpResponseMessage>(null)); }); HttpMessageHandler handler = CreateProductUnderTest(inner); using (HttpRequestMessage request = new HttpRequestMessage()) { request.SetRequestContext(requestContextMock.Object); // Act handler.SendAsync(request, CancellationToken.None); } // Assert Assert.NotNull(principalBeforeInnerHandler); IIdentity identity = principalBeforeInnerHandler.Identity; Assert.NotNull(identity); Assert.False(identity.IsAuthenticated); Assert.Null(identity.Name); Assert.Null(identity.AuthenticationType); }
public void SendAsync_SuppressesAuthenticationChallenges_WhenNoChallengeIsSet() { // Arrange IHostPrincipalService principalService = CreateStubPrincipalService(); HttpMessageHandler inner = CreateStubHandler(); HttpMessageHandler handler = CreateProductUnderTest(principalService, inner); IOwinContext context = CreateOwinContext(); using (HttpRequestMessage request = CreateRequestWithOwinContext(context)) { // Act HttpResponseMessage ignore = handler.SendAsync(request, CancellationToken.None).Result; } // Assert IAuthenticationManager authenticationManager = context.Authentication; AuthenticationResponseChallenge challenge = authenticationManager.AuthenticationResponseChallenge; Assert.NotNull(challenge); string[] authenticationTypes = challenge.AuthenticationTypes; Assert.NotNull(authenticationTypes); Assert.Equal(1, authenticationTypes.Length); string authenticationType = authenticationTypes[0]; Assert.Null(authenticationType); }
public async Task SendAsync_SuppressesAuthenticationChallenges_WhenNoChallengeIsSet() { // Arrange HttpMessageHandler inner = CreateStubHandler(); HttpMessageHandler handler = CreateProductUnderTest(inner); IOwinContext context = CreateOwinContext(); using ( HttpRequestMessage request = CreateRequestWithOwinContextAndRequestContext(context) ) { // Act HttpResponseMessage ignore = await handler.SendAsync( request, CancellationToken.None ); } // Assert IAuthenticationManager authenticationManager = context.Authentication; AuthenticationResponseChallenge challenge = authenticationManager.AuthenticationResponseChallenge; Assert.NotNull(challenge); string[] authenticationTypes = challenge.AuthenticationTypes; Assert.NotNull(authenticationTypes); string authenticationType = Assert.Single(authenticationTypes); Assert.Null(authenticationType); }
public async Task SendAsync_IfSendAsyncCancels_InControllerSelector_DoesNotCallExceptionServices() { // Arrange Exception expectedException = new OperationCanceledException(); Mock <IExceptionLogger> exceptionLoggerMock = new Mock <IExceptionLogger>(MockBehavior.Strict); IExceptionLogger exceptionLogger = exceptionLoggerMock.Object; Mock <IExceptionHandler> exceptionHandlerMock = new Mock <IExceptionHandler>(MockBehavior.Strict); IExceptionHandler exceptionHandler = exceptionHandlerMock.Object; using (HttpRequestMessage expectedRequest = CreateRequestWithRouteData()) using (HttpConfiguration configuration = CreateConfiguration()) using (HttpMessageHandler product = CreateProductUnderTest(configuration, exceptionLogger, exceptionHandler)) { configuration.Services.Replace(typeof(IHttpControllerSelector), CreateThrowingControllerSelector(expectedException)); CancellationToken cancellationToken = CreateCancellationToken(); // Act & Assert await Assert.ThrowsAsync <OperationCanceledException>(() => product.SendAsync(expectedRequest, cancellationToken)); } }
public async Task SendAsync_SuppressesAuthenticationChallenges_WhenExistingAuthenticationTypesIsEmpty() { // Arrange HttpMessageHandler inner = CreateStubHandler(); HttpMessageHandler handler = CreateProductUnderTest(inner); IOwinContext context = CreateOwinContext(); IAuthenticationManager authenticationManager = context.Authentication; AuthenticationProperties extraWrapper = new AuthenticationProperties(); IDictionary <string, string> expectedExtra = extraWrapper.Dictionary; authenticationManager.AuthenticationResponseChallenge = new AuthenticationResponseChallenge(new string[0], extraWrapper); using (HttpRequestMessage request = CreateRequestWithOwinContextAndRequestContext(context)) { // Act HttpResponseMessage ignore = await handler.SendAsync(request, CancellationToken.None); } // Assert AuthenticationResponseChallenge challenge = authenticationManager.AuthenticationResponseChallenge; Assert.NotNull(challenge); string[] authenticationTypes = challenge.AuthenticationTypes; Assert.NotNull(authenticationTypes); Assert.Equal(1, authenticationTypes.Length); string authenticationType = authenticationTypes[0]; Assert.Null(authenticationType); AuthenticationProperties actualExtraWrapper = challenge.Properties; Assert.NotNull(actualExtraWrapper); Assert.Same(expectedExtra, actualExtraWrapper.Dictionary); }
public void SendAsync_IfSendAsyncCancels_InControllerSelector_DoesNotCallExceptionServices() { // Arrange Exception expectedException = new OperationCanceledException(); Mock <IExceptionLogger> exceptionLoggerMock = new Mock <IExceptionLogger>(MockBehavior.Strict); IExceptionLogger exceptionLogger = exceptionLoggerMock.Object; Mock <IExceptionHandler> exceptionHandlerMock = new Mock <IExceptionHandler>(MockBehavior.Strict); IExceptionHandler exceptionHandler = exceptionHandlerMock.Object; using (HttpRequestMessage expectedRequest = CreateRequestWithRouteData()) using (HttpConfiguration configuration = CreateConfiguration()) using (HttpMessageHandler product = CreateProductUnderTest(configuration, exceptionLogger, exceptionHandler)) { configuration.Services.Replace(typeof(IHttpControllerSelector), CreateThrowingControllerSelector(expectedException)); CancellationToken cancellationToken = CreateCancellationToken(); Task <HttpResponseMessage> task = product.SendAsync(expectedRequest, cancellationToken); // Act task.WaitUntilCompleted(); // Assert Assert.Equal(TaskStatus.Canceled, task.Status); } }
public async Task SendAsync_IfExceptionHandlerSetsNullResult_PropogatesFaultedTaskException() { // Arrange ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(); string expectedStackTrace = exceptionInfo.SourceException.StackTrace; IExceptionLogger exceptionLogger = CreateStubExceptionLogger(); Mock <IExceptionHandler> exceptionHandlerMock = new Mock <IExceptionHandler>(MockBehavior.Strict); exceptionHandlerMock .Setup(h => h.HandleAsync(It.IsAny <ExceptionHandlerContext>(), It.IsAny <CancellationToken>())) .Callback <ExceptionHandlerContext, CancellationToken>((c, i) => c.Result = null) .Returns(Task.FromResult(0)); IExceptionHandler exceptionHandler = exceptionHandlerMock.Object; using (HttpRequestMessage request = CreateRequestWithRouteData()) using (HttpConfiguration configuration = CreateConfiguration()) using (HttpMessageHandler product = CreateProductUnderTest(configuration, exceptionLogger, exceptionHandler)) { configuration.Services.Replace(typeof(IHttpControllerSelector), CreateThrowingControllerSelector(exceptionInfo)); CancellationToken cancellationToken = CreateCancellationToken(); // Act & Assert var exception = await Assert.ThrowsAsync <Exception>(() => product.SendAsync(request, cancellationToken)); Assert.Same(exceptionInfo.SourceException, exception); Assert.NotNull(exception.StackTrace); Assert.StartsWith(expectedStackTrace, exception.StackTrace); } }
public async Task SendAsync_IfSendAsyncThrows_Controller_CallsExceptionServices() { // Arrange Exception expectedException = CreateException(); Mock <IExceptionLogger> exceptionLoggerMock = CreateStubExceptionLoggerMock(); IExceptionLogger exceptionLogger = exceptionLoggerMock.Object; Mock <IExceptionHandler> exceptionHandlerMock = CreateStubExceptionHandlerMock(); IExceptionHandler exceptionHandler = exceptionHandlerMock.Object; var controller = new ThrowingController(expectedException); var controllerActivator = new Mock <IHttpControllerActivator>(); controllerActivator .Setup( activator => activator.Create( It.IsAny <HttpRequestMessage>(), It.IsAny <HttpControllerDescriptor>(), It.IsAny <Type>())) .Returns(controller); using (HttpRequestMessage expectedRequest = CreateRequestWithRouteData()) using (HttpConfiguration configuration = CreateConfiguration()) using (HttpMessageHandler product = CreateProductUnderTest(configuration, exceptionLogger, exceptionHandler)) { var controllerSelector = new Mock <IHttpControllerSelector>(MockBehavior.Strict); controllerSelector .Setup(selector => selector.SelectController(It.IsAny <HttpRequestMessage>())) .Returns(new HttpControllerDescriptor(configuration, "Throwing", controller.GetType())); configuration.Services.Replace(typeof(IHttpControllerSelector), controllerSelector.Object); configuration.Services.Replace(typeof(IHttpControllerActivator), controllerActivator.Object); CancellationToken cancellationToken = CreateCancellationToken(); // Act await Assert.ThrowsAsync <Exception>(() => product.SendAsync(expectedRequest, cancellationToken)); // Assert Func <ExceptionContext, bool> exceptionContextMatches = (c) => c != null && c.Exception == expectedException && c.CatchBlock == ExceptionCatchBlocks.HttpControllerDispatcher && c.Request == expectedRequest && c.ControllerContext != null && c.ControllerContext == controller.ControllerContext && c.ControllerContext.Controller == controller; exceptionLoggerMock.Verify(l => l.LogAsync( It.Is <ExceptionLoggerContext>(c => exceptionContextMatches(c.ExceptionContext)), cancellationToken), Times.Once()); exceptionHandlerMock.Verify(h => h.HandleAsync( It.Is <ExceptionHandlerContext>((c) => exceptionContextMatches(c.ExceptionContext)), cancellationToken), Times.Once()); } }
public async Task SendAsync_SetsRequestContextPrincipalToAnonymous_BeforeCallingInnerHandler() { // Arrange var requestContextMock = new Mock <HttpRequestContext>(MockBehavior.Strict); var sequence = new MockSequence(); var initialPrincipal = new GenericPrincipal( new GenericIdentity("generic user"), new[] { "generic role" } ); IPrincipal requestContextPrincipal = null; requestContextMock .InSequence(sequence) .SetupGet(c => c.Principal) .Returns(initialPrincipal); requestContextMock .InSequence(sequence) .SetupSet(c => c.Principal = It.IsAny <IPrincipal>()) .Callback <IPrincipal>(value => requestContextPrincipal = value); // SendAsync also restores the old principal. requestContextMock .InSequence(sequence) .SetupGet(c => c.Principal) .Returns(requestContextPrincipal); requestContextMock.InSequence(sequence).SetupSet(c => c.Principal = initialPrincipal); IPrincipal principalBeforeInnerHandler = null; HttpMessageHandler inner = new LambdaHttpMessageHandler( (ignore1, ignore2) => { principalBeforeInnerHandler = requestContextPrincipal; return(Task.FromResult <HttpResponseMessage>(null)); } ); HttpMessageHandler handler = CreateProductUnderTest(inner); var context = CreateOwinContext(); using (var request = new HttpRequestMessage()) { request.SetOwinContext(context); request.SetRequestContext(requestContextMock.Object); // Act await handler.SendAsync(request, CancellationToken.None); } // Assert Assert.Equal(requestContextPrincipal, principalBeforeInnerHandler); Assert.NotNull(principalBeforeInnerHandler); var identity = principalBeforeInnerHandler.Identity; Assert.NotNull(identity); Assert.False(identity.IsAuthenticated); Assert.Null(identity.Name); Assert.Null(identity.AuthenticationType); }
public async Task SendAsync_Throws_WhenRequestContextIsNull() { // Arrange HttpMessageHandler innerHandler = CreateDummyHandler(); HttpMessageHandler handler = CreateProductUnderTest(innerHandler); using (HttpRequestMessage request = new HttpRequestMessage()) { // Act & Assert await Assert.ThrowsArgumentAsync( () => handler.SendAsync(request, CancellationToken.None), "request", "The request must have a request context."); } }
public async Task SendAsync_Throws_WhenAuthenticationManagerIsNull() { // Arrange HttpMessageHandler innerHandler = CreateStubHandler(); HttpMessageHandler handler = CreateProductUnderTest(innerHandler); IOwinContext context = CreateOwinContext(null); using (HttpRequestMessage request = CreateRequestWithOwinContextAndRequestContext(context)) { // Act & Assert InvalidOperationException exception = await Assert.ThrowsAsync <InvalidOperationException>( () => handler.SendAsync(request, CancellationToken.None)); Assert.Equal("No OWIN authentication manager is associated with the request.", exception.Message); } }
public void SendAsync_Throws_WhenOwinContextIsNull() { // Arrange IHostPrincipalService principalService = CreateStubPrincipalService(); HttpMessageHandler innerHandler = CreateStubHandler(); HttpMessageHandler handler = CreateProductUnderTest(principalService, innerHandler); using (HttpRequestMessage request = new HttpRequestMessage()) { // Act & Assert InvalidOperationException exception = Assert.Throws <InvalidOperationException>(() => { HttpResponseMessage ignore = handler.SendAsync(request, CancellationToken.None).Result; }); Assert.Equal("No OWIN authentication manager is associated with the request.", exception.Message); } }
public void SendAsync_IfSendAsyncThrows_InControllerSelector_CallsExceptionServices() { // Arrange Exception expectedException = CreateException(); Mock <IExceptionLogger> exceptionLoggerMock = CreateStubExceptionLoggerMock(); IExceptionLogger exceptionLogger = exceptionLoggerMock.Object; Mock <IExceptionHandler> exceptionHandlerMock = CreateStubExceptionHandlerMock(); IExceptionHandler exceptionHandler = exceptionHandlerMock.Object; using (HttpRequestMessage expectedRequest = CreateRequestWithRouteData()) using (HttpConfiguration configuration = CreateConfiguration()) using (HttpMessageHandler product = CreateProductUnderTest(configuration, exceptionLogger, exceptionHandler)) { configuration.Services.Replace(typeof(IHttpControllerSelector), CreateThrowingControllerSelector(expectedException)); CancellationToken cancellationToken = CreateCancellationToken(); Task <HttpResponseMessage> task = product.SendAsync(expectedRequest, cancellationToken); // Act task.WaitUntilCompleted(); // Assert Func <ExceptionContext, bool> exceptionContextMatches = (c) => c != null && c.Exception == expectedException && c.CatchBlock == ExceptionCatchBlocks.HttpControllerDispatcher && c.Request == expectedRequest && c.ControllerContext == null; exceptionLoggerMock.Verify(l => l.LogAsync( It.Is <ExceptionLoggerContext>(c => exceptionContextMatches(c.ExceptionContext)), cancellationToken), Times.Once()); exceptionHandlerMock.Verify(h => h.HandleAsync( It.Is <ExceptionHandlerContext>((c) => exceptionContextMatches(c.ExceptionContext)), cancellationToken), Times.Once()); } }
public override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { Uri proxyUri = null; try { if (!_proxy.IsBypassed(request.RequestUri)) { proxyUri = _proxy.GetProxy(request.RequestUri); } } catch (Exception) { // Eat any exception from the IWebProxy and just treat it as no proxy. // TODO #21452: This seems a bit questionable, but it's what the tests expect } return(proxyUri == null? _innerHandler.SendAsync(request, cancellationToken) : SendWithProxyAsync(proxyUri, request, cancellationToken)); }
public override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { HttpResponseMessage response = await _innerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false); uint redirectCount = 0; while (true) { bool needRedirect = false; bool forceGet = false; switch (response.StatusCode) { case HttpStatusCode.Moved: case HttpStatusCode.TemporaryRedirect: needRedirect = true; break; case HttpStatusCode.Found: case HttpStatusCode.SeeOther: needRedirect = true; forceGet = true; break; case HttpStatusCode.MultipleChoices: // Don't redirect if no Location specified if (response.Headers.Location != null) { needRedirect = true; } break; } if (!needRedirect) { break; } Uri location = response.Headers.Location; if (location == null) { throw new HttpRequestException("no Location header for redirect"); } if (!location.IsAbsoluteUri) { location = new Uri(request.RequestUri, location); } // Disallow automatic redirection from https to http bool allowed = (request.RequestUri.Scheme == UriScheme.Http && (location.Scheme == UriScheme.Http || location.Scheme == UriScheme.Https)) || (request.RequestUri.Scheme == UriScheme.Https && location.Scheme == UriScheme.Https); if (!allowed) { break; } redirectCount++; if (redirectCount > _maxAutomaticRedirections) { throw new HttpRequestException("max redirects exceeded"); } // Set up for the automatic redirect request.RequestUri = location; if (forceGet) { request.Method = HttpMethod.Get; request.Content = null; } // Do the redirect. response.Dispose(); response = await _innerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false); } return(response); }