From 64e5a2e0ba85f913b04c7733a798aae560cdcf11 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Wed, 7 Jan 2015 11:54:27 -0700 Subject: [PATCH] protect against a null RequestDispatcher --- .../zuul/filters/post/SendErrorFilter.java | 11 +++- .../zuul/SampleZuulProxyApplicationTests.java | 8 +++ .../filters/post/SendErrorFilterTests.java | 51 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java index 736faa28..4f88398d 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java @@ -6,6 +6,8 @@ import com.netflix.zuul.context.RequestContext; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import javax.servlet.RequestDispatcher; + /** * @author Spencer Gibb */ @@ -42,10 +44,17 @@ public class SendErrorFilter extends ZuulFilter { ctx.getRequest().setAttribute("javax.servlet.error.exception", e); } ctx.getRequest().setAttribute("javax.servlet.error.status_code", statusCode); - ctx.getRequest().getRequestDispatcher(errorPath).forward(ctx.getRequest(), ctx.getResponse()); + RequestDispatcher dispatcher = ctx.getRequest().getRequestDispatcher(errorPath); + if (dispatcher != null) { + dispatcher.forward(ctx.getRequest(), ctx.getResponse()); + } } catch (Exception e) { Throwables.propagate(e); } return null; } + + public void setErrorPath(String errorPath) { + this.errorPath = errorPath; + } } 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 b72f31a1..1d40673f 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 @@ -81,6 +81,14 @@ public class SampleZuulProxyApplicationTests { assertEquals("Deleted!", result.getBody()); } + @Test + public void testNotFound() { + ResponseEntity result = new TestRestTemplate().exchange( + "http://localhost:" + port + "/myinvalidpath", HttpMethod.GET, + new HttpEntity((Void) null), String.class); + assertEquals(HttpStatus.NOT_FOUND, result.getStatusCode()); + } + } //Don't use @SpringBootApplication because we don't want to component scan diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java new file mode 100644 index 00000000..b176e3d1 --- /dev/null +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java @@ -0,0 +1,51 @@ +package org.springframework.cloud.netflix.zuul.filters.post; + +import com.netflix.zuul.context.RequestContext; +import org.junit.After; +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import javax.servlet.http.HttpServletRequest; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +/** + * @author Spencer Gibb + */ +public class SendErrorFilterTests { + + @After + public void reset() { + RequestContext.testSetCurrentContext(null); + } + + @Test + public void runsNormally() { + SendErrorFilter filter = createSendErrorFilter(new MockHttpServletRequest()); + + assertTrue("shouldFilter returned false", filter.shouldFilter()); + filter.run(); + } + + private SendErrorFilter createSendErrorFilter(HttpServletRequest request) { + RequestContext context = new RequestContext(); + context.setRequest(request); + context.setResponse(new MockHttpServletResponse()); + context.set("error.status_code", HttpStatus.NOT_FOUND.value()); + RequestContext.testSetCurrentContext(context); + SendErrorFilter filter = new SendErrorFilter(); + filter.setErrorPath("/error"); + return filter; + } + + @Test + public void noRequestDispatcher() { + SendErrorFilter filter = createSendErrorFilter(mock(HttpServletRequest.class)); + + assertTrue("shouldFilter returned false", filter.shouldFilter()); + filter.run(); + } +}