private void SetupHandlerChain() { Debug.Assert(_handler == null); HttpMessageHandler handler = new HttpConnectionHandler( _clientCertificates, _serverCertificateCustomValidationCallback, _checkCertificateRevocationList, _sslProtocols); if (_useProxy && _proxy != null) { handler = new HttpProxyConnectionHandler(_proxy, handler); } if (_credentials != null) { handler = new AuthenticationHandler(_preAuthenticate, _credentials, handler); } if (_useCookies) { handler = new CookieHandler(CookieContainer, handler); } if (_allowAutoRedirect) { handler = new AutoRedirectHandler(_maxAutomaticRedirections, handler); } if (_automaticDecompression != DecompressionMethods.None) { handler = new DecompressionHandler(_automaticDecompression, handler); } _handler = handler; }
protected internal override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (_preAuthenticate) { // Try using previous digest response WWWAuthenticate header if (_digestResponse != null) { await AuthenticationHelper.TrySetDigestAuthToken(request, _credentials, _digestResponse, HttpKnownHeaderNames.Authorization).ConfigureAwait(false); } else { AuthenticationHelper.TrySetBasicAuthToken(request, _credentials); } } HttpResponseMessage response = await _innerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false); // In case of redirection, ensure _credentials as CredentialCache if (AutoRedirectHandler.RequestNeedsRedirect(response)) { // Just as with WinHttpHandler and CurlHandler, for security reasons, we drop the server credential if it is // anything other than a CredentialCache. We allow credentials in a CredentialCache since they // are specifically tied to URIs. _credentials = _credentials as CredentialCache; } else if (_credentials != null && !_preAuthenticate && response.StatusCode == HttpStatusCode.Unauthorized) { HttpHeaderValueCollection <AuthenticationHeaderValue> authenticateValues = response.Headers.WwwAuthenticate; foreach (AuthenticationHeaderValue h in authenticateValues) { // We only support Basic and digest auth, ignore others if (h.Scheme == AuthenticationHelper.Basic) { if (AuthenticationHelper.TrySetBasicAuthToken(request, _credentials)) { response.Dispose(); response = await _innerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false); break; } } else if (h.Scheme == AuthenticationHelper.Digest) { // Update digest response with new parameter from WWWAuthenticate _digestResponse = new AuthenticationHelper.DigestResponse(h.Parameter); if (await AuthenticationHelper.TrySetDigestAuthToken(request, _credentials, _digestResponse, HttpKnownHeaderNames.Authorization).ConfigureAwait(false)) { response.Dispose(); response = await _innerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false); // Retry in case of nonce timeout in server. if (response.StatusCode == HttpStatusCode.Unauthorized) { foreach (AuthenticationHeaderValue ahv in response.Headers.WwwAuthenticate) { if (ahv.Scheme == AuthenticationHelper.Digest) { _digestResponse = new AuthenticationHelper.DigestResponse(ahv.Parameter); if (AuthenticationHelper.IsServerNonceStale(_digestResponse) && await AuthenticationHelper.TrySetDigestAuthToken(request, _credentials, _digestResponse, HttpKnownHeaderNames.Authorization).ConfigureAwait(false)) { response.Dispose(); response = await _innerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false); } break; } } } break; } } } } return(response); }