+//
+// System.Web.HttpRuntime.cs
//
-// System.Web.HttpRuntime
+// Author:
+// Miguel de Icaza (miguel@novell.com)
//
-// Authors:
-// Patrik Torstensson (ptorsten@hotmail.com)
-// Gaurav Vaish (gvaish@iitk.ac.in)
-// Gonzalo Paniagua Javier (gonzalo@ximian.com)
//
-
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
-using System.Collections;
+
+//
+// TODO: Call HttpRequest.CloseInputStream when we finish a request, as we are using the IntPtr stream.
+//
using System.IO;
using System.Text;
+using System.Globalization;
+using System.Collections;
+using System.Reflection;
using System.Security;
using System.Security.Permissions;
-using System.Threading;
+using System.Web.Caching;
using System.Web.Configuration;
using System.Web.UI;
using System.Web.Util;
-using System.Web.Caching;
+using System.Threading;
-namespace System.Web {
+#if NET_2_0 && !TARGET_JVM
+using System.CodeDom.Compiler;
+using System.Web.Compilation;
+#endif
+namespace System.Web {
+
+ // CAS - no InheritanceDemand here as the class is sealed
+ [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
public sealed class HttpRuntime {
-
- // Security permission helper objects
- private static IStackWalk appPathDiscoveryStackWalk;
- private static IStackWalk ctrlPrincipalStackWalk;
- private static IStackWalk sensitiveInfoStackWalk;
- private static IStackWalk unmgdCodeStackWalk;
- private static IStackWalk unrestrictedStackWalk;
- private static IStackWalk reflectionStackWalk;
-
- private static HttpRuntime _runtime;
- private static string appDomainAppId;
- private static string appDomainId;
- private static string appDomainAppPath;
- private static string appDomainAppVirtualPath;
- private Cache _cache;
-
- private int _activeRequests;
- private HttpWorkerRequest.EndOfSendNotification _endOfSendCallback;
- private AsyncCallback _handlerCallback;
- private WaitCallback unloadDomainCallback;
-
- private bool _firstRequestStarted;
- //private bool _firstRequestExecuted;
-
- private Exception _initError;
- private TimeoutManager timeoutManager;
- private QueueManager queueManager;
- private TraceManager traceManager;
- private WaitCallback doRequestCallback;
- private int pendingCallbacks;
+#if TARGET_J2EE
+ 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 ()
{
- _runtime = new HttpRuntime ();
- _runtime.Init();
+ do_RealProcessRequest = new WaitCallback (RealProcessRequest);
}
public HttpRuntime ()
{
- doRequestCallback = new WaitCallback (DoRequest);
- }
-
- static internal object CreateInternalObject(Type type) {
- return Activator.CreateInstance(type, true);
- }
-
- private void Init ()
- {
- try {
- _cache = new Cache ();
- timeoutManager = new TimeoutManager ();
-
- _endOfSendCallback = new HttpWorkerRequest.EndOfSendNotification (OnEndOfSend);
- _handlerCallback = new AsyncCallback (OnHandlerReady);
- unloadDomainCallback = new WaitCallback (DoUnload);
- AppDomain.CurrentDomain.DomainUnload += new EventHandler (OnDomainUnload);
- }
- catch (Exception error) {
- _initError = error;
- }
- }
-
- private void OnFirstRequestStart(HttpContext context) {
- if (_initError != null)
- throw _initError;
-
- try {
- WebConfigurationSettings.Init (context);
- traceManager = new TraceManager ();
- queueManager = new QueueManager ();
- } catch (Exception e) {
- _initError = e;
- }
-
- // If we got an error during init, throw to client now..
- if (null != _initError)
- throw _initError;
+ WebConfigurationManager.Init ();
+ _queue_manager = new QueueManager ();
+ _trace_manager = new TraceManager ();
+ _cache = new Cache ();
+ _internalCache = new Cache();
}
- /* Not used
- private void OnFirstRequestEnd() {
- }
- */
-
- private void OnHandlerReady(IAsyncResult ar) {
- HttpContext context = (HttpContext) ar.AsyncState;
- try {
- IHttpAsyncHandler handler = context.AsyncHandler;
-
- try {
- handler.EndProcessRequest(ar);
- }
- catch (Exception error) {
- context.AddError(error);
- }
- }
- finally {
- context.AsyncHandler = null;
- }
-
- FinishRequest(context, context.Error);
- }
-
- private void OnEndOfSend(HttpWorkerRequest request, object data) {
- HttpContext context = (HttpContext) data;
-
- context.Request.Dispose();
- context.Response.Dispose();
- }
-
- internal void FinishRequest(HttpContext context, Exception error) {
- if (error == null) {
- try {
- context.Response.FlushAtEndOfRequest();
- } catch (Exception obj) {
- error = obj;
- }
- }
-
- HttpWorkerRequest request = context.WorkerRequest;
- if (null != error) {
- WebTrace.WriteLine (error.ToString ());
-
- // We don't want the 'headers sent error'
- context.Response.SetHeadersSent (false);
- context.Response.Clear ();
- context.Response.ClearHeaders ();
-
- if (!(error is HttpException)) {
- error = new HttpException (String.Empty, error);
- context.Response.StatusCode = 500;
- } else {
- context.Response.StatusCode = ((HttpException) error).GetHttpCode ();
- }
-
- if (!RedirectCustomError (context))
- context.Response.Write (((HttpException) error).GetHtmlErrorMessage ());
-
- context.Response.FinalFlush ();
- }
-
- /*
- * This is not being used. OnFirstRequestEnd is empty.
- if (!_firstRequestExecuted) {
- lock (this) {
- if (!_firstRequestExecuted) {
- _firstRequestExecuted = true;
- OnFirstRequestEnd();
+ static private HttpRuntime _runtimeInstance {
+ get {
+ HttpRuntime runtime = (HttpRuntime) AppDomain.CurrentDomain.GetData ("HttpRuntime");
+ if (runtime == null)
+ lock (typeof (HttpRuntime)) {
+ runtime = (HttpRuntime) AppDomain.CurrentDomain.GetData ("HttpRuntime");
+ if (runtime == null) {
+ runtime = new HttpRuntime ();
+ AppDomain.CurrentDomain.SetData ("HttpRuntime", runtime);
+ }
}
- }
+ return runtime;
}
- */
-
- Interlocked.Decrement(ref _activeRequests);
-
- if (null != request)
- request.EndOfRequest();
-
- TryExecuteQueuedRequests ();
}
-
- bool RedirectCustomError (HttpContext context)
+ static private HttpRuntime _runtime
{
- if (!context.IsCustomErrorEnabled)
- return false;
-
- CustomErrorsConfig config = null;
- try {
- config = (CustomErrorsConfig) context.GetConfig ("system.web/customErrors");
- } catch { }
-
- if (config == null) {
- if (context.ErrorPage != null)
- return context.Response.RedirectCustomError (context.ErrorPage);
-
- return false;
+ get
+ {
+ if (HttpContext.Current != null)
+ return HttpContext.Current.HttpRuntimeInstance;
+ else
+ return _runtimeInstance;
}
-
- string redirect = config [context.Response.StatusCode];
- if (redirect == null) {
- redirect = context.ErrorPage;
- if (redirect == null)
- redirect = config.DefaultRedirect;
- }
-
- if (redirect == null)
- return false;
-
- return context.Response.RedirectCustomError (redirect);
- }
-
- internal static void FinishUnavailable (HttpWorkerRequest wr)
- {
- HttpContext context = new HttpContext (wr);
- HttpException exception = new HttpException (503, "Service unavailable");
- Interlocked.Increment (ref _runtime._activeRequests);
- context.Response.InitializeWriter ();
- _runtime.FinishRequest (context, exception);
- }
-
- void DoUnload (object state)
- {
- try {
- AppDomain.Unload (AppDomain.CurrentDomain);
- } catch {}
- }
-
- internal void Dispose() {
- WaitForRequests (2000);
- queueManager.Dispose (); // Send a 503 to all queued requests
- queueManager = null;
-
- _cache = null;
- HttpApplicationFactory.EndApplication ();
- }
-
- void OnDomainUnload (object o, EventArgs args)
- {
- HttpApplicationFactory.EndApplication ();
- }
-
- internal void ByeByeDomain ()
- {
- HttpApplicationFactory.EndApplication ();
- ThreadPool.QueueUserWorkItem (unloadDomainCallback);
- }
-
- internal void WaitForRequests(int ms) {
- DateTime timeout = DateTime.Now.AddMilliseconds(ms);
-
- do {
- if (Interlocked.CompareExchange (ref _activeRequests, 0, 0) == 0)
- return;
-
- Thread.Sleep (100);
- } while (timeout > DateTime.Now);
}
-
- internal void InternalExecuteRequest (HttpWorkerRequest request)
+#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 ()
{
- IHttpHandler handler;
- IHttpAsyncHandler async_handler;
-
- HttpContext context = new HttpContext(request);
-
- request.SetEndOfSendNotification(_endOfSendCallback, context);
-
- Interlocked.Increment(ref _activeRequests);
-
+ firstRun = true;
+#if NET_2_0
try {
- if (!_firstRequestStarted) {
- lock (this) {
- if (!_firstRequestStarted) {
- OnFirstRequestStart(context);
- _firstRequestStarted = true;
- }
- }
- }
-
- // This *must* be done after the configuration is initialized.
- context.Response.InitializeWriter ();
- handler = HttpApplicationFactory.GetInstance(context);
- if (null == handler)
- throw new HttpException(FormatResourceString("unable_to_create_app"));
-
- if (handler is IHttpAsyncHandler) {
- async_handler = (IHttpAsyncHandler) handler;
-
- context.AsyncHandler = async_handler;
- async_handler.BeginProcessRequest(context, _handlerCallback, context);
- } else {
- handler.ProcessRequest(context);
- FinishRequest(context, null);
- }
+ WebConfigurationManager.Init ();
+ } catch (Exception ex) {
+ initialException = ex;
}
- catch (Exception error) {
- context.Response.InitializeWriter ();
- FinishRequest(context, error);
- }
- }
+
+#endif
- void DoRequest (object o)
- {
- Interlocked.Decrement (ref pendingCallbacks);
- InternalExecuteRequest ((HttpWorkerRequest) o);
- }
-
- void TryExecuteQueuedRequests ()
- {
- // Wait for pending jobs to start
- if (Interlocked.CompareExchange (ref pendingCallbacks, 3, 3) >= 3)
- return;
+ // 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;
- HttpWorkerRequest wr = queueManager.GetNextRequest (null);
- if (wr == null)
- return;
+ trace_manager = new TraceManager ();
+ if (trace_manager.HasException)
+ initialException = trace_manager.InitialException;
- Interlocked.Increment (ref pendingCallbacks);
- ThreadPool.QueueUserWorkItem (doRequestCallback, wr);
- TryExecuteQueuedRequests ();
+ timeout_manager = new TimeoutManager ();
+ cache = new Cache ();
+ internalCache = new Cache ();
+ do_RealProcessRequest = new WaitCallback (RealProcessRequest);
}
- public static void ProcessRequest (HttpWorkerRequest request)
+#if ONLY_1_1
+ [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
+#endif
+ public HttpRuntime ()
{
- if (request == null)
- throw new ArgumentNullException ("request");
- QueueManager mgr = _runtime.queueManager;
- if (_runtime._firstRequestStarted && mgr != null) {
- request = mgr.GetNextRequest (request);
- // We're busy, return immediately
- if (request == null)
- return;
- }
-
- _runtime.InternalExecuteRequest (request);
- }
-
-#if NET_1_1
- public static void UnloadAppDomain ()
- {
- _runtime.ByeByeDomain ();
}
#endif
- public static Cache Cache {
- get {
- return _runtime._cache;
- }
- }
-
+
+#region AppDomain handling
+ //
+ // http://radio.weblogs.com/0105476/stories/2002/07/12/executingAspxPagesWithoutAWebServer.html
+ //
public static string AppDomainAppId {
+ [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
get {
- if (appDomainAppId == null)
- appDomainAppId = (string) AppDomain.CurrentDomain.GetData (".appId");
-
- return appDomainAppId;
+ //
+ // This value should not change across invocations
+ //
+ string dirname = (string) AppDomain.CurrentDomain.GetData (".appId");
+ if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
+ new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+ }
+ return dirname;
}
}
+ // Physical directory for the application
public static string AppDomainAppPath {
get {
- if (appDomainAppPath == null)
- appDomainAppPath = (string) AppDomain.CurrentDomain.GetData (".appPath");
-
- return appDomainAppPath;
+ string dirname = (string) AppDomain.CurrentDomain.GetData (".appPath");
+ if (SecurityManager.SecurityEnabled) {
+ new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+ }
+ return dirname;
}
}
public static string AppDomainAppVirtualPath {
get {
- if (appDomainAppVirtualPath == null)
- appDomainAppVirtualPath = (string) AppDomain.CurrentDomain.GetData (".appVPath");
-
- return appDomainAppVirtualPath;
+ return (string) AppDomain.CurrentDomain.GetData (".appVPath");
}
}
public static string AppDomainId {
+ [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
get {
- if (appDomainId == null)
- appDomainId = (string) AppDomain.CurrentDomain.GetData (".domainId");
-
- return appDomainId;
+ return (string) AppDomain.CurrentDomain.GetData (".domainId");
}
}
public static string AspInstallDirectory {
get {
- return ICalls.GetMachineInstallDirectory ();
+ string dirname = (string) AppDomain.CurrentDomain.GetData (".hostingInstallDir");
+ if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
+ new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+ }
+ return dirname;
}
}
-
+#endregion
+
public static string BinDirectory {
get {
- return Path.Combine (AppDomainAppPath, "bin");
+ string dirname = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath;
+ if (SecurityManager.SecurityEnabled) {
+ new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+ }
+ return dirname;
+ }
+ }
+
+ public static Cache Cache {
+ get {
+ return cache;
}
}
+ internal static Cache InternalCache {
+ get {
+ return internalCache;
+ }
+ }
+
public static string ClrInstallDirectory {
get {
- return ICalls.GetMachineInstallDirectory ();
+ string dirname = Path.GetDirectoryName (typeof (Object).Assembly.Location);
+ if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
+ new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+ }
+ return dirname;
}
}
public static string CodegenDir {
get {
- return AppDomain.CurrentDomain.SetupInformation.DynamicBase;
+ string dirname = AppDomain.CurrentDomain.SetupInformation.DynamicBase;
+ if (SecurityManager.SecurityEnabled) {
+ new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+ }
+ return dirname;
}
}
+ [MonoTODO]
public static bool IsOnUNCShare {
+ [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)]
get {
- // IsUnc broken under unix?
-#if NET_2_0
- return (Environment.OSVersion.Platform != PlatformID.Unix &&
-#else
- return (!((int) Environment.OSVersion.Platform == 128) &&
-#endif
- new Uri ("file://" + ClrInstallDirectory).IsUnc);
+ throw new NotImplementedException ();
}
}
public static string MachineConfigurationDirectory {
get {
- return Path.GetDirectoryName (WebConfigurationSettings.MachineConfigPath);
- }
- }
-
- internal static TimeoutManager TimeoutManager {
- get {
- return HttpRuntime._runtime.timeoutManager;
+ string dirname = Path.GetDirectoryName (ICalls.GetMachineConfigPath ());
+ if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
+ new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+ }
+ return dirname;
}
}
- internal static TraceManager TraceManager {
- get {
- return HttpRuntime._runtime.traceManager;
- }
- }
-
+
+ [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
public static void Close ()
{
- _runtime.Dispose ();
+ // Remove all items from cache.
}
- internal static string FormatResourceString (string key)
+ static void QueuePendingRequests ()
{
- return GetResourceString (key);
+ HttpWorkerRequest request = queue_manager.GetNextRequest (null);
+ if (request == null)
+ return;
+ ThreadPool.QueueUserWorkItem (do_RealProcessRequest, request);
}
-
- internal static string FormatResourceString (string key, string arg0)
+
+ static void RealProcessRequest (object o)
{
- /*string format = GetResourceString (key);
+ 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
- if (format == null)
- return null;
+ //
+ // Get application instance (create or reuse an instance of the correct class)
+ //
+ HttpApplication app = null;
+ if (!error) {
+ try {
+ app = HttpApplicationFactory.GetApplication (context);
+ } catch (Exception e) {
+ FinishWithException ((HttpWorkerRequest) o, new HttpException ("", e));
+ error = true;
+ }
+ }
- return String.Format (format, arg0);
- */
- return String.Format ("{0}: {1}", key, arg0);
+ if (error) {
+ context.Request.ReleaseResources ();
+ context.Response.ReleaseResources ();
+ HttpContext.Current = null;
+ } else {
+ context.ApplicationInstance = app;
+
+ //
+ // Ask application to service the request
+ //
+ IHttpAsyncHandler ihah = app;
+
+ IAsyncResult appiar = ihah.BeginProcessRequest (context, new AsyncCallback (request_processed), context);
+ ihah.EndProcessRequest (appiar);
+
+ HttpApplicationFactory.Recycle (app);
+ }
+
+ QueuePendingRequests ();
}
+
+ //
+ // ProcessRequest method is executed in the AppDomain of the application
+ //
+ // Observations:
+ // ProcessRequest does not guarantee that `wr' will be processed synchronously,
+ // the request can be queued and processed later.
+ //
+ [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
+ public static void ProcessRequest (HttpWorkerRequest wr)
+ {
+ if (wr == null)
+ throw new ArgumentNullException ("wr");
+ //
+ // Queue our request, fetch the next available one from the queue
+ //
+ HttpWorkerRequest request = queue_manager.GetNextRequest (wr);
+ if (request == null)
+ return;
- [MonoTODO ("FormatResourceString (string, string, string)")]
- internal static string FormatResourceString (string key, string arg0, string type) {
- return String.Format ("{0}: {1} {2}", key, arg0, type);
+ RealProcessRequest (request);
}
- [MonoTODO ("FormatResourceString (string, string, string, string)")]
- internal static string FormatResourceString (string key, string arg0,
- string arg1, string arg2)
+ //
+ // Callback to be invoked by IHttpAsyncHandler.BeginProcessRequest
+ //
+ static void request_processed (IAsyncResult iar)
{
- return String.Format ("{0}: {1} {2} {3}", key, arg0, arg1, arg2);
+ HttpContext context = (HttpContext) iar.AsyncState;
+
+ context.Request.ReleaseResources ();
+ context.Response.ReleaseResources ();
}
- [MonoTODO ("FormatResourceString (string, string[]")]
- internal static string FormatResourceString (string key, string[] args)
+ //
+ // Called when we are shutting down or we need to reload an application
+ // that has been modified (touch global.asax)
+ //
+ [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
+ public static void UnloadAppDomain ()
{
- //StringBuilder sb = new StringBuilder ();
- /*sb.AppendFormat ("{0}: ", key);
- foreach (string s in args)
- sb.AppendFormat ("{0} ", s);
-
- if (sb.Length > 0)
- sb.Length--;
- return sb.ToString ();*/
- string s = key + ": ";
- if (args != null)
- foreach (string k in args)
- s += k + " ";
- return s;
+ //
+ // TODO: call ReleaseResources
+ //
+ ThreadPool.QueueUserWorkItem (new WaitCallback (ShutdownAppDomain), null);
}
- private static string GetResourceString (string key) {
- return _runtime.GetResourceStringFromResourceManager (key);
+ //
+ // Shuts down the AppDomain
+ //
+ static void ShutdownAppDomain (object args)
+ {
+ queue_manager.Dispose ();
+ // This will call Session_End if needed.
+ InternalCache.InvokePrivateCallbacks ();
+ // Kill our application.
+ HttpApplicationFactory.Dispose ();
+ ThreadPool.QueueUserWorkItem (new WaitCallback (DoUnload), null);
}
- [MonoTODO ("GetResourceStringFromResourceManager (string)")]
- private string GetResourceStringFromResourceManager (string key) {
- return key;
+ 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
+ AppDomain.Unload (AppDomain.CurrentDomain);
+#endif
}
- #region Security Internal Methods (not impl)
- [MonoTODO ("Get Application path from the appdomain object")]
- internal static IStackWalk AppPathDiscovery {
- get {
- if (appPathDiscoveryStackWalk == null) {
- appPathDiscoveryStackWalk = new FileIOPermission (
- FileIOPermissionAccess.PathDiscovery, "<apppath>");
- }
- return appPathDiscoveryStackWalk;
- }
- }
+ 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" +
+ "<h1>Server Unavailable</h1>\n" +
+ "</body></html>\n";
- internal static IStackWalk ControlPrincipal {
- get {
- if (ctrlPrincipalStackWalk == null) {
- ctrlPrincipalStackWalk = new SecurityPermission (
- SecurityPermissionFlag.ControlPrincipal);
- }
- return ctrlPrincipalStackWalk;
+ static void FinishWithException (HttpWorkerRequest wr, HttpException e)
+ {
+ int code = e.GetHttpCode ();
+ wr.SendStatus (code, HttpWorkerRequest.GetStatusDescription (code));
+ wr.SendUnknownResponseHeader ("Connection", "close");
+ wr.SendUnknownResponseHeader ("Date", DateTime.Now.ToUniversalTime ().ToString ("r"));
+ Encoding enc = Encoding.ASCII;
+ wr.SendUnknownResponseHeader ("Content-Type", "text/html; charset=" + enc.WebName);
+ string msg = e.GetHtmlErrorMessage ();
+ byte [] contentBytes = enc.GetBytes (msg);
+ wr.SendUnknownResponseHeader ("Content-Length", contentBytes.Length.ToString ());
+ wr.SendResponseFromMemory (contentBytes, contentBytes.Length);
+ wr.FlushResponse (true);
+ wr.CloseConnection ();
+ }
+
+ //
+ // This is called from the QueueManager if a request
+ // can not be processed (load, no resources, or
+ // appdomain unload).
+ //
+ static internal void FinishUnavailable (HttpWorkerRequest wr)
+ {
+ wr.SendStatus (503, "Service unavailable");
+ wr.SendUnknownResponseHeader ("Connection", "close");
+ wr.SendUnknownResponseHeader ("Date", DateTime.Now.ToUniversalTime ().ToString ("r"));
+ Encoding enc = Encoding.ASCII;
+ wr.SendUnknownResponseHeader ("Content-Type", "text/html; charset=" + enc.WebName);
+ byte [] contentBytes = enc.GetBytes (content503);
+ wr.SendUnknownResponseHeader ("Content-Length", contentBytes.Length.ToString ());
+ wr.SendResponseFromMemory (contentBytes, contentBytes.Length);
+ wr.FlushResponse (true);
+ 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");
- internal static IStackWalk Reflection {
- get {
- if (reflectionStackWalk == null) {
- reflectionStackWalk = new ReflectionPermission (
- ReflectionPermissionFlag.TypeInformation |
- ReflectionPermissionFlag.MemberAccess);
- }
- return reflectionStackWalk;
+ 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 IStackWalk SensitiveInformation {
- get {
- if (sensitiveInfoStackWalk == null) {
- sensitiveInfoStackWalk = new EnvironmentPermission (
- PermissionState.Unrestricted);
- }
- return sensitiveInfoStackWalk;
+
+ 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);
}
}
-
- internal static IStackWalk UnmanagedCode {
+#endif
+
+ internal static TraceManager TraceManager {
get {
- if (unmgdCodeStackWalk == null) {
- unmgdCodeStackWalk = new SecurityPermission (
- SecurityPermissionFlag.UnmanagedCode);
- }
- return unmgdCodeStackWalk;
+ return trace_manager;
}
}
- internal static IStackWalk Unrestricted {
+#if !TARGET_JVM
+ internal static TimeoutManager TimeoutManager {
get {
- if (unrestrictedStackWalk == null) {
- unrestrictedStackWalk = new PermissionSet (
- PermissionState.Unrestricted);
- }
- return unrestrictedStackWalk;
+ return timeout_manager;
}
}
-
- internal static IStackWalk FileReadAccess (string file)
- {
- return new FileIOPermission (FileIOPermissionAccess.Read, file);
- }
-
- internal static IStackWalk PathDiscoveryAccess (string path)
- {
- return new FileIOPermission (FileIOPermissionAccess.PathDiscovery, path);
- }
- #endregion
+#endif
}
}