Browse Source

Extension-less files now save.

Former-commit-id: 76da3932b9c51bd840c5d6f87d5bc6b842577e73
af/merge-core
James South 12 years ago
parent
commit
fbd74a3fd6
  1. 18
      src/ImageProcessor.Web/Caching/DiskCache.cs
  2. 4
      src/ImageProcessor.Web/Configuration/ImageProcessingSection.cs
  3. 2
      src/ImageProcessor.Web/Configuration/ImageProcessorConfiguration.cs
  4. 22
      src/ImageProcessor.Web/Configuration/ImageSecuritySection.cs
  5. 2
      src/ImageProcessor.Web/Configuration/Resources/security.config
  6. 22
      src/ImageProcessor.Web/Helpers/ImageHelpers.cs
  7. 30
      src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs
  8. 4
      src/ImageProcessor.Web/Services/IImageService.cs
  9. 28
      src/ImageProcessor/Imaging/Colors/RGBAColor.cs
  10. 1
      src/ImageProcessor/Processors/Hue.cs
  11. 2
      src/TestWebsites/MVC/config/imageprocessor/security.config

18
src/ImageProcessor.Web/Caching/DiskCache.cs

@ -66,11 +66,6 @@ namespace ImageProcessor.Web.Caching
/// </summary>
private readonly string fullPath;
/// <summary>
/// The image name
/// </summary>
private readonly string imageName;
/// <summary>
/// The physical cached path.
/// </summary>
@ -92,14 +87,10 @@ namespace ImageProcessor.Web.Caching
/// <param name="fullPath">
/// The full path for the image.
/// </param>
/// <param name="imageName">
/// The image name.
/// </param>
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.
/// </param>
/// <returns>
/// 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.
/// </returns>
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(@"\", "/");

4
src/ImageProcessor.Web/Configuration/ImageProcessingSection.cs

@ -292,7 +292,7 @@ namespace ImageProcessor.Web.Configuration
/// </summary>
/// <param name="index">The index at which to get the specified object.</param>
/// <returns>
/// The the <see cref="T:ImageProcessor.Web.Config.ImageProcessingSection.PluginElement"/>
/// The <see cref="T:ImageProcessor.Web.Config.ImageProcessingSection.PluginElement"/>
/// at the specified index within the collection.
/// </returns>
public PluginElement this[int index]
@ -413,7 +413,7 @@ namespace ImageProcessor.Web.Configuration
/// </summary>
/// <param name="index">The index at which to get the specified object.</param>
/// <returns>
/// The the <see cref="T:ImageProcessor.Web.Config.ImageProcessingSection.SettingElement"/>
/// The <see cref="T:ImageProcessor.Web.Config.ImageProcessingSection.SettingElement"/>
/// at the specified index within the collection.
/// </returns>
public SettingElement this[int index]

2
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

22
src/ImageProcessor.Web/Configuration/ImageSecuritySection.cs

@ -132,12 +132,12 @@ namespace ImageProcessor.Web.Configuration
/// <remarks>Defaults to <value>True</value>.</remarks>
/// </summary>
/// <value>If True plugins are auto discovered and loaded from all assemblies otherwise they must be defined in the configuration file</value>
[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; }
}
/// <summary>
@ -288,14 +288,14 @@ namespace ImageProcessor.Web.Configuration
/// </summary>
/// <param name="index">The index at which to get the specified object.</param>
/// <returns>
/// The the <see cref="T:ImageProcessor.Web.Config.ImageSecuritySection.SettingElement"/>
/// The <see cref="T:ImageProcessor.Web.Config.ImageSecuritySection.SettingElement"/>
/// at the specified index within the collection.
/// </returns>
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
/// </summary>
/// <param name="key">the key representing the element</param>
/// <returns>the setting element</returns>
public new ImageSecuritySection.SettingElement this[string key]
public new SettingElement this[string key]
{
get { return (ImageSecuritySection.SettingElement)BaseGet(key); }
get { return (SettingElement)BaseGet(key); }
}
/// <summary>
@ -342,7 +342,7 @@ namespace ImageProcessor.Web.Configuration
/// <returns>The element key for a specified PluginElement configuration element.</returns>
protected override object GetElementKey(ConfigurationElement element)
{
return ((ImageSecuritySection.SettingElement)element).Key;
return ((SettingElement)element).Key;
}
/// <summary>
@ -353,7 +353,7 @@ namespace ImageProcessor.Web.Configuration
/// </returns>
protected override ConfigurationElement CreateNewElement()
{
return new ImageSecuritySection.SettingElement();
return new SettingElement();
}
}

2
src/ImageProcessor.Web/Configuration/Resources/security.config

@ -1,5 +1,5 @@
<security>
<services autoLoadPlugins="true">
<services autoLoadServices="true">
<service name="LocalFileImageService" type="ImageProcessor.Web.Services.LocalFileImageService, ImageProcessor.Web"/>
<service name="RemoteImageService" type="ImageProcessor.Web.Services.RemoteImageService, ImageProcessor.Web">
<settings>

22
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
/// <summary>
/// Get the correct mime-type for the given string input.
/// </summary>
/// <param name="identifier">
/// The identifier.
/// <param name="path">
/// The path to the cached image.
/// </param>
/// <returns>
/// The <see cref="string"/> matching the correct mime-type.
/// </returns>
public static string GetMimeType(string identifier)
public static string GetMimeType(string path)
{
identifier = GetExtension(identifier).Replace(".", string.Empty);
List<ISupportedImageFormat> 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;

30
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
/// <summary>
@ -267,7 +265,6 @@ namespace ImageProcessor.Web.HttpModules
/// <returns>
/// The <see cref="T:System.Threading.Tasks.Task"/>.
/// </returns>
[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<string> { 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<string> { 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
/// <summary>
/// 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
/// <see href="http://en.wikipedia.org/wiki/HTTP_ETag"/>
/// </summary>
/// <param name="context">
/// the <see cref="T:System.Web.HttpContext">HttpContext</see> object that provides
/// references to the intrinsic server objects
/// </param>
/// <param name="responseType">
/// The HTTP MIME type to to send.
/// The HTTP MIME type to send.
/// </param>
/// <param name="dependencyPaths">
/// The dependency path for the cache dependency.

4
src/ImageProcessor.Web/Services/IImageService.cs

@ -4,7 +4,7 @@
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Defines properties and methods for allowing retrieval of image from different means.
// Defines properties and methods for allowing retrieval of image from different sources.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
@ -15,7 +15,7 @@ namespace ImageProcessor.Web.Services
using System.Threading.Tasks;
/// <summary>
/// Defines properties and methods for allowing retrieval of image from different means.
/// Defines properties and methods for allowing retrieval of image from different sources.
/// </summary>
public interface IImageService
{

28
src/ImageProcessor/Imaging/Colors/RGBAColor.cs

@ -254,20 +254,20 @@ namespace ImageProcessor.Imaging.Colors
return HslaColor.FromColor(rgba);
}
///// <summary>
///// Allows the implicit conversion of an instance of <see cref="RgbaColor"/> to a
///// <see cref="YCbCrColor"/>.
///// </summary>
///// <param name="rgba">
///// The instance of <see cref="RgbaColor"/> to convert.
///// </param>
///// <returns>
///// An instance of <see cref="YCbCrColor"/>.
///// </returns>
//public static implicit operator YCbCrColor(RgbaColor rgba)
//{
// return YCbCrColor.FromColor(rgba);
//}
/// <summary>
/// Allows the implicit conversion of an instance of <see cref="RgbaColor"/> to a
/// <see cref="YCbCrColor"/>.
/// </summary>
/// <param name="rgba">
/// The instance of <see cref="RgbaColor"/> to convert.
/// </param>
/// <returns>
/// An instance of <see cref="YCbCrColor"/>.
/// </returns>
public static implicit operator YCbCrColor(RgbaColor rgba)
{
return YCbCrColor.FromColor(rgba);
}
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.

1
src/ImageProcessor/Processors/Hue.cs

@ -57,7 +57,6 @@ namespace ImageProcessor.Processors
try
{
Tuple<int, bool> parameters = this.DynamicParameter;
int degrees = parameters.Item1;
bool rotate = parameters.Item2;

2
src/TestWebsites/MVC/config/imageprocessor/security.config

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<security>
<services autoLoadPlugins="true">
<services autoLoadServices="true">
<service name="LocalFileImageService" type="ImageProcessor.Web.Services.LocalFileImageService, ImageProcessor.Web"/>
<service name="RemoteImageService" type="ImageProcessor.Web.Services.RemoteImageService, ImageProcessor.Web">
<settings>

Loading…
Cancel
Save