2 // System.Net.WebRequest (for 2.1 profile)
5 // Jb Evain <jbevain@novell.com>
6 // Sebastien Pouliot <sebastien@ximian.com>
8 // Copyright (C) 2008-2010 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections.Generic;
37 namespace System.Net {
39 public abstract class WebRequest {
41 const string SystemWindows = "System.Windows, PublicKey=00240000048000009400000006020000002400005253413100040000010001008D56C76F9E8649383049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B37AB";
42 const string BrowserStack = "System.Net.Browser.BrowserHttpWebRequestCreator, " + SystemWindows;
43 const string ClientStack = "System.Net.Browser.ClientHttpWebRequestCreator, " + SystemWindows;
45 static IWebRequestCreate default_creator;
46 static IWebRequestCreate browser_creator;
47 static IWebRequestCreate client_creator;
48 static Dictionary<string, IWebRequestCreate> registred_prefixes;
50 internal Action<long,long> progress;
52 public abstract string ContentType { get; set; }
53 public abstract WebHeaderCollection Headers { get; set; }
54 public abstract string Method { get; set; }
55 public abstract Uri RequestUri { get; }
57 public virtual long ContentLength {
58 get { throw NotImplemented (); }
59 set { throw NotImplemented (); }
62 // custom registered prefixes return null (unless they override this)
63 public virtual IWebRequestCreate CreatorInstance {
67 public virtual ICredentials Credentials {
68 get { throw NotImplemented (); }
69 set { throw NotImplemented (); }
72 public virtual bool UseDefaultCredentials {
73 get { throw NotImplemented (); }
74 set { throw NotImplemented (); }
79 registred_prefixes = new Dictionary<string, IWebRequestCreate> (StringComparer.OrdinalIgnoreCase);
80 browser_creator = (IWebRequestCreate) Activator.CreateInstance (Type.GetType (BrowserStack));
81 client_creator = (IWebRequestCreate) Activator.CreateInstance (Type.GetType (ClientStack));
82 default_creator = browser_creator;
85 protected WebRequest ()
89 public abstract void Abort();
90 public abstract IAsyncResult BeginGetRequestStream (AsyncCallback callback, object state);
91 public abstract IAsyncResult BeginGetResponse (AsyncCallback callback, object state);
92 public abstract Stream EndGetRequestStream (IAsyncResult asyncResult);
93 public abstract WebResponse EndGetResponse (IAsyncResult asyncResult);
95 internal virtual IAsyncResult BeginGetResponse (AsyncCallback callback, object state, bool policy)
97 return BeginGetResponse (callback, state);
100 public static WebRequest Create (string requestUriString)
102 return Create (new Uri (requestUriString));
105 public static WebRequest Create (Uri requestUri)
107 if (requestUri == null)
108 throw new ArgumentNullException ("requestUri");
109 if (!requestUri.IsAbsoluteUri)
110 throw new InvalidOperationException ("This operation is not supported for a relative URI.");
112 IWebRequestCreate creator = null;
114 // look for the most promising match in the registred prefixes
115 foreach (KeyValuePair<string, IWebRequestCreate> kvp in registred_prefixes) {
116 string key = kvp.Key;
117 if ((key.Length > n) && requestUri.AbsoluteUri.StartsWith (key)) {
123 // 'http:/[/]' or 'https:/[/]' needs to be registred otherwise it gets ignored
124 // note that this is unlike other protocols (e.g. 'ftp') - see unit tests
125 string scheme = requestUri.Scheme;
126 if ((scheme == "http" && n <= 5) || (scheme == "https" && n <= 6))
127 creator = default_creator;
130 throw new NotSupportedException (string.Format ("Scheme {0} not supported", scheme));
132 return creator.Create (requestUri);
135 public static HttpWebRequest CreateHttp (string requestUriString)
137 return CreateHttp (new Uri (requestUriString));
140 public static HttpWebRequest CreateHttp (Uri requestUri)
142 if (requestUri == null)
143 throw new ArgumentNullException ("requestUri");
144 if (!requestUri.IsAbsoluteUri)
145 throw new InvalidOperationException ("Uri is not absolute.");
147 // we do not check the registred prefixes from CreateHttp and *always* use the client HTTP stack
148 switch (requestUri.Scheme) {
151 return (HttpWebRequest) client_creator.Create (requestUri);
153 throw new NotSupportedException (string.Format ("Scheme {0} not supported", requestUri.Scheme));
157 // We can register for
158 // * a protocol (e.g. http) for all requests
159 // * a protocol (e.g. https) for a domain
160 // * a protocol (e.g. http) for a single request
162 // See "How to: Specify Browser or Client HTTP Handling" for more details
163 // http://msdn.microsoft.com/en-us/library/dd920295%28VS.95%29.aspx
164 public static bool RegisterPrefix (string prefix, IWebRequestCreate creator)
167 throw new ArgumentNullException ("prefix");
169 throw new ArgumentNullException ("creator");
172 if (Uri.TryCreate (prefix, UriKind.Absolute, out uri)) {
173 // if a valid URI is supplied then only register the scheme + domain
174 prefix = uri.Scheme + Uri.SchemeDelimiter + uri.DnsSafeHost;
177 // registering 'http', 'http://' or even 'http:/' are all ok - but *never* would 'http:' be correct!
178 if ((String.Compare (prefix, "http:", StringComparison.OrdinalIgnoreCase) == 0) ||
179 (String.Compare (prefix, "https:", StringComparison.OrdinalIgnoreCase) == 0))
182 if (registred_prefixes.ContainsKey (prefix))
185 registred_prefixes.Add (prefix, creator);
189 static Exception NotImplemented ()
191 // hide the "normal" NotImplementedException from corcompare-like tools
192 return new NotImplementedException ();