[ProducesResponseType(404)] // not found public IActionResult ListSizesByHash(string f) { // For serving jpeg files f = FilenamesHelper.GetFileNameWithoutExtension(f); // Restrict the fileHash to letters and digits only // I/O function calls should not be vulnerable to path injection attacks if (!Regex.IsMatch(f, "^[a-zA-Z0-9_-]+$")) { return(BadRequest()); } var data = new ThumbnailSizesExistStatusModel { TinyMeta = _thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, ThumbnailSize.TinyMeta)), Small = _thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, ThumbnailSize.Small)), Large = _thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, ThumbnailSize.Large)), ExtraLarge = _thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, ThumbnailSize.ExtraLarge)) }; // Success has all items (except tinyMeta) if (data.Small && data.Large && data.ExtraLarge) { return(Json(data)); } var sourcePath = _query.GetSubPathByHash(f); var isThumbnailSupported = ExtensionRolesHelper.IsExtensionThumbnailSupported(sourcePath); switch (isThumbnailSupported) { case true when !string.IsNullOrEmpty(sourcePath): Response.StatusCode = 202; return(Json(data)); case false when !string.IsNullOrEmpty(sourcePath): Response.StatusCode = 210; // A conflict, that the thumb is not generated yet return(Json("Thumbnail is not supported; for example you try to view a raw or video file")); default: return(NotFound("not in index")); } }
[ProducesResponseType(500)] // "Thumbnail generation failed" public async Task <IActionResult> DownloadPhoto(string f, bool isThumbnail = true, bool cache = true) { // f = subpath/filepath if (f.Contains("?isthumbnail")) { return(NotFound("please use &isthumbnail = " + "instead of ?isthumbnail= ")); } var fileIndexItem = await _query.GetObjectByFilePathAsync(f); if (fileIndexItem == null) { return(NotFound("not in index " + f)); } if (!_iStorage.ExistFile(fileIndexItem.FilePath)) { return(NotFound($"source image missing {fileIndexItem.FilePath}")); } // Return full image if (!isThumbnail) { if (cache) { CacheControlOverwrite.SetExpiresResponseHeaders(Request); } var fileStream = _iStorage.ReadStream(fileIndexItem.FilePath); // Return the right mime type (enableRangeProcessing = needed for safari and mp4) return(File(fileStream, MimeHelper.GetMimeTypeByFileName(fileIndexItem.FilePath), true)); } if (!_thumbnailStorage.ExistFolder("/")) { return(NotFound("ThumbnailTempFolder not found")); } var data = new ThumbnailSizesExistStatusModel { Small = _thumbnailStorage.ExistFile( ThumbnailNameHelper.Combine(fileIndexItem.FileHash, ThumbnailSize.Small)), Large = _thumbnailStorage.ExistFile( ThumbnailNameHelper.Combine(fileIndexItem.FileHash, ThumbnailSize.Large)), ExtraLarge = _thumbnailStorage.ExistFile( ThumbnailNameHelper.Combine(fileIndexItem.FileHash, ThumbnailSize.ExtraLarge)) }; if (!data.Small || !data.Large || !data.ExtraLarge) { await new Thumbnail(_iStorage, _thumbnailStorage, _logger).CreateThumb(fileIndexItem.FilePath, fileIndexItem.FileHash); if (!_thumbnailStorage.ExistFile( ThumbnailNameHelper.Combine(fileIndexItem.FileHash, ThumbnailSize.Large))) { Response.StatusCode = 500; return(Json("Thumbnail generation failed")); } } var thumbnailFs = _thumbnailStorage.ReadStream( ThumbnailNameHelper.Combine(fileIndexItem.FileHash, ThumbnailSize.Large)); return(File(thumbnailFs, "image/jpeg")); }