From efc3f888dab6b7bcf4e877726d2c302f6ff105d1 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 7 Feb 2018 17:01:55 +0000 Subject: [PATCH] Avoid exception throw-catch for non-MatchableHandlerMapping mappings Closes gh-11912 --- .../web/servlet/WebMvcMetricsFilter.java | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilter.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilter.java index 83cdb29c348..f995f04da00 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilter.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilter.java @@ -28,6 +28,7 @@ import java.util.function.Supplier; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import io.micrometer.core.annotation.Timed; @@ -49,6 +50,7 @@ import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.HandlerExecutionChain; +import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.handler.HandlerMappingIntrospector; import org.springframework.web.servlet.handler.MatchableHandlerMapping; import org.springframework.web.util.NestedServletException; @@ -125,11 +127,18 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter { } private Object getHandler(HttpServletRequest request) throws Exception { - MatchableHandlerMapping handlerMapping = getMappingIntrospector() - .getMatchableHandlerMapping(request); - HandlerExecutionChain chain = (handlerMapping == null ? null - : handlerMapping.getHandler(request)); - return (chain == null ? null : chain.getHandler()); + HttpServletRequest wrapper = new UnmodifiableAttributesRequestWrapper(request); + for (HandlerMapping handlerMapping : getMappingIntrospector() + .getHandlerMappings()) { + HandlerExecutionChain chain = handlerMapping.getHandler(wrapper); + if (chain != null) { + if (handlerMapping instanceof MatchableHandlerMapping) { + return chain.getHandler(); + } + return null; + } + } + return null; } private HandlerMappingIntrospector getMappingIntrospector() { @@ -272,4 +281,21 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter { } + /** + * An {@link HttpServletRequestWrapper} that prevents modification of the request's + * attributes. + */ + private static final class UnmodifiableAttributesRequestWrapper + extends HttpServletRequestWrapper { + + private UnmodifiableAttributesRequestWrapper(HttpServletRequest request) { + super(request); + } + + @Override + public void setAttribute(String name, Object value) { + + } + } + }