diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilter.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilter.java index 49163231..865ae6fd 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilter.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilter.java @@ -94,17 +94,19 @@ public class ReactiveLoadBalancerClientFilter implements GlobalFilter, Ordered { "Unable to find instance for " + url.getHost()); } + ServiceInstance retrievedInstance = response.getServer(); + URI uri = exchange.getRequest().getURI(); // if the `lb:` mechanism was used, use `` as the default, // if the loadbalancer doesn't provide one. - String overrideScheme = null; + String overrideScheme = retrievedInstance.isSecure() ? "https" : "http"; if (schemePrefix != null) { overrideScheme = url.getScheme(); } DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance( - response.getServer(), overrideScheme); + retrievedInstance, overrideScheme); URI requestUrl = reconstructURI(serviceInstance, uri); diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilterTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilterTests.java index 562d3e15..49a8441c 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilterTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilterTests.java @@ -35,6 +35,7 @@ import org.springframework.cloud.gateway.support.NotFoundException; import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer; import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; +import org.springframework.cloud.loadbalancer.support.ServiceInstanceListSuppliers; import org.springframework.cloud.loadbalancer.support.ServiceInstanceSuppliers; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -262,6 +263,31 @@ public class ReactiveLoadBalancerClientFilterTests { } } + @SuppressWarnings("unchecked") + @Test + public void shouldOverrideSchemeUsingIsSecure() { + URI url = UriComponentsBuilder.fromUriString("lb://myservice").build().toUri(); + ServerWebExchange exchange = MockServerWebExchange + .from(MockServerHttpRequest.get("https://localhost:9999/mypath").build()); + exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, url); + ServiceInstance serviceInstance = new DefaultServiceInstance("myservice1", + "myservice", "localhost", 8080, false); + when(clientFactory.getInstance("myservice", + ReactorServiceInstanceLoadBalancer.class)).thenReturn( + new RoundRobinLoadBalancer(ServiceInstanceListSuppliers + .toProvider("myservice", serviceInstance), "myservice", -1)); + when(chain.filter(exchange)).thenReturn(Mono.empty()); + + filter.filter(exchange, chain).block(); + + assertThat((LinkedHashSet) exchange + .getAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR)).contains(url); + assertThat((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)) + .isEqualTo(URI.create("http://localhost:8080/mypath")); + verify(chain).filter(exchange); + verifyNoMoreInteractions(chain); + } + private ServerWebExchange testFilter(MockServerHttpRequest request, URI uri) { return testFilter(MockServerWebExchange.from(request), uri); }