From ad5bd67b31051c60c337a7762e88286d0fc7fbec Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Fri, 19 Jun 2026 16:06:49 +0100 Subject: [PATCH] Improve ambiguous preflight checks in AbstractHandlerMethodMapping Closes gh-36903 --- .../method/AbstractHandlerMethodMapping.java | 6 ++---- .../result/method/HandlerMethodMappingTests.java | 11 ++++++++--- .../handler/AbstractHandlerMethodMapping.java | 6 ++---- .../handler/HandlerMethodMappingTests.java | 16 +++++++++++----- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java index dcc48f9a66c..b2e9acf8ca3 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java @@ -334,10 +334,8 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap logger.trace(exchange.getLogPrefix() + matches.size() + " matching mappings: " + matches); } if (CorsUtils.isPreFlightRequest(exchange.getRequest())) { - for (Match match : matches) { - if (match.hasCorsConfig()) { - return PREFLIGHT_AMBIGUOUS_MATCH; - } + if (matches.stream().allMatch(Match::hasCorsConfig)) { + return PREFLIGHT_AMBIGUOUS_MATCH; } } else { diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/HandlerMethodMappingTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/HandlerMethodMappingTests.java index ba7488c4bed..664de757bdf 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/HandlerMethodMappingTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/HandlerMethodMappingTests.java @@ -131,8 +131,8 @@ class HandlerMethodMappingTests { @Test // gh-26490 void ambiguousMatchOnPreFlightRequestWithCorsConfig() throws Exception { - this.mapping.registerMapping("/f?o", this.handler, this.method1); - this.mapping.registerMapping("/fo?", this.handler, this.handler.getClass().getMethod("corsHandlerMethod")); + this.mapping.registerMapping("/f?o", this.handler, this.handler.getClass().getMethod("corsHandlerMethod1")); + this.mapping.registerMapping("/fo?", this.handler, this.handler.getClass().getMethod("corsHandlerMethod2")); MockServerWebExchange exchange = MockServerWebExchange.from( MockServerHttpRequest.options("https://example.org/foo") @@ -256,7 +256,12 @@ class HandlerMethodMappingTests { @RequestMapping @CrossOrigin(originPatterns = "*") - public void corsHandlerMethod() { + public void corsHandlerMethod1() { + } + + @RequestMapping + @CrossOrigin(originPatterns = "*") + public void corsHandlerMethod2() { } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java index 2c7a8bdd62d..0261368eca5 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java @@ -409,10 +409,8 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap logger.trace(matches.size() + " matching mappings: " + matches); } if (CorsUtils.isPreFlightRequest(request)) { - for (Match match : matches) { - if (match.hasCorsConfig()) { - return PREFLIGHT_AMBIGUOUS_MATCH; - } + if (matches.stream().allMatch(Match::hasCorsConfig)) { + return PREFLIGHT_AMBIGUOUS_MATCH; } } else { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java index 953594f6d14..2574aa2016b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java @@ -142,8 +142,8 @@ class HandlerMethodMappingTests { @Test // gh-26490 void ambiguousMatchOnPreFlightRequestWithCorsConfig() throws Exception { - this.mapping.registerMapping("/f?o", this.handler, this.method1); - this.mapping.registerMapping("/fo?", this.handler, this.handler.getClass().getMethod("corsHandlerMethod")); + this.mapping.registerMapping("/f?o", this.handler, this.handler.getClass().getMethod("corsHandlerMethod1")); + this.mapping.registerMapping("/fo?", this.handler, this.handler.getClass().getMethod("corsHandlerMethod2")); MockHttpServletRequest request = new MockHttpServletRequest("OPTIONS", "/foo"); request.addHeader(HttpHeaders.ORIGIN, "https://domain.com"); @@ -166,7 +166,7 @@ class HandlerMethodMappingTests { @Test void abortInterceptorInPreFlightRequestWithCorsConfig() throws Exception { - this.mapping.registerMapping("/foo", this.handler, this.handler.getClass().getMethod("corsHandlerMethod")); + this.mapping.registerMapping("/foo", this.handler, this.handler.getClass().getMethod("corsHandlerMethod1")); MockHttpServletRequest request = new MockHttpServletRequest("OPTIONS", "/foo"); request.addParameter("abort", "true"); @@ -297,7 +297,7 @@ class HandlerMethodMappingTests { @Test void registerCustomHandlerMethod() throws Exception { this.mapping.setCustomerHandlerMethod(true); - this.mapping.registerMapping("/foo", this.handler, this.handler.getClass().getMethod("corsHandlerMethod")); + this.mapping.registerMapping("/foo", this.handler, this.handler.getClass().getMethod("corsHandlerMethod1")); MockHttpServletRequest request = new MockHttpServletRequest("OPTIONS", "/foo"); request.addParameter("abort", "true"); @@ -418,7 +418,13 @@ class HandlerMethodMappingTests { @RequestMapping @CrossOrigin(originPatterns = "*") - public void corsHandlerMethod() { + public void corsHandlerMethod1() { + } + + @RequestMapping + @CrossOrigin(originPatterns = "*") + public void corsHandlerMethod2() { } } + }