Exemple #1
0
        protected string GetCachedImagePath(int?mediaFileId, MediaPathData data, ProcessImageQuery query = null)
        {
            string result = "";

            // xxxxxxx
            if (mediaFileId.GetValueOrDefault() > 0)
            {
                result = mediaFileId.Value.ToString(IdFormatString);
            }

            //// INFO: (mm) don't include folder id in pathes for now. It results in more complex image cache invalidation code.
            //// xxxxxxx-f
            //if (data.Folder != null)
            //{
            //	result = result.Grow(data.Folder.Id.ToString(CultureInfo.InvariantCulture), "-");
            //}

            // xxxxxxx-f-abc
            result = result.Grow(data.FileTitle, "-");

            if (result.IsEmpty())
            {
                // files without name? No way!
                return(null);
            }

            if (query != null && query.NeedsProcessing())
            {
                // xxxxxxx-f-abc-w100-h100
                result += query.CreateHash();
            }

            if (_mediaSettings.MultipleThumbDirectories && result.Length > MaxDirLength)
            {
                // Get the first four letters of the file name
                // 0001/xxxxxxx-f-abc-w100-h100
                var subDirectoryName = result.Substring(0, MaxDirLength);
                result = subDirectoryName + "/" + result;
            }

            // 0001/xxxxxxx-f-abc-w100-h100.png
            return(result.Grow(data.Extension, "."));
        }
Exemple #2
0
        public virtual async Task <CachedImage> GetAsync(int?mediaFileId, MediaPathData pathData, ProcessImageQuery query = null)
        {
            Guard.NotNull(pathData, nameof(pathData));

            var resultExtension = query?.GetResultExtension();

            if (resultExtension != null)
            {
                pathData.Extension = resultExtension;
            }

            var imagePath = GetCachedImagePath(mediaFileId, pathData, query);
            var file      = await _fileSystem.GetFileAsync(BuildPath(imagePath));

            var result = new CachedImage(file)
            {
                Path      = imagePath,
                Extension = pathData.Extension,
                IsRemote  = _fileSystem.StorageConfiguration.IsCloudStorage
            };

            return(result);
        }
Exemple #3
0
        public virtual CachedImage Get(int?mediaFileId, MediaPathData data, ProcessImageQuery query = null)
        {
            Guard.NotNull(data, nameof(data));

            var resultExtension = query?.GetResultExtension();

            if (resultExtension != null)
            {
                data.Extension = resultExtension;
            }

            var imagePath = GetCachedImagePath(mediaFileId, data, query);
            var file      = _fileSystem.GetFile(BuildPath(imagePath));

            var result = new CachedImage(file)
            {
                Path      = imagePath,
                Extension = data.Extension,
                IsRemote  = _fileSystem.IsCloudStorage
            };

            return(result);
        }
        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));
            }
        }