/// <summary>
/// Processes the image.
/// </summary>
/// <param name="context">
/// the <see cref="T:System.Web.HttpContext">HttpContext</see> object that provides
/// references to the intrinsic server objects
/// </param>
/// <returns>
/// The <see cref="T:System.Threading.Tasks.Task"/>.
/// </returns>
private async Task ProcessImageAsync(HttpContext context)
{
HttpRequest request = context.Request;
bool isRemote = request.Path.Equals(RemotePrefix, StringComparison.OrdinalIgnoreCase);
string requestPath = string.Empty;
string queryString = string.Empty;
if (isRemote)
{
// We need to split the querystring to get the actual values we want.
string urlDecode = HttpUtility.UrlDecode(request.QueryString.ToString());
if (urlDecode != null)
{
string[] paths = urlDecode.Split('?');
requestPath = paths[0];
if (paths.Length > 1)
{
queryString = paths[1];
}
}
}
else
{
requestPath = HostingEnvironment.MapPath(request.Path);
queryString = HttpUtility.UrlDecode(request.QueryString.ToString());
}
// Only process requests that pass our sanitizing filter.
if (ImageUtils.IsValidImageExtension(requestPath) && !string.IsNullOrWhiteSpace(queryString))
{
string fullPath = string.Format("{0}?{1}", requestPath, queryString);
string imageName = Path.GetFileName(requestPath);
// Create a new cache to help process and cache the request.
DiskCache cache = new DiskCache(request, requestPath, fullPath, imageName, isRemote);
// Is the file new or updated?
bool isNewOrUpdated = await cache.IsNewOrUpdatedFileAsync();
// Only process if the file has been updated.
if (isNewOrUpdated)
{
// Process the image.
using (ImageFactory imageFactory = new ImageFactory())
{
if (isRemote)
{
Uri uri = new Uri(requestPath);
RemoteFile remoteFile = new RemoteFile(uri, false);
// Prevent response blocking.
WebResponse webResponse = await remoteFile.GetWebResponseAsync().ConfigureAwait(false);
using (MemoryStream memoryStream = new MemoryStream())
{
using (WebResponse response = webResponse)
{
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
// Trim the cache.
await cache.TrimCachedFoldersAsync();
responseStream.CopyTo(memoryStream);
imageFactory.Load(memoryStream)
.AddQueryString(queryString)
.Format(ImageUtils.GetImageFormat(imageName))
.AutoProcess().Save(cache.CachedPath);
// Ensure that the LastWriteTime property of the source and cached file match.
DateTime dateTime = await cache.SetCachedLastWriteTimeAsync();
// Add to the cache.
await cache.AddImageToCacheAsync(dateTime);
}
}
}
}
}
else
{
// Trim the cache.
await cache.TrimCachedFoldersAsync();
imageFactory.Load(fullPath).AutoProcess().Save(cache.CachedPath);
// Ensure that the LastWriteTime property of the source and cached file match.
DateTime dateTime = await cache.SetCachedLastWriteTimeAsync();
// Add to the cache.
await cache.AddImageToCacheAsync(dateTime);
}
}
}
// Store the response type in the context for later retrieval.
context.Items[CachedResponseTypeKey] = ImageUtils.GetResponseType(fullPath).ToDescription();
// The cached file is valid so just rewrite the path.
context.RewritePath(cache.GetVirtualCachedPath(), false);
}
}