2 // System.Net.WebRequest
5 // Lawrence Pit (loz@cable.a2000.nl)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections;
31 using System.Collections.Specialized;
32 using System.Configuration;
34 using System.Reflection;
35 using System.Runtime.Serialization;
36 using System.Globalization;
38 using System.Net.Configuration;
39 using System.Net.Security;
40 using System.Net.Cache;
41 using System.Security.Principal;
45 using ConfigurationException = System.ArgumentException;
47 namespace System.Net.Configuration {
55 internal abstract class WebRequest : ISerializable {
58 public abstract class WebRequest : MarshalByRefObject, ISerializable {
60 static HybridDictionary prefixes = new HybridDictionary ();
62 static bool isDefaultWebProxySet;
63 static IWebProxy defaultWebProxy;
64 static RequestCachePolicy defaultCachePolicy;
65 static MethodInfo cfGetDefaultProxy;
72 if (Platform.IsMacOS) {
74 Type type = Type.GetType ("MonoTouch.CoreFoundation.CFNetwork, monotouch");
76 Type type = Type.GetType ("MonoMac.CoreFoundation.CFNetwork, monomac");
79 cfGetDefaultProxy = type.GetMethod ("GetDefaultProxy");
83 IWebRequestCreate http = new HttpRequestCreator ();
84 RegisterPrefix ("http", http);
85 RegisterPrefix ("https", http);
87 RegisterPrefix ("file", new FileWebRequestCreator ());
88 RegisterPrefix ("ftp", new FtpRequestCreator ());
92 defaultCachePolicy = new HttpRequestCachePolicy (HttpRequestCacheLevel.NoCacheNoStore);
94 #if NET_2_0 && CONFIGURATION_DEP
95 object cfg = ConfigurationManager.GetSection ("system.net/webRequestModules");
96 WebRequestModulesSection s = cfg as WebRequestModulesSection;
98 foreach (WebRequestModuleElement el in
100 AddPrefix (el.Prefix, el.Type);
104 ConfigurationSettings.GetConfig ("system.net/webRequestModules");
108 protected WebRequest ()
112 protected WebRequest (SerializationInfo serializationInfo, StreamingContext streamingContext)
115 throw GetMustImplement ();
119 static Exception GetMustImplement ()
121 return new NotImplementedException ("This method must be implemented in derived classes");
127 private AuthenticationLevel authentication_level = AuthenticationLevel.MutualAuthRequested;
129 public AuthenticationLevel AuthenticationLevel
132 return(authentication_level);
135 authentication_level = value;
139 [MonoTODO ("Implement the caching system. Currently always returns a policy with the NoCacheNoStore level")]
140 public virtual RequestCachePolicy CachePolicy
142 get { return DefaultCachePolicy; }
148 public virtual string ConnectionGroupName {
149 get { throw GetMustImplement (); }
150 set { throw GetMustImplement (); }
153 public virtual long ContentLength {
154 get { throw GetMustImplement (); }
155 set { throw GetMustImplement (); }
158 public virtual string ContentType {
159 get { throw GetMustImplement (); }
160 set { throw GetMustImplement (); }
163 public virtual ICredentials Credentials {
164 get { throw GetMustImplement (); }
165 set { throw GetMustImplement (); }
169 public static RequestCachePolicy DefaultCachePolicy
171 get { return defaultCachePolicy; }
173 throw GetMustImplement ();
178 public virtual WebHeaderCollection Headers {
179 get { throw GetMustImplement (); }
180 set { throw GetMustImplement (); }
183 #if NET_2_0 && !MOONLIGHT
184 public TokenImpersonationLevel ImpersonationLevel {
185 get { throw GetMustImplement (); }
186 set { throw GetMustImplement (); }
189 public virtual string Method {
190 get { throw GetMustImplement (); }
191 set { throw GetMustImplement (); }
194 public virtual bool PreAuthenticate {
195 get { throw GetMustImplement (); }
196 set { throw GetMustImplement (); }
199 public virtual IWebProxy Proxy {
200 get { throw GetMustImplement (); }
201 set { throw GetMustImplement (); }
204 public virtual Uri RequestUri {
205 get { throw GetMustImplement (); }
208 public virtual int Timeout {
209 get { throw GetMustImplement (); }
210 set { throw GetMustImplement (); }
214 public virtual bool UseDefaultCredentials
217 throw GetMustImplement ();
220 throw GetMustImplement ();
224 // volatile static IWebProxy proxy;
225 static readonly object lockobj = new object ();
227 public static IWebProxy DefaultWebProxy {
229 if (!isDefaultWebProxySet) {
231 if (defaultWebProxy == null)
232 defaultWebProxy = GetDefaultWebProxy ();
235 return defaultWebProxy;
238 /* MS documentation states that a null value would cause an ArgumentNullException
239 * but that's not the way it behaves:
240 * https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304724
242 defaultWebProxy = value;
243 isDefaultWebProxySet = true;
247 [MonoTODO("Needs to respect Module, Proxy.AutoDetect, and Proxy.ScriptLocation config settings")]
248 static IWebProxy GetDefaultWebProxy ()
250 #if CONFIGURATION_DEP
251 DefaultProxySection sec = ConfigurationManager.GetSection ("system.net/defaultProxy") as DefaultProxySection;
255 return GetSystemWebProxy ();
257 ProxyElement pe = sec.Proxy;
259 if ((pe.UseSystemDefault != ProxyElement.UseSystemDefaultValues.False) && (pe.ProxyAddress == null))
260 p = (WebProxy) GetSystemWebProxy ();
264 if (pe.ProxyAddress != null)
265 p.Address = pe.ProxyAddress;
267 if (pe.BypassOnLocal != ProxyElement.BypassOnLocalValues.Unspecified)
268 p.BypassProxyOnLocal = (pe.BypassOnLocal == ProxyElement.BypassOnLocalValues.True);
272 return GetSystemWebProxy ();
279 public virtual void Abort()
281 throw GetMustImplement ();
284 public virtual IAsyncResult BeginGetRequestStream (AsyncCallback callback, object state)
286 throw GetMustImplement ();
289 public virtual IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
291 throw GetMustImplement ();
294 public static WebRequest Create (string requestUriString)
296 if (requestUriString == null)
297 throw new ArgumentNullException ("requestUriString");
298 return Create (new Uri (requestUriString));
301 public static WebRequest Create (Uri requestUri)
303 if (requestUri == null)
304 throw new ArgumentNullException ("requestUri");
305 return GetCreator (requestUri.AbsoluteUri).Create (requestUri);
308 public static WebRequest CreateDefault (Uri requestUri)
310 if (requestUri == null)
311 throw new ArgumentNullException ("requestUri");
312 return GetCreator (requestUri.Scheme).Create (requestUri);
315 public virtual Stream EndGetRequestStream (IAsyncResult asyncResult)
317 throw GetMustImplement ();
320 public virtual WebResponse EndGetResponse (IAsyncResult asyncResult)
322 throw GetMustImplement ();
325 public virtual Stream GetRequestStream()
327 throw GetMustImplement ();
330 public virtual WebResponse GetResponse()
332 throw GetMustImplement ();
336 [MonoTODO("Look in other places for proxy config info")]
337 public static IWebProxy GetSystemWebProxy ()
339 string address = Environment.GetEnvironmentVariable ("http_proxy");
341 address = Environment.GetEnvironmentVariable ("HTTP_PROXY");
343 if (address != null) {
345 if (!address.StartsWith ("http://"))
346 address = "http://" + address;
347 Uri uri = new Uri (address);
349 if (IPAddress.TryParse (uri.Host, out ip)) {
350 if (IPAddress.Any.Equals (ip)) {
351 UriBuilder builder = new UriBuilder (uri);
352 builder.Host = "127.0.0.1";
354 } else if (IPAddress.IPv6Any.Equals (ip)) {
355 UriBuilder builder = new UriBuilder (uri);
356 builder.Host = "[::1]";
360 return new WebProxy (uri);
361 } catch (UriFormatException) { }
364 if (cfGetDefaultProxy != null)
365 return (IWebProxy) cfGetDefaultProxy.Invoke (null, null);
367 return new WebProxy ();
371 void ISerializable.GetObjectData
372 (SerializationInfo serializationInfo,
373 StreamingContext streamingContext)
375 throw new NotSupportedException ();
380 protected virtual void GetObjectData (SerializationInfo serializationInfo, StreamingContext streamingContext)
382 throw GetMustImplement ();
386 public static bool RegisterPrefix (string prefix, IWebRequestCreate creator)
389 throw new ArgumentNullException ("prefix");
391 throw new ArgumentNullException ("creator");
393 lock (prefixes.SyncRoot) {
394 string lowerCasePrefix = prefix.ToLower (CultureInfo.InvariantCulture);
395 if (prefixes.Contains (lowerCasePrefix))
397 prefixes.Add (lowerCasePrefix, creator);
402 private static IWebRequestCreate GetCreator (string prefix)
404 int longestPrefix = -1;
405 IWebRequestCreate creator = null;
407 prefix = prefix.ToLower (CultureInfo.InvariantCulture);
409 IDictionaryEnumerator e = prefixes.GetEnumerator ();
410 while (e.MoveNext ()) {
411 string key = e.Key as string;
413 if (key.Length <= longestPrefix)
416 if (!prefix.StartsWith (key))
419 longestPrefix = key.Length;
420 creator = (IWebRequestCreate) e.Value;
424 throw new NotSupportedException (prefix);
429 internal static void ClearPrefixes ()
434 internal static void RemovePrefix (string prefix)
436 prefixes.Remove (prefix);
439 internal static void AddPrefix (string prefix, string typeName)
441 Type type = Type.GetType (typeName);
443 throw new ConfigurationException (String.Format ("Type {0} not found", typeName));
444 AddPrefix (prefix, type);
447 internal static void AddPrefix (string prefix, Type type)
449 object o = Activator.CreateInstance (type, true);
450 prefixes [prefix] = o;