Description
Expected Behavior
It is expected that reactor-netty
always honors the provided X-Forwarded-Port
when calling HttpServerRequest#hostPort
.
Actual Behavior
The problem is that reactor-netty
does not honor the X-Forwarded-Port
header if X-Forwarded-Host
isn’t set, and thus it can report the port of a proxied connection rather than the actual (forwarded) host port.
As a result, reactor-netty
incorrectly reports port 80, while the scheme is https
and X-Forwarded-Port
is set. This becomes a problem in our setup which is as follows:
We have AWS Application Load Balancers (ALBs) which perform TLS termination and proxy requests to pods running within our Kubernetes clusters. ALBs only add the following headers to a proxied request, as per the documentation:
X-Forwarded-For
X-Forwarded-Proto
X-Forwarded-Port
In addition, the Host
header is set by the original request. However, when we call HttpServerRequest#hostPort
for a request that requests a URL of the format https://some-host.domain
, we would expect hostPort
to return 443
. Instead, it returns 80
.
The following issue may be related: #2714.
This became a problem in combination with the following commit from Spring framework: spring-projects/spring-framework@a2b7a90, where they (correctly) prefer the host address rather than parsing the Host
header themselves.
Steps to Reproduce
@Test
void xForwardedForAndHost() {
testClientRequest(
clientRequestHeaders -> {
clientRequestHeaders.add("Host", "a.example.com");
clientRequestHeaders.add("X-Forwarded-For", "192.168.0.1");
clientRequestHeaders.add("X-Forwarded-Port", "443");
clientRequestHeaders.add("X-Forwarded-Proto", "https");
},
serverRequest -> {
Assertions.assertThat(serverRequest.hostPort()).isEqualTo(443);
Assertions.assertThat(serverRequest.hostName()).isEqualTo("a.example.com");
Assertions.assertThat(serverRequest.scheme()).isEqualTo("https");
});
}
This test fails as the port returned is 80
instead of 443
.
Possible Solution
Adding the following line results in the expected result:
clientRequestHeaders.add("X-Forwarded-Host", "a.example.com");
Your Environment
- Reactor version(s) used: 2020.0.30, we use the
reactor-bom
. - Other relevant libraries versions (eg.
netty
, ...): Netty 1.0.30. - JVM version (
java -version
):
$ java -version
openjdk version "17.0.3" 2022-04-19 LTS
OpenJDK Runtime Environment Zulu17.34+19-CA (build 17.0.3+7-LTS)
OpenJDK 64-Bit Server VM Zulu17.34+19-CA (build 17.0.3+7-LTS, mixed mode, sharing)
- OS and version (eg.
uname -a
):
$ uname -a
Linux rick-ommitted 5.15.0-67-generic #74~20.04.1-Ubuntu SMP Wed Feb 22 14:52:34 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux