Esempio n. 1
0
        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));
            }
        }
Esempio n. 2
0
        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());
                }
            }
        }