Exemplo n.º 1
0
        internal static WebResponse GetResponse(Func <WebRequest> createRequest,
                                                Action <WebRequest> prepareRequest,
                                                IProxyCache proxyCache,
                                                ICredentialCache credentialCache,
                                                ICredentialProvider credentialProvider)
        {
            HttpWebRequest   previousRequest    = null;
            IHttpWebResponse previousResponse   = null;
            HttpStatusCode?  previousStatusCode = null;
            bool             usingSTSAuth       = false;
            bool             continueIfFailed   = true;
            int proxyCredentialsRetryCount      = 0;
            int credentialsRetryCount           = 0;

            while (true)
            {
                // Create the request
                var request = (HttpWebRequest)createRequest();
                request.Proxy = proxyCache.GetProxy(request.RequestUri);
                if (request.Proxy != null && request.Proxy.Credentials == null)
                {
                    request.Proxy.Credentials = CredentialCache.DefaultCredentials;
                }

                if (previousResponse == null || ShouldKeepAliveBeUsedInRequest(previousRequest, previousResponse))
                {
                    // Try to use the cached credentials (if any, for the first request)
                    request.Credentials = credentialCache.GetCredentials(request.RequestUri);

                    // If there are no cached credentials, use the default ones
                    if (request.Credentials == null)
                    {
                        request.UseDefaultCredentials = true;
                    }
                }
                else if (previousStatusCode == HttpStatusCode.ProxyAuthenticationRequired)
                {
                    request.Proxy.Credentials = credentialProvider.GetCredentials(request, CredentialType.ProxyCredentials, retrying: proxyCredentialsRetryCount > 0);

                    continueIfFailed = request.Proxy.Credentials != null;

                    proxyCredentialsRetryCount++;
                }
                else if ((previousStatusCode == HttpStatusCode.Unauthorized) && !usingSTSAuth)
                {
                    // If we are using STS, the auth's being performed by a request header. We do not need to ask the user for credentials at this point.
                    request.Credentials = credentialProvider.GetCredentials(request, CredentialType.RequestCredentials, retrying: credentialsRetryCount > 0);

                    continueIfFailed = request.Credentials != null;

                    credentialsRetryCount++;
                }

                try
                {
                    ICredentials credentials = request.Credentials;

                    SetKeepAliveHeaders(request, previousResponse);

                    if (usingSTSAuth)
                    {
                        // Add request headers if the server requires STS based auth.
                        STSAuthHelper.PrepareSTSRequest(request);
                    }

                    // Prepare the request, we do something like write to the request stream
                    // which needs to happen last before the request goes out
                    prepareRequest(request);

                    // Wrap the credentials in a CredentialCache in case there is a redirect
                    // and credentials need to be kept around.
                    request.Credentials = request.Credentials.AsCredentialCache(request.RequestUri);

                    WebResponse response = request.GetResponse();

                    // Cache the proxy and credentials
                    proxyCache.Add(request.Proxy);

                    credentialCache.Add(request.RequestUri, credentials);
                    credentialCache.Add(response.ResponseUri, credentials);

                    return(response);
                }
                catch (WebException ex)
                {
                    using (IHttpWebResponse response = GetResponse(ex.Response))
                    {
                        if (response == null &&
                            ex.Status != WebExceptionStatus.SecureChannelFailure)
                        {
                            // No response, something went wrong so just rethrow
                            throw;
                        }

                        // Special case https connections that might require authentication
                        if (ex.Status == WebExceptionStatus.SecureChannelFailure)
                        {
                            if (continueIfFailed)
                            {
                                // Act like we got a 401 so that we prompt for credentials on the next request
                                previousStatusCode = HttpStatusCode.Unauthorized;
                                continue;
                            }
                            throw;
                        }

                        // If we were trying to authenticate the proxy or the request and succeeded, cache the result.
                        if (previousStatusCode == HttpStatusCode.ProxyAuthenticationRequired &&
                            response.StatusCode != HttpStatusCode.ProxyAuthenticationRequired)
                        {
                            proxyCache.Add(request.Proxy);
                        }
                        else if (previousStatusCode == HttpStatusCode.Unauthorized &&
                                 response.StatusCode != HttpStatusCode.Unauthorized)
                        {
                            credentialCache.Add(request.RequestUri, request.Credentials);
                            credentialCache.Add(response.ResponseUri, request.Credentials);
                        }

                        usingSTSAuth = STSAuthHelper.TryRetrieveSTSToken(request.RequestUri, response);

                        if (!IsAuthenticationResponse(response) || !continueIfFailed)
                        {
                            throw;
                        }

                        previousRequest    = request;
                        previousResponse   = response;
                        previousStatusCode = previousResponse.StatusCode;
                    }
                }
            }
        }
