From 184dfc1f04f9dd63270d3e987c96cd0fd23d4e36 Mon Sep 17 00:00:00 2001 From: James South Date: Sat, 8 Nov 2014 18:59:24 +0000 Subject: [PATCH] Much better extension parsing. Former-commit-id: 05400d03f0b51df2bb62a9178df9ee6105ec995a Former-commit-id: e17df46703b600ff2267342f75f7128b423b004d --- src/ImageProcessor.Web/Caching/DiskCache.cs | 13 ++++- .../Helpers/ImageHelpers.cs | 47 ++++++++++++++----- .../HttpModules/ImageProcessingModule.cs | 6 +-- .../Configuration/NativeBinaryFactory.cs | 2 +- src/ImageProcessor/ImageFactory.cs | 2 +- 5 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/ImageProcessor.Web/Caching/DiskCache.cs b/src/ImageProcessor.Web/Caching/DiskCache.cs index 58eb5ea32..fd0778e76 100644 --- a/src/ImageProcessor.Web/Caching/DiskCache.cs +++ b/src/ImageProcessor.Web/Caching/DiskCache.cs @@ -66,6 +66,11 @@ namespace ImageProcessor.Web.Caching /// private readonly string fullPath; + /// + /// The querystring containing processing instructions. + /// + private readonly string querystring; + /// /// The physical cached path. /// @@ -87,10 +92,14 @@ namespace ImageProcessor.Web.Caching /// /// The full path for the image. /// - public DiskCache(string requestPath, string fullPath) + /// + /// The querystring containing instructions. + /// + public DiskCache(string requestPath, string fullPath, string querystring) { this.requestPath = requestPath; this.fullPath = fullPath; + this.querystring = querystring; // Get the physical and virtual paths. this.GetCachePaths(); @@ -279,7 +288,7 @@ 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 sub-folders. - string parsedExtension = ImageHelpers.GetExtension(this.fullPath); + string parsedExtension = ImageHelpers.GetExtension(this.fullPath, this.querystring); string encryptedName = (streamHash + this.fullPath).ToSHA1Fingerprint(); // Collision rate of about 1 in 10000 for the folder structure. diff --git a/src/ImageProcessor.Web/Helpers/ImageHelpers.cs b/src/ImageProcessor.Web/Helpers/ImageHelpers.cs index cfa6186fd..3ba8a56fc 100644 --- a/src/ImageProcessor.Web/Helpers/ImageHelpers.cs +++ b/src/ImageProcessor.Web/Helpers/ImageHelpers.cs @@ -11,10 +11,13 @@ namespace ImageProcessor.Web.Helpers { using System.IO; + using System.Linq; using System.Text; using System.Text.RegularExpressions; using ImageProcessor.Configuration; using ImageProcessor.Imaging.Formats; + using ImageProcessor.Web.Configuration; + using ImageProcessor.Web.Processors; /// /// The image helpers. @@ -27,10 +30,9 @@ namespace ImageProcessor.Web.Helpers public static readonly string ExtensionRegexPattern = BuildExtensionRegexPattern(); /// - /// The exclude regex for matching things to ignore when parsing image extensions. - /// TODO: This is hacky and awful and should go. + /// The regex for matching the format to ignore when parsing image extensions. /// - private static readonly Regex ExcludeRegex = new Regex(@"(mask|overlay)=[\w+-]+.", RegexOptions.IgnoreCase); + private static readonly Regex FormatProcessorRegex = new Regex(@"format=[\w+-]+.", RegexOptions.IgnoreCase); /// /// The image format regex. @@ -55,31 +57,52 @@ namespace ImageProcessor.Web.Helpers /// /// Returns the correct file extension for the given string input /// - /// + /// /// The string to parse. /// + /// + /// The querystring containing instructions. + /// /// /// The correct file extension for the given string input if it can find one; otherwise an empty string. /// - public static string GetExtension(string input) + public static string GetExtension(string fullPath, string queryString) { - // First filter out any troublesome elements. - foreach (Match exclude in ExcludeRegex.Matches(input)) + Match match; + + // First check to see if the format processor is being used and test against that. + IWebGraphicsProcessor format = ImageProcessorConfiguration.Instance.GraphicsProcessors + .First(p => typeof(Format) == p.GetType()); + + if (format != null) { - input = input.Replace(exclude.Value, string.Empty); + match = format.RegexPattern.Match(queryString); + } + else + { + // Test against the path minus the querystring so any other + // processors don't interere. + string trimmed = fullPath.Replace(queryString, string.Empty); + match = FormatRegex.Match(trimmed); } - - Match match = FormatRegex.Match(input); if (match.Success) { + string value = match.Value; + + // Clip if format processor match. + if (match.Value.Contains("=")) + { + value = value.Split('=')[1]; + } + // Ah the enigma that is the png file. - if (match.Value.ToLowerInvariant().EndsWith("png8")) + if (value.ToLowerInvariant().EndsWith("png8")) { return "png"; } - return match.Value; + return value; } return string.Empty; diff --git a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs index f8f8f4bf5..5f15c4e0d 100644 --- a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs +++ b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs @@ -145,7 +145,7 @@ namespace ImageProcessor.Web.HttpModules this.Dispose(true); // This object will be cleaned up by the Dispose method. - // Therefore, you should call GC.SupressFinalize to + // Therefore, you should call GC.SuppressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. @@ -269,7 +269,7 @@ namespace ImageProcessor.Web.HttpModules { HttpRequest request = context.Request; - // SHould we ignore this request? + // Should we ignore this request? if (request.RawUrl.ToUpperInvariant().Contains("IPIGNORE=TRUE")) { return; @@ -329,7 +329,7 @@ namespace ImageProcessor.Web.HttpModules string fullPath = string.Format("{0}{1}?{2}", requestPath, parts, queryString); // Create a new cache to help process and cache the request. - DiskCache cache = new DiskCache(requestPath, fullPath); + DiskCache cache = new DiskCache(requestPath, fullPath, queryString); string cachedPath = cache.CachedPath; // Since we are now rewriting the path we need to check again that the current user has access diff --git a/src/ImageProcessor/Configuration/NativeBinaryFactory.cs b/src/ImageProcessor/Configuration/NativeBinaryFactory.cs index 16ab92261..1f939fe5d 100644 --- a/src/ImageProcessor/Configuration/NativeBinaryFactory.cs +++ b/src/ImageProcessor/Configuration/NativeBinaryFactory.cs @@ -163,7 +163,7 @@ namespace ImageProcessor.Configuration this.Dispose(true); // This object will be cleaned up by the Dispose method. - // Therefore, you should call GC.SupressFinalize to + // Therefore, you should call GC.SuppressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs index c5ce4f630..8e8a1d396 100644 --- a/src/ImageProcessor/ImageFactory.cs +++ b/src/ImageProcessor/ImageFactory.cs @@ -1075,7 +1075,7 @@ namespace ImageProcessor this.Dispose(true); // This object will be cleaned up by the Dispose method. - // Therefore, you should call GC.SupressFinalize to + // Therefore, you should call GC.SuppressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time.