private async Task <byte[]> ProcessAndPutToCacheAsync(CachedImageResult cachedImage, byte[] buffer, ProcessImageQuery query) { if (!query.NeedsProcessing()) { await _imageCache.PutAsync(cachedImage, buffer); return(buffer); } else { var processQuery = new ProcessImageQuery(query) { Source = buffer, Format = query.Format ?? cachedImage.Extension, FileName = cachedImage.FileName, DisposeSource = true }; using (var result = _imageProcessor.ProcessImage(processQuery)) { var outBuffer = result.OutputStream.ToArray(); await _imageCache.PutAsync(cachedImage, outBuffer); if (cachedImage.Extension != result.FileExtension) { // jpg <> jpeg cachedImage.Path = Path.ChangeExtension(cachedImage.Path, result.FileExtension); cachedImage.Extension = result.FileExtension; } Logger.DebugFormat($"Processed image '{cachedImage.FileName}' in {result.ProcessTimeMs} ms.", null); return(outBuffer); } } }
private async Task <ActionResult> HandleImageAsync( ProcessImageQuery query, CachedImageResult cachedImage, string nameWithoutExtension, string mime, string extension, Func <string, Task <byte[]> > getSourceBufferAsync) { string prevMime = null; if (extension != cachedImage.Extension) { // The query requests another format. // Adjust extension and mime type fo proper ETag creation. extension = cachedImage.Extension; prevMime = mime; mime = MimeTypes.MapNameToMimeType(cachedImage.FileName); } try { if (!cachedImage.Exists) { // Lock concurrent requests to same resource using (await KeyedLock.LockAsync("MediaController.HandleImage." + cachedImage.Path)) { _imageCache.RefreshInfo(cachedImage); // File could have been processed by another request in the meantime, check again. if (!cachedImage.Exists) { // Call inner function byte[] source = await getSourceBufferAsync(prevMime); if (source == null || source.Length == 0) { return(NotFound(mime)); } source = await ProcessAndPutToCacheAsync(cachedImage, source, query); return(new CachedFileResult(mime, cachedImage.LastModifiedUtc.GetValueOrDefault(), () => source, source.LongLength)); } } } if (Request.HttpMethod == "HEAD") { return(new HttpStatusCodeResult(200)); } if (cachedImage.IsRemote && !_streamRemoteMedia) { // Redirect to existing remote file Response.ContentType = mime; return(Redirect(_imageCache.GetPublicUrl(cachedImage.Path))); } else { // Open existing stream return(new CachedFileResult(cachedImage.File, mime)); } } catch (Exception ex) { if (!(ex is ProcessImageException)) { // ProcessImageException is logged already in ImageProcessor Logger.ErrorFormat(ex, "Error processing media file '{0}'.", cachedImage.Path); } return(new HttpStatusCodeResult(500, ex.Message)); } }
private async Task <ActionResult> HandleImage( ProcessImageQuery query, CachedImageResult cachedImage, string nameWithoutExtension, string mime, string extension, Func <string, Task <byte[]> > getSourceBuffer) { string prevMime = null; if (extension != cachedImage.Extension) { // The query requests another format. // Adjust extension and mime type fo proper ETag creation. extension = cachedImage.Extension; prevMime = mime; mime = MimeTypes.MapNameToMimeType(cachedImage.FileName); } if (cachedImage.Exists) { if (ETagMatches(nameWithoutExtension, mime, cachedImage.LastModifiedUtc.Value)) { return(Content(null)); } } var isFaulted = false; try { if (!cachedImage.Exists) { // get the async (semaphore) locker specific to this key var keyLock = AsyncLock.Acquire("lock" + cachedImage.Path); // Lock concurrent requests to same resource using (await keyLock.LockAsync()) { _imageCache.RefreshInfo(cachedImage); // File could have been processed by another request in the meantime, check again. if (!cachedImage.Exists) { // Call inner function byte[] source = await getSourceBuffer(prevMime); if (source == null) { return(NotFound(mime)); } source = await ProcessAndPutToCacheAsync(cachedImage, source, query); return(File(source, mime)); } } } if (Request.HttpMethod == "HEAD") { return(new HttpStatusCodeResult(200)); } if (cachedImage.IsRemote && !_streamRemoteMedia) { // Redirect to existing remote file Response.ContentType = mime; return(Redirect(_imageCache.GetPublicUrl(cachedImage.Path))); } else { // Open existing stream return(File(cachedImage.File.OpenRead(), mime)); } } catch (Exception ex) { isFaulted = true; if (!(ex is ProcessImageException)) { // ProcessImageException is logged already in ImageProcessor Logger.ErrorFormat(ex, "Error processing media file '{0}'.", cachedImage.Path); } return(new HttpStatusCodeResult(500, ex.Message)); } finally { if (!isFaulted) { FinalizeRequest(nameWithoutExtension, mime, cachedImage.LastModifiedUtc.GetValueOrDefault()); } } }
public void HandleEvent(AppStartedEvent msg, ref CachedImageResult result) { }