diff --git a/src/ImageProcessor.Web/Caching/DiskCache.cs b/src/ImageProcessor.Web/Caching/DiskCache.cs index b5e94ea06..58eb5ea32 100644 --- a/src/ImageProcessor.Web/Caching/DiskCache.cs +++ b/src/ImageProcessor.Web/Caching/DiskCache.cs @@ -66,11 +66,6 @@ namespace ImageProcessor.Web.Caching /// private readonly string fullPath; - /// - /// The image name - /// - private readonly string imageName; - /// /// The physical cached path. /// @@ -92,14 +87,10 @@ namespace ImageProcessor.Web.Caching /// /// The full path for the image. /// - /// - /// The image name. - /// - public DiskCache(string requestPath, string fullPath, string imageName) + public DiskCache(string requestPath, string fullPath) { this.requestPath = requestPath; this.fullPath = fullPath; - this.imageName = imageName; // Get the physical and virtual paths. this.GetCachePaths(); @@ -207,7 +198,7 @@ namespace ImageProcessor.Web.Caching /// The path to the cached image. /// /// - /// True if the the original file is new or has been updated; otherwise, false. + /// True if The original file is new or has been updated; otherwise, false. /// public bool IsNewOrUpdatedFile(string cachedPath) { @@ -289,7 +280,6 @@ namespace ImageProcessor.Web.Caching // 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 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. @@ -297,9 +287,9 @@ namespace ImageProcessor.Web.Caching string virtualPathFromKey = pathFromKey.Replace(@"\", "/"); string cachedFileName = string.Format( - "{0}{1}", + "{0}.{1}", encryptedName, - !string.IsNullOrWhiteSpace(parsedExtension) ? "." + parsedExtension.Replace(".", string.Empty) : string.Empty); + !string.IsNullOrWhiteSpace(parsedExtension) ? parsedExtension.Replace(".", string.Empty) : "jpg"); this.physicalCachedPath = Path.Combine(AbsoluteCachePath, pathFromKey, cachedFileName); this.virtualCachedPath = Path.Combine(VirtualCachePath, virtualPathFromKey, cachedFileName).Replace(@"\", "/"); diff --git a/src/ImageProcessor.Web/Configuration/ImageProcessingSection.cs b/src/ImageProcessor.Web/Configuration/ImageProcessingSection.cs index 6ece1681b..6c2926c29 100644 --- a/src/ImageProcessor.Web/Configuration/ImageProcessingSection.cs +++ b/src/ImageProcessor.Web/Configuration/ImageProcessingSection.cs @@ -292,7 +292,7 @@ namespace ImageProcessor.Web.Configuration /// /// The index at which to get the specified object. /// - /// The the + /// The /// at the specified index within the collection. /// public PluginElement this[int index] @@ -413,7 +413,7 @@ namespace ImageProcessor.Web.Configuration /// /// The index at which to get the specified object. /// - /// The the + /// The /// at the specified index within the collection. /// public SettingElement this[int index] diff --git a/src/ImageProcessor.Web/Configuration/ImageProcessorConfiguration.cs b/src/ImageProcessor.Web/Configuration/ImageProcessorConfiguration.cs index 20e4cbc8d..a562df7d4 100644 --- a/src/ImageProcessor.Web/Configuration/ImageProcessorConfiguration.cs +++ b/src/ImageProcessor.Web/Configuration/ImageProcessorConfiguration.cs @@ -291,7 +291,7 @@ namespace ImageProcessor.Web.Configuration { if (this.ImageServices == null) { - if (GetImageSecuritySection().ImageServices.AutoLoadPlugins) + if (GetImageSecuritySection().ImageServices.AutoLoadServices) { Type type = typeof(IImageService); try diff --git a/src/ImageProcessor.Web/Configuration/ImageSecuritySection.cs b/src/ImageProcessor.Web/Configuration/ImageSecuritySection.cs index f57f64a6b..60fa113fa 100644 --- a/src/ImageProcessor.Web/Configuration/ImageSecuritySection.cs +++ b/src/ImageProcessor.Web/Configuration/ImageSecuritySection.cs @@ -132,12 +132,12 @@ namespace ImageProcessor.Web.Configuration /// Defaults to True. /// /// If True plugins are auto discovered and loaded from all assemblies otherwise they must be defined in the configuration file - [ConfigurationProperty("autoLoadPlugins", DefaultValue = true, IsRequired = false)] - public bool AutoLoadPlugins + [ConfigurationProperty("autoLoadServices", DefaultValue = true, IsRequired = false)] + public bool AutoLoadServices { - get { return (bool)this["autoLoadPlugins"]; } + get { return (bool)this["autoLoadServices"]; } - set { this["autoLoadPlugins"] = value; } + set { this["autoLoadServices"] = value; } } /// @@ -288,14 +288,14 @@ namespace ImageProcessor.Web.Configuration /// /// The index at which to get the specified object. /// - /// The the + /// The /// at the specified index within the collection. /// - public ImageSecuritySection.SettingElement this[int index] + public SettingElement this[int index] { get { - return (ImageSecuritySection.SettingElement)BaseGet(index); + return (SettingElement)BaseGet(index); } set @@ -314,9 +314,9 @@ namespace ImageProcessor.Web.Configuration /// /// the key representing the element /// the setting element - public new ImageSecuritySection.SettingElement this[string key] + public new SettingElement this[string key] { - get { return (ImageSecuritySection.SettingElement)BaseGet(key); } + get { return (SettingElement)BaseGet(key); } } /// @@ -342,7 +342,7 @@ namespace ImageProcessor.Web.Configuration /// The element key for a specified PluginElement configuration element. protected override object GetElementKey(ConfigurationElement element) { - return ((ImageSecuritySection.SettingElement)element).Key; + return ((SettingElement)element).Key; } /// @@ -353,7 +353,7 @@ namespace ImageProcessor.Web.Configuration /// protected override ConfigurationElement CreateNewElement() { - return new ImageSecuritySection.SettingElement(); + return new SettingElement(); } } diff --git a/src/ImageProcessor.Web/Configuration/Resources/security.config b/src/ImageProcessor.Web/Configuration/Resources/security.config index aaa2fbf9b..1e415c0d3 100644 --- a/src/ImageProcessor.Web/Configuration/Resources/security.config +++ b/src/ImageProcessor.Web/Configuration/Resources/security.config @@ -1,5 +1,5 @@ - + diff --git a/src/ImageProcessor.Web/Helpers/ImageHelpers.cs b/src/ImageProcessor.Web/Helpers/ImageHelpers.cs index 21445c1d8..ab93a43a3 100644 --- a/src/ImageProcessor.Web/Helpers/ImageHelpers.cs +++ b/src/ImageProcessor.Web/Helpers/ImageHelpers.cs @@ -10,10 +10,7 @@ namespace ImageProcessor.Web.Helpers { - using System; - using System.Collections.Generic; using System.IO; - using System.Linq; using System.Text; using System.Text.RegularExpressions; using ImageProcessor.Configuration; @@ -79,21 +76,22 @@ namespace ImageProcessor.Web.Helpers /// /// Get the correct mime-type for the given string input. /// - /// - /// The identifier. + /// + /// The path to the cached image. /// /// /// The matching the correct mime-type. /// - public static string GetMimeType(string identifier) + public static string GetMimeType(string path) { - identifier = GetExtension(identifier).Replace(".", string.Empty); - List formats = ImageProcessorBootstrapper.Instance.SupportedImageFormats.ToList(); - ISupportedImageFormat format = formats.FirstOrDefault(f => f.FileExtensions.Any(e => e.Equals(identifier, StringComparison.InvariantCultureIgnoreCase))); - - if (format != null) + using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false)) { - return format.MimeType; + ISupportedImageFormat format = FormatUtilities.GetFormat(file); + + if (format != null) + { + return format.MimeType; + } } return string.Empty; diff --git a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs index e1fd2b583..bf4f2e754 100644 --- a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs +++ b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs @@ -13,7 +13,6 @@ namespace ImageProcessor.Web.HttpModules #region Using using System; using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Net; @@ -31,7 +30,6 @@ namespace ImageProcessor.Web.HttpModules using ImageProcessor.Web.Configuration; using ImageProcessor.Web.Helpers; using ImageProcessor.Web.Services; - #endregion /// @@ -267,7 +265,6 @@ namespace ImageProcessor.Web.HttpModules /// /// The . /// - [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1122:UseStringEmptyForEmptyStrings", Justification = "Reviewed. Suppression is OK here.")] private async Task ProcessImageAsync(HttpContext context) { HttpRequest request = context.Request; @@ -278,12 +275,12 @@ namespace ImageProcessor.Web.HttpModules throw new HttpException(500, "No ImageService found for current request."); } - bool isRemote = !currentService.IsFileLocalService; + bool isFileLocal = currentService.IsFileLocalService; string requestPath = string.Empty; string queryString = string.Empty; - string urlParameters = ""; + string urlParameters = string.Empty; - if (isRemote) + if (!isFileLocal) { // We need to split the querystring to get the actual values we want. string urlDecode = HttpUtility.UrlDecode(request.QueryString.ToString()); @@ -324,11 +321,11 @@ namespace ImageProcessor.Web.HttpModules // Replace any presets in the querystring with the actual value. queryString = this.ReplacePresetsInQueryString(queryString); - string fullPath = string.Format("{0}?{1}", requestPath, queryString); - string imageName = Path.GetFileName(requestPath); + string parts = !string.IsNullOrWhiteSpace(urlParameters) ? "?" + urlParameters : string.Empty; + 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, imageName); + DiskCache cache = new DiskCache(requestPath, fullPath); string cachedPath = cache.CachedPath; // Since we are now rewriting the path we need to check again that the current user has access @@ -369,7 +366,7 @@ namespace ImageProcessor.Web.HttpModules { byte[] imageBuffer; - if (isRemote) + if (!isFileLocal) { Uri uri = new Uri(requestPath + "?" + urlParameters); imageBuffer = await currentService.GetImage(uri); @@ -412,6 +409,11 @@ namespace ImageProcessor.Web.HttpModules } } + if (context.Items[CachedResponseFileDependency] == null) + { + context.Items[CachedResponseFileDependency] = new List { cachedPath }; + } + string incomingEtag = context.Request.Headers["If" + "-None-Match"]; if (incomingEtag != null && !isNewOrUpdated) @@ -422,7 +424,7 @@ namespace ImageProcessor.Web.HttpModules context.Response.StatusCode = (int)HttpStatusCode.NotModified; context.Response.SuppressContent = true; - if (!isRemote) + if (!isFileLocal) { // Set the headers and quit. this.SetHeaders(context, (string)context.Items[CachedResponseTypeKey], new List { requestPath, cachedPath }); @@ -440,7 +442,7 @@ namespace ImageProcessor.Web.HttpModules throw new HttpException(403, "Access denied"); } } - else if (isRemote) + else if (!isFileLocal) { // Just re-point to the external url. HttpContext.Current.Response.Redirect(requestPath); @@ -450,14 +452,14 @@ namespace ImageProcessor.Web.HttpModules /// /// This will make the browser and server keep the output /// in its cache and thereby improve performance. - /// See http://en.wikipedia.org/wiki/HTTP_ETag + /// /// /// /// the HttpContext object that provides /// references to the intrinsic server objects /// /// - /// The HTTP MIME type to to send. + /// The HTTP MIME type to send. /// /// /// The dependency path for the cache dependency. diff --git a/src/ImageProcessor.Web/Services/IImageService.cs b/src/ImageProcessor.Web/Services/IImageService.cs index 7d0c2a5fc..23746cea0 100644 --- a/src/ImageProcessor.Web/Services/IImageService.cs +++ b/src/ImageProcessor.Web/Services/IImageService.cs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0. // // -// Defines properties and methods for allowing retrieval of image from different means. +// Defines properties and methods for allowing retrieval of image from different sources. // // -------------------------------------------------------------------------------------------------------------------- @@ -15,7 +15,7 @@ namespace ImageProcessor.Web.Services using System.Threading.Tasks; /// - /// Defines properties and methods for allowing retrieval of image from different means. + /// Defines properties and methods for allowing retrieval of image from different sources. /// public interface IImageService { diff --git a/src/ImageProcessor/Imaging/Colors/RGBAColor.cs b/src/ImageProcessor/Imaging/Colors/RGBAColor.cs index 87e8fa9aa..790e2ae09 100644 --- a/src/ImageProcessor/Imaging/Colors/RGBAColor.cs +++ b/src/ImageProcessor/Imaging/Colors/RGBAColor.cs @@ -254,20 +254,20 @@ namespace ImageProcessor.Imaging.Colors return HslaColor.FromColor(rgba); } - ///// - ///// Allows the implicit conversion of an instance of to a - ///// . - ///// - ///// - ///// The instance of to convert. - ///// - ///// - ///// An instance of . - ///// - //public static implicit operator YCbCrColor(RgbaColor rgba) - //{ - // return YCbCrColor.FromColor(rgba); - //} + /// + /// Allows the implicit conversion of an instance of to a + /// . + /// + /// + /// The instance of to convert. + /// + /// + /// An instance of . + /// + public static implicit operator YCbCrColor(RgbaColor rgba) + { + return YCbCrColor.FromColor(rgba); + } /// /// Returns a that represents this instance. diff --git a/src/ImageProcessor/Processors/Hue.cs b/src/ImageProcessor/Processors/Hue.cs index 4d049c676..11a7b4841 100644 --- a/src/ImageProcessor/Processors/Hue.cs +++ b/src/ImageProcessor/Processors/Hue.cs @@ -57,7 +57,6 @@ namespace ImageProcessor.Processors try { - Tuple parameters = this.DynamicParameter; int degrees = parameters.Item1; bool rotate = parameters.Item2; diff --git a/src/TestWebsites/MVC/config/imageprocessor/security.config b/src/TestWebsites/MVC/config/imageprocessor/security.config index 8671f06df..cd54dde6a 100644 --- a/src/TestWebsites/MVC/config/imageprocessor/security.config +++ b/src/TestWebsites/MVC/config/imageprocessor/security.config @@ -1,6 +1,6 @@  - +