In gmcs:
[mono.git] / mcs / class / System / System.Net / WebProxy.cs
1 //
2 // System.Net.WebProxy.cs
3 //
4 // Authors:
5 //   Lawrence Pit (loz@cable.a2000.nl)
6 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 //
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System;
31 using System.Collections;
32 using System.Globalization;
33 using System.Runtime.Serialization;
34 using System.Text.RegularExpressions;
35
36 namespace System.Net 
37 {
38         [Serializable]
39         public class WebProxy : IWebProxy, ISerializable
40         {
41                 Uri address;
42                 bool bypassOnLocal;
43                 ArrayList bypassList;
44                 ICredentials credentials;
45 #if NET_2_0
46                 bool useDefaultCredentials;
47 #endif
48
49                 // Constructors
50
51                 public WebProxy ()
52                         : this ((Uri) null, false, null, null) {}
53
54                 public WebProxy (string address)
55                         : this (ToUri (address), false, null, null) {}
56
57                 public WebProxy (Uri address) 
58                         : this (address, false, null, null) {}
59
60                 public WebProxy (string address, bool bypassOnLocal) 
61                         : this (ToUri (address), bypassOnLocal, null, null) {}
62
63                 public WebProxy (string host, int port)
64                         : this (new Uri ("http://" + host + ":" + port)) {}
65
66                 public WebProxy (Uri address, bool bypassOnLocal)
67                         : this (address, bypassOnLocal, null, null) {}
68
69                 public WebProxy (string address, bool bypassOnLocal, string [] bypassList)
70                         : this (ToUri (address), bypassOnLocal, bypassList, null) {}
71
72                 public WebProxy (Uri address, bool bypassOnLocal, string [] bypassList)
73                         : this (address, bypassOnLocal, bypassList, null) {}
74
75                 public WebProxy (string address, bool bypassOnLocal, string [] bypassList,
76                                 ICredentials credentials)
77                         : this (ToUri (address), bypassOnLocal, bypassList, credentials) {}
78
79                 public WebProxy (Uri address, bool bypassOnLocal, 
80                                  string[] bypassList, ICredentials credentials)
81                 {
82                         this.address = address;
83                         this.bypassOnLocal = bypassOnLocal;
84                         if (bypassList != null)
85                                 this.bypassList = new ArrayList (bypassList);
86                         this.credentials = credentials;
87                         CheckBypassList ();
88                 }
89
90                 protected WebProxy (SerializationInfo serializationInfo, StreamingContext streamingContext) 
91                 {
92                         this.address = (Uri) serializationInfo.GetValue ("_ProxyAddress", typeof (Uri));
93                         this.bypassOnLocal = serializationInfo.GetBoolean ("_BypassOnLocal");
94                         this.bypassList = (ArrayList) serializationInfo.GetValue ("_BypassList", typeof (ArrayList));
95 #if NET_2_0
96                         this.useDefaultCredentials =  serializationInfo.GetBoolean ("_UseDefaultCredentials");
97 #endif
98                         this.credentials = null;
99                         CheckBypassList ();
100                 }
101
102                 // Properties
103                 public Uri Address {
104                         get { return address; }
105                         set { address = value; }
106                 }
107
108                 public ArrayList BypassArrayList {
109                         get {
110                                 if (bypassList == null)
111                                         bypassList = new ArrayList ();
112                                 return bypassList;
113                         }
114                 }
115
116                 public string [] BypassList {
117                         get { return (string []) BypassArrayList.ToArray (typeof (string)); }
118                         set { 
119                                 if (value == null)
120                                         throw new ArgumentNullException ();
121                                 bypassList = new ArrayList (value); 
122                                 CheckBypassList ();
123                         }
124                 }
125
126                 public bool BypassProxyOnLocal {
127                         get { return bypassOnLocal; }
128                         set { bypassOnLocal = value; }
129                 }
130
131                 public ICredentials Credentials {
132                         get { return credentials; }
133                         set { credentials = value; }
134                 }
135
136 #if NET_2_0
137                 [MonoTODO ("Does not affect Credentials, since CredentialCache.DefaultCredentials is not implemented.")]
138                 public bool UseDefaultCredentials {
139                         get { return useDefaultCredentials; }
140                         set { useDefaultCredentials = value; }
141                 }
142 #endif
143
144                 // Methods
145                 [MonoTODO("Can we get this info under windows from the system?")]
146                 public static WebProxy GetDefaultProxy ()
147                 {
148                         // Select gets a WebProxy from config files, if available.
149                         IWebProxy p = GlobalProxySelection.Select;
150                         if (p is WebProxy)
151                                 return (WebProxy) p;
152
153                         return new WebProxy ();
154                 }
155
156                 public Uri GetProxy (Uri destination)
157                 {
158                         if (IsBypassed (destination))
159                                 return destination;
160
161                         return address;
162                 }
163
164                 public bool IsBypassed (Uri host)
165                 {
166 #if NET_2_0
167                         if (host == null)
168                                 throw new ArgumentNullException ("host");
169 #endif
170
171                         if (bypassOnLocal && host.IsLoopback)
172                                 return true;
173
174                         string server = host.Host;
175                         if (bypassOnLocal && server.IndexOf ('.') == -1)
176                                 return true;
177
178                         // LAMESPEC
179                         if (!bypassOnLocal) {
180                                 if (String.Compare (server, "localhost", true, CultureInfo.InvariantCulture) == 0)
181                                         return true;
182                                 if (String.Compare (server, "loopback", true, CultureInfo.InvariantCulture) == 0)
183                                         return true;
184
185                                 try {
186                                         IPAddress addr = IPAddress.Parse (server);
187                                         if (IPAddress.IsLoopback (addr))
188                                                 return true;
189                                 } catch {}
190                         }
191
192                         if (bypassList == null)
193                                 return false;
194
195                         try {
196                                 string hostStr = host.Scheme + "://" + host.Authority;
197                                 int i = 0;
198                                 for (; i < bypassList.Count; i++) {
199                                         Regex regex = new Regex ((string) bypassList [i], 
200                                                 // TODO: RegexOptions.Compiled |  // not implemented yet by Regex
201                                                 RegexOptions.IgnoreCase |
202                                                 RegexOptions.Singleline);
203
204                                         if (regex.IsMatch (hostStr))
205                                                 break;
206                                 }
207
208                                 if (i == bypassList.Count)
209                                         return false;
210
211                                 // continue checking correctness of regular expressions..
212                                 // will throw expression when an invalid one is found
213                                 for (; i < bypassList.Count; i++)
214                                         new Regex ((string) bypassList [i]);
215
216                                 return true;
217                         } catch (ArgumentException) {
218                                 return false;
219                         }
220                 }
221
222                 void ISerializable.GetObjectData (SerializationInfo serializationInfo,
223                                                   StreamingContext streamingContext)
224                 {
225                         serializationInfo.AddValue ("_BypassOnLocal", bypassOnLocal);
226                         serializationInfo.AddValue ("_ProxyAddress", address);
227                         serializationInfo.AddValue ("_BypassList", bypassList);
228 #if NET_2_0
229                         serializationInfo.AddValue ("_UseDefaultCredentials", UseDefaultCredentials);
230 #endif
231                 }
232
233                 // Private Methods
234                 // this compiles the regular expressions, and will throw
235                 // an exception when an invalid one is found.
236                 void CheckBypassList ()
237                 {
238                         if (bypassList == null)
239                                 return;
240                         for (int i = 0; i < bypassList.Count; i++)
241                                 new Regex ((string) bypassList [i]);
242                 }
243
244                 static Uri ToUri (string address)
245                 {
246                         if (address == null)
247                                 return null;
248                                 
249                         if (address.IndexOf ("://") == -1) 
250                                 address = "http://" + address;
251
252                         return new Uri (address);
253                 }
254         }
255 }