Closed stiyyagura closed 7 years ago
Why are you not using a ZuulFilter
to do what you need?
Besides, Servlet Request attributes are not part of HTTP and do not get forwarded. You would need to use a header.
@spencergibb very true i was aware of that just tried to give one example of adding more to incomeing request at Zuul level but my objective is to have a better control of the incoming request and add/transform the request/response in to origin service understandable contract. Can you suggest a way to do it? @ryanjbaxter that's exactly i wanted to do but didn't get a complete picture on how to get the request (headers,body,etc..) information and transform it. Any advice is really helps.
There are plenty of examples that you can look at here https://github.com/spring-cloud/spring-cloud-netflix/tree/master/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre
@ryanjbaxter @spencergibb I have tried like below,
requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class, "req", HttpServletRequest.class);
HttpServletRequest wrapped = (HttpServletRequest) ReflectionUtils.getField(this.requestField, request);
XYZRequestWrapper wrapper = new XYZRequestWrapper(wrapped );
inputStream = wrapper .getInputStream(); -- This is always giving
String str = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
But this is not giving me any byte array/input stream where as if i pass the RequestContext(zuul).getRequest diredtlly to the above wrapper i am getting the input stream/byte array. Not sure why it is behaving as per the Zuul orginal request is in "req" element!!!
Please let me know if it safe to do like this...below
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
XYZRequestWrapper wrapper = null;
try {
wrapper = new XYZRequestWrapper (request);
InputStream inputStream = wrapper.getInputStream();
String str = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
LOGGER.info("STRING: " + str);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Using a wrapper isn't the right way to access the input stream. See https://github.com/spring-cloud/spring-cloud-netflix/blob/master/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java#L196-L209 for how we access the input stream.
It is in the RequestContext
with the key requestEntity
.
@spencergibb I see the below code in there. Even here we are getting the InputStream from the request how is this different from my wrapper?? Just an fyi My wrapper i am calling in "pre" filters..something similar to FormBodyRequestWrapper (this is giving only query params as stream) but i need body of the request as well since i am trying to get the same from request.getInputStream().
Please let me know if i need to upload the classes..i can do that.
protected InputStream getRequestBody(HttpServletRequest request) {
InputStream requestEntity = null;
try {
requestEntity = (InputStream) RequestContext.getCurrentContext()
.get("requestEntity");
if (requestEntity == null) {
requestEntity = request.getInputStream();
}
}
catch (IOException ex) {
log.error("Error during getRequestBody", ex);
}
return requestEntity;
}
How can I access original Request attributes particularly the X509 certificate chain from a zuul filter?
@scaryPonens please open a separate issue
I thought the question was very similar and relevant to the thread. I found my answer reviewing the Zuul request lifecycle. There is no intermediate request created. Sorry for the hijack attempt. How it Works
@stiyyagura if it helps I was able to using a PRE filter to retrieve the x.509 certificate chain from the HttpRequest calculate the fingerprint and stick it into a custom header which was then used upstream.
@scaryPonens Agree with you but in my case want to transform the request body from one format to another in filter and send it to the back end services.
@stiyyagura I think the difference is that we are checking the RequestContext
first
thanks for pointers and clarifications.
I am trying to transform the original request by writing custom wrapper extending HttpServletRequestWrapper and adding additional attribute in ZuulFilter 1. But my origin service is not receiving this attribute but in Zuul filter 2 i can access this attribute. Do i need to do anything else to handle this use case. I might need to do the same thing for response as well. Please suggest best way to do request/response transformations.