diff --git a/src/ImageProcessor.Web/NET45/Config/ImageProcessorConfig.cs b/src/ImageProcessor.Web/NET45/Config/ImageProcessorConfig.cs
index 6160150d8..76082ab7d 100644
--- a/src/ImageProcessor.Web/NET45/Config/ImageProcessorConfig.cs
+++ b/src/ImageProcessor.Web/NET45/Config/ImageProcessorConfig.cs
@@ -121,6 +121,17 @@ namespace ImageProcessor.Web.Config
}
}
+ ///
+ ///
+ ///
+ public ImageSecuritySection.SafeUrl[] RemoteFileWhiteListExtensions
+ {
+ get
+ {
+ return GetImageSecuritySection().WhiteList.Cast().ToArray();
+ }
+ }
+
///
/// Gets a value indicating whether the current application is allowed to download remote files.
///
diff --git a/src/ImageProcessor.Web/NET45/Config/ImageSecuritySection.cs b/src/ImageProcessor.Web/NET45/Config/ImageSecuritySection.cs
index ac20ff498..16ec62db7 100644
--- a/src/ImageProcessor.Web/NET45/Config/ImageSecuritySection.cs
+++ b/src/ImageProcessor.Web/NET45/Config/ImageSecuritySection.cs
@@ -178,6 +178,22 @@ namespace ImageProcessor.Web.Config
set { this["url"] = value; }
}
+
+ [ConfigurationProperty("extensionLess", DefaultValue = false, IsRequired = false)]
+ public bool ExtensionLess
+ {
+ get { return (bool)this["extensionLess"]; }
+
+ set { this["extensionLess"] = value; }
+ }
+
+ [ConfigurationProperty("imageFormat", DefaultValue = "", IsRequired = false)]
+ public string ImageFormat
+ {
+ get { return (string)this["imageFormat"]; }
+
+ set { this["imageFormat"] = value; }
+ }
}
}
}
diff --git a/src/ImageProcessor.Web/NET45/Helpers/RemoteFile.cs b/src/ImageProcessor.Web/NET45/Helpers/RemoteFile.cs
index 211d8e1f2..bd6cdee9c 100644
--- a/src/ImageProcessor.Web/NET45/Helpers/RemoteFile.cs
+++ b/src/ImageProcessor.Web/NET45/Helpers/RemoteFile.cs
@@ -48,6 +48,11 @@ namespace ImageProcessor.Web.Helpers
///
private static readonly Uri[] RemoteFileWhiteList = ImageProcessorConfig.Instance.RemoteFileWhiteList;
+ ///
+ /// The white-list of url[s] from which to download remote files.
+ ///
+ public static readonly ImageSecuritySection.SafeUrl[] RemoteFileWhiteListExtensions = ImageProcessorConfig.Instance.RemoteFileWhiteListExtensions;
+
///
/// The length of time, in milliseconds, that a remote file download attempt can last before timing out.
///
diff --git a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs
index df1363b92..f6a8fb1aa 100644
--- a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs
+++ b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs
@@ -5,6 +5,11 @@
//
// -----------------------------------------------------------------------
+using System.Linq;
+using System.Security.Cryptography;
+using System.Security.Policy;
+using System.Text;
+
namespace ImageProcessor.Web.HttpModules
{
#region Using
@@ -177,6 +182,10 @@ namespace ImageProcessor.Web.HttpModules
string requestPath = string.Empty;
string queryString = string.Empty;
+ bool validExtensionLessUrl = false;
+ string urlParameters = "";
+ string extensionLessExtension = "";
+
if (isRemote)
{
// We need to split the querystring to get the actual values we want.
@@ -194,10 +203,25 @@ namespace ImageProcessor.Web.HttpModules
requestPath = paths[0];
- if (paths.Length > 1)
+ if (paths.Count() > 2)
+ {
+ queryString = paths[2];
+ urlParameters = paths[1];
+ }
+ else if (paths.Length > 1)
{
queryString = paths[1];
}
+
+ validExtensionLessUrl = RemoteFile.RemoteFileWhiteListExtensions.Any(
+ x => x.ExtensionLess == true && requestPath.StartsWith(x.Url.AbsoluteUri));
+
+ if (validExtensionLessUrl)
+ {
+ extensionLessExtension = RemoteFile.RemoteFileWhiteListExtensions.First(
+ x => x.ExtensionLess == true && requestPath.StartsWith(x.Url.AbsoluteUri)).ImageFormat;
+
+ }
}
}
else
@@ -207,11 +231,31 @@ namespace ImageProcessor.Web.HttpModules
}
// Only process requests that pass our sanitizing filter.
- if (ImageUtils.IsValidImageExtension(requestPath) && !string.IsNullOrWhiteSpace(queryString))
+ if ((ImageUtils.IsValidImageExtension(requestPath) || validExtensionLessUrl ) && !string.IsNullOrWhiteSpace(queryString))
{
string fullPath = string.Format("{0}?{1}", requestPath, queryString);
string imageName = Path.GetFileName(requestPath);
+ if (validExtensionLessUrl && !string.IsNullOrWhiteSpace(extensionLessExtension))
+ {
+ fullPath = requestPath;
+
+ if (!string.IsNullOrWhiteSpace(urlParameters))
+ {
+ //TODO: Add hash for querystring parameters
+ HashAlgorithm algorithm = MD5.Create(); // SHA1.Create()
+ var hashCode = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlParameters));
+ StringBuilder sb = new StringBuilder();
+ foreach (byte b in hashCode)
+ sb.Append(b.ToString("X2"));
+ imageName += sb.ToString();
+ fullPath += sb.ToString();
+ }
+
+ imageName += "." + extensionLessExtension;
+ fullPath += extensionLessExtension + "?" + queryString;
+ }
+
// Create a new cache to help process and cache the request.
DiskCache cache = new DiskCache(request, requestPath, fullPath, imageName, isRemote);
@@ -251,7 +295,7 @@ namespace ImageProcessor.Web.HttpModules
{
if (isRemote)
{
- Uri uri = new Uri(requestPath);
+ Uri uri = new Uri(requestPath + "?" + urlParameters);
RemoteFile remoteFile = new RemoteFile(uri, false);
diff --git a/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj b/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
index 7274ce547..4cadb0c9e 100644
--- a/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
+++ b/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
@@ -11,6 +11,8 @@
ImageProcessor.Web
v4.5
512
+ ..\..\..\..\..\..\..\..\TFS\ActiMeet\ActiMeet2\
+ true
true
@@ -31,10 +33,10 @@
- ..\..\packages\Csharp-Sqlite.3.7.7.1\lib\net40\Community.CsharpSqlite.dll
+ ..\..\..\..\..\..\..\..\TFS\ActiMeet\ActiMeet2\packages\Csharp-Sqlite.3.7.7.1\lib\net40\Community.CsharpSqlite.dll
- ..\..\packages\Csharp-Sqlite.3.7.7.1\lib\net40\Community.CsharpSqlite.SQLiteClient.dll
+ ..\..\..\..\..\..\..\..\TFS\ActiMeet\ActiMeet2\packages\Csharp-Sqlite.3.7.7.1\lib\net40\Community.CsharpSqlite.SQLiteClient.dll
@@ -75,6 +77,7 @@
+