Beispiel #1
0
        private async Task <IActionResult> ImageResult(string id, string slug, int w = 0, int h = 0, int quality = 100, string options = "")
        {
            byte[] bytes;
            try
            {
                var host = _fileService.GetHostConfig(slug);

                if (host.WhiteList != null && host.WhiteList.Any() && host.WhiteList.All(x => x != $"{w}x{h}")) //whitelist checking
                {
                    _logger.LogError("Image request cancelled due to whitelist.");
                    return(new StatusCodeResult((int)HttpStatusCode.BadRequest));
                }

                bytes = await _fileService.GetFileAsync(slug, id);

                if (bytes == null)
                {
                    _logger.LogWarning("File is empty or not found, we should get an exception instead!");
                    return(NotFound());
                }
            }
            catch (RedirectToFallbackException e)
            {
                _logger.LogWarning(e, e.Message);
                return(Redirect(string.IsNullOrEmpty(options)
                    ? $"/i/{slug}/{quality}/{w}x{h}/{e.FallbackImage}"
                    : $"/i/{slug}/{quality}/{w}x{h}/{options}/{e.FallbackImage}"));
            }
            catch (SlugNotFoundException e)
            {
                _logger.LogError(e, "Unknown host requested: " + e.Message);
                return(new StatusCodeResult((int)HttpStatusCode.BadRequest));
            }
            catch (GridFsObjectIdException e)
            {
                _logger.LogError(e, "GridFS ObjectId Parse Error:" + e.Message);
                return(new StatusCodeResult((int)HttpStatusCode.BadRequest));
            }
            catch (TimeoutException e)
            {
                _logger.LogError(e, "Timeout: " + e.Message);
                return(new StatusCodeResult((int)HttpStatusCode.GatewayTimeout));
            }
            catch (UnauthorizedAccessException e)
            {
                _logger.LogError(e, "Access denied: " + e.Message);
                return(new StatusCodeResult((int)HttpStatusCode.Unauthorized));
            }
            catch (System.IO.FileNotFoundException e)
            {
                _logger.LogError(e, "Filen not found: " + e.Message);
                return(new StatusCodeResult((int)HttpStatusCode.NotFound));
            }
            catch (Exception e)
            {
                _logger.LogError(e, e.Message);
                throw;
            }

            try
            {
                bytes = _imageService.GetImageAsBytes(w, h, quality, bytes, options, out var mimeType);

                if (bytes != null)
                {
                    var file = File(bytes, mimeType);

                    using (var sha = System.Security.Cryptography.SHA1.Create())
                    {
                        var hash     = sha.ComputeHash(bytes);
                        var checksum = $"\"{WebEncoders.Base64UrlEncode(hash)}\"";
                        file.EntityTag = new Microsoft.Net.Http.Headers.EntityTagHeaderValue(checksum);
                    }

                    return(file);
                }


                _logger.LogError("File found but image operation failed by unknown cause");
                return(StatusCode((int)HttpStatusCode.NotAcceptable));
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Image Service Error: " + e.Message);
                throw;
            }
        }
Beispiel #2
0
        private async Task <IActionResult> ImageResult(string id, string slug, int w = 0, int h = 0, int quality = 100, string options = "", string hash = "")
        {
            if (string.IsNullOrWhiteSpace(id))
            {
                _logger.LogError("Id is null");
                return(new StatusCodeResult((int)HttpStatusCode.BadRequest));
            }

            if (0 > w || 0 > h)
            {
                _logger.LogError("Width or height is negative");
                return(new StatusCodeResult((int)HttpStatusCode.BadRequest));
            }

            byte[]      bytes;
            CustomRatio customRatio = null;

            try
            {
                var host = _fileService.GetHostConfig(slug);

                if (host.WhiteList != null && host.WhiteList.Any() && host.WhiteList.All(x => x != $"{w}x{h}")) //whitelist checking
                {
                    _logger.LogError("Image request cancelled due to whitelist.");
                    return(new StatusCodeResult((int)HttpStatusCode.BadRequest));
                }

                if (w != 0 && h != 0 && !string.IsNullOrEmpty(hash) && host.Type == HostType.GridFs) //customratio & mongodb file
                {
                    var metadata = await _metadataService.GetFileMetadataAsync(host, id);

                    var ratio = (double)w / h; //image request ratio

                    customRatio = double.IsNaN(ratio)
                        ? metadata.CustomRatio.FirstOrDefault(x => x.Hash == hash)
                        : metadata.CustomRatio.FirstOrDefault(x => x.MinRatio < ratio && x.MaxRatio >= ratio);

                    if (customRatio == null) // request with hash but no customratio
                    {
                        _logger.LogError(
                            "Image request redirected due to wrong custom ratio hash (redirected to base url)");
                        return(Redirect(string.IsNullOrEmpty(options)
                            ? $"/i/{slug}/{quality}/{w}x{h}/{id}"
                            : $"/i/{slug}/{quality}/{w}x{h}/{options}/{id}"));
                    }

                    if (!double.IsNaN(ratio) && customRatio.Hash != hash) //hash is not correct
                    {
                        _logger.LogError(
                            "Image request redirected due to wrong custom ratio hash (redirected to new customRatio)");
                        return(Redirect(string.IsNullOrEmpty(options)
                            ? $"/i/{slug}/{quality}/{w}x{h}/h-{customRatio.Hash}/{id}"
                            : $"/i/{slug}/{quality}/{w}x{h}/{options}/h-{customRatio.Hash}/{id}"));
                    }
                }

                bytes = await _fileService.GetFileAsync(slug, id);

                if (bytes == null)
                {
                    _logger.LogError("File not found");
                    return(NotFound());
                }
            }
            catch (RedirectToFallbackException e)
            {
                _logger.LogWarning(e, e.Message);
                return(Redirect(string.IsNullOrEmpty(options)
                    ? $"/i/{slug}/{quality}/{w}x{h}/{e.FallbackImage}"
                    : $"/i/{slug}/{quality}/{w}x{h}/{options}/{e.FallbackImage}"));
            }
            catch (SlugNotFoundException e)
            {
                _logger.LogError(e, e.Message);
                return(new StatusCodeResult((int)HttpStatusCode.BadRequest));
            }
            catch (GridFsObjectIdException e)
            {
                _logger.LogError(e, "GridFS ObjectId Parse Error:" + e.Message);
                return(new StatusCodeResult((int)HttpStatusCode.BadRequest));
            }
            catch (TimeoutException e)
            {
                _logger.LogError(e, "Timeout: " + e.Message);
                return(new StatusCodeResult((int)HttpStatusCode.GatewayTimeout));
            }
            catch (Exception e)
            {
                _logger.LogError(e, e.Message);
                throw;
            }

            try
            {
                bytes = _imageService.GetImageAsBytes(w, h, quality, bytes, options, out var mime, customRatio);

                if (bytes != null)
                {
                    return(File(bytes, mime));
                }

                _logger.LogError("File found but image operation failed by unknown cause");
                return(StatusCode((int)HttpStatusCode.NotAcceptable));
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Image Service Error: " + e.Message);
                throw;
            }
        }