From 45dd8ac61ede60e1995deebfdb7b644a9342730d Mon Sep 17 00:00:00 2001 From: Alexey Nesterov Date: Thu, 14 Nov 2019 16:24:46 +0000 Subject: [PATCH] Keep Host header in the outbound request (#1412) Commit 0d2b87a changed how outbound request headers are updated, instead of using HttpClientOperations.headers() method to merged headers, HttpHeaders.add() is now used. However HttpClientOperations.headers() method treats Host header specially and do not override it from the provided headers collection. This fix just copies the same logic within NettyRoutingFilter for backward compatibility. There is one issue with this approach, if Host header is set by a filter it will be ignored. However this is how it worked before, with HttpClientOperations.headers() method in place. gh-1345 --- .../cloud/gateway/filter/NettyRoutingFilter.java | 2 ++ .../filter/NettyRoutingFilterIntegrationTests.java | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java index 958f2c12..ff5d26ef 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/NettyRoutingFilter.java @@ -119,6 +119,8 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered { Flux responseFlux = this.httpClient.headers(headers -> { headers.add(httpHeaders); + // Will either be set below, or later by Netty + headers.remove(HttpHeaders.HOST); if (preserveHost) { String host = request.getHeaders().getFirst(HttpHeaders.HOST); headers.add(HttpHeaders.HOST, host); diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/NettyRoutingFilterIntegrationTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/NettyRoutingFilterIntegrationTests.java index 9ab01ca4..366af89b 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/NettyRoutingFilterIntegrationTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/NettyRoutingFilterIntegrationTests.java @@ -27,6 +27,7 @@ import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @@ -45,6 +46,18 @@ public class NettyRoutingFilterIntegrationTests extends BaseWebClientTests { .isEqualTo("Response took longer than timeout: PT3S"); } + @Test + public void outboundHostHeaderNotOverwrittenByInbound() { + // different base url to have different host header in inbound / outbound requests + // Host: 127.0.0.1 -> request to Gateway, Host: localhost -> request from Gateway, + // resolved from lb://testservice + WebTestClient client = testClient.mutate().baseUrl("http://127.0.0.1:" + port) + .build(); + + client.get().uri("/headers").exchange().expectBody().jsonPath("$.headers.host") + .isEqualTo("localhost:" + port); + } + @EnableAutoConfiguration @SpringBootConfiguration @Import(DefaultTestConfig.class)