55 * you may not use this file except in compliance with the License.
66 * You may obtain a copy of the License at
77 *
8- * http://www.apache.org/licenses/LICENSE-2.0
8+ * http://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121import java .util .List ;
2222
2323import org .springframework .http .HttpMethod ;
24+ import org .springframework .util .CollectionUtils ;
2425import org .springframework .util .ObjectUtils ;
2526import org .springframework .util .StringUtils ;
2627
3031 *
3132 * @author Sebastien Deleuze
3233 * @author Rossen Stoyanchev
34+ * @author Juergen Hoeller
3335 * @author Sam Brannen
3436 * @since 4.2
3537 * @see <a href="http://www.w3.org/TR/cors/">CORS W3C recommendation</a>
@@ -41,10 +43,22 @@ public class CorsConfiguration {
4143 */
4244 public static final String ALL = "*" ;
4345
46+ private static final List <HttpMethod > DEFAULT_METHODS ;
47+
48+ static {
49+ List <HttpMethod > rawMethods = new ArrayList <HttpMethod >(2 );
50+ rawMethods .add (HttpMethod .GET );
51+ rawMethods .add (HttpMethod .HEAD );
52+ DEFAULT_METHODS = Collections .unmodifiableList (rawMethods );
53+ }
54+
55+
4456 private List <String > allowedOrigins ;
4557
4658 private List <String > allowedMethods ;
4759
60+ private List <HttpMethod > resolvedMethods = DEFAULT_METHODS ;
61+
4862 private List <String > allowedHeaders ;
4963
5064 private List <String > exposedHeaders ;
@@ -67,6 +81,7 @@ public CorsConfiguration() {
6781 public CorsConfiguration (CorsConfiguration other ) {
6882 this .allowedOrigins = other .allowedOrigins ;
6983 this .allowedMethods = other .allowedMethods ;
84+ this .resolvedMethods = other .resolvedMethods ;
7085 this .allowedHeaders = other .allowedHeaders ;
7186 this .exposedHeaders = other .exposedHeaders ;
7287 this .allowCredentials = other .allowCredentials ;
@@ -86,10 +101,10 @@ public CorsConfiguration combine(CorsConfiguration other) {
86101 return this ;
87102 }
88103 CorsConfiguration config = new CorsConfiguration (this );
89- config .setAllowedOrigins (combine (this . getAllowedOrigins (), other .getAllowedOrigins ()));
90- config .setAllowedMethods (combine (this . getAllowedMethods (), other .getAllowedMethods ()));
91- config .setAllowedHeaders (combine (this . getAllowedHeaders (), other .getAllowedHeaders ()));
92- config .setExposedHeaders (combine (this . getExposedHeaders (), other .getExposedHeaders ()));
104+ config .setAllowedOrigins (combine (getAllowedOrigins (), other .getAllowedOrigins ()));
105+ config .setAllowedMethods (combine (getAllowedMethods (), other .getAllowedMethods ()));
106+ config .setAllowedHeaders (combine (getAllowedHeaders (), other .getAllowedHeaders ()));
107+ config .setExposedHeaders (combine (getExposedHeaders (), other .getExposedHeaders ()));
93108 Boolean allowCredentials = other .getAllowCredentials ();
94109 if (allowCredentials != null ) {
95110 config .setAllowCredentials (allowCredentials );
@@ -137,7 +152,7 @@ public List<String> getAllowedOrigins() {
137152 */
138153 public void addAllowedOrigin (String origin ) {
139154 if (this .allowedOrigins == null ) {
140- this .allowedOrigins = new ArrayList <String >();
155+ this .allowedOrigins = new ArrayList <String >(4 );
141156 }
142157 this .allowedOrigins .add (origin );
143158 }
@@ -146,16 +161,29 @@ public void addAllowedOrigin(String origin) {
146161 * Set the HTTP methods to allow, e.g. {@code "GET"}, {@code "POST"},
147162 * {@code "PUT"}, etc.
148163 * <p>The special value {@code "*"} allows all methods.
149- * <p>If not set, only {@code "GET"} is allowed.
164+ * <p>If not set, only {@code "GET"} and {@code "HEAD"} are allowed.
150165 * <p>By default this is not set.
151166 */
152167 public void setAllowedMethods (List <String > allowedMethods ) {
153168 this .allowedMethods = (allowedMethods != null ? new ArrayList <String >(allowedMethods ) : null );
169+ if (!CollectionUtils .isEmpty (allowedMethods )) {
170+ this .resolvedMethods = new ArrayList <HttpMethod >(allowedMethods .size ());
171+ for (String method : allowedMethods ) {
172+ if (ALL .equals (method )) {
173+ this .resolvedMethods = null ;
174+ break ;
175+ }
176+ this .resolvedMethods .add (HttpMethod .resolve (method ));
177+ }
178+ }
179+ else {
180+ this .resolvedMethods = DEFAULT_METHODS ;
181+ }
154182 }
155183
156184 /**
157185 * Return the allowed HTTP methods, possibly {@code null} in which case
158- * only {@code "GET"} is allowed.
186+ * only {@code "GET"} and {@code "HEAD"} allowed.
159187 * @see #addAllowedMethod(HttpMethod)
160188 * @see #addAllowedMethod(String)
161189 * @see #setAllowedMethods(List)
@@ -179,9 +207,16 @@ public void addAllowedMethod(HttpMethod method) {
179207 public void addAllowedMethod (String method ) {
180208 if (StringUtils .hasText (method )) {
181209 if (this .allowedMethods == null ) {
182- this .allowedMethods = new ArrayList <String >();
210+ this .allowedMethods = new ArrayList <String >(4 );
211+ this .resolvedMethods = new ArrayList <HttpMethod >(4 );
183212 }
184213 this .allowedMethods .add (method );
214+ if (ALL .equals (method )) {
215+ this .resolvedMethods = null ;
216+ }
217+ else if (this .resolvedMethods != null ) {
218+ this .resolvedMethods .add (HttpMethod .resolve (method ));
219+ }
185220 }
186221 }
187222
@@ -213,7 +248,7 @@ public List<String> getAllowedHeaders() {
213248 */
214249 public void addAllowedHeader (String allowedHeader ) {
215250 if (this .allowedHeaders == null ) {
216- this .allowedHeaders = new ArrayList <String >();
251+ this .allowedHeaders = new ArrayList <String >(4 );
217252 }
218253 this .allowedHeaders .add (allowedHeader );
219254 }
@@ -230,7 +265,7 @@ public void setExposedHeaders(List<String> exposedHeaders) {
230265 if (exposedHeaders != null && exposedHeaders .contains (ALL )) {
231266 throw new IllegalArgumentException ("'*' is not a valid exposed header value" );
232267 }
233- this .exposedHeaders = (exposedHeaders == null ? null : new ArrayList <String >(exposedHeaders ));
268+ this .exposedHeaders = (exposedHeaders != null ? new ArrayList <String >(exposedHeaders ) : null );
234269 }
235270
236271 /**
@@ -333,27 +368,10 @@ public List<HttpMethod> checkHttpMethod(HttpMethod requestMethod) {
333368 if (requestMethod == null ) {
334369 return null ;
335370 }
336- List <String > allowedMethods =
337- (this .allowedMethods != null ? this .allowedMethods : new ArrayList <String >());
338- if (allowedMethods .contains (ALL )) {
371+ if (this .resolvedMethods == null ) {
339372 return Collections .singletonList (requestMethod );
340373 }
341- if (allowedMethods .isEmpty ()) {
342- allowedMethods .add (HttpMethod .GET .name ());
343- allowedMethods .add (HttpMethod .HEAD .name ());
344- }
345- List <HttpMethod > result = new ArrayList <HttpMethod >(allowedMethods .size ());
346- boolean allowed = false ;
347- for (String method : allowedMethods ) {
348- if (requestMethod .matches (method )) {
349- allowed = true ;
350- }
351- HttpMethod resolved = HttpMethod .resolve (method );
352- if (resolved != null ) {
353- result .add (resolved );
354- }
355- }
356- return (allowed ? result : null );
374+ return (this .resolvedMethods .contains (requestMethod ) ? this .resolvedMethods : null );
357375 }
358376
359377 /**
@@ -376,14 +394,19 @@ public List<String> checkHeaders(List<String> requestHeaders) {
376394 }
377395
378396 boolean allowAnyHeader = this .allowedHeaders .contains (ALL );
379- List <String > result = new ArrayList <String >();
397+ List <String > result = new ArrayList <String >(requestHeaders . size () );
380398 for (String requestHeader : requestHeaders ) {
381399 if (StringUtils .hasText (requestHeader )) {
382400 requestHeader = requestHeader .trim ();
383- for (String allowedHeader : this .allowedHeaders ) {
384- if (allowAnyHeader || requestHeader .equalsIgnoreCase (allowedHeader )) {
385- result .add (requestHeader );
386- break ;
401+ if (allowAnyHeader ) {
402+ result .add (requestHeader );
403+ }
404+ else {
405+ for (String allowedHeader : this .allowedHeaders ) {
406+ if (requestHeader .equalsIgnoreCase (allowedHeader )) {
407+ result .add (requestHeader );
408+ break ;
409+ }
387410 }
388411 }
389412 }
0 commit comments