Fixed MacOS proxy support for proxies requiring authentication
authorJeffrey Stedfast <jeff@xamarin.com>
Mon, 3 Dec 2012 17:23:08 +0000 (12:23 -0500)
committerJeffrey Stedfast <jeff@xamarin.com>
Mon, 3 Dec 2012 17:23:55 +0000 (12:23 -0500)
mcs/class/System/System.Net/MacProxy.cs

index f213b0d29e156704baef9450a37558a6cf578564..eb279fc2c745ef9bd0629455821014f058ec8ed7 100644 (file)
@@ -729,16 +729,22 @@ namespace System.Net
                }
                
                class CFWebProxy : IWebProxy {
+                       ICredentials credentials;
+                       bool userSpecified;
+                       
                        public CFWebProxy ()
                        {
-                               
                        }
                        
                        public ICredentials Credentials {
-                               get; set;
+                               get { return credentials; }
+                               set {
+                                       userSpecified = true;
+                                       credentials = value;
+                               }
                        }
                        
-                       static Uri GetProxyUri (CFProxy proxy)
+                       static Uri GetProxyUri (CFProxy proxy, out NetworkCredential credentials)
                        {
                                string protocol;
                                
@@ -751,6 +757,7 @@ namespace System.Net
                                        protocol = "http://";
                                        break;
                                default:
+                                       credentials = null;
                                        return null;
                                }
                                
@@ -758,29 +765,26 @@ namespace System.Net
                                string password = proxy.Password;
                                string hostname = proxy.HostName;
                                int port = proxy.Port;
-                               string userinfo;
                                string uri;
                                
-                               if (username != null) {
-                                       if (password != null)
-                                               userinfo = Uri.EscapeDataString (username) + ':' + Uri.EscapeDataString (password) + '@';
-                                       else
-                                               userinfo = Uri.EscapeDataString (username) + '@';
-                               } else {
-                                       userinfo = string.Empty;
-                               }
+                               if (username != null)
+                                       credentials = new NetworkCredential (username, password);
+                               else
+                                       credentials = null;
                                
-                               uri = protocol + userinfo + hostname + (port != 0 ? ':' + port.ToString () : string.Empty);
+                               uri = protocol + hostname + (port != 0 ? ':' + port.ToString () : string.Empty);
                                
                                return new Uri (uri, UriKind.Absolute);
                        }
                        
-                       static Uri GetProxyUriFromScript (IntPtr script, Uri targetUri)
+                       static Uri GetProxyUriFromScript (IntPtr script, Uri targetUri, out NetworkCredential credentials)
                        {
                                CFProxy[] proxies = CFNetwork.GetProxiesForAutoConfigurationScript (script, targetUri);
                                
-                               if (proxies == null)
+                               if (proxies == null) {
+                                       credentials = null;
                                        return targetUri;
+                               }
                                
                                for (int i = 0; i < proxies.Length; i++) {
                                        switch (proxies[i].ProxyType) {
@@ -788,60 +792,76 @@ namespace System.Net
                                        case CFProxyType.HTTP:
                                        case CFProxyType.FTP:
                                                // create a Uri based on the hostname/port/etc info
-                                               return GetProxyUri (proxies[i]);
+                                               return GetProxyUri (proxies[i], out credentials);
                                        case CFProxyType.SOCKS:
                                        default:
                                                // unsupported proxy type, try the next one
                                                break;
                                        case CFProxyType.None:
                                                // no proxy should be used
+                                               credentials = null;
                                                return targetUri;
                                        }
                                }
                                
+                               credentials = null;
+                               
                                return null;
                        }
                        
                        public Uri GetProxy (Uri targetUri)
                        {
+                               NetworkCredentials credentials = null;
+                               Uri proxy = null;
+                               
                                if (targetUri == null)
                                        throw new ArgumentNullException ("targetUri");
                                
                                try {
                                        CFProxySettings settings = CFNetwork.GetSystemProxySettings ();
                                        CFProxy[] proxies = CFNetwork.GetProxiesForUri (targetUri, settings);
-                                       Uri uri;
-                                       
-                                       if (proxies == null)
-                                               return targetUri;
                                        
-                                       for (int i = 0; i < proxies.Length; i++) {
-                                               switch (proxies[i].ProxyType) {
-                                               case CFProxyType.AutoConfigurationJavaScript:
-                                                       if ((uri = GetProxyUriFromScript (proxies[i].AutoConfigurationJavaScript, targetUri)) != null)
-                                                               return uri;
-                                                       break;
-                                               case CFProxyType.AutoConfigurationUrl:
-                                                       // unsupported proxy type (requires fetching script from remote url)
-                                                       break;
-                                               case CFProxyType.HTTPS:
-                                               case CFProxyType.HTTP:
-                                               case CFProxyType.FTP:
-                                                       // create a Uri based on the hostname/port/etc info
-                                                       return GetProxyUri (proxies[i]);
-                                               case CFProxyType.SOCKS:
-                                                       // unsupported proxy type, try the next one
-                                                       break;
-                                               case CFProxyType.None:
-                                                       // no proxy should be used
-                                                       return targetUri;
+                                       if (proxies != null) {
+                                               for (int i = 0; i < proxies.Length && proxy == null; i++) {
+                                                       switch (proxies[i].ProxyType) {
+                                                       case CFProxyType.AutoConfigurationJavaScript:
+                                                               proxy = GetProxyUriFromScript (proxies[i].AutoConfigurationJavaScript, targetUri, out credentials);
+                                                               break;
+                                                       case CFProxyType.AutoConfigurationUrl:
+                                                               // unsupported proxy type (requires fetching script from remote url)
+                                                               break;
+                                                       case CFProxyType.HTTPS:
+                                                       case CFProxyType.HTTP:
+                                                       case CFProxyType.FTP:
+                                                               // create a Uri based on the hostname/port/etc info
+                                                               proxy = GetProxyUri (proxies[i], out credentials);
+                                                               break;
+                                                       case CFProxyType.SOCKS:
+                                                               // unsupported proxy type, try the next one
+                                                               break;
+                                                       case CFProxyType.None:
+                                                               // no proxy should be used
+                                                               proxy = targetUri;
+                                                               break;
+                                                       }
                                                }
+                                               
+                                               if (proxy == null) {
+                                                       // no supported proxies for this Uri, fall back to trying to connect to targetUri directly
+                                                       proxy = targetUri;
+                                               }
+                                       } else {
+                                               proxy = targetUri;
                                        }
                                } catch {
                                        // ignore errors while retrieving proxy data
+                                       proxy = targetUri;
                                }
-                               // no supported proxies for this Uri, fall back to trying to connect to targetUri directly.
-                               return targetUri;
+                               
+                               if (!userSpecified)
+                                       this.credentials = credentials;
+                               
+                               return proxy;
                        }
                        
                        public bool IsBypassed (Uri targetUri)