Suppress PREFLIGHT_AMBIGUOUS_MATCH if matches have no CORS config

Closes gh-26490
This commit is contained in:
Rossen Stoyanchev
2021-02-03 10:43:08 +00:00
parent 0575e6637c
commit 996c86f448
5 changed files with 215 additions and 79 deletions

View File

@@ -330,19 +330,25 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
logger.trace(exchange.getLogPrefix() + matches.size() + " matching mappings: " + matches);
}
if (CorsUtils.isPreFlightRequest(exchange.getRequest())) {
return PREFLIGHT_AMBIGUOUS_MATCH;
for (Match match : matches) {
if (match.hasCorsConfig()) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
}
}
Match secondBestMatch = matches.get(1);
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.handlerMethod.getMethod();
Method m2 = secondBestMatch.handlerMethod.getMethod();
RequestPath path = exchange.getRequest().getPath();
throw new IllegalStateException(
"Ambiguous handler methods mapped for '" + path + "': {" + m1 + ", " + m2 + "}");
else {
Match secondBestMatch = matches.get(1);
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.getHandlerMethod().getMethod();
Method m2 = secondBestMatch.getHandlerMethod().getMethod();
RequestPath path = exchange.getRequest().getPath();
throw new IllegalStateException(
"Ambiguous handler methods mapped for '" + path + "': {" + m1 + ", " + m2 + "}");
}
}
}
handleMatch(bestMatch.mapping, bestMatch.handlerMethod, exchange);
return bestMatch.handlerMethod;
handleMatch(bestMatch.mapping, bestMatch.getHandlerMethod(), exchange);
return bestMatch.getHandlerMethod();
}
else {
return handleNoMatch(this.mappingRegistry.getRegistrations().keySet(), exchange);
@@ -353,8 +359,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
for (T mapping : mappings) {
T match = getMatchingMapping(mapping, exchange);
if (match != null) {
matches.add(new Match(match,
this.mappingRegistry.getRegistrations().get(mapping).getHandlerMethod()));
matches.add(new Match(match, this.mappingRegistry.getRegistrations().get(mapping)));
}
}
}
@@ -519,13 +524,14 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
this.pathLookup.add(path, mapping);
}
CorsConfiguration config = initCorsConfiguration(handler, method, mapping);
if (config != null) {
config.validateAllowCredentials();
this.corsLookup.put(handlerMethod, config);
CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
if (corsConfig != null) {
corsConfig.validateAllowCredentials();
this.corsLookup.put(handlerMethod, corsConfig);
}
this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directPaths));
this.registry.put(mapping,
new MappingRegistration<>(mapping, handlerMethod, directPaths, corsConfig != null));
}
finally {
this.readWriteLock.writeLock().unlock();
@@ -578,12 +584,17 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
private final Set<String> directPaths;
public MappingRegistration(T mapping, HandlerMethod handlerMethod, @Nullable Set<String> directPaths) {
private final boolean corsConfig;
public MappingRegistration(
T mapping, HandlerMethod handlerMethod, @Nullable Set<String> directPaths, boolean corsConfig) {
Assert.notNull(mapping, "Mapping must not be null");
Assert.notNull(handlerMethod, "HandlerMethod must not be null");
this.mapping = mapping;
this.handlerMethod = handlerMethod;
this.directPaths = (directPaths != null ? directPaths : Collections.emptySet());
this.corsConfig = corsConfig;
}
public T getMapping() {
@@ -597,6 +608,10 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
public Set<String> getDirectPaths() {
return this.directPaths;
}
public boolean hasCorsConfig() {
return this.corsConfig;
}
}
@@ -608,11 +623,23 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
private final T mapping;
private final HandlerMethod handlerMethod;
private final MappingRegistration<T> registration;
public Match(T mapping, HandlerMethod handlerMethod) {
public Match(T mapping, MappingRegistration<T> registration) {
this.mapping = mapping;
this.handlerMethod = handlerMethod;
this.registration = registration;
}
public T getMapping() {
return this.mapping;
}
public HandlerMethod getHandlerMethod() {
return this.registration.getHandlerMethod();
}
public boolean hasCorsConfig() {
return this.registration.hasCorsConfig();
}
@Override