-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Description
Discovered whilst working on spring-projects/spring-boot#24645. Running CorsSampleActuatorApplicationTests.preflightRequestToEndpointShouldReturnOk from this branch should replicate the problem.
This issue is a quite subtle and hard to replicate. I've found it to cause problems for CorsFilter as well as MvcRequestMatcher in Spring Security. It appears that HandlerMappingIntrospector can fail to find mappings if they are configured with a PathPattern.
In AbstractHandlerMapping.initLookupPath there's the following branch:
if (usesPathPatterns()) {
request.removeAttribute(UrlPathHelper.PATH_ATTRIBUTE);
RequestPath requestPath = ServletRequestPathUtils.getParsedRequestPath(request);
String lookupPath = requestPath.pathWithinApplication().value();
return UrlPathHelper.defaultInstance.removeSemicolonContent(lookupPath);
}
else {
return getUrlPathHelper().resolveAndCacheLookupPath(request);
}This means that ServletRequestPathUtils.getParsedRequestPath(request) is called when a PathPattern is set. That code will fail if request.getAttribute(PATH_ATTRIBUTE) is null.
Usually HandlerMappers are only called from the DispatcherServlet which has the following logic:
RequestPath previousRequestPath = null;
if (this.parseRequestPath) {
previousRequestPath = (RequestPath) request.getAttribute(ServletRequestPathUtils.PATH_ATTRIBUTE);
ServletRequestPathUtils.parseAndCache(request);
}
The problem is that HandlerMappingIntrospector is designed to be called from a Filter which means that it can be executed before the DisatcherServlet runs.