Beispiel #1
0
        public async Task <ActionResult> File(int id /* mediaFileId */, string path)
        {
            MediaFileInfo mediaFile = null;
            MediaPathData pathData  = null;

            if (id == 0)
            {
                // This is most likely a request for a default placeholder image
                pathData = new MediaPathData(path);
            }
            else if (!_mediaHelper.TokenizePath(path, false, out pathData))
            {
                // Missing or malformed Uri: get file metadata from DB by id, but only when current user has media manage rights
                if (!_permissionService.Authorize(Permissions.Media.Update))
                {
                    return(NotFound(null));
                }

                mediaFile = _mediaService.GetFileById(id, MediaLoadFlags.AsNoTracking);
                if (mediaFile == null || mediaFile.FolderId == null || mediaFile.Deleted)
                {
                    return(NotFound(mediaFile?.MimeType));
                }

                pathData = new MediaPathData(_folderService.GetNodeById(mediaFile.FolderId.Value), mediaFile.Name)
                {
                    Extension = mediaFile.Extension,
                    MimeType  = mediaFile.MimeType
                };
            }

            var q = CreateImageQuery(pathData.MimeType, pathData.Extension);

            // Security: check allowed thumnail sizes and return 404 if disallowed.
            var thumbSizeAllowed = IsThumbnailSizeAllowed(q.MaxWidth) && (q.MaxHeight == q.MaxWidth || IsThumbnailSizeAllowed(q.MaxHeight));

            if (!thumbSizeAllowed)
            {
                return(NotFound(pathData.MimeType));
            }

            var handlerContext = new MediaHandlerContext
            {
                HttpContext       = HttpContext,
                CurrentCustomer   = _workContext.CurrentCustomer,
                PermissionService = _permissionService,
                MediaFileId       = id,
                RawPath           = path,
                MediaService      = _mediaService,
                PathData          = pathData,
                SourceFile        = mediaFile,
                ImageQuery        = q
            };

            var handlers = _mediaHandlers.Value.OrderBy(x => x.Order).ToArray();

            IMediaHandler currentHandler;

            for (var i = 0; i < handlers.Length; i++)
            {
                currentHandler = handlers[i];

                // Execute handler
                await currentHandler.ExecuteAsync(handlerContext);

                if (handlerContext.Exception != null)
                {
                    var isThumbExtractFail = handlerContext.Exception is ExtractThumbnailException;
                    var statusCode         = isThumbExtractFail ? HttpStatusCode.NoContent : HttpStatusCode.InternalServerError;
                    var statusMessage      = isThumbExtractFail ? handlerContext.Exception.InnerException?.Message.EmptyNull() : handlerContext.Exception.Message;

                    return(new HttpStatusCodeResult(statusCode, statusMessage));
                }

                if (handlerContext.Executed || handlerContext.ResultFile != null)
                {
                    // Get out if the handler produced a result file or has been executed in any way
                    break;
                }
            }

            try
            {
                var responseFile = handlerContext.ResultFile ?? handlerContext.SourceFile;
                if (responseFile == null || !responseFile.Exists)
                {
                    return(NotFound(pathData.MimeType));
                }

                if (string.Equals(responseFile.Extension, "." + pathData.Extension, StringComparison.CurrentCultureIgnoreCase))
                {
                    pathData.MimeType = MimeTypes.MapNameToMimeType(responseFile.Extension);
                }

                return(new CachedFileResult(responseFile, pathData.MimeType));
            }
            finally
            {
                Debug.WriteLine("ImageProcessor TOTAL: {0} ms.".FormatCurrent(EngineContext.Current.Resolve <IImageProcessor>().TotalProcessingTimeMs));
            }
        }
        public async Task <ActionResult> File(int id /* mediaFileId */, string path)
        {
            MediaFileInfo mediaFile = null;
            MediaPathData pathData  = null;

            if (id == 0)
            {
                // This is most likely a request for a default placeholder image
                pathData = new MediaPathData(path);
            }
            else if (!_mediaHelper.TokenizePath(path, out pathData))
            {
                // Missing or malformed Uri: get file metadata from DB by id, but only when current user has media manage rights
                if (!_permissionService.Authorize(Permissions.Media.Update))
                {
                    return(NotFound(null));
                }

                mediaFile = _mediaService.GetFileById(id, MediaLoadFlags.AsNoTracking);
                if (mediaFile == null || mediaFile.FolderId == null || mediaFile.Deleted)
                {
                    return(NotFound(mediaFile?.MimeType));
                }

                pathData = new MediaPathData(_folderService.GetNodeById(mediaFile.FolderId.Value), mediaFile.Name)
                {
                    Extension = mediaFile.Extension,
                    MimeType  = mediaFile.MimeType
                };
            }

            var handlerContext = new MediaHandlerContext
            {
                HttpContext       = HttpContext,
                CurrentCustomer   = _workContext.CurrentCustomer,
                PermissionService = _permissionService,
                MediaFileId       = id,
                RawPath           = path,
                MediaService      = _mediaService,
                PathData          = pathData,
                SourceFile        = mediaFile,
                ImageQuery        = CreateImageQuery(pathData.MimeType, pathData.Extension)
            };

            var handlers = _mediaHandlers.Value.OrderBy(x => x.Order).ToArray();

            IMediaHandler currentHandler;

            for (var i = 0; i < handlers.Length; i++)
            {
                currentHandler = handlers[i];

                // Execute handler
                await currentHandler.ExecuteAsync(handlerContext);

                if (handlerContext.Exception != null)
                {
                    var isThumbExtractFail = handlerContext.Exception is ExtractThumbnailException;
                    var statusCode         = isThumbExtractFail ? HttpStatusCode.NoContent : HttpStatusCode.InternalServerError;
                    var statusMessage      = isThumbExtractFail ? handlerContext.Exception.InnerException?.Message.EmptyNull() : handlerContext.Exception.Message;

                    return(new HttpStatusCodeResult(statusCode, statusMessage));
                }

                if (handlerContext.Executed || handlerContext.ResultFile != null)
                {
                    // Get out if the handler produced a result file or has been executed in any way
                    break;
                }
            }

            var responseFile = handlerContext.ResultFile ?? handlerContext.SourceFile;

            if (responseFile == null || !responseFile.Exists)
            {
                return(NotFound(pathData.MimeType));
            }

            if (handlerContext.ResultStream != null)
            {
                // A result stream instance is given when the file has just been processed by a media handler during this request.
                // In this case there is no need to open the stream from storage again.
                return(new CachedFileResult(MimeTypes.MapNameToMimeType(responseFile.Name), responseFile.LastUpdated, () => handlerContext.ResultStream, handlerContext.ResultStream.Length));
            }
            else
            {
                return(new CachedFileResult(responseFile, pathData.MimeType));
            }
        }