using System.Text;
using System.Globalization;
using System.Collections;
+using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Web.Caching;
using System.Web.Configuration;
using System.Web.UI;
+using System.Web.Util;
using System.Threading;
#if NET_2_0 && !TARGET_JVM
static QueueManager queue_manager { get { return _runtime._queue_manager; } }
static TraceManager trace_manager { get { return _runtime._trace_manager; } }
static Cache cache { get { return _runtime._cache; } }
+ static Cache internalCache { get { return _runtime._internalCache; } }
static WaitCallback do_RealProcessRequest;
-
+
QueueManager _queue_manager;
TraceManager _trace_manager;
Cache _cache;
+ Cache _internalCache;
static HttpRuntime ()
{
public HttpRuntime ()
{
+ WebConfigurationManager.Init ();
_queue_manager = new QueueManager ();
_trace_manager = new TraceManager ();
_cache = new Cache ();
+ _internalCache = new Cache();
}
- static private HttpRuntime _runtime {
+ static private HttpRuntime _runtimeInstance {
get {
- HttpRuntime runtime = (HttpRuntime)AppDomain.CurrentDomain.GetData("HttpRuntime");
+ HttpRuntime runtime = (HttpRuntime) AppDomain.CurrentDomain.GetData ("HttpRuntime");
if (runtime == null)
- lock (typeof(HttpRuntime)) {
- runtime = (HttpRuntime)AppDomain.CurrentDomain.GetData("HttpRuntime");
+ lock (typeof (HttpRuntime)) {
+ runtime = (HttpRuntime) AppDomain.CurrentDomain.GetData ("HttpRuntime");
if (runtime == null) {
- runtime = new HttpRuntime();
- AppDomain.CurrentDomain.SetData("HttpRuntime", runtime);
+ runtime = new HttpRuntime ();
+ AppDomain.CurrentDomain.SetData ("HttpRuntime", runtime);
}
}
return runtime;
}
}
+ static private HttpRuntime _runtime
+ {
+ get
+ {
+ if (HttpContext.Current != null)
+ return HttpContext.Current.HttpRuntimeInstance;
+ else
+ return _runtimeInstance;
+ }
+ }
#else
static QueueManager queue_manager;
static TraceManager trace_manager;
static TimeoutManager timeout_manager;
static Cache cache;
+ static Cache internalCache;
static WaitCallback do_RealProcessRequest;
-
+ static Exception initialException;
+ static bool firstRun;
+
+#if NET_2_0
+ static bool assemblyMappingEnabled;
+ static object assemblyMappingLock = new object ();
+#endif
+
static HttpRuntime ()
{
+ firstRun = true;
+#if NET_2_0
+ try {
+ WebConfigurationManager.Init ();
+ } catch (Exception ex) {
+ initialException = ex;
+ }
+
+#endif
+
+ // The classes in whose constructors exceptions may be thrown, should be handled the same way QueueManager
+ // and TraceManager are below. The constructors themselves MUST NOT throw any exceptions - we MUST be sure
+ // the objects are created here. The exceptions will be dealt with below, in RealProcessRequest.
queue_manager = new QueueManager ();
+ if (queue_manager.HasException)
+ initialException = queue_manager.InitialException;
+
trace_manager = new TraceManager ();
+ if (trace_manager.HasException)
+ initialException = trace_manager.InitialException;
+
timeout_manager = new TimeoutManager ();
cache = new Cache ();
+ internalCache = new Cache ();
do_RealProcessRequest = new WaitCallback (RealProcessRequest);
}
#endif
public HttpRuntime ()
{
+
}
#endif
-
+
#region AppDomain handling
//
// http://radio.weblogs.com/0105476/stories/2002/07/12/executingAspxPagesWithoutAWebServer.html
public static string BinDirectory {
get {
- string dirname = Path.Combine (AppDomainAppPath, "bin");
+ string dirname = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath;
if (SecurityManager.SecurityEnabled) {
new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
}
}
}
+ internal static Cache InternalCache {
+ get {
+ return internalCache;
+ }
+ }
+
public static string ClrInstallDirectory {
get {
string dirname = Path.GetDirectoryName (typeof (Object).Assembly.Location);
public static string MachineConfigurationDirectory {
get {
-#if NET_2_0
- string dirname = Path.GetDirectoryName (WebConfigurationManager.OpenMachineConfiguration().FilePath);
-#else
- string dirname = Path.GetDirectoryName (WebConfigurationSettings.MachineConfigPath);
-#endif
+ string dirname = Path.GetDirectoryName (ICalls.GetMachineConfigPath ());
if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
}
}
}
+
[SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
public static void Close ()
{
return;
ThreadPool.QueueUserWorkItem (do_RealProcessRequest, request);
}
-
+
static void RealProcessRequest (object o)
{
HttpContext context = new HttpContext ((HttpWorkerRequest) o);
HttpContext.Current = context;
+ bool error = false;
+#if !TARGET_J2EE
+ if (firstRun) {
+ firstRun = false;
+ if (initialException != null) {
+ FinishWithException ((HttpWorkerRequest) o, new HttpException ("Initial exception", initialException));
+ error = true;
+ }
+ }
+#endif
+
//
// Get application instance (create or reuse an instance of the correct class)
//
HttpApplication app = null;
- bool error = false;
- try {
- app = HttpApplicationFactory.GetApplication (context);
- } catch (Exception e) {
- FinishWithException ((HttpWorkerRequest) o, new HttpException ("", e));
- error = true;
+ if (!error) {
+ try {
+ app = HttpApplicationFactory.GetApplication (context);
+ } catch (Exception e) {
+ FinishWithException ((HttpWorkerRequest) o, new HttpException ("", e));
+ error = true;
+ }
}
-
+
if (error) {
context.Request.ReleaseResources ();
context.Response.ReleaseResources ();
HttpContext.Current = null;
} else {
context.ApplicationInstance = app;
-
-#if NET_2_0 && !TARGET_JVM
- //
- // Compile the local resources, if any
- //
- AppLocalResourcesCompiler alrc = new AppLocalResourcesCompiler();
- alrc.Compile();
-#endif
//
// Ask application to service the request
{
queue_manager.Dispose ();
// This will call Session_End if needed.
- Cache.InvokePrivateCallbacks ();
+ InternalCache.InvokePrivateCallbacks ();
// Kill our application.
HttpApplicationFactory.Dispose ();
ThreadPool.QueueUserWorkItem (new WaitCallback (DoUnload), null);
}
-#if TARGET_J2EE // No unload support for appdomains under Grasshopper
static void DoUnload (object state)
{
- }
+ if (Environment.GetEnvironmentVariable ("MONO_ASPNET_NODELETE") == null)
+ System.Web.Hosting.ApplicationHost.ClearDynamicBaseDirectory (
+ AppDomain.CurrentDomain.SetupInformation.DynamicBase
+ );
+#if TARGET_J2EE
+ // No unload support for appdomains under Grasshopper
#else
- static void DoUnload (object state)
- {
AppDomain.Unload (AppDomain.CurrentDomain);
- }
#endif
+ }
static string content503 = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" +
"<html><head>\n<title>503 Server Unavailable</title>\n</head><body>\n" +
wr.CloseConnection ();
}
+#if NET_2_0 && !TARGET_J2EE
+ static internal void WritePreservationFile (Assembly asm, string genericNameBase)
+ {
+ if (asm == null)
+ throw new ArgumentNullException ("asm");
+ if (String.IsNullOrEmpty (genericNameBase))
+ throw new ArgumentNullException ("genericNameBase");
+
+ string compiled = Path.Combine (AppDomain.CurrentDomain.SetupInformation.DynamicBase,
+ genericNameBase + ".compiled");
+ PreservationFile pf = new PreservationFile ();
+ try {
+ pf.VirtualPath = String.Format ("/{0}/", genericNameBase);
+
+ AssemblyName an = asm.GetName ();
+ pf.Assembly = an.Name;
+ pf.ResultType = BuildResultTypeCode.TopLevelAssembly;
+ pf.Save (compiled);
+ } catch (Exception ex) {
+ throw new HttpException (
+ String.Format ("Failed to write preservation file {0}", genericNameBase + ".compiled"),
+ ex);
+ }
+ }
+
+ static Assembly ResolveAssemblyHandler(object sender, ResolveEventArgs e)
+ {
+ AssemblyName an = new AssemblyName (e.Name);
+ string dynamic_base = AppDomain.CurrentDomain.SetupInformation.DynamicBase;
+ string compiled = Path.Combine (dynamic_base, an.Name + ".compiled");
+
+ if (!File.Exists (compiled))
+ return null;
+
+ PreservationFile pf;
+ try {
+ pf = new PreservationFile (compiled);
+ } catch (Exception ex) {
+ throw new HttpException (
+ String.Format ("Failed to read preservation file {0}", an.Name + ".compiled"),
+ ex);
+ }
+
+ Assembly ret = null;
+ try {
+ string asmPath = Path.Combine (dynamic_base, pf.Assembly + ".dll");
+ ret = Assembly.LoadFrom (asmPath);
+ } catch (Exception) {
+ // ignore
+ }
+
+ return ret;
+ }
+
+ internal static void EnableAssemblyMapping (bool enable)
+ {
+ lock (assemblyMappingLock) {
+ if (assemblyMappingEnabled == enable)
+ return;
+ if (enable)
+ AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler (ResolveAssemblyHandler);
+ else
+ AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler (ResolveAssemblyHandler);
+ }
+ }
+#endif
+
internal static TraceManager TraceManager {
get {
return trace_manager;