diff --git a/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java b/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java index d774012e51..71624a0917 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java +++ b/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java @@ -18,7 +18,9 @@ package org.springframework.web.cors; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import org.springframework.http.HttpMethod; import org.springframework.util.CollectionUtils; @@ -123,12 +125,11 @@ public class CorsConfiguration { if (source == null || source.contains(ALL)) { return other; } - List combined = new ArrayList(source); + Set combined = new LinkedHashSet(source); combined.addAll(other); - return combined; + return new ArrayList(combined); } - /** * Set the origins to allow, e.g. {@code "http://domain1.com"}. *

The special value {@code "*"} allows all domains. diff --git a/spring-web/src/test/java/org/springframework/web/cors/CorsConfigurationTests.java b/spring-web/src/test/java/org/springframework/web/cors/CorsConfigurationTests.java index 9b7cbb8e8e..a7c54566b0 100644 --- a/spring-web/src/test/java/org/springframework/web/cors/CorsConfigurationTests.java +++ b/spring-web/src/test/java/org/springframework/web/cors/CorsConfigurationTests.java @@ -131,6 +131,29 @@ public class CorsConfigurationTests { assertEquals(Arrays.asList(HttpMethod.PUT.name()), combinedConfig.getAllowedMethods()); } + @Test // SPR-14792 + public void combineWithDuplicatedElements() { + CorsConfiguration config = new CorsConfiguration(); + config.addAllowedOrigin("http://domain1.com"); + config.addAllowedOrigin("http://domain2.com"); + config.addAllowedHeader("header1"); + config.addAllowedHeader("header2"); + config.addExposedHeader("header3"); + config.addExposedHeader("header4"); + config.addAllowedMethod(HttpMethod.GET.name()); + config.addAllowedMethod(HttpMethod.PUT.name()); + CorsConfiguration other = new CorsConfiguration(); + other.addAllowedOrigin("http://domain1.com"); + other.addAllowedHeader("header1"); + other.addExposedHeader("header3"); + other.addAllowedMethod(HttpMethod.GET.name()); + CorsConfiguration combinedConfig = config.combine(other); + assertEquals(Arrays.asList("http://domain1.com", "http://domain2.com"), combinedConfig.getAllowedOrigins()); + assertEquals(Arrays.asList("header1", "header2"), combinedConfig.getAllowedHeaders()); + assertEquals(Arrays.asList("header3", "header4"), combinedConfig.getExposedHeaders()); + assertEquals(Arrays.asList(HttpMethod.GET.name(), HttpMethod.PUT.name()), combinedConfig.getAllowedMethods()); + } + @Test public void combine() { CorsConfiguration config = new CorsConfiguration();