PageRenderTime 57ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/System/System.Net/WebRequest.cs

https://github.com/iainlane/mono
C# | 517 lines | 396 code | 85 blank | 36 comment | 64 complexity | 8a3b7077767dd845beb3745546dc08e9 MD5 | raw file
  1. //
  2. // System.Net.WebRequest
  3. //
  4. // Authors:
  5. // Lawrence Pit (loz@cable.a2000.nl)
  6. // Marek Safar (marek.safar@gmail.com)
  7. //
  8. // Copyright 2011 Xamarin Inc.
  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. using System;
  30. using System.Collections;
  31. using System.Collections.Specialized;
  32. using System.Configuration;
  33. using System.IO;
  34. using System.Reflection;
  35. using System.Runtime.Serialization;
  36. using System.Globalization;
  37. using System.Net.Configuration;
  38. using System.Net.Security;
  39. using System.Net.Cache;
  40. using System.Security.Principal;
  41. #if NET_4_5
  42. using System.Threading.Tasks;
  43. #endif
  44. #if NET_2_1
  45. using ConfigurationException = System.ArgumentException;
  46. namespace System.Net.Configuration {
  47. class Dummy {}
  48. }
  49. #endif
  50. namespace System.Net
  51. {
  52. #if MOONLIGHT
  53. internal abstract class WebRequest : ISerializable {
  54. #else
  55. [Serializable]
  56. public abstract class WebRequest : MarshalByRefObject, ISerializable {
  57. #endif
  58. static HybridDictionary prefixes = new HybridDictionary ();
  59. static bool isDefaultWebProxySet;
  60. static IWebProxy defaultWebProxy;
  61. static RequestCachePolicy defaultCachePolicy;
  62. static MethodInfo cfGetDefaultProxy;
  63. // Constructors
  64. static WebRequest ()
  65. {
  66. if (Platform.IsMacOS) {
  67. #if MONOTOUCH
  68. Type type = Type.GetType ("MonoTouch.CoreFoundation.CFNetwork, monotouch");
  69. #else
  70. Type type = Type.GetType ("MonoMac.CoreFoundation.CFNetwork, monomac");
  71. #endif
  72. if (type != null)
  73. cfGetDefaultProxy = type.GetMethod ("GetDefaultProxy");
  74. }
  75. #if NET_2_1
  76. IWebRequestCreate http = new HttpRequestCreator ();
  77. RegisterPrefix ("http", http);
  78. RegisterPrefix ("https", http);
  79. #if MOBILE
  80. RegisterPrefix ("file", new FileWebRequestCreator ());
  81. RegisterPrefix ("ftp", new FtpRequestCreator ());
  82. #endif
  83. #else
  84. defaultCachePolicy = new HttpRequestCachePolicy (HttpRequestCacheLevel.NoCacheNoStore);
  85. #if CONFIGURATION_DEP
  86. object cfg = ConfigurationManager.GetSection ("system.net/webRequestModules");
  87. WebRequestModulesSection s = cfg as WebRequestModulesSection;
  88. if (s != null) {
  89. foreach (WebRequestModuleElement el in
  90. s.WebRequestModules)
  91. AddPrefix (el.Prefix, el.Type);
  92. return;
  93. }
  94. #endif
  95. ConfigurationSettings.GetConfig ("system.net/webRequestModules");
  96. #endif
  97. }
  98. protected WebRequest ()
  99. {
  100. }
  101. protected WebRequest (SerializationInfo serializationInfo, StreamingContext streamingContext)
  102. {
  103. }
  104. static Exception GetMustImplement ()
  105. {
  106. return new NotImplementedException ("This method must be implemented in derived classes");
  107. }
  108. // Properties
  109. private AuthenticationLevel authentication_level = AuthenticationLevel.MutualAuthRequested;
  110. public AuthenticationLevel AuthenticationLevel
  111. {
  112. get {
  113. return(authentication_level);
  114. }
  115. set {
  116. authentication_level = value;
  117. }
  118. }
  119. [MonoTODO ("Implement the caching system. Currently always returns a policy with the NoCacheNoStore level")]
  120. public virtual RequestCachePolicy CachePolicy
  121. {
  122. get { return DefaultCachePolicy; }
  123. set {
  124. }
  125. }
  126. public virtual string ConnectionGroupName {
  127. get { throw GetMustImplement (); }
  128. set { throw GetMustImplement (); }
  129. }
  130. public virtual long ContentLength {
  131. get { throw GetMustImplement (); }
  132. set { throw GetMustImplement (); }
  133. }
  134. public virtual string ContentType {
  135. get { throw GetMustImplement (); }
  136. set { throw GetMustImplement (); }
  137. }
  138. public virtual ICredentials Credentials {
  139. get { throw GetMustImplement (); }
  140. set { throw GetMustImplement (); }
  141. }
  142. public static RequestCachePolicy DefaultCachePolicy
  143. {
  144. get { return defaultCachePolicy; }
  145. set {
  146. throw GetMustImplement ();
  147. }
  148. }
  149. public virtual WebHeaderCollection Headers {
  150. get { throw GetMustImplement (); }
  151. set { throw GetMustImplement (); }
  152. }
  153. #if !MOONLIGHT
  154. public TokenImpersonationLevel ImpersonationLevel {
  155. get { throw GetMustImplement (); }
  156. set { throw GetMustImplement (); }
  157. }
  158. #endif
  159. public virtual string Method {
  160. get { throw GetMustImplement (); }
  161. set { throw GetMustImplement (); }
  162. }
  163. public virtual bool PreAuthenticate {
  164. get { throw GetMustImplement (); }
  165. set { throw GetMustImplement (); }
  166. }
  167. public virtual IWebProxy Proxy {
  168. get { throw GetMustImplement (); }
  169. set { throw GetMustImplement (); }
  170. }
  171. public virtual Uri RequestUri {
  172. get { throw GetMustImplement (); }
  173. }
  174. public virtual int Timeout {
  175. get { throw GetMustImplement (); }
  176. set { throw GetMustImplement (); }
  177. }
  178. public virtual bool UseDefaultCredentials
  179. {
  180. get {
  181. throw GetMustImplement ();
  182. }
  183. set {
  184. throw GetMustImplement ();
  185. }
  186. }
  187. // volatile static IWebProxy proxy;
  188. static readonly object lockobj = new object ();
  189. public static IWebProxy DefaultWebProxy {
  190. get {
  191. if (!isDefaultWebProxySet) {
  192. lock (lockobj) {
  193. if (defaultWebProxy == null)
  194. defaultWebProxy = GetDefaultWebProxy ();
  195. }
  196. }
  197. return defaultWebProxy;
  198. }
  199. set {
  200. /* MS documentation states that a null value would cause an ArgumentNullException
  201. * but that's not the way it behaves:
  202. * https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304724
  203. */
  204. defaultWebProxy = value;
  205. isDefaultWebProxySet = true;
  206. }
  207. }
  208. [MonoTODO("Needs to respect Module, Proxy.AutoDetect, and Proxy.ScriptLocation config settings")]
  209. static IWebProxy GetDefaultWebProxy ()
  210. {
  211. #if CONFIGURATION_DEP
  212. DefaultProxySection sec = ConfigurationManager.GetSection ("system.net/defaultProxy") as DefaultProxySection;
  213. WebProxy p;
  214. if (sec == null)
  215. return GetSystemWebProxy ();
  216. ProxyElement pe = sec.Proxy;
  217. if ((pe.UseSystemDefault != ProxyElement.UseSystemDefaultValues.False) && (pe.ProxyAddress == null))
  218. p = (WebProxy) GetSystemWebProxy ();
  219. else
  220. p = new WebProxy ();
  221. if (pe.ProxyAddress != null)
  222. p.Address = pe.ProxyAddress;
  223. if (pe.BypassOnLocal != ProxyElement.BypassOnLocalValues.Unspecified)
  224. p.BypassProxyOnLocal = (pe.BypassOnLocal == ProxyElement.BypassOnLocalValues.True);
  225. foreach(BypassElement elem in sec.BypassList)
  226. p.BypassArrayList.Add(elem.Address);
  227. return p;
  228. #else
  229. return GetSystemWebProxy ();
  230. #endif
  231. }
  232. // Methods
  233. public virtual void Abort()
  234. {
  235. throw GetMustImplement ();
  236. }
  237. public virtual IAsyncResult BeginGetRequestStream (AsyncCallback callback, object state)
  238. {
  239. throw GetMustImplement ();
  240. }
  241. public virtual IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
  242. {
  243. throw GetMustImplement ();
  244. }
  245. public static WebRequest Create (string requestUriString)
  246. {
  247. if (requestUriString == null)
  248. throw new ArgumentNullException ("requestUriString");
  249. return Create (new Uri (requestUriString));
  250. }
  251. public static WebRequest Create (Uri requestUri)
  252. {
  253. if (requestUri == null)
  254. throw new ArgumentNullException ("requestUri");
  255. return GetCreator (requestUri.AbsoluteUri).Create (requestUri);
  256. }
  257. public static WebRequest CreateDefault (Uri requestUri)
  258. {
  259. if (requestUri == null)
  260. throw new ArgumentNullException ("requestUri");
  261. return GetCreator (requestUri.Scheme).Create (requestUri);
  262. }
  263. public virtual Stream EndGetRequestStream (IAsyncResult asyncResult)
  264. {
  265. throw GetMustImplement ();
  266. }
  267. public virtual WebResponse EndGetResponse (IAsyncResult asyncResult)
  268. {
  269. throw GetMustImplement ();
  270. }
  271. public virtual Stream GetRequestStream()
  272. {
  273. throw GetMustImplement ();
  274. }
  275. public virtual WebResponse GetResponse()
  276. {
  277. throw GetMustImplement ();
  278. }
  279. [MonoTODO("Look in other places for proxy config info")]
  280. public static IWebProxy GetSystemWebProxy ()
  281. {
  282. #if !NET_2_1
  283. if (IsWindows ()) {
  284. int iProxyEnable = (int)Microsoft.Win32.Registry.GetValue ("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "ProxyEnable", 0);
  285. if (iProxyEnable > 0) {
  286. string strHttpProxy = "";
  287. bool bBypassOnLocal = false;
  288. ArrayList al = new ArrayList ();
  289. string strProxyServer = (string)Microsoft.Win32.Registry.GetValue ("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "ProxyServer", null);
  290. string strProxyOverrride = (string)Microsoft.Win32.Registry.GetValue ("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "ProxyOverride", null);
  291. if (strProxyServer.Contains ("=")) {
  292. foreach (string strEntry in strProxyServer.Split (new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
  293. if (strEntry.StartsWith ("http=")) {
  294. strHttpProxy = strEntry.Substring (5);
  295. break;
  296. }
  297. } else strHttpProxy = strProxyServer;
  298. if (strProxyOverrride != null) {
  299. string[] bypassList = strProxyOverrride.Split (new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
  300. foreach (string str in bypassList) {
  301. if (str != "<local>")
  302. al.Add (str);
  303. else
  304. bBypassOnLocal = true;
  305. }
  306. }
  307. return new WebProxy (strHttpProxy, bBypassOnLocal, al.ToArray (typeof(string)) as string[]);
  308. }
  309. } else {
  310. #endif
  311. string address = Environment.GetEnvironmentVariable ("http_proxy");
  312. if (address == null)
  313. address = Environment.GetEnvironmentVariable ("HTTP_PROXY");
  314. if (address != null) {
  315. try {
  316. if (!address.StartsWith ("http://"))
  317. address = "http://" + address;
  318. Uri uri = new Uri (address);
  319. IPAddress ip;
  320. if (IPAddress.TryParse (uri.Host, out ip)) {
  321. if (IPAddress.Any.Equals (ip)) {
  322. UriBuilder builder = new UriBuilder (uri);
  323. builder.Host = "127.0.0.1";
  324. uri = builder.Uri;
  325. } else if (IPAddress.IPv6Any.Equals (ip)) {
  326. UriBuilder builder = new UriBuilder (uri);
  327. builder.Host = "[::1]";
  328. uri = builder.Uri;
  329. }
  330. }
  331. bool bBypassOnLocal = false;
  332. ArrayList al = new ArrayList ();
  333. string bypass = Environment.GetEnvironmentVariable ("no_proxy");
  334. if (bypass == null)
  335. bypass = Environment.GetEnvironmentVariable ("NO_PROXY");
  336. if (bypass != null) {
  337. string[] bypassList = bypass.Split (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  338. foreach (string str in bypassList) {
  339. if (str != "*.local")
  340. al.Add (str);
  341. else
  342. bBypassOnLocal = true;
  343. }
  344. }
  345. return new WebProxy (uri, bBypassOnLocal, al.ToArray (typeof(string)) as string[]);
  346. } catch (UriFormatException) {
  347. }
  348. }
  349. #if !NET_2_1
  350. }
  351. #endif
  352. if (cfGetDefaultProxy != null)
  353. return (IWebProxy) cfGetDefaultProxy.Invoke (null, null);
  354. return new WebProxy ();
  355. }
  356. void ISerializable.GetObjectData (SerializationInfo serializationInfo, StreamingContext streamingContext)
  357. {
  358. throw new NotSupportedException ();
  359. }
  360. protected virtual void GetObjectData (SerializationInfo serializationInfo, StreamingContext streamingContext)
  361. {
  362. throw GetMustImplement ();
  363. }
  364. public static bool RegisterPrefix (string prefix, IWebRequestCreate creator)
  365. {
  366. if (prefix == null)
  367. throw new ArgumentNullException ("prefix");
  368. if (creator == null)
  369. throw new ArgumentNullException ("creator");
  370. lock (prefixes.SyncRoot) {
  371. string lowerCasePrefix = prefix.ToLower (CultureInfo.InvariantCulture);
  372. if (prefixes.Contains (lowerCasePrefix))
  373. return false;
  374. prefixes.Add (lowerCasePrefix, creator);
  375. }
  376. return true;
  377. }
  378. private static IWebRequestCreate GetCreator (string prefix)
  379. {
  380. int longestPrefix = -1;
  381. IWebRequestCreate creator = null;
  382. prefix = prefix.ToLower (CultureInfo.InvariantCulture);
  383. IDictionaryEnumerator e = prefixes.GetEnumerator ();
  384. while (e.MoveNext ()) {
  385. string key = e.Key as string;
  386. if (key.Length <= longestPrefix)
  387. continue;
  388. if (!prefix.StartsWith (key))
  389. continue;
  390. longestPrefix = key.Length;
  391. creator = (IWebRequestCreate) e.Value;
  392. }
  393. if (creator == null)
  394. throw new NotSupportedException (prefix);
  395. return creator;
  396. }
  397. internal static bool IsWindows ()
  398. {
  399. return (int) Environment.OSVersion.Platform < 4;
  400. }
  401. internal static void ClearPrefixes ()
  402. {
  403. prefixes.Clear ();
  404. }
  405. internal static void RemovePrefix (string prefix)
  406. {
  407. prefixes.Remove (prefix);
  408. }
  409. internal static void AddPrefix (string prefix, string typeName)
  410. {
  411. Type type = Type.GetType (typeName);
  412. if (type == null)
  413. throw new ConfigurationException (String.Format ("Type {0} not found", typeName));
  414. AddPrefix (prefix, type);
  415. }
  416. internal static void AddPrefix (string prefix, Type type)
  417. {
  418. object o = Activator.CreateInstance (type, true);
  419. prefixes [prefix] = o;
  420. }
  421. #if NET_4_5
  422. public virtual Task<Stream> GetRequestStreamAsync ()
  423. {
  424. return Task<Stream>.Factory.FromAsync (BeginGetRequestStream, EndGetRequestStream, null);
  425. }
  426. public virtual Task<WebResponse> GetResponseAsync ()
  427. {
  428. return Task<WebResponse>.Factory.FromAsync (BeginGetResponse, EndGetResponse, null);
  429. }
  430. #endif
  431. }
  432. }