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]");