Ejemplo n.º 1
0
        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));
        }