Fix contextPath request matching with PathPatterns

Prior to this commit, `SimpleUrlHandlerMapping` and other
implementations of `AbstractUrlHandlerMapping` would not strip the
Servlet context path from the request path before performing path
matching with PathPattern instances.

This resulted in requests not matching as expected if the application
was configured with a Servlet context path.

This commit ensures that the `RequestPath` "path whithin the
application" is used for matching against path patterns.

Fixes gh-26411
This commit is contained in:
Brian Clozel 2021-01-21 10:09:49 +01:00
parent 584dabbb39
commit 5a4a677fbd
2 changed files with 11 additions and 4 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -186,7 +186,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i
// Pattern match?
List<PathPattern> matches = null;
for (PathPattern pattern : this.pathPatternHandlerMap.keySet()) {
if (pattern.matches(path)) {
if (pattern.matches(path.pathWithinApplication())) {
matches = (matches != null ? matches : new ArrayList<>());
matches.add(pattern);
}
@ -207,7 +207,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i
handler = obtainApplicationContext().getBean(handlerName);
}
validateHandler(handler, request);
PathContainer pathWithinMapping = pattern.extractPathWithinPattern(path);
PathContainer pathWithinMapping = pattern.extractPathWithinPattern(path.pathWithinApplication());
return buildPathExposingHandler(handler, pattern.getPatternString(), pathWithinMapping.value(), null);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -108,6 +108,12 @@ public class SimpleUrlHandlerMappingTests {
assertThat(request.getAttribute(PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).isEqualTo("welcome.x");
assertThat(request.getAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE)).isEqualTo(otherBean);
request = PathPatternsTestUtils.initRequest("GET", "/app", "/welcome.x", usePathPatterns);
chain = getHandler(hm, request);
assertThat(chain.getHandler()).isSameAs(otherBean);
assertThat(request.getAttribute(PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).isEqualTo("welcome.x");
assertThat(request.getAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE)).isEqualTo(otherBean);
request = PathPatternsTestUtils.initRequest("GET", "/welcome/", usePathPatterns);
chain = getHandler(hm, request);
assertThat(chain.getHandler()).isSameAs(otherBean);
@ -122,6 +128,7 @@ public class SimpleUrlHandlerMappingTests {
chain = getHandler(hm, request);
assertThat(chain.getHandler()).isSameAs(bean);
request = PathPatternsTestUtils.initRequest("GET", "/show.html", usePathPatterns);
chain = getHandler(hm, request);
assertThat(chain.getHandler()).isSameAs(bean);