Exemplo n.º 2
0
        public WebResponse GetResponse()
        {
            _previousRequest            = null;
            _previousResponse           = null;
            _previousStatusCode         = null;
            _usingSTSAuth               = false;
            _continueIfFailed           = true;
            _proxyCredentialsRetryCount = 0;
            _credentialsRetryCount      = 0;
            int       failureCount    = 0;
            const int MaxFailureCount = 10;

            while (true)
            {
                // Create the request
                var request = (HttpWebRequest)_createRequest();
                ConfigureRequest(request);

                try
                {
                    if (_disableBuffering)
                    {
                        request.AllowWriteStreamBuffering = false;

                        // When buffering is disabled, we need to add the Authorization header
                        // for basic authentication by ourselves.
                        bool basicAuth = _previousResponse != null &&
                                         _previousResponse.AuthType != null &&
                                         _previousResponse.AuthType.IndexOf("Basic", StringComparison.OrdinalIgnoreCase) != -1;
                        var networkCredentials = request.Credentials.GetCredential(request.RequestUri, "Basic");
                        if (networkCredentials != null && basicAuth)
                        {
                            string authInfo = networkCredentials.UserName + ":" + networkCredentials.Password;
                            authInfo = Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(authInfo));
                            request.Headers["Authorization"]  = "Basic " + authInfo;
                            _basicAuthIsUsedInPreviousRequest = true;
                        }
                    }

                    // Prepare the request, we do something like write to the request stream
                    // which needs to happen last before the request goes out
                    _prepareRequest(request);

                    // Shim and replace this request if needed for v3
                    WebResponse response = HttpShim.Instance.ShimWebRequest(request);

                    // Cache the proxy and credentials
                    _proxyCache.Add(request.Proxy);

                    ICredentials credentials = request.Credentials;
                    _credentialCache.Add(request.RequestUri, credentials);
                    _credentialCache.Add(response.ResponseUri, credentials);

                    return(response);
                }
                catch (WebException ex)
                {
                    ++failureCount;
                    if (failureCount >= MaxFailureCount)
                    {
                        throw;
                    }

                    using (IHttpWebResponse response = GetResponse(ex.Response))
                    {
                        if (response == null &&
                            ex.Status != WebExceptionStatus.SecureChannelFailure)
                        {
                            // No response, something went wrong so just rethrow
                            throw;
                        }

                        // Special case https connections that might require authentication
                        if (ex.Status == WebExceptionStatus.SecureChannelFailure)
                        {
                            if (_continueIfFailed)
                            {
                                // Act like we got a 401 so that we prompt for credentials on the next request
                                _previousStatusCode = HttpStatusCode.Unauthorized;
                                continue;
                            }
                            throw;
                        }

                        // If we were trying to authenticate the proxy or the request and succeeded, cache the result.
                        if (_previousStatusCode == HttpStatusCode.ProxyAuthenticationRequired &&
                            response.StatusCode != HttpStatusCode.ProxyAuthenticationRequired)
                        {
                            _proxyCache.Add(request.Proxy);
                        }
                        else if (_previousStatusCode == HttpStatusCode.Unauthorized &&
                                 response.StatusCode != HttpStatusCode.Unauthorized)
                        {
                            _credentialCache.Add(request.RequestUri, request.Credentials);
                            _credentialCache.Add(response.ResponseUri, request.Credentials);
                        }

                        _usingSTSAuth = STSAuthHelper.TryRetrieveSTSToken(request.RequestUri, response);

                        if (!IsAuthenticationResponse(response) || !_continueIfFailed)
                        {
                            throw;
                        }

                        if (!EnvironmentUtility.IsNet45Installed &&
                            request.AllowWriteStreamBuffering == false &&
                            response.AuthType != null &&
                            IsNtlmOrKerberos(response.AuthType))
                        {
                            // integrated windows authentication does not work when buffering is
                            // disabled on .net 4.0.
                            throw;
                        }

                        _previousRequest    = request;
                        _previousResponse   = response;
                        _previousStatusCode = _previousResponse.StatusCode;
                    }
                }
            }
        }
