title: Sending a redirect form a zuul filter
body: <p>I am implementing an addition to our set of zuul filters.
  This additional filter would look at a header and decide that a request should be redirected to a known location that I would configure.</p>
  
  <p>This is the body of the run method for the filter</p>
  
  <pre><code> @Override
      public Object run() {
          log.debug("Running the PreRouteTransMarkAndLoggingZuulFilter filter ");
          // retrieve redirect URL
          String redirectURL = filterConfigurationBean.getRedirectURL();
          if (redirectURL.isEmpty()) {
              return null;
          }
          // get the white list for allowed entries
          Set&lt;String&gt; whiteList = new HashSet&lt;&gt;(Arrays.asList(filterConfigurationBean.getWhiteList().split(",")));
          RequestContext ctx = RequestContext.getCurrentContext();
          // if request url is part of white list then allow
          String url = ctx.getRequest().getRequestURL().toString();
          if (checkWhiteList(url, whiteList)) {
              return null;
          }
          // get headers
          // check if an authorization header is present
          if (validHeader(ctx.getRequest())) {
              return null;
          }
          // if it got to here then if no header then redirect request
          try {
              ctx.getResponse().sendRedirect(redirectURL);
          } catch (IOException e) {
              log.error("unable to send a redirect to the login page");
          }
          return null;
      }
  </code></pre>
  
  <p>Ok, so I implemented and tested it (it is defined as a pre-filter since I don't want the request sent on in the route phase.</p>
  
  <p>Somewhere, a bit further, it tosses an exception.</p>
  
  <pre><code>2017-06-26 17:00:36.482  WARN 6267 --- [tp1303192419-23] o.s.c.n.z.filters.post.SendErrorFilter   : Error during filtering
  com.netflix.zuul.exception.ZuulException: Filter threw Exception
      at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:227)
      at com.netflix.zuul.FilterProcessor.runFilters(FilterProcessor.java:157)
      at com.netflix.zuul.FilterProcessor.postRoute(FilterProcessor.java:92)
      at com.netflix.zuul.ZuulRunner.postRoute(ZuulRunner.java:87)
      at com.netflix.zuul.http.ZuulServlet.postRoute(ZuulServlet.java:107)
      at com.netflix.zuul.http.ZuulServlet.service(ZuulServlet.java:88)
      at org.springframework.web.servlet.mvc.ServletWrappingController.handleRequestInternal(ServletWrappingController.java:157)
      at org.springframework.cloud.netflix.zuul.web.ZuulController.handleRequest(ZuulController.java:44)
      at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50)
      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
      at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
      at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
      at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841)
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650)
      at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:206)
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
      at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
      at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
      at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:208)
      at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
      at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
      at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
      at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
      at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
      at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
      at com.cisco.phisphere.routerservice.BasicCORSFilter.doFilter(BasicCORSFilter.java:78)
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
      at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
      at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
      at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
      at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
      at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
      at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
      at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188)
      at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253)
      at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168)
      at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
      at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
      at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166)
      at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155)
      at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
      at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
      at org.eclipse.jetty.server.Server.handle(Server.java:564)
      at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:317)
      at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
      at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
      at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110)
      at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
      at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:128)
      at org.eclipse.jetty.util.thread.Invocable$InvocableExecutor.invoke(Invocable.java:222)
      at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:294)
      at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:126)
      at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
      at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
      at java.lang.Thread.run(Thread.java:745)
  Caused by: java.lang.reflect.UndeclaredThrowableException: null
      at org.springframework.util.ReflectionUtils.rethrowRuntimeException(ReflectionUtils.java:317)
      at org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter.run(SendResponseFilter.java:115)
      at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:112)
      at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:193)
      ... 75 common frames omitted
  Caused by: org.eclipse.jetty.io.EofException: Closed
      at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:476)
      at org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter.writeResponse(SendResponseFilter.java:214)
      at org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter.writeResponse(SendResponseFilter.java:183)
      at org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter.run(SendResponseFilter.java:112)
      ... 77 common frames omitted
  </code></pre>
  
  <p>So the question I have is this.  Is this the right way to perform redirects from zuul?  </p>
  
  <p>I have a well defined condition for redirection and a well defined location to send it.  I don't want this request to continue if the condition is held but be redirected to an external location.</p>
  
  <p>Thanks</p>