* Mono.Posix.dll.sources: Rename Mono.Posix to Mono.Unix.
[mono.git] / mcs / class / System.Web / System.Web / HttpContext.cs
1 //
2 // System.Web.HttpContext
3 //
4 // Authors:
5 //      Patrik Torstensson (Patrik.Torstensson@labs2.com)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // (c) 2003, 2004 Novell, Inc. (http://www.novell.com)
9 //
10
11 //
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:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
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.
30 //
31
32 using System;
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;
42
43 namespace System.Web
44 {
45         public sealed class HttpContext : IServiceProvider
46         {
47                 private ArrayList _arrExceptions;
48
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;
58
59                 private bool _skipauth;
60                 private Hashtable               _oItems;
61                 private DateTime                _oTimestamp;
62                 int timeoutPossible;
63                 long timeoutBegin;
64                 object configTimeout;
65                 string errorPage;
66                 IPrincipal user;
67
68                 public HttpContext (HttpRequest Request, HttpResponse Response)
69                 {
70                         Context = this;
71
72                         _arrExceptions = null;
73                         _oItems = null;
74                         _oTimestamp = DateTime.Now;
75                         _oRequest = Request;
76                         _oResponse = Response;
77                         _oTrace = new TraceContext (this);
78                 }
79
80                 public HttpContext (HttpWorkerRequest WorkerRequest)
81                 {
82                         Context = this;
83
84                         _arrExceptions = null;
85                         _oItems = null;
86                         _oTimestamp = DateTime.Now;
87                         _oRequest = new HttpRequest (WorkerRequest, this);
88                         _oResponse = new HttpResponse (WorkerRequest, this);
89                         _oWorkerRequest = WorkerRequest;
90                         _oTrace = new TraceContext (this);
91                 }
92
93                 internal HttpWorkerRequest WorkerRequest
94                 {
95                         get {
96                                 return _oWorkerRequest;
97                         }
98                 }
99
100                 internal static HttpContext Context
101                 {
102                         get {
103                                 return (HttpContext) CallContext.GetData ("Context");
104                         }
105
106                         set {
107                                 CallContext.SetData ("Context", value);
108                         }
109                 }
110
111                 public Exception [] AllErrors
112                 {
113                         get {
114                                 if (_arrExceptions == null || _arrExceptions.Count == 0)
115                                         return null;
116
117                                 return (Exception []) _arrExceptions.ToArray (typeof (Exception));
118                         }
119                 }
120
121                 public HttpApplicationState Application
122                 {
123                         get {
124                                 return HttpApplicationFactory.ApplicationState;
125                         }
126                 }
127
128                 public HttpApplication ApplicationInstance
129                 {
130                         get {
131                                 return _oApplication;
132                         }
133                         set {
134                                 _oApplication = value;
135                         }
136                 }
137
138                 public Cache Cache
139                 {
140                         get {
141                                 return HttpRuntime.Cache;
142                         }
143                 }
144
145                 public static HttpContext Current {
146                         get { return Context; }
147 #if NET_1_1
148                         set { Context = value; }
149 #endif
150                 }
151
152                 public Exception Error
153                 {
154                         get {
155                                 if (_arrExceptions == null || _arrExceptions.Count == 0)
156                                         return null;
157
158                                 return (Exception) _arrExceptions [0];
159                         }
160                 }
161
162                 public IHttpHandler Handler
163                 {
164                         get {    
165                                 return _Handler;
166                         }
167
168                         set {
169                                 _Handler = value;
170                         }
171                 }
172
173                 internal IHttpAsyncHandler AsyncHandler
174                 {
175                         get {    
176                                 return _AsyncHandler;
177                         }
178
179                         set {
180                                 _AsyncHandler = value;
181                         }
182                 }
183
184                 public bool IsCustomErrorEnabled {
185                         get {
186                                 CustomErrorsConfig cfg;
187                                 try {
188                                         cfg = (CustomErrorsConfig) GetConfig ("system.web/customErrors");
189                                 } catch (Exception) {
190                                         return false;
191                                 }
192                                 
193                                 if (cfg == null)
194                                         return false;
195
196                                 CustomErrorMode mode = cfg.Mode;
197                                 if (mode == CustomErrorMode.On)
198                                         return true;
199
200                                 return (mode == CustomErrorMode.RemoteOnly &&
201                                         _oRequest.ServerVariables ["LOCAL_ADDR"] == _oRequest.UserHostAddress);
202                         }
203                 }
204
205                 public bool IsDebuggingEnabled
206                 {
207                         get {
208                                 return CompilationConfiguration.GetInstance (this).Debug;
209                         }
210                 }
211
212                 public IDictionary Items
213                 {
214                         get {
215                                 if (_oItems == null)
216                                         _oItems = new Hashtable ();
217
218                                 return _oItems;
219                         }
220                 }
221
222                 public HttpRequest Request
223                 {
224                         get {
225                                 return _oRequest;
226                         }
227                 }
228
229                 public HttpResponse Response
230                 {
231                         get {
232                                 return _oResponse;
233                         }
234                 }
235
236                 public HttpServerUtility Server
237                 {
238                         get {
239                                 if (null == _Server)
240                                         _Server = new HttpServerUtility (this);
241
242                                 return _Server; 
243                         }
244                 }
245
246                 public HttpSessionState Session
247                 {
248                         get {
249                                 return (HttpSessionState) _oSession;
250                         }
251                 }
252
253                 public bool SkipAuthorization
254                 {
255                         get {
256                                 return _skipauth;
257                         }
258
259                         set {
260                                 _skipauth = value;
261                         }
262                 }
263
264                 public DateTime Timestamp
265                 {
266                         get {
267                                 return _oTimestamp;
268                         }
269                 }
270
271                 public TraceContext Trace
272                 {
273                         get {
274                                 return _oTrace;
275                         }
276                 }
277
278                 public IPrincipal User {
279                         get { return user; }
280                         set { user = value; }
281                 }
282
283                 internal bool TimeoutPossible {
284                         get { return (Interlocked.CompareExchange (ref timeoutPossible, 1, 1) == 1); }
285                 }
286                 
287                 internal void BeginTimeoutPossible ()
288                 {
289                         timeoutPossible = 1;
290                         timeoutBegin = DateTime.UtcNow.Ticks;
291                 }
292
293                 internal void EndTimeoutPossible ()
294                 {
295                         Interlocked.CompareExchange (ref timeoutPossible, 0, 1);
296                 }
297                 
298                 internal void TryWaitForTimeout () 
299                 {
300                         while (Interlocked.CompareExchange (ref timeoutPossible, 1, 1) == 1) {
301                                 Thread.Sleep (500);
302                         }
303                 }
304
305                 internal bool CheckIfTimeout (DateTime dt)
306                 {
307                         TimeSpan ts = new TimeSpan (dt.Ticks - timeoutBegin);
308                         return (ts > ConfigTimeout);
309                 }
310
311                 internal TimeSpan ConfigTimeout {
312                         get {
313                                 if (configTimeout == null) {
314                                         HttpRuntimeConfig config = (HttpRuntimeConfig)
315                                                                 GetConfig ("system.web/httpRuntime");
316                                         configTimeout = new TimeSpan (0, 0, config.ExecutionTimeout);
317                                 }
318
319                                 return (TimeSpan) configTimeout;
320                         }
321                         set {
322                                 configTimeout = value;
323                         }
324                 }
325                 
326                 internal string ErrorPage {
327                         get { return errorPage; }
328                         set { errorPage = value; }
329                 }
330                 
331                 internal void SetSession (HttpSessionState session)
332                 {
333                         _oSession = session;
334                 }
335                 
336                 public void AddError (Exception errorInfo)
337                 {
338                         if (_arrExceptions == null)
339                                 _arrExceptions = new ArrayList ();
340
341                         _arrExceptions.Add (errorInfo);
342                 }
343
344                 public void ClearError ()
345                 {
346                         _arrExceptions = null;
347                 }
348
349                 public object GetConfig (string name)
350                 {
351                         return WebConfigurationSettings.GetConfig (name, this);
352                 }
353
354                 public static object GetAppConfig (string name)
355                 {
356                         return WebConfigurationSettings.GetConfig (name);
357                 }
358
359                 object IServiceProvider.GetService (Type service)
360                 {
361                         if (service == typeof (HttpWorkerRequest)) 
362                                 return _oWorkerRequest;
363
364                         if (service == typeof (HttpRequest))
365                                 return Request;
366
367                         if (service == typeof (HttpResponse))
368                                 return Response;
369
370                         if (service == typeof (HttpApplication))
371                                 return ApplicationInstance;
372
373                         if (service == typeof (HttpApplicationState))
374                                 return Application;
375
376                         if (service == typeof (HttpSessionState))
377                                 return Session;
378
379                         if (service == typeof (HttpServerUtility))
380                                 return Server;
381
382                         return null;
383                 }
384
385                 public void RewritePath (string path)
386                 {
387                         //LAMESPEC: they say that they throw a ArgumentNullException, however,
388                         // i get a NullReferenceException...
389                         if (path == null)
390                                 throw new ArgumentNullException ("path");
391
392                         string query;
393                         int qmark = path.IndexOf ('?');
394                         if (qmark == -1 || qmark + 1 >= path.Length) {
395                                 query = null;
396                         } else {
397                                 query = path.Substring (qmark + 1);
398                                 path = path.Substring (0, qmark);
399                         }
400
401                         path = UrlUtils.Combine (Request.BaseVirtualDir, path);
402                         if (!path.StartsWith (HttpRuntime.AppDomainAppVirtualPath))
403                                 throw new HttpException (404, "The virtual path '" + path +
404                                                          "' maps to another application.");
405
406                         Request.SetCurrentExePath (path);
407                         Request.QueryStringRaw = query;
408                 }
409
410 #if NET_1_1
411                 public void RewritePath (string filePath, string pathInfo, string queryString)
412                 {
413                         RewritePath (filePath + "?" + queryString);
414                         Request.SetPathInfo (pathInfo);
415                 }
416 #endif
417         }
418 }
419