Leverage PathPatternParser in CORS configuration source
Previously `UrlBasedCorsConfigurationSource` was relying on `PathMatcher` implementations for matching incoming request lookup paths with the configured path patterns for CORS configuration. This commit replaces the use of `PathMatcher` with a `PathPatternParser` that parses the string patterns into `PathPattenr` instances and allows for faster matching against lookup paths. Issue: SPR-15688
This commit is contained in:
@@ -16,16 +16,14 @@
|
||||
|
||||
package org.springframework.web.cors.reactive;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.pattern.ParsingPathMatcher;
|
||||
import org.springframework.web.util.pattern.PathPattern;
|
||||
import org.springframework.web.util.pattern.PathPatternParser;
|
||||
|
||||
/**
|
||||
* Provide a per reactive request {@link CorsConfiguration} instance based on a
|
||||
@@ -35,23 +33,18 @@ import org.springframework.web.util.pattern.ParsingPathMatcher;
|
||||
* as well as Ant-style path patterns (such as {@code "/admin/**"}).
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Brian Clozel
|
||||
* @since 5.0
|
||||
*/
|
||||
public class UrlBasedCorsConfigurationSource implements CorsConfigurationSource {
|
||||
|
||||
private final Map<String, CorsConfiguration> corsConfigurations = new LinkedHashMap<>();
|
||||
private final Map<PathPattern, CorsConfiguration> corsConfigurations;
|
||||
|
||||
private PathMatcher pathMatcher = new ParsingPathMatcher();
|
||||
|
||||
|
||||
/**
|
||||
* Set the PathMatcher implementation to use for matching URL paths
|
||||
* against registered URL patterns. Default is ParsingPathMatcher.
|
||||
* @see ParsingPathMatcher
|
||||
*/
|
||||
public void setPathMatcher(PathMatcher pathMatcher) {
|
||||
Assert.notNull(pathMatcher, "PathMatcher must not be null");
|
||||
this.pathMatcher = pathMatcher;
|
||||
private final PathPatternParser patternParser;
|
||||
|
||||
public UrlBasedCorsConfigurationSource(PathPatternParser patternParser) {
|
||||
this.corsConfigurations = new LinkedHashMap<>();
|
||||
this.patternParser = patternParser;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,33 +53,25 @@ public class UrlBasedCorsConfigurationSource implements CorsConfigurationSource
|
||||
public void setCorsConfigurations(@Nullable Map<String, CorsConfiguration> corsConfigurations) {
|
||||
this.corsConfigurations.clear();
|
||||
if (corsConfigurations != null) {
|
||||
this.corsConfigurations.putAll(corsConfigurations);
|
||||
corsConfigurations.forEach((path, config) -> registerCorsConfiguration(path, config));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CORS configuration.
|
||||
*/
|
||||
public Map<String, CorsConfiguration> getCorsConfigurations() {
|
||||
return Collections.unmodifiableMap(this.corsConfigurations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@link CorsConfiguration} for the specified path pattern.
|
||||
*/
|
||||
public void registerCorsConfiguration(String path, CorsConfiguration config) {
|
||||
this.corsConfigurations.put(path, config);
|
||||
this.corsConfigurations.put(this.patternParser.parse(path), config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CorsConfiguration getCorsConfiguration(ServerWebExchange exchange) {
|
||||
String lookupPath = exchange.getRequest().getPath().pathWithinApplication().value();
|
||||
for (Map.Entry<String, CorsConfiguration> entry : this.corsConfigurations.entrySet()) {
|
||||
if (this.pathMatcher.match(entry.getKey(), lookupPath)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return this.corsConfigurations.entrySet().stream()
|
||||
.filter(entry -> entry.getKey().matches(lookupPath))
|
||||
.map(entry -> entry.getValue())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user