@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
/ *
* Copyright 2002 - 2015 the original author or authors .
* Copyright 2002 - 2016 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 .
@ -22,6 +22,7 @@ import java.lang.annotation.RetentionPolicy;
@@ -22,6 +22,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target ;
import java.lang.reflect.Method ;
import java.util.Arrays ;
import java.util.Properties ;
import org.junit.Before ;
import org.junit.Rule ;
@ -29,8 +30,10 @@ import org.junit.Test;
@@ -29,8 +30,10 @@ import org.junit.Test;
import org.junit.rules.ExpectedException ;
import org.springframework.beans.DirectFieldAccessor ;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer ;
import org.springframework.core.annotation.AnnotatedElementUtils ;
import org.springframework.core.annotation.AnnotationUtils ;
import org.springframework.core.env.PropertiesPropertySource ;
import org.springframework.http.HttpHeaders ;
import org.springframework.mock.web.test.MockHttpServletRequest ;
import org.springframework.stereotype.Controller ;
@ -72,9 +75,15 @@ public class CrossOriginTests {
@@ -72,9 +75,15 @@ public class CrossOriginTests {
@Before
public void setUp ( ) {
StaticWebApplicationContext wac = new StaticWebApplicationContext ( ) ;
Properties props = new Properties ( ) ;
props . setProperty ( "myOrigin" , "http://example.com" ) ;
wac . getEnvironment ( ) . getPropertySources ( ) . addFirst ( new PropertiesPropertySource ( "ps" , props ) ) ;
wac . registerSingleton ( "ppc" , PropertySourcesPlaceholderConfigurer . class ) ;
wac . refresh ( ) ;
this . handlerMapping . setRemoveSemicolonContent ( false ) ;
this . handlerMapping . setApplicationContext ( new StaticWebApplicationContext ( ) ) ;
this . handlerMapping . afterPropertiesSet ( ) ;
wac . getAutowireCapableBeanFactory ( ) . initializeBean ( this . handlerMapping , "hm" ) ;
this . request . setMethod ( "GET" ) ;
this . request . addHeader ( HttpHeaders . ORIGIN , "http://domain.com/" ) ;
@ -112,10 +121,10 @@ public class CrossOriginTests {
@@ -112,10 +121,10 @@ public class CrossOriginTests {
HandlerExecutionChain chain = this . handlerMapping . getHandler ( request ) ;
CorsConfiguration config = getCorsConfiguration ( chain , false ) ;
assertNotNull ( config ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertTrue ( config . getAllowCredentials ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedHeaders ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedHeaders ( ) . toArray ( ) ) ;
assertTrue ( CollectionUtils . isEmpty ( config . getExposedHeaders ( ) ) ) ;
assertEquals ( new Long ( 1800 ) , config . getMaxAge ( ) ) ;
}
@ -127,10 +136,10 @@ public class CrossOriginTests {
@@ -127,10 +136,10 @@ public class CrossOriginTests {
HandlerExecutionChain chain = this . handlerMapping . getHandler ( request ) ;
CorsConfiguration config = getCorsConfiguration ( chain , false ) ;
assertNotNull ( config ) ;
assertArrayEquals ( new String [ ] { "DELETE" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "http://site1.com" , "http://site2.com" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "header1" , "header2" } , config . getAllowedHeaders ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "header3" , "header4" } , config . getExposedHeaders ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "DELETE" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "http://site1.com" , "http://site2.com" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "header1" , "header2" } , config . getAllowedHeaders ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "header3" , "header4" } , config . getExposedHeaders ( ) . toArray ( ) ) ;
assertEquals ( new Long ( 123 ) , config . getMaxAge ( ) ) ;
assertFalse ( config . getAllowCredentials ( ) ) ;
}
@ -146,6 +155,17 @@ public class CrossOriginTests {
@@ -146,6 +155,17 @@ public class CrossOriginTests {
assertTrue ( config . getAllowCredentials ( ) ) ;
}
@Test
public void customOriginDefinedViaPlaceholder ( ) throws Exception {
this . handlerMapping . registerHandler ( new MethodLevelController ( ) ) ;
this . request . setRequestURI ( "/someOrigin" ) ;
HandlerExecutionChain chain = this . handlerMapping . getHandler ( request ) ;
CorsConfiguration config = getCorsConfiguration ( chain , false ) ;
assertNotNull ( config ) ;
assertEquals ( Arrays . asList ( "http://example.com" ) , config . getAllowedOrigins ( ) ) ;
assertTrue ( config . getAllowCredentials ( ) ) ;
}
@Test
public void bogusAllowCredentialsValue ( ) throws Exception {
exception . expect ( IllegalStateException . class ) ;
@ -162,24 +182,24 @@ public class CrossOriginTests {
@@ -162,24 +182,24 @@ public class CrossOriginTests {
HandlerExecutionChain chain = this . handlerMapping . getHandler ( request ) ;
CorsConfiguration config = getCorsConfiguration ( chain , false ) ;
assertNotNull ( config ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertFalse ( config . getAllowCredentials ( ) ) ;
this . request . setRequestURI ( "/bar" ) ;
chain = this . handlerMapping . getHandler ( request ) ;
config = getCorsConfiguration ( chain , false ) ;
assertNotNull ( config ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertFalse ( config . getAllowCredentials ( ) ) ;
this . request . setRequestURI ( "/baz" ) ;
chain = this . handlerMapping . getHandler ( request ) ;
config = getCorsConfiguration ( chain , false ) ;
assertNotNull ( config ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertTrue ( config . getAllowCredentials ( ) ) ;
}
@ -191,8 +211,8 @@ public class CrossOriginTests {
@@ -191,8 +211,8 @@ public class CrossOriginTests {
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 ( ) ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "http://foo.com" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertTrue ( config . getAllowCredentials ( ) ) ;
}
@ -204,8 +224,8 @@ public class CrossOriginTests {
@@ -204,8 +224,8 @@ public class CrossOriginTests {
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 ( ) ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "http://foo.com" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertTrue ( config . getAllowCredentials ( ) ) ;
}
@ -218,10 +238,10 @@ public class CrossOriginTests {
@@ -218,10 +238,10 @@ public class CrossOriginTests {
HandlerExecutionChain chain = this . handlerMapping . getHandler ( request ) ;
CorsConfiguration config = getCorsConfiguration ( chain , true ) ;
assertNotNull ( config ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "GET" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertTrue ( config . getAllowCredentials ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedHeaders ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedHeaders ( ) . toArray ( ) ) ;
assertTrue ( CollectionUtils . isEmpty ( config . getExposedHeaders ( ) ) ) ;
assertEquals ( new Long ( 1800 ) , config . getMaxAge ( ) ) ;
}
@ -236,9 +256,9 @@ public class CrossOriginTests {
@@ -236,9 +256,9 @@ public class CrossOriginTests {
HandlerExecutionChain chain = this . handlerMapping . getHandler ( request ) ;
CorsConfiguration config = getCorsConfiguration ( chain , true ) ;
assertNotNull ( config ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedHeaders ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedHeaders ( ) . toArray ( ) ) ;
assertTrue ( config . getAllowCredentials ( ) ) ;
assertTrue ( CollectionUtils . isEmpty ( config . getExposedHeaders ( ) ) ) ;
assertNull ( config . getMaxAge ( ) ) ;
@ -253,9 +273,9 @@ public class CrossOriginTests {
@@ -253,9 +273,9 @@ public class CrossOriginTests {
HandlerExecutionChain chain = this . handlerMapping . getHandler ( request ) ;
CorsConfiguration config = getCorsConfiguration ( chain , true ) ;
assertNotNull ( config ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedHeaders ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedMethods ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedOrigins ( ) . toArray ( ) ) ;
assertArrayEquals ( new String [ ] { "*" } , config . getAllowedHeaders ( ) . toArray ( ) ) ;
assertTrue ( config . getAllowCredentials ( ) ) ;
assertTrue ( CollectionUtils . isEmpty ( config . getExposedHeaders ( ) ) ) ;
assertNull ( config . getMaxAge ( ) ) ;
@ -343,8 +363,14 @@ public class CrossOriginTests {
@@ -343,8 +363,14 @@ public class CrossOriginTests {
@RequestMapping ( "/customOrigin" )
public void customOriginDefinedViaValueAttribute ( ) {
}
@CrossOrigin ( "${myOrigin}" )
@RequestMapping ( "/someOrigin" )
public void customOriginDefinedViaPlaceholder ( ) {
}
}
@Controller
private static class MethodLevelControllerWithBogusAllowCredentialsValue {
@ -354,6 +380,7 @@ public class CrossOriginTests {
@@ -354,6 +380,7 @@ public class CrossOriginTests {
}
}
@Controller
@CrossOrigin ( allowCredentials = "false" )
private static class ClassLevelController {
@ -374,14 +401,18 @@ public class CrossOriginTests {
@@ -374,14 +401,18 @@ 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 {
@ -401,6 +432,7 @@ public class CrossOriginTests {
@@ -401,6 +432,7 @@ public class CrossOriginTests {
}
}
private static class TestRequestMappingInfoHandlerMapping extends RequestMappingHandlerMapping {
public void registerHandler ( Object handler ) {