From 5a4a677fbd05373d4a63c9b161128cb61cbc9feb Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Thu, 21 Jan 2021 10:09:49 +0100 Subject: [PATCH] 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 --- .../web/servlet/handler/AbstractUrlHandlerMapping.java | 6 +++--- .../servlet/handler/SimpleUrlHandlerMappingTests.java | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java index 097415af953..3841449aec0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java @@ -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 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); } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMappingTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMappingTests.java index 408ee13517f..9aaa75d3184 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMappingTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMappingTests.java @@ -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);