diff --git a/src/ImageProcessor.Web/NET45/Config/ImageProcessorConfig.cs b/src/ImageProcessor.Web/NET45/Config/ImageProcessorConfig.cs index 21c848a61..2f0357d8b 100644 --- a/src/ImageProcessor.Web/NET45/Config/ImageProcessorConfig.cs +++ b/src/ImageProcessor.Web/NET45/Config/ImageProcessorConfig.cs @@ -12,6 +12,7 @@ namespace ImageProcessor.Web.Config { #region Using using System; + using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -37,14 +38,14 @@ namespace ImageProcessor.Web.Config /// A collection of the elements /// for available plugins. /// - private static readonly Dictionary> PluginSettings = - new Dictionary>(); + private static readonly ConcurrentDictionary> PluginSettings = + new ConcurrentDictionary>(); /// /// A collection of the processing presets defined in the configuration. /// for available plugins. /// - private static readonly Dictionary PresetSettings = new Dictionary(); + private static readonly ConcurrentDictionary PresetSettings = new ConcurrentDictionary(); /// /// The processing configuration section from the current application configuration. @@ -185,33 +186,26 @@ namespace ImageProcessor.Web.Config #region Methods /// - /// Returns the collection of the processing presets defined in the configuration. + /// Returns the processing instructions matching the preset defined in the configuration. /// /// /// The name of the plugin to get the settings for. /// /// - /// The containing the processing presets defined in the configuration. + /// The the processing instructions. /// public string GetPresetSettings(string name) { - if (!PresetSettings.ContainsKey(name)) - { - var presetElement = - GetImageProcessingSection().Presets - .Cast() - .FirstOrDefault(x => x.Name == name); - - if (presetElement != null) - { - PresetSettings[presetElement.Name] = presetElement.Value; - } - } - - string preset; - PresetSettings.TryGetValue(name, out preset); - - return preset; + return PresetSettings.GetOrAdd( + name, + n => + { + ImageProcessingSection.PresetElement presetElement = GetImageProcessingSection() + .Presets + .Cast() + .FirstOrDefault(x => x.Name == n); + return presetElement != null ? presetElement.Value : null; + }); } /// @@ -225,31 +219,30 @@ namespace ImageProcessor.Web.Config /// public Dictionary GetPluginSettings(string name) { - if (!PluginSettings.ContainsKey(name)) - { - var pluginElement = - GetImageProcessingSection().Plugins - .Cast() - .FirstOrDefault(x => x.Name == name); - - Dictionary settings; - - if (pluginElement != null) + return PluginSettings.GetOrAdd( + name, + n => { - settings = pluginElement.Settings - .Cast() - .ToDictionary(setting => setting.Key, setting => setting.Value); - } - else - { - settings = new Dictionary(); - } + ImageProcessingSection.PluginElement pluginElement = GetImageProcessingSection() + .Plugins + .Cast() + .FirstOrDefault(x => x.Name == n); - PluginSettings.Add(name, settings); - return settings; - } + Dictionary settings; + + if (pluginElement != null) + { + settings = pluginElement.Settings + .Cast() + .ToDictionary(setting => setting.Key, setting => setting.Value); + } + else + { + settings = new Dictionary(); + } - return PluginSettings[name]; + return settings; + }); } /// diff --git a/src/ImageProcessor.Web/NET45/Helpers/RemoteFile.cs b/src/ImageProcessor.Web/NET45/Helpers/RemoteFile.cs index 79ecfd29e..05c2f9753 100644 --- a/src/ImageProcessor.Web/NET45/Helpers/RemoteFile.cs +++ b/src/ImageProcessor.Web/NET45/Helpers/RemoteFile.cs @@ -15,7 +15,6 @@ namespace ImageProcessor.Web.Helpers using System.Collections.Generic; using System.Globalization; using System.IO; - using System.Linq; using System.Net; using System.Security; using System.Text; @@ -354,8 +353,24 @@ namespace ImageProcessor.Web.Helpers string upper = this.url.Host.ToUpperInvariant(); // Check for root or subdomain. - bool validUrl = RemoteFileWhiteList.Any(item => - upper.StartsWith(item.Host.ToUpperInvariant()) || upper.EndsWith(item.Host.ToUpperInvariant())); + bool validUrl = false; + foreach (Uri uri in RemoteFileWhiteList) + { + if (!uri.IsAbsoluteUri) + { + Uri rebaseUri = new Uri("http://" + uri.ToString().TrimStart(new[] { '.', '/' })); + validUrl = upper.StartsWith(rebaseUri.Host.ToUpperInvariant()) || upper.EndsWith(rebaseUri.Host.ToUpperInvariant()); + } + else + { + validUrl = upper.StartsWith(uri.Host.ToUpperInvariant()) || upper.EndsWith(uri.Host.ToUpperInvariant()); + } + + if (validUrl) + { + break; + } + } if (!validUrl) { diff --git a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs index 5e36ff128..a1f4b62da 100644 --- a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs +++ b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs @@ -261,7 +261,6 @@ namespace ImageProcessor.Web.HttpModules bool isRemote = request.Path.EndsWith(remotePrefix, StringComparison.OrdinalIgnoreCase); string requestPath = string.Empty; string queryString = string.Empty; - bool validExtensionLessUrl = false; string urlParameters = ""; string extensionLessExtension = ""; @@ -346,14 +345,12 @@ namespace ImageProcessor.Web.HttpModules // in the UrlAuthorizationModule by creating a generic identity. string virtualCachedPath = cache.GetVirtualCachedPath(); - IPrincipal user = context.User - ?? new GenericPrincipal(new GenericIdentity(string.Empty, string.Empty), new string[0]); + IPrincipal user = context.User ?? new GenericPrincipal(new GenericIdentity(string.Empty, string.Empty), new string[0]); // Do we have permission to call UrlAuthorizationModule.CheckUrlAccessForPrincipal? PermissionSet permission = new PermissionSet(PermissionState.None); permission.AddPermission(new AspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted)); bool hasPermission = permission.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet); - bool isAllowed = true; // Run the rewritten path past the auth system again, using the result as the default "AllowAccess" value @@ -493,6 +490,11 @@ namespace ImageProcessor.Web.HttpModules throw new HttpException(403, "Access denied"); } } + else if (isRemote) + { + // Just repoint to the external url. + HttpContext.Current.Response.Redirect(requestPath); + } } /// diff --git a/src/Images/falahill_design__160p.jpg b/src/Images/falahill_design__160p.jpg new file mode 100644 index 000000000..aa3ee4f40 Binary files /dev/null and b/src/Images/falahill_design__160p.jpg differ diff --git a/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/External.cshtml b/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/External.cshtml index 220d6a0a9..668f48863 100644 --- a/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/External.cshtml +++ b/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/External.cshtml @@ -11,4 +11,9 @@ +
+
+ +
+
diff --git a/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/Index.cshtml b/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/Index.cshtml index d1378da35..33cc843d0 100644 --- a/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/Index.cshtml +++ b/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/Index.cshtml @@ -11,6 +11,8 @@

Foreign language test.

+

Strange name

+

Cropped

@@ -201,18 +203,6 @@

Color Profiles

- @*
-
-
-

CMYK original jpg

- -
-
-

sRGB original jpg

- -
-
-
*@
@@ -233,4 +223,4 @@
-
+ \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_NET45/config/imageprocessor/security.config b/src/TestWebsites/NET45/Test_Website_NET45/config/imageprocessor/security.config index 05f9ed734..78b957605 100644 --- a/src/TestWebsites/NET45/Test_Website_NET45/config/imageprocessor/security.config +++ b/src/TestWebsites/NET45/Test_Website_NET45/config/imageprocessor/security.config @@ -1,14 +1,15 @@  - - - - - - - - - - - - - + + + + + + + + + + + + + +