Skip to content
Permalink
Browse files
CXF-8642: ResponseImpl#hasEntity return 'false' when entity is buffer…
…ed but entity stream is fully consumed with processing exception (#893)
  • Loading branch information
reta committed Jan 23, 2022
1 parent e2715ce commit c047c2a446716c90f9f198abb16fca66199ea2e1
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
@@ -152,6 +152,9 @@ public boolean hasEntity() {
Object actualEntity = getActualEntity();
if (actualEntity == null) {
return false;
} else if (entityBufferred) {
// if actualEntity is not null and entity was buffered, the response definitely has entity
return true;
} else if (actualEntity instanceof InputStream) {
final InputStream is = (InputStream) actualEntity;
try {
@@ -25,6 +25,7 @@
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.URI;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
@@ -34,6 +35,9 @@
import java.util.Set;

import javax.activation.DataSource;
import javax.ws.rs.Consumes;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.client.ResponseProcessingException;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.GenericEntity;
@@ -50,6 +54,8 @@
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.Variant;
import javax.ws.rs.core.Variant.VariantListBuilder;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.RuntimeDelegate;
import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
import javax.xml.transform.Source;
@@ -60,6 +66,7 @@
import org.w3c.dom.Document;

import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.provider.ProviderFactory;
import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
import org.apache.cxf.jaxrs.resources.Book;
@@ -641,7 +648,7 @@ public void testReadInputStream() {

response.close();
}

@Test
public void testReadDataSource() throws IOException {
final String str = "ouch";
@@ -683,6 +690,80 @@ public void testReadEntityWithAnnotations() {
assertThrows(IllegalStateException.class,
() -> response.readEntity(Reader.class, annotations));
}

@Test
public void testBufferAndReadInputStream() throws IOException {
final String str = "ouch";

try (ByteArrayInputStream out = new ByteArrayInputStream(str.getBytes())) {
final ResponseImpl response = new ResponseImpl(500, out);
final Message outMessage = createMessage();
outMessage.put(Message.REQUEST_URI, "http://localhost");
response.setOutMessage(outMessage);

final MultivaluedMap<String, Object> headers = new MetadataMap<>();
headers.putSingle("Content-Type", "text/rdf");
response.addMetadata(headers);

assertTrue(response.bufferEntity());
assertNotNull(response.readEntity(InputStream.class));
assertNotNull(response.getEntity());
assertTrue(response.hasEntity());

assertNotNull(response.readEntity(InputStream.class));
assertNotNull(response.getEntity());
assertTrue(response.hasEntity());

response.close();
}
}

@Test
public void testBufferAndReadInputStreamWithException() throws IOException {
final String str = "ouch";

try (ByteArrayInputStream out = new ByteArrayInputStream(str.getBytes())) {
final ResponseImpl response = new ResponseImpl(500, out);
final Message outMessage = createMessage();
outMessage.put(Message.REQUEST_URI, "http://localhost");
response.setOutMessage(outMessage);

ProviderFactory factory = ProviderFactory.getInstance(outMessage);
factory.registerUserProvider(new FaultyMessageBodyReader<InputStream>());

final MultivaluedMap<String, Object> headers = new MetadataMap<>();
headers.putSingle("Content-Type", "text/rdf");
response.addMetadata(headers);

assertTrue(response.bufferEntity());
assertThrows(ResponseProcessingException.class, () -> response.readEntity(InputStream.class));
assertNotNull(response.getEntity());
assertTrue(response.hasEntity());

assertThrows(ResponseProcessingException.class, () -> response.readEntity(InputStream.class));
assertNotNull(response.getEntity());
assertTrue(response.hasEntity());

response.close();
}
}

@Provider
@Consumes("text/rdf")
public static class FaultyMessageBodyReader<T> implements MessageBodyReader<T> {
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
}

@Override
public T readFrom(Class<T> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException {
IOUtils.consume(entityStream);
throw new IOException();
}
}

public static class StringBean {
private String header;

0 comments on commit c047c2a

Please sign in to comment.