CORS support in HTTP method predicate

This commit introduces CORS support for the HttpMethodPredicate in
WebMvc.fn and WebFlux.fn.

Closes gh-24564
This commit is contained in:
Arjen Poutsma
2020-03-10 15:32:00 +01:00
parent fc12891006
commit c03cdbac21
4 changed files with 156 additions and 48 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,6 +53,7 @@ import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.MultiValueMap;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.util.UriBuilder;
import org.springframework.web.util.UriUtils;
import org.springframework.web.util.pattern.PathPattern;
@@ -444,11 +445,24 @@ public abstract class RequestPredicates {
@Override
public boolean test(ServerRequest request) {
boolean match = this.httpMethods.contains(request.method());
traceMatch("Method", this.httpMethods, request.method(), match);
HttpMethod method = method(request);
boolean match = this.httpMethods.contains(method);
traceMatch("Method", this.httpMethods, method, match);
return match;
}
@Nullable
private static HttpMethod method(ServerRequest request) {
if (CorsUtils.isPreFlightRequest(request.servletRequest())) {
String accessControlRequestMethod =
request.headers().firstHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD);
return HttpMethod.resolve(accessControlRequestMethod);
}
else {
return request.method();
}
}
@Override
public void accept(Visitor visitor) {
visitor.method(Collections.unmodifiableSet(this.httpMethods));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import java.util.function.Function;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
@@ -57,6 +58,22 @@ public class RequestPredicatesTests {
assertThat(predicate.test(request)).isFalse();
}
@Test
public void methodCorsPreFlight() {
RequestPredicate predicate = RequestPredicates.method(HttpMethod.PUT);
MockHttpServletRequest servletRequest = new MockHttpServletRequest("OPTIONS", "https://example.com");
servletRequest.addHeader("Origin", "https://example.com");
servletRequest.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "PUT");
ServerRequest request = new DefaultServerRequest(servletRequest, emptyList());
assertThat(predicate.test(request)).isTrue();
servletRequest.removeHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD);
servletRequest.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST");
request = new DefaultServerRequest(servletRequest, emptyList());
assertThat(predicate.test(request)).isFalse();
}
@Test
public void methods() {
RequestPredicate predicate = RequestPredicates.methods(HttpMethod.GET, HttpMethod.HEAD);