CorsUtilsTests.java 5.6 KB
Newer Older
S
Sebastien Deleuze 已提交
1
/*
2
 * Copyright 2002-2018 the original author or authors.
S
Sebastien Deleuze 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 *
 * 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.cors.reactive;

19 20
import java.util.concurrent.atomic.AtomicReference;

S
Sebastien Deleuze 已提交
21
import org.junit.Test;
22
import reactor.core.publisher.Mono;
S
Sebastien Deleuze 已提交
23 24

import org.springframework.http.HttpHeaders;
25
import org.springframework.http.server.reactive.ServerHttpRequest;
S
Sebastien Deleuze 已提交
26
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
27 28
import org.springframework.mock.web.test.server.MockServerWebExchange;
import org.springframework.web.filter.reactive.ForwardedHeaderFilter;
29

30 31
import static org.junit.Assert.*;
import static org.springframework.mock.http.server.reactive.test.MockServerHttpRequest.*;
S
Sebastien Deleuze 已提交
32 33 34 35

/**
 * Test case for reactive {@link CorsUtils}.
 * @author Sebastien Deleuze
36
 * @author Rossen Stoyanchev
S
Sebastien Deleuze 已提交
37 38 39 40 41
 */
public class CorsUtilsTests {

	@Test
	public void isCorsRequest() {
S
Spring Operator 已提交
42
		ServerHttpRequest request = get("/").header(HttpHeaders.ORIGIN, "https://domain.com").build();
S
Sebastien Deleuze 已提交
43 44 45 46 47
		assertTrue(CorsUtils.isCorsRequest(request));
	}

	@Test
	public void isNotCorsRequest() {
48
		ServerHttpRequest request = get("/").build();
S
Sebastien Deleuze 已提交
49 50 51 52 53
		assertFalse(CorsUtils.isCorsRequest(request));
	}

	@Test
	public void isPreFlightRequest() {
54
		ServerHttpRequest request = options("/")
S
Spring Operator 已提交
55
				.header(HttpHeaders.ORIGIN, "https://domain.com")
56 57
				.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET")
				.build();
S
Sebastien Deleuze 已提交
58 59 60 61 62
		assertTrue(CorsUtils.isPreFlightRequest(request));
	}

	@Test
	public void isNotPreFlightRequest() {
63
		ServerHttpRequest request = get("/").build();
S
Sebastien Deleuze 已提交
64 65
		assertFalse(CorsUtils.isPreFlightRequest(request));

S
Spring Operator 已提交
66
		request = options("/").header(HttpHeaders.ORIGIN, "https://domain.com").build();
S
Sebastien Deleuze 已提交
67 68
		assertFalse(CorsUtils.isPreFlightRequest(request));

69
		request = options("/").header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET").build();
S
Sebastien Deleuze 已提交
70 71 72
		assertFalse(CorsUtils.isPreFlightRequest(request));
	}

S
sdeleuze 已提交
73 74
	@Test  // SPR-16262
	public void isSameOriginWithXForwardedHeaders() {
75 76 77 78 79 80 81
		String server = "mydomain1.com";
		testWithXForwardedHeaders(server, -1, "https", null, -1, "https://mydomain1.com");
		testWithXForwardedHeaders(server, 123, "https", null, -1, "https://mydomain1.com");
		testWithXForwardedHeaders(server, -1, "https", "mydomain2.com", -1, "https://mydomain2.com");
		testWithXForwardedHeaders(server, 123, "https", "mydomain2.com", -1, "https://mydomain2.com");
		testWithXForwardedHeaders(server, -1, "https", "mydomain2.com", 456, "https://mydomain2.com:456");
		testWithXForwardedHeaders(server, 123, "https", "mydomain2.com", 456, "https://mydomain2.com:456");
S
sdeleuze 已提交
82 83 84 85
	}

	@Test  // SPR-16262
	public void isSameOriginWithForwardedHeader() {
86 87 88 89 90 91 92
		String server = "mydomain1.com";
		testWithForwardedHeader(server, -1, "proto=https", "https://mydomain1.com");
		testWithForwardedHeader(server, 123, "proto=https", "https://mydomain1.com");
		testWithForwardedHeader(server, -1, "proto=https; host=mydomain2.com", "https://mydomain2.com");
		testWithForwardedHeader(server, 123, "proto=https; host=mydomain2.com", "https://mydomain2.com");
		testWithForwardedHeader(server, -1, "proto=https; host=mydomain2.com:456", "https://mydomain2.com:456");
		testWithForwardedHeader(server, 123, "proto=https; host=mydomain2.com:456", "https://mydomain2.com:456");
S
sdeleuze 已提交
93 94
	}

95 96 97
	@Test  // SPR-16362
	public void isSameOriginWithDifferentSchemes() {
		MockServerHttpRequest request = MockServerHttpRequest
S
Spring Operator 已提交
98
				.get("https://mydomain1.com")
99 100 101 102 103
				.header(HttpHeaders.ORIGIN, "https://mydomain1.com")
				.build();
		assertFalse(CorsUtils.isSameOrigin(request));
	}

104 105 106
	private void testWithXForwardedHeaders(String serverName, int port,
			String forwardedProto, String forwardedHost, int forwardedPort, String originHeader) {

S
sdeleuze 已提交
107 108 109 110
		String url = "http://" + serverName;
		if (port != -1) {
			url = url + ":" + port;
		}
111 112

		MockServerHttpRequest.BaseBuilder<?> builder = get(url).header(HttpHeaders.ORIGIN, originHeader);
S
sdeleuze 已提交
113 114 115 116 117 118 119 120 121
		if (forwardedProto != null) {
			builder.header("X-Forwarded-Proto", forwardedProto);
		}
		if (forwardedHost != null) {
			builder.header("X-Forwarded-Host", forwardedHost);
		}
		if (forwardedPort != -1) {
			builder.header("X-Forwarded-Port", String.valueOf(forwardedPort));
		}
122 123 124

		ServerHttpRequest request = adaptFromForwardedHeaders(builder);
		assertTrue(CorsUtils.isSameOrigin(request));
S
sdeleuze 已提交
125 126
	}

127 128 129
	private void testWithForwardedHeader(String serverName, int port,
			String forwardedHeader, String originHeader) {

S
sdeleuze 已提交
130 131 132 133
		String url = "http://" + serverName;
		if (port != -1) {
			url = url + ":" + port;
		}
134

S
sdeleuze 已提交
135 136 137
		MockServerHttpRequest.BaseBuilder<?> builder = get(url)
				.header("Forwarded", forwardedHeader)
				.header(HttpHeaders.ORIGIN, originHeader);
138 139 140 141 142 143 144 145 146 147 148 149 150 151

		ServerHttpRequest request = adaptFromForwardedHeaders(builder);
		assertTrue(CorsUtils.isSameOrigin(request));
	}

	// SPR-16668
	private ServerHttpRequest adaptFromForwardedHeaders(MockServerHttpRequest.BaseBuilder<?> builder) {
		AtomicReference<ServerHttpRequest> requestRef = new AtomicReference<>();
		MockServerWebExchange exchange = MockServerWebExchange.from(builder);
		new ForwardedHeaderFilter().filter(exchange, exchange2 -> {
			requestRef.set(exchange2.getRequest());
			return Mono.empty();
		}).block();
		return requestRef.get();
S
sdeleuze 已提交
152 153
	}

S
Sebastien Deleuze 已提交
154
}