Timeout of handling requests is not supported in TARGET_J2EE (Thread.Abort not supported)
[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 #if TARGET_JVM // No remoting support (CallContext) yet in Grasshopper
69                 static LocalDataStoreSlot _ContextSlot = Thread.GetNamedDataSlot ("Context");
70 #endif
71
72 #if NET_2_0
73                 private System.Web.UI.Page lastPage;
74 #endif
75
76                 public HttpContext (HttpRequest Request, HttpResponse Response)
77                 {
78                         Context = this;
79
80                         _oTimestamp = DateTime.Now;
81                         _oRequest = Request;
82                         _oResponse = Response;
83                         _oTrace = new TraceContext (this);
84                 }
85
86                 public HttpContext (HttpWorkerRequest WorkerRequest)
87                 {
88                         Context = this;
89
90                         _oTimestamp = DateTime.Now;
91                         _oRequest = new HttpRequest (WorkerRequest, this);
92                         _oResponse = new HttpResponse (WorkerRequest, this);
93                         _oWorkerRequest = WorkerRequest;
94                         _oTrace = new TraceContext (this);
95                 }
96
97                 internal HttpWorkerRequest WorkerRequest
98                 {
99                         get {
100                                 return _oWorkerRequest;
101                         }
102                 }
103
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
107                 {
108                         get { return (HttpContext) Thread.GetData (_ContextSlot); }
109                         set { Thread.SetData (_ContextSlot, value); }
110                 }
111 #else
112                 internal static HttpContext Context
113                 {
114                         get {
115                                 return (HttpContext) CallContext.GetData ("Context");
116                         }
117
118                         set {
119                                 CallContext.SetData ("Context", value);
120                         }
121                 }
122 #endif
123
124                 public Exception [] AllErrors
125                 {
126                         get {
127                                 if (_arrExceptions == null || _arrExceptions.Count == 0)
128                                         return null;
129
130                                 return (Exception []) _arrExceptions.ToArray (typeof (Exception));
131                         }
132                 }
133
134                 public HttpApplicationState Application
135                 {
136                         get {
137                                 return HttpApplicationFactory.ApplicationState;
138                         }
139                 }
140
141                 public HttpApplication ApplicationInstance
142                 {
143                         get {
144                                 return _oApplication;
145                         }
146                         set {
147                                 _oApplication = value;
148                         }
149                 }
150
151                 public Cache Cache
152                 {
153                         get {
154                                 return HttpRuntime.Cache;
155                         }
156                 }
157
158                 public static HttpContext Current {
159                         get { return Context; }
160 #if NET_1_1
161                         set { Context = value; }
162 #endif
163                 }
164
165                 public Exception Error
166                 {
167                         get {
168                                 if (_arrExceptions == null || _arrExceptions.Count == 0)
169                                         return null;
170
171                                 return (Exception) _arrExceptions [0];
172                         }
173                 }
174
175                 public IHttpHandler Handler
176                 {
177                         get {    
178                                 return _Handler;
179                         }
180
181                         set {
182                                 _Handler = value;
183                         }
184                 }
185
186                 internal IHttpAsyncHandler AsyncHandler
187                 {
188                         get {    
189                                 return _AsyncHandler;
190                         }
191
192                         set {
193                                 _AsyncHandler = value;
194                         }
195                 }
196
197                 public bool IsCustomErrorEnabled {
198                         get {
199                                 CustomErrorsConfig cfg;
200                                 try {
201                                         cfg = (CustomErrorsConfig) GetConfig ("system.web/customErrors");
202                                 } catch (Exception) {
203                                         return false;
204                                 }
205                                 
206                                 if (cfg == null)
207                                         return false;
208
209                                 CustomErrorMode mode = cfg.Mode;
210                                 if (mode == CustomErrorMode.On)
211                                         return true;
212
213                                 return (mode == CustomErrorMode.RemoteOnly &&
214                                         _oRequest.ServerVariables ["LOCAL_ADDR"] == _oRequest.UserHostAddress);
215                         }
216                 }
217
218 #if TARGET_J2EE
219                 public bool IsDebuggingEnabled
220                 {
221                         get {
222                                 return false;
223                         }
224                 }
225 #else
226                 public bool IsDebuggingEnabled
227                 {
228                         get {
229                                 return CompilationConfiguration.GetInstance (this).Debug;
230                         }
231                 }
232 #endif
233
234                 public IDictionary Items
235                 {
236                         get {
237                                 if (_oItems == null)
238                                         _oItems = new Hashtable ();
239
240                                 return _oItems;
241                         }
242                 }
243
244                 public HttpRequest Request
245                 {
246                         get {
247                                 return _oRequest;
248                         }
249                 }
250
251                 public HttpResponse Response
252                 {
253                         get {
254                                 return _oResponse;
255                         }
256                 }
257
258                 public HttpServerUtility Server
259                 {
260                         get {
261                                 if (null == _Server)
262                                         _Server = new HttpServerUtility (this);
263
264                                 return _Server; 
265                         }
266                 }
267
268                 public HttpSessionState Session
269                 {
270                         get {
271                                 return (HttpSessionState) _oSession;
272                         }
273                 }
274
275                 public bool SkipAuthorization
276                 {
277                         get {
278                                 return _skipauth;
279                         }
280
281                         set {
282                                 _skipauth = value;
283                         }
284                 }
285
286                 public DateTime Timestamp
287                 {
288                         get {
289                                 return _oTimestamp;
290                         }
291                 }
292
293                 public TraceContext Trace
294                 {
295                         get {
296                                 return _oTrace;
297                         }
298                 }
299
300                 public IPrincipal User {
301                         get { return user; }
302                         set { user = value; }
303                 }
304
305 #if TARGET_J2EE
306                 internal bool TimeoutPossible {
307                         get { return (timeoutPossible==1);}
308                 }
309                 internal void EndTimeoutPossible () {
310                         timeoutPossible = 0;
311                 }
312                 internal void TryWaitForTimeout () {
313                         while (TimeoutPossible) {
314                                 Thread.Sleep (500);
315                         }
316                 }
317 #endif
318                 
319 #if !TARGET_J2EE
320                 internal bool TimeoutPossible {
321                         get { return (Interlocked.CompareExchange (ref timeoutPossible, 1, 1) == 1); }
322                 }
323 #endif
324                 internal void BeginTimeoutPossible ()
325                 {
326                         timeoutPossible = 1;
327                         timeoutBegin = DateTime.UtcNow.Ticks;
328                 }
329
330 #if !TARGET_J2EE
331                 internal void EndTimeoutPossible ()
332                 {
333                         Interlocked.CompareExchange (ref timeoutPossible, 0, 1);
334                 }
335                 
336                 internal void TryWaitForTimeout () 
337                 {
338                         while (Interlocked.CompareExchange (ref timeoutPossible, 1, 1) == 1) {
339                                 Thread.Sleep (500);
340                         }
341                 }
342 #endif
343
344                 internal bool CheckIfTimeout (DateTime dt)
345                 {
346                         TimeSpan ts = new TimeSpan (dt.Ticks - timeoutBegin);
347                         return (ts > ConfigTimeout);
348                 }
349
350                 internal TimeSpan ConfigTimeout {
351                         get {
352                                 if (configTimeout == null) {
353                                         HttpRuntimeConfig config = (HttpRuntimeConfig)
354                                                                 GetConfig ("system.web/httpRuntime");
355                                         configTimeout = new TimeSpan (0, 0, config.ExecutionTimeout);
356                                 }
357
358                                 return (TimeSpan) configTimeout;
359                         }
360                         set {
361                                 configTimeout = value;
362                         }
363                 }
364                 
365                 internal string ErrorPage {
366                         get { return errorPage; }
367                         set { errorPage = value; }
368                 }
369                 
370                 internal void SetSession (HttpSessionState session)
371                 {
372                         _oSession = session;
373                 }
374                 
375                 public void AddError (Exception errorInfo)
376                 {
377                         if (_arrExceptions == null)
378                                 _arrExceptions = new ArrayList ();
379
380                         _arrExceptions.Add (errorInfo);
381                 }
382
383                 public void ClearError ()
384                 {
385                         _arrExceptions = null;
386                 }
387
388                 public object GetConfig (string name)
389                 {
390                         return WebConfigurationSettings.GetConfig (name, this);
391                 }
392
393                 public static object GetAppConfig (string name)
394                 {
395                         return WebConfigurationSettings.GetConfig (name);
396                 }
397
398                 object IServiceProvider.GetService (Type service)
399                 {
400                         if (service == typeof (HttpWorkerRequest)) 
401                                 return _oWorkerRequest;
402
403                         if (service == typeof (HttpRequest))
404                                 return Request;
405
406                         if (service == typeof (HttpResponse))
407                                 return Response;
408
409                         if (service == typeof (HttpApplication))
410                                 return ApplicationInstance;
411
412                         if (service == typeof (HttpApplicationState))
413                                 return Application;
414
415                         if (service == typeof (HttpSessionState))
416                                 return Session;
417
418                         if (service == typeof (HttpServerUtility))
419                                 return Server;
420
421                         return null;
422                 }
423
424                 public void RewritePath (string path)
425                 {
426                         //LAMESPEC: they say that they throw a ArgumentNullException, however,
427                         // i get a NullReferenceException...
428                         if (path == null)
429                                 throw new ArgumentNullException ("path");
430
431                         string query;
432                         int qmark = path.IndexOf ('?');
433                         if (qmark == -1 || qmark + 1 >= path.Length) {
434                                 query = null;
435                         } else {
436                                 query = path.Substring (qmark + 1);
437                                 path = path.Substring (0, qmark);
438                         }
439
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.");
444
445                         Request.SetCurrentExePath (path);
446                         Request.QueryStringRaw = query;
447                 }
448
449 #if NET_1_1
450                 public void RewritePath (string filePath, string pathInfo, string queryString)
451                 {
452                         RewritePath (filePath + "?" + queryString);
453                         Request.SetPathInfo (pathInfo);
454                 }
455 #endif
456
457 #if NET_2_0
458                 internal System.Web.UI.Page LastPage {
459                         get { return lastPage; }
460                         set { lastPage = value; }
461                 }
462 #endif
463
464         }
465 }
466