public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) { if (absoluteUri == null) { throw new ArgumentNullException("absoluteUri"); } if (absoluteUri.Scheme == "http" && (ofObjectToReturn == null || ofObjectToReturn == typeof(Stream))) { try { return(GetResponse(absoluteUri)); } catch (Exception e) { if (WebProxyService.ProxyAuthenticationRequired(e)) { WebProxyState state = ps.PrepareWebProxy(this.GetProxy(), absoluteUri.AbsoluteUri, WebProxyState.DefaultCredentials, true); if (state != WebProxyState.Abort) { // try again... return(GetResponse(absoluteUri)); } } throw; } } else { return(base.GetEntity(absoluteUri, role, ofObjectToReturn)); } }
/// <summary> /// This method attaches credentials to the web proxy object. /// </summary> /// <param name="proxy">The proxy to attach credentials to.</param> /// <param name="webCallUrl">The url for the web call.</param> /// <param name="oldProxyState">The current state fo the web call.</param> /// <param name="newProxyState">The new state for the web call.</param> /// <param name="okToPrompt">Prompt user for credentials if they are not available.</param> public WebProxyState PrepareWebProxy(IWebProxy proxy, string webCallUrl, WebProxyState oldProxyState, bool okToPrompt) { WebProxyState newProxyState = WebProxyState.Abort; if (string.IsNullOrEmpty(webCallUrl)) { Debug.Fail("PrepareWebProxy called with an empty WebCallUrl."); webCallUrl = "http://go.microsoft.com/fwlink/?LinkId=81947"; } // Get the web proxy url for the the current web call. Uri webCallProxy = null; if (proxy != null) { webCallProxy = proxy.GetProxy(new Uri(webCallUrl)); } if ((proxy != null) && (webCallProxy != null)) { // get proxy url. string proxyUrl = webCallProxy.Host; if (string.IsNullOrEmpty(currentProxyUrl)) { currentProxyUrl = proxyUrl; } switch (oldProxyState) { case WebProxyState.NoCredentials: // Add the default credentials only if there aren't any credentials attached to // the DefaultWebProxy. If the first calls attaches the correct credentials, the // second call will just use them, instead of overwriting it with the default credentials. // This avoids multiple web calls. Note that state is transitioned to DefaultCredentials // instead of CachedCredentials. This ensures that web calls be tried with the // cached credentials if the currently attached credentials don't result in successful web call. if ((proxy.Credentials == null)) { proxy.Credentials = CredentialCache.DefaultCredentials; } newProxyState = WebProxyState.DefaultCredentials; break; case WebProxyState.DefaultCredentials: // Fetch cached credentials if they are null or if the proxy url has changed. if ((cachedCredentials == null) || !string.Equals(currentProxyUrl, proxyUrl, StringComparison.OrdinalIgnoreCase)) { cachedCredentials = GetCachedCredentials(proxyUrl); } if (cachedCredentials != null) { proxy.Credentials = cachedCredentials; newProxyState = WebProxyState.CachedCredentials; break; } // Proceed to next step if cached credentials are not available. goto case WebProxyState.CachedCredentials; case WebProxyState.CachedCredentials: case WebProxyState.PromptForCredentials: if (okToPrompt) { if (DialogResult.OK == PromptForCredentials(proxyUrl)) { proxy.Credentials = cachedCredentials; newProxyState = WebProxyState.PromptForCredentials; } else { newProxyState = WebProxyState.Abort; } } else { newProxyState = WebProxyState.Abort; } break; case WebProxyState.Abort: throw new InvalidOperationException(); default: throw new ArgumentException(string.Empty, "oldProxyState"); } } else { // No proxy for the webCallUrl scenario. if (oldProxyState == WebProxyState.NoCredentials) { // if it is the first call, change the state and let the web call proceed. newProxyState = WebProxyState.DefaultCredentials; } else { Debug.Fail("This method is called a second time when 407 occurs. A 407 shouldn't have occurred as there is no default proxy."); // We dont have a good idea of the circumstances under which // WebProxy might be null for a url. To be safe, for VS 2005 SP1, // we will just return the abort state, instead of throwing // an exception. Abort state will ensure that no further procesing // occurs and we will not bring down the app. // throw new InvalidOperationException(); newProxyState = WebProxyState.Abort; } } return newProxyState; }
/// <summary> /// This method attaches credentials to the web proxy object. /// </summary> /// <param name="proxy">The proxy to attach credentials to.</param> /// <param name="webCallUrl">The url for the web call.</param> /// <param name="oldProxyState">The current state fo the web call.</param> /// <param name="newProxyState">The new state for the web call.</param> /// <param name="okToPrompt">Prompt user for credentials if they are not available.</param> public WebProxyState PrepareWebProxy(IWebProxy proxy, string webCallUrl, WebProxyState oldProxyState, bool okToPrompt) { WebProxyState newProxyState = WebProxyState.Abort; if (string.IsNullOrEmpty(webCallUrl)) { Debug.Fail("PrepareWebProxy called with an empty WebCallUrl."); webCallUrl = "http://go.microsoft.com/fwlink/?LinkId=81947"; } // Get the web proxy url for the the current web call. Uri webCallProxy = null; if (proxy != null) { webCallProxy = proxy.GetProxy(new Uri(webCallUrl)); } if ((proxy != null) && (webCallProxy != null)) { // get proxy url. string proxyUrl = webCallProxy.Host; if (string.IsNullOrEmpty(currentProxyUrl)) { currentProxyUrl = proxyUrl; } switch (oldProxyState) { case WebProxyState.NoCredentials: // Add the default credentials only if there aren't any credentials attached to // the DefaultWebProxy. If the first calls attaches the correct credentials, the // second call will just use them, instead of overwriting it with the default credentials. // This avoids multiple web calls. Note that state is transitioned to DefaultCredentials // instead of CachedCredentials. This ensures that web calls be tried with the // cached credentials if the currently attached credentials don't result in successful web call. if ((proxy.Credentials == null)) { proxy.Credentials = CredentialCache.DefaultCredentials; } newProxyState = WebProxyState.DefaultCredentials; break; case WebProxyState.DefaultCredentials: // Fetch cached credentials if they are null or if the proxy url has changed. if ((cachedCredentials == null) || !string.Equals(currentProxyUrl, proxyUrl, StringComparison.OrdinalIgnoreCase)) { cachedCredentials = GetCachedCredentials(proxyUrl); } if (cachedCredentials != null) { proxy.Credentials = cachedCredentials; newProxyState = WebProxyState.CachedCredentials; break; } // Proceed to next step if cached credentials are not available. goto case WebProxyState.CachedCredentials; case WebProxyState.CachedCredentials: case WebProxyState.PromptForCredentials: if (okToPrompt) { if (DialogResult.OK == PromptForCredentials(proxyUrl)) { proxy.Credentials = cachedCredentials; newProxyState = WebProxyState.PromptForCredentials; } else { newProxyState = WebProxyState.Abort; } } else { newProxyState = WebProxyState.Abort; } break; case WebProxyState.Abort: throw new InvalidOperationException(); default: throw new ArgumentException(string.Empty, "oldProxyState"); } } else { // No proxy for the webCallUrl scenario. if (oldProxyState == WebProxyState.NoCredentials) { // if it is the first call, change the state and let the web call proceed. newProxyState = WebProxyState.DefaultCredentials; } else { Debug.Fail("This method is called a second time when 407 occurs. A 407 shouldn't have occurred as there is no default proxy."); // We dont have a good idea of the circumstances under which // WebProxy might be null for a url. To be safe, for VS 2005 SP1, // we will just return the abort state, instead of throwing // an exception. Abort state will ensure that no further procesing // occurs and we will not bring down the app. // throw new InvalidOperationException(); newProxyState = WebProxyState.Abort; } } return(newProxyState); }