diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java index 1488092a..2d3c2629 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java @@ -241,7 +241,7 @@ public class SimpleHostRoutingFilter extends ZuulFilter { requestEntity); URL host = RequestContext.getCurrentContext().getRouteHost(); HttpHost httpHost = getHttpHost(host); - uri = StringUtils.cleanPath(host.getPath() + uri); + uri = StringUtils.cleanPath((host.getPath() + uri).replaceAll("/{2,}", "/")); HttpRequest httpRequest; switch (verb.toUpperCase()) { case "POST": diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SampleZuulProxyApplicationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SampleZuulProxyApplicationTests.java index ab2d5365..d2e5f37e 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SampleZuulProxyApplicationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SampleZuulProxyApplicationTests.java @@ -16,13 +16,11 @@ package org.springframework.cloud.netflix.zuul; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.servlet.http.HttpServletRequest; import org.junit.Test; import org.junit.runner.RunWith; @@ -64,6 +62,9 @@ import com.netflix.loadbalancer.ServerList; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = SampleZuulProxyApplication.class) @WebAppConfiguration @@ -188,6 +189,17 @@ public class SampleZuulProxyApplicationTests { assertEquals("Received {key=[overridden]}", result.getBody()); } + @Test + public void simpleHostRouteWithTrailingSlash() { + routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); + this.endpoint.reset(); + ResponseEntity result = new TestRestTemplate().exchange( + "http://localhost:" + this.port + "/self/trailing-slash", + HttpMethod.GET, new HttpEntity<>((Void) null), String.class); + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertEquals("/trailing-slash", result.getBody()); + } + @Test public void ribbonCommandFactoryOverridden() { assertTrue("ribbonCommandFactory not a MyRibbonCommandFactory", @@ -246,6 +258,11 @@ class SampleZuulProxyApplication { return "Hello space"; } + @RequestMapping(value = "/trailing-slash") + public String trailingSlash(HttpServletRequest request) { + return request.getRequestURI(); + } + @Bean public RibbonCommandFactory ribbonCommandFactory(SpringClientFactory clientFactory) { return new MyRibbonCommandFactory(clientFactory);