Polish Forwarded header support
This commit is contained in:
parent
1e4a3a2370
commit
72022899de
|
@ -42,19 +42,19 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||||
import org.springframework.web.util.UrlPathHelper;
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract values from "Forwarded" and "X-Forwarded-*" headers in order to wrap
|
* Extract values from "Forwarded" and "X-Forwarded-*" headers, wrap the request
|
||||||
* and override the following from the request and response:
|
* and response, and make they reflect the client-originated protocol and
|
||||||
* {@link HttpServletRequest#getServerName() getServerName()},
|
* address in the following methods:
|
||||||
* {@link HttpServletRequest#getServerPort() getServerPort()},
|
* <ul>
|
||||||
* {@link HttpServletRequest#getScheme() getScheme()},
|
* <li>{@link HttpServletRequest#getServerName() getServerName()}
|
||||||
* {@link HttpServletRequest#isSecure() isSecure()}, and
|
* <li>{@link HttpServletRequest#getServerPort() getServerPort()}
|
||||||
* {@link HttpServletResponse#sendRedirect(String) sendRedirect(String)}.
|
* <li>{@link HttpServletRequest#getScheme() getScheme()}
|
||||||
* In effect the wrapped request and response reflect the client-originated
|
* <li>{@link HttpServletRequest#isSecure() isSecure()}
|
||||||
* protocol and address.
|
* <li>{@link HttpServletResponse#sendRedirect(String) sendRedirect(String)}.
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p><strong>Note:</strong> This filter can also be used in a
|
* <p>This filter can also be used in a {@link #setRemoveOnly removeOnly} mode
|
||||||
* {@link #setRemoveOnly removeOnly} mode where "Forwarded" and "X-Forwarded-*"
|
* where "Forwarded" and "X-Forwarded-*" headers are eliminated, and not used.
|
||||||
* headers are only eliminated without being used.
|
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @author Eddú Meléndez
|
* @author Eddú Meléndez
|
||||||
|
@ -117,7 +117,7 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
|
protected boolean shouldNotFilter(HttpServletRequest request) {
|
||||||
for (String headerName : FORWARDED_HEADER_NAMES) {
|
for (String headerName : FORWARDED_HEADER_NAMES) {
|
||||||
if (request.getHeader(headerName) != null) {
|
if (request.getHeader(headerName) != null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -141,15 +141,18 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
|
||||||
FilterChain filterChain) throws ServletException, IOException {
|
FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
|
||||||
if (this.removeOnly) {
|
if (this.removeOnly) {
|
||||||
ForwardedHeaderRemovingRequest theRequest = new ForwardedHeaderRemovingRequest(request);
|
ForwardedHeaderRemovingRequest wrappedRequest = new ForwardedHeaderRemovingRequest(request);
|
||||||
filterChain.doFilter(theRequest, response);
|
filterChain.doFilter(wrappedRequest, response);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
HttpServletRequest theRequest = new ForwardedHeaderExtractingRequest(request, this.pathHelper);
|
HttpServletRequest wrappedRequest =
|
||||||
HttpServletResponse theResponse = (this.relativeRedirects ?
|
new ForwardedHeaderExtractingRequest(request, this.pathHelper);
|
||||||
|
|
||||||
|
HttpServletResponse wrappedResponse = this.relativeRedirects ?
|
||||||
RelativeRedirectResponseWrapper.wrapIfNecessary(response, HttpStatus.SEE_OTHER) :
|
RelativeRedirectResponseWrapper.wrapIfNecessary(response, HttpStatus.SEE_OTHER) :
|
||||||
new ForwardedHeaderExtractingResponse(response, theRequest));
|
new ForwardedHeaderExtractingResponse(response, wrappedRequest);
|
||||||
filterChain.doFilter(theRequest, theResponse);
|
|
||||||
|
filterChain.doFilter(wrappedRequest, wrappedResponse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +224,8 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
private final String requestUrl;
|
private final String requestUrl;
|
||||||
|
|
||||||
public ForwardedHeaderExtractingRequest(HttpServletRequest request, UrlPathHelper pathHelper) {
|
|
||||||
|
ForwardedHeaderExtractingRequest(HttpServletRequest request, UrlPathHelper pathHelper) {
|
||||||
super(request);
|
super(request);
|
||||||
|
|
||||||
HttpRequest httpRequest = new ServletServerHttpRequest(request);
|
HttpRequest httpRequest = new ServletServerHttpRequest(request);
|
||||||
|
@ -257,6 +261,7 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
|
||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getScheme() {
|
public String getScheme() {
|
||||||
|
@ -302,11 +307,13 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
private final HttpServletRequest request;
|
private final HttpServletRequest request;
|
||||||
|
|
||||||
public ForwardedHeaderExtractingResponse(HttpServletResponse response, HttpServletRequest request) {
|
|
||||||
|
ForwardedHeaderExtractingResponse(HttpServletResponse response, HttpServletRequest request) {
|
||||||
super(response);
|
super(response);
|
||||||
this.request = request;
|
this.request = request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendRedirect(String location) throws IOException {
|
public void sendRedirect(String location) throws IOException {
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2017 the original author or authors.
|
* Copyright 2002-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -31,17 +31,16 @@ import org.springframework.web.server.WebFilterChain;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract values from "Forwarded" and "X-Forwarded-*" headers in order to change
|
* Extract values from "Forwarded" and "X-Forwarded-*" headers, and use them to
|
||||||
* and override {@link ServerHttpRequest#getURI()}.
|
* override {@link ServerHttpRequest#getURI()} to reflect the client-originated
|
||||||
* In effect the request URI will reflect the client-originated
|
|
||||||
* protocol and address.
|
* protocol and address.
|
||||||
*
|
*
|
||||||
* <p><strong>Note:</strong> This filter can also be used in a
|
* <p>This filter can also be used in a {@link #setRemoveOnly removeOnly} mode
|
||||||
* {@link #setRemoveOnly removeOnly} mode where "Forwarded" and "X-Forwarded-*"
|
* where "Forwarded" and "X-Forwarded-*" headers are eliminated, and not used.
|
||||||
* headers are only eliminated without being used.
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @see <a href="https://tools.ietf.org/html/rfc7239">https://tools.ietf.org/html/rfc7239</a>
|
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
|
* @see <a href="https://tools.ietf.org/html/rfc7239">https://tools.ietf.org/html/rfc7239</a>
|
||||||
*/
|
*/
|
||||||
public class ForwardedHeaderFilter implements WebFilter {
|
public class ForwardedHeaderFilter implements WebFilter {
|
||||||
|
|
||||||
|
@ -55,8 +54,10 @@ public class ForwardedHeaderFilter implements WebFilter {
|
||||||
FORWARDED_HEADER_NAMES.add("X-Forwarded-Prefix");
|
FORWARDED_HEADER_NAMES.add("X-Forwarded-Prefix");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean removeOnly;
|
private boolean removeOnly;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables mode in which any "Forwarded" or "X-Forwarded-*" headers are
|
* Enables mode in which any "Forwarded" or "X-Forwarded-*" headers are
|
||||||
* removed only and the information in them ignored.
|
* removed only and the information in them ignored.
|
||||||
|
@ -66,6 +67,7 @@ public class ForwardedHeaderFilter implements WebFilter {
|
||||||
this.removeOnly = removeOnly;
|
this.removeOnly = removeOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||||
|
|
||||||
|
@ -73,31 +75,29 @@ public class ForwardedHeaderFilter implements WebFilter {
|
||||||
return chain.filter(exchange);
|
return chain.filter(exchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerWebExchange mutatedExchange;
|
||||||
|
|
||||||
if (this.removeOnly) {
|
if (this.removeOnly) {
|
||||||
ServerWebExchange withoutForwardHeaders = exchange.mutate()
|
mutatedExchange = exchange.mutate().request(builder ->
|
||||||
.request(builder -> builder.headers(
|
builder.headers(headers -> {
|
||||||
headers -> {
|
FORWARDED_HEADER_NAMES.forEach(headers::remove);
|
||||||
for (String headerName : FORWARDED_HEADER_NAMES) {
|
}))
|
||||||
headers.remove(headerName);
|
.build();
|
||||||
}
|
|
||||||
})).build();
|
|
||||||
return chain.filter(withoutForwardHeaders);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
URI uri = UriComponentsBuilder.fromHttpRequest(exchange.getRequest()).build().toUri();
|
URI uri = UriComponentsBuilder.fromHttpRequest(exchange.getRequest()).build().toUri();
|
||||||
String prefix = getForwardedPrefix(exchange.getRequest().getHeaders());
|
String prefix = getForwardedPrefix(exchange.getRequest().getHeaders());
|
||||||
|
|
||||||
ServerWebExchange withChangedUri = exchange.mutate()
|
mutatedExchange = exchange.mutate().request(builder -> {
|
||||||
.request(builder -> {
|
|
||||||
builder.uri(uri);
|
builder.uri(uri);
|
||||||
if (prefix != null) {
|
if (prefix != null) {
|
||||||
builder.path(prefix + uri.getPath());
|
builder.path(prefix + uri.getPath());
|
||||||
builder.contextPath(prefix);
|
builder.contextPath(prefix);
|
||||||
}
|
}
|
||||||
}).build();
|
}).build();
|
||||||
return chain.filter(withChangedUri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return chain.filter(mutatedExchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldNotFilter(ServerHttpRequest request) {
|
private boolean shouldNotFilter(ServerHttpRequest request) {
|
||||||
|
|
|
@ -103,6 +103,17 @@ public class ForwardedHeaderFilterTests {
|
||||||
assertEquals("/prefix", actual);
|
assertEquals("/prefix", actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String filterAndGetContextPath() throws ServletException, IOException {
|
||||||
|
return filterAndGetWrappedRequest().getContextPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpServletRequest filterAndGetWrappedRequest() throws ServletException, IOException {
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
this.filter.doFilterInternal(this.request, response, this.filterChain);
|
||||||
|
return (HttpServletRequest) this.filterChain.getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contextPathPreserveEncoding() throws Exception {
|
public void contextPathPreserveEncoding() throws Exception {
|
||||||
this.request.setContextPath("/app%20");
|
this.request.setContextPath("/app%20");
|
||||||
|
@ -183,8 +194,8 @@ public class ForwardedHeaderFilterTests {
|
||||||
@Test
|
@Test
|
||||||
public void caseInsensitiveForwardedPrefix() throws Exception {
|
public void caseInsensitiveForwardedPrefix() throws Exception {
|
||||||
this.request = new MockHttpServletRequest() {
|
this.request = new MockHttpServletRequest() {
|
||||||
// Make it case-sensitive (SPR-14372)
|
|
||||||
@Override
|
@Override // SPR-14372: make it case-sensitive
|
||||||
public String getHeader(String header) {
|
public String getHeader(String header) {
|
||||||
Enumeration<String> names = getHeaderNames();
|
Enumeration<String> names = getHeaderNames();
|
||||||
while (names.hasMoreElements()) {
|
while (names.hasMoreElements()) {
|
||||||
|
@ -204,15 +215,21 @@ public class ForwardedHeaderFilterTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldFilter() throws Exception {
|
public void shouldFilter() {
|
||||||
testShouldFilter("Forwarded");
|
testShouldFilter("Forwarded");
|
||||||
testShouldFilter(X_FORWARDED_HOST);
|
testShouldFilter(X_FORWARDED_HOST);
|
||||||
testShouldFilter(X_FORWARDED_PORT);
|
testShouldFilter(X_FORWARDED_PORT);
|
||||||
testShouldFilter(X_FORWARDED_PROTO);
|
testShouldFilter(X_FORWARDED_PROTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void testShouldFilter(String headerName) {
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addHeader(headerName, "1");
|
||||||
|
assertFalse(this.filter.shouldNotFilter(request));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldNotFilter() throws Exception {
|
public void shouldNotFilter() {
|
||||||
assertTrue(this.filter.shouldNotFilter(new MockHttpServletRequest()));
|
assertTrue(this.filter.shouldNotFilter(new MockHttpServletRequest()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,7 +434,6 @@ public class ForwardedHeaderFilterTests {
|
||||||
this.request.addHeader(X_FORWARDED_HOST, "example.com");
|
this.request.addHeader(X_FORWARDED_HOST, "example.com");
|
||||||
this.request.addHeader(X_FORWARDED_PORT, "443");
|
this.request.addHeader(X_FORWARDED_PORT, "443");
|
||||||
this.filter.setRelativeRedirects(true);
|
this.filter.setRelativeRedirects(true);
|
||||||
|
|
||||||
String location = sendRedirect("/a");
|
String location = sendRedirect("/a");
|
||||||
|
|
||||||
assertEquals("/a", location);
|
assertEquals("/a", location);
|
||||||
|
@ -426,7 +442,6 @@ public class ForwardedHeaderFilterTests {
|
||||||
@Test
|
@Test
|
||||||
public void sendRedirectWhenRequestOnlyAndNoXForwardedThenUsesRelativeRedirects() throws Exception {
|
public void sendRedirectWhenRequestOnlyAndNoXForwardedThenUsesRelativeRedirects() throws Exception {
|
||||||
this.filter.setRelativeRedirects(true);
|
this.filter.setRelativeRedirects(true);
|
||||||
|
|
||||||
String location = sendRedirect("/a");
|
String location = sendRedirect("/a");
|
||||||
|
|
||||||
assertEquals("/a", location);
|
assertEquals("/a", location);
|
||||||
|
@ -441,34 +456,12 @@ public class ForwardedHeaderFilterTests {
|
||||||
res.sendRedirect(location);
|
res.sendRedirect(location);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
MockHttpServletResponse response = doWithFiltersAndGetResponse(this.filter, filter);
|
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
FilterChain filterChain = new MockFilterChain(new HttpServlet() {}, this.filter, filter);
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
|
||||||
return response.getRedirectedUrl();
|
return response.getRedirectedUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
private MockHttpServletResponse doWithFiltersAndGetResponse(Filter... filters)
|
|
||||||
throws ServletException, IOException {
|
|
||||||
|
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
|
||||||
FilterChain filterChain = new MockFilterChain(new HttpServlet() {}, filters);
|
|
||||||
filterChain.doFilter(request, response);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String filterAndGetContextPath() throws ServletException, IOException {
|
|
||||||
return filterAndGetWrappedRequest().getContextPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpServletRequest filterAndGetWrappedRequest() throws ServletException, IOException {
|
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
|
||||||
this.filter.doFilterInternal(this.request, response, this.filterChain);
|
|
||||||
return (HttpServletRequest) this.filterChain.getRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testShouldFilter(String headerName) throws ServletException {
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader(headerName, "1");
|
|
||||||
assertFalse(this.filter.shouldNotFilter(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2017 the original author or authors.
|
* Copyright 2002-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -24,18 +24,21 @@ import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
|
||||||
import org.springframework.mock.web.test.server.MockServerWebExchange;
|
import org.springframework.mock.web.test.server.MockServerWebExchange;
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
import org.springframework.web.server.WebFilterChain;
|
import org.springframework.web.server.WebFilterChain;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import static org.springframework.mock.http.server.reactive.test.MockServerHttpRequest.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
*/
|
*/
|
||||||
public class ForwardedHeaderFilterTests {
|
public class ForwardedHeaderFilterTests {
|
||||||
|
|
||||||
|
private static final String BASE_URL = "http://example.com/path";
|
||||||
|
|
||||||
|
|
||||||
private final ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
|
private final ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
|
||||||
|
|
||||||
private final TestWebFilterChain filterChain = new TestWebFilterChain();
|
private final TestWebFilterChain filterChain = new TestWebFilterChain();
|
||||||
|
@ -43,8 +46,7 @@ public class ForwardedHeaderFilterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeOnly() {
|
public void removeOnly() {
|
||||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest
|
ServerWebExchange exchange = MockServerWebExchange.from(get(BASE_URL)
|
||||||
.get("/")
|
|
||||||
.header("Forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43")
|
.header("Forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43")
|
||||||
.header("X-Forwarded-Host", "example.com")
|
.header("X-Forwarded-Host", "example.com")
|
||||||
.header("X-Forwarded-Port", "8080")
|
.header("X-Forwarded-Port", "8080")
|
||||||
|
@ -65,66 +67,57 @@ public class ForwardedHeaderFilterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void xForwardedRequest() throws Exception {
|
public void xForwardedRequest() throws Exception {
|
||||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest
|
ServerWebExchange exchange = MockServerWebExchange.from(get(BASE_URL)
|
||||||
.get("http://example.com/path")
|
|
||||||
.header("X-Forwarded-Host", "84.198.58.199")
|
.header("X-Forwarded-Host", "84.198.58.199")
|
||||||
.header("X-Forwarded-Port", "443")
|
.header("X-Forwarded-Port", "443")
|
||||||
.header("X-Forwarded-Proto", "https"));
|
.header("X-Forwarded-Proto", "https"));
|
||||||
|
|
||||||
this.filter.filter(exchange, this.filterChain).block(Duration.ZERO);
|
assertEquals(new URI("https://84.198.58.199/path"), filterAndGetUri(exchange));
|
||||||
|
|
||||||
URI uri = this.filterChain.uri;
|
|
||||||
assertEquals(new URI("https://84.198.58.199/path"), uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void forwardedRequest() throws Exception {
|
public void forwardedRequest() throws Exception {
|
||||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest
|
ServerWebExchange exchange = MockServerWebExchange.from(get(BASE_URL)
|
||||||
.get("http://example.com/path")
|
|
||||||
.header("Forwarded", "host=84.198.58.199;proto=https"));
|
.header("Forwarded", "host=84.198.58.199;proto=https"));
|
||||||
|
|
||||||
this.filter.filter(exchange, this.filterChain).block(Duration.ZERO);
|
assertEquals(new URI("https://84.198.58.199/path"), filterAndGetUri(exchange));
|
||||||
|
|
||||||
URI uri = this.filterChain.uri;
|
|
||||||
assertEquals(new URI("https://84.198.58.199/path"), uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void requestUriWithForwardedPrefix() throws Exception {
|
public void requestUriWithForwardedPrefix() throws Exception {
|
||||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest
|
ServerWebExchange exchange = MockServerWebExchange.from(get(BASE_URL)
|
||||||
.get("http://example.com/path")
|
|
||||||
.header("X-Forwarded-Prefix", "/prefix"));
|
.header("X-Forwarded-Prefix", "/prefix"));
|
||||||
|
|
||||||
this.filter.filter(exchange, this.filterChain).block(Duration.ZERO);
|
assertEquals(new URI("http://example.com/prefix/path"), filterAndGetUri(exchange));
|
||||||
|
|
||||||
URI uri = this.filterChain.uri;
|
|
||||||
assertEquals(new URI("http://example.com/prefix/path"), uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void requestUriWithForwardedPrefixTrailingSlash() throws Exception {
|
public void requestUriWithForwardedPrefixTrailingSlash() throws Exception {
|
||||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest
|
ServerWebExchange exchange = MockServerWebExchange.from(get(BASE_URL)
|
||||||
.get("http://example.com/path")
|
|
||||||
.header("X-Forwarded-Prefix", "/prefix/"));
|
.header("X-Forwarded-Prefix", "/prefix/"));
|
||||||
|
|
||||||
this.filter.filter(exchange, this.filterChain).block(Duration.ZERO);
|
assertEquals(new URI("http://example.com/prefix/path"), filterAndGetUri(exchange));
|
||||||
|
}
|
||||||
|
|
||||||
URI uri = this.filterChain.uri;
|
@Nullable
|
||||||
assertEquals(new URI("http://example.com/prefix/path"), uri);
|
private URI filterAndGetUri(ServerWebExchange exchange) {
|
||||||
|
this.filter.filter(exchange, this.filterChain).block(Duration.ZERO);
|
||||||
|
return this.filterChain.uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class TestWebFilterChain implements WebFilterChain {
|
private static class TestWebFilterChain implements WebFilterChain {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private HttpHeaders httpHeaders;
|
private HttpHeaders headers;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private URI uri;
|
private URI uri;
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public HttpHeaders getHeaders() {
|
public HttpHeaders getHeaders() {
|
||||||
return this.httpHeaders;
|
return this.headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -134,12 +127,10 @@ public class ForwardedHeaderFilterTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> filter(ServerWebExchange exchange) {
|
public Mono<Void> filter(ServerWebExchange exchange) {
|
||||||
this.httpHeaders = exchange.getRequest().getHeaders();
|
this.headers = exchange.getRequest().getHeaders();
|
||||||
this.uri = exchange.getRequest().getURI();
|
this.uri = exchange.getRequest().getURI();
|
||||||
return Mono.empty();
|
return Mono.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue