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()); }
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) }); }