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/
> 

Reply via email to