From 96d06da5e4cd4a8fd9dc59973a160bf6869ee887 Mon Sep 17 00:00:00 2001 From: Tommy Parnell Date: Wed, 1 Jun 2022 21:28:56 -0400 Subject: [PATCH] rename push header --- .../Controllers/HomeController.cs | 3 ++ .../Controllers/SearchController.cs | 2 + .../Controllers/TagsController.cs | 2 + .../Filters/Http2PushFilter.cs | 38 +++++++++++++++ src/TerribleDev.Blog.Web/Startup.cs | 11 +++-- .../Taghelpers/Http2Push.cs | 46 +++++++++++++++++++ .../Views/Shared/_Layout.cshtml | 12 ++--- src/TerribleDev.Blog.Web/appsettings.json | 5 -- 8 files changed, 105 insertions(+), 14 deletions(-) create mode 100644 src/TerribleDev.Blog.Web/Filters/Http2PushFilter.cs create mode 100644 src/TerribleDev.Blog.Web/Taghelpers/Http2Push.cs diff --git a/src/TerribleDev.Blog.Web/Controllers/HomeController.cs b/src/TerribleDev.Blog.Web/Controllers/HomeController.cs index da13b42..53edb65 100644 --- a/src/TerribleDev.Blog.Web/Controllers/HomeController.cs +++ b/src/TerribleDev.Blog.Web/Controllers/HomeController.cs @@ -7,9 +7,12 @@ using Microsoft.AspNetCore.Mvc; using TerribleDev.Blog.Web.Models; using System.IO; using Microsoft.AspNetCore.Html; +using TerribleDev.Blog.Web.Filters; +using Microsoft.Extensions.Logging; namespace TerribleDev.Blog.Web.Controllers { + [Http2PushFilter] public class HomeController : Controller { private readonly PostCache postCache; diff --git a/src/TerribleDev.Blog.Web/Controllers/SearchController.cs b/src/TerribleDev.Blog.Web/Controllers/SearchController.cs index 9392074..40860e5 100644 --- a/src/TerribleDev.Blog.Web/Controllers/SearchController.cs +++ b/src/TerribleDev.Blog.Web/Controllers/SearchController.cs @@ -2,10 +2,12 @@ using System; using System.ComponentModel.DataAnnotations; using System.Linq; using Microsoft.AspNetCore.Mvc; +using TerribleDev.Blog.Web.Filters; using TerribleDev.Blog.Web.Models; namespace TerribleDev.Blog.Web.Controllers { + [Http2PushFilter] public class SearchController : Controller { private readonly BlogConfiguration configuration; diff --git a/src/TerribleDev.Blog.Web/Controllers/TagsController.cs b/src/TerribleDev.Blog.Web/Controllers/TagsController.cs index b6b2958..f69170e 100644 --- a/src/TerribleDev.Blog.Web/Controllers/TagsController.cs +++ b/src/TerribleDev.Blog.Web/Controllers/TagsController.cs @@ -3,10 +3,12 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using TerribleDev.Blog.Web.Filters; using TerribleDev.Blog.Web.Models; namespace TerribleDev.Blog.Web.Controllers { + [Http2PushFilter] public class TagsController : Controller { private readonly PostCache postCache; diff --git a/src/TerribleDev.Blog.Web/Filters/Http2PushFilter.cs b/src/TerribleDev.Blog.Web/Filters/Http2PushFilter.cs new file mode 100644 index 0000000..ba2b0ee --- /dev/null +++ b/src/TerribleDev.Blog.Web/Filters/Http2PushFilter.cs @@ -0,0 +1,38 @@ +using System; +using System.Text; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Logging; +using TerribleDev.Blog.Web.Taghelpers; + +namespace TerribleDev.Blog.Web.Filters +{ + public class Http2PushFilter : ActionFilterAttribute + { + public override void OnResultExecuted(ResultExecutedContext context) + { + var logger = context.HttpContext.RequestServices.GetService(typeof(ILogger)) as ILogger; + logger.LogDebug("Http2PushFilter.OnActionExecuted"); + if(!context.HttpContext.Items.TryGetValue(HttpPush.Key, out var links)) + { + logger.LogDebug("Did not find any links to push"); + return; + } + var linkData = links as System.Collections.Generic.List; + if(linkData == null || linkData.Count == 0) { + logger.LogDebug("Http2PushFilter.OnActionExecuted: No links"); + return; + } + var headerBuilder = new StringBuilder(); + for(var i = 0; i < linkData.Count; i++) { + var url = linkData[i]; + var resolvedUrl = url.StartsWith("~") ? context.HttpContext.Request.PathBase.ToString() + url.Substring(1) : url; + headerBuilder.Append($"<{resolvedUrl}>; rel=preload; as=style"); + if(i < linkData.Count - 1) { + headerBuilder.Append(", "); + } + } + logger.LogDebug("Http2PushFilter.OnActionExecuted: " + headerBuilder.ToString()); + context.HttpContext.Response.Headers.Add("Link", headerBuilder.ToString()); + } + } +} \ No newline at end of file diff --git a/src/TerribleDev.Blog.Web/Startup.cs b/src/TerribleDev.Blog.Web/Startup.cs index 6784892..1ec418f 100644 --- a/src/TerribleDev.Blog.Web/Startup.cs +++ b/src/TerribleDev.Blog.Web/Startup.cs @@ -13,6 +13,7 @@ using TerribleDev.Blog.Web.Models; using TerribleDev.Blog.Web.Factories; using Microsoft.Extensions.Hosting; using WebMarkupMin.AspNetCore6; +using Microsoft.Extensions.Logging; namespace TerribleDev.Blog.Web { @@ -43,6 +44,8 @@ namespace TerribleDev.Blog.Web { services.AddSingleton(blogConfiguration); } + // enable logging + services.AddLogging(); services.AddSingleton((i) => { var posts = new BlogFactory().GetAllPostsAsync(Env.IsDevelopment() ? "https://localhost:5001": "https://blog.terrible.dev").Result; var postCache = BlogCacheFactory.ProjectPostCache(posts); @@ -67,8 +70,7 @@ namespace TerribleDev.Blog.Web a.EnableForHttps = true; }) - .AddMemoryCache() - .AddOutputCaching(); + .AddMemoryCache(); services.AddWebMarkupMin(a => { a.AllowMinificationInDevelopmentEnvironment = true; a.DisablePoweredByHttpHeaders = true; @@ -132,7 +134,10 @@ namespace TerribleDev.Blog.Web // }, UpgradeInsecureRequests = true }); - app.UseOutputCaching(); + if(env.IsProduction()) + { + app.UseOutputCaching(); + } app.UseWebMarkupMin(); app.UseRouting(); app.UseEndpoints(endpoints => diff --git a/src/TerribleDev.Blog.Web/Taghelpers/Http2Push.cs b/src/TerribleDev.Blog.Web/Taghelpers/Http2Push.cs new file mode 100644 index 0000000..3c86002 --- /dev/null +++ b/src/TerribleDev.Blog.Web/Taghelpers/Http2Push.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Encodings.Web; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Razor.Infrastructure; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.Routing; +using Microsoft.AspNetCore.Mvc.TagHelpers; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Razor.TagHelpers; + +namespace TerribleDev.Blog.Web.Taghelpers +{ + [HtmlTargetElement("link", Attributes = "rel, href, http-2-push")] + public class HttpPush : LinkTagHelper + { + public bool Http2PushEnabled { get; set; } = true; + + public static readonly string Key = "http2push-link"; + + public HttpPush(IWebHostEnvironment hostingEnvironment, TagHelperMemoryCacheProvider cacheProvider, IFileVersionProvider fileVersionProvider, HtmlEncoder htmlEncoder, JavaScriptEncoder javaScriptEncoder, IUrlHelperFactory urlHelperFactory) : base(hostingEnvironment, cacheProvider, fileVersionProvider, htmlEncoder, javaScriptEncoder, urlHelperFactory) + { + } + + public override void Process(TagHelperContext context, TagHelperOutput output) + { + if(!this.Http2PushEnabled) + { + return; + } + var url = base.TryResolveUrl(output.Attributes["href"].Value.ToString(), out string resolvedUrl) ? resolvedUrl : output.Attributes["href"].Value.ToString(); + var linkList = ViewContext.HttpContext.Items.TryGetValue(Key, out var links) ? links as List : null; + if(linkList == null) + { + linkList = new List() { url }; + ViewContext.HttpContext.Items.Add(HttpPush.Key, linkList); + } + else + { + linkList.Add(url); + } + } + } +} \ No newline at end of file diff --git a/src/TerribleDev.Blog.Web/Views/Shared/_Layout.cshtml b/src/TerribleDev.Blog.Web/Views/Shared/_Layout.cshtml index e8fb543..2276d84 100644 --- a/src/TerribleDev.Blog.Web/Views/Shared/_Layout.cshtml +++ b/src/TerribleDev.Blog.Web/Views/Shared/_Layout.cshtml @@ -29,22 +29,22 @@ else { - + - + - + - + - + - + diff --git a/src/TerribleDev.Blog.Web/appsettings.json b/src/TerribleDev.Blog.Web/appsettings.json index c482656..63554e6 100644 --- a/src/TerribleDev.Blog.Web/appsettings.json +++ b/src/TerribleDev.Blog.Web/appsettings.json @@ -2,11 +2,6 @@ "Logging": { "LogLevel": { "Default": "Warning" - }, - "Console": { - "LogLevel": { - "Default": "None" - } } }, "AllowedHosts": "*",