2007-07-21 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.Hosting / ApplicationHost.cs
index 6e57f1b94bfc86ac55664576268bc66dadaaad54..0159bbb4fe22253e3e1e36c25dc42189bb579c91 100644 (file)
@@ -37,7 +37,7 @@ namespace System.Web.Hosting {
        [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public sealed class ApplicationHost {
 
-               static string [] types = { "Web.config", "web.config" };
+               static string [] types = { "Web.config", "Web.Config", "web.config" };
 
                private ApplicationHost ()
                {
@@ -57,36 +57,101 @@ namespace System.Web.Hosting {
                        return r;
                }
 
+#if NET_2_0
+               static object create_dir = new object ();
+#endif
+
+               internal static bool ClearDynamicBaseDirectory (string directory)
+               {
+                       string[] entries = null;
+                       
+                       try {
+                               entries = Directory.GetDirectories (directory);
+                       } catch {
+                               // ignore
+                       }
+
+                       bool dirEmpty = true;
+                       if (entries != null && entries.Length > 0) {
+                               foreach (string e in entries) {
+                                       if (ClearDynamicBaseDirectory (e)) {
+                                               try {
+                                                       Directory.Delete (e);
+                                               } catch {
+                                                       dirEmpty = false;
+                                               }
+                                       }
+                               }
+                       }
+
+                       try {
+                               entries = Directory.GetFiles (directory);
+                       } catch {
+                               entries = null;
+                       }
+
+                       if (entries != null && entries.Length > 0) {
+                               foreach (string e in entries) {
+                                       try {
+                                               File.Delete (e);
+                                       } catch {
+                                               dirEmpty = false;
+                                       }
+                               }
+                       }
+
+                       return dirEmpty;
+               }
+               
+               static bool CreateDirectory (string directory)
+               {
+#if NET_2_0
+                       lock (create_dir) {
+#endif
+                               if (!Directory.Exists (directory)) {
+                                       Directory.CreateDirectory (directory);
+                                       return false;
+                               } else
+                                       return true;
+#if NET_2_0
+                       }
+#endif
+               }
+
+               static string GetBinPath (string physicalDir)
+               {
+                       string ret = Path.Combine (physicalDir, "Bin");
+                       if (Directory.Exists (ret))
+                               return ret;
+                       ret = Path.Combine (physicalDir, "bin");
+                       return ret;
+               }
+               
                //
                // For further details see `Hosting the ASP.NET runtime'
                //
                //    http://www.west-wind.com/presentations/aspnetruntime/aspnetruntime.asp
                // 
+#if TARGET_JVM
+               [MonoNotSupported ("")]
+#endif
                [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
                public static object CreateApplicationHost (Type hostType, string virtualDir, string physicalDir)
                {
                        if (physicalDir == null)
                                throw new NullReferenceException ();
 
-#if NET_2_0
+                       // Make sure physicalDir has file system semantics
+                       // and not uri semantics ( '\' and not '/' ).
                        physicalDir = Path.GetFullPath (physicalDir);
-#endif
-                       // This might throw
-                       Uri u = new Uri (physicalDir);
-                       physicalDir = HttpUtility.UrlDecode (u.AbsolutePath);
 
                        if (hostType == null)
-                               throw new NullReferenceException ();
+                               throw new ArgumentException ("hostType can't be null");
 
                        if (virtualDir == null)
-                               throw new NullReferenceException ();
+                               throw new ArgumentNullException ("virtualDir");
 
                        Evidence evidence = new Evidence (AppDomain.CurrentDomain.Evidence);
-
-                       // 
-                       // Unique Domain ID
-                       //
-                       string domain_id = "ASPHOST_" + DateTime.Now.ToString().GetHashCode().ToString("x");
                        
                        //
                        // Setup
@@ -96,10 +161,9 @@ namespace System.Web.Hosting {
                        setup.ApplicationBase = physicalDir;
 
                        setup.CachePath = null;
-                       setup.ApplicationName = domain_id;
                        setup.ConfigurationFile = FindWebConfig (physicalDir);
                        setup.DisallowCodeDownload = true;
-                       string bin_path = Path.Combine (physicalDir, "bin");
+                       string bin_path = GetBinPath (physicalDir);
                        setup.PrivateBinPath = bin_path;
                        setup.PrivateBinPathProbe = "*";
                        setup.ShadowCopyFiles = "true";
@@ -107,23 +171,35 @@ namespace System.Web.Hosting {
 
                        string dynamic_dir = null;
                        string user = Environment.UserName;
+                       int tempDirTag = 0;
+                       
                        for (int i = 0; ; i++){
                                string d = Path.Combine (Path.GetTempPath (),
                                        String.Format ("{0}-temp-aspnet-{1:x}", user, i));
                        
                                try {
-                                       Directory.CreateDirectory (d);
+                                       CreateDirectory (d);
                                        string stamp = Path.Combine (d, "stamp");
-                                       Directory.CreateDirectory (stamp);
+                                       CreateDirectory (stamp);
                                        dynamic_dir = d;
                                        Directory.Delete (stamp);
+                                       tempDirTag = i.GetHashCode ();
                                        break;
                                } catch (UnauthorizedAccessException){
                                        continue;
                                }
                        }
+                       // 
+                       // Unique Domain ID
+                       //
+                       string domain_id = (virtualDir.GetHashCode () ^ physicalDir.GetHashCode () ^ tempDirTag).ToString ("x");
+
+                       setup.ApplicationName = domain_id;
                        setup.DynamicBase = dynamic_dir;
-                       Directory.CreateDirectory (setup.DynamicBase);
+
+                       string dynamic_base = setup.DynamicBase;
+                       if (CreateDirectory (dynamic_base) && (Environment.GetEnvironmentVariable ("MONO_ASPNET_NODELETE") == null))
+                               ClearDynamicBaseDirectory (dynamic_base);
 
                        //
                        // Create app domain
@@ -144,7 +220,9 @@ namespace System.Web.Hosting {
                        appdomain.SetData (".domainId", domain_id);
                        appdomain.SetData (".hostingVirtualPath", virtualDir);
                        appdomain.SetData (".hostingInstallDir", Path.GetDirectoryName (typeof (Object).Assembly.CodeBase));
-
+#if NET_2_0
+                       appdomain.SetData ("DataDirectory", Path.Combine (physicalDir, "App_Data"));
+#endif
                        return appdomain.CreateInstanceAndUnwrap (hostType.Module.Assembly.FullName, hostType.FullName);
                }
        }