[ 
https://issues.apache.org/jira/browse/CXF-6149?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Dmitry Kozlov updated CXF-6149:
-------------------------------
    Description: 
According to [JAX-RS API 2.0 
documentation|https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/container/ContainerRequestContext.html#hasEntity()]
 the {{ContainerRequestContext.hasEntity()}} should return {{true}} only, when 
there is *non-empty* entity input stream available.

But {{ContainerRequestContextImpl}} always returns {{true}} for any non-GET 
request even if there is *no* entity passed with request - check 
[ContainerRequestContextImpl.java:70|https://github.com/apache/cxf/blob/cxf-3.0.3/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ContainerRequestContextImpl.java#L70]:
{code}
    @Override
    public boolean hasEntity() {
        InputStream is = getEntityStream();
        return is != null && !HttpMethod.GET.equals(getMethod());
    }
{code}

This happens due to the fact that {{getEntityStream()}} is never {{null}}. It 
always returns a {{DelegatingInputStream}} wrapper around 
{{javax.servlet.ServletInputStream}} put in message in 
{{AbstractHTTPDestination}} - check 
[AbstractHTTPDestination.java:298|https://github.com/apache/cxf/blob/cxf-3.0.3/rt/transports/http/src/main/java/org/apache/cxf/transport/http/AbstractHTTPDestination.java#L298]:
{code}
        DelegatingInputStream in = new 
DelegatingInputStream(req.getInputStream()) {

                     ... // skipped

        };
        
        inMessage.setContent(DelegatingInputStream.class, in);
        inMessage.setContent(InputStream.class, in);
{code}

Thus method contract is not satisfied. Presence of input stream doesn't mean 
that this stream has content. Implementation should check that there is indeed 
non-empty entity stream, e.g. via checking EOF using 
[read()|https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read()]
 (obviously caching results for actual consumer).

*N.B.*: I believe the same issue affects {{ClientResponseContextImpl}} - check 
[ClientResponseContextImpl.java:62|https://github.com/apache/cxf/blob/cxf-3.0.3/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientResponseContextImpl.java#L62]:
{code}
    @Override
    public boolean hasEntity() { 
        return getEntityStream() != null;
    }
{code}

  was:
According to [JAX-RS API 2.0 
documentation|https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/container/ContainerRequestContext.html#hasEntity()]
 the {{ContainerRequestContext.hasEntity()}} should return {{true}} only, when 
there is *non-empty* entity input stream available.

But {{ContainerRequestContextImpl}} always returns {{true}} for any non-GET 
request even if there is *no* entity passed with request - check 
[ContainerRequestContextImpl.java:70|https://github.com/apache/cxf/blob/cxf-3.0.3/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ContainerRequestContextImpl.java#L70]:
{code}
    @Override
    public boolean hasEntity() {
        InputStream is = getEntityStream();
        return is != null && !HttpMethod.GET.equals(getMethod());
    }
{code}

This happens due to the fact that {{getEntityStream()}} is never {{null}}. It 
always returns a {{DelegatingInputStream}} wrapper around 
{{javax.servlet.ServletInputStream}} put in message in 
{{AbstractHTTPDestination}} - check 
[AbstractHTTPDestination.java:298|https://github.com/apache/cxf/blob/cxf-3.0.3/rt/transports/http/src/main/java/org/apache/cxf/transport/http/AbstractHTTPDestination.java#L298]:
{code}
        DelegatingInputStream in = new 
DelegatingInputStream(req.getInputStream()) {

                     ... // skipped

        };
        
        inMessage.setContent(DelegatingInputStream.class, in);
        inMessage.setContent(InputStream.class, in);
{code}

Thus method contract is not satisfied. Presence of input stream doesn't mean 
that this stream has content, e.g. via checking EOF using 
[read()|https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read()]
 (obviously caching results for actual consumer).

*N.B.*: I believe the same issue affects {{ClientResponseContextImpl}} - check 
[ClientResponseContextImpl.java:62|https://github.com/apache/cxf/blob/cxf-3.0.3/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientResponseContextImpl.java#L62]:
{code}
    @Override
    public boolean hasEntity() { 
        return getEntityStream() != null;
    }
{code}


> ContainerRequestContextImpl hasEntity() always returns true for non-GET 
> requests. Similar for ClientResponseContextImpl
> -----------------------------------------------------------------------------------------------------------------------
>
>                 Key: CXF-6149
>                 URL: https://issues.apache.org/jira/browse/CXF-6149
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-RS
>    Affects Versions: 3.0.3
>            Reporter: Dmitry Kozlov
>              Labels: jax-rs, jaxrs
>
> According to [JAX-RS API 2.0 
> documentation|https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/container/ContainerRequestContext.html#hasEntity()]
>  the {{ContainerRequestContext.hasEntity()}} should return {{true}} only, 
> when there is *non-empty* entity input stream available.
> But {{ContainerRequestContextImpl}} always returns {{true}} for any non-GET 
> request even if there is *no* entity passed with request - check 
> [ContainerRequestContextImpl.java:70|https://github.com/apache/cxf/blob/cxf-3.0.3/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ContainerRequestContextImpl.java#L70]:
> {code}
>     @Override
>     public boolean hasEntity() {
>         InputStream is = getEntityStream();
>         return is != null && !HttpMethod.GET.equals(getMethod());
>     }
> {code}
> This happens due to the fact that {{getEntityStream()}} is never {{null}}. It 
> always returns a {{DelegatingInputStream}} wrapper around 
> {{javax.servlet.ServletInputStream}} put in message in 
> {{AbstractHTTPDestination}} - check 
> [AbstractHTTPDestination.java:298|https://github.com/apache/cxf/blob/cxf-3.0.3/rt/transports/http/src/main/java/org/apache/cxf/transport/http/AbstractHTTPDestination.java#L298]:
> {code}
>         DelegatingInputStream in = new 
> DelegatingInputStream(req.getInputStream()) {
>                      ... // skipped
>         };
>         
>         inMessage.setContent(DelegatingInputStream.class, in);
>         inMessage.setContent(InputStream.class, in);
> {code}
> Thus method contract is not satisfied. Presence of input stream doesn't mean 
> that this stream has content. Implementation should check that there is 
> indeed non-empty entity stream, e.g. via checking EOF using 
> [read()|https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read()]
>  (obviously caching results for actual consumer).
> *N.B.*: I believe the same issue affects {{ClientResponseContextImpl}} - 
> check 
> [ClientResponseContextImpl.java:62|https://github.com/apache/cxf/blob/cxf-3.0.3/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientResponseContextImpl.java#L62]:
> {code}
>     @Override
>     public boolean hasEntity() { 
>         return getEntityStream() != null;
>     }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to