public async Task <IActionResult> FileAsync(string id, string slug) { Response.Headers.Add("Access-Control-Allow-Origin", "*"); byte[] bytes; if (string.IsNullOrWhiteSpace(id)) { _logger.LogError("Id is null"); return(new StatusCodeResult((int)HttpStatusCode.BadRequest)); } try { bytes = await _fileService.GetFileAsync(slug, id); } 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 (Exception e) { _logger.LogError(e, e.Message); throw; } if (bytes != null) { var file = File(bytes, "application/octet-stream"); 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 not found"); return(NotFound()); }
public async Task <IActionResult> FileAsync(string id, string slug) { byte[] bytes; if (string.IsNullOrWhiteSpace(id)) { _logger.LogError("Id is null"); return(new StatusCodeResult((int)HttpStatusCode.BadRequest)); } try { bytes = await _fileService.GetFileAsync(slug, id); } 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; } if (bytes != null) { return(File(bytes, "application/octet-stream")); } _logger.LogError("File not found"); return(NotFound()); }
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; } }
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; } }