[System] WebRequest from referencesource
[mono.git] / mcs / class / System / System.Net / WebProxy.cs
index 6d49a01c00987556daf9a7de5a7f3cb8417ae5c6..a0f422b4c6a4a28002fa1c27a71a0a17e26661d8 100644 (file)
@@ -32,15 +32,18 @@ using System.Collections;
 using System.Globalization;
 using System.Runtime.Serialization;
 using System.Text.RegularExpressions;
+using Mono.Net;
 
 namespace System.Net 
 {
        [Serializable]
-       public class WebProxy : IWebProxy, ISerializable {
+       public class WebProxy : IWebProxy, ISerializable
+       {
                Uri address;
                bool bypassOnLocal;
                ArrayList bypassList;
                ICredentials credentials;
+               bool useDefaultCredentials;
 
                // Constructors
 
@@ -77,18 +80,18 @@ namespace System.Net
                {
                        this.address = address;
                        this.bypassOnLocal = bypassOnLocal;
-                       if (bypassList == null)
-                               bypassList = new string [] {};
-                       this.bypassList = new ArrayList (bypassList);
+                       if (bypassList != null)
+                               this.bypassList = new ArrayList (bypassList);
                        this.credentials = credentials;
                        CheckBypassList ();
                }
 
                protected WebProxy (SerializationInfo serializationInfo, StreamingContext streamingContext) 
                {
-                       this.address = (Uri) serializationInfo.GetValue ("address", typeof (Uri));
-                       this.bypassOnLocal = serializationInfo.GetBoolean ("bypassOnLocal");
-                       this.bypassList = (ArrayList) serializationInfo.GetValue ("bypassList", typeof (ArrayList));
+                       this.address = (Uri) serializationInfo.GetValue ("_ProxyAddress", typeof (Uri));
+                       this.bypassOnLocal = serializationInfo.GetBoolean ("_BypassOnLocal");
+                       this.bypassList = (ArrayList) serializationInfo.GetValue ("_BypassList", typeof (ArrayList));
+                       this.useDefaultCredentials =  serializationInfo.GetBoolean ("_UseDefaultCredentials");
                        this.credentials = null;
                        CheckBypassList ();
                }
@@ -100,11 +103,15 @@ namespace System.Net
                }
 
                public ArrayList BypassArrayList {
-                       get { return bypassList; }
+                       get {
+                               if (bypassList == null)
+                                       bypassList = new ArrayList ();
+                               return bypassList;
+                       }
                }
 
                public string [] BypassList {
-                       get { return (string []) bypassList.ToArray (typeof (string)); }
+                       get { return (string []) BypassArrayList.ToArray (typeof (string)); }
                        set { 
                                if (value == null)
                                        throw new ArgumentNullException ();
@@ -123,7 +130,14 @@ namespace System.Net
                        set { credentials = value; }
                }
 
+               [MonoTODO ("Does not affect Credentials, since CredentialCache.DefaultCredentials is not implemented.")]
+               public bool UseDefaultCredentials {
+                       get { return useDefaultCredentials; }
+                       set { useDefaultCredentials = value; }
+               }
+
                // Methods
+               [Obsolete ("This method has been deprecated", false)]
                [MonoTODO("Can we get this info under windows from the system?")]
                public static WebProxy GetDefaultProxy ()
                {
@@ -145,10 +159,13 @@ namespace System.Net
 
                public bool IsBypassed (Uri host)
                {
-                       if (address == null)
+                       if (host == null)
+                               throw new ArgumentNullException ("host");
+
+                       if (host.IsLoopback && bypassOnLocal)
                                return true;
 
-                       if (bypassOnLocal && host.IsLoopback)
+                       if (address == null)
                                return true;
 
                        string server = host.Host;
@@ -162,15 +179,16 @@ namespace System.Net
                                if (String.Compare (server, "loopback", true, CultureInfo.InvariantCulture) == 0)
                                        return true;
 
-                               try {
-                                       IPAddress addr = IPAddress.Parse (server);
-                                       if (IPAddress.IsLoopback (addr))
-                                               return true;
-                               } catch {}
+                               IPAddress addr = null;
+                               if (IPAddress.TryParse (server, out addr) && IPAddress.IsLoopback (addr))
+                                       return true;
                        }
 
-                       try {                           
-                               string hostStr = host.Scheme + "://" + host.Authority;                          
+                       if (bypassList == null || bypassList.Count == 0)
+                               return false;
+
+                       try {
+                               string hostStr = host.Scheme + "://" + host.Authority;
                                int i = 0;
                                for (; i < bypassList.Count; i++) {
                                        Regex regex = new Regex ((string) bypassList [i], 
@@ -196,19 +214,27 @@ namespace System.Net
                        }
                }
 
+               protected virtual void GetObjectData (SerializationInfo serializationInfo, StreamingContext streamingContext)
+               {
+                       serializationInfo.AddValue ("_BypassOnLocal", bypassOnLocal);
+                       serializationInfo.AddValue ("_ProxyAddress", address);
+                       serializationInfo.AddValue ("_BypassList", bypassList);
+                       serializationInfo.AddValue ("_UseDefaultCredentials", UseDefaultCredentials);
+               }
+
                void ISerializable.GetObjectData (SerializationInfo serializationInfo,
                                                  StreamingContext streamingContext)
                {
-                       serializationInfo.AddValue ("bypassOnLocal", bypassOnLocal);
-                       serializationInfo.AddValue ("address", address);
-                       serializationInfo.AddValue ("bypassList", bypassList);
+                       GetObjectData (serializationInfo, streamingContext);
                }
 
                // Private Methods
                // this compiles the regular expressions, and will throw
                // an exception when an invalid one is found.
                void CheckBypassList ()
-               {                       
+               {
+                       if (bypassList == null)
+                               return;
                        for (int i = 0; i < bypassList.Count; i++)
                                new Regex ((string) bypassList [i]);
                }
@@ -218,11 +244,142 @@ namespace System.Net
                        if (address == null)
                                return null;
                                
-                       if (address.IndexOf ("://") == -1) 
+                       if (address.IndexOf ("://", StringComparison.Ordinal) == -1) 
                                address = "http://" + address;
 
                        return new Uri (address);
                }
+
+               internal static IWebProxy CreateDefaultProxy ()
+               {
+#if MONOTOUCH
+                       return CFNetwork.GetDefaultProxy ();
+#elif MONODROID
+                       // Return the system web proxy.  This only works for ICS+.
+                       var androidProxy = AndroidPlatform.GetDefaultProxy ();
+                       if (androidProxy != null)
+                               return androidProxy;
+
+                       return new WebProxy (false);
+#else
+                       if (Platform.IsMacOS)
+                               return CFNetwork.GetDefaultProxy ();
+
+                       return new WebProxy (false);
+#endif
+               }
+
+               // Global settings initialization
+               private WebProxy (bool enableAutoproxy)
+               {
+#if !MOBILE                    
+                       if (IsWindows () && InitializeRegistryGlobalProxy ())
+                               return;
+#endif
+                       string address = Environment.GetEnvironmentVariable ("http_proxy") ?? Environment.GetEnvironmentVariable ("HTTP_PROXY");
+
+                       if (address != null) {
+                               try {
+                                       if (!address.StartsWith ("http://"))
+                                               address = "http://" + address;
+
+                                       Uri uri = new Uri (address);
+                                       IPAddress ip;
+                                       
+                                       if (IPAddress.TryParse (uri.Host, out ip)) {
+                                               if (IPAddress.Any.Equals (ip)) {
+                                                       UriBuilder builder = new UriBuilder (uri);
+                                                       builder.Host = "127.0.0.1";
+                                                       uri = builder.Uri;
+                                               } else if (IPAddress.IPv6Any.Equals (ip)) {
+                                                       UriBuilder builder = new UriBuilder (uri);
+                                                       builder.Host = "[::1]";
+                                                       uri = builder.Uri;
+                                               }
+                                       }
+
+                                       bool bBypassOnLocal = false;
+                                       ArrayList al = new ArrayList ();
+                                       string bypass = Environment.GetEnvironmentVariable ("no_proxy") ?? Environment.GetEnvironmentVariable ("NO_PROXY");
+                                       
+                                       if (bypass != null) {
+                                               string[] bypassList = bypass.Split (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+                                       
+                                               foreach (string str in bypassList) {
+                                                       if (str != "*.local")
+                                                               al.Add (str);
+                                                       else
+                                                               bBypassOnLocal = true;
+                                               }
+                                       }
+
+                                       this.address = uri;
+                                       this.bypassOnLocal = bBypassOnLocal;
+                                       this.bypassList = CreateBypassList (al);
+                                       return;
+                               } catch (UriFormatException) {
+                               }
+                       }
+               }
+
+#if !MOBILE
+               static bool IsWindows ()
+               {
+                       return (int) Environment.OSVersion.Platform < 4;
+               }
+                               
+               bool InitializeRegistryGlobalProxy ()
+               {
+                       int iProxyEnable = (int)Microsoft.Win32.Registry.GetValue ("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "ProxyEnable", 0);
+
+                       if (iProxyEnable > 0) {
+                               string strHttpProxy = "";
+                               bool bBypassOnLocal = false;
+                               ArrayList al = new ArrayList ();
+                               
+                               string strProxyServer = (string)Microsoft.Win32.Registry.GetValue ("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "ProxyServer", null);
+                               string strProxyOverrride = (string)Microsoft.Win32.Registry.GetValue ("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "ProxyOverride", null);
+                               
+                               if (strProxyServer.Contains ("=")) {
+                                       foreach (string strEntry in strProxyServer.Split (new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
+                                               if (strEntry.StartsWith ("http=")) {
+                                                       strHttpProxy = strEntry.Substring (5);
+                                                       break;
+                                               }
+                               } else strHttpProxy = strProxyServer;
+                               
+                               if (strProxyOverrride != null) {
+                                       string[] bypassList = strProxyOverrride.Split (new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
+                               
+                                       foreach (string str in bypassList) {
+                                               if (str != "<local>")
+                                                       al.Add (str);
+                                               else
+                                                       bBypassOnLocal = true;
+                                       }
+                               }
+
+                               this.address = ToUri (strHttpProxy);
+                               this.bypassOnLocal = bBypassOnLocal;
+                               this.bypassList = CreateBypassList (al);
+                               return true;
+                       }
+
+                       return false;
+               }
+#endif
+
+               // Takes an ArrayList of fileglob-formatted strings and returns an array of Regex-formatted strings
+               static ArrayList CreateBypassList (ArrayList al)
+               {
+                       string[] result = al.ToArray (typeof (string)) as string[];
+                       for (int c = 0; c < result.Length; c++)
+                       {
+                               result [c] = "^" +
+                                       Regex.Escape (result [c]).Replace (@"\*", ".*").Replace (@"\?", ".") +
+                                       "$";
+                       }
+                       return new ArrayList (result);
+               }
        }
 }
-