Hi Sergey :). Some weeks ago, I tried 3.1.6 to check. As it seems there sneaked a new version out behind my back ;).
All good. Thanks for the quick feedback! Cheers Veit > Gesendet: Mittwoch, 10. August 2016 um 23:52 Uhr > Von: "Sergey Beryozkin" <[email protected]> > An: [email protected] > Betreff: Re: Entity stream corruption in ClientResponseContext.hasEntity() > > Hi Veit > > Good to hear from you, looks like it is time to migrate :-). > > This is 3.1.5: > > https://github.com/apache/cxf/blob/cxf-3.1.5/core/src/main/java/org/apache/cxf/helpers/IOUtils.java#L69 > > and here is 3.1.7 > > https://github.com/apache/cxf/blob/cxf-3.1.7/core/src/main/java/org/apache/cxf/helpers/IOUtils.java#L73 > > HTH, > Sergey > > > On 10/08/16 17:28, Veit Guna wrote: > > Hi. > > > > I'm using Apache CXF 3.1.5 as a JAX-RS client implementation and recently > > encountered > > a stream corruption bug when using client side JAX-RS filters. > > > > In my scenario, I use a JAX-RS client side filter to perform response > > logging while > > using client side JAX-RS proxies. > > > > For that I created a JAX-RS filter implementing ClientRequestFilter and > > ClientResponseFilter > > and added it as a provider to the JAX-RS/CXF runtime. > > > > Now when I perform e.g. a GET request, the filter is invoked as expected > > calling > > > > @Override > > public void filter(ClientRequestContext requestContext, > > ClientResponseContext responseContext) throws IOException { > > > > if (responseContext.hasEntity()) { > > // wrap responseContext.getEntityStream() with > > LoggingBufferedStream and set it on responseContext > > ... > > } > > } > > > > with the current response. > > > > Now from time to time it happened, that the received content missed the > > first byte of > > the payload leading to an exception in jackson, that it couldn't parse the > > JSON content > > correctly. > > > > After investigation, this happend most of the time, when the response had > > "transfer-encoding: chunked" set. Looking deeper into CXFs > > responseContext.hasEntity() > > implementation showed, that the lost byte is due to a call to > > IOUtils.isEmpty(stream): > > > > https://github.com/apache/cxf/blob/master/core/src/main/java/org/apache/cxf/helpers/IOUtils.java > > > > In there are basically 3 checks: > > > > - is mark supported? > > - is available > 0 > > - if NOT the above, wrap stream with PushbackInputStream, try to read a > > byte and unread. > > > > Sadly, in this chunked scenario, it seems that the > > responseContext.getEntityStream() > > neither supports mark nor is available > 0 (it is 0). So it wraps the > > stream with > > PushbackInputStream, reads a byte and unreads. But, as the underlying > > stream doesn't > > support reset/rewind or similar, the read byte is "lost". As the > > PushbackInputStream > > isn't returned from that method and so there's no way to get that byte back. > > > > Not invoking hasEntity() in the filter at all and just taking the stream > > and reading > > (buffered) from it, fixes the problem. > > > > It would be great if someone from the CXF team could take a peek at it :). > > > > Thanks! > > Veit > > > > > -- > Sergey Beryozkin > > Talend Community Coders > http://coders.talend.com/ >
