Browse Source
Removed deprecated HttpClient APIs, exposed method to override client, fixed ignoredHeaderspull/6/head
2 changed files with 326 additions and 172 deletions
@ -0,0 +1,211 @@
@@ -0,0 +1,211 @@
|
||||
package org.springframework.cloud.netflix.zuul.filters; |
||||
|
||||
import org.apache.http.client.config.CookieSpecs; |
||||
import org.apache.http.client.config.RequestConfig; |
||||
import org.apache.http.impl.client.BasicCookieStore; |
||||
import org.apache.http.impl.client.CloseableHttpClient; |
||||
import org.apache.http.impl.client.HttpClients; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
||||
import org.springframework.boot.test.IntegrationTest; |
||||
import org.springframework.boot.test.SpringApplicationConfiguration; |
||||
import org.springframework.boot.test.TestRestTemplate; |
||||
import org.springframework.cloud.netflix.zuul.EnableZuulProxy; |
||||
import org.springframework.cloud.netflix.zuul.RoutesEndpoint; |
||||
import org.springframework.cloud.netflix.zuul.ZuulProxyConfiguration; |
||||
import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.http.HttpEntity; |
||||
import org.springframework.http.HttpMethod; |
||||
import org.springframework.http.HttpStatus; |
||||
import org.springframework.http.ResponseEntity; |
||||
import org.springframework.test.annotation.DirtiesContext; |
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
||||
import org.springframework.test.context.web.WebAppConfiguration; |
||||
import org.springframework.util.LinkedMultiValueMap; |
||||
import org.springframework.util.MultiValueMap; |
||||
import org.springframework.web.bind.annotation.PathVariable; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RequestMethod; |
||||
import org.springframework.web.bind.annotation.RequestParam; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
import org.springframework.web.client.RestTemplate; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
import javax.servlet.http.HttpSession; |
||||
|
||||
import static junit.framework.TestCase.assertFalse; |
||||
import static junit.framework.TestCase.assertTrue; |
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class) |
||||
@SpringApplicationConfiguration(classes = SampleCustomZuulProxyApplication.class) |
||||
@WebAppConfiguration |
||||
@IntegrationTest({"server.port: 0", "server.contextPath: /app"}) |
||||
@DirtiesContext |
||||
public class CustomHostRoutingFilterTests { |
||||
|
||||
@Value("${local.server.port}") |
||||
private int port; |
||||
|
||||
@Autowired |
||||
private ProxyRouteLocator routes; |
||||
|
||||
@Autowired |
||||
private RoutesEndpoint endpoint; |
||||
|
||||
@Test |
||||
public void getOnSelfViaCustomHostRoutingFilter() { |
||||
this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); |
||||
this.endpoint.reset(); |
||||
ResponseEntity<String> result = new TestRestTemplate().getForEntity( |
||||
"http://localhost:" + this.port + "/app/self/get/1", String.class); |
||||
assertEquals(HttpStatus.OK, result.getStatusCode()); |
||||
assertEquals("Get 1", result.getBody()); |
||||
} |
||||
|
||||
@Test |
||||
public void postOnSelfViaCustomHostRoutingFilter() { |
||||
this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); |
||||
this.endpoint.reset(); |
||||
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); |
||||
params.add("id", "2"); |
||||
ResponseEntity<String> result = new TestRestTemplate().postForEntity( |
||||
"http://localhost:" + this.port + "/app/self/post", params, String.class); |
||||
assertEquals(HttpStatus.OK, result.getStatusCode()); |
||||
assertEquals("Post 2", result.getBody()); |
||||
} |
||||
|
||||
@Test |
||||
public void putOnSelfViaCustomHostRoutingFilter() { |
||||
this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); |
||||
this.endpoint.reset(); |
||||
ResponseEntity<String> result = new TestRestTemplate().exchange( |
||||
"http://localhost:" + this.port + "/app/self/put/3", HttpMethod.PUT, |
||||
new HttpEntity<>((Void) null), String.class); |
||||
assertEquals(HttpStatus.OK, result.getStatusCode()); |
||||
assertEquals("Put 3", result.getBody()); |
||||
} |
||||
|
||||
@Test |
||||
public void patchOnSelfViaCustomHostRoutingFilter() { |
||||
this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); |
||||
this.endpoint.reset(); |
||||
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); |
||||
params.add("patch", "5"); |
||||
ResponseEntity<String> result = new TestRestTemplate().exchange( |
||||
"http://localhost:" + this.port + "/app/self/patch/4", HttpMethod.PATCH, |
||||
new HttpEntity<>(params), String.class); |
||||
assertEquals(HttpStatus.OK, result.getStatusCode()); |
||||
assertEquals("Patch 45", result.getBody()); |
||||
} |
||||
|
||||
@Test |
||||
public void getOnSelfIgnoredHeaders() { |
||||
this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); |
||||
this.endpoint.reset(); |
||||
ResponseEntity<String> result = new TestRestTemplate().getForEntity( |
||||
"http://localhost:" + this.port + "/app/self/get/1", String.class); |
||||
assertEquals(HttpStatus.OK, result.getStatusCode()); |
||||
assertTrue(result.getHeaders().containsKey("X-NotIgnored")); |
||||
assertFalse(result.getHeaders().containsKey("X-Ignored")); |
||||
} |
||||
|
||||
@Test |
||||
public void getOnSelfWithSessionCookie() { |
||||
this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); |
||||
this.endpoint.reset(); |
||||
|
||||
RestTemplate restTemplate = new RestTemplate(); |
||||
|
||||
ResponseEntity<String> result1 = restTemplate.getForEntity( |
||||
"http://localhost:" + this.port + "/app/self/cookie/1", String.class); |
||||
|
||||
ResponseEntity<String> result2 = restTemplate.getForEntity( |
||||
"http://localhost:" + this.port + "/app/self/cookie/2", String.class); |
||||
|
||||
assertEquals("SetCookie 1", result1.getBody()); |
||||
assertEquals("GetCookie 1", result2.getBody()); |
||||
} |
||||
|
||||
} |
||||
|
||||
@Configuration |
||||
@EnableAutoConfiguration |
||||
@RestController |
||||
class SampleCustomZuulProxyApplication { |
||||
|
||||
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET) |
||||
public String get(@PathVariable String id, HttpServletResponse response) { |
||||
response.setHeader("X-Ignored", "foo"); |
||||
response.setHeader("X-NotIgnored", "bar"); |
||||
return "Get " + id; |
||||
} |
||||
|
||||
@RequestMapping(value = "/cookie/{id}", method = RequestMethod.GET) |
||||
public String getWithCookie(@PathVariable String id, HttpSession session) { |
||||
Object testCookie = session.getAttribute("testCookie"); |
||||
if (testCookie != null) { |
||||
return "GetCookie " + testCookie; |
||||
} |
||||
session.setAttribute("testCookie", id); |
||||
return "SetCookie " + id; |
||||
} |
||||
|
||||
@RequestMapping(value = "/post", method = RequestMethod.POST) |
||||
public String post(@RequestParam("id") String id) { |
||||
return "Post " + id; |
||||
} |
||||
|
||||
@RequestMapping(value = "/put/{id}", method = RequestMethod.PUT) |
||||
public String put(@PathVariable String id) { |
||||
return "Put " + id; |
||||
} |
||||
|
||||
@RequestMapping(value = "/patch/{id}", method = RequestMethod.PATCH) |
||||
public String patch(@PathVariable String id, @RequestParam("patch") String patch) { |
||||
return "Patch " + id + patch; |
||||
} |
||||
|
||||
public static void main(String[] args) { |
||||
SpringApplication.run(SampleCustomZuulProxyApplication.class, args); |
||||
} |
||||
|
||||
@Configuration |
||||
@EnableZuulProxy |
||||
protected static class CustomZuulProxyConfig extends ZuulProxyConfiguration { |
||||
@Bean |
||||
@Override |
||||
public SimpleHostRoutingFilter simpleHostRoutingFilter() { |
||||
return new CustomHostRoutingFilter(); |
||||
} |
||||
|
||||
private class CustomHostRoutingFilter extends SimpleHostRoutingFilter { |
||||
|
||||
@Override |
||||
public Object run() { |
||||
super.addIgnoredHeaders("X-Ignored"); |
||||
return super.run(); |
||||
} |
||||
|
||||
@Override |
||||
protected CloseableHttpClient newClient() { |
||||
// Custom client with cookie support.
|
||||
// In practice, we would want a custom cookie store using a multimap with a user key.
|
||||
return HttpClients.custom() |
||||
.setConnectionManager(newConnectionManager()) |
||||
.setDefaultCookieStore(new BasicCookieStore()) |
||||
.setDefaultRequestConfig(RequestConfig.custom() |
||||
.setCookieSpec(CookieSpecs.DEFAULT) |
||||
.build()) |
||||
.build(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue