public void should_build_etag()
        {
            var fileModifiedAtUtc = DateTime.Parse("2002/2/13 0:00:00");

            var etag = _tagBuilder.EntityTagBuild(fileModifiedAtUtc, 4166);

            Assert.Equal("\"1c1b4216127d046\"", etag.Tag.ToString());
        }
示例#2
0
        public async Task <IActionResult> DownloadFile(string slug, [FromQuery] bool?download)
        {
            var fileRecord = _fileRepo.All().FirstOrDefault(f => f.Slug.ToLower() == slug.ToLower());

            if (fileRecord == null)
            {
                return(NotFound());
            }
            var file = await _fileSystem.GetFileAsync(fileRecord.StoragePath);

            if (file == null)
            {
                return(NotFound());
            }

            var shouldDownload = download.HasValue && download.Value;
            var entityTag      = _tagbuilder.EntityTagBuild(fileRecord.ModifiedAtUtc, file.GetSize());

            if (!shouldDownload)
            {
                var modifiedSinceHeader = Request.Headers["If-Modified-Since"];
                var modifiedSinceUtc    = DateTimeOffset.MinValue;
                var formatValid         = modifiedSinceHeader.Any() &&
                                          DateTimeOffset.TryParseExact(modifiedSinceHeader.ToString(), "R", CultureInfo.InvariantCulture, DateTimeStyles.None, out modifiedSinceUtc);
                if (formatValid && modifiedSinceUtc.UtcDateTime >= fileRecord.ModifiedAtUtc)
                {
                    return(new StatusCodeResult(304));
                }

                var etagHeader = Request.Headers["If-None-Match"];
                if (etagHeader.Any() && entityTag.Tag.Value.Trim('\"').Equals(etagHeader.ToString().Trim('\"')))
                {
                    return(new StatusCodeResult(304));
                }
            }

            var buffered = new BufferedStream(await file.OpenReadAsync(), 8 * 1024);

            if (!_contentTypeProvider.TryGetContentType(fileRecord.OriginalName, out var contentType))
            {
                contentType = "application/octet-stream";
            }
            return(new FileStreamResult(buffered, contentType)
            {
                FileDownloadName = shouldDownload ? fileRecord.OriginalName : null,
                EntityTag = entityTag,
                LastModified = new DateTimeOffset(fileRecord.ModifiedAtUtc, TimeSpan.Zero)
            });
        }