etags
This commit is contained in:
@@ -27,8 +27,8 @@ namespace TerribleDev.Blog.Web.Controllers
|
||||
[Route("/index.html", Order = 2)]
|
||||
[Route("/")]
|
||||
[Route("/page/{pageNumber:required:int:min(1)}")]
|
||||
[OutputCache(Duration = 31536000, VaryByParam = "pageNumber")]
|
||||
[ResponseCache(Duration = 900)]
|
||||
[OutputCache(Duration = 31536000, VaryByParam = "pageNumber", VaryByHeader = "User-Agent")]
|
||||
// [ResponseCache(Duration = 900)]
|
||||
public IActionResult Index(int pageNumber = 1)
|
||||
{
|
||||
if(!postCache.PostsByPage.TryGetValue(pageNumber, out var result))
|
||||
@@ -47,7 +47,7 @@ namespace TerribleDev.Blog.Web.Controllers
|
||||
}
|
||||
[Route("/offline")]
|
||||
[Route("/offline.html")]
|
||||
[ResponseCache(Duration = 3600)]
|
||||
// [ResponseCache(Duration = 3600)]
|
||||
public IActionResult Offline()
|
||||
{
|
||||
return View();
|
||||
@@ -60,8 +60,8 @@ namespace TerribleDev.Blog.Web.Controllers
|
||||
}
|
||||
|
||||
[Route("{postUrl}/{amp?}")]
|
||||
[OutputCache(Duration = 31536000, VaryByParam = "postUrl,amp")]
|
||||
[ResponseCache(Duration = 900)]
|
||||
[OutputCache(Duration = 31536000, VaryByParam = "postUrl,amp", VaryByHeader = "User-Agent")]
|
||||
// [ResponseCache(Duration = 900)]
|
||||
public IActionResult Post(string postUrl, string amp = "")
|
||||
{
|
||||
if(!String.IsNullOrEmpty(amp) && amp != "amp")
|
||||
|
||||
@@ -18,13 +18,13 @@ namespace TerribleDev.Blog.Web.Controllers
|
||||
this.postCache = postCache;
|
||||
}
|
||||
[Route("/all-tags")]
|
||||
[OutputCache(Duration = 31536000)]
|
||||
[OutputCache(Duration = 31536000, VaryByHeader = "User-Agent")]
|
||||
public IActionResult AllTags()
|
||||
{
|
||||
return View(postCache.TagsToPosts);
|
||||
}
|
||||
[Route("/tags/{tagName}")]
|
||||
[OutputCache(Duration = 31536000, VaryByParam = "tagName")]
|
||||
[OutputCache(Duration = 31536000, VaryByParam = "tagName", VaryByHeader = "User-Agent")]
|
||||
public IActionResult TagPluralRedirect(string tagName)
|
||||
{
|
||||
if(string.IsNullOrEmpty(tagName))
|
||||
@@ -34,7 +34,7 @@ namespace TerribleDev.Blog.Web.Controllers
|
||||
return Redirect($"/tag/{tagName}/");
|
||||
}
|
||||
[Route("/tag/{tagName}")]
|
||||
[OutputCache(Duration = 31536000, VaryByParam = "tagName")]
|
||||
[OutputCache(Duration = 31536000, VaryByParam = "tagName", VaryByHeader = "User-Agent")]
|
||||
public IActionResult GetTag(string tagName)
|
||||
{
|
||||
if(!postCache.TagsToPosts.TryGetValue(tagName.ToLower(), out var models))
|
||||
|
||||
@@ -9,8 +9,13 @@ namespace TerribleDev.Blog.Web.Factories
|
||||
public class CodeFactory
|
||||
{
|
||||
private HttpClient httpClient = new HttpClient();
|
||||
private static Boolean IsDisabled = !String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("DISABLE_PRISMA"));
|
||||
public async Task<(string result, bool hasCode)> ReplaceFencedCode(string markdown)
|
||||
{
|
||||
if(CodeFactory.IsDisabled)
|
||||
{
|
||||
return (markdown, false);
|
||||
}
|
||||
|
||||
// regex grab all text between backticks
|
||||
var regex = new Regex(@"```(.*?)```", RegexOptions.Singleline);
|
||||
|
||||
@@ -17,16 +17,16 @@ namespace TerribleDev.Blog.Web.Filters
|
||||
logger.LogDebug("Did not find any links to push");
|
||||
return;
|
||||
}
|
||||
var linkData = links as System.Collections.Generic.List<string>;
|
||||
var linkData = links as System.Collections.Generic.List<PushUrl>;
|
||||
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 (url, AsProperty) = linkData[i];
|
||||
var resolvedUrl = url.StartsWith("~") ? context.HttpContext.Request.PathBase.ToString() + url.Substring(1) : url;
|
||||
headerBuilder.Append($"<{resolvedUrl}>; rel=preload; as=style");
|
||||
headerBuilder.Append($"<{resolvedUrl}>; rel=preload; as={AsProperty}");
|
||||
if(i < linkData.Count - 1) {
|
||||
headerBuilder.Append(", ");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,45 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TerribleDev.Blog.Web.Taghelpers
|
||||
{
|
||||
public class AbstractPlatformTagHelper
|
||||
public abstract class AbstractPlatformTagHelper : TagHelper
|
||||
{
|
||||
|
||||
static Regex MobileCheck = new Regex(@"(?:phone|windows\s+phone|ipod|blackberry|(?:android|bb\d+|meego|silk|googlebot) .+? mobile|palm|windows\s+ce|opera\ mini|avantgo|mobilesafari|docomo|ipad)", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ECMAScript);
|
||||
static ConcurrentDictionary<string, Platform> CachedChecks = new ConcurrentDictionary<string, Platform>(); // dictionary of user agent -> mobilre
|
||||
protected HttpRequest Request => ViewContext.HttpContext.Request;
|
||||
protected HttpResponse Response => ViewContext.HttpContext.Response;
|
||||
|
||||
[ViewContext]
|
||||
public ViewContext ViewContext { get; set; }
|
||||
protected abstract bool ShouldRender();
|
||||
public Platform GetPlatform()
|
||||
{
|
||||
var userAgent = this.Request.Headers.UserAgent;
|
||||
if (string.IsNullOrEmpty(userAgent))
|
||||
{
|
||||
return Platform.Desktop; // mobile is default
|
||||
}
|
||||
if(CachedChecks.TryGetValue(userAgent, out var cacheResult))
|
||||
{
|
||||
return cacheResult;
|
||||
}
|
||||
var isMobile = AbstractPlatformTagHelper.MobileCheck.IsMatch(this.Request.Headers.UserAgent);
|
||||
return isMobile ? Platform.Mobile : Platform.Desktop;
|
||||
}
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
output.TagName = null;
|
||||
if(!this.ShouldRender())
|
||||
{
|
||||
output.SuppressOutput();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TerribleDev.Blog.Web.Taghelpers
|
||||
{
|
||||
[HtmlTargetElement("desktop", TagStructure = TagStructure.NormalOrSelfClosing)]
|
||||
public class DesktopTagHelper : AbstractPlatformTagHelper
|
||||
{
|
||||
protected override bool ShouldRender() => this.GetPlatform() == Platform.Desktop;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,12 @@ using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
namespace TerribleDev.Blog.Web.Taghelpers
|
||||
{
|
||||
[HtmlTargetElement("link", Attributes = "rel, href, http-2-push")]
|
||||
public record PushUrl(string Url, string asProperty);
|
||||
[HtmlTargetElement("link", Attributes = "[rel=stylesheet],href,push")]
|
||||
[HtmlTargetElement("img", Attributes = "src,push")]
|
||||
public class HttpPush : LinkTagHelper
|
||||
{
|
||||
[HtmlAttributeNotBound]
|
||||
public bool Http2PushEnabled { get; set; } = true;
|
||||
|
||||
public static readonly string Key = "http2push-link";
|
||||
@@ -24,23 +27,34 @@ namespace TerribleDev.Blog.Web.Taghelpers
|
||||
{
|
||||
}
|
||||
|
||||
private (string Url, string AsProperty) GetTagInfo(string tag) =>
|
||||
tag switch {
|
||||
"link" => ("href", "link"),
|
||||
"img" => ("src", "image"),
|
||||
_ => (null, null)
|
||||
};
|
||||
|
||||
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<string> : null;
|
||||
var (urlAttribute, asProperty) = GetTagInfo(output.TagName);
|
||||
// var urlAttribute = context.TagName == "link" ? "href" : "src";
|
||||
var url = base.TryResolveUrl(output.Attributes[urlAttribute].Value.ToString(), out string resolvedUrl) ? resolvedUrl : output.Attributes[urlAttribute].Value.ToString();
|
||||
var linkList = ViewContext.HttpContext.Items.TryGetValue(Key, out var links) ? links as List<PushUrl> : null;
|
||||
|
||||
if(linkList == null)
|
||||
{
|
||||
linkList = new List<string>() { url };
|
||||
linkList = new List<PushUrl>() { new PushUrl(url, asProperty) };
|
||||
ViewContext.HttpContext.Items.Add(HttpPush.Key, linkList);
|
||||
}
|
||||
else
|
||||
{
|
||||
linkList.Add(url);
|
||||
linkList.Add(new PushUrl(url, asProperty));
|
||||
}
|
||||
output.Attributes.Remove(output.Attributes["push"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,35 +8,9 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace TerribleDev.Blog.Web.Taghelpers
|
||||
{
|
||||
[HtmlTargetElement("desktopOnly", TagStructure = TagStructure.NormalOrSelfClosing)]
|
||||
public class DesktopTagHelper : TagHelper
|
||||
[HtmlTargetElement("mobile", TagStructure = TagStructure.NormalOrSelfClosing)]
|
||||
public class MobileTagHelper : AbstractPlatformTagHelper
|
||||
{
|
||||
static Regex MobileCheck = new Regex(@"(?:phone|windows\s+phone|ipod|blackberry|(?:android|bb\d+|meego|silk|googlebot) .+? mobile|palm|windows\s+ce|opera\ mini|avantgo|mobilesafari|docomo|ipad)", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ECMAScript);
|
||||
static ConcurrentDictionary<string, bool> CachedChecks = new ConcurrentDictionary<string, bool>();
|
||||
public string UserAgent { get; set; }
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
|
||||
output.TagName = context.TagName;
|
||||
if (string.IsNullOrEmpty(UserAgent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var shouldRender = true;
|
||||
if(CachedChecks.TryGetValue(UserAgent, out var cacheResult))
|
||||
{
|
||||
shouldRender = cacheResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
var isMobile = MobileCheck.IsMatch(UserAgent);
|
||||
shouldRender = !isMobile;
|
||||
CachedChecks.TryAdd(UserAgent, !isMobile);
|
||||
}
|
||||
if(!shouldRender)
|
||||
{
|
||||
output.SuppressOutput();
|
||||
}
|
||||
}
|
||||
protected override bool ShouldRender() => this.GetPlatform() == Platform.Mobile;
|
||||
}
|
||||
}
|
||||
|
||||
8
src/TerribleDev.Blog.Web/Taghelpers/Platforms.cs
Normal file
8
src/TerribleDev.Blog.Web/Taghelpers/Platforms.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace TerribleDev.Blog.Web.Taghelpers
|
||||
{
|
||||
public enum Platform
|
||||
{
|
||||
Desktop,
|
||||
Mobile,
|
||||
}
|
||||
}
|
||||
@@ -10,10 +10,11 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<picture class="navHero">
|
||||
<source srcset="/content/tommyAvatar4.jpg.webp" loading="lazy" type="image/webp" alt="An image of TerribleDev" class="round" />
|
||||
<img src="/content/tommyAvatar4.jpg" loading="lazy" alt="An image of TerribleDev" class="round" />
|
||||
</picture>
|
||||
<desktop>
|
||||
<picture class="navHero">
|
||||
<img src="/content/tommyAvatar4.jpg.webp" loading="lazy" alt="An image of TerribleDev" class="round" push />
|
||||
</picture>
|
||||
</desktop>
|
||||
}
|
||||
<span>Tommy "Terrible Dev" Parnell</span>
|
||||
<ul class="sidebarBtns">
|
||||
|
||||
@@ -24,10 +24,22 @@
|
||||
else
|
||||
{
|
||||
<environment names="Development">
|
||||
<inline-style href="css/site.css,css/site.mobile.css,css/site.desktop.css"></inline-style>
|
||||
@* <inline-style href="css/site.css,css/site.mobile.css,css/site.desktop.css"></inline-style> *@
|
||||
<desktop>
|
||||
<inline-style href="css/site.css,css/site.desktop.css"></inline-style>
|
||||
</desktop>
|
||||
<mobile>
|
||||
<inline-style href="css/site.css,css/site.mobile.css"></inline-style>
|
||||
</mobile>
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<inline-style href="css/site.min.css,css/site.mobile.min.css,css/site.desktop.min.css"></inline-style>
|
||||
<desktop>
|
||||
<inline-style href="css/site.min.css,css/site.desktop.min.css"></inline-style>
|
||||
</desktop>
|
||||
<mobile>
|
||||
<inline-style href="css/site.min.css,css/site.mobile.min.css"></inline-style>
|
||||
</mobile>
|
||||
@* <inline-style href="css/site.min.css,css/site.mobile.min.css,css/site.desktop.min.css"></inline-style> *@
|
||||
</environment>
|
||||
}
|
||||
|
||||
@@ -43,7 +55,7 @@
|
||||
<link rel="alternate" type="application/atom+xml" title="RSS" href="/rss.xml">
|
||||
<link rel="manifest" href="~/manifest.json" asp-append-version="true">
|
||||
<meta name="author" content="Tommy "TerribleDev" Parnell" />
|
||||
<link asp-append-version="true" rel="icon" href="~/favicon.ico" />
|
||||
<link asp-append-version="true" rel="icon" href="~/favicon.ico" push />
|
||||
@RenderSection("Head", false)
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user