From 181e452aec5c61eea421b567000648a9385b1563 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Thu, 28 Oct 2021 20:19:32 +0200 Subject: [PATCH] Make XForwardedHeadersTransformer work with client properties. (#1035) --- docs/src/main/asciidoc/_configprops.adoc | 1 + .../LoadBalancerClientConfiguration.java | 5 ++--- .../blocking/XForwardedHeadersTransformer.java | 13 ++++++++----- ...ingLoadBalancerClientAutoConfiguration.java | 5 +++-- .../core/XForwardedHeadersTransformer.java | 10 +++++++--- .../XForwardedHeadersTransformerTests.java | 18 +++++++++++++----- .../XForwardedHeadersTransformerTests.java | 16 +++++++++++----- 7 files changed, 45 insertions(+), 23 deletions(-) diff --git a/docs/src/main/asciidoc/_configprops.adoc b/docs/src/main/asciidoc/_configprops.adoc index ec7c409f..61f60ac9 100644 --- a/docs/src/main/asciidoc/_configprops.adoc +++ b/docs/src/main/asciidoc/_configprops.adoc @@ -40,6 +40,7 @@ |spring.cloud.loadbalancer.retry.enabled | | Enables LoadBalancer retries. |spring.cloud.loadbalancer.service-discovery.timeout | | String representation of Duration of the timeout for calls to service discovery. |spring.cloud.loadbalancer.sticky-session | | Properties for LoadBalancer sticky-session. +|spring.cloud.loadbalancer.x-forwarded | | Enabling X-Forwarded Host and Proto Headers. |spring.cloud.loadbalancer.zone | | Spring Cloud LoadBalancer zone. |spring.cloud.refresh.additional-property-sources-to-retain | | Additional property sources to retain during a refresh. Typically only system property sources are retained. This property allows property sources, such as property sources created by EnvironmentPostProcessors to be retained as well. |spring.cloud.refresh.enabled | `true` | Enables autoconfiguration for the refresh scope and associated features. diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java index 9dae56f0..3216e21a 100644 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java @@ -30,7 +30,6 @@ import org.springframework.cloud.client.ConditionalOnReactiveDiscoveryEnabled; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer; import org.springframework.cloud.loadbalancer.core.RetryAwareServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer; @@ -98,8 +97,8 @@ public class LoadBalancerClientConfiguration { @ConditionalOnBean(XForwardedHeadersTransformer.class) @ConditionalOnMissingBean @ConditionalOnProperty(value = "spring.cloud.loadbalancer.xForwarded.enabledXforwarded", havingValue = "true") - public XForwardedHeadersTransformer xForwarderHeadersTransformer(LoadBalancerProperties properties) { - return new XForwardedHeadersTransformer(properties.getXForwarded()); + public XForwardedHeadersTransformer xForwarderHeadersTransformer(LoadBalancerClientFactory clientFactory) { + return new XForwardedHeadersTransformer(clientFactory); } @Bean diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformer.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformer.java index 398a652c..3d96d584 100644 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformer.java +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformer.java @@ -19,6 +19,7 @@ package org.springframework.cloud.loadbalancer.blocking; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestTransformer; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpRequest; @@ -26,15 +27,16 @@ import org.springframework.http.HttpRequest; * To add X-Forwarded-Host and X-Forwarded-Proto Headers. * * @author Gandhimathi Velusamy + * @author Olga Maciaszek-Sharma * @since 3.1.0 */ public class XForwardedHeadersTransformer implements LoadBalancerRequestTransformer { - private final LoadBalancerProperties.XForwarded xForwarded; + private final LoadBalancerClientFactory factory; - public XForwardedHeadersTransformer(LoadBalancerProperties.XForwarded xForwarded) { - this.xForwarded = xForwarded; + public XForwardedHeadersTransformer(LoadBalancerClientFactory factory) { + this.factory = factory; } @Override @@ -42,12 +44,13 @@ public class XForwardedHeadersTransformer implements LoadBalancerRequestTransfor if (instance == null) { return request; } + LoadBalancerProperties.XForwarded xForwarded = factory.getProperties(instance.getServiceId()).getXForwarded(); if (xForwarded.isEnabled()) { HttpHeaders headers = request.getHeaders(); String xForwardedHost = request.getURI().getHost(); - String xForwardedProto = request.getURI().getScheme(); + String xforwardedProto = request.getURI().getScheme(); headers.add("X-Forwarded-Host", xForwardedHost); - headers.add("X-Forwarded-Proto", xForwardedProto); + headers.add("X-Forwarded-Proto", xforwardedProto); } return request; } diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java index 1cdcbb17..4ee9d928 100644 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java @@ -76,8 +76,9 @@ public class BlockingLoadBalancerClientAutoConfiguration { @Bean @ConditionalOnProperty(value = "spring.cloud.loadbalancer.xforwarded.enabledXforwarded", havingValue = "true") @ConditionalOnMissingBean(XForwardedHeadersTransformer.class) - public XForwardedHeadersTransformer xForwarderHeadersTransformer(LoadBalancerProperties properties) { - return new XForwardedHeadersTransformer(properties.getXForwarded()); + public XForwardedHeadersTransformer xForwarderHeadersTransformer( + LoadBalancerClientFactory loadBalancerClientFactory) { + return new XForwardedHeadersTransformer(loadBalancerClientFactory); } @Configuration diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformer.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformer.java index c4432559..b4bc45f9 100644 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformer.java +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformer.java @@ -19,6 +19,7 @@ package org.springframework.cloud.loadbalancer.core; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerClientRequestTransformer; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.http.HttpHeaders; import org.springframework.web.reactive.function.client.ClientRequest; @@ -26,15 +27,16 @@ import org.springframework.web.reactive.function.client.ClientRequest; * To add X-Forwarded-Host and X-Forwarded-Proto Headers. * * @author Gandhimathi Velusamy + * @author Olga Maciaszek-Sharma * @since 3.1.0 */ public class XForwardedHeadersTransformer implements LoadBalancerClientRequestTransformer { - private final LoadBalancerProperties.XForwarded xForwarded; + private final LoadBalancerClientFactory clientFactory; - public XForwardedHeadersTransformer(LoadBalancerProperties.XForwarded xForwarded) { - this.xForwarded = xForwarded; + public XForwardedHeadersTransformer(LoadBalancerClientFactory clientFactory) { + this.clientFactory = clientFactory; } @Override @@ -42,6 +44,8 @@ public class XForwardedHeadersTransformer implements LoadBalancerClientRequestTr if (instance == null) { return request; } + LoadBalancerProperties.XForwarded xForwarded = clientFactory.getProperties(instance.getServiceId()) + .getXForwarded(); if (xForwarded.isEnabled()) { HttpHeaders headers = request.headers(); String xForwardedHost = request.url().getHost(); diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformerTests.java index 9b6addc2..6899772b 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformerTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformerTests.java @@ -22,6 +22,7 @@ import org.junit.jupiter.api.Test; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpRequest; @@ -40,9 +41,12 @@ import static org.mockito.Mockito.when; class XForwardedHeadersTransformerTests { - private final LoadBalancerProperties.XForwarded xForwarded = new LoadBalancerProperties().getXForwarded(); + private final LoadBalancerClientFactory loadBalancerClientFactory = mock(LoadBalancerClientFactory.class); - private final ServiceInstance serviceInstance = new DefaultServiceInstance("test1", "test", "test.org", 8080, false); + private final LoadBalancerProperties loadBalancerProperties = new LoadBalancerProperties(); + + private final ServiceInstance serviceInstance = new DefaultServiceInstance("test1", "test", "test.org", 8080, + false); private final HttpRequest request = mock(HttpRequest.class); @@ -55,8 +59,9 @@ class XForwardedHeadersTransformerTests { @Test void shouldAppendXForwardedHeadersIfEnabled() { - XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(xForwarded); - xForwarded.setEnabled(true); + loadBalancerProperties.getXForwarded().setEnabled(true); + when(loadBalancerClientFactory.getProperties("test")).thenReturn(loadBalancerProperties); + XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(loadBalancerClientFactory); HttpRequest newRequest = transformer.transformRequest(request, serviceInstance); @@ -68,7 +73,10 @@ class XForwardedHeadersTransformerTests { @Test void shouldNotAppendXForwardedHeadersIfDefault() { - XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(xForwarded); + when(loadBalancerClientFactory.getProperties("test")).thenReturn(loadBalancerProperties); + + XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(loadBalancerClientFactory); + HttpRequest newRequest = transformer.transformRequest(request, serviceInstance); assertThat(newRequest.getHeaders()).doesNotContainKey("X-Forwarded-Host"); assertThat(newRequest.getHeaders()).doesNotContainKey("X-Forwarded-Proto"); diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformerTests.java index c5988183..3c6b500c 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformerTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformerTests.java @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.web.reactive.function.client.ClientRequest; @@ -41,9 +42,12 @@ import static org.mockito.Mockito.when; class XForwardedHeadersTransformerTests { - private final LoadBalancerProperties.XForwarded xForwarded = new LoadBalancerProperties().getXForwarded(); + private final LoadBalancerClientFactory loadBalancerClientFactory = mock(LoadBalancerClientFactory.class); - private final ServiceInstance serviceInstance = new DefaultServiceInstance("test1", "test", "test.org", 8080, false); + private final LoadBalancerProperties loadBalancerProperties = new LoadBalancerProperties(); + + private final ServiceInstance serviceInstance = new DefaultServiceInstance("test1", "test", "test.org", 8080, + false); private final ClientRequest request = mock(ClientRequest.class); @@ -56,8 +60,9 @@ class XForwardedHeadersTransformerTests { @Test void shouldAppendXForwardedHeadersIfEnabled() { - xForwarded.setEnabled(true); - XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(xForwarded); + loadBalancerProperties.getXForwarded().setEnabled(true); + when(loadBalancerClientFactory.getProperties("test")).thenReturn(loadBalancerProperties); + XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(loadBalancerClientFactory); ClientRequest newRequest = transformer.transformRequest(request, serviceInstance); @@ -69,7 +74,8 @@ class XForwardedHeadersTransformerTests { @Test void shouldNotAppendXForwardedHeadersIfDefault() { - XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(xForwarded); + when(loadBalancerClientFactory.getProperties("test")).thenReturn(loadBalancerProperties); + XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(loadBalancerClientFactory); ClientRequest newRequest = transformer.transformRequest(request, serviceInstance);