In my custom pre filter I want to set responseDataStream and disable route filters.
My first implementation was:
//sets response input stream
ctx.setResponseDataStream(new ByteArrayInputStream(body));
// disables route filters
ctx.setSendZuulResponse(false);
But this code doesn't work, because SendResponseFilter doesn't send responseDataStream if sendZuulResponse is false. My workaround was following:
//sets response input stream
ctx.setResponseDataStream(new ByteArrayInputStream(body));
//Disable SimpleHostRoutingFilter
ctx.setRouteHost(null);
//Disable RibbonRoutingFilter
ctx.remove("serviceId");
As for me such implementation is too bad.
I would like to have ability to turn off route filters without changing of response sending flow.
Thanks.
why are you trying to send a body but are disabling send zuul response?
The idea of the whole post is to serve cached responses (byte arrays) via Zuul.
To implement this firstly I need to disable both routing filters: RibbonRoutingFilter and SimpleHostRoutingFilter. This can be done by the following code:
//Disable SimpleHostRoutingFilter
ctx.setRouteHost(null);
//Disable RibbonRoutingFilter
ctx.remove("serviceId");
Or by:
ctx.setSendZuulResponse(false);
Why these 2 solutions? Let's see method shouldFilter from SimpleHostRoutingFilter and RibbonRoutingFilter:
public boolean shouldFilter() {
return RequestContext.getCurrentContext().getRouteHost() != null
&& RequestContext.getCurrentContext().sendZuulResponse();
}
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
return (ctx.getRouteHost() == null && ctx.get("serviceId") != null
&& ctx.sendZuulResponse());
}
As you can see from these lines to disable both of them you either need to setSendZuulResponse to false or remove serviceId and routeHost from RequestContext.
So I would like to have ability to disable route filters by something like: ctx.disableRouting();. Is that possible to implement or are there any reasons not to do that?
We can't add methods to RequestContext, just attributes. I don't think disabling routing is something that is a very common thing to do. I'd rather not add 3rd item for each filter to check. Is this something you want to do per route, or just disable routing all together?
For certain requests I would like to serve cached response. Cached or not is determined by pre-filter. So, for cached responses I need to skip routing, iow not call backend service.
@Aloren @spencergibb I have similar case where i need to disable filters for one Channel/Consumer. Also please let me know if there is a way to configure a complete set of different filters for other channel. thanks in advance.
@stiyyagura there is not a general way. You can disable routing in a prefilter:
//Disable SimpleHostRoutingFilter
ctx.setRouteHost(null);
//Disable RibbonRoutingFilter
ctx.remove("serviceId");
@Aloren good job!
I am trying to pre filter the requests as @Aloren suggested, but they still get routed to the target service. What I want to do is simple: pre filter certain requests to my proxy and send a response with a specific status and response body.
The problem with the following code is that the request is not blocked, still routed and
response body sent to the client is empty.
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String customHeader = request.getHeader("some-custom-header");
if (customHeader == null) {
ctx.setRouteHost(null);
ctx.remove("serviceId");
ctx.setResponseStatusCode(HttpStatus.BAD_REQUEST.value());
ctx.setResponseBody("Error");
}
return null;
}
@hakkibagci we are using the following code for this case:
public void sendJsonResponse(RequestContext ctx, HttpStatus httpCode, Object body) {
String bodyJson = objectMapper.writeValueAsString(body);
ctx.setResponseStatusCode(httpCode.value());
ctx.setResponseBody(bodyJson);
ctx.addZuulResponseHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE);
//We do not expect bytes to be gzipped
ctx.setResponseGZipped(false);
//Disable SimpleHostRoutingFilter
ctx.setRouteHost(null);
//Disable RibbonRoutingFilter
ctx.remove("serviceId");
}
This module has entered maintenance mode. This means that the Spring Cloud team will no longer be adding new features to the module. We will fix blocker bugs and security issues, and we will also consider and review small pull requests from the community.
Most helpful comment
For certain requests I would like to serve cached response. Cached or not is determined by pre-filter. So, for cached responses I need to skip routing, iow not call backend service.