|
33 | 33 | import jakarta.servlet.ServletRequest;
|
34 | 34 | import jakarta.servlet.http.HttpServletRequest;
|
35 | 35 | import jakarta.servlet.http.HttpServletRequestWrapper;
|
| 36 | +import jakarta.servlet.http.HttpServletResponse; |
36 | 37 | import org.apache.commons.logging.Log;
|
37 | 38 | import org.apache.commons.logging.LogFactory;
|
38 | 39 |
|
|
45 | 46 | import org.springframework.core.io.Resource;
|
46 | 47 | import org.springframework.core.io.support.PropertiesLoaderUtils;
|
47 | 48 | import org.springframework.http.server.RequestPath;
|
| 49 | +import org.springframework.http.server.ServletServerHttpRequest; |
48 | 50 | import org.springframework.lang.Nullable;
|
49 | 51 | import org.springframework.util.Assert;
|
50 | 52 | import org.springframework.util.ClassUtils;
|
51 | 53 | import org.springframework.util.StringUtils;
|
52 | 54 | import org.springframework.web.cors.CorsConfiguration;
|
53 | 55 | import org.springframework.web.cors.CorsConfigurationSource;
|
| 56 | +import org.springframework.web.cors.CorsUtils; |
| 57 | +import org.springframework.web.cors.PreFlightRequestHandler; |
54 | 58 | import org.springframework.web.servlet.DispatcherServlet;
|
55 | 59 | import org.springframework.web.servlet.HandlerExecutionChain;
|
56 | 60 | import org.springframework.web.servlet.HandlerInterceptor;
|
57 | 61 | import org.springframework.web.servlet.HandlerMapping;
|
| 62 | +import org.springframework.web.servlet.NoHandlerFoundException; |
58 | 63 | import org.springframework.web.util.ServletRequestPathUtils;
|
59 | 64 | import org.springframework.web.util.UrlPathHelper;
|
60 | 65 | import org.springframework.web.util.pattern.PathPatternParser;
|
|
87 | 92 | * @since 4.3.1
|
88 | 93 | */
|
89 | 94 | public class HandlerMappingIntrospector
|
90 |
| - implements CorsConfigurationSource, ApplicationContextAware, InitializingBean { |
| 95 | + implements CorsConfigurationSource, PreFlightRequestHandler, ApplicationContextAware, InitializingBean { |
91 | 96 |
|
92 | 97 | private static final Log logger = LogFactory.getLog(HandlerMappingIntrospector.class.getName());
|
93 | 98 |
|
@@ -172,6 +177,49 @@ public List<HandlerMapping> getHandlerMappings() {
|
172 | 177 | return (this.handlerMappings != null ? this.handlerMappings : Collections.emptyList());
|
173 | 178 | }
|
174 | 179 |
|
| 180 | + /** |
| 181 | + * Return {@code true} if all {@link HandlerMapping} beans |
| 182 | + * {@link HandlerMapping#usesPathPatterns() use parsed PathPatterns}, |
| 183 | + * and {@code false} if any don't. |
| 184 | + * @since 6.2 |
| 185 | + */ |
| 186 | + public boolean allHandlerMappingsUsePathPatternParser() { |
| 187 | + Assert.state(this.handlerMappings != null, "Not yet initialized via afterPropertiesSet."); |
| 188 | + return getHandlerMappings().stream().allMatch(HandlerMapping::usesPathPatterns); |
| 189 | + } |
| 190 | + |
| 191 | + |
| 192 | + /** |
| 193 | + * Find the matching {@link HandlerMapping} for the request, and invoke the |
| 194 | + * handler it returns as a {@link PreFlightRequestHandler}. |
| 195 | + * @throws NoHandlerFoundException if no handler matches the request |
| 196 | + * @since 6.2 |
| 197 | + */ |
| 198 | + public void handlePreFlight(HttpServletRequest request, HttpServletResponse response) throws Exception { |
| 199 | + Assert.state(this.handlerMappings != null, "Not yet initialized via afterPropertiesSet."); |
| 200 | + Assert.state(CorsUtils.isPreFlightRequest(request), "Not a pre-flight request."); |
| 201 | + RequestPath previousPath = (RequestPath) request.getAttribute(ServletRequestPathUtils.PATH_ATTRIBUTE); |
| 202 | + try { |
| 203 | + ServletRequestPathUtils.parseAndCache(request); |
| 204 | + for (HandlerMapping mapping : this.handlerMappings) { |
| 205 | + HandlerExecutionChain chain = mapping.getHandler(request); |
| 206 | + if (chain != null) { |
| 207 | + Object handler = chain.getHandler(); |
| 208 | + if (handler instanceof PreFlightRequestHandler preFlightHandler) { |
| 209 | + preFlightHandler.handlePreFlight(request, response); |
| 210 | + return; |
| 211 | + } |
| 212 | + throw new IllegalStateException("Expected PreFlightRequestHandler: " + handler.getClass()); |
| 213 | + } |
| 214 | + } |
| 215 | + throw new NoHandlerFoundException( |
| 216 | + request.getMethod(), request.getRequestURI(), new ServletServerHttpRequest(request).getHeaders()); |
| 217 | + } |
| 218 | + finally { |
| 219 | + ServletRequestPathUtils.setParsedRequestPath(previousPath, request); |
| 220 | + } |
| 221 | + } |
| 222 | + |
175 | 223 |
|
176 | 224 | /**
|
177 | 225 | * {@link Filter} that looks up the {@code MatchableHandlerMapping} and
|
|
0 commit comments