/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.reactive.handler;
import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.server.ServerWebExchange;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
/**
* Unit tests for CORS support at {@link AbstractUrlHandlerMapping} level.
*
* @author Sebastien Deleuze
* @author Rossen Stoyanchev
*/
public class CorsUrlHandlerMappingTests {
private AbstractUrlHandlerMapping handlerMapping;
private Object welcomeController = new Object();
private CorsAwareHandler corsController = new CorsAwareHandler();
@Before
public void setup() {
this.handlerMapping = new AbstractUrlHandlerMapping() {};
this.handlerMapping.setUseTrailingSlashMatch(true);
this.handlerMapping.registerHandler("/welcome.html", this.welcomeController);
this.handlerMapping.registerHandler("/cors.html", this.corsController);
}
@Test
public void actualRequestWithoutCorsConfigurationProvider() throws Exception {
String origin = "http://domain2.com";
ServerWebExchange exchange = createExchange(HttpMethod.GET, "/welcome.html", origin);
Object actual = this.handlerMapping.getHandler(exchange).block();
assertNotNull(actual);
assertSame(this.welcomeController, actual);
}
@Test
public void preflightRequestWithoutCorsConfigurationProvider() throws Exception {
String origin = "http://domain2.com";
ServerWebExchange exchange = createExchange(HttpMethod.OPTIONS, "/welcome.html", origin);
Object actual = this.handlerMapping.getHandler(exchange).block();
assertNotNull(actual);
assertNotSame(this.welcomeController, actual);
assertNull(exchange.getResponse().getHeaders().getFirst(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN));
}
@Test
public void actualRequestWithCorsAwareHandler() throws Exception {
String origin = "http://domain2.com";
ServerWebExchange exchange = createExchange(HttpMethod.GET, "/cors.html", origin);
Object actual = this.handlerMapping.getHandler(exchange).block();
assertNotNull(actual);
assertSame(this.corsController, actual);
assertEquals("*", exchange.getResponse().getHeaders().getFirst(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN));
}
@Test
public void preFlightWithCorsAwareHandler() throws Exception {
String origin = "http://domain2.com";
ServerWebExchange exchange = createExchange(HttpMethod.OPTIONS, "/cors.html", origin);
Object actual = this.handlerMapping.getHandler(exchange).block();
assertNotNull(actual);
assertNotSame(this.corsController, actual);
assertEquals("*", exchange.getResponse().getHeaders().getFirst(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN));
}
@Test
public void actualRequestWithGlobalCorsConfig() throws Exception {
CorsConfiguration mappedConfig = new CorsConfiguration();
mappedConfig.addAllowedOrigin("*");
this.handlerMapping.setCorsConfigurations(Collections.singletonMap("/welcome.html", mappedConfig));
String origin = "http://domain2.com";
ServerWebExchange exchange = createExchange(HttpMethod.GET, "/welcome.html", origin);
Object actual = this.handlerMapping.getHandler(exchange).block();
assertNotNull(actual);
assertSame(this.welcomeController, actual);
assertEquals("*", exchange.getResponse().getHeaders().getFirst(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN));
}
@Test
public void preFlightRequestWithGlobalCorsConfig() throws Exception {
CorsConfiguration mappedConfig = new CorsConfiguration();
mappedConfig.addAllowedOrigin("*");
this.handlerMapping.setCorsConfigurations(Collections.singletonMap("/welcome.html", mappedConfig));
String origin = "http://domain2.com";
ServerWebExchange exchange = createExchange(HttpMethod.OPTIONS, "/welcome.html", origin);
Object actual = this.handlerMapping.getHandler(exchange).block();
assertNotNull(actual);
assertNotSame(this.welcomeController, actual);
assertEquals("*", exchange.getResponse().getHeaders().getFirst(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN));
}
private ServerWebExchange createExchange(HttpMethod method, String path, String origin) {
return MockServerHttpRequest
.method(method, "http://localhost" + path)
.header("Origin", origin)
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET")
.toExchange();
}
private class CorsAwareHandler implements CorsConfigurationSource {
@Override
public CorsConfiguration getCorsConfiguration(ServerWebExchange exchange) {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
return config;
}
}
}