Exemplo n.º 3
0
        public WebResponse GetResponse()
        {
            WebResponse response2;

            this._previousRequest            = null;
            this._previousResponse           = null;
            this._previousStatusCode         = null;
            this._usingSTSAuth               = false;
            this._continueIfFailed           = true;
            this._proxyCredentialsRetryCount = 0;
            this._credentialsRetryCount      = 0;
            int num = 0;

            while (true)
            {
                HttpWebRequest request = (HttpWebRequest)this._createRequest();
                this.ConfigureRequest(request);
                try
                {
                    if (this._disableBuffering)
                    {
                        request.AllowWriteStreamBuffering = false;
                        bool flag = ((this._previousResponse != null) && (this._previousResponse.AuthType != null)) && (this._previousResponse.AuthType.IndexOf("Basic", StringComparison.OrdinalIgnoreCase) != -1);
                        NetworkCredential credential = request.Credentials.GetCredential(request.RequestUri, "Basic");
                        if ((credential != null) & flag)
                        {
                            string s = credential.UserName + ":" + credential.Password;
                            s = Convert.ToBase64String(Encoding.Default.GetBytes(s));
                            request.Headers["Authorization"]       = "Basic " + s;
                            this._basicAuthIsUsedInPreviousRequest = true;
                        }
                    }
                    this._prepareRequest(request);
                    WebResponse response = HttpShim.Instance.ShimWebRequest(request);
                    this._proxyCache.Add(request.Proxy);
                    ICredentials credentials = request.Credentials;
                    this._credentialCache.Add(request.RequestUri, credentials);
                    this._credentialCache.Add(response.ResponseUri, credentials);
                    response2 = response;
                    break;
                }
                catch (WebException exception)
                {
                    if ((num + 1) >= 10)
                    {
                        throw;
                    }
                    using (IHttpWebResponse response3 = GetResponse(exception.Response))
                    {
                        if ((response3 == null) && (exception.Status != WebExceptionStatus.SecureChannelFailure))
                        {
                            throw;
                        }
                        if (exception.Status == WebExceptionStatus.SecureChannelFailure)
                        {
                            if (!this._continueIfFailed)
                            {
                                throw;
                            }
                            this._previousStatusCode = 0x191;
                        }
                        else
                        {
                            HttpStatusCode?nullable = this._previousStatusCode;
                            HttpStatusCode proxyAuthenticationRequired = HttpStatusCode.ProxyAuthenticationRequired;
                            if (((((HttpStatusCode)nullable.GetValueOrDefault()) == proxyAuthenticationRequired) ? (nullable != null) : false) && (response3.StatusCode != HttpStatusCode.ProxyAuthenticationRequired))
                            {
                                this._proxyCache.Add(request.Proxy);
                            }
                            else
                            {
                                nullable = this._previousStatusCode;
                                proxyAuthenticationRequired = HttpStatusCode.Unauthorized;
                                if (((((HttpStatusCode)nullable.GetValueOrDefault()) == proxyAuthenticationRequired) ? (nullable != null) : false) && (response3.StatusCode != HttpStatusCode.Unauthorized))
                                {
                                    this._credentialCache.Add(request.RequestUri, request.Credentials);
                                    this._credentialCache.Add(response3.ResponseUri, request.Credentials);
                                }
                            }
                            this._usingSTSAuth = STSAuthHelper.TryRetrieveSTSToken(request.RequestUri, response3);
                            if (!IsAuthenticationResponse(response3) || !this._continueIfFailed)
                            {
                                throw;
                            }
                            if (!EnvironmentUtility.IsNet45Installed && (!request.AllowWriteStreamBuffering && ((response3.AuthType != null) && IsNtlmOrKerberos(response3.AuthType))))
                            {
                                throw;
                            }
                            this._previousRequest    = request;
                            this._previousResponse   = response3;
                            this._previousStatusCode = new HttpStatusCode?(this._previousResponse.StatusCode);
                        }
                    }
                }
            }
            return(response2);
        }