diff --git a/docs/se/webserver/03_routing.adoc b/docs/se/webserver/03_routing.adoc index 3252b5d665f..69b5893f932 100644 --- a/docs/se/webserver/03_routing.adoc +++ b/docs/se/webserver/03_routing.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2018, 2020 Oracle and/or its affiliates. + Copyright (c) 2018, 2021 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -85,6 +85,7 @@ You can use *path pattern* instead of _path_ with the following syntax: * `/foo/{+var}` - Convenience shortcut for {var:.+}. A matcher is not a true URI template (as defined by RFC) but this convenience is in sync with the Apiary templates * `/foo/{+}` - Convenience shortcut for unnamed segment with regular expression {:.+} * `/foo[/bar]` - An optional block, which translates to the `/foo(/bar)?` regular expression +* `/*` or `/foo*` - `*` Wildcard character can be matched with any number of characters. IMPORTANT: Path (matcher) routing is *exact*. For example, a `/foo/bar` request is *not* routed to `.post('/foo', ...)`. diff --git a/webserver/webserver/src/main/java/io/helidon/webserver/PathMatcher.java b/webserver/webserver/src/main/java/io/helidon/webserver/PathMatcher.java index 0ad40688ce0..84eaadbac80 100644 --- a/webserver/webserver/src/main/java/io/helidon/webserver/PathMatcher.java +++ b/webserver/webserver/src/main/java/io/helidon/webserver/PathMatcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +54,8 @@ * A convenience shortcut for {@code /foo/{:.+}}. * {@code /foo[/bar]} * A optional section. Translated to regexp: {@code /foo(/bar)?} + * {@code /* or /foo*} + * Wildcard character can be matched with any number of characters. * */ public interface PathMatcher { diff --git a/webserver/webserver/src/main/java/io/helidon/webserver/PathPattern.java b/webserver/webserver/src/main/java/io/helidon/webserver/PathPattern.java index 363b9fc70bf..4778e168056 100644 --- a/webserver/webserver/src/main/java/io/helidon/webserver/PathPattern.java +++ b/webserver/webserver/src/main/java/io/helidon/webserver/PathPattern.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020 Oracle and/or its affiliates. + * Copyright (c) 2018, 2021 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -126,6 +126,10 @@ static PathMatcher compile(CharSequence pattern) { paramCounter++; } break; + case '*': + isRegexp = true; + regexp.append(".*?"); + break; default: shouldContinue = false; } diff --git a/webserver/webserver/src/test/java/io/helidon/webserver/PathPatternTest.java b/webserver/webserver/src/test/java/io/helidon/webserver/PathPatternTest.java index cc66549c8d2..45655a15e13 100644 --- a/webserver/webserver/src/test/java/io/helidon/webserver/PathPatternTest.java +++ b/webserver/webserver/src/test/java/io/helidon/webserver/PathPatternTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,6 @@ import java.util.Map; import java.util.stream.Collectors; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import static org.hamcrest.CoreMatchers.is; @@ -32,7 +31,6 @@ /** * The PathTemplateTest. */ -@Disabled public class PathPatternTest { private String normalize(String path) { @@ -229,6 +227,22 @@ public void testGreedyParams() throws Exception { assertMatchWithParams("/foo/bar/baz/xxx", "/foo/{+}/xxx"); } + @Test + public void testWildCard() throws Exception { + assertMatch("/foo/bar", "/foo*"); + assertMatch("/foo/bar", "/foo/*"); + assertMatch("/foo/bar", "/foo/ba*"); + assertMatch("/foo/bar", "/foo[/*]"); + assertMatch("/foo/bar", "/foo[/ba*]"); + assertMatch("/foo/bar/baz", "/foo/*"); + assertMatch("/foo/bar/baz", "/foo/ba*"); + assertMatch("/foo/bar/baz", "/foo/*/*"); + assertMatch("/foo/bar/baz", "/foo/*/b*"); + assertNotMatch("/foobar", "/foo/*"); + assertMatchWithParams("/foo/bar/baz", "/foo[/{var}]/*", "var", "bar"); + assertMatchWithParams("/foo/bar/baz", "/foo/*[/{var}]", "var", "baz"); + } + @Test public void testOptionals() throws Exception { assertMatch("/foo/bar", "/foo[/bar]");