diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index 02f3322ec9..395502d1b2 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -538,24 +538,41 @@ namespace Umbraco.Core.Configuration internal static bool ContentCacheXmlStoredInCodeGen { - get { return ContentCacheXmlStorageLocation == ContentXmlStorage.AspNetTemp; } + get { return LocalTempStorageLocation == LocalTempStorage.AspNetTemp; } } - - internal static ContentXmlStorage ContentCacheXmlStorageLocation + + /// + /// This is the location type to store temporary files such as cache files or other localized files for a given machine + /// + /// + /// Currently used for the xml cache file and the plugin cache files + /// + internal static LocalTempStorage LocalTempStorageLocation { get - { + { + //there's a bunch of backwards compat config checks here.... + + //This is the current one + if (ConfigurationManager.AppSettings.ContainsKey("umbracoLocalTempStorage")) + { + return Enum.Parse(ConfigurationManager.AppSettings["umbracoLocalTempStorage"]); + } + + //This one is old if (ConfigurationManager.AppSettings.ContainsKey("umbracoContentXMLStorage")) { - return Enum.Parse(ConfigurationManager.AppSettings["umbracoContentXMLStorage"]); - } + return Enum.Parse(ConfigurationManager.AppSettings["umbracoContentXMLStorage"]); + } + + //This one is older if (ConfigurationManager.AppSettings.ContainsKey("umbracoContentXMLUseLocalTemp")) { return bool.Parse(ConfigurationManager.AppSettings["umbracoContentXMLUseLocalTemp"]) - ? ContentXmlStorage.AspNetTemp - : ContentXmlStorage.Default; + ? LocalTempStorage.AspNetTemp + : LocalTempStorage.Default; } - return ContentXmlStorage.Default; + return LocalTempStorage.Default; } } diff --git a/src/Umbraco.Core/Configuration/ContentXmlStorage.cs b/src/Umbraco.Core/Configuration/LocalTempStorage.cs similarity index 75% rename from src/Umbraco.Core/Configuration/ContentXmlStorage.cs rename to src/Umbraco.Core/Configuration/LocalTempStorage.cs index 7cbbc70675..d41f7d1925 100644 --- a/src/Umbraco.Core/Configuration/ContentXmlStorage.cs +++ b/src/Umbraco.Core/Configuration/LocalTempStorage.cs @@ -1,6 +1,6 @@ namespace Umbraco.Core.Configuration { - internal enum ContentXmlStorage + internal enum LocalTempStorage { Default, AspNetTemp, diff --git a/src/Umbraco.Core/IO/SystemFiles.cs b/src/Umbraco.Core/IO/SystemFiles.cs index 437ddd3ef7..ccf8ea5b2c 100644 --- a/src/Umbraco.Core/IO/SystemFiles.cs +++ b/src/Umbraco.Core/IO/SystemFiles.cs @@ -73,19 +73,19 @@ namespace Umbraco.Core.IO { get { - switch (GlobalSettings.ContentCacheXmlStorageLocation) + switch (GlobalSettings.LocalTempStorageLocation) { - case ContentXmlStorage.AspNetTemp: + case LocalTempStorage.AspNetTemp: return Path.Combine(HttpRuntime.CodegenDir, @"UmbracoData\umbraco.config"); - case ContentXmlStorage.EnvironmentTemp: + case LocalTempStorage.EnvironmentTemp: var appDomainHash = HttpRuntime.AppDomainAppId.ToSHA1(); - var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoXml", - //include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back - // to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not - // utilizing an old path + var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", + //include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back + // to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not + // utilizing an old path appDomainHash); return Path.Combine(cachePath, "umbraco.config"); - case ContentXmlStorage.Default: + case LocalTempStorage.Default: return IOHelper.ReturnPath("umbracoContentXML", "~/App_Data/umbraco.config"); default: throw new ArgumentOutOfRangeException(); diff --git a/src/Umbraco.Core/PluginManager.cs b/src/Umbraco.Core/PluginManager.cs index f90163d181..0489093712 100644 --- a/src/Umbraco.Core/PluginManager.cs +++ b/src/Umbraco.Core/PluginManager.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Reflection; using System.Text; using System.Threading; +using System.Web; using System.Web.Compilation; using Umbraco.Core.Cache; using Umbraco.Core.IO; @@ -15,6 +16,7 @@ using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Profiling; using Umbraco.Core.PropertyEditors; using umbraco.interfaces; +using Umbraco.Core.Configuration; using File = System.IO.File; namespace Umbraco.Core @@ -80,21 +82,23 @@ namespace Umbraco.Core RequiresRescanning = (CachedAssembliesHash != CurrentAssembliesHash) || CachedAssembliesHash == string.Empty; //if they have changed, we need to write the new file if (RequiresRescanning) - { - // if the hash has changed, clear out the persisted list no matter what, this will force - // rescanning of all plugin types including lazy ones. - // http://issues.umbraco.org/issue/U4-4789 - File.Delete(pluginListFile); + { + // if the hash has changed, clear out the persisted list no matter what, this will force + // rescanning of all plugin types including lazy ones. + // http://issues.umbraco.org/issue/U4-4789 + if(File.Exists(pluginListFile)) + File.Delete(pluginListFile); WriteCachePluginsHash(); } } else - { - // if the hash has changed, clear out the persisted list no matter what, this will force - // rescanning of all plugin types including lazy ones. + { + // if the hash has changed, clear out the persisted list no matter what, this will force + // rescanning of all plugin types including lazy ones. // http://issues.umbraco.org/issue/U4-4789 - File.Delete(pluginListFile); + if (File.Exists(pluginListFile)) + File.Delete(pluginListFile); // always set to true if we're not detecting (generally only for testing) RequiresRescanning = true; @@ -231,6 +235,14 @@ namespace Umbraco.Core private void WriteCachePluginsHash() { var filePath = GetPluginHashFilePath(); + + // be absolutely sure the folder exists + var folder = Path.GetDirectoryName(filePath); + if (folder == null) + throw new InvalidOperationException("The folder could not be determined for the file " + filePath); + if (Directory.Exists(folder) == false) + Directory.CreateDirectory(folder); + File.WriteAllText(filePath, CurrentAssembliesHash.ToString(), Encoding.UTF8); } @@ -426,25 +438,56 @@ namespace Umbraco.Core } private string GetPluginListFilePath() - { - var filename = "umbraco-plugins." + NetworkHelper.FileSafeMachineName + ".list"; - return Path.Combine(_tempFolder, filename); + { + switch (GlobalSettings.LocalTempStorageLocation) + { + case LocalTempStorage.AspNetTemp: + return Path.Combine(HttpRuntime.CodegenDir, @"UmbracoData\umbraco-plugins.list"); + case LocalTempStorage.EnvironmentTemp: + var appDomainHash = HttpRuntime.AppDomainAppId.ToSHA1(); + var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", + //include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back + // to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not + // utilizing an old path + appDomainHash); + return Path.Combine(cachePath, "umbraco-plugins.list"); + case LocalTempStorage.Default: + default: + return Path.Combine(_tempFolder, "umbraco-plugins." + NetworkHelper.FileSafeMachineName + ".list"); + } } private string GetPluginHashFilePath() { - var filename = "umbraco-plugins." + NetworkHelper.FileSafeMachineName + ".hash"; - return Path.Combine(_tempFolder, filename); + switch (GlobalSettings.LocalTempStorageLocation) + { + case LocalTempStorage.AspNetTemp: + return Path.Combine(HttpRuntime.CodegenDir, @"UmbracoData\umbraco-plugins.hash"); + case LocalTempStorage.EnvironmentTemp: + var appDomainHash = HttpRuntime.AppDomainAppId.ToSHA1(); + var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", + //include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back + // to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not + // utilizing an old path + appDomainHash); + return Path.Combine(cachePath, "umbraco-plugins.hash"); + case LocalTempStorage.Default: + default: + return Path.Combine(_tempFolder, "umbraco-plugins." + NetworkHelper.FileSafeMachineName + ".hash"); + } } internal void WriteCache() { - // be absolutely sure - if (Directory.Exists(_tempFolder) == false) - Directory.CreateDirectory(_tempFolder); - - var filePath = GetPluginListFilePath(); + var filePath = GetPluginListFilePath(); + // be absolutely sure the folder exists + var folder = Path.GetDirectoryName(filePath); + if (folder == null) + throw new InvalidOperationException("The folder could not be determined for the file " + filePath); + if (Directory.Exists(folder) == false) + Directory.CreateDirectory(folder); + using (var stream = GetFileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, ListFileOpenWriteTimeout)) using (var writer = new StreamWriter(stream)) { diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index c4c1d58fdc..7de98685da 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -198,7 +198,7 @@ - +