Unverified Commit d0841f79 by Adrian Ivan Committed by Spencer Gibb

Send 404 in zuul servlet when no route is found.

Fixes false 200 in zuul when using zuul servlet rather than mvc servlet. Fixes gh-865
parent cef37773
......@@ -87,8 +87,8 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
@Bean
public PreDecorationFilter preDecorationFilter(RouteLocator routeLocator) {
return new PreDecorationFilter(routeLocator,
this.zuulProperties.isAddProxyHeaders(),
this.zuulProperties.isRemoveSemicolonContent());
this.server.getServletPrefix(),
this.zuulProperties);
}
// route filters
......
......@@ -90,6 +90,9 @@ public class SimpleRouteLocator implements RouteLocator {
log.debug("servletPath=" + this.dispatcherServletPath);
log.debug("zuulServletPath=" + this.zuulServletPath);
log.debug("RequestUtils.isDispatcherServletRequest()=" + RequestUtils.isDispatcherServletRequest());
log.debug("RequestUtils.isZuulServletRequest()=" + RequestUtils.isZuulServletRequest());
String adjustedPath = adjustPath(path);
......@@ -173,12 +176,14 @@ public class SimpleRouteLocator implements RouteLocator {
&& StringUtils.hasText(this.dispatcherServletPath)) {
if (!this.dispatcherServletPath.equals("/")) {
adjustedPath = path.substring(this.dispatcherServletPath.length());
log.debug("Stripped dispatcherServletPath");
}
}
else if (RequestUtils.isZuulServletRequest()) {
if (StringUtils.hasText(this.zuulServletPath)
&& !this.zuulServletPath.equals("/")) {
adjustedPath = path.substring(this.zuulServletPath.length());
log.debug("Stripped zuulServletPath");
}
}
else {
......
......@@ -21,6 +21,8 @@ import java.net.URL;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.util.RequestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UrlPathHelper;
......@@ -36,14 +38,20 @@ public class PreDecorationFilter extends ZuulFilter {
private RouteLocator routeLocator;
private boolean addProxyHeaders;
private String dispatcherServletPath;
private String zuulServletPath;
private UrlPathHelper urlPathHelper = new UrlPathHelper();
public PreDecorationFilter(RouteLocator routeLocator, boolean addProxyHeaders,
boolean removeSemicolonContent) {
public PreDecorationFilter(RouteLocator routeLocator,
String dispatcherServletPath, ZuulProperties zuulProperties) {
this.routeLocator = routeLocator;
this.addProxyHeaders = addProxyHeaders;
this.urlPathHelper.setRemoveSemicolonContent(removeSemicolonContent);
this.addProxyHeaders = zuulProperties.isAddProxyHeaders();
this.urlPathHelper.setRemoveSemicolonContent(zuulProperties.isRemoveSemicolonContent());
this.dispatcherServletPath = dispatcherServletPath;
this.zuulServletPath = zuulProperties.getServletPath();
}
@Override
......@@ -121,7 +129,27 @@ public class PreDecorationFilter extends ZuulFilter {
}
else {
log.warn("No route found for uri: " + requestURI);
ctx.set("forward.to", requestURI);
String fallBackUri = requestURI;
String fallbackPrefix = dispatcherServletPath; //default fallback servlet is DispatcherServlet
if (RequestUtils.isZuulServletRequest()) {
//remove the Zuul servletPath from the requestUri
log.debug("zuulServletPath=" + zuulServletPath);
fallBackUri = fallBackUri.replaceFirst(zuulServletPath, "");
log.debug("Replaced Zuul servlet path:" + fallBackUri);
} else {
//remove the DispatcherServlet servletPath from the requestUri
log.debug("dispatcherServletPath=" + dispatcherServletPath);
fallBackUri = fallBackUri.replaceFirst(dispatcherServletPath, "");
log.debug("Replaced DispatcherServlet servlet path:" + fallBackUri);
}
if (!fallBackUri.startsWith("/")) {
fallBackUri = "/" + fallBackUri;
}
String forwardURI = fallbackPrefix + fallBackUri;
forwardURI = forwardURI.replaceAll("//", "/");
ctx.set("forward.to", forwardURI);
}
return null;
}
......
......@@ -52,10 +52,10 @@ public class PreDecorationFilterTests {
@Before
public void init() {
initMocks(this);
this.properties = new ZuulProperties();
this.routeLocator = new DiscoveryClientRouteLocator("/", this.discovery,
this.properties);
this.filter = new PreDecorationFilter(this.routeLocator, true,
this.properties.isRemoveSemicolonContent());
this.filter = new PreDecorationFilter(this.routeLocator, "/", this.properties);
RequestContext ctx = RequestContext.getCurrentContext();
ctx.clear();
ctx.setRequest(this.request);
......@@ -138,6 +138,105 @@ public class PreDecorationFilterTests {
assertEquals("foo",
getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid"));
}
@Test
public void routeNotFound() throws Exception {
this.properties.setPrefix("/api");
this.properties.setStripPrefix(true);
this.routeLocator.addRoute(
new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null));
this.request.setRequestURI("/api/bar/1");
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/api/bar/1", ctx.get("forward.to"));
}
@Test
public void routeNotFoundDispatcherServletSpecialPath() throws Exception {
this.properties.setPrefix("/api");
this.properties.setStripPrefix(true);
this.properties.setAddProxyHeaders(true);
this.routeLocator.addRoute(
new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null));
this.filter = new PreDecorationFilter(this.routeLocator,
"/special", this.properties);
this.request.setRequestURI("/api/bar/1");
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/special/api/bar/1", ctx.get("forward.to"));
}
@Test
public void routeNotFoundZuulRequest() throws Exception {
setTestRequestContext();
RequestContext ctx = RequestContext.getCurrentContext();
ctx.getCurrentContext().setZuulEngineRan();
this.request.setRequestURI("/zuul/api/bar/1");
ctx.setRequest(this.request);
this.properties.setPrefix("/api");
this.properties.setStripPrefix(true);
this.properties.setServletPath("/zuul");
this.routeLocator.addRoute(
new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null));
this.filter.run();
assertEquals("/api/bar/1", ctx.get("forward.to"));
}
@Test
public void routeNotFoundZuulRequestDispatcherServletSpecialPath() throws Exception {
setTestRequestContext();
RequestContext ctx = RequestContext.getCurrentContext();
ctx.getCurrentContext().setZuulEngineRan();
this.request.setRequestURI("/zuul/api/bar/1");
ctx.setRequest(this.request);
this.properties.setPrefix("/api");
this.properties.setStripPrefix(true);
this.properties.setServletPath("/zuul");
this.properties.setAddProxyHeaders(true);
this.routeLocator.addRoute(
new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null));
this.filter = new PreDecorationFilter(this.routeLocator,
"/special", this.properties);
this.filter.run();
assertEquals("/special/api/bar/1", ctx.get("forward.to"));
}
@Test
public void routeNotFoundZuulRequestZuulHomeMapping() throws Exception {
setTestRequestContext();
RequestContext ctx = RequestContext.getCurrentContext();
ctx.getCurrentContext().setZuulEngineRan();
this.request.setRequestURI("/api/bar/1");
ctx.setRequest(this.request);
this.properties.setPrefix("/api");
this.properties.setStripPrefix(true);
this.properties.setServletPath("/");
this.properties.setAddProxyHeaders(true);
this.routeLocator.addRoute(
new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null));
this.filter = new PreDecorationFilter(this.routeLocator,
"/special", this.properties);
this.filter.run();
assertEquals("/special/api/bar/1", ctx.get("forward.to"));
}
private Object getHeader(List<Pair<String, String>> headers, String key) {
String value = null;
......@@ -149,5 +248,11 @@ public class PreDecorationFilterTests {
}
return value;
}
private void setTestRequestContext() {
RequestContext context = new RequestContext();
RequestContext.testSetCurrentContext(context);
}
}
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