Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
* </p>
*
* @author Josh Cummings
* @author Andrey Litvitski
* @since 6.5
*/
public final class PathPatternRequestMatcher implements RequestMatcher {
Expand Down Expand Up @@ -200,14 +201,15 @@ public static final class Builder {
*
* <p>
* Prefixes should be of the form {@code /my/prefix}, starting with a slash, not
* ending in a slash, and not containing and wildcards
* ending in a slash, and not containing and wildcards The special value
* {@code "/"} may be used to indicate the root context.
* @param basePath the path prefix
* @return the {@link Builder} for more configuration
*/
public Builder basePath(String basePath) {
Assert.notNull(basePath, "basePath cannot be null");
Assert.isTrue(basePath.startsWith("/"), "basePath must start with '/'");
Assert.isTrue(!basePath.endsWith("/"), "basePath must not end with a slash");
Assert.isTrue("/".equals(basePath) || !basePath.endsWith("/"), "basePath must not end with a slash");
Comment on lines -210 to +212
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe in gh-17812, it was proposed to allow passing basePath as “/”.

Assert.isTrue(!basePath.contains("*"), "basePath must not contain a star");
return new Builder(this.parser, basePath);
}
Expand Down Expand Up @@ -282,7 +284,8 @@ public PathPatternRequestMatcher matcher(String path) {
public PathPatternRequestMatcher matcher(@Nullable HttpMethod method, String path) {
Assert.notNull(path, "pattern cannot be null");
Assert.isTrue(path.startsWith("/"), "pattern must start with a /");
PathPattern pathPattern = this.parser.parse(this.basePath + path);
String prefix = ("/".equals(this.basePath)) ? "" : this.basePath;
PathPattern pathPattern = this.parser.parse(prefix + path);
return new PathPatternRequestMatcher(pathPattern,
(method != null) ? new HttpMethodRequestMatcher(method) : AnyRequestMatcher.INSTANCE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ void servletPathWhenEndsWithSlashOrStarThenIllegalArgument() {
.isThrownBy(() -> PathPatternRequestMatcher.withDefaults().basePath("/path/"));
}

@Test
void matcherWhenBasePathIsRootThenNoDoubleSlash() {
PathPatternRequestMatcher.Builder builder = PathPatternRequestMatcher.withDefaults().basePath("/");
RequestMatcher matcher = builder.matcher(HttpMethod.GET, "/path");
MockHttpServletRequest mock = get("/path").servletPath("/path").buildRequest(null);
assertThat(matcher.matches(mock)).isTrue();
}

MockHttpServletRequest request(String uri) {
MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);
ServletRequestPathUtils.parseAndCache(request);
Expand Down