in shenyu-web/src/main/java/org/apache/shenyu/web/filter/CrossFilter.java [59:122]
public Mono<Void> filter(@NonNull final ServerWebExchange exchange, @NonNull final WebFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
if (CorsUtils.isCorsRequest(request)) {
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
// finger allow origins
final String origin = request.getHeaders().getOrigin();
boolean allowCors = this.filterConfig.isAllowedAnyOrigin();
if (!allowCors && Objects.nonNull(this.filterConfig.getAllowedOrigin())) {
final String scheme = exchange.getRequest().getURI().getScheme();
final CrossFilterConfig.AllowedOriginConfig allowedOriginConfig = this.filterConfig.getAllowedOrigin();
Set<String> allowedOrigin = Optional.ofNullable(allowedOriginConfig.getPrefixes()).orElse(Collections.emptySet())
.stream()
.filter(StringUtils::isNoneBlank)
// scheme://prefix spacer domain
.map(prefix -> String.format("%s://%s%s%s",
scheme, prefix.trim(),
StringUtils.defaultString(allowedOriginConfig.getSpacer(), ".").trim(),
StringUtils.defaultString(allowedOriginConfig.getDomain(), "").trim()))
.collect(Collectors.toSet());
// add all origin domains
allowedOrigin.addAll(Optional.ofNullable(allowedOriginConfig.getOrigins()).orElse(Collections.emptySet())
.stream()
.filter(StringUtils::isNoneBlank)
.map(oneOrigin -> {
if (ALL.equals(oneOrigin) || oneOrigin.startsWith(String.format("%s://", scheme))) {
return oneOrigin.trim();
}
return String.format("%s://%s", scheme, oneOrigin.trim());
})
.collect(Collectors.toSet()));
allowCors = allowedOrigin.contains(origin) || allowedOrigin.contains(ALL);
// if the origin is not allow check match origin again
String originRegex;
if (!allowCors && StringUtils.isNotBlank(originRegex = this.filterConfig.getAllowedOrigin().getOriginRegex())) {
allowCors = Pattern.matches(originRegex.trim(), origin);
}
}
if (allowCors) {
// "Access-Control-Allow-Origin"
headers.set(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
// "Access-Control-Allow-Methods"
this.filterSameHeader(headers, HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,
this.filterConfig.getAllowedMethods());
// "Access-Control-Max-Age"
this.filterSameHeader(headers, HttpHeaders.ACCESS_CONTROL_MAX_AGE,
this.filterConfig.getMaxAge());
// "Access-Control-Allow-Headers"
this.filterSameHeader(headers, HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
this.filterConfig.getAllowedHeaders());
// "Access-Control-Expose-Headers"
this.filterSameHeader(headers, HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,
this.filterConfig.getAllowedExpose());
// "Access-Control-Allow-Credentials"
this.filterSameHeader(headers, HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS,
String.valueOf(this.filterConfig.isAllowCredentials()));
}
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
}
return chain.filter(exchange);
}