Author: mhabersack
Date: 2007-08-30 21:18:21 -0400 (Thu, 30 Aug 2007)
New Revision: 85090
Modified:
trunk/mcs/class/System.Web/System.Web/ChangeLog
trunk/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs
trunk/mcs/class/System.Web/System.Web/HttpResponse.cs
trunk/mcs/class/System.Web/System.Web/HttpRuntime.cs
Log:
2007-08-31 Marek Habersack <[EMAIL PROTECTED]>
* HttpApplicationFactory.cs: added methods to enable/disable
watchers.
* HttpRuntime.cs: implemented handling of app_offline.htm file in
the application root directory. Fixes bug #81127.
* HttpResponse.cs: make sure neither context or
context.ApplicationInstance are null in End ().
Modified: trunk/mcs/class/System.Web/System.Web/ChangeLog
===================================================================
--- trunk/mcs/class/System.Web/System.Web/ChangeLog 2007-08-31 01:18:15 UTC
(rev 85089)
+++ trunk/mcs/class/System.Web/System.Web/ChangeLog 2007-08-31 01:18:21 UTC
(rev 85090)
@@ -1,3 +1,14 @@
+2007-08-31 Marek Habersack <[EMAIL PROTECTED]>
+
+ * HttpApplicationFactory.cs: added methods to enable/disable
+ watchers.
+
+ * HttpRuntime.cs: implemented handling of app_offline.htm file in
+ the application root directory. Fixes bug #81127.
+
+ * HttpResponse.cs: make sure neither context or
+ context.ApplicationInstance are null in End ().
+
2007-08-27 Marek Habersack <[EMAIL PROTECTED]>
* HttpCookie.cs: make sure a key is output even if it has no
Modified: trunk/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs
2007-08-31 01:18:15 UTC (rev 85089)
+++ trunk/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs
2007-08-31 01:18:21 UTC (rev 85090)
@@ -80,6 +80,9 @@
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;
+#endif
Stack available = new Stack ();
Stack available_for_end = new Stack ();
@@ -544,7 +547,30 @@
return false;
}
}
+
+#if NET_2_0
+ internal static bool ApplicationDisabled {
+ get { return app_disabled; }
+ set { app_disabled = value; }
+ }
+#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);
@@ -558,9 +584,8 @@
app_shutdown = true;
// Disable event raising to avoid concurrent
restarts
- foreach (FileSystemWatcher watcher in watchers)
{
- watcher.EnableRaisingEvents = false;
- }
+ DisableWatchers ();
+
// Restart application
HttpRuntime.UnloadAppDomain();
}
Modified: trunk/mcs/class/System.Web/System.Web/HttpResponse.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web/HttpResponse.cs 2007-08-31
01:18:15 UTC (rev 85089)
+++ trunk/mcs/class/System.Web/System.Web/HttpResponse.cs 2007-08-31
01:18:21 UTC (rev 85090)
@@ -558,12 +558,17 @@
public void End ()
{
+ if (context == null)
+ return;
+
if (context.TimeoutPossible) {
Thread.CurrentThread.Abort (FlagEnd);
} else {
// If this is called from an async event,
signal the completion
// but don't throw.
- context.ApplicationInstance.CompleteRequest ();
+ HttpApplication app_instance =
context.ApplicationInstance;
+ if (app_instance != null)
+ app_instance.CompleteRequest ();
}
}
Modified: trunk/mcs/class/System.Web/System.Web/HttpRuntime.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web/HttpRuntime.cs 2007-08-31
01:18:15 UTC (rev 85089)
+++ trunk/mcs/class/System.Web/System.Web/HttpRuntime.cs 2007-08-31
01:18:21 UTC (rev 85090)
@@ -116,6 +116,7 @@
#if NET_2_0
static bool assemblyMappingEnabled;
static object assemblyMappingLock = new object ();
+ static object appOfflineLock = new object ();
#endif
static HttpRuntime ()
@@ -283,7 +284,81 @@
return;
ThreadPool.QueueUserWorkItem (do_RealProcessRequest,
request);
}
+
+#if NET_2_0
+ static readonly string[] app_offline_files =
{"app_offline.htm", "App_Offline.htm", "APP_OFFLINE.HTM"};
+ static FileSystemWatcher app_offline_watcher;
+
+ static void AppOfflineFileRenamed (object sender,
RenamedEventArgs args)
+ {
+ AppOfflineFileChanged (sender, args);
+ }
+ static void AppOfflineFileChanged (object sender,
FileSystemEventArgs args)
+ {
+ lock (appOfflineLock) {
+ HttpApplicationFactory.DisableWatchers ();
+ app_offline_watcher.EnableRaisingEvents = false;
+
+ // Restart application
+ HttpRuntime.UnloadAppDomain();
+ }
+ }
+
+ static bool AppIsOffline (HttpContext context)
+ {
+ string app_path =
context.Request.PhysicalApplicationPath;
+ string aof_path = null;
+ bool haveOfflineFile = false;
+
+ foreach (string aof in app_offline_files) {
+ aof_path = Path.Combine (app_path, aof);
+ if (File.Exists (aof_path)) {
+ haveOfflineFile = true;
+ break;
+ }
+ }
+
+ lock (appOfflineLock) {
+ if (!haveOfflineFile) {
+ if
(HttpApplicationFactory.ApplicationDisabled) {
+
HttpApplicationFactory.ApplicationDisabled = false;
+
HttpApplicationFactory.EnableWatchers ();
+ }
+
+ return false;
+ }
+
+ HttpApplicationFactory.ApplicationDisabled =
true;
+ HttpApplicationFactory.DisableWatchers ();
+
+ FileSystemEventHandler seh = new
FileSystemEventHandler (AppOfflineFileChanged);
+ RenamedEventHandler reh = new
RenamedEventHandler (AppOfflineFileRenamed);
+
+ app_offline_watcher = new FileSystemWatcher ();
+ app_offline_watcher.Path =
Path.GetDirectoryName (aof_path);
+ app_offline_watcher.Filter = Path.GetFileName
(aof_path);
+ app_offline_watcher.NotifyFilter |=
NotifyFilters.Size;
+ app_offline_watcher.Deleted += seh;
+ app_offline_watcher.Changed += seh;
+ app_offline_watcher.Renamed += reh;
+ app_offline_watcher.EnableRaisingEvents = true;
+ }
+
+ HttpResponse response = context.Response;
+ response.Clear ();
+ response.ContentType = "text/html";
+ response.ExpiresAbsolute = DateTime.UtcNow;
+ response.TransmitFile (aof_path, true);
+
+ context.Request.ReleaseResources ();
+ context.Response.ReleaseResources ();
+ HttpContext.Current = null;
+
+ return true;
+ }
+#endif
+
static void RealProcessRequest (object o)
{
HttpContext context = new HttpContext
((HttpWorkerRequest) o);
@@ -300,6 +375,11 @@
}
#endif
+#if NET_2_0
+ if (AppIsOffline (context))
+ return;
+#endif
+
//
// Get application instance (create or reuse an
instance of the correct class)
//
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches