X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Web%2FSystem.Web%2FHttpContext.cs;h=3666134304c9754a0fad78c38d9acd9bde56ce54;hb=60f847468e0e5740947aea5e0df987bc6b052e77;hp=0b0076f779b87b05a57590c49d461be2aefc6b35;hpb=aef2ee73d107c86e0963e92ef58620b65b68705c;p=mono.git diff --git a/mcs/class/System.Web/System.Web/HttpContext.cs b/mcs/class/System.Web/System.Web/HttpContext.cs index 0b0076f779b..3666134304c 100644 --- a/mcs/class/System.Web/System.Web/HttpContext.cs +++ b/mcs/class/System.Web/System.Web/HttpContext.cs @@ -52,7 +52,6 @@ using CustomErrorMode = System.Web.Configuration.CustomErrorsMode; #endif namespace System.Web { - // CAS - no InheritanceDemand here as the class is sealed [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] public sealed partial class HttpContext : IServiceProvider { @@ -72,7 +71,16 @@ namespace System.Web { object config_timeout; int timeout_possible; DateTime time_stamp = DateTime.UtcNow; + Timer timer; + Thread thread; + bool _isProcessingInclude; + #if NET_2_0 + [ThreadStatic] + static ResourceProviderFactory provider_factory; + [ThreadStatic] + static Dictionary resource_providers; + #if TARGET_JVM const string app_global_res_key = "HttpContext.app_global_res_key"; internal static Assembly AppGlobalResourcesAssembly { @@ -80,12 +88,14 @@ namespace System.Web { set { AppDomain.CurrentDomain.SetData (app_global_res_key, value); } } #else + [ThreadStatic] + static Dictionary resourceManagerCache; internal static Assembly AppGlobalResourcesAssembly; #endif ProfileBase profile = null; LinkedList handlers; #endif - + public HttpContext (HttpWorkerRequest wr) { WorkerRequest = wr; @@ -100,6 +110,11 @@ namespace System.Web { } + internal bool IsProcessingInclude { + get { return _isProcessingInclude; } + set { _isProcessingInclude = value; } + } + public Exception [] AllErrors { get { if (errors == null) @@ -137,6 +152,12 @@ namespace System.Web { } } + internal Cache InternalCache { + get { + return HttpRuntime.InternalCache; + } + } + // // The "Current" property is set just after we have constructed it with // the 'HttpContext (HttpWorkerRequest)' constructor. @@ -173,8 +194,19 @@ namespace System.Web { public bool IsCustomErrorEnabled { get { + try { + return IsCustomErrorEnabledUnsafe; + } + catch { + return false; + } + } + } + + internal bool IsCustomErrorEnabledUnsafe { + get { #if NET_2_0 - CustomErrorsSection cfg = WebConfigurationManager.SafeGetSection ("system.web/customErrors", typeof (CustomErrorsSection)) as CustomErrorsSection; + CustomErrorsSection cfg = (CustomErrorsSection) WebConfigurationManager.GetSection ("system.web/customErrors"); #else CustomErrorsConfig cfg = null; try { @@ -189,24 +221,12 @@ namespace System.Web { if (cfg.Mode == CustomErrorMode.On) return true; - return (cfg.Mode == CustomErrorMode.RemoteOnly) && - (Request.WorkerRequest.GetLocalAddress () != Request.UserHostAddress); + return (cfg.Mode == CustomErrorMode.RemoteOnly) && !Request.IsLocal; } } #if !TARGET_JVM public bool IsDebuggingEnabled { - get { -#if NET_2_0 - CompilationSection section = (CompilationSection) WebConfigurationManager.GetSection ("system.web/compilation"); - return section.Debug; -#else - try { - return CompilationConfiguration.GetInstance (this).Debug; - } catch { - return false; - } -#endif - } + get { return HttpRuntime.IsDebuggingEnabled; } } #endif public IDictionary Items { @@ -279,7 +299,22 @@ namespace System.Web { } } -#if NET_2_0 +#if NET_2_0 + internal bool MapRequestHandlerDone { + get; + set; + } + + // The two properties below are defined only when the IIS7 integrated mode is used. + // They are useless under Mono + public RequestNotification CurrentNotification { + get { throw new PlatformNotSupportedException ("This property is not supported on Mono."); } + } + + public bool IsPostNotification { + get { throw new PlatformNotSupportedException ("This property is not supported on Mono."); } + } + internal void PushHandler (IHttpHandler handler) { if (handler == null) @@ -322,6 +357,10 @@ namespace System.Web { get { return GetPreviousHandler (); } } + internal bool ProfileInitialized { + get { return profile != null; } + } + public ProfileBase Profile { get { if (profile == null) { @@ -361,6 +400,15 @@ namespace System.Web { errors = null; } + internal bool HasError (Exception e) + { + if (errors == e) + return true; + + return (errors is ArrayList) ? + ((ArrayList) errors).Contains (e) : false; + } + public void ClearError () { errors = null; @@ -393,8 +441,16 @@ namespace System.Web { { ResourceManager rm; try { - rm = new ResourceManager (classKey, assembly); - rm.IgnoreCase = true; + if (resourceManagerCache == null) + resourceManagerCache = new Dictionary (); + + ResourceManagerCacheKey key = new ResourceManagerCacheKey (classKey, assembly); + if (!resourceManagerCache.TryGetValue (key, out rm)) { + rm = new ResourceManager (classKey, assembly); + rm.IgnoreCase = true; + resourceManagerCache.Add (key, rm); + } + return rm.GetObject (resourceKey, culture); } catch (MissingManifestResourceException) { throw; @@ -408,10 +464,71 @@ namespace System.Web { return GetGlobalResourceObject (classKey, resourceKey, Thread.CurrentThread.CurrentUICulture); } + static bool EnsureProviderFactory () + { + if (resource_providers == null) + resource_providers = new Dictionary (); + + if (provider_factory != null) + return true; + + GlobalizationSection gs = WebConfigurationManager.GetSection ("system.web/globalization") as GlobalizationSection; + + if (gs == null) + return false; + + String rsfTypeName = gs.ResourceProviderFactoryType; + if (String.IsNullOrEmpty (rsfTypeName)) + return false; + + Type rsfType = HttpApplication.LoadType (rsfTypeName, true); + ResourceProviderFactory rpf = Activator.CreateInstance (rsfType) as ResourceProviderFactory; + + if (rpf == null) + return false; + + provider_factory = rpf; + return true; + } + + internal static IResourceProvider GetResourceProvider (string key, bool isLocal) + { + if (!EnsureProviderFactory ()) + return null; + + IResourceProvider rp = null; + if (!resource_providers.TryGetValue (key, out rp)) { + if (isLocal) + rp = provider_factory.CreateLocalResourceProvider (key); + else + rp = provider_factory.CreateGlobalResourceProvider (key); + if (rp == null) + return null; + resource_providers.Add (key, rp); + } + + return rp; + } + + static object GetGlobalObjectFromFactory (string classKey, string resourceKey, CultureInfo culture) + { + // FIXME: Retention of data + IResourceProvider rp = GetResourceProvider (classKey, false); + if (rp == null) + return null; + + return rp.GetObject (resourceKey, culture); + } + public static object GetGlobalResourceObject (string classKey, string resourceKey, CultureInfo culture) { + object ret = GetGlobalObjectFromFactory (classKey, resourceKey, culture); + if (ret != null) + return ret; + if (AppGlobalResourcesAssembly == null) - throw new MissingManifestResourceException (); + return null; + return GetResourceObject ("Resources." + classKey, resourceKey, culture, AppGlobalResourcesAssembly); } @@ -420,12 +537,25 @@ namespace System.Web { return GetLocalResourceObject (virtualPath, resourceKey, Thread.CurrentThread.CurrentUICulture); } + static object GetLocalObjectFromFactory (string virtualPath, string resourceKey, CultureInfo culture) + { + IResourceProvider rp = GetResourceProvider (virtualPath, true); + if (rp == null) + return null; + + return rp.GetObject (resourceKey, culture); + } + public static object GetLocalResourceObject (string virtualPath, string resourceKey, CultureInfo culture) { if (!VirtualPathUtility.IsAbsolute (virtualPath)) throw new ArgumentException ("The specified virtualPath was not rooted."); + + object ret = GetLocalObjectFromFactory (virtualPath, resourceKey, culture); + if (ret != null) + return ret; - string path = Path.GetDirectoryName (virtualPath); + string path = VirtualPathUtility.GetDirectory (virtualPath); Assembly asm = AppResourcesCompiler.GetCachedLocalResourcesAssembly (path); if (asm == null) { AppResourcesCompiler ac = new AppResourcesCompiler (path); @@ -442,6 +572,31 @@ namespace System.Web { { return WebConfigurationManager.GetSection (name); } + + sealed class ResourceManagerCacheKey + { + readonly string _name; + readonly Assembly _asm; + + public ResourceManagerCacheKey (string name, Assembly asm) + { + _name = name; + _asm = asm; + } + + public override bool Equals (object obj) + { + if (!(obj is ResourceManagerCacheKey)) + return false; + ResourceManagerCacheKey key = (ResourceManagerCacheKey) obj; + return key._asm == _asm && _name.Equals (key._name, StringComparison.Ordinal); + } + + public override int GetHashCode () + { + return _name.GetHashCode () + _asm.GetHashCode (); + } + } #endif object IServiceProvider.GetService (Type service) { @@ -488,6 +643,15 @@ namespace System.Web { return null; } +#if NET_2_0 + public void RemapHandler (IHttpHandler handler) + { + if (MapRequestHandlerDone) + throw new InvalidOperationException ("The RemapHandler method was called after the MapRequestHandler event occurred."); + Handler = handler; + } +#endif + public void RewritePath (string path) { #if NET_2_0 @@ -523,22 +687,41 @@ namespace System.Web { #endif void RewritePath (string filePath, string pathInfo, string queryString, bool setClientFilePath) { - filePath = UrlUtils.Combine (Request.BaseVirtualDir, filePath); - if (!StrUtils.StartsWith (filePath, HttpRuntime.AppDomainAppVirtualPath)) - throw new HttpException (404, "The virtual path '" + filePath + - "' maps to another application."); + if (filePath == null) + throw new ArgumentNullException ("filePath"); + if (!VirtualPathUtility.IsValidVirtualPath (filePath)) + throw new HttpException ("'" + HttpUtility.HtmlEncode (filePath) + "' is not a valid virtual path."); + + bool pathRelative = VirtualPathUtility.IsAppRelative (filePath); + bool pathAbsolute = pathRelative ? false : VirtualPathUtility.IsAbsolute (filePath); + if (pathRelative || pathAbsolute) { + bool needSubstring = false; + + if (pathRelative && filePath.Length > 1) + needSubstring = true; + string bvd = Request.BaseVirtualDir; + if (bvd.Length > 1) + bvd += "/"; + + string canonizedFilePath = VirtualPathUtility.Canonize (filePath); + filePath = VirtualPathUtility.Combine (bvd, needSubstring ? canonizedFilePath.Substring (2) : canonizedFilePath); + } else + filePath = VirtualPathUtility.Combine (VirtualPathUtility.GetDirectory (Request.FilePath), filePath); + + if (!StrUtils.StartsWith (filePath, HttpRuntime.AppDomainAppVirtualPath)) + throw new HttpException (404, "The virtual path '" + HttpUtility.HtmlEncode (filePath) + "' maps to another application.", filePath); + Request.SetCurrentExePath (filePath); + if (setClientFilePath) + Request.SetFilePath (filePath); + // A null pathInfo or queryString is ignored and previous values remain untouched if (pathInfo != null) Request.SetPathInfo (pathInfo); if (queryString != null) Request.QueryStringRaw = queryString; -#if NET_2_0 - if (setClientFilePath) - Request.SetFilePath (filePath); -#endif } #region internals @@ -577,17 +760,43 @@ namespace System.Web { set { config_timeout = value; +#if !TARGET_J2EE + if (timer != null) { + TimeSpan remaining = value - (DateTime.UtcNow - time_stamp); + long remaining_ms = Math.Max ((long)remaining.TotalMilliseconds, 0); + + // See http://msdn2.microsoft.com/en-us/library/7hs7492w.aspx + if (remaining_ms > 4294967294) + remaining_ms = 4294967294; + + timer.Change (remaining_ms, (long)Timeout.Infinite); + } +#endif } } #if !TARGET_J2EE - internal bool CheckIfTimeout (DateTime t) - { - if (Interlocked.CompareExchange (ref timeout_possible, 0, 0) == 0) - return false; - - TimeSpan ts = t - time_stamp; - return (ts > ConfigTimeout); + void TimeoutReached(object state) { + HttpRuntime.QueuePendingRequest (false); + if (Interlocked.CompareExchange (ref timeout_possible, 0, 0) == 0) { + timer.Change(2000, 0); + return; + } + StopTimeoutTimer(); + + thread.Abort (new StepTimeout ()); + } + + internal void StartTimeoutTimer() { + thread = Thread.CurrentThread; + timer = new Timer (TimeoutReached, null, (int)ConfigTimeout.TotalMilliseconds, Timeout.Infinite); + } + + internal void StopTimeoutTimer() { + if(timer != null) { + timer.Dispose (); + timer = null; + } } internal bool TimeoutPossible { @@ -605,19 +814,9 @@ namespace System.Web { } #endif #endregion - -#if NET_2_0 - Page last_page; - - internal Page LastPage { - get { - return last_page; - } - - set { - last_page = value; - } - } -#endif + } + + class StepTimeout + { } }