New tests.
[mono.git] / mcs / class / System.Web / System.Web / HttpRuntime.cs
1 //
2 // System.Web.HttpRuntime.cs 
3 // 
4 // Authors:
5 //      Miguel de Icaza (miguel@novell.com)
6 //      Marek Habersack <mhabersack@novell.com>
7 //
8 //
9 // Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 //
32 // TODO: Call HttpRequest.CloseInputStream when we finish a request, as we are using the IntPtr stream.
33 //
34 using System.IO;
35 using System.Text;
36 using System.Globalization;
37 using System.Collections;
38 using System.Reflection;
39 using System.Security;
40 using System.Security.Permissions;
41 using System.Web.Caching;
42 using System.Web.Configuration;
43 using System.Web.Management;
44 using System.Web.UI;
45 using System.Web.Util;
46 #if MONOWEB_DEP
47 using Mono.Web.Util;
48 #endif
49 using System.Threading;
50 #if TARGET_J2EE
51 using Mainsoft.Web;
52 #else
53 using System.CodeDom.Compiler;
54 using System.Web.Compilation;
55 #endif
56
57 namespace System.Web
58 {       
59         // CAS - no InheritanceDemand here as the class is sealed
60         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
61         public sealed class HttpRuntime
62         {
63                 static bool domainUnloading;
64                 
65 #if TARGET_J2EE
66                 static QueueManager queue_manager { get { return _runtime._queue_manager; } }
67                 static TraceManager trace_manager { get { return _runtime._trace_manager; } }
68                 static Cache cache { get { return _runtime._cache; } }
69                 static Cache internalCache { get { return _runtime._internalCache; } }
70                 static WaitCallback do_RealProcessRequest;
71                 
72                 QueueManager _queue_manager;
73                 TraceManager _trace_manager;
74                 Cache _cache;
75                 Cache _internalCache;
76
77                 public HttpRuntime ()
78                 {
79                         WebConfigurationManager.Init ();
80                         _queue_manager = new QueueManager ();
81                         _trace_manager = new TraceManager ();
82                         _cache = new Cache ();
83                         _internalCache = new Cache();
84                         _internalCache.DependencyCache = _cache;
85                 }
86
87                 static HttpRuntime _runtimeInstance {
88                         get {
89                                 HttpRuntime runtime = (HttpRuntime) AppDomain.CurrentDomain.GetData ("HttpRuntime");
90                                 if (runtime == null)
91                                         lock (typeof (HttpRuntime)) {
92                                                 runtime = (HttpRuntime) AppDomain.CurrentDomain.GetData ("HttpRuntime");
93                                                 if (runtime == null) {
94                                                         runtime = new HttpRuntime ();
95                                                         AppDomain.CurrentDomain.SetData ("HttpRuntime", runtime);
96                                                 }
97                                         }
98                                 return runtime;
99                         }
100                 }
101                 static HttpRuntime _runtime
102                 {
103                         get
104                         {
105                                 if (HttpContext.Current != null)
106                                         return HttpContext.Current.HttpRuntimeInstance;
107                                 else
108                                         return _runtimeInstance;
109                         }
110                 }
111 #else
112                 static QueueManager queue_manager;
113                 static TraceManager trace_manager;
114                 static Cache cache;
115                 static Cache internalCache;
116                 static WaitCallback do_RealProcessRequest;
117                 static Exception initialException;
118                 static bool firstRun;
119                 static bool assemblyMappingEnabled;
120                 static object assemblyMappingLock = new object ();
121                 static object appOfflineLock = new object ();
122                 
123                 public HttpRuntime ()
124                 {
125
126                 }
127 #endif
128
129                 static HttpRuntime ()
130                 {
131 #if !TARGET_J2EE
132                         firstRun = true;
133                         try {
134                                 WebConfigurationManager.Init ();
135 #if MONOWEB_DEP
136                                 SettingsMappingManager.Init ();
137 #endif
138                         } catch (Exception ex) {
139                                 initialException = ex;
140                         }
141
142                         // The classes in whose constructors exceptions may be thrown, should be handled the same way QueueManager
143                         // and TraceManager are below. The constructors themselves MUST NOT throw any exceptions - we MUST be sure
144                         // the objects are created here. The exceptions will be dealt with below, in RealProcessRequest.
145                         queue_manager = new QueueManager ();
146                         if (queue_manager.HasException)
147                                 initialException = queue_manager.InitialException;
148
149                         trace_manager = new TraceManager ();
150                         if (trace_manager.HasException)
151                                         initialException = trace_manager.InitialException;
152
153                         cache = new Cache ();
154                         internalCache = new Cache ();
155                         internalCache.DependencyCache = internalCache;
156 #endif
157                         do_RealProcessRequest = new WaitCallback (RealProcessRequest);
158                 }
159                 
160 #region AppDomain handling
161                 internal static bool DomainUnloading {
162                         get { return domainUnloading; }
163                 }
164                 
165                 //
166                 // http://radio.weblogs.com/0105476/stories/2002/07/12/executingAspxPagesWithoutAWebServer.html
167                 //
168                 public static string AppDomainAppId {
169                         [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
170                         get {
171                                 //
172                                 // This value should not change across invocations
173                                 //
174                                 string dirname = (string) AppDomain.CurrentDomain.GetData (".appId");
175                                 if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
176                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
177                                 }
178                                 return dirname;
179                         }
180                 }
181
182                 // Physical directory for the application
183                 public static string AppDomainAppPath {
184                         get {
185                                 string dirname = (string) AppDomain.CurrentDomain.GetData (".appPath");
186                                 if (SecurityManager.SecurityEnabled) {
187                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
188                                 }
189                                 return dirname;
190                         }
191                 }
192
193                 public static string AppDomainAppVirtualPath {
194                         get {
195                                 return (string) AppDomain.CurrentDomain.GetData (".appVPath");
196                         }
197                 }
198
199                 public static string AppDomainId {
200                         [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
201                         get {
202                                 return (string) AppDomain.CurrentDomain.GetData (".domainId");
203                         }
204                 }
205
206                 public static string AspInstallDirectory {
207                         get {
208                                 string dirname = (string) AppDomain.CurrentDomain.GetData (".hostingInstallDir");
209                                 if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
210                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
211                                 }
212                                 return dirname;
213                         }
214                 }
215 #endregion
216
217                 static string _actual_bin_directory;
218                 public static string BinDirectory {
219                         get {
220                                 if (_actual_bin_directory == null) {
221                                         string[] parts = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath.Split (';');
222                                         string mypath = AppDomainAppPath;
223                                         string tmp;
224                                         
225                                         foreach (string p in parts) {
226                                                 tmp = Path.Combine (mypath, p);
227                                                 if (Directory.Exists (tmp)) {
228                                                         _actual_bin_directory = tmp;
229                                                         break;
230                                                 }
231                                         }
232
233                                         if (_actual_bin_directory == null)
234                                                 _actual_bin_directory = Path.Combine (mypath, "bin");
235
236                                         if (_actual_bin_directory [_actual_bin_directory.Length - 1] != Path.DirectorySeparatorChar)
237                                                 _actual_bin_directory += Path.DirectorySeparatorChar;
238                                 }
239                                 
240                                 if (SecurityManager.SecurityEnabled)
241                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, _actual_bin_directory).Demand ();
242
243                                 return _actual_bin_directory;
244                         }
245                 }
246
247                 public static Cache Cache {
248                         get {
249                                 return cache;
250                         }
251                 }
252
253                 internal static Cache InternalCache {
254                         get {
255                                 return internalCache;
256                         }
257                 }
258                 
259                 public static string ClrInstallDirectory {
260                         get {
261                                 string dirname = Path.GetDirectoryName (typeof (Object).Assembly.Location);
262                                 if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
263                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
264                                 }
265                                 return dirname;
266                         }
267                 }
268
269                 public static string CodegenDir {
270                         get {
271                                 string dirname = AppDomain.CurrentDomain.SetupInformation.DynamicBase;
272                                 if (SecurityManager.SecurityEnabled) {
273                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
274                                 }
275                                 return dirname;
276                         }
277                 }
278
279                 public static bool IsOnUNCShare {
280                         [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)]
281                         get {
282                                 return RuntimeHelpers.IsUncShare;
283                         }
284                 }
285
286                 public static string MachineConfigurationDirectory {
287                         get {
288                                 string dirname = Path.GetDirectoryName (ICalls.GetMachineConfigPath ());
289                                 if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
290                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
291                                 }
292                                 return dirname;
293                         }
294                 }
295
296                 
297                 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
298                 public static void Close ()
299                 {
300                         // Remove all items from cache.
301                 }
302
303                 internal static HttpWorkerRequest QueuePendingRequest (bool started_internally)
304                 {
305                         HttpWorkerRequest next = queue_manager.GetNextRequest (null);
306                         if (next == null)
307                                 return null;
308
309                         if (!started_internally) {
310                                 next.StartedInternally = true;
311                                 ThreadPool.QueueUserWorkItem (do_RealProcessRequest, next);
312                                 return null;
313                         }
314                         return next;
315                 }
316
317 #if !TARGET_J2EE
318                 static readonly string[] app_offline_files = {"app_offline.htm", "App_Offline.htm", "APP_OFFLINE.HTM"};
319                 static string app_offline_file;
320                 
321                 static bool AppIsOffline (HttpContext context)
322                 {
323                         if (!HttpApplicationFactory.ApplicationDisabled || app_offline_file == null)
324                                 return false;
325
326                         HttpResponse response = context.Response;
327                         response.Clear ();
328                         response.ContentType = "text/html";
329                         response.ExpiresAbsolute = DateTime.UtcNow;
330                         response.StatusCode = 503;
331                         response.TransmitFile (app_offline_file, true);
332                         
333                         context.Request.ReleaseResources ();
334                         context.Response.ReleaseResources ();
335                         HttpContext.Current = null;
336                         HttpApplication.requests_total_counter.Increment ();
337                         
338                         return true;
339                 }
340
341                 static void AppOfflineFileRenamed (object sender, RenamedEventArgs args)
342                 {
343                         AppOfflineFileChanged (sender, args);
344                 }
345
346                 static void AppOfflineFileChanged (object sender, FileSystemEventArgs args)
347                 {
348                         lock (appOfflineLock) {
349                                 bool offline;
350                                 
351                                 switch (args.ChangeType) {
352                                         case WatcherChangeTypes.Created:
353                                         case WatcherChangeTypes.Changed:
354                                                 offline = true;
355                                                 break;
356
357                                         case WatcherChangeTypes.Deleted:
358                                                 offline = false;
359                                                 break;
360
361                                         case WatcherChangeTypes.Renamed:
362                                                 RenamedEventArgs rargs = args as RenamedEventArgs;
363
364                                                 if (rargs != null &&
365                                                     String.Compare (rargs.Name, "app_offline.htm", StringComparison.OrdinalIgnoreCase) == 0)
366                                                         offline = true;
367                                                 else
368                                                         offline = false;
369                                                 break;
370
371                                         default:
372                                                 offline = false;
373                                                 break;
374                                 }
375                                 SetOfflineMode (offline, args.FullPath);
376                         }
377                 }
378
379                 static void SetOfflineMode (bool offline, string filePath)
380                 {
381                         if (!offline) {
382                                 app_offline_file = null;
383                                 if (HttpApplicationFactory.ApplicationDisabled)
384                                         HttpRuntime.UnloadAppDomain ();
385                         } else {
386                                 app_offline_file = filePath;
387                                 HttpApplicationFactory.DisableWatchers ();
388                                 HttpApplicationFactory.ApplicationDisabled = true;
389                                 InternalCache.InvokePrivateCallbacks ();
390                                 HttpApplicationFactory.Dispose ();
391                         }
392                 }
393                 
394                 static void SetupOfflineWatch ()
395                 {
396                         lock (appOfflineLock) {
397                                 FileSystemEventHandler seh = new FileSystemEventHandler (AppOfflineFileChanged);
398                                 RenamedEventHandler reh = new RenamedEventHandler (AppOfflineFileRenamed);
399
400                                 string app_dir = AppDomainAppPath;
401                                 ArrayList watchers = new ArrayList ();
402                                 FileSystemWatcher watcher;
403                                 string offlineFile = null, tmp;
404                                 
405                                 foreach (string f in app_offline_files) {
406                                         watcher = new FileSystemWatcher ();
407                                         watcher.Path = Path.GetDirectoryName (app_dir);
408                                         watcher.Filter = Path.GetFileName (f);
409                                         watcher.NotifyFilter |= NotifyFilters.Size;
410                                         watcher.Deleted += seh;
411                                         watcher.Changed += seh;
412                                         watcher.Created += seh;
413                                         watcher.Renamed += reh;
414                                         watcher.EnableRaisingEvents = true;
415                                         
416                                         watchers.Add (watcher);
417
418                                         tmp = Path.Combine (app_dir, f);
419                                         if (File.Exists (tmp))
420                                                 offlineFile = tmp;
421                                 }
422
423                                 if (offlineFile != null)
424                                         SetOfflineMode (true, offlineFile);
425                         }
426                 }
427 #endif
428                 
429                 static void RealProcessRequest (object o)
430                 {
431                         HttpWorkerRequest req = (HttpWorkerRequest) o;
432                         bool started_internally = req.StartedInternally;
433                         do {
434                                 Process (req);
435                                 req = QueuePendingRequest (started_internally);
436                         } while (started_internally && req != null);
437                 }
438
439                 static void Process (HttpWorkerRequest req)
440                 {
441 #if TARGET_J2EE
442                         HttpContext context = HttpContext.Current;
443                         if (context == null)
444                                 context = new HttpContext (req);
445                         else
446                                 context.SetWorkerRequest (req);
447 #else
448                         HttpContext context = new HttpContext (req);
449 #endif
450                         HttpContext.Current = context;
451                         bool error = false;
452 #if !TARGET_J2EE
453                         if (firstRun) {
454                                 SetupOfflineWatch ();
455                                 firstRun = false;
456                                 if (initialException != null) {
457                                         FinishWithException (req, HttpException.NewWithCode ("Initial exception", initialException, WebEventCodes.RuntimeErrorRequestAbort));
458                                         error = true;
459                                 }
460                         }
461
462                         if (AppIsOffline (context))
463                                 return;
464 #endif
465                         
466                         //
467                         // Get application instance (create or reuse an instance of the correct class)
468                         //
469                         HttpApplication app = null;
470                         if (!error) {
471                                 try {
472                                         app = HttpApplicationFactory.GetApplication (context);
473                                 } catch (Exception e) {
474                                         FinishWithException (req, HttpException.NewWithCode (String.Empty, e, WebEventCodes.RuntimeErrorRequestAbort));
475                                         error = true;
476                                 }
477                         }
478                         
479                         if (error) {
480                                 context.Request.ReleaseResources ();
481                                 context.Response.ReleaseResources ();
482                                 HttpContext.Current = null;
483                         } else {
484                                 context.ApplicationInstance = app;
485
486                                 //
487                                 // Ask application to service the request
488                                 //
489                                 
490 #if TARGET_J2EE
491                                 IHttpAsyncHandler ihah = app;
492                                 if (context.Handler == null)
493                                         ihah.BeginProcessRequest (context, new AsyncCallback (request_processed), context);
494                                 else
495                                         app.Tick ();
496                                 //ihh.ProcessRequest (context);
497                                 IHttpExtendedHandler extHandler = context.Handler as IHttpExtendedHandler;
498                                 if (extHandler != null && !extHandler.IsCompleted)
499                                         return;
500                                 if (context.Error is UnifyRequestException)
501                                         return;
502
503                                 ihah.EndProcessRequest (null);
504 #else
505                                 IHttpHandler ihh = app;
506 //                              IAsyncResult appiar = ihah.BeginProcessRequest (context, new AsyncCallback (request_processed), context);
507 //                              ihah.EndProcessRequest (appiar);
508                                 ihh.ProcessRequest (context);
509 #endif
510
511                                 HttpApplicationFactory.Recycle (app);
512                         }
513                 }
514                 
515                 //
516                 // ProcessRequest method is executed in the AppDomain of the application
517                 //
518                 // Observations:
519                 //    ProcessRequest does not guarantee that `wr' will be processed synchronously,
520                 //    the request can be queued and processed later.
521                 //
522                 [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
523                 public static void ProcessRequest (HttpWorkerRequest wr)
524                 {
525                         if (wr == null)
526                                 throw new ArgumentNullException ("wr");
527                         //
528                         // Queue our request, fetch the next available one from the queue
529                         //
530                         HttpWorkerRequest request = queue_manager.GetNextRequest (wr);
531                         if (request == null)
532                                 return;
533
534                         QueuePendingRequest (false);
535                         RealProcessRequest (request);
536                 }
537
538 #if TARGET_J2EE
539                 //
540                 // Callback to be invoked by IHttpAsyncHandler.BeginProcessRequest
541                 //
542                 static void request_processed (IAsyncResult iar)
543                 {
544                         HttpContext context = (HttpContext) iar.AsyncState;
545
546                         context.Request.ReleaseResources ();
547                         context.Response.ReleaseResources ();
548                 }
549 #endif
550                 
551 #if TARGET_JVM
552                 [MonoNotSupported ("UnloadAppDomain is not supported")]
553                 public static void UnloadAppDomain ()
554                 {
555                         throw new NotImplementedException ("UnloadAppDomain is not supported");
556                 }
557 #else
558                 //
559                 // Called when we are shutting down or we need to reload an application
560                 // that has been modified (touch global.asax) 
561                 //
562                 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
563                 public static void UnloadAppDomain ()
564                 {
565                         //
566                         // TODO: call ReleaseResources
567                         //
568                         domainUnloading = true;
569                         ThreadPool.QueueUserWorkItem (new WaitCallback (ShutdownAppDomain), null);
570                 }
571 #endif
572                 //
573                 // Shuts down the AppDomain
574                 //
575                 static void ShutdownAppDomain (object args)
576                 {
577                         queue_manager.Dispose ();
578                         // This will call Session_End if needed.
579                         InternalCache.InvokePrivateCallbacks ();
580                         // Kill our application.
581                         HttpApplicationFactory.Dispose ();
582                         ThreadPool.QueueUserWorkItem (new WaitCallback (DoUnload), null);
583                 }
584
585                 static void DoUnload (object state)
586                 {
587 #if TARGET_J2EE
588                         // No unload support for appdomains under Grasshopper
589 #else
590                         AppDomain.Unload (AppDomain.CurrentDomain);
591 #endif
592                 }
593
594                 static string content503 = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" +
595                         "<html><head>\n<title>503 Server Unavailable</title>\n</head><body>\n" +
596                         "<h1>Server Unavailable</h1>\n" +
597                         "</body></html>\n";
598
599                 static void FinishWithException (HttpWorkerRequest wr, HttpException e)
600                 {
601                         int code = e.GetHttpCode ();
602                         wr.SendStatus (code, HttpWorkerRequest.GetStatusDescription (code));
603                         wr.SendUnknownResponseHeader ("Connection", "close");
604                         Encoding enc = Encoding.ASCII;
605                         wr.SendUnknownResponseHeader ("Content-Type", "text/html; charset=" + enc.WebName);
606                         string msg = e.GetHtmlErrorMessage ();
607                         byte [] contentBytes = enc.GetBytes (msg);
608                         wr.SendUnknownResponseHeader ("Content-Length", contentBytes.Length.ToString ());
609                         wr.SendResponseFromMemory (contentBytes, contentBytes.Length);
610                         wr.FlushResponse (true);
611                         wr.CloseConnection ();
612                         HttpApplication.requests_total_counter.Increment ();
613                 }
614
615                 //
616                 // This is called from the QueueManager if a request
617                 // can not be processed (load, no resources, or
618                 // appdomain unload).
619                 //
620                 static internal void FinishUnavailable (HttpWorkerRequest wr)
621                 {
622                         wr.SendStatus (503, "Service unavailable");
623                         wr.SendUnknownResponseHeader ("Connection", "close");
624                         Encoding enc = Encoding.ASCII;
625                         wr.SendUnknownResponseHeader ("Content-Type", "text/html; charset=" + enc.WebName);
626                         byte [] contentBytes = enc.GetBytes (content503);
627                         wr.SendUnknownResponseHeader ("Content-Length", contentBytes.Length.ToString ());
628                         wr.SendResponseFromMemory (contentBytes, contentBytes.Length);
629                         wr.FlushResponse (true);
630                         wr.CloseConnection ();
631                         HttpApplication.requests_total_counter.Increment ();
632                 }
633
634 #if !TARGET_J2EE
635                 static internal void WritePreservationFile (Assembly asm, string genericNameBase)
636                 {
637                         if (asm == null)
638                                 throw new ArgumentNullException ("asm");
639                         if (String.IsNullOrEmpty (genericNameBase))
640                                 throw new ArgumentNullException ("genericNameBase");
641
642                         string compiled = Path.Combine (AppDomain.CurrentDomain.SetupInformation.DynamicBase,
643                                                         genericNameBase + ".compiled");
644                         PreservationFile pf = new PreservationFile ();
645                         try {
646                                 pf.VirtualPath = String.Concat ("/", genericNameBase, "/");
647
648                                 AssemblyName an = asm.GetName ();
649                                 pf.Assembly = an.Name;
650                                 pf.ResultType = BuildResultTypeCode.TopLevelAssembly;
651                                 pf.Save (compiled);
652                         } catch (Exception ex) {
653                                 throw new HttpException (
654                                         String.Format ("Failed to write preservation file {0}", genericNameBase + ".compiled"),
655                                         ex);
656                         }
657                 }
658                 
659                 static Assembly ResolveAssemblyHandler(object sender, ResolveEventArgs e)
660                 {
661                         AssemblyName an = new AssemblyName (e.Name);
662                         string dynamic_base = AppDomain.CurrentDomain.SetupInformation.DynamicBase;
663                         string compiled = Path.Combine (dynamic_base, an.Name + ".compiled");
664
665                         if (!File.Exists (compiled))
666                                 return null;
667
668                         PreservationFile pf;
669                         try {
670                                 pf = new PreservationFile (compiled);
671                         } catch (Exception ex) {
672                                 throw new HttpException (
673                                         String.Format ("Failed to read preservation file {0}", an.Name + ".compiled"),
674                                         ex);
675                         }
676                         
677                         Assembly ret = null;
678                         try {
679                                 string asmPath = Path.Combine (dynamic_base, pf.Assembly + ".dll");
680                                 ret = Assembly.LoadFrom (asmPath);
681                         } catch (Exception) {
682                                 // ignore
683                         }
684                         
685                         return ret;
686                 }
687                 
688                 internal static void EnableAssemblyMapping (bool enable)
689                 {
690                         lock (assemblyMappingLock) {
691                                 if (assemblyMappingEnabled == enable)
692                                         return;
693                                 if (enable)
694                                         AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler (ResolveAssemblyHandler);
695                                 else
696                                         AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler (ResolveAssemblyHandler);
697                                 assemblyMappingEnabled = enable;
698                         }
699                 }
700 #endif // #if !TARGET_J2EE
701                 
702                 internal static TraceManager TraceManager {
703                         get {
704                                 return trace_manager;
705                         }
706                 }
707         }
708 }