public async Task <IActionResult> GetSmallFileAsync(ControllerBase controller, LiteDatabase database, string fileId, HttpClient httpClient, string url, HashResult hashResult, string fileName = null, ILogger logger = null) { logger = logger ?? this._logger; var file = database.FileStorage.FindById(fileId); if (file == null) { this.HitData.GetFileCache.Miss(); var response = await httpClient.GetOrNullAsync(url, logger); if (response?.IsSuccessStatusCode != true) { var(code, message) = await response.GetErrorInfoAsync(); return(controller.StatusCode(code, message)); } if (fileName == null) { fileName = response.RequestMessage.RequestUri.Segments.Last(); } byte[] buffer; try { buffer = await response.Content.ReadAsByteArrayAsync(); } catch (IOException e) { logger.LogTrace("GET {} body -> {}", url, e); return(controller.StatusCode((int)HttpStatusCode.InternalServerError, e.Message)); } if (!hashResult.Equals(buffer)) { return(controller.StatusCode((int)HttpStatusCode.InternalServerError, "hashes not matches")); } file = database.FileStorage.Upload(fileId, fileName, new MemoryStream(buffer)); } else { this.HitData.GetFileCache.Hit(); } var downloads = file.Metadata.RawValue.GetValueOrDefault("Downloads", 0) + 1; if (downloads > 1) { logger.LogInformation("Hit file cache: {} ({})", url, downloads); } file.Metadata["Downloads"] = downloads; file.Metadata["LastUsed"] = DateTime.UtcNow; database.FileStorage.SetMetadata(fileId, file.Metadata); var stream = file.OpenRead(); controller.Response.RegisterForDispose(stream); return(controller.File(stream, "binary/octet-stream", file.Filename)); }