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.Reflection;
46 using System.Resources;
47 using System.Web.Profile;
48 using CustomErrorMode = System.Web.Configuration.CustomErrorsMode;
51 namespace System.Web {
53 // CAS - no InheritanceDemand here as the class is sealed
54 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
55 public sealed class HttpContext : IServiceProvider {
56 internal HttpWorkerRequest WorkerRequest;
57 HttpApplication app_instance;
59 HttpResponse response;
60 HttpSessionState session_state;
61 HttpServerUtility server;
62 TraceContext trace_context;
65 bool skip_authorization = false;
69 object config_timeout;
71 DateTime time_stamp = DateTime.UtcNow;
73 ProfileBase profile = null;
75 #if TARGET_JVM // No remoting support (CallContext) yet in Grasshopper
76 static LocalDataStoreSlot _ContextSlot = Thread.GetNamedDataSlot ("Context");
79 public HttpContext (HttpWorkerRequest wr)
82 request = new HttpRequest (WorkerRequest, this);
83 response = new HttpResponse (WorkerRequest, this);
86 public HttpContext (HttpRequest request, HttpResponse response)
88 this.request = request;
89 this.response = response;
93 public Exception [] AllErrors {
98 if (errors is Exception){
99 Exception [] all = new Exception [1];
100 all [0] = (Exception) errors;
103 return (Exception []) (((ArrayList) errors).ToArray (typeof (Exception)));
107 public HttpApplicationState Application {
109 return HttpApplicationFactory.ApplicationState;
113 public HttpApplication ApplicationInstance {
119 app_instance = value;
126 return HttpRuntime.Cache;
131 // The "Current" property is set just after we have constructed it with
132 // the 'HttpContext (HttpWorkerRequest)' constructor.
134 #if TARGET_JVM // No remoting support (CallContext) yet in Grasshopper
135 [MonoTODO("Context - Use System.Remoting.Messaging.CallContext instead of Thread storage")]
136 public static HttpContext Current
138 get { return (HttpContext) Thread.GetData (_ContextSlot); }
139 set { Thread.SetData (_ContextSlot, value); }
142 public static HttpContext Current {
144 return (HttpContext) CallContext.GetData ("c");
148 CallContext.SetData ("c", value);
153 public Exception Error {
155 if (errors == null || (errors is Exception))
156 return (Exception) errors;
157 return (Exception) (((ArrayList) errors) [0]);
161 public IHttpHandler Handler {
171 public bool IsCustomErrorEnabled {
174 CustomErrorsSection cfg = (CustomErrorsSection) WebConfigurationManager.GetSection ("system.web/customErrors");
176 CustomErrorsConfig cfg = null;
178 cfg = (CustomErrorsConfig) GetConfig ("system.web/customErrors");
186 if (cfg.Mode == CustomErrorMode.On)
189 return (cfg.Mode == CustomErrorMode.RemoteOnly) &&
190 (Request.WorkerRequest.GetLocalAddress () != Request.UserHostAddress);
194 public bool IsDebuggingEnabled { get { return false; } }
196 public bool IsDebuggingEnabled {
199 CompilationSection section = (CompilationSection) WebConfigurationManager.GetSection ("system.web/compilation");
200 return section.Debug;
203 return CompilationConfiguration.GetInstance (this).Debug;
211 public IDictionary Items {
214 items = new Hashtable ();
219 public HttpRequest Request {
225 public HttpResponse Response {
231 public HttpServerUtility Server {
234 server = new HttpServerUtility (this);
239 public HttpSessionState Session {
241 return session_state;
245 public bool SkipAuthorization {
247 return skip_authorization;
250 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
252 skip_authorization = value;
256 public DateTime Timestamp {
258 return time_stamp.ToLocalTime ();
262 public TraceContext Trace {
264 if (trace_context == null)
265 trace_context = new TraceContext (this);
266 return trace_context;
270 public IPrincipal User {
275 [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
282 [MonoTODO ("Not implemented")]
283 public IHttpHandler CurrentHandler {
284 get { throw new NotImplementedException (); }
287 [MonoTODO ("Not implemented")]
288 public IHttpHandler PreviousHandler {
289 get { throw new NotImplementedException (); }
292 public ProfileBase Profile {
295 if (profile == null) {
296 if (Request.IsAuthenticated)
297 profile = ProfileBase.Create (User.Identity.Name);
299 profile = ProfileBase.Create (Request.AnonymousID, false);
306 public void AddError (Exception errorInfo)
313 if (errors is Exception){
314 l = new ArrayList ();
318 l = (ArrayList) errors;
322 internal void ClearError (Exception e)
328 public void ClearError ()
334 [Obsolete ("use WebConfigurationManager.GetWebApplicationSection")]
336 public static object GetAppConfig (string name)
338 object o = ConfigurationSettings.GetConfig (name);
344 [Obsolete ("see GetSection")]
346 public object GetConfig (string name)
349 return GetSection (name);
351 return WebConfigurationSettings.GetConfig (name, this);
356 internal static Type GetGLResourceType (string typeName)
359 Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
361 foreach (Assembly ass in assemblies) {
362 type = ass.GetType (typeName);
369 throw new MissingManifestResourceException (String.Format ("Missing resource class {0}", typeName));
372 internal static object GetGLResourceObject (Type type, string resourceKey)
376 PropertyInfo pi = type.GetProperty (resourceKey,
377 BindingFlags.GetProperty |
378 BindingFlags.Public |
379 BindingFlags.Static);
382 ret = pi.GetValue (null, null);
389 internal static void SetGLResourceObjectCulture (Type type, CultureInfo ci)
392 PropertyInfo pi = type.GetProperty ("Culture",
393 BindingFlags.SetProperty |
394 BindingFlags.Public |
395 BindingFlags.Static);
397 return; // internal error actually...
398 pi.SetValue (null, ci, null);
403 public static object GetGlobalResourceObject (string classKey, string resourceKey)
405 string className = String.Format ("System.Resources.{0}", classKey);
406 Type type = GetGLResourceType (className);
407 SetGLResourceObjectCulture (type, null);
408 return GetGLResourceObject (type, resourceKey);
411 public static object GetGlobalResourceObject (string classKey, string resourceKey, CultureInfo culture)
413 string className = String.Format ("System.Resources.{0}", classKey);
414 Type type = GetGLResourceType (className);
415 SetGLResourceObjectCulture (type, culture);
416 return GetGLResourceObject (type, resourceKey);
419 [MonoTODO ("Not implemented")]
420 public static object GetLocalResourceObject (string virtualPath, string resourceKey)
422 throw new NotImplementedException ();
425 [MonoTODO ("Not implemented")]
426 public static object GetLocalResourceObject (string virtualPath, string resourceKey, CultureInfo culture)
428 throw new NotImplementedException ();
431 [MonoTODO ("Only implemented for ASP.NET 2.x applications")]
432 public object GetSection (string name)
435 return WebConfigurationManager.GetSection (name);
437 throw new NotImplementedException ();
441 object IServiceProvider.GetService (Type service)
443 if (service == typeof (HttpWorkerRequest))
444 return WorkerRequest;
447 // We return everything out of properties in case
448 // they are dynamically computed in some form in the future.
450 if (service == typeof (HttpApplication))
451 return ApplicationInstance;
453 if (service == typeof (HttpRequest))
456 if (service == typeof (HttpResponse))
459 if (service == typeof (HttpSessionState))
462 if (service == typeof (HttpApplicationState))
465 if (service == typeof (IPrincipal))
468 if (service == typeof (Cache))
471 if (service == typeof (HttpContext))
474 if (service == typeof (IHttpHandler))
477 if (service == typeof (HttpServerUtility))
480 if (service == typeof (TraceContext))
486 public void RewritePath (string path)
489 RewritePath (path, true);
491 RewritePath (path, false);
495 public void RewritePath (string filePath, string pathInfo, string queryString)
497 RewritePath (filePath, pathInfo, queryString, false);
505 void RewritePath (string path, bool rebaseClientPath)
507 int qmark = path.IndexOf ('?');
509 RewritePath (path.Substring (0, qmark), "", path.Substring (qmark + 1), rebaseClientPath);
511 RewritePath (path, null, null, rebaseClientPath);
519 void RewritePath (string filePath, string pathInfo, string queryString, bool setClientFilePath)
521 filePath = UrlUtils.Combine (Request.BaseVirtualDir, filePath);
522 if (!filePath.StartsWith (HttpRuntime.AppDomainAppVirtualPath))
523 throw new HttpException (404, "The virtual path '" + filePath +
524 "' maps to another application.");
526 Request.SetCurrentExePath (filePath);
527 // A null pathInfo or queryString is ignored and previous values remain untouched
528 if (pathInfo != null)
529 Request.SetPathInfo (pathInfo);
531 if (queryString != null)
532 Request.QueryStringRaw = queryString;
534 if (setClientFilePath)
535 Request.SetFilePath (filePath);
541 internal void SetSession (HttpSessionState state)
543 session_state = state;
546 // URL of a page used for error redirection.
547 internal string ErrorPage {
557 internal TimeSpan ConfigTimeout {
559 if (config_timeout == null) {
561 HttpRuntimeSection section = (HttpRuntimeSection)WebConfigurationManager.GetSection ("system.web/httpRuntime");
562 config_timeout = section.ExecutionTimeout;
564 HttpRuntimeConfig config = (HttpRuntimeConfig)
565 GetConfig ("system.web/httpRuntime");
566 config_timeout = new TimeSpan (0, 0, config.ExecutionTimeout);
570 return (TimeSpan) config_timeout;
574 config_timeout = value;
578 internal bool CheckIfTimeout (DateTime t)
580 if (Interlocked.CompareExchange (ref timeout_possible, 0, 0) == 0)
583 TimeSpan ts = t - time_stamp;
584 return (ts > ConfigTimeout);
587 internal bool TimeoutPossible {
588 get { return (Interlocked.CompareExchange (ref timeout_possible, 1, 1) == 1); }
591 internal void BeginTimeoutPossible ()
593 timeout_possible = 1;
596 internal void EndTimeoutPossible ()
598 Interlocked.CompareExchange (ref timeout_possible, 0, 1);
605 internal Page LastPage {