Mark tests as not working under TARGET_JVM
[mono.git] / mcs / class / System.Web / System.Web / HttpContext.cs
1 //
2 // System.Web.HttpContext.cs 
3 //
4 // Author:
5 //      Miguel de Icaza (miguel@novell.com)
6 //      Gonzalo Paniagua Javier (gonzalo@novell.com)
7 //
8
9 //
10 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
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.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;
42 using System.Web.UI;
43 using System.Web.Util;
44 #if NET_2_0
45 using System.Collections.Generic;
46 using System.IO;
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;
52 #endif
53
54 namespace System.Web {
55         
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;
61                 HttpRequest request;
62                 HttpResponse response;
63                 HttpSessionState session_state;
64                 HttpServerUtility server;
65                 TraceContext trace_context;
66                 IHttpHandler handler;
67                 string error_page;
68                 bool skip_authorization = false;
69                 IPrincipal user;
70                 object errors;
71                 Hashtable items;
72                 object config_timeout;
73                 int timeout_possible;
74                 DateTime time_stamp = DateTime.UtcNow;
75 #if NET_2_0
76                 internal static Assembly AppGlobalResourcesAssembly;
77                 ProfileBase profile = null;
78                 LinkedList<IHttpHandler> handlers;
79 #endif
80
81                 public HttpContext (HttpWorkerRequest wr)
82                 {
83                         WorkerRequest = wr;
84                         request = new HttpRequest (WorkerRequest, this);
85                         response = new HttpResponse (WorkerRequest, this);
86                 }
87
88                 public HttpContext (HttpRequest request, HttpResponse response)
89                 {
90                         this.request = request;
91                         this.response = response;
92                         
93                 }
94
95                 public Exception [] AllErrors {
96                         get {
97                                 if (errors == null)
98                                         return null;
99
100                                 if (errors is Exception){
101                                         Exception [] all = new Exception [1];
102                                         all [0] = (Exception) errors;
103                                         return all;
104                                 } 
105                                 return (Exception []) (((ArrayList) errors).ToArray (typeof (Exception)));
106                         }
107                 }
108
109                 public HttpApplicationState Application {
110                         get {
111                                 return HttpApplicationFactory.ApplicationState;
112                         }
113                 }
114
115                 public HttpApplication ApplicationInstance {
116                         get {
117                                 return app_instance;
118                         }
119
120                         set {
121                                 app_instance = value;
122                         }
123                               
124                 }
125
126                 public Cache Cache {
127                         get {
128                                 return HttpRuntime.Cache;
129                         }
130                 }
131
132                 //
133                 // The "Current" property is set just after we have constructed it with 
134                 // the 'HttpContext (HttpWorkerRequest)' constructor.
135                 //
136 #if !TARGET_JVM // No remoting CallContext support in Grasshopper
137                 public static HttpContext Current {
138                         get {
139                                 return (HttpContext) CallContext.GetData ("c");
140                         }
141
142                         set {
143                                 CallContext.SetData ("c", value);
144                         }
145                 }
146 #endif
147
148                 public Exception Error {
149                         get {
150                                 if (errors == null || (errors is Exception))
151                                         return (Exception) errors;
152                                 return (Exception) (((ArrayList) errors) [0]);
153                         }
154                 }
155
156                 public IHttpHandler Handler {
157                         get {
158                                 return handler;
159                         }
160
161                         set {
162                                 handler = value;
163                         }
164                 }
165
166                 public bool IsCustomErrorEnabled {
167                         get {
168 #if NET_2_0
169                                 CustomErrorsSection cfg = (CustomErrorsSection) WebConfigurationManager.GetSection ("system.web/customErrors");
170 #else
171                                 CustomErrorsConfig cfg = null;
172                                 try {
173                                         cfg = (CustomErrorsConfig) GetConfig ("system.web/customErrors");
174                                 } catch {
175                                 }
176
177                                 if (cfg == null)
178                                         return false;
179 #endif
180
181                                 if (cfg.Mode == CustomErrorMode.On)
182                                         return true;
183
184                                 return (cfg.Mode == CustomErrorMode.RemoteOnly) && 
185                                         (Request.WorkerRequest.GetLocalAddress () != Request.UserHostAddress);
186                         }
187                 }
188 #if !TARGET_JVM
189                 public bool IsDebuggingEnabled {
190                         get {
191 #if NET_2_0
192                                 CompilationSection section = (CompilationSection) WebConfigurationManager.GetSection ("system.web/compilation");
193                                 return section.Debug;
194 #else
195                                 try {
196                                         return CompilationConfiguration.GetInstance (this).Debug;
197                                 } catch {
198                                         return false;
199                                 }
200 #endif
201                         }
202                 }
203 #endif
204                 public IDictionary Items {
205                         get {
206                                 if (items == null)
207                                         items = new Hashtable ();
208                                 return items;
209                         }
210                 }
211
212                 public HttpRequest Request {
213                         get {
214                                 return request;
215                         }
216                 }
217
218                 public HttpResponse Response {
219                         get {
220                                 return response;
221                         }
222                 }
223
224                 public HttpServerUtility Server {
225                         get {
226                                 if (server == null)
227                                         server = new HttpServerUtility (this);
228                                 return server;
229                         }
230                 }
231
232                 public HttpSessionState Session {
233                         get {
234                                 return session_state;
235                         }
236                 }
237
238                 public bool SkipAuthorization {
239                         get {
240                                 return skip_authorization;
241                         }
242
243                         [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
244                         set {
245                                 skip_authorization = value;
246                         }
247                 }
248
249                 public DateTime Timestamp {
250                         get {
251                                 return time_stamp.ToLocalTime ();
252                         }
253                 }
254                 
255                 public TraceContext Trace {
256                         get {
257                                 if (trace_context == null)
258                                         trace_context = new TraceContext (this);
259                                 return trace_context;
260                         }
261                 }
262
263                 public IPrincipal User {
264                         get {
265                                 return user;
266                         }
267
268                         [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
269                         set {
270                                 user = value;
271                         }
272                 }
273
274 #if NET_2_0             
275                 internal void PushHandler (IHttpHandler handler)
276                 {
277                         if (handler == null)
278                                 return;
279                         if (handlers == null)
280                                 handlers = new LinkedList <IHttpHandler> ();
281                         handlers.AddLast (handler);
282                 }
283
284                 internal void PopHandler ()
285                 {
286                         if (handlers == null || handlers.Count == 0)
287                                 return;
288                         handlers.RemoveLast ();
289                 }
290                 
291                 IHttpHandler GetCurrentHandler ()
292                 {
293                         if (handlers == null || handlers.Count == 0)
294                                 return null;
295                         
296                         return handlers.Last.Value;
297                 }
298
299                 IHttpHandler GetPreviousHandler ()
300                 {
301                         if (handlers == null || handlers.Count <= 1)
302                                 return null;
303                         LinkedListNode <IHttpHandler> previous = handlers.Last.Previous;
304                         if (previous != null)
305                                 return previous.Value;
306                         return null;
307                 }
308                 
309                 public IHttpHandler CurrentHandler {
310                         get { return GetCurrentHandler (); }
311                 }
312
313                 public IHttpHandler PreviousHandler {
314                         get { return GetPreviousHandler (); }
315                 }
316
317                 public ProfileBase Profile {
318                         get {
319                                 if (profile == null) {
320                                         if (Request.IsAuthenticated)
321                                                 profile = ProfileBase.Create (User.Identity.Name);
322                                         else
323                                                 profile = ProfileBase.Create (Request.AnonymousID, false);
324                                 }
325                                 return profile;
326                         }
327
328                         internal set {
329                                 profile = value;
330                         }
331                 }
332 #endif
333
334                 public void AddError (Exception errorInfo)
335                 {
336                         if (errors == null){
337                                 errors = errorInfo;
338                                 return;
339                         }
340                         ArrayList l;
341                         if (errors is Exception){
342                                 l = new ArrayList ();
343                                 l.Add (errors);
344                                 errors = l;
345                         } else 
346                                 l = (ArrayList) errors;
347                         l.Add (errorInfo);
348                 }
349
350                 internal void ClearError (Exception e)
351                 {
352                         if (errors == e)
353                                 errors = null;
354                 }
355
356                 public void ClearError ()
357                 {
358                         errors = null;
359                 }
360
361 #if NET_2_0
362                 [Obsolete ("use WebConfigurationManager.GetWebApplicationSection")]
363 #endif
364                 public static object GetAppConfig (string name)
365                 {
366                         object o = ConfigurationSettings.GetConfig (name);
367
368                         return o;
369                 }
370
371 #if NET_2_0
372                 [Obsolete ("see GetSection")]
373 #endif
374                 public object GetConfig (string name)
375                 {
376 #if NET_2_0
377                         return GetSection (name);
378 #else
379                         return WebConfigurationSettings.GetConfig (name, this);
380 #endif
381                 }
382
383 #if NET_2_0
384                 static object GetResourceObject (string classKey, string resourceKey, CultureInfo culture, Assembly assembly)
385                 {
386                         ResourceManager rm;
387                         try {
388                                 rm = new ResourceManager (classKey, assembly);
389                                 return rm.GetObject (resourceKey, culture);
390                         } catch (MissingManifestResourceException) {
391                                 throw;
392                         } catch (Exception ex) {
393                                 throw new HttpException ("Failed to retrieve the specified global resource object.", ex);
394                         }
395                 }
396                 
397                 public static object GetGlobalResourceObject (string classKey, string resourceKey)
398                 {
399                         return GetGlobalResourceObject (classKey, resourceKey, Thread.CurrentThread.CurrentUICulture);
400                 }
401
402                 public static object GetGlobalResourceObject (string classKey, string resourceKey, CultureInfo culture)
403                 {
404                         if (AppGlobalResourcesAssembly == null)
405                                 throw new MissingManifestResourceException ();
406                         return GetResourceObject ("Resources." + classKey, resourceKey, culture, AppGlobalResourcesAssembly);
407                 }
408
409                 public static object GetLocalResourceObject (string virtualPath, string resourceKey)
410                 {
411                         return GetLocalResourceObject (virtualPath, resourceKey, Thread.CurrentThread.CurrentUICulture);
412                 }
413
414                 public static object GetLocalResourceObject (string virtualPath, string resourceKey, CultureInfo culture)
415                 {
416                         if (!VirtualPathUtility.IsAbsolute (virtualPath))
417                                 throw new ArgumentException ("The specified virtualPath was not rooted.");
418                         
419                         string path = Path.GetDirectoryName (virtualPath);
420                         Assembly asm = AppResourcesCompiler.GetCachedLocalResourcesAssembly (path);
421                         if (asm == null) {
422                                 AppResourcesCompiler ac = new AppResourcesCompiler (path);
423                                 asm = ac.Compile ();
424                                 if (asm == null)
425                                         throw new MissingManifestResourceException ("A resource object was not found at the specified virtualPath.");
426                         }
427                         
428                         path = Path.GetFileName (virtualPath);
429                         return GetResourceObject ("Resources." + path, resourceKey, culture, asm);
430                 }
431
432                 public object GetSection (string name)
433                 {
434                         return WebConfigurationManager.GetSection (name);
435                 }
436 #endif
437                 object IServiceProvider.GetService (Type service)
438                 {
439                         if (service == typeof (HttpWorkerRequest))
440                                 return WorkerRequest;
441
442                         //
443                         // We return everything out of properties in case
444                         // they are dynamically computed in some form in the future.
445                         //
446                         if (service == typeof (HttpApplication))
447                                 return ApplicationInstance;
448
449                         if (service == typeof (HttpRequest))
450                                 return Request;
451
452                         if (service == typeof (HttpResponse))
453                                 return Response;
454
455                         if (service == typeof (HttpSessionState))
456                                 return Session;
457
458                         if (service == typeof (HttpApplicationState))
459                                 return Application;
460
461                         if (service == typeof (IPrincipal))
462                                 return User;
463
464                         if (service == typeof (Cache))
465                                 return Cache;
466
467                         if (service == typeof (HttpContext))
468                                 return Current;
469
470                         if (service == typeof (IHttpHandler))
471                                 return Handler;
472
473                         if (service == typeof (HttpServerUtility))
474                                 return Server;
475                         
476                         if (service == typeof (TraceContext))
477                                 return Trace;
478                         
479                         return null;
480                 }
481
482                 public void RewritePath (string path)
483                 {
484 #if NET_2_0
485                         RewritePath (path, true);
486 #else
487                         RewritePath (path, false);
488 #endif
489                 }
490
491                 public void RewritePath (string filePath, string pathInfo, string queryString)
492                 {
493                         RewritePath (filePath, pathInfo, queryString, false);
494                 }
495
496 #if NET_2_0
497                 public
498 #else
499                 internal
500 #endif
501                 void RewritePath (string path, bool rebaseClientPath)
502                 {
503                         int qmark = path.IndexOf ('?');
504                         if (qmark != -1)
505                                 RewritePath (path.Substring (0, qmark), "", path.Substring (qmark + 1), rebaseClientPath);
506                         else
507                                 RewritePath (path, null, null, rebaseClientPath);
508                 }
509
510 #if NET_2_0
511                 public
512 #else
513                 internal
514 #endif
515                 void RewritePath (string filePath, string pathInfo, string queryString, bool setClientFilePath)
516                 {
517                         filePath = UrlUtils.Combine (Request.BaseVirtualDir, filePath);
518                         if (!filePath.StartsWith (HttpRuntime.AppDomainAppVirtualPath))
519                                 throw new HttpException (404, "The virtual path '" + filePath +
520                                         "' maps to another application.");
521
522                         Request.SetCurrentExePath (filePath);
523                         // A null pathInfo or queryString is ignored and previous values remain untouched
524                         if (pathInfo != null)
525                                 Request.SetPathInfo (pathInfo);
526
527                         if (queryString != null)
528                                 Request.QueryStringRaw = queryString;
529 #if NET_2_0
530                         if (setClientFilePath)
531                                 Request.SetFilePath (filePath);
532 #endif
533                 }
534
535 #region internals
536                 
537                 internal void SetSession (HttpSessionState state)
538                 {
539                         session_state = state;
540                 }
541
542                 // URL of a page used for error redirection.
543                 internal string ErrorPage {
544                         get {
545                                 return error_page;
546                         }
547
548                         set {
549                                 error_page = value;
550                         }
551                 }
552
553                 internal TimeSpan ConfigTimeout {
554                         get {
555                                 if (config_timeout == null) {
556 #if NET_2_0
557                                         HttpRuntimeSection section = (HttpRuntimeSection)WebConfigurationManager.GetSection ("system.web/httpRuntime");
558                                         config_timeout = section.ExecutionTimeout;
559 #else
560                                         HttpRuntimeConfig config = (HttpRuntimeConfig)
561                                                                 GetConfig ("system.web/httpRuntime");
562                                         config_timeout = new TimeSpan (0, 0, config.ExecutionTimeout);
563 #endif
564                                 }
565
566                                 return (TimeSpan) config_timeout;
567                         }
568
569                         set {
570                                 config_timeout = value;
571                         }
572                 }
573
574                 internal bool CheckIfTimeout (DateTime t)
575                 {
576                         if (Interlocked.CompareExchange (ref timeout_possible, 0, 0) == 0)
577                                 return false;
578
579                         TimeSpan ts = t - time_stamp;
580                         return (ts > ConfigTimeout);
581                 }
582
583                 internal bool TimeoutPossible {
584                         get { return (Interlocked.CompareExchange (ref timeout_possible, 1, 1) == 1); }
585                 }
586
587                 internal void BeginTimeoutPossible ()
588                 {
589                         timeout_possible = 1;
590                 }
591
592                 internal void EndTimeoutPossible ()
593                 {
594                         Interlocked.CompareExchange (ref timeout_possible, 0, 1);
595                 }
596 #endregion
597
598 #if NET_2_0
599                 Page last_page;
600                 
601                 internal Page LastPage {
602                         get {
603                                 return last_page;
604                         }
605
606                         set {
607                                 last_page = value;
608                         }
609                 }
610 #endif
611         }
612 }