Skip to content

Commit

Permalink
Fixing file dependencies and mime/type
Browse files Browse the repository at this point in the history
Former-commit-id: 7c7d7bfade817e51454bfdf6366c796d8a6d8a28
  • Loading branch information
JimBobSquarePants committed Aug 15, 2014
1 parent e40f0d6 commit e2c3b41
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 29 deletions.
34 changes: 30 additions & 4 deletions src/ImageProcessor.Web/Helpers/ImageHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

namespace ImageProcessor.Web.Helpers
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using ImageProcessor.Configuration;
Expand All @@ -23,17 +26,17 @@ public static class ImageHelpers
/// <summary>
/// The regex pattern.
/// </summary>
private static readonly string RegexPattern = BuildRegexPattern();
private static readonly string ExtensionRegexPattern = BuildExtensionRegexPattern();

/// <summary>
/// The image format regex.
/// </summary>
private static readonly Regex FormatRegex = new Regex(@"(\.?)(png8|" + RegexPattern + ")", RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
private static readonly Regex FormatRegex = new Regex(@"(\.?)(png8|" + ExtensionRegexPattern + ")", RegexOptions.IgnoreCase | RegexOptions.RightToLeft);

/// <summary>
/// The image format regex for matching the file format at the end of a string.
/// </summary>
private static readonly Regex EndFormatRegex = new Regex(@"(\.)" + RegexPattern + "$", RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
private static readonly Regex EndFormatRegex = new Regex(@"(\.)" + ExtensionRegexPattern + "$", RegexOptions.IgnoreCase | RegexOptions.RightToLeft);

/// <summary>
/// Checks a given string to check whether the value contains a valid image extension.
Expand Down Expand Up @@ -72,13 +75,36 @@ public static string GetExtension(string input)
return string.Empty;
}

/// <summary>
/// Get the correct mime-type for the given string input.
/// </summary>
/// <param name="identifier">
/// The identifier.
/// </param>
/// <returns>
/// The <see cref="string"/> matching the correct mime-type.
/// </returns>
public static string GetMimeType(string identifier)
{
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)
{
return format.MimeType;
}

return string.Empty;
}

/// <summary>
/// Builds a regular expression from the <see cref="T:ImageProcessor.Imaging.Formats.ISupportedImageFormat"/> type, this allows extensibility.
/// </summary>
/// <returns>
/// The <see cref="Regex"/> to match matrix filters.
/// </returns>
private static string BuildRegexPattern()
private static string BuildExtensionRegexPattern()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("(");
Expand Down
51 changes: 26 additions & 25 deletions src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace ImageProcessor.Web.HttpModules
{
#region Using
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -208,10 +209,10 @@ private void ContextPreSendRequestHeaders(object sender, EventArgs e)
if (responseTypeObject != null && dependencyFileObject != null)
{
string responseType = (string)responseTypeObject;
string dependencyFile = (string)dependencyFileObject;
List<string> dependencyFiles = (List<string>)dependencyFileObject;

// Set the headers
this.SetHeaders(context, responseType, dependencyFile);
this.SetHeaders(context, responseType, dependencyFiles);

context.Items[CachedResponseTypeKey] = null;
context.Items[CachedResponseFileDependency] = null;
Expand Down Expand Up @@ -352,11 +353,7 @@ private async Task ProcessImageAsync(HttpContext context)
{
if (isRemote)
{
#if NET45 && !__MonoCS__
using (await Locker.LockAsync(cachedPath))
#else
using (Locker.Lock(cachedPath))
#endif
{
Uri uri = new Uri(requestPath + "?" + urlParameters);
RemoteFile remoteFile = new RemoteFile(uri, false);
Expand All @@ -382,14 +379,15 @@ private async Task ProcessImageAsync(HttpContext context)
.AutoProcess(queryString)
.Save(cachedPath);

// Store the response type in the context for later retrieval.
context.Items[CachedResponseTypeKey] = imageFactory.CurrentImageFormat.MimeType;

// Add to the cache.
cache.AddImageToCache(cachedPath);

// Trim the cache.
await cache.TrimCachedFolderAsync(cachedPath);

// Store the response type and cache dependency in the context for later retrieval.
context.Items[CachedResponseTypeKey] = imageFactory.CurrentImageFormat.MimeType;
context.Items[CachedResponseFileDependency] = new List<string> { cachedPath };
}
}
}
Expand All @@ -398,11 +396,7 @@ private async Task ProcessImageAsync(HttpContext context)
}
else
{
#if NET45 && !__MonoCS__
using (await Locker.LockAsync(cachedPath))
#else
using (Locker.Lock(cachedPath))
#endif
{
// Check to see if the file exists.
// ReSharper disable once AssignNullToNotNullAttribute
Expand All @@ -418,14 +412,15 @@ private async Task ProcessImageAsync(HttpContext context)
.AutoProcess(queryString)
.Save(cachedPath);

// Store the response type in the context for later retrieval.
context.Items[CachedResponseTypeKey] = imageFactory.CurrentImageFormat.MimeType;

// Add to the cache.
cache.AddImageToCache(cachedPath);

// Trim the cache.
await cache.TrimCachedFolderAsync(cachedPath);

// Store the response type and cache dependencies in the context for later retrieval.
context.Items[CachedResponseTypeKey] = imageFactory.CurrentImageFormat.MimeType;
context.Items[CachedResponseFileDependency] = new List<string> { requestPath, cachedPath };
}
}
}
Expand All @@ -434,26 +429,32 @@ private async Task ProcessImageAsync(HttpContext context)
// Image is from the cache so the mime-type will need to be set.
if (context.Items[CachedResponseTypeKey] == null)
{
context.Items[CachedResponseTypeKey] = ImageHelpers.GetExtension(cachedPath).Replace(".", "image/");
}
string mimetype = ImageHelpers.GetMimeType(cachedPath);

context.Items[CachedResponseFileDependency] = cachedPath;
if (!string.IsNullOrEmpty(mimetype))
{
context.Items[CachedResponseTypeKey] = mimetype;
}
}

string incomingEtag = context.Request.Headers["If" + "-None-Match"];

if (incomingEtag != null && !isNewOrUpdated)
{
// Explicitly set the Content-Length header so the client doesn't wait for
// content but keeps the connection open for other requests
// Set the Content-Length header so the client doesn't wait for
// content but keeps the connection open for other requests.
context.Response.AddHeader("Content-Length", "0");
context.Response.StatusCode = (int)HttpStatusCode.NotModified;
context.Response.SuppressContent = true;
this.SetHeaders(context, (string)context.Items[CachedResponseTypeKey], cachedPath);

if (!isRemote)
{
// Set the headers and quit.
this.SetHeaders(context, (string)context.Items[CachedResponseTypeKey], new List<string> { requestPath, cachedPath });
return;
}

this.SetHeaders(context, (string)context.Items[CachedResponseTypeKey], new List<string> { cachedPath });
}

// The cached file is valid so just rewrite the path.
Expand Down Expand Up @@ -483,10 +484,10 @@ private async Task ProcessImageAsync(HttpContext context)
/// <param name="responseType">
/// The HTTP MIME type to to send.
/// </param>
/// <param name="dependencyPath">
/// <param name="dependencyPaths">
/// The dependency path for the cache dependency.
/// </param>
private void SetHeaders(HttpContext context, string responseType, string dependencyPath)
private void SetHeaders(HttpContext context, string responseType, IEnumerable<string> dependencyPaths)
{
HttpResponse response = context.Response;

Expand All @@ -501,7 +502,7 @@ private void SetHeaders(HttpContext context, string responseType, string depende
cache.SetCacheability(HttpCacheability.Public);
cache.VaryByHeaders["Accept-Encoding"] = true;

context.Response.AddFileDependency(dependencyPath);
context.Response.AddFileDependencies(dependencyPaths.ToArray());
cache.SetLastModifiedFromFileDependencies();

int maxDays = DiskCache.MaxFileCachedDuration;
Expand Down

0 comments on commit e2c3b41

Please sign in to comment.