2 // System.Web.HttpContext.cs
5 // Miguel de Icaza (miguel@novell.com)
6 // Gonzalo Paniagua Javier (gonzalo@novell.com)
10 // Copyright (C) 2005 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.
32 using System.Collections;
33 using System.Configuration;
34 using System.Globalization;
35 using System.Runtime.Remoting.Messaging;
36 using System.Security.Permissions;
37 using System.Security.Principal;
38 using System.Threading;
39 using System.Web.Caching;
40 using System.Web.Configuration;
41 using System.Web.SessionState;
43 using System.Web.Util;
45 using System.Collections.Generic;
47 using System.Reflection;
48 using System.Resources;
49 using System.Web.Compilation;
50 using System.Web.Profile;
51 using CustomErrorMode = System.Web.Configuration.CustomErrorsMode;
54 namespace System.Web {
56 // CAS - no InheritanceDemand here as the class is sealed
57 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
58 public sealed partial class HttpContext : IServiceProvider {
59 internal HttpWorkerRequest WorkerRequest;
60 HttpApplication app_instance;
62 HttpResponse response;
63 HttpSessionState session_state;
64 HttpServerUtility server;
65 TraceContext trace_context;
68 bool skip_authorization = false;
72 object config_timeout;
74 DateTime time_stamp = DateTime.UtcNow;
77 const string app_global_res_key = "HttpContext.app_global_res_key";
78 internal static Assembly AppGlobalResourcesAssembly {
79 get { return (Assembly) AppDomain.CurrentDomain.GetData (app_global_res_key); }
80 set { AppDomain.CurrentDomain.SetData (app_global_res_key, value); }
83 internal static Assembly AppGlobalResourcesAssembly;
85 ProfileBase profile = null;
86 LinkedList<IHttpHandler> handlers;
89 public HttpContext (HttpWorkerRequest wr)
92 request = new HttpRequest (WorkerRequest, this);
93 response = new HttpResponse (WorkerRequest, this);
96 public HttpContext (HttpRequest request, HttpResponse response)
98 this.request = request;
99 this.response = response;
103 public Exception [] AllErrors {
108 if (errors is Exception){
109 Exception [] all = new Exception [1];
110 all [0] = (Exception) errors;
113 return (Exception []) (((ArrayList) errors).ToArray (typeof (Exception)));
117 public HttpApplicationState Application {
119 return HttpApplicationFactory.ApplicationState;
123 public HttpApplication ApplicationInstance {
129 app_instance = value;
136 return HttpRuntime.Cache;
140 internal Cache InternalCache {
142 return HttpRuntime.InternalCache;
147 // The "Current" property is set just after we have constructed it with
148 // the 'HttpContext (HttpWorkerRequest)' constructor.
150 #if !TARGET_JVM // No remoting CallContext support in Grasshopper
151 public static HttpContext Current {
153 return (HttpContext) CallContext.GetData ("c");
157 CallContext.SetData ("c", value);
162 public Exception Error {
164 if (errors == null || (errors is Exception))
165 return (Exception) errors;
166 return (Exception) (((ArrayList) errors) [0]);
170 public IHttpHandler Handler {
180 public bool IsCustomErrorEnabled {
183 return IsCustomErrorEnabledUnsafe;
191 internal bool IsCustomErrorEnabledUnsafe {
194 CustomErrorsSection cfg = (CustomErrorsSection) WebConfigurationManager.GetSection ("system.web/customErrors");
196 CustomErrorsConfig cfg = null;
198 cfg = (CustomErrorsConfig) GetConfig ("system.web/customErrors");
206 if (cfg.Mode == CustomErrorMode.On)
209 return (cfg.Mode == CustomErrorMode.RemoteOnly) && !Request.IsLocal;
213 public bool IsDebuggingEnabled {
216 CompilationSection section = (CompilationSection) WebConfigurationManager.GetSection ("system.web/compilation");
217 return section.Debug;
220 return CompilationConfiguration.GetInstance (this).Debug;
228 public IDictionary Items {
231 items = new Hashtable ();
236 public HttpRequest Request {
242 public HttpResponse Response {
248 public HttpServerUtility Server {
251 server = new HttpServerUtility (this);
256 public HttpSessionState Session {
258 return session_state;
262 public bool SkipAuthorization {
264 return skip_authorization;
267 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
269 skip_authorization = value;
273 public DateTime Timestamp {
275 return time_stamp.ToLocalTime ();
279 public TraceContext Trace {
281 if (trace_context == null)
282 trace_context = new TraceContext (this);
283 return trace_context;
287 public IPrincipal User {
292 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
299 internal void PushHandler (IHttpHandler handler)
303 if (handlers == null)
304 handlers = new LinkedList <IHttpHandler> ();
305 handlers.AddLast (handler);
308 internal void PopHandler ()
310 if (handlers == null || handlers.Count == 0)
312 handlers.RemoveLast ();
315 IHttpHandler GetCurrentHandler ()
317 if (handlers == null || handlers.Count == 0)
320 return handlers.Last.Value;
323 IHttpHandler GetPreviousHandler ()
325 if (handlers == null || handlers.Count <= 1)
327 LinkedListNode <IHttpHandler> previous = handlers.Last.Previous;
328 if (previous != null)
329 return previous.Value;
333 public IHttpHandler CurrentHandler {
334 get { return GetCurrentHandler (); }
337 public IHttpHandler PreviousHandler {
338 get { return GetPreviousHandler (); }
341 internal bool ProfileInitialized {
342 get { return profile != null; }
345 public ProfileBase Profile {
347 if (profile == null) {
348 if (Request.IsAuthenticated)
349 profile = ProfileBase.Create (User.Identity.Name);
351 profile = ProfileBase.Create (Request.AnonymousID, false);
362 public void AddError (Exception errorInfo)
369 if (errors is Exception){
370 l = new ArrayList ();
374 l = (ArrayList) errors;
378 internal void ClearError (Exception e)
384 public void ClearError ()
390 [Obsolete ("use WebConfigurationManager.GetWebApplicationSection")]
392 public static object GetAppConfig (string name)
394 object o = ConfigurationSettings.GetConfig (name);
400 [Obsolete ("see GetSection")]
402 public object GetConfig (string name)
405 return GetSection (name);
407 return WebConfigurationSettings.GetConfig (name, this);
412 static object GetResourceObject (string classKey, string resourceKey, CultureInfo culture, Assembly assembly)
416 rm = new ResourceManager (classKey, assembly);
417 rm.IgnoreCase = true;
418 return rm.GetObject (resourceKey, culture);
419 } catch (MissingManifestResourceException) {
421 } catch (Exception ex) {
422 throw new HttpException ("Failed to retrieve the specified global resource object.", ex);
426 public static object GetGlobalResourceObject (string classKey, string resourceKey)
428 return GetGlobalResourceObject (classKey, resourceKey, Thread.CurrentThread.CurrentUICulture);
431 public static object GetGlobalResourceObject (string classKey, string resourceKey, CultureInfo culture)
433 if (AppGlobalResourcesAssembly == null)
434 throw new MissingManifestResourceException ();
435 return GetResourceObject ("Resources." + classKey, resourceKey, culture, AppGlobalResourcesAssembly);
438 public static object GetLocalResourceObject (string virtualPath, string resourceKey)
440 return GetLocalResourceObject (virtualPath, resourceKey, Thread.CurrentThread.CurrentUICulture);
443 public static object GetLocalResourceObject (string virtualPath, string resourceKey, CultureInfo culture)
445 if (!VirtualPathUtility.IsAbsolute (virtualPath))
446 throw new ArgumentException ("The specified virtualPath was not rooted.");
448 string path = Path.GetDirectoryName (virtualPath);
449 Assembly asm = AppResourcesCompiler.GetCachedLocalResourcesAssembly (path);
451 AppResourcesCompiler ac = new AppResourcesCompiler (path);
454 throw new MissingManifestResourceException ("A resource object was not found at the specified virtualPath.");
457 path = Path.GetFileName (virtualPath);
458 return GetResourceObject (path, resourceKey, culture, asm);
461 public object GetSection (string name)
463 return WebConfigurationManager.GetSection (name);
466 object IServiceProvider.GetService (Type service)
468 if (service == typeof (HttpWorkerRequest))
469 return WorkerRequest;
472 // We return everything out of properties in case
473 // they are dynamically computed in some form in the future.
475 if (service == typeof (HttpApplication))
476 return ApplicationInstance;
478 if (service == typeof (HttpRequest))
481 if (service == typeof (HttpResponse))
484 if (service == typeof (HttpSessionState))
487 if (service == typeof (HttpApplicationState))
490 if (service == typeof (IPrincipal))
493 if (service == typeof (Cache))
496 if (service == typeof (HttpContext))
499 if (service == typeof (IHttpHandler))
502 if (service == typeof (HttpServerUtility))
505 if (service == typeof (TraceContext))
511 public void RewritePath (string path)
514 RewritePath (path, true);
516 RewritePath (path, false);
520 public void RewritePath (string filePath, string pathInfo, string queryString)
522 RewritePath (filePath, pathInfo, queryString, false);
530 void RewritePath (string path, bool rebaseClientPath)
532 int qmark = path.IndexOf ('?');
534 RewritePath (path.Substring (0, qmark), "", path.Substring (qmark + 1), rebaseClientPath);
536 RewritePath (path, null, null, rebaseClientPath);
544 void RewritePath (string filePath, string pathInfo, string queryString, bool setClientFilePath)
546 filePath = UrlUtils.Combine (Request.BaseVirtualDir, filePath);
547 if (!StrUtils.StartsWith (filePath, HttpRuntime.AppDomainAppVirtualPath))
548 throw new HttpException (404, "The virtual path '" + filePath +
549 "' maps to another application.");
551 Request.SetCurrentExePath (filePath);
552 // A null pathInfo or queryString is ignored and previous values remain untouched
553 if (pathInfo != null)
554 Request.SetPathInfo (pathInfo);
556 if (queryString != null)
557 Request.QueryStringRaw = queryString;
559 if (setClientFilePath)
560 Request.SetFilePath (filePath);
566 internal void SetSession (HttpSessionState state)
568 session_state = state;
571 // URL of a page used for error redirection.
572 internal string ErrorPage {
582 internal TimeSpan ConfigTimeout {
584 if (config_timeout == null) {
586 HttpRuntimeSection section = (HttpRuntimeSection)WebConfigurationManager.GetSection ("system.web/httpRuntime");
587 config_timeout = section.ExecutionTimeout;
589 HttpRuntimeConfig config = (HttpRuntimeConfig)
590 GetConfig ("system.web/httpRuntime");
591 config_timeout = new TimeSpan (0, 0, config.ExecutionTimeout);
595 return (TimeSpan) config_timeout;
599 config_timeout = value;
604 internal bool CheckIfTimeout (DateTime t)
606 if (Interlocked.CompareExchange (ref timeout_possible, 0, 0) == 0)
609 TimeSpan ts = t - time_stamp;
610 return (ts > ConfigTimeout);
613 internal bool TimeoutPossible {
614 get { return (Interlocked.CompareExchange (ref timeout_possible, 1, 1) == 1); }
617 internal void BeginTimeoutPossible ()
619 timeout_possible = 1;
622 internal void EndTimeoutPossible ()
624 Interlocked.CompareExchange (ref timeout_possible, 0, 1);
632 internal Page LastPage {