|
|
@ -16,6 +16,10 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.web.servlet.mvc.method.annotation; |
|
|
|
package org.springframework.web.servlet.mvc.method.annotation; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.lang.annotation.ElementType; |
|
|
|
|
|
|
|
import java.lang.annotation.Retention; |
|
|
|
|
|
|
|
import java.lang.annotation.RetentionPolicy; |
|
|
|
|
|
|
|
import java.lang.annotation.Target; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Arrays; |
|
|
|
|
|
|
|
|
|
|
@ -25,6 +29,7 @@ import org.junit.Test; |
|
|
|
import org.junit.rules.ExpectedException; |
|
|
|
import org.junit.rules.ExpectedException; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.DirectFieldAccessor; |
|
|
|
import org.springframework.beans.DirectFieldAccessor; |
|
|
|
|
|
|
|
import org.springframework.core.annotation.AnnotatedElementUtils; |
|
|
|
import org.springframework.core.annotation.AnnotationUtils; |
|
|
|
import org.springframework.core.annotation.AnnotationUtils; |
|
|
|
import org.springframework.http.HttpHeaders; |
|
|
|
import org.springframework.http.HttpHeaders; |
|
|
|
import org.springframework.mock.web.test.MockHttpServletRequest; |
|
|
|
import org.springframework.mock.web.test.MockHttpServletRequest; |
|
|
@ -53,6 +58,7 @@ import static org.junit.Assert.*; |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Sebastien Deleuze |
|
|
|
* @author Sebastien Deleuze |
|
|
|
* @author Sam Brannen |
|
|
|
* @author Sam Brannen |
|
|
|
|
|
|
|
* @author Nicolas Labrot |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class CrossOriginTests { |
|
|
|
public class CrossOriginTests { |
|
|
|
|
|
|
|
|
|
|
@ -79,8 +85,7 @@ public class CrossOriginTests { |
|
|
|
this.handlerMapping.registerHandler(new MethodLevelController()); |
|
|
|
this.handlerMapping.registerHandler(new MethodLevelController()); |
|
|
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/no"); |
|
|
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/no"); |
|
|
|
HandlerExecutionChain chain = this.handlerMapping.getHandler(request); |
|
|
|
HandlerExecutionChain chain = this.handlerMapping.getHandler(request); |
|
|
|
CorsConfiguration config = getCorsConfiguration(chain, false); |
|
|
|
assertNull(getCorsConfiguration(chain, false)); |
|
|
|
assertNull(config); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test // SPR-12931
|
|
|
|
@Test // SPR-12931
|
|
|
@ -88,8 +93,7 @@ public class CrossOriginTests { |
|
|
|
this.handlerMapping.registerHandler(new MethodLevelController()); |
|
|
|
this.handlerMapping.registerHandler(new MethodLevelController()); |
|
|
|
this.request.setRequestURI("/no"); |
|
|
|
this.request.setRequestURI("/no"); |
|
|
|
HandlerExecutionChain chain = this.handlerMapping.getHandler(request); |
|
|
|
HandlerExecutionChain chain = this.handlerMapping.getHandler(request); |
|
|
|
CorsConfiguration config = getCorsConfiguration(chain, false); |
|
|
|
assertNull(getCorsConfiguration(chain, false)); |
|
|
|
assertNull(config); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test // SPR-12931
|
|
|
|
@Test // SPR-12931
|
|
|
@ -98,8 +102,7 @@ public class CrossOriginTests { |
|
|
|
this.request.setMethod("POST"); |
|
|
|
this.request.setMethod("POST"); |
|
|
|
this.request.setRequestURI("/no"); |
|
|
|
this.request.setRequestURI("/no"); |
|
|
|
HandlerExecutionChain chain = this.handlerMapping.getHandler(request); |
|
|
|
HandlerExecutionChain chain = this.handlerMapping.getHandler(request); |
|
|
|
CorsConfiguration config = getCorsConfiguration(chain, false); |
|
|
|
assertNull(getCorsConfiguration(chain, false)); |
|
|
|
assertNull(config); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
@ -180,6 +183,32 @@ public class CrossOriginTests { |
|
|
|
assertTrue(config.getAllowCredentials()); |
|
|
|
assertTrue(config.getAllowCredentials()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test // SPR-13468
|
|
|
|
|
|
|
|
public void classLevelComposedAnnotation() throws Exception { |
|
|
|
|
|
|
|
this.handlerMapping.registerHandler(new ClassLevelMappingWithComposedAnnotation()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.request.setRequestURI("/foo"); |
|
|
|
|
|
|
|
HandlerExecutionChain chain = this.handlerMapping.getHandler(request); |
|
|
|
|
|
|
|
CorsConfiguration config = getCorsConfiguration(chain, false); |
|
|
|
|
|
|
|
assertNotNull(config); |
|
|
|
|
|
|
|
assertArrayEquals(new String[]{"GET"}, config.getAllowedMethods().toArray()); |
|
|
|
|
|
|
|
assertArrayEquals(new String[]{"http://foo.com"}, config.getAllowedOrigins().toArray()); |
|
|
|
|
|
|
|
assertTrue(config.getAllowCredentials()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test // SPR-13468
|
|
|
|
|
|
|
|
public void methodLevelComposedAnnotation() throws Exception { |
|
|
|
|
|
|
|
this.handlerMapping.registerHandler(new MethodLevelMappingWithComposedAnnotation()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.request.setRequestURI("/foo"); |
|
|
|
|
|
|
|
HandlerExecutionChain chain = this.handlerMapping.getHandler(request); |
|
|
|
|
|
|
|
CorsConfiguration config = getCorsConfiguration(chain, false); |
|
|
|
|
|
|
|
assertNotNull(config); |
|
|
|
|
|
|
|
assertArrayEquals(new String[]{"GET"}, config.getAllowedMethods().toArray()); |
|
|
|
|
|
|
|
assertArrayEquals(new String[]{"http://foo.com"}, config.getAllowedOrigins().toArray()); |
|
|
|
|
|
|
|
assertTrue(config.getAllowCredentials()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void preFlightRequest() throws Exception { |
|
|
|
public void preFlightRequest() throws Exception { |
|
|
|
this.handlerMapping.registerHandler(new MethodLevelController()); |
|
|
|
this.handlerMapping.registerHandler(new MethodLevelController()); |
|
|
@ -345,6 +374,33 @@ public class CrossOriginTests { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Target({ElementType.METHOD, ElementType.TYPE}) |
|
|
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
|
|
|
|
@CrossOrigin |
|
|
|
|
|
|
|
private @interface ComposedCrossOrigin { |
|
|
|
|
|
|
|
String[] origins() default {}; |
|
|
|
|
|
|
|
String allowCredentials() default ""; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Controller |
|
|
|
|
|
|
|
@ComposedCrossOrigin(origins = "http://foo.com", allowCredentials = "true") |
|
|
|
|
|
|
|
private static class ClassLevelMappingWithComposedAnnotation { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(path = "/foo", method = RequestMethod.GET) |
|
|
|
|
|
|
|
public void foo() { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Controller |
|
|
|
|
|
|
|
private static class MethodLevelMappingWithComposedAnnotation { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(path = "/foo", method = RequestMethod.GET) |
|
|
|
|
|
|
|
@ComposedCrossOrigin(origins = "http://foo.com", allowCredentials = "true") |
|
|
|
|
|
|
|
public void foo() { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static class TestRequestMappingInfoHandlerMapping extends RequestMappingHandlerMapping { |
|
|
|
private static class TestRequestMappingInfoHandlerMapping extends RequestMappingHandlerMapping { |
|
|
|
|
|
|
|
|
|
|
|
public void registerHandler(Object handler) { |
|
|
|
public void registerHandler(Object handler) { |
|
|
@ -358,7 +414,7 @@ public class CrossOriginTests { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { |
|
|
|
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { |
|
|
|
RequestMapping annotation = AnnotationUtils.findAnnotation(method, RequestMapping.class); |
|
|
|
RequestMapping annotation = AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class); |
|
|
|
if (annotation != null) { |
|
|
|
if (annotation != null) { |
|
|
|
return new RequestMappingInfo( |
|
|
|
return new RequestMappingInfo( |
|
|
|
new PatternsRequestCondition(annotation.value(), getUrlPathHelper(), getPathMatcher(), true, true), |
|
|
|
new PatternsRequestCondition(annotation.value(), getUrlPathHelper(), getPathMatcher(), true, true), |
|
|
|