1 //------------------------------------------------------------------------------
2 // <copyright file="WebRequest.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
10 namespace System.Net {
11 using System.Collections;
12 using System.Collections.Generic;
13 using System.Configuration;
14 using System.Diagnostics.CodeAnalysis;
15 using System.Diagnostics.Contracts;
16 using System.Diagnostics.Tracing;
17 using System.Globalization;
19 using System.Net.Cache;
20 using System.Net.Configuration;
21 using System.Reflection;
22 using System.Runtime.Serialization;
23 using System.Security.Permissions;
24 using System.Security.Principal;
25 using System.Threading;
26 using System.Threading.Tasks;
27 using System.Net.Security;
28 using System.ComponentModel;
29 using System.Security;
31 // WebRequest - the base class of all Web resource/protocol objects. Provides
32 // common methods, data and proprties for making the top level request
36 /// <para>A request to a Uniform Resource Identifier (Uri). This
37 /// is an abstract class.</para>
40 public abstract class WebRequest : MarshalByRefObject, ISerializable
42 #if FEATURE_PAL // ROTORTODO - after speed ups (like real JIT and GC) remove this one
44 internal const int DefaultTimeout = 100000 * 10;
46 internal const int DefaultTimeout = 100000 * 5;
49 internal const int DefaultTimeout = 100000; // default timeout is 100 seconds (ASP .NET is 90 seconds)
51 private static volatile ArrayList s_PrefixList;
52 private static Object s_InternalSyncObject;
53 private static TimerThread.Queue s_DefaultTimerQueue = TimerThread.CreateQueue(DefaultTimeout);
56 private AuthenticationLevel m_AuthenticationLevel;
57 private TokenImpersonationLevel m_ImpersonationLevel;
60 private RequestCachePolicy m_CachePolicy;
61 private RequestCacheProtocol m_CacheProtocol;
62 private RequestCacheBinding m_CacheBinding;
64 #region designer support for System.Windows.dll
65 internal class DesignerWebRequestCreate : IWebRequestCreate
67 public WebRequest Create(Uri uri)
69 return WebRequest.Create(uri);
72 private static DesignerWebRequestCreate webRequestCreate = new DesignerWebRequestCreate();
73 //introduced for supporting design-time loading of System.Windows.dll
74 [Obsolete("This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.", true)]
75 [EditorBrowsable(EditorBrowsableState.Never)]
76 public virtual IWebRequestCreate CreatorInstance { get { return webRequestCreate; } }
78 //introduced for supporting design-time loading of System.Windows.dll
79 [Obsolete("This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.", true)]
80 [EditorBrowsable(EditorBrowsableState.Never)]
81 public static void RegisterPortableWebRequestCreator(IWebRequestCreate creator) { }
84 private static Object InternalSyncObject {
86 if (s_InternalSyncObject == null) {
87 Object o = new Object();
88 Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
90 return s_InternalSyncObject;
94 internal static TimerThread.Queue DefaultTimerQueue {
96 return s_DefaultTimerQueue;
102 Create - Create a WebRequest.
104 This is the main creation routine. We take a Uri object, look
105 up the Uri in the prefix match table, and invoke the appropriate
106 handler to create the object. We also have a parameter that
107 tells us whether or not to use the whole Uri or just the
108 scheme portion of it.
112 RequestUri - Uri object for request.
113 UseUriBase - True if we're only to look at the scheme
118 Newly created WebRequest.
121 private static WebRequest Create(Uri requestUri, bool useUriBase) {
122 if(Logging.On)Logging.Enter(Logging.Web, "WebRequest", "Create", requestUri.ToString());
125 WebRequestPrefixElement Current = null;
130 LookupUri = requestUri.AbsoluteUri;
135 // schemes are registered as <schemeName>":", so add the separator
136 // to the string returned from the Uri object
139 LookupUri = requestUri.Scheme + ':';
142 int LookupLength = LookupUri.Length;
144 // Copy the prefix list so that if it is updated it will
145 // not affect us on this thread.
147 ArrayList prefixList = PrefixList;
149 // Look for the longest matching prefix.
151 // Walk down the list of prefixes. The prefixes are kept longest
152 // first. When we find a prefix that is shorter or the same size
153 // as this Uri, we'll do a compare to see if they match. If they
154 // do we'll break out of the loop and call the creator.
156 for (int i = 0; i < prefixList.Count; i++) {
157 Current = (WebRequestPrefixElement)prefixList[i];
160 // See if this prefix is short enough.
163 if (LookupLength >= Current.Prefix.Length) {
166 // It is. See if these match.
169 if (String.Compare(Current.Prefix,
173 Current.Prefix.Length,
174 StringComparison.OrdinalIgnoreCase ) == 0) {
177 // These match. Remember that we found it and break
187 WebRequest webRequest = null;
192 // We found a match, so just call the creator and return what it
196 webRequest = Current.Creator.Create(requestUri);
197 if(Logging.On)Logging.Exit(Logging.Web, "WebRequest", "Create", webRequest);
201 if(Logging.On)Logging.Exit(Logging.Web, "WebRequest", "Create", null);
204 // Otherwise no match, throw an exception.
207 throw new NotSupportedException(SR.GetString(SR.net_unknown_prefix));
212 Create - Create a WebRequest.
214 An overloaded utility version of the real Create that takes a
215 string instead of an Uri object.
220 RequestString - Uri string to create.
224 Newly created WebRequest.
229 /// Creates a new <see cref='System.Net.WebRequest'/>
231 /// the specified Uri scheme.
234 public static WebRequest Create(string requestUriString) {
235 if (requestUriString == null) {
236 throw new ArgumentNullException("requestUriString");
238 // In .NET FX v4.0, custom IWebRequestCreate implementations can
239 // cause this to return null. Consider tightening this in the future.
240 //Contract.Ensures(Contract.Result<WebRequest>() != null);
242 return Create(new Uri(requestUriString), false);
247 Create - Create a WebRequest.
249 Another overloaded version of the Create function that doesn't
250 take the UseUriBase parameter.
254 RequestUri - Uri object for request.
258 Newly created WebRequest.
263 /// Creates a new <see cref='System.Net.WebRequest'/> instance for the specified Uri scheme.
266 public static WebRequest Create(Uri requestUri) {
267 if (requestUri == null) {
268 throw new ArgumentNullException("requestUri");
270 // In .NET FX v4.0, custom IWebRequestCreate implementations can
271 // cause this to return null. Consider tightening this in the future.
272 //Contract.Ensures(Contract.Result<WebRequest>() != null);
274 return Create(requestUri, false);
279 CreateDefault - Create a default WebRequest.
281 This is the creation routine that creates a default WebRequest.
282 We take a Uri object and pass it to the base create routine,
283 setting the useUriBase parameter to true.
287 RequestUri - Uri object for request.
291 Newly created WebRequest.
294 /// <para>[To be supplied.]</para>
296 public static WebRequest CreateDefault(Uri requestUri) {
297 if (requestUri == null) {
298 throw new ArgumentNullException("requestUri");
300 // In .NET FX v4.0, custom IWebRequestCreate implementations can
301 // cause this to return null. Consider tightening this in the future.
302 //Contract.Ensures(Contract.Result<WebRequest>() != null);
304 return Create(requestUri, true);
308 public static HttpWebRequest CreateHttp(string requestUriString) {
309 if (requestUriString == null) {
310 throw new ArgumentNullException("requestUriString");
312 return CreateHttp(new Uri(requestUriString));
316 public static HttpWebRequest CreateHttp(Uri requestUri) {
317 if (requestUri == null) {
318 throw new ArgumentNullException("requestUri");
320 if ((requestUri.Scheme != Uri.UriSchemeHttp) && (requestUri.Scheme != Uri.UriSchemeHttps)) {
321 throw new NotSupportedException(SR.GetString(SR.net_unknown_prefix));
323 return (HttpWebRequest)CreateDefault(requestUri);
328 RegisterPrefix - Register an Uri prefix for creating WebRequests.
330 This function registers a prefix for creating WebRequests. When an
331 user wants to create a WebRequest, we scan a table looking for a
332 longest prefix match for the Uri they're passing. We then invoke
333 the sub creator for that prefix. This function puts entries in
336 We don't allow duplicate entries, so if there is a dup this call
341 Prefix - Represents Uri prefix being registered.
342 Creator - Interface for sub creator.
346 True if the registration worked, false otherwise.
351 /// Registers a <see cref='System.Net.WebRequest'/> descendent
352 /// for a specific Uniform Resource Identifier.
355 public static bool RegisterPrefix(string prefix, IWebRequestCreate creator) {
359 WebRequestPrefixElement Current;
361 if (prefix == null) {
362 throw new ArgumentNullException("prefix");
364 if (creator == null) {
365 throw new ArgumentNullException("creator");
369 ExceptionHelper.WebPermissionUnrestricted.Demand();
372 // Lock this object, then walk down PrefixList looking for a place to
373 // to insert this prefix.
375 lock(InternalSyncObject) {
377 // clone the object and update the clone thus
378 // allowing other threads to still read from it
381 ArrayList prefixList = (ArrayList)PrefixList.Clone();
383 // As AbsoluteUri is used later for Create, account for formating changes
384 // like Unicode escaping, default ports, etc.
386 if (Uri.TryCreate(prefix, UriKind.Absolute, out tempUri))
388 String cookedUri = tempUri.AbsoluteUri;
390 // Special case for when a partial host matching is requested, drop the added trailing slash
391 // IE: http://host could match host or host.domain
392 if (!prefix.EndsWith("/", StringComparison.Ordinal)
393 && tempUri.GetComponents(UriComponents.PathAndQuery | UriComponents.Fragment,
394 UriFormat.UriEscaped)
396 cookedUri = cookedUri.Substring(0, cookedUri.Length - 1);
403 // The prefix list is sorted with longest entries at the front. We
404 // walk down the list until we find a prefix shorter than this
405 // one, then we insert in front of it. Along the way we check
406 // equal length prefixes to make sure this isn't a dupe.
408 while (i < prefixList.Count) {
409 Current = (WebRequestPrefixElement)prefixList[i];
411 // See if the new one is longer than the one we're looking at.
413 if (prefix.Length > Current.Prefix.Length) {
414 // It is. Break out of the loop here.
418 // If these are of equal length, compare them.
420 if (prefix.Length == Current.Prefix.Length) {
421 // They're the same length.
422 if (String.Compare(Current.Prefix, prefix, StringComparison.OrdinalIgnoreCase) == 0) {
423 // ...and the strings are identical. This is an error.
432 // When we get here either i contains the index to insert at or
433 // we've had an error, in which case Error is true.
436 // No error, so insert.
439 new WebRequestPrefixElement(prefix, creator)
443 // no error, assign the clone to the static object, other
444 // threads using it will have copied the oriignal object already
446 PrefixList = prefixList;
453 public static bool UnregisterPrefix(string prefix) {
454 if (prefix == null) {
455 throw new ArgumentNullException("prefix");
457 ExceptionHelper.WebPermissionUnrestricted.Demand();
459 // Lock this object, then walk down PrefixList looking for a place to
460 // to insert this prefix.
462 lock(InternalSyncObject) {
464 // clone the object and update the clone thus
465 // allowing other threads to still read from it
468 ArrayList prefixList = (ArrayList) PrefixList.Clone();
471 WebRequestPrefixElement Current;
473 // The prefix list is sorted with longest entries at the front. We
474 // walk down the list until we find a prefix shorter than this
475 // one, then we insert in front of it. Along the way we check
476 // equal length prefixes to make sure this isn't a dupe.
477 while (i < prefixList.Count) {
478 Current = (WebRequestPrefixElement)prefixList[i];
480 // See if the new one is longer than the one we're looking at.
482 if (prefix.Length > Current.Prefix.Length) {
486 // If these are of equal length, compare them.
488 if (prefix.Length == Current.Prefix.Length) {
489 // They're the same length.
490 if (String.Compare(Current.Prefix, prefix, StringComparison.OrdinalIgnoreCase ) == 0) {
491 prefixList.RemoveAt(i);
492 PrefixList = prefixList;
507 PrefixList - Returns And Initialize our prefix list.
510 This is the method that initializes the prefix list. We create
511 an ArrayList for the PrefixList, then an HttpRequestCreator object,
512 and then we register the HTTP and HTTPS prefixes.
519 internal static ArrayList PrefixList {
523 // GetConfig() might use us, so we have a circular dependency issue,
524 // that causes us to nest here, we grab the lock, only
525 // if we haven't initialized.
527 if (s_PrefixList == null) {
529 lock (InternalSyncObject) {
530 if (s_PrefixList == null) {
531 GlobalLog.Print("WebRequest::Initialize(): calling ConfigurationManager.GetSection()");
533 s_PrefixList = PopulatePrefixList ();
535 s_PrefixList = WebRequestModulesSectionInternal.GetSection().WebRequestModules;
544 s_PrefixList = value;
549 static ArrayList PopulatePrefixList ()
551 var res = new ArrayList();
553 #if MOBILE || !CONFIGURATION_DEP
554 IWebRequestCreate http = new HttpRequestCreator ();
555 res.Add(new WebRequestPrefixElement("http", http));
556 res.Add(new WebRequestPrefixElement("https", http));
557 res.Add(new WebRequestPrefixElement("file", new FileWebRequestCreator ()));
558 res.Add(new WebRequestPrefixElement("ftp", new FtpRequestCreator ()));
560 object cfg = ConfigurationManager.GetSection ("system.net/webRequestModules");
561 WebRequestModulesSection s = cfg as WebRequestModulesSection;
563 foreach (WebRequestModuleElement el in s.WebRequestModules)
564 res.Add (new WebRequestPrefixElement(el.Prefix, el.Type));
576 /// Initializes a new instance of the <see cref='System.Net.WebRequest'/>
581 protected WebRequest()
584 // Defautl values are set as per V1.0 behavior
585 m_ImpersonationLevel = TokenImpersonationLevel.Delegation;
586 m_AuthenticationLevel= AuthenticationLevel.MutualAuthRequested;
590 // ISerializable constructor
593 /// <para>[To be supplied.]</para>
595 protected WebRequest(SerializationInfo serializationInfo, StreamingContext streamingContext) {
599 // ISerializable method
602 [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
603 [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter, SerializationFormatter=true)]
604 void ISerializable.GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
606 GetObjectData(serializationInfo, streamingContext);
610 // FxCop: Provide a way for inherited classes to access base.GetObjectData in case they also implement ISerializable.
612 [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)]
613 protected virtual void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
617 // This is a shortcut that would set the default policy for HTTP/HTTPS.
618 // The default policy is overridden by any prefix-registered policy.
619 // Will demand permission for set{}
620 public static RequestCachePolicy DefaultCachePolicy {
622 return RequestCacheManager.GetBinding(string.Empty).Policy;
626 // This is a replacement of RequestCachePermission demand since we are not including the latest in the product.
627 ExceptionHelper.WebPermissionUnrestricted.Demand();
630 RequestCacheBinding binding = RequestCacheManager.GetBinding(string.Empty);
631 RequestCacheManager.SetBinding(string.Empty, new RequestCacheBinding(binding.Cache, binding.Validator, value));
637 public virtual RequestCachePolicy CachePolicy {
639 return m_CachePolicy;
643 // Delayed creation of CacheProtocol until caching is actually turned on.
644 InternalSetCachePolicy(value);
649 void InternalSetCachePolicy(RequestCachePolicy policy){
650 // Delayed creation of CacheProtocol until caching is actually turned on.
651 if (m_CacheBinding != null &&
652 m_CacheBinding.Cache != null &&
653 m_CacheBinding.Validator != null &&
654 CacheProtocol == null &&
656 policy.Level != RequestCacheLevel.BypassCache)
658 CacheProtocol = new RequestCacheProtocol(m_CacheBinding.Cache, m_CacheBinding.Validator.CreateValidator());
661 m_CachePolicy = policy;
666 /// <para>When overridden in a derived class, gets and
669 /// protocol method used in this request. Default value should be
672 public virtual string Method {
674 throw ExceptionHelper.PropertyNotImplementedException;
677 throw ExceptionHelper.PropertyNotImplementedException;
683 /// <para>When overridden in a derived class, gets a <see cref='Uri'/>
684 /// instance representing the resource associated with
685 /// the request.</para>
687 public virtual Uri RequestUri { // read-only
689 throw ExceptionHelper.PropertyNotImplementedException;
694 // This is a group of connections that may need to be used for
695 // grouping connecitons.
699 public virtual string ConnectionGroupName {
701 throw ExceptionHelper.PropertyNotImplementedException;
704 throw ExceptionHelper.PropertyNotImplementedException;
711 Headers - Gets any request specific headers associated
712 with this request, this is simply a name/value pair collection
716 Returns: This property returns WebHeaderCollection.
723 /// <para>When overridden in a derived class,
725 /// a collection of header name-value pairs associated with this
728 public virtual WebHeaderCollection Headers {
730 Contract.Ensures(Contract.Result<WebHeaderCollection>() != null);
731 throw ExceptionHelper.PropertyNotImplementedException;
734 throw ExceptionHelper.PropertyNotImplementedException;
741 /// overridden in a derived class, gets
744 /// content length of request data being sent.</para>
746 public virtual long ContentLength {
748 throw ExceptionHelper.PropertyNotImplementedException;
751 throw ExceptionHelper.PropertyNotImplementedException;
757 /// overridden in a derived class, gets
760 /// the content type of the request data being sent.</para>
762 public virtual string ContentType {
764 throw ExceptionHelper.PropertyNotImplementedException;
767 throw ExceptionHelper.PropertyNotImplementedException;
772 /// <para>When overridden in a derived class, gets and sets the network
773 /// credentials used for authentication to this Uri.</para>
775 public virtual ICredentials Credentials {
777 throw ExceptionHelper.PropertyNotImplementedException;
780 throw ExceptionHelper.PropertyNotImplementedException;
785 /// <para>Sets Credentials to CredentialCache.DefaultCredentials</para>
787 public virtual bool UseDefaultCredentials {
789 throw ExceptionHelper.PropertyNotImplementedException;
792 throw ExceptionHelper.PropertyNotImplementedException;
797 /// <para>When overridden in a derived class,
798 /// gets and set proxy info. </para>
800 public virtual IWebProxy Proxy {
802 throw ExceptionHelper.PropertyNotImplementedException;
805 throw ExceptionHelper.PropertyNotImplementedException;
810 /// <para>When overridden in a derived class,
811 /// enables or disables pre-authentication.</para>
813 public virtual bool PreAuthenticate {
815 throw ExceptionHelper.PropertyNotImplementedException;
818 throw ExceptionHelper.PropertyNotImplementedException;
823 // Timeout in milliseconds, if request takes longer
824 // than timeout, a WebException is thrown
828 /// <para>[To be supplied.]</para>
830 public virtual int Timeout {
832 throw ExceptionHelper.PropertyNotImplementedException;
835 throw ExceptionHelper.PropertyNotImplementedException;
841 /// <para>When overridden in a derived class,
842 /// returns a <see cref='System.IO.Stream'/> object that is used for writing data
843 /// to the resource identified by <see cref='WebRequest.RequestUri'/>
846 public virtual Stream GetRequestStream() {
847 throw ExceptionHelper.MethodNotImplementedException;
851 /// <para>When overridden in a derived class,
852 /// returns the response
853 /// to an Internet request.</para>
855 public virtual WebResponse GetResponse() {
856 Contract.Ensures(Contract.Result<WebResponse>() != null);
858 throw ExceptionHelper.MethodNotImplementedException;
862 /// <para>Asynchronous version of GetResponse.</para>
864 [HostProtection(ExternalThreading=true)]
865 public virtual IAsyncResult BeginGetResponse(AsyncCallback callback, object state) {
866 throw ExceptionHelper.MethodNotImplementedException;
871 /// <para>Returns a WebResponse object.</para>
873 public virtual WebResponse EndGetResponse(IAsyncResult asyncResult) {
874 throw ExceptionHelper.MethodNotImplementedException;
878 /// <para>Asynchronous version of GetRequestStream
881 [HostProtection(ExternalThreading=true)]
882 public virtual IAsyncResult BeginGetRequestStream(AsyncCallback callback, Object state) {
883 throw ExceptionHelper.MethodNotImplementedException;
887 /// <para>Returns a <see cref='System.IO.Stream'/> object that is used for writing data to the resource
888 /// identified by <see cref='System.Net.WebRequest.RequestUri'/>
891 public virtual Stream EndGetRequestStream(IAsyncResult asyncResult) {
892 throw ExceptionHelper.MethodNotImplementedException;
895 // Offload to a different thread to avoid blocking the caller durring request submission.
896 [HostProtection(ExternalThreading = true)]
897 public virtual Task<Stream> GetRequestStreamAsync()
899 IWebProxy proxy = null;
900 try { proxy = Proxy; }
901 catch (NotImplementedException) { }
903 // Preserve context for authentication
904 if (ExecutionContext.IsFlowSuppressed()
905 && (UseDefaultCredentials || Credentials != null
906 || (proxy != null && proxy.Credentials != null)))
908 WindowsIdentity currentUser = SafeCaptureIdenity();
910 // When flow is suppressed we would lose track of the current user across this thread switch.
911 // Flow manually so that UseDefaultCredentials will work. BeginGetRequestStream will
912 // take over from there.
913 return Task.Run(() =>
917 using (currentUser.Impersonate())
919 return Task<Stream>.Factory.FromAsync(this.BeginGetRequestStream,
920 this.EndGetRequestStream, null);
927 return Task.Run(() => Task<Stream>.Factory.FromAsync(this.BeginGetRequestStream,
928 this.EndGetRequestStream, null));
932 // Offload to a different thread to avoid blocking the caller durring request submission.
933 [HostProtection(ExternalThreading = true)]
934 public virtual Task<WebResponse> GetResponseAsync()
936 IWebProxy proxy = null;
937 try { proxy = Proxy; }
938 catch (NotImplementedException) { }
940 // Preserve context for authentication
941 if (ExecutionContext.IsFlowSuppressed()
942 && (UseDefaultCredentials || Credentials != null
943 || (proxy != null && proxy.Credentials != null)))
945 WindowsIdentity currentUser = SafeCaptureIdenity();
947 // When flow is suppressed we would lose track of the current user across this thread switch.
948 // Flow manually so that UseDefaultCredentials will work. BeginGetResponse will
949 // take over from there.
950 return Task.Run(() =>
954 using (currentUser.Impersonate())
956 return Task<WebResponse>.Factory.FromAsync(this.BeginGetResponse,
957 this.EndGetResponse, null);
964 return Task.Run(() => Task<WebResponse>.Factory.FromAsync(this.BeginGetResponse,
965 this.EndGetResponse, null));
969 // Security: We need an assert for a call into WindowsIdentity.GetCurrent
970 [SecuritySafeCritical]
971 [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.ControlPrincipal)]
972 [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "Needed for identity flow.")]
973 private WindowsIdentity SafeCaptureIdenity()
975 return WindowsIdentity.GetCurrent();
980 /// <para>Aborts the Request</para>
982 public virtual void Abort() {
983 throw ExceptionHelper.MethodNotImplementedException;
989 internal RequestCacheProtocol CacheProtocol
993 return m_CacheProtocol;
997 m_CacheProtocol = value;
1005 public AuthenticationLevel AuthenticationLevel {
1007 return m_AuthenticationLevel;
1010 m_AuthenticationLevel = value;
1015 // Methods to retrieve the context of the "reading phase" and of the "writing phase" of the request.
1016 // Each request type can define what goes into what phase. Typically, the writing phase corresponds to
1017 // GetRequestStream() and the reading phase to GetResponse(), but if there's no request body, both phases
1018 // may happen inside GetResponse().
1020 // Return null only on [....] (if we're on the [....] thread). Otherwise throw if no context is available.
1021 internal virtual ContextAwareResult GetConnectingContext()
1023 throw ExceptionHelper.MethodNotImplementedException;
1026 internal virtual ContextAwareResult GetWritingContext()
1028 throw ExceptionHelper.MethodNotImplementedException;
1031 internal virtual ContextAwareResult GetReadingContext()
1033 throw ExceptionHelper.MethodNotImplementedException;
1040 public TokenImpersonationLevel ImpersonationLevel {
1042 return m_ImpersonationLevel;
1045 m_ImpersonationLevel = value;
1048 #endif // !FEATURE_PAL
1051 /// <para>Provides an abstract way of having Async code callback into the request (saves a delegate)</para>
1053 internal virtual void RequestCallback(object obj) {
1054 throw ExceptionHelper.MethodNotImplementedException;
1058 // Default Web Proxy implementation.
1060 private static volatile IWebProxy s_DefaultWebProxy;
1061 private static volatile bool s_DefaultWebProxyInitialized;
1063 internal static IWebProxy InternalDefaultWebProxy
1067 if (!s_DefaultWebProxyInitialized)
1069 lock (InternalSyncObject)
1071 if (!s_DefaultWebProxyInitialized)
1073 GlobalLog.Print("WebRequest::get_InternalDefaultWebProxy(): Getting config.");
1074 DefaultProxySectionInternal section = DefaultProxySectionInternal.GetSection();
1075 if (section != null)
1077 s_DefaultWebProxy = section.WebProxy;
1079 s_DefaultWebProxyInitialized = true;
1083 return s_DefaultWebProxy;
1088 // Same lock as above. Avoid hitting config if the proxy is set first.
1089 if (!s_DefaultWebProxyInitialized)
1091 lock (InternalSyncObject)
1093 s_DefaultWebProxy = value;
1094 s_DefaultWebProxyInitialized = true;
1099 s_DefaultWebProxy = value;
1105 // Get and set the global default proxy. Use this instead of the old GlobalProxySelection.
1107 public static IWebProxy DefaultWebProxy
1111 #if !DISABLE_CAS_USE
1112 ExceptionHelper.WebPermissionUnrestricted.Demand();
1114 return InternalDefaultWebProxy;
1119 #if !DISABLE_CAS_USE
1120 ExceptionHelper.WebPermissionUnrestricted.Demand();
1122 InternalDefaultWebProxy = value;
1127 // This returns an "IE Proxy" based on the currently impersonated user's proxy settings.
1129 public static IWebProxy GetSystemWebProxy()
1131 #if !DISABLE_CAS_USE
1132 ExceptionHelper.WebPermissionUnrestricted.Demand();
1134 return InternalGetSystemWebProxy();
1137 internal static IWebProxy InternalGetSystemWebProxy()
1140 // FIXME: Need to break mobile internal API
1141 return WebProxy.CreateDefaultProxy();
1143 return new WebProxyWrapperOpaque(new WebProxy(true));
1148 // To maintain backwards-compatibility, GlobalProxySelection.Select must return a proxy castable to WebProxy.
1149 // To get away from that restriction in the future, new APIs wrap the WebProxy in an internal wrapper.
1150 // Once Select is removed, the system-proxy functionality can be factored out of the WebProxy class.
1154 // This doesn't expose the WebProxy. It's used by GetSystemWebProxy(), which should never be castable to WebProxy.
1156 internal class WebProxyWrapperOpaque : IAutoWebProxy
1158 protected readonly WebProxy webProxy;
1160 internal WebProxyWrapperOpaque(WebProxy webProxy)
1162 this.webProxy = webProxy;
1165 public Uri GetProxy(Uri destination)
1167 return webProxy.GetProxy(destination);
1170 public bool IsBypassed(Uri host)
1172 return webProxy.IsBypassed(host);
1175 public ICredentials Credentials
1179 return webProxy.Credentials;
1184 webProxy.Credentials = value;
1188 public ProxyChain GetProxies(Uri destination)
1190 return ((IAutoWebProxy) webProxy).GetProxies(destination);
1195 // Select returns the WebProxy out of this one.
1197 internal class WebProxyWrapper : WebProxyWrapperOpaque
1199 internal WebProxyWrapper(WebProxy webProxy) :
1203 internal WebProxy WebProxy
1214 internal void SetupCacheProtocol(Uri uri)
1216 m_CacheBinding = RequestCacheManager.GetBinding(uri.Scheme);
1218 // Note if the cache is disabled it will give back a bypass policy.
1219 InternalSetCachePolicy( m_CacheBinding.Policy);
1220 if (m_CachePolicy == null)
1222 // If the protocol cache policy is not specifically configured, grab from the base class.
1223 InternalSetCachePolicy(WebRequest.DefaultCachePolicy);
1227 delegate void DelEtwFireBeginWRGet(object id, string uri, bool success, bool synchronous);
1228 delegate void DelEtwFireEndWRGet(object id, bool success, bool synchronous);
1229 delegate void DelEtwFireEndWRespGet(object id, bool success, bool synchronous, int statusCode);
1230 static DelEtwFireBeginWRGet s_EtwFireBeginGetResponse;
1231 static DelEtwFireEndWRespGet s_EtwFireEndGetResponse;
1232 static DelEtwFireBeginWRGet s_EtwFireBeginGetRequestStream;
1233 static DelEtwFireEndWRGet s_EtwFireEndGetRequestStream;
1234 static volatile bool s_TriedGetEtwDelegates;
1236 private static void InitEtwMethods()
1238 Type fest = typeof(FrameworkEventSource);
1239 var beginParamTypes = new Type[] { typeof(object), typeof(string), typeof(bool), typeof(bool) };
1240 var bindingFlags = BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public;
1241 var mi1 = fest.GetMethod("BeginGetResponse", bindingFlags, null, beginParamTypes, null);
1242 var mi2 = fest.GetMethod("EndGetResponse", bindingFlags, null, new Type[] { typeof(object), typeof(bool), typeof(bool), typeof(int) }, null);
1243 var mi3 = fest.GetMethod("BeginGetRequestStream", bindingFlags, null, beginParamTypes, null);
1244 var mi4 = fest.GetMethod("EndGetRequestStream", bindingFlags, null, new Type[] { typeof(object), typeof(bool), typeof(bool) }, null);
1245 if (mi1 != null && mi2 != null && mi3 != null && mi4 != null)
1247 s_EtwFireBeginGetResponse = (DelEtwFireBeginWRGet) mi1.CreateDelegate(typeof(DelEtwFireBeginWRGet), FrameworkEventSource.Log);
1248 s_EtwFireEndGetResponse = (DelEtwFireEndWRespGet)mi2.CreateDelegate(typeof(DelEtwFireEndWRespGet), FrameworkEventSource.Log);
1249 s_EtwFireBeginGetRequestStream = (DelEtwFireBeginWRGet) mi3.CreateDelegate(typeof(DelEtwFireBeginWRGet), FrameworkEventSource.Log);
1250 s_EtwFireEndGetRequestStream = (DelEtwFireEndWRGet) mi4.CreateDelegate(typeof(DelEtwFireEndWRGet), FrameworkEventSource.Log);
1252 s_TriedGetEtwDelegates = true;
1255 internal void LogBeginGetResponse(bool success, bool synchronous)
1257 string uri = this.RequestUri.OriginalString;
1258 if (!s_TriedGetEtwDelegates)
1260 if (s_EtwFireBeginGetResponse != null)
1262 s_EtwFireBeginGetResponse(this, uri, success, synchronous);
1265 internal void LogEndGetResponse(bool success, bool synchronous, int statusCode)
1267 if (!s_TriedGetEtwDelegates)
1269 if (s_EtwFireEndGetResponse != null) {
1270 s_EtwFireEndGetResponse(this, success, synchronous, statusCode);
1273 internal void LogBeginGetRequestStream(bool success, bool synchronous)
1275 string uri = this.RequestUri.OriginalString;
1276 if (!s_TriedGetEtwDelegates)
1278 if (s_EtwFireBeginGetRequestStream != null)
1280 s_EtwFireBeginGetRequestStream(this, uri, success, synchronous);
1283 internal void LogEndGetRequestStream(bool success, bool synchronous)
1285 if (!s_TriedGetEtwDelegates)
1287 if (s_EtwFireEndGetRequestStream != null) {
1289 s_EtwFireEndGetRequestStream(this, success, synchronous);
1293 } // class WebRequest
1294 } // namespace System.Net