diff --git a/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs b/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs index 57c29f3eb..c046cfd8a 100644 --- a/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs +++ b/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs @@ -47,17 +47,17 @@ namespace ImageProcessor.Web.Caching /// /// /// - private const int MaxFilesCount = 50; + private const int MaxFilesCount = 100; /// - /// The absolute path to virtual cache path on the server. + /// The virtual cache path. /// - private static readonly string AbsoluteCachePath = HostingEnvironment.MapPath(ImageProcessorConfig.Instance.VirtualCachePath); + private static readonly string VirtualCachePath = ImageProcessorConfig.Instance.VirtualCachePath; /// - /// The request for the image. + /// The absolute path to virtual cache path on the server. /// - private readonly HttpRequest request; + private static readonly string AbsoluteCachePath = HostingEnvironment.MapPath(ImageProcessorConfig.Instance.VirtualCachePath); /// /// The request path for the image. @@ -78,15 +78,22 @@ namespace ImageProcessor.Web.Caching /// Whether the request is for a remote image. /// private readonly bool isRemote; + + /// + /// The physical cached path. + /// + private string physicalCachedPath; + + /// + /// The virtual cached path. + /// + private string virtualCachedPath; #endregion #region Constructors /// /// Initializes a new instance of the class. /// - /// - /// The request for the image. - /// /// /// The request path for the image. /// @@ -99,14 +106,15 @@ namespace ImageProcessor.Web.Caching /// /// Whether the request is for a remote image. /// - public DiskCache(HttpRequest request, string requestPath, string fullPath, string imageName, bool isRemote) + public DiskCache(string requestPath, string fullPath, string imageName, bool isRemote) { - this.request = request; this.requestPath = requestPath; this.fullPath = fullPath; this.imageName = imageName; this.isRemote = isRemote; - this.CachedPath = this.GetCachePath(); + + // Get the physical and virtual paths. + this.GetCachePaths(); } #endregion @@ -114,30 +122,28 @@ namespace ImageProcessor.Web.Caching /// /// Gets the cached path. /// - internal string CachedPath { get; private set; } - #endregion + public string CachedPath + { + get + { + return this.physicalCachedPath; + } + } - #region Methods - #region Internal /// - /// Gets the virtual path to the cached processed image. + /// Gets the cached path. /// - /// The virtual path to the cached processed image. - internal string GetVirtualCachedPath() + public string VirtualCachedPath { - string applicationPath = this.request.PhysicalApplicationPath; - string virtualDir = this.request.ApplicationPath; - virtualDir = virtualDir == "/" ? virtualDir : (virtualDir + "/"); - - if (applicationPath != null) + get { - return this.CachedPath.Replace(applicationPath, virtualDir).Replace(@"\", "/"); + return this.virtualCachedPath; } - - throw new InvalidOperationException( - "We can only map an absolute back to a relative path if the application path is available."); } + #endregion + #region Methods + #region Internal /// /// Adds an image to the cache. /// @@ -269,11 +275,9 @@ namespace ImageProcessor.Web.Caching /// taking the individual characters of the hash to determine their location. /// This allows us to store millions of images. /// - /// The full cached path for the image. [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")] - private string GetCachePath() + private void GetCachePaths() { - string cachedPath = string.Empty; string streamHash = string.Empty; if (AbsoluteCachePath != null) @@ -304,23 +308,23 @@ namespace ImageProcessor.Web.Caching // Use an sha1 hash of the full path including the querystring to create the image name. // That name can also be used as a key for the cached image and we should be able to use - // The characters of that hash as subfolders. + // The characters of that hash as sub-folders. string parsedExtension = ImageHelpers.GetExtension(this.fullPath); string fallbackExtension = this.imageName.Substring(this.imageName.LastIndexOf(".", StringComparison.Ordinal) + 1); string encryptedName = (streamHash + this.fullPath).ToSHA1Fingerprint(); // Collision rate of about 1 in 10000 for the folder structure. string pathFromKey = string.Join("\\", encryptedName.ToCharArray().Take(6)); + string virtualPathFromKey = pathFromKey.Replace(@"\", "/"); string cachedFileName = string.Format( "{0}.{1}", encryptedName, !string.IsNullOrWhiteSpace(parsedExtension) ? parsedExtension.Replace(".", string.Empty) : fallbackExtension); - cachedPath = Path.Combine(AbsoluteCachePath, pathFromKey, cachedFileName); + this.physicalCachedPath = Path.Combine(AbsoluteCachePath, pathFromKey, cachedFileName); + this.virtualCachedPath = Path.Combine(VirtualCachePath, virtualPathFromKey, cachedFileName).Replace(@"\", "/"); } - - return cachedPath; } /// diff --git a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs index 22c03bef7..8bf539b54 100644 --- a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs +++ b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs @@ -346,14 +346,14 @@ namespace ImageProcessor.Web.HttpModules } // Create a new cache to help process and cache the request. - DiskCache cache = new DiskCache(request, requestPath, fullPath, imageName, isRemote); + DiskCache cache = new DiskCache(requestPath, fullPath, imageName, isRemote); // Since we are now rewriting the path we need to check again that the current user has access // to the rewritten path. // Get the user for the current request // If the user is anonymous or authentication doesn't work for this suffix avoid a NullReferenceException // in the UrlAuthorizationModule by creating a generic identity. - string virtualCachedPath = cache.GetVirtualCachedPath(); + string virtualCachedPath = cache.VirtualCachedPath; IPrincipal user = context.User ?? new GenericPrincipal(new GenericIdentity(string.Empty, string.Empty), new string[0]); @@ -475,7 +475,7 @@ namespace ImageProcessor.Web.HttpModules context.Response.AddHeader("Content-Length", "0"); context.Response.StatusCode = (int)HttpStatusCode.NotModified; context.Response.SuppressContent = true; - context.Response.AddFileDependency(context.Server.MapPath(cache.GetVirtualCachedPath())); + context.Response.AddFileDependency(context.Server.MapPath(virtualCachedPath)); this.SetHeaders(context, (string)context.Items[CachedResponseTypeKey]); if (!isRemote) @@ -484,10 +484,8 @@ namespace ImageProcessor.Web.HttpModules } } - string virtualPath = cache.GetVirtualCachedPath(); - // The cached file is valid so just rewrite the path. - context.RewritePath(virtualPath, false); + context.RewritePath(virtualCachedPath, false); } else { diff --git a/src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs b/src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs index e09d25366..831e5543e 100644 --- a/src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs +++ b/src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs @@ -35,5 +35,5 @@ using ImageProcessor.Web.HttpModules; // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.2.9.0")] -[assembly: AssemblyFileVersion("3.2.9.0")] \ No newline at end of file +[assembly: AssemblyVersion("3.3.0.0")] +[assembly: AssemblyFileVersion("3.3.0.0")] \ No newline at end of file