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.Runtime.Serialization;
35 using System.Globalization;
37 using System.Net.Configuration;
38 using System.Net.Security;
39 using System.Net.Cache;
40 using System.Security.Principal;
44 using ConfigurationException = System.ArgumentException;
46 namespace System.Net.Configuration {
54 internal abstract class WebRequest : ISerializable {
57 public abstract class WebRequest : MarshalByRefObject, ISerializable {
59 static HybridDictionary prefixes = new HybridDictionary ();
61 static bool isDefaultWebProxySet;
62 static IWebProxy defaultWebProxy;
70 AddPrefix ("http", typeof (HttpRequestCreator));
71 AddPrefix ("https", typeof (HttpRequestCreator));
73 AddPrefix ("file", typeof (FileWebRequestCreator));
74 AddPrefix ("ftp", typeof (FtpRequestCreator));
77 #if NET_2_0 && CONFIGURATION_DEP
78 object cfg = ConfigurationManager.GetSection ("system.net/webRequestModules");
79 WebRequestModulesSection s = cfg as WebRequestModulesSection;
81 foreach (WebRequestModuleElement el in
83 AddPrefix (el.Prefix, el.Type);
87 ConfigurationSettings.GetConfig ("system.net/webRequestModules");
91 protected WebRequest ()
95 protected WebRequest (SerializationInfo serializationInfo, StreamingContext streamingContext)
98 throw GetMustImplement ();
102 static Exception GetMustImplement ()
104 return new NotImplementedException ("This method must be implemented in derived classes");
110 private AuthenticationLevel authentication_level = AuthenticationLevel.MutualAuthRequested;
112 public AuthenticationLevel AuthenticationLevel
115 return(authentication_level);
118 authentication_level = value;
122 public virtual RequestCachePolicy CachePolicy
125 throw GetMustImplement ();
132 public virtual string ConnectionGroupName {
133 get { throw GetMustImplement (); }
134 set { throw GetMustImplement (); }
137 public virtual long ContentLength {
138 get { throw GetMustImplement (); }
139 set { throw GetMustImplement (); }
142 public virtual string ContentType {
143 get { throw GetMustImplement (); }
144 set { throw GetMustImplement (); }
147 public virtual ICredentials Credentials {
148 get { throw GetMustImplement (); }
149 set { throw GetMustImplement (); }
153 public static RequestCachePolicy DefaultCachePolicy
156 throw GetMustImplement ();
159 throw GetMustImplement ();
164 public virtual WebHeaderCollection Headers {
165 get { throw GetMustImplement (); }
166 set { throw GetMustImplement (); }
169 #if NET_2_0 && !MOONLIGHT
170 public TokenImpersonationLevel ImpersonationLevel {
171 get { throw GetMustImplement (); }
172 set { throw GetMustImplement (); }
175 public virtual string Method {
176 get { throw GetMustImplement (); }
177 set { throw GetMustImplement (); }
180 public virtual bool PreAuthenticate {
181 get { throw GetMustImplement (); }
182 set { throw GetMustImplement (); }
185 public virtual IWebProxy Proxy {
186 get { throw GetMustImplement (); }
187 set { throw GetMustImplement (); }
190 public virtual Uri RequestUri {
191 get { throw GetMustImplement (); }
194 public virtual int Timeout {
195 get { throw GetMustImplement (); }
196 set { throw GetMustImplement (); }
200 public virtual bool UseDefaultCredentials
203 throw GetMustImplement ();
206 throw GetMustImplement ();
210 // volatile static IWebProxy proxy;
211 static readonly object lockobj = new object ();
213 public static IWebProxy DefaultWebProxy {
215 if (!isDefaultWebProxySet) {
217 if (defaultWebProxy == null)
218 defaultWebProxy = GetDefaultWebProxy ();
221 return defaultWebProxy;
224 /* MS documentation states that a null value would cause an ArgumentNullException
225 * but that's not the way it behaves:
226 * https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304724
228 defaultWebProxy = value;
229 isDefaultWebProxySet = true;
233 [MonoTODO("Needs to respect Module, Proxy.AutoDetect, and Proxy.ScriptLocation config settings")]
234 static IWebProxy GetDefaultWebProxy ()
238 #if CONFIGURATION_DEP
239 DefaultProxySection sec = ConfigurationManager.GetSection ("system.net/defaultProxy") as DefaultProxySection;
241 return GetSystemWebProxy ();
243 ProxyElement pe = sec.Proxy;
245 if ((pe.UseSystemDefault != ProxyElement.UseSystemDefaultValues.False) && (pe.ProxyAddress == null))
246 p = (WebProxy) GetSystemWebProxy ();
250 if (pe.ProxyAddress != null)
251 p.Address = pe.ProxyAddress;
253 if (pe.BypassOnLocal != ProxyElement.BypassOnLocalValues.Unspecified)
254 p.BypassProxyOnLocal = (pe.BypassOnLocal == ProxyElement.BypassOnLocalValues.True);
262 public virtual void Abort()
264 throw GetMustImplement ();
267 public virtual IAsyncResult BeginGetRequestStream (AsyncCallback callback, object state)
269 throw GetMustImplement ();
272 public virtual IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
274 throw GetMustImplement ();
277 public static WebRequest Create (string requestUriString)
279 if (requestUriString == null)
280 throw new ArgumentNullException ("requestUriString");
281 return Create (new Uri (requestUriString));
284 public static WebRequest Create (Uri requestUri)
286 if (requestUri == null)
287 throw new ArgumentNullException ("requestUri");
288 return GetCreator (requestUri.AbsoluteUri).Create (requestUri);
291 public static WebRequest CreateDefault (Uri requestUri)
293 if (requestUri == null)
294 throw new ArgumentNullException ("requestUri");
295 return GetCreator (requestUri.Scheme).Create (requestUri);
298 public virtual Stream EndGetRequestStream (IAsyncResult asyncResult)
300 throw GetMustImplement ();
303 public virtual WebResponse EndGetResponse (IAsyncResult asyncResult)
305 throw GetMustImplement ();
308 public virtual Stream GetRequestStream()
310 throw GetMustImplement ();
313 public virtual WebResponse GetResponse()
315 throw GetMustImplement ();
319 [MonoTODO("Look in other places for proxy config info")]
320 public static IWebProxy GetSystemWebProxy ()
322 string address = Environment.GetEnvironmentVariable ("http_proxy");
324 address = Environment.GetEnvironmentVariable ("HTTP_PROXY");
326 if (address != null) {
328 if (!address.StartsWith ("http://"))
329 address = "http://" + address;
330 Uri uri = new Uri (address);
332 if (IPAddress.TryParse (uri.Host, out ip)) {
333 if (IPAddress.Any.Equals (ip)) {
334 UriBuilder builder = new UriBuilder (uri);
335 builder.Host = "127.0.0.1";
337 } else if (IPAddress.IPv6Any.Equals (ip)) {
338 UriBuilder builder = new UriBuilder (uri);
339 builder.Host = "[::1]";
343 return new WebProxy (uri);
344 } catch (UriFormatException) { }
346 return new WebProxy ();
350 void ISerializable.GetObjectData
351 (SerializationInfo serializationInfo,
352 StreamingContext streamingContext)
354 throw new NotSupportedException ();
359 protected virtual void GetObjectData (SerializationInfo serializationInfo, StreamingContext streamingContext)
361 throw GetMustImplement ();
365 public static bool RegisterPrefix (string prefix, IWebRequestCreate creator)
368 throw new ArgumentNullException ("prefix");
370 throw new ArgumentNullException ("creator");
372 lock (prefixes.SyncRoot) {
373 string lowerCasePrefix = prefix.ToLower (CultureInfo.InvariantCulture);
374 if (prefixes.Contains (lowerCasePrefix))
376 prefixes.Add (lowerCasePrefix, creator);
381 private static IWebRequestCreate GetCreator (string prefix)
383 int longestPrefix = -1;
384 IWebRequestCreate creator = null;
386 prefix = prefix.ToLower (CultureInfo.InvariantCulture);
388 IDictionaryEnumerator e = prefixes.GetEnumerator ();
389 while (e.MoveNext ()) {
390 string key = e.Key as string;
392 if (key.Length <= longestPrefix)
395 if (!prefix.StartsWith (key))
398 longestPrefix = key.Length;
399 creator = (IWebRequestCreate) e.Value;
403 throw new NotSupportedException (prefix);
408 internal static void ClearPrefixes ()
413 internal static void RemovePrefix (string prefix)
415 prefixes.Remove (prefix);
418 internal static void AddPrefix (string prefix, string typeName)
420 Type type = Type.GetType (typeName);
422 throw new ConfigurationException (String.Format ("Type {0} not found", typeName));
423 AddPrefix (prefix, type);
426 internal static void AddPrefix (string prefix, Type type)
428 object o = Activator.CreateInstance (type, true);
429 prefixes [prefix] = o;