spring-cloud-gateway
spring-cloud-gateway copied to clipboard
The "Host" header is not preserved with "preserveHostHeader()" when the route's target URI starts with "https"
I configured the following route with Gateway MVC.fn:
private RouterFunction<ServerResponse> createDefaultRoute(String routeId) {
return route(routeId)
.route(RequestPredicates.path("/**"), http("http://httpbin.org"))
.before(preserveHostHeader())
.filter(this.handlerFilterFunctionBuilder.buildRateLimitFilter(routeId))
.filter(this.handlerFilterFunctionBuilder.buildSecureHeadersFilter(routeId))
.build();
}
When I test it with http://localhost:8080/headers, then I correctly get that the Host header has the value localhost:
{
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,el;q=0.5",
"Cookie": "[STRIPPED-OUT]",
"Forwarded": "proto=http;host=\"localhost:8080\";for=\"127.0.0.1:52521\"",
"Host": "localhost",
"Http2-Settings": "AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "cross-site",
"Transfer-Encoding": "chunked",
"Upgrade": "h2c",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0",
"X-Amzn-Trace-Id": "Root=1-65a52ebf-4150fa8f2b4495e91ff06def",
"X-Forwarded-Host": "localhost:8080"
}
}
Then I change the route configuration to target https instead of http:
private RouterFunction<ServerResponse> createDefaultRoute(String routeId) {
return route(routeId)
.route(RequestPredicates.path("/**"), http("https://httpbin.org"))
.before(preserveHostHeader())
.filter(this.handlerFilterFunctionBuilder.buildRateLimitFilter(routeId))
.filter(this.handlerFilterFunctionBuilder.buildSecureHeadersFilter(routeId))
.build();
}
When I tested again, the remote application is receiving a Host header with value httpbin.org:
{
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,el;q=0.5",
"Cookie": "[STRIPPED-OUT]",
"Forwarded": "proto=http;host=\"localhost:8080\";for=\"127.0.0.1:52580\"",
"Host": "httpbin.org",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "cross-site",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0",
"X-Amzn-Trace-Id": "Root=1-65a52fae-595a56ec0688739134637885",
"X-Forwarded-Host": "localhost:8080"
}
}
However, I would expect the Host header on the application side to continue to be localhost, since the preserveHostHeader() filter is used.
I took a look in the code but couldn't find any flaws, so I feel like I'm missing something, although this does look like a bug to me.