X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Web%2FSystem.Web%2FHttpApplicationFactory.cs;h=d9260af0cf209b75aa05515358e92de6dafa8253;hb=a77d9eca1990b55115c66a2ae7acecf47f9cce97;hp=1151cb1caee6909110a1944e760c9c3dd384f7fd;hpb=30c28c41d7859b7de6ecd7afb652468517048d12;p=mono.git diff --git a/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs b/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs index 1151cb1caee..d9260af0cf2 100644 --- a/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs +++ b/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs @@ -45,6 +45,8 @@ using System.CodeDom.Compiler; namespace System.Web { class HttpApplicationFactory { + object this_lock = new object (); + // Initialized in InitType #if TARGET_J2EE static HttpApplicationFactory theFactory { @@ -67,8 +69,6 @@ namespace System.Web { #else static HttpApplicationFactory theFactory = new HttpApplicationFactory(); #endif - - MethodInfo session_end; bool needs_init = true; bool app_start_needed = true; @@ -77,6 +77,11 @@ namespace System.Web { Hashtable app_event_handlers; static ArrayList watchers = new ArrayList(); static object watchers_lock = new object(); + static bool app_shutdown = false; +#if NET_2_0 + static bool app_disabled = false; + static string[] app_browsers_files = new string[0]; +#endif Stack available = new Stack (); Stack available_for_end = new Stack (); @@ -123,22 +128,48 @@ namespace System.Web { list.Add (method); } + + ArrayList GetMethodsDeep (Type type) + { + ArrayList al = new ArrayList (); + MethodInfo[] methods = type.GetMethods (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy); + al.AddRange (methods); + + Type t = type.BaseType; + while (t != null) { + methods = t.GetMethods (BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); + al.AddRange (methods); + t = t.BaseType; + } + + return al; + } Hashtable GetApplicationTypeEvents (Type type) { - lock (this) { + lock (this_lock) { if (app_event_handlers != null) return app_event_handlers; app_event_handlers = new Hashtable (); - BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | - BindingFlags.Instance | BindingFlags.Static; - - MethodInfo [] methods = type.GetMethods (flags); - foreach (MethodInfo m in methods) { - if (m.DeclaringType != typeof (HttpApplication) && IsEventHandler (m)) + ArrayList methods = GetMethodsDeep (type); + Hashtable used = null; + MethodInfo m; + string mname; + + foreach (object o in methods) { + m = o as MethodInfo; + if (m.DeclaringType != typeof (HttpApplication) && IsEventHandler (m)) { + mname = m.ToString (); + if (used == null) + used = new Hashtable (); + else if (used.ContainsKey (mname)) + continue; + used.Add (mname, m); AddEvent (m, app_event_handlers); + } } + used = null; } return app_event_handlers; @@ -146,7 +177,7 @@ namespace System.Web { Hashtable GetApplicationTypeEvents (HttpApplication app) { - lock (this) { + lock (this_lock) { if (app_event_handlers != null) return app_event_handlers; @@ -175,7 +206,9 @@ namespace System.Web { context.ApplicationInstance = app; app.SetContext (context); object [] args = new object [] {app, EventArgs.Empty}; + app.InApplicationStart = true; FireEvent ("Application_Start", app, args); + app.InApplicationStart = false; return app; } @@ -186,7 +219,8 @@ namespace System.Web { HttpApplication app = (HttpApplication) Activator.CreateInstance (app_type, true); FireEvent ("Application_End", app, new object [] {new object (), EventArgs.Empty}); - app.Dispose (); + app.DisposeInternal (); + app_type = null; } // @@ -204,7 +238,10 @@ namespace System.Web { watcher.Path = Path.GetFullPath (Path.GetDirectoryName (file)); watcher.Filter = Path.GetFileName (file); - + + // This will enable the Modify flag for Linux/inotify + watcher.NotifyFilter |= NotifyFilters.Size; + watcher.Changed += hnd; watcher.Created += hnd; watcher.Deleted += hnd; @@ -265,12 +302,19 @@ namespace System.Web { int length = method.GetParameters ().Length; if (length == 0) { - NoParamsInvoker npi = new NoParamsInvoker (app, method.Name); + NoParamsInvoker npi = new NoParamsInvoker (app, method); evt.AddEventHandler (target, npi.FakeDelegate); } else { evt.AddEventHandler (target, Delegate.CreateDelegate ( - evt.EventHandlerType, app, method.Name)); + evt.EventHandlerType, app, +#if NET_2_0 + method +#else + method.Name +#endif + )); } + } internal static void InvokeSessionEnd (object state) @@ -342,14 +386,14 @@ namespace System.Web { void InitType (HttpContext context) { - lock (this) { + lock (this_lock) { if (!needs_init) return; #if NET_2_0 try { #endif - string physical_app_path = context.Request.PhysicalApplicationPath; + string physical_app_path = HttpRuntime.AppDomainAppPath; string app_file = null; app_file = Path.Combine (physical_app_path, "Global.asax"); @@ -366,40 +410,51 @@ namespace System.Web { #if NET_2_0 && !TARGET_J2EE AppResourcesCompiler ac = new AppResourcesCompiler (context); ac.Compile (); - - // Todo: Process App_WebResources here - + +#if WEBSERVICES_DEP + AppWebReferencesCompiler awrc = new AppWebReferencesCompiler (); + awrc.Compile (); +#endif + // Todo: Generate profile properties assembly from Web.config here - // Todo: Compile code from App_Code here AppCodeCompiler acc = new AppCodeCompiler (); acc.Compile (); + + // Note whether there are any App_Browsers/*.browser files. If there + // are we will be using *.browser files for sniffing in addition to browscap.ini + string app_browsers_path = Path.Combine (physical_app_path, "App_Browsers"); + app_browsers_files = new string[0]; + if (Directory.Exists (app_browsers_path)) { + app_browsers_files = Directory.GetFiles (app_browsers_path, "*.browser"); + } #endif if (app_file != null) { #if TARGET_J2EE - app_type = System.Web.J2EE.PageMapper.GetObjectType(app_file); + app_file = System.Web.Util.UrlUtils.ResolveVirtualPathFromAppAbsolute("~/" + Path.GetFileName(app_file)); + app_type = System.Web.J2EE.PageMapper.GetObjectType(context, app_file); +#else +#if NET_2_0 + app_type = BuildManager.GetCompiledType ("~/" + Path.GetFileName (app_file)); #else app_type = ApplicationFileParser.GetCompiledApplicationType (app_file, context); +#endif +#endif if (app_type == null) { string msg = String.Format ("Error compiling application file ({0}).", app_file); throw new ApplicationException (msg); } -#endif } else { app_type = typeof (System.Web.HttpApplication); app_state = new HttpApplicationState (); } - if (app_file != null) - WatchLocationForRestart(app_file); - - if (File.Exists(Path.Combine(physical_app_path, "Web.config"))) - WatchLocationForRestart("Web.config"); - else if (File.Exists(Path.Combine(physical_app_path, "web.config"))) - WatchLocationForRestart("web.config"); - else if (File.Exists(Path.Combine(physical_app_path, "Web.Config"))) - WatchLocationForRestart("Web.Config"); + WatchLocationForRestart("Global.asax"); + WatchLocationForRestart("global.asax"); + WatchLocationForRestart("Web.config"); + WatchLocationForRestart("web.config"); + WatchLocationForRestart("Web.Config"); needs_init = false; #if NET_2_0 } catch (Exception) { @@ -426,6 +481,10 @@ namespace System.Web { // internal static HttpApplication GetApplication (HttpContext context) { +#if TARGET_J2EE + if (context.ApplicationInstance!=null) + return context.ApplicationInstance; +#endif HttpApplicationFactory factory = theFactory; HttpApplication app = null; if (factory.app_start_needed){ @@ -435,12 +494,17 @@ namespace System.Web { factory.InitType (context); lock (factory) { if (factory.app_start_needed) { - WatchLocationForRestart (AppDomain.CurrentDomain.SetupInformation.PrivateBinPath, - "*.dll"); + foreach (string dir in HttpApplication.BinDirs) + WatchLocationForRestart (dir, "*.dll"); #if NET_2_0 - WatchLocationForRestart ("App_Code", ""); - WatchLocationForRestart ("App_Browsers", ""); - WatchLocationForRestart ("App_GlobalResources", ""); + // Restart if the App_* directories are created... + WatchLocationForRestart (".", "App_Code"); + WatchLocationForRestart (".", "App_Browsers"); + WatchLocationForRestart (".", "App_GlobalResources"); + // ...or their contents is changed. + WatchLocationForRestart ("App_Code", "*", true); + WatchLocationForRestart ("App_Browsers", "*"); + WatchLocationForRestart ("App_GlobalResources", "*"); #endif app = factory.FireOnAppStart (context); factory.app_start_needed = false; @@ -498,26 +562,34 @@ namespace System.Web { internal static bool ContextAvailable { get { return theFactory != null && !theFactory.app_start_needed; } } - - internal static bool WatchLocationForRestart(string filter) + + + internal static bool WatchLocationForRestart (string filter) { - return WatchLocationForRestart("", filter); + return WatchLocationForRestart ("", filter, false); } - - internal static bool WatchLocationForRestart(string virtualPath, string filter) + + internal static bool WatchLocationForRestart (string virtualPath, string filter) + { + return WatchLocationForRestart (virtualPath, filter, false); + } + + internal static bool WatchLocationForRestart(string virtualPath, string filter, bool watchSubdirs) { // map the path to the physical one string physicalPath = HttpRuntime.AppDomainAppPath; physicalPath = Path.Combine(physicalPath, virtualPath); - - if (Directory.Exists(physicalPath) || File.Exists(physicalPath)) { - physicalPath = Path.Combine(physicalPath, filter); - + bool isDir = Directory.Exists(physicalPath); + bool isFile = isDir ? false : File.Exists(physicalPath); + + if (isDir || isFile) { // create the watcher FileSystemEventHandler fseh = new FileSystemEventHandler(OnFileChanged); RenamedEventHandler reh = new RenamedEventHandler(OnFileRenamed); - FileSystemWatcher watcher = CreateWatcher(physicalPath, fseh, reh); - + FileSystemWatcher watcher = CreateWatcher(Path.Combine(physicalPath, filter), fseh, reh); + if (isDir) + watcher.IncludeSubdirectories = watchSubdirs; + lock (watchers_lock) { watchers.Add(watcher); } @@ -527,6 +599,57 @@ namespace System.Web { } } +#if NET_2_0 + internal static bool ApplicationDisabled { + get { return app_disabled; } + set { app_disabled = value; } + } + + internal static string[] AppBrowsersFiles { + get { return app_browsers_files; } + } + + static System.Web.Configuration.nBrowser.Build capabilities_processor = null; + static object capabilities_processor_lock = new object(); + internal static System.Web.Configuration.ICapabilitiesProcess CapabilitiesProcessor { + get { + lock (capabilities_processor_lock) { + if (capabilities_processor == null) { + capabilities_processor = new System.Web.Configuration.nBrowser.Build(); + string machine_browsers_path = Path.Combine (HttpRuntime.MachineConfigurationDirectory, "Browsers"); + if (Directory.Exists (machine_browsers_path)) { + string[] machine_browsers_files + = Directory.GetFiles (machine_browsers_path, "*.browser"); + foreach (string f in machine_browsers_files) { + capabilities_processor.AddBrowserFile(f); + } + } + foreach (string f in app_browsers_files) { + capabilities_processor.AddBrowserFile(f); + } + } + } + return capabilities_processor; + } + } +#endif + + internal static void DisableWatchers () + { + lock (watchers_lock) { + foreach (FileSystemWatcher watcher in watchers) + watcher.EnableRaisingEvents = false; + } + } + + internal static void EnableWatchers () + { + lock (watchers_lock) { + foreach (FileSystemWatcher watcher in watchers) + watcher.EnableRaisingEvents = true; + } + } + static void OnFileRenamed(object sender, RenamedEventArgs args) { OnFileChanged(sender, args); @@ -535,10 +658,13 @@ namespace System.Web { static void OnFileChanged(object sender, FileSystemEventArgs args) { lock (watchers_lock) { + if(app_shutdown) + return; + app_shutdown = true; + // Disable event raising to avoid concurrent restarts - foreach (FileSystemWatcher watcher in watchers) { - watcher.EnableRaisingEvents = false; - } + DisableWatchers (); + // Restart application HttpRuntime.UnloadAppDomain(); }