New test.
[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                 Uri address;
41                 bool bypassOnLocal;
42                 ArrayList bypassList;
43                 ICredentials credentials;
44
45                 // Constructors
46
47                 public WebProxy ()
48                         : this ((Uri) null, false, null, null) {}
49
50                 public WebProxy (string address)
51                         : this (ToUri (address), false, null, null) {}
52
53                 public WebProxy (Uri address) 
54                         : this (address, false, null, null) {}
55
56                 public WebProxy (string address, bool bypassOnLocal) 
57                         : this (ToUri (address), bypassOnLocal, null, null) {}
58
59                 public WebProxy (string host, int port)
60                         : this (new Uri ("http://" + host + ":" + port)) {}
61
62                 public WebProxy (Uri address, bool bypassOnLocal)
63                         : this (address, bypassOnLocal, null, null) {}
64
65                 public WebProxy (string address, bool bypassOnLocal, string [] bypassList)
66                         : this (ToUri (address), bypassOnLocal, bypassList, null) {}
67
68                 public WebProxy (Uri address, bool bypassOnLocal, string [] bypassList)
69                         : this (address, bypassOnLocal, bypassList, null) {}
70
71                 public WebProxy (string address, bool bypassOnLocal, string [] bypassList,
72                                 ICredentials credentials)
73                         : this (ToUri (address), bypassOnLocal, bypassList, credentials) {}
74
75                 public WebProxy (Uri address, bool bypassOnLocal, 
76                                  string[] bypassList, ICredentials credentials)
77                 {
78                         this.address = address;
79                         this.bypassOnLocal = bypassOnLocal;
80                         if (bypassList == null)
81                                 bypassList = new string [] {};
82                         this.bypassList = new ArrayList (bypassList);
83                         this.credentials = credentials;
84                         CheckBypassList ();
85                 }
86
87                 protected WebProxy (SerializationInfo serializationInfo, StreamingContext streamingContext) 
88                 {
89                         this.address = (Uri) serializationInfo.GetValue ("address", typeof (Uri));
90                         this.bypassOnLocal = serializationInfo.GetBoolean ("bypassOnLocal");
91                         this.bypassList = (ArrayList) serializationInfo.GetValue ("bypassList", typeof (ArrayList));
92                         this.credentials = null;
93                         CheckBypassList ();
94                 }
95
96                 // Properties
97                 public Uri Address {
98                         get { return address; }
99                         set { address = value; }
100                 }
101
102                 public ArrayList BypassArrayList {
103                         get { return bypassList; }
104                 }
105
106                 public string [] BypassList {
107                         get { return (string []) bypassList.ToArray (typeof (string)); }
108                         set { 
109                                 if (value == null)
110                                         throw new ArgumentNullException ();
111                                 bypassList = new ArrayList (value); 
112                                 CheckBypassList ();
113                         }
114                 }
115
116                 public bool BypassProxyOnLocal {
117                         get { return bypassOnLocal; }
118                         set { bypassOnLocal = value; }
119                 }
120
121                 public ICredentials Credentials {
122                         get { return credentials; }
123                         set { credentials = value; }
124                 }
125
126                 // Methods
127                 [MonoTODO("Can we get this info under windows from the system?")]
128                 public static WebProxy GetDefaultProxy ()
129                 {
130                         // Select gets a WebProxy from config files, if available.
131                         IWebProxy p = GlobalProxySelection.Select;
132                         if (p is WebProxy)
133                                 return (WebProxy) p;
134
135                         return new WebProxy ();
136                 }
137
138                 public Uri GetProxy (Uri destination)
139                 {
140                         if (IsBypassed (destination))
141                                 return destination;
142
143                         return address;
144                 }
145
146                 public bool IsBypassed (Uri host)
147                 {
148                         if (address == null)
149                                 return true;
150
151                         if (bypassOnLocal && host.IsLoopback)
152                                 return true;
153
154                         string server = host.Host;
155                         if (bypassOnLocal && server.IndexOf ('.') == -1)
156                                 return true;
157
158                         // LAMESPEC
159                         if (!bypassOnLocal) {
160                                 if (String.Compare (server, "localhost", true, CultureInfo.InvariantCulture) == 0)
161                                         return true;
162                                 if (String.Compare (server, "loopback", true, CultureInfo.InvariantCulture) == 0)
163                                         return true;
164
165                                 try {
166                                         IPAddress addr = IPAddress.Parse (server);
167                                         if (IPAddress.IsLoopback (addr))
168                                                 return true;
169                                 } catch {}
170                         }
171
172                         try {                           
173                                 string hostStr = host.Scheme + "://" + host.Authority;                          
174                                 int i = 0;
175                                 for (; i < bypassList.Count; i++) {
176                                         Regex regex = new Regex ((string) bypassList [i], 
177                                                 // TODO: RegexOptions.Compiled |  // not implemented yet by Regex
178                                                 RegexOptions.IgnoreCase |
179                                                 RegexOptions.Singleline);
180
181                                         if (regex.IsMatch (hostStr))
182                                                 break;
183                                 }
184
185                                 if (i == bypassList.Count)
186                                         return false;
187
188                                 // continue checking correctness of regular expressions..
189                                 // will throw expression when an invalid one is found
190                                 for (; i < bypassList.Count; i++)
191                                         new Regex ((string) bypassList [i]);
192
193                                 return true;
194                         } catch (ArgumentException) {
195                                 return false;
196                         }
197                 }
198
199                 void ISerializable.GetObjectData (SerializationInfo serializationInfo,
200                                                   StreamingContext streamingContext)
201                 {
202                         serializationInfo.AddValue ("bypassOnLocal", bypassOnLocal);
203                         serializationInfo.AddValue ("address", address);
204                         serializationInfo.AddValue ("bypassList", bypassList);
205                 }
206
207                 // Private Methods
208                 // this compiles the regular expressions, and will throw
209                 // an exception when an invalid one is found.
210                 void CheckBypassList ()
211                 {                       
212                         for (int i = 0; i < bypassList.Count; i++)
213                                 new Regex ((string) bypassList [i]);
214                 }
215
216                 static Uri ToUri (string address)
217                 {
218                         if (address == null)
219                                 return null;
220                                 
221                         if (address.IndexOf ("://") == -1) 
222                                 address = "http://" + address;
223
224                         return new Uri (address);
225                 }
226         }
227 }
228