using System; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Text.Json; using API.Helpers; using Microsoft.AspNetCore.Http; namespace API.Extensions { public static class HttpExtensions { public static void AddPaginationHeader(this HttpResponse response, int currentPage, int itemsPerPage, int totalItems, int totalPages) { var paginationHeader = new PaginationHeader(currentPage, itemsPerPage, totalItems, totalPages); var options = new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; response.Headers.Add("Pagination", JsonSerializer.Serialize(paginationHeader, options)); response.Headers.Add("Access-Control-Expose-Headers", "Pagination"); } /// /// Calculates SHA256 hash for a byte[] and sets as ETag. Ensures Cache-Control: private header is added. /// /// /// If byte[] is null or empty, will only add cache-control public static void AddCacheHeader(this HttpResponse response, byte[] content) { if (content == null || content.Length <= 0) return; using var sha1 = SHA256.Create(); response.Headers.Add("ETag", string.Concat(sha1.ComputeHash(content).Select(x => x.ToString("X2")))); } /// /// Calculates SHA256 hash for a cover image filename and sets as ETag. Ensures Cache-Control: private header is added. /// /// /// /// Maximum amount of seconds to set for Cache-Control public static void AddCacheHeader(this HttpResponse response, string filename, int maxAge = 10) { if (filename is not {Length: > 0}) return; var hashContent = filename + File.GetLastWriteTimeUtc(filename); using var sha1 = SHA256.Create(); response.Headers.Add("ETag", string.Concat(sha1.ComputeHash(Encoding.UTF8.GetBytes(hashContent)).Select(x => x.ToString("X2")))); if (maxAge != 10) { response.Headers.CacheControl = $"max-age={maxAge}"; } } } }