Add ForwardedInfo to ForwardedHeaderUtils

This commit adds two new methods in ForwardedHeaderUtils, one to parse
the standard "Forwarded" header only, and another to parse the
"X-Forwarded-*" alternative headers. As those are single parse methods,
a ForwardedInfo container type is necessary to return the results.

See gh-36964
This commit is contained in:
rstoyanchev
2026-07-23 12:15:24 +03:00
parent 224522244f
commit 7b71df72e5
2 changed files with 233 additions and 92 deletions
@@ -51,7 +51,7 @@ class ForwardedHeaderUtilsTests {
request.setQueryString("a=1");
ServletServerHttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo("http");
assertThat(result.getHost()).isEqualTo("localhost");
assertThat(result.getPort()).isEqualTo(-1);
@@ -72,7 +72,7 @@ class ForwardedHeaderUtilsTests {
request.setRequestURI("/rest/mobile/users/1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo(protocol);
assertThat(result.getHost()).isEqualTo("84.198.58.199");
@@ -93,7 +93,7 @@ class ForwardedHeaderUtilsTests {
request.setRequestURI("/path");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo(protocol);
assertThat(result.getHost()).isEqualTo("84.198.58.199");
@@ -111,7 +111,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("Forwarded", "host=192.168.0.1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromForwardedHeader(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.toString()).isEqualTo("https://192.168.0.1/mvc-showcase");
}
@@ -126,7 +126,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("Forwarded", "host=[1abc:2abc:3abc::5ABC:6abc]");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromForwardedHeader(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.toString()).isEqualTo("http://[1abc:2abc:3abc::5ABC:6abc]/mvc-showcase");
}
@@ -141,7 +141,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Host", "[1abc:2abc:3abc::5ABC:6abc]");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.toString()).isEqualTo("http://[1abc:2abc:3abc::5ABC:6abc]/mvc-showcase");
}
@@ -156,7 +156,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Host", "[1abc:2abc:3abc::5ABC:6abc]:8080");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.toString()).isEqualTo("http://[1abc:2abc:3abc::5ABC:6abc]:8080/mvc-showcase");
}
@@ -172,8 +172,7 @@ class ForwardedHeaderUtilsTests {
HttpRequest httpRequest = new ServletServerHttpRequest(request);
assertThatThrownBy(() ->
ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build())
assertThatThrownBy(() -> adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()))
.isInstanceOf(IllegalArgumentException.class);
}
@@ -187,7 +186,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Host", "anotherHost");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.toString()).isEqualTo("https://anotherHost/mvc-showcase");
}
@@ -202,7 +201,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Host", "webtest.foo.bar.com:443");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getHost()).isEqualTo("webtest.foo.bar.com");
assertThat(result.getPort()).isEqualTo(443);
@@ -217,7 +216,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Host", "a.example.org, b.example.org, c.example.org");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getHost()).isEqualTo("a.example.org");
assertThat(result.getPort()).isEqualTo(-1);
@@ -233,7 +232,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Port", "9090");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getHost()).isEqualTo("foobarhost");
assertThat(result.getPort()).isEqualTo(9090);
@@ -248,7 +247,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Host", "example.org");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getHost()).isEqualTo("example.org");
assertThat(result.getPort()).isEqualTo(-1);
@@ -263,7 +262,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Proto", "https");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("example.org");
@@ -279,7 +278,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Ssl", "on");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("example.org");
@@ -296,7 +295,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Proto", "https");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getHost()).isEqualTo("example.org");
assertThat(result.getScheme()).isEqualTo("https");
@@ -315,7 +314,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Port", "443");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.toString()).isEqualTo("https://84.198.58.199/mvc-showcase");
}
@@ -331,7 +330,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Port", "80,52022");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.toString()).isEqualTo("http://a.example.org/mvc-showcase");
}
@@ -348,7 +347,7 @@ class ForwardedHeaderUtilsTests {
request.addHeader("X-Forwarded-Proto", "https,https");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.toString()).isEqualTo("https://a.example.org/mvc-showcase");
}
@@ -376,7 +375,7 @@ class ForwardedHeaderUtilsTests {
return new HttpHeaders();
}
};
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(request.getURI(), request.getHeaders()).build();
UriComponents result = adaptFromXForwardedHeaders(request.getURI(), request.getHeaders());
assertThat(result.toString()).isEqualTo("/");
}
@@ -390,7 +389,7 @@ class ForwardedHeaderUtilsTests {
request.setRequestURI("/rest/mobile/users/1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromForwardedHeader(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("84.198.58.199");
@@ -406,7 +405,7 @@ class ForwardedHeaderUtilsTests {
request.setRequestURI("/rest/mobile/users/1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromForwardedHeader(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("84.198.58.199");
@@ -423,7 +422,7 @@ class ForwardedHeaderUtilsTests {
request.setRequestURI("/rest/mobile/users/1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromForwardedHeader(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("84.198.58.199");
@@ -439,7 +438,7 @@ class ForwardedHeaderUtilsTests {
request.setRequestURI("/rest/mobile/users/1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromForwardedHeader(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("84.198.58.199");
@@ -455,7 +454,7 @@ class ForwardedHeaderUtilsTests {
request.setRequestURI("/rest/mobile/users/1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromForwardedHeader(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("84.198.58.199");
@@ -474,7 +473,7 @@ class ForwardedHeaderUtilsTests {
request.setRequestURI("/rest/mobile/users/1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromForwardedHeader(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("84.198.58.199");
@@ -493,7 +492,7 @@ class ForwardedHeaderUtilsTests {
request.setRequestURI("/rest/mobile/users/1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromForwardedHeader(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("84.198.58.199");
@@ -512,7 +511,7 @@ class ForwardedHeaderUtilsTests {
request.setRequestURI("/rest/mobile/users/1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
UriComponents result = adaptFromForwardedHeader(httpRequest.getURI(), httpRequest.getHeaders());
assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("example.com");
@@ -531,13 +530,17 @@ class ForwardedHeaderUtilsTests {
request.setRequestURI("/rest/mobile/users/1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
ForwardedHeaderUtils.ForwardedInfo info =
ForwardedHeaderUtils.parseForwardedHeader(httpRequest.getURI(), httpRequest.getHeaders(), null, null);
assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("192.0.2.3");
assertThat(info.forAddress()).isNotNull();
assertThat(info.forAddress().getHostString()).isEqualTo("192.0.2.0");
UriComponents result = info.uriComponentsBuilder().build();
assertThat(result.getScheme()).isEqualTo("http");
assertThat(result.getHost()).isEqualTo("example.com");
assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
assertThat(result.getPort()).isEqualTo(9090);
assertThat(result.toUriString()).isEqualTo("https://192.0.2.3:9090/rest/mobile/users/1");
assertThat(result.getPort()).isEqualTo(8080);
}
@Test // gh-34253
@@ -545,8 +548,8 @@ class ForwardedHeaderUtilsTests {
HttpHeaders headers = new HttpHeaders();
headers.add("X-Forwarded-For", "fd00:fefe:1::4, 192.168.0.1");
InetSocketAddress address =
ForwardedHeaderUtils.parseForwardedFor(URI.create("https://example.com"), headers, null);
InetSocketAddress address = ForwardedHeaderUtils.parseXForwardedHeaders(
URI.create("https://example.com"), headers, null, null).forAddress();
assertThat(address.getHostName()).isEqualTo("[fd00:fefe:1::4]");
}
@@ -556,10 +559,21 @@ class ForwardedHeaderUtilsTests {
HttpHeaders headers = new HttpHeaders();
headers.add("Forwarded", "by=[fd00:fefe:1::4], 192.168.0.1");
InetSocketAddress address =
ForwardedHeaderUtils.parseForwardedBy(URI.create("https://example.com"), headers, null);
InetSocketAddress address = ForwardedHeaderUtils.parseForwardedHeader(
URI.create("https://example.com"), headers, null, null).byAddress();
assertThat(address.getHostName()).isEqualTo("[fd00:fefe:1::4]");
}
private static UriComponents adaptFromForwardedHeader(URI uri, HttpHeaders headers) {
return ForwardedHeaderUtils.parseForwardedHeader(uri, headers, null, null)
.uriComponentsBuilder().build();
}
private static UriComponents adaptFromXForwardedHeaders(URI uri, HttpHeaders headers) {
return ForwardedHeaderUtils.parseXForwardedHeaders(uri, headers, null, null)
.uriComponentsBuilder().build();
}
}