From 7b69fe9439cc99e5433eb468b59f64c0a46e4352 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Wed, 18 May 2022 20:42:12 -0400 Subject: [PATCH] Return 404 if page URLs have extra content at the end --- src/MyWebLog/Handlers/Post.fs | 88 +++++++++++++++++++---------------- src/MyWebLog/appsettings.json | 2 +- 2 files changed, 49 insertions(+), 41 deletions(-) diff --git a/src/MyWebLog/Handlers/Post.fs b/src/MyWebLog/Handlers/Post.fs index c67ef7c..eefb2e8 100644 --- a/src/MyWebLog/Handlers/Post.fs +++ b/src/MyWebLog/Handlers/Post.fs @@ -9,7 +9,11 @@ open Microsoft.AspNetCore.Http let private pathAndPageNumber (ctx : HttpContext) = let slugs = (string ctx.Request.RouteValues["slug"]).Split "/" |> Array.filter (fun it -> it <> "") let pageIdx = Array.IndexOf (slugs, "page") - let pageNbr = if pageIdx > 0 then (int64 slugs[pageIdx + 1]) else 1L + let pageNbr = + match pageIdx with + | -1 -> Some 1L + | idx when idx + 2 = slugs.Length -> Some (int64 slugs[pageIdx + 1]) + | _ -> None let slugParts = if pageIdx > 0 then Array.truncate pageIdx slugs else slugs pageNbr, String.Join ("/", slugParts) @@ -101,27 +105,29 @@ let pageOfPosts pageNbr : HttpHandler = fun next ctx -> task { // GET /category/{slug}/ // GET /category/{slug}/page/{pageNbr} let pageOfCategorizedPosts : HttpHandler = fun next ctx -> task { - let webLog = WebLogCache.get ctx - let conn = conn ctx - let pageNbr, slug = pathAndPageNumber ctx - let allCats = CategoryCache.get ctx - let cat = allCats |> Array.find (fun cat -> cat.slug = slug) - // Category pages include posts in subcategories - let catIds = - allCats - |> Seq.ofArray - |> Seq.filter (fun c -> c.id = cat.id || Array.contains cat.name c.parentNames) - |> Seq.map (fun c -> CategoryId c.id) - |> List.ofSeq - match! Data.Post.findPageOfCategorizedPosts webLog.id catIds pageNbr webLog.postsPerPage conn with - | posts when List.length posts > 0 -> - let! hash = preparePostList webLog posts CategoryList cat.slug pageNbr webLog.postsPerPage ctx conn - let pgTitle = if pageNbr = 1L then "" else $""" (Page {pageNbr})""" - hash.Add ("page_title", $"{cat.name}: Category Archive{pgTitle}") - hash.Add ("subtitle", cat.description.Value) - hash.Add ("is_category", true) - return! themedView "index" next ctx hash - | _ -> return! Error.notFound next ctx + let webLog = WebLogCache.get ctx + let conn = conn ctx + match pathAndPageNumber ctx with + | Some pageNbr, slug -> + let allCats = CategoryCache.get ctx + let cat = allCats |> Array.find (fun cat -> cat.slug = slug) + // Category pages include posts in subcategories + let catIds = + allCats + |> Seq.ofArray + |> Seq.filter (fun c -> c.id = cat.id || Array.contains cat.name c.parentNames) + |> Seq.map (fun c -> CategoryId c.id) + |> List.ofSeq + match! Data.Post.findPageOfCategorizedPosts webLog.id catIds pageNbr webLog.postsPerPage conn with + | posts when List.length posts > 0 -> + let! hash = preparePostList webLog posts CategoryList cat.slug pageNbr webLog.postsPerPage ctx conn + let pgTitle = if pageNbr = 1L then "" else $""" (Page {pageNbr})""" + hash.Add ("page_title", $"{cat.name}: Category Archive{pgTitle}") + hash.Add ("subtitle", cat.description.Value) + hash.Add ("is_category", true) + return! themedView "index" next ctx hash + | _ -> return! Error.notFound next ctx + | None, _ -> return! Error.notFound next ctx } open System.Web @@ -129,25 +135,27 @@ open System.Web // GET /tag/{tag}/ // GET /tag/{tag}/page/{pageNbr} let pageOfTaggedPosts : HttpHandler = fun next ctx -> task { - let webLog = WebLogCache.get ctx - let conn = conn ctx - let pageNbr, rawTag = pathAndPageNumber ctx - let tag = HttpUtility.UrlDecode rawTag - match! Data.Post.findPageOfTaggedPosts webLog.id tag pageNbr webLog.postsPerPage conn with - | posts when List.length posts > 0 -> - let! hash = preparePostList webLog posts TagList rawTag pageNbr webLog.postsPerPage ctx conn - let pgTitle = if pageNbr = 1L then "" else $""" (Page {pageNbr})""" - hash.Add ("page_title", $"Posts Tagged “{tag}”{pgTitle}") - hash.Add ("is_tag", true) - return! themedView "index" next ctx hash - // Other systems use hyphens for spaces; redirect if this is an old tag link - | _ -> - let spacedTag = tag.Replace ("-", " ") - match! Data.Post.findPageOfTaggedPosts webLog.id spacedTag pageNbr 1 conn with + let webLog = WebLogCache.get ctx + let conn = conn ctx + match pathAndPageNumber ctx with + | Some pageNbr, rawTag -> + let tag = HttpUtility.UrlDecode rawTag + match! Data.Post.findPageOfTaggedPosts webLog.id tag pageNbr webLog.postsPerPage conn with | posts when List.length posts > 0 -> - let endUrl = if pageNbr = 1L then "" else $"page/{pageNbr}" - return! redirectTo true $"""/tag/{spacedTag.Replace (" ", "+")}/{endUrl}""" next ctx - | _ -> return! Error.notFound next ctx + let! hash = preparePostList webLog posts TagList rawTag pageNbr webLog.postsPerPage ctx conn + let pgTitle = if pageNbr = 1L then "" else $""" (Page {pageNbr})""" + hash.Add ("page_title", $"Posts Tagged “{tag}”{pgTitle}") + hash.Add ("is_tag", true) + return! themedView "index" next ctx hash + // Other systems use hyphens for spaces; redirect if this is an old tag link + | _ -> + let spacedTag = tag.Replace ("-", " ") + match! Data.Post.findPageOfTaggedPosts webLog.id spacedTag pageNbr 1 conn with + | posts when List.length posts > 0 -> + let endUrl = if pageNbr = 1L then "" else $"page/{pageNbr}" + return! redirectTo true $"""/tag/{spacedTag.Replace (" ", "+")}/{endUrl}""" next ctx + | _ -> return! Error.notFound next ctx + | None, _ -> return! Error.notFound next ctx } // GET / diff --git a/src/MyWebLog/appsettings.json b/src/MyWebLog/appsettings.json index ec1c59d..70a2d94 100644 --- a/src/MyWebLog/appsettings.json +++ b/src/MyWebLog/appsettings.json @@ -3,5 +3,5 @@ "hostname": "data02.bitbadger.solutions", "database": "myWebLog_dev" }, - "Generator": "myWebLog 2.0-alpha03" + "Generator": "myWebLog 2.0-alpha04" }