I am using Zuul to proxy a strange client that sends a body as part of a GET request. There is unfortunately no way I can change the client.
With curl such a request can be sent as:
curl -XGET 'localhost:8765/kibana/index.html' -d' {"key": "value"}'
And the data is really sent in the body. On zuul side, however, when I try to read the body it is empty. Here is my prototype zuul code:
@Configuration
@ComponentScan
@EnableAutoConfiguration
@Controller
@EnableZuulProxy
public class ZuulServerApplication {
@Bean
public ZuulFilter myFilter() {
return new ZuulFilter(){
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request=(HttpServletRequest)ctx.getRequest();
try {
InputStream is=request.getInputStream();
String content=IOUtils.toString(is);
System.out.println("Request content:"+content);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public int filterOrder() {
return 10;
}
@Override
public String filterType() {
return "pre";
}};
}
public static void main(String[] args) {
new SpringApplicationBuilder(ZuulServerApplication.class).web(true).run(args);
}
}
If I send a POST request, the this code prints the request body without problem. However, if I send the above GET request, the body is not printed. Anything I can do to actually get the body sent as part of a GET request?
It seems that some underlying machinery[0], e.g. some built-in Zuul filter with lesser filter order, replaces default "raw" HttpServletRequest
with HttpServletRequestWrapper
which, under standard circumstances (i.e. not GET
method with body), is able to handle multiple acquisition of input stream. But in the case of GET
method with body HttpServletRequestWrapper
seems to not proxy input stream at all.
Thus solution could be to change filterOrder
e.g. to -10
.
Then it works for the filter since HttpServletRequest
is used - the mentioned machinery did not get to its turn and thus didn't replace HttpServletRequest
with HttpServletRequestWrapper
yet. But potential issue with this solution is that the filter might exhaust input stream for something else, e.g. filter with higher filter order. But since GET
with body is not a good practice anyway, it might be good enough solution after all :)
[0] I've debug into this longer time ago, but did not get to exact point - thus vague definition of "the machinery".