2 // System.Web.HttpContext
5 // Patrik Torstensson (Patrik.Torstensson@labs2.com)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // (c) 2003, 2004 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.
33 using System.Collections;
34 using System.Configuration;
35 using System.Security.Principal;
36 using System.Web.Caching;
37 using System.Web.Configuration;
38 using System.Web.Util;
39 using System.Web.SessionState;
40 using System.Threading;
41 using System.Runtime.Remoting.Messaging;
45 public sealed class HttpContext : IServiceProvider
47 private ArrayList _arrExceptions;
49 private HttpResponse _oResponse;
50 private HttpRequest _oRequest;
51 private HttpServerUtility _Server;
52 private HttpApplication _oApplication;
53 private HttpSessionState _oSession;
54 private HttpWorkerRequest _oWorkerRequest;
55 private TraceContext _oTrace;
56 private IHttpHandler _Handler;
57 private IHttpAsyncHandler _AsyncHandler;
59 private bool _skipauth;
60 private Hashtable _oItems;
61 private DateTime _oTimestamp;
68 #if TARGET_JVM // No remoting support (CallContext) yet in Grasshopper
69 static LocalDataStoreSlot _ContextSlot = Thread.GetNamedDataSlot ("Context");
73 private System.Web.UI.Page lastPage;
76 public HttpContext (HttpRequest Request, HttpResponse Response)
80 _oTimestamp = DateTime.Now;
82 _oResponse = Response;
83 _oTrace = new TraceContext (this);
86 public HttpContext (HttpWorkerRequest WorkerRequest)
90 _oTimestamp = DateTime.Now;
91 _oRequest = new HttpRequest (WorkerRequest, this);
92 _oResponse = new HttpResponse (WorkerRequest, this);
93 _oWorkerRequest = WorkerRequest;
94 _oTrace = new TraceContext (this);
97 internal HttpWorkerRequest WorkerRequest
100 return _oWorkerRequest;
104 #if TARGET_JVM // No remoting support (CallContext) yet in Grasshopper
105 [MonoTODO("Context - Use System.Remoting.Messaging.CallContext instead of Thread storage")]
106 internal static HttpContext Context
108 get { return (HttpContext) Thread.GetData (_ContextSlot); }
109 set { Thread.SetData (_ContextSlot, value); }
112 internal static HttpContext Context
115 return (HttpContext) CallContext.GetData ("Context");
119 CallContext.SetData ("Context", value);
124 public Exception [] AllErrors
127 if (_arrExceptions == null || _arrExceptions.Count == 0)
130 return (Exception []) _arrExceptions.ToArray (typeof (Exception));
134 public HttpApplicationState Application
137 return HttpApplicationFactory.ApplicationState;
141 public HttpApplication ApplicationInstance
144 return _oApplication;
147 _oApplication = value;
154 return HttpRuntime.Cache;
158 public static HttpContext Current {
159 get { return Context; }
161 set { Context = value; }
165 public Exception Error
168 if (_arrExceptions == null || _arrExceptions.Count == 0)
171 return (Exception) _arrExceptions [0];
175 public IHttpHandler Handler
186 internal IHttpAsyncHandler AsyncHandler
189 return _AsyncHandler;
193 _AsyncHandler = value;
197 public bool IsCustomErrorEnabled {
199 CustomErrorsConfig cfg;
201 cfg = (CustomErrorsConfig) GetConfig ("system.web/customErrors");
202 } catch (Exception) {
209 CustomErrorMode mode = cfg.Mode;
210 if (mode == CustomErrorMode.On)
213 return (mode == CustomErrorMode.RemoteOnly &&
214 _oRequest.ServerVariables ["LOCAL_ADDR"] == _oRequest.UserHostAddress);
219 public bool IsDebuggingEnabled
226 public bool IsDebuggingEnabled
229 return CompilationConfiguration.GetInstance (this).Debug;
234 public IDictionary Items
238 _oItems = new Hashtable ();
244 public HttpRequest Request
251 public HttpResponse Response
258 public HttpServerUtility Server
262 _Server = new HttpServerUtility (this);
268 public HttpSessionState Session
271 return (HttpSessionState) _oSession;
275 public bool SkipAuthorization
286 public DateTime Timestamp
293 public TraceContext Trace
300 public IPrincipal User {
302 set { user = value; }
306 internal bool TimeoutPossible {
307 get { return (timeoutPossible==1);}
309 internal void EndTimeoutPossible () {
312 internal void TryWaitForTimeout () {
313 while (TimeoutPossible) {
320 internal bool TimeoutPossible {
321 get { return (Interlocked.CompareExchange (ref timeoutPossible, 1, 1) == 1); }
324 internal void BeginTimeoutPossible ()
327 timeoutBegin = DateTime.UtcNow.Ticks;
331 internal void EndTimeoutPossible ()
333 Interlocked.CompareExchange (ref timeoutPossible, 0, 1);
336 internal void TryWaitForTimeout ()
338 while (Interlocked.CompareExchange (ref timeoutPossible, 1, 1) == 1) {
344 internal bool CheckIfTimeout (DateTime dt)
346 TimeSpan ts = new TimeSpan (dt.Ticks - timeoutBegin);
347 return (ts > ConfigTimeout);
350 internal TimeSpan ConfigTimeout {
352 if (configTimeout == null) {
353 HttpRuntimeConfig config = (HttpRuntimeConfig)
354 GetConfig ("system.web/httpRuntime");
355 configTimeout = new TimeSpan (0, 0, config.ExecutionTimeout);
358 return (TimeSpan) configTimeout;
361 configTimeout = value;
365 internal string ErrorPage {
366 get { return errorPage; }
367 set { errorPage = value; }
370 internal void SetSession (HttpSessionState session)
375 public void AddError (Exception errorInfo)
377 if (_arrExceptions == null)
378 _arrExceptions = new ArrayList ();
380 _arrExceptions.Add (errorInfo);
383 public void ClearError ()
385 _arrExceptions = null;
388 public object GetConfig (string name)
390 return WebConfigurationSettings.GetConfig (name, this);
393 public static object GetAppConfig (string name)
395 return WebConfigurationSettings.GetConfig (name);
398 object IServiceProvider.GetService (Type service)
400 if (service == typeof (HttpWorkerRequest))
401 return _oWorkerRequest;
403 if (service == typeof (HttpRequest))
406 if (service == typeof (HttpResponse))
409 if (service == typeof (HttpApplication))
410 return ApplicationInstance;
412 if (service == typeof (HttpApplicationState))
415 if (service == typeof (HttpSessionState))
418 if (service == typeof (HttpServerUtility))
424 public void RewritePath (string path)
426 //LAMESPEC: they say that they throw a ArgumentNullException, however,
427 // i get a NullReferenceException...
429 throw new ArgumentNullException ("path");
432 int qmark = path.IndexOf ('?');
433 if (qmark == -1 || qmark + 1 >= path.Length) {
436 query = path.Substring (qmark + 1);
437 path = path.Substring (0, qmark);
440 path = UrlUtils.Combine (Request.BaseVirtualDir, path);
441 if (!StrUtils.StartsWith (path, HttpRuntime.AppDomainAppVirtualPath))
442 throw new HttpException (404, "The virtual path '" + path +
443 "' maps to another application.");
445 Request.SetCurrentExePath (path);
446 Request.QueryStringRaw = query;
450 public void RewritePath (string filePath, string pathInfo, string queryString)
452 RewritePath (filePath + "?" + queryString);
453 Request.SetPathInfo (pathInfo);
458 internal System.Web.UI.Page LastPage {
459 get { return lastPage; }
460 set { lastPage = value; }