Commit 2bdd2dab by Ryan Baxter Committed by GitHub

Merge pull request #1173 from denyska/master

Disable cookie management for RibbonLoadBalancingHttpClient Fixes gh-301
parents 29083237 5d664cd0
...@@ -36,7 +36,7 @@ import com.netflix.loadbalancer.ILoadBalancer; ...@@ -36,7 +36,7 @@ import com.netflix.loadbalancer.ILoadBalancer;
public class RibbonLoadBalancingHttpClient public class RibbonLoadBalancingHttpClient
extends extends
AbstractLoadBalancingClient<RibbonApacheHttpRequest, RibbonApacheHttpResponse> { AbstractLoadBalancingClient<RibbonApacheHttpRequest, RibbonApacheHttpResponse> {
private final HttpClient delegate = HttpClientBuilder.create().build(); private final HttpClient delegate = HttpClientBuilder.create().disableCookieManagement().build();
public RibbonLoadBalancingHttpClient() { public RibbonLoadBalancingHttpClient() {
super(); super();
......
...@@ -17,9 +17,15 @@ ...@@ -17,9 +17,15 @@
package org.springframework.cloud.netflix.zuul.filters.route.apache; package org.springframework.cloud.netflix.zuul.filters.route.apache;
import com.netflix.client.RetryHandler;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.web.ErrorAttributes; import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.SpringApplicationConfiguration;
...@@ -28,6 +34,8 @@ import org.springframework.boot.test.WebIntegrationTest; ...@@ -28,6 +34,8 @@ import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients; import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.netflix.ribbon.StaticServerList;
import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory;
import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase; import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase;
...@@ -44,9 +52,16 @@ import org.springframework.web.bind.annotation.RequestBody; ...@@ -44,9 +52,16 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.WebUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.springframework.http.HttpHeaders.SET_COOKIE;
/** /**
* @author Spencer Gibb * @author Spencer Gibb
...@@ -55,7 +70,8 @@ import static org.junit.Assert.assertTrue; ...@@ -55,7 +70,8 @@ import static org.junit.Assert.assertTrue;
@SpringApplicationConfiguration(classes = HttpClientRibbonCommandIntegrationTests.TestConfig.class) @SpringApplicationConfiguration(classes = HttpClientRibbonCommandIntegrationTests.TestConfig.class)
@WebIntegrationTest(randomPort = true, value = { @WebIntegrationTest(randomPort = true, value = {
"zuul.routes.other: /test/**=http://localhost:7777/local", "zuul.routes.other: /test/**=http://localhost:7777/local",
"zuul.routes.another: /another/twolevel/**", "zuul.routes.simple: /simple/**" }) "zuul.routes.another: /another/twolevel/**", "zuul.routes.simple: /simple/**",
"zuul.routes.singleton: /singleton/**", "zuul.routes.singleton.sensitiveHeaders: " })
@DirtiesContext @DirtiesContext
public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
...@@ -97,6 +113,33 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { ...@@ -97,6 +113,33 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
} }
@Test @Test
public void ribbonLoadBalancingHttpClientCookiePolicy() {
ResponseEntity<String> result = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/simple/downstream_cookie", HttpMethod.POST,
new HttpEntity<>((Void) null), String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Cookie 434354454!", result.getBody());
assertNull(result.getHeaders().getFirst(SET_COOKIE));
// if new instance of RibbonLoadBalancingHttpClient is getting created every time
// and HttpClient is not reused then there are no concerns for the shared cookie storage
// but since https://github.com/spring-cloud/spring-cloud-netflix/issues/1150 is on the way a
result = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/singleton/downstream_cookie", HttpMethod.POST,
new HttpEntity<>((Void) null), String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Cookie 434354454!", result.getBody());
assertEquals("jsessionid=434354454", result.getHeaders().getFirst(SET_COOKIE));
result = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/singleton/downstream_cookie", HttpMethod.GET,
new HttpEntity<>((Void) null), String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Cookie null!", result.getBody());
}
@Test
public void ribbonCommandFactoryOverridden() { public void ribbonCommandFactoryOverridden() {
assertTrue("ribbonCommandFactory not a HttpClientRibbonCommandFactory", assertTrue("ribbonCommandFactory not a HttpClientRibbonCommandFactory",
this.ribbonCommandFactory instanceof HttpClientRibbonCommandFactory); this.ribbonCommandFactory instanceof HttpClientRibbonCommandFactory);
...@@ -108,7 +151,8 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { ...@@ -108,7 +151,8 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
@EnableZuulProxy @EnableZuulProxy
@RibbonClients({ @RibbonClients({
@RibbonClient(name = "simple", configuration = ZuulProxyTestBase.SimpleRibbonClientConfiguration.class), @RibbonClient(name = "simple", configuration = ZuulProxyTestBase.SimpleRibbonClientConfiguration.class),
@RibbonClient(name = "another", configuration = ZuulProxyTestBase.AnotherRibbonClientConfiguration.class) }) @RibbonClient(name = "another", configuration = ZuulProxyTestBase.AnotherRibbonClientConfiguration.class),
@RibbonClient(name = "singleton", configuration = SingletonRibbonClientConfiguration.class) })
static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication { static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication {
@RequestMapping(value = "/local/{id}", method = RequestMethod.PATCH) @RequestMapping(value = "/local/{id}", method = RequestMethod.PATCH)
...@@ -116,6 +160,21 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { ...@@ -116,6 +160,21 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
return "Patched " + id + "!"; return "Patched " + id + "!";
} }
@RequestMapping(value = "/downstream_cookie", method = RequestMethod.POST)
public String setDownstreamCookie(HttpServletResponse response)
{
response.addCookie(new Cookie("jsessionid", "434354454"));
return "Cookie 434354454!";
}
@RequestMapping(value = "/downstream_cookie", method = RequestMethod.GET)
public String readDownstreamCookie(HttpServletRequest request)
{
final Cookie cookie = WebUtils.getCookie(request, "jsessionid");
return "Cookie " + cookie + "!";
}
@Bean @Bean
public RibbonCommandFactory<?> ribbonCommandFactory( public RibbonCommandFactory<?> ribbonCommandFactory(
final SpringClientFactory clientFactory) { final SpringClientFactory clientFactory) {
...@@ -127,4 +186,28 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { ...@@ -127,4 +186,28 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
return new ZuulProxyTestBase.MyErrorController(errorAttributes); return new ZuulProxyTestBase.MyErrorController(errorAttributes);
} }
} }
// Load balancer with fixed server list and defined ribbon rest client
@Configuration
public static class SingletonRibbonClientConfiguration {
@Value("${local.server.port}")
private int port;
@Bean
public ServerList<Server> ribbonServerList() {
return new StaticServerList<>(new Server("localhost", this.port));
}
@Bean
public RibbonLoadBalancingHttpClient ribbonClient(IClientConfig config, ILoadBalancer loadBalancer, RetryHandler retryHandler)
{
final RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient();
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
client.initWithNiwsConfig(config);
return client;
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment