From 84617c3e96220493b26316ee26fa6b48a959ecf7 Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Wed, 26 Oct 2022 15:24:10 +0800 Subject: [PATCH] refactor: ignore trailing separator for permalink router (#2632) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area core /milestone 2.0 #### What this PR does / why we need it: permalink 路由匹配时自动忽略末尾分隔符 例如 /archives 匹配到 /archives /archives/ 匹配到 /archives #### Special notes for your reviewer: /cc @halo-dev/sig-halo #### Does this PR introduce a user-facing change? ```release-note None ``` --- .../app/theme/router/RadixRouterTree.java | 5 ++- .../strategy/ArchivesRouteStrategy.java | 3 +- .../app/theme/router/RadixRouterTreeTest.java | 44 +++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 src/test/java/run/halo/app/theme/router/RadixRouterTreeTest.java diff --git a/src/main/java/run/halo/app/theme/router/RadixRouterTree.java b/src/main/java/run/halo/app/theme/router/RadixRouterTree.java index 1a2d5f38e..787f9be50 100644 --- a/src/main/java/run/halo/app/theme/router/RadixRouterTree.java +++ b/src/main/java/run/halo/app/theme/router/RadixRouterTree.java @@ -125,7 +125,7 @@ public class RadixRouterTree extends RadixTree> * TODO Optimize parameter route matching query. * Router 仅匹配请求方法和请求的 URL 路径, 形如 /?p=post-name 是 URL query,而不是 URL 路径的一部分。 */ - private String pathToFind(ServerRequest request) { + static String pathToFind(ServerRequest request) { String requestPath = processRequestPath(request.path()); MultiValueMap queryParams = request.queryParams(); // 文章的 permalink 规则需要对 p 参数规则特殊处理 @@ -141,6 +141,7 @@ public class RadixRouterTree extends RadixTree> requestPath = requestPath.substring(0, i); } } + requestPath = StringUtils.removeEnd(requestPath, "/"); return StringUtils.prependIfMissing(requestPath, "/"); } @@ -177,7 +178,7 @@ public class RadixRouterTree extends RadixTree> } } - private String processRequestPath(String requestPath) { + private static String processRequestPath(String requestPath) { String path = StringUtils.prependIfMissing(requestPath, "/"); return UriUtils.decode(path, StandardCharsets.UTF_8); } diff --git a/src/main/java/run/halo/app/theme/router/strategy/ArchivesRouteStrategy.java b/src/main/java/run/halo/app/theme/router/strategy/ArchivesRouteStrategy.java index f64b8c3aa..09b612b17 100644 --- a/src/main/java/run/halo/app/theme/router/strategy/ArchivesRouteStrategy.java +++ b/src/main/java/run/halo/app/theme/router/strategy/ArchivesRouteStrategy.java @@ -5,6 +5,7 @@ import static run.halo.app.theme.router.PageUrlUtils.totalPage; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.server.HandlerFunction; import org.springframework.web.reactive.function.server.ServerRequest; @@ -64,7 +65,7 @@ public class ArchivesRouteStrategy implements ListPageRouteHandlerStrategy { @Override public List getRouterPaths(String prefix) { return List.of( - prefix, + StringUtils.prependIfMissing(prefix, "/"), PathUtils.combinePath(prefix, "/page/{page:\\d+}"), PathUtils.combinePath(prefix, "/{year:\\d{4}}"), PathUtils.combinePath(prefix, "/{year:\\d{4}}/page/{page:\\d+}"), diff --git a/src/test/java/run/halo/app/theme/router/RadixRouterTreeTest.java b/src/test/java/run/halo/app/theme/router/RadixRouterTreeTest.java new file mode 100644 index 000000000..8ea5598ff --- /dev/null +++ b/src/test/java/run/halo/app/theme/router/RadixRouterTreeTest.java @@ -0,0 +1,44 @@ +package run.halo.app.theme.router; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URI; +import java.net.URISyntaxException; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpMethod; +import org.springframework.mock.web.reactive.function.server.MockServerRequest; + +/** + * Tests for {@link RadixRouterTree}. + * + * @author guqing + * @since 2.0.0 + */ +class RadixRouterTreeTest { + + @Test + void pathToFind() throws URISyntaxException { + MockServerRequest request = + MockServerRequest.builder().uri(new URI("/archives")) + .method(HttpMethod.GET).build(); + String path = RadixRouterTree.pathToFind(request); + assertThat(path).isEqualTo("/archives"); + + request = MockServerRequest.builder().uri(new URI("/archives/")) + .method(HttpMethod.GET).build(); + assertThat(RadixRouterTree.pathToFind(request)).isEqualTo("/archives"); + + request = MockServerRequest.builder().uri(new URI("/archives/page/1")) + .method(HttpMethod.GET).build(); + assertThat(RadixRouterTree.pathToFind(request)).isEqualTo("/archives"); + + request = MockServerRequest.builder().uri(new URI("/")) + .method(HttpMethod.GET).build(); + assertThat(RadixRouterTree.pathToFind(request)).isEqualTo("/"); + + request = MockServerRequest.builder().uri(new URI("/")) + .queryParam("p", "fake-post") + .method(HttpMethod.GET).build(); + assertThat(RadixRouterTree.pathToFind(request)).isEqualTo("/?p=fake-post"); + } +} \ No newline at end of file