mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 16:30:28 +00:00
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:
@@ -56,6 +56,163 @@ public abstract class ForwardedHeaderUtils {
|
||||
|
||||
private static final Pattern FORWARDED_BY_PATTERN = Pattern.compile("(?i:by)=" + FORWARDED_VALUE);
|
||||
|
||||
/**
|
||||
* Parse the "Forwarded" header.
|
||||
* @param uri the request {@code URI}
|
||||
* @param headers the HTTP headers to get the "Forwarded" header from
|
||||
* @param remoteAddress for a default port for the parsed "for" value
|
||||
* @param localAddress for a default port for the parsed "by" value
|
||||
* @return a {@link ForwardedInfo} with the parse results
|
||||
* @since 7.1
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7239">RFC 7239</a>
|
||||
*/
|
||||
public static ForwardedInfo parseForwardedHeader(URI uri, HttpHeaders headers,
|
||||
@Nullable InetSocketAddress remoteAddress, @Nullable InetSocketAddress localAddress) {
|
||||
|
||||
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUri(uri);
|
||||
InetSocketAddress forAddress = null;
|
||||
InetSocketAddress byAddress = null;
|
||||
|
||||
String forwardedHeader = headers.getFirst("Forwarded");
|
||||
if (StringUtils.hasText(forwardedHeader)) {
|
||||
String forwardedToUse = getLeftMostValue(forwardedHeader);
|
||||
|
||||
Matcher matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedToUse);
|
||||
if (matcher.find()) {
|
||||
uriComponentsBuilder.scheme(matcher.group(1).trim());
|
||||
uriComponentsBuilder.port(null);
|
||||
}
|
||||
matcher = FORWARDED_HOST_PATTERN.matcher(forwardedToUse);
|
||||
if (matcher.find()) {
|
||||
adaptForwardedHost(uriComponentsBuilder, matcher.group(1).trim());
|
||||
}
|
||||
uriComponentsBuilder.resetPortIfDefaultForScheme();
|
||||
|
||||
matcher = FORWARDED_FOR_PATTERN.matcher(forwardedToUse);
|
||||
if (matcher.find()) {
|
||||
forAddress = parseInetSocketAddress(matcher.group(1).trim(), getPortToUse(remoteAddress, uri));
|
||||
}
|
||||
|
||||
matcher = FORWARDED_BY_PATTERN.matcher(forwardedToUse);
|
||||
if (matcher.find()) {
|
||||
byAddress = parseInetSocketAddress(matcher.group(1).trim(), getPortToUse(localAddress, uri));
|
||||
}
|
||||
}
|
||||
|
||||
return new ForwardedInfo(uriComponentsBuilder, forAddress, byAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the "X-Forwarded-Proto", "X-Forwarded-Host", "X-Forwarded-Port", and
|
||||
* "X-Forwarded-For" headers, the alternative to the "Forwarded" header.
|
||||
* <p>There is no parsing of "X-Forwarded-By" currently, so the
|
||||
* {@code byAddress} in {@link ForwardedInfo} is always {@code null}.
|
||||
* @param uri the request {@code URI}
|
||||
* @param headers the HTTP headers to get the "Forwarded" header from
|
||||
* @param remoteAddress for a default port for the parsed "for" value
|
||||
* @param localAddress for a default port for the parsed "by" value
|
||||
* @return a {@link ForwardedInfo} with the scheme, host, and port adapted
|
||||
* from the "X-Forwarded-*" headers, and the parsed "for" address
|
||||
* @since 7.1
|
||||
*/
|
||||
public static ForwardedInfo parseXForwardedHeaders(URI uri, HttpHeaders headers,
|
||||
@Nullable InetSocketAddress remoteAddress, @Nullable InetSocketAddress localAddress) {
|
||||
|
||||
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUri(uri);
|
||||
|
||||
String protocolHeader = headers.getFirst("X-Forwarded-Proto");
|
||||
if (StringUtils.hasText(protocolHeader)) {
|
||||
uriComponentsBuilder.scheme(getLeftMostValue(protocolHeader));
|
||||
uriComponentsBuilder.port(null);
|
||||
}
|
||||
else if (isForwardedSslOn(headers)) {
|
||||
uriComponentsBuilder.scheme("https");
|
||||
uriComponentsBuilder.port(null);
|
||||
}
|
||||
String hostHeader = headers.getFirst("X-Forwarded-Host");
|
||||
if (StringUtils.hasText(hostHeader)) {
|
||||
adaptForwardedHost(uriComponentsBuilder, getLeftMostValue(hostHeader));
|
||||
}
|
||||
String portHeader = headers.getFirst("X-Forwarded-Port");
|
||||
if (StringUtils.hasText(portHeader)) {
|
||||
try {
|
||||
uriComponentsBuilder.port(Integer.parseInt(getLeftMostValue(portHeader)));
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new IllegalArgumentException("Failed to parse \"X-Forwarded-Port: " + portHeader + "\"");
|
||||
}
|
||||
}
|
||||
uriComponentsBuilder.resetPortIfDefaultForScheme();
|
||||
|
||||
InetSocketAddress forAddress = null;
|
||||
String forHeader = headers.getFirst("X-Forwarded-For");
|
||||
if (StringUtils.hasText(forHeader)) {
|
||||
String host = getLeftMostValue(forHeader);
|
||||
boolean ipv6 = (host.indexOf(':') != -1);
|
||||
host = (ipv6 && !host.startsWith("[") && !host.endsWith("]") ? "[" + host + "]" : host);
|
||||
int port = getPortToUse(remoteAddress, uri);
|
||||
forAddress = InetSocketAddress.createUnresolved(host, port);
|
||||
}
|
||||
|
||||
return new ForwardedInfo(uriComponentsBuilder, forAddress, null);
|
||||
}
|
||||
|
||||
private static String getLeftMostValue(String headerValue) {
|
||||
return StringUtils.tokenizeToStringArray(headerValue, ",")[0];
|
||||
}
|
||||
|
||||
private static boolean isForwardedSslOn(HttpHeaders headers) {
|
||||
String forwardedSsl = headers.getFirst("X-Forwarded-Ssl");
|
||||
return (StringUtils.hasText(forwardedSsl) && forwardedSsl.equalsIgnoreCase("on"));
|
||||
}
|
||||
|
||||
private static void adaptForwardedHost(UriComponentsBuilder uriComponentsBuilder, String rawValue) {
|
||||
int portSeparatorIdx = rawValue.lastIndexOf(':');
|
||||
int squareBracketIdx = rawValue.lastIndexOf(']');
|
||||
if (portSeparatorIdx > squareBracketIdx) {
|
||||
if (squareBracketIdx == -1 && rawValue.indexOf(':') != portSeparatorIdx) {
|
||||
throw new IllegalArgumentException("Invalid IPv4 address: " + rawValue);
|
||||
}
|
||||
uriComponentsBuilder.host(rawValue.substring(0, portSeparatorIdx));
|
||||
try {
|
||||
uriComponentsBuilder.port(
|
||||
Integer.parseInt(rawValue, portSeparatorIdx + 1, rawValue.length(), 10));
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new IllegalArgumentException(
|
||||
"Failed to parse port in forwarded host value: " + rawValue + "\"");
|
||||
}
|
||||
}
|
||||
else {
|
||||
uriComponentsBuilder.host(rawValue);
|
||||
uriComponentsBuilder.port(null);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getPortToUse(@Nullable InetSocketAddress address, URI uri) {
|
||||
return (address != null ? address.getPort() : "https".equals(uri.getScheme()) ? 443 : 80);
|
||||
}
|
||||
|
||||
private static InetSocketAddress parseInetSocketAddress(String value, int port) {
|
||||
String host = value;
|
||||
int portSeparatorIdx = value.lastIndexOf(':');
|
||||
int squareBracketIdx = value.lastIndexOf(']');
|
||||
if (portSeparatorIdx > squareBracketIdx) {
|
||||
if (squareBracketIdx == -1 && value.indexOf(':') != portSeparatorIdx) {
|
||||
throw new IllegalArgumentException("Invalid IPv4 address: " + value);
|
||||
}
|
||||
host = value.substring(0, portSeparatorIdx);
|
||||
try {
|
||||
port = Integer.parseInt(value, portSeparatorIdx + 1, value.length(), 10);
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new IllegalArgumentException(
|
||||
"Failed to parse port in forwarded address value: " + value);
|
||||
}
|
||||
}
|
||||
return InetSocketAddress.createUnresolved(host, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt the scheme+host+port of the given {@link URI} from the "Forwarded" header
|
||||
* (see <a href="https://tools.ietf.org/html/rfc7239">RFC 7239</a>) or from the
|
||||
@@ -88,7 +245,7 @@ public abstract class ForwardedHeaderUtils {
|
||||
else {
|
||||
String protocolHeader = headers.getFirst("X-Forwarded-Proto");
|
||||
if (StringUtils.hasText(protocolHeader)) {
|
||||
uriComponentsBuilder.scheme(StringUtils.tokenizeToStringArray(protocolHeader, ",")[0]);
|
||||
uriComponentsBuilder.scheme(getLeftMostValue(protocolHeader));
|
||||
uriComponentsBuilder.port(null);
|
||||
}
|
||||
else if (isForwardedSslOn(headers)) {
|
||||
@@ -97,11 +254,11 @@ public abstract class ForwardedHeaderUtils {
|
||||
}
|
||||
String hostHeader = headers.getFirst("X-Forwarded-Host");
|
||||
if (StringUtils.hasText(hostHeader)) {
|
||||
adaptForwardedHost(uriComponentsBuilder, StringUtils.tokenizeToStringArray(hostHeader, ",")[0]);
|
||||
adaptForwardedHost(uriComponentsBuilder, getLeftMostValue(hostHeader));
|
||||
}
|
||||
String portHeader = headers.getFirst("X-Forwarded-Port");
|
||||
if (StringUtils.hasText(portHeader)) {
|
||||
uriComponentsBuilder.port(Integer.parseInt(StringUtils.tokenizeToStringArray(portHeader, ",")[0]));
|
||||
uriComponentsBuilder.port(Integer.parseInt(getLeftMostValue(portHeader)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,27 +273,6 @@ public abstract class ForwardedHeaderUtils {
|
||||
return uriComponentsBuilder;
|
||||
}
|
||||
|
||||
private static boolean isForwardedSslOn(HttpHeaders headers) {
|
||||
String forwardedSsl = headers.getFirst("X-Forwarded-Ssl");
|
||||
return StringUtils.hasText(forwardedSsl) && forwardedSsl.equalsIgnoreCase("on");
|
||||
}
|
||||
|
||||
private static void adaptForwardedHost(UriComponentsBuilder uriComponentsBuilder, String rawValue) {
|
||||
int portSeparatorIdx = rawValue.lastIndexOf(':');
|
||||
int squareBracketIdx = rawValue.lastIndexOf(']');
|
||||
if (portSeparatorIdx > squareBracketIdx) {
|
||||
if (squareBracketIdx == -1 && rawValue.indexOf(':') != portSeparatorIdx) {
|
||||
throw new IllegalArgumentException("Invalid IPv4 address: " + rawValue);
|
||||
}
|
||||
uriComponentsBuilder.host(rawValue.substring(0, portSeparatorIdx));
|
||||
uriComponentsBuilder.port(Integer.parseInt(rawValue, portSeparatorIdx + 1, rawValue.length(), 10));
|
||||
}
|
||||
else {
|
||||
uriComponentsBuilder.host(rawValue);
|
||||
uriComponentsBuilder.port(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the first "Forwarded: for=..." or "X-Forwarded-For" header value to
|
||||
* an {@code InetSocketAddress} representing the address of the client.
|
||||
@@ -150,25 +286,22 @@ public abstract class ForwardedHeaderUtils {
|
||||
public static @Nullable InetSocketAddress parseForwardedFor(
|
||||
URI uri, HttpHeaders headers, @Nullable InetSocketAddress remoteAddress) {
|
||||
|
||||
int port = (remoteAddress != null ?
|
||||
remoteAddress.getPort() : "https".equals(uri.getScheme()) ? 443 : 80);
|
||||
|
||||
String forwardedHeader = headers.getFirst("Forwarded");
|
||||
if (StringUtils.hasText(forwardedHeader)) {
|
||||
String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
|
||||
String forwardedToUse = getLeftMostValue(forwardedHeader);
|
||||
Matcher matcher = FORWARDED_FOR_PATTERN.matcher(forwardedToUse);
|
||||
if (matcher.find()) {
|
||||
String value = matcher.group(1).trim();
|
||||
return parseInetSocketAddress(value, port);
|
||||
return parseInetSocketAddress(value, getPortToUse(remoteAddress, uri));
|
||||
}
|
||||
}
|
||||
|
||||
String forHeader = headers.getFirst("X-Forwarded-For");
|
||||
if (StringUtils.hasText(forHeader)) {
|
||||
String host = StringUtils.tokenizeToStringArray(forHeader, ",")[0];
|
||||
String host = getLeftMostValue(forHeader);
|
||||
boolean ipv6 = (host.indexOf(':') != -1);
|
||||
host = (ipv6 && !host.startsWith("[") && !host.endsWith("]") ? "[" + host + "]" : host);
|
||||
return InetSocketAddress.createUnresolved(host, port);
|
||||
return InetSocketAddress.createUnresolved(host, getPortToUse(remoteAddress, uri));
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -188,40 +321,34 @@ public abstract class ForwardedHeaderUtils {
|
||||
public static @Nullable InetSocketAddress parseForwardedBy(
|
||||
URI uri, HttpHeaders headers, @Nullable InetSocketAddress localAddress) {
|
||||
|
||||
int port = (localAddress != null ?
|
||||
localAddress.getPort() : "https".equals(uri.getScheme()) ? 443 : 80);
|
||||
|
||||
String forwardedHeader = headers.getFirst("Forwarded");
|
||||
if (StringUtils.hasText(forwardedHeader)) {
|
||||
String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
|
||||
String forwardedToUse = getLeftMostValue(forwardedHeader);
|
||||
Matcher matcher = FORWARDED_BY_PATTERN.matcher(forwardedToUse);
|
||||
if (matcher.find()) {
|
||||
String value = matcher.group(1).trim();
|
||||
return parseInetSocketAddress(value, port);
|
||||
return parseInetSocketAddress(value, getPortToUse(localAddress, uri));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static InetSocketAddress parseInetSocketAddress(String value, int port) {
|
||||
String host = value;
|
||||
int portSeparatorIdx = value.lastIndexOf(':');
|
||||
int squareBracketIdx = value.lastIndexOf(']');
|
||||
if (portSeparatorIdx > squareBracketIdx) {
|
||||
if (squareBracketIdx == -1 && value.indexOf(':') != portSeparatorIdx) {
|
||||
throw new IllegalArgumentException("Invalid IPv4 address: " + value);
|
||||
}
|
||||
host = value.substring(0, portSeparatorIdx);
|
||||
try {
|
||||
port = Integer.parseInt(value, portSeparatorIdx + 1, value.length(), 10);
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new IllegalArgumentException(
|
||||
"Failed to parse a port from \"forwarded\"-type header value: " + value);
|
||||
}
|
||||
}
|
||||
return InetSocketAddress.createUnresolved(host, port);
|
||||
|
||||
/**
|
||||
* Container for the combined results of parsing either the "Forwarded"
|
||||
* header or the "X-Forwarded-*" alternative headers.
|
||||
* @since 7.1
|
||||
* @param uriComponentsBuilder the request URI adapted with the scheme, host,
|
||||
* and port from forwarded header values
|
||||
* @param forAddress the address parsed from the "Forwarded" header "for" or
|
||||
* "X-Forwarded-For" value, representing the client, or {@code null} if not present
|
||||
* @param byAddress the address parsed from the "Forwarded" header "by",
|
||||
* representing the server, or {@code null} if not present;
|
||||
* always {@code null} when returned from {@link #parseXForwardedHeaders}
|
||||
*/
|
||||
public record ForwardedInfo(UriComponentsBuilder uriComponentsBuilder,
|
||||
@Nullable InetSocketAddress forAddress, @Nullable InetSocketAddress byAddress) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+52
-38
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user