You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2022/01/23 17:55:24 UTC
[cxf] branch 3.4.x-fixes updated: CXF-8642: ResponseImpl#hasEntity return 'false' when entity is buffered but entity stream is fully consumed with processing exception (#893)
This is an automated email from the ASF dual-hosted git repository.
reta pushed a commit to branch 3.4.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/3.4.x-fixes by this push:
new 97ada30 CXF-8642: ResponseImpl#hasEntity return 'false' when entity is buffered but entity stream is fully consumed with processing exception (#893)
97ada30 is described below
commit 97ada30ae538dd9d4a6519e8cfe1efc88b792729
Author: Andriy Redko <dr...@gmail.com>
AuthorDate: Sun Jan 23 11:14:03 2022 -0500
CXF-8642: ResponseImpl#hasEntity return 'false' when entity is buffered but entity stream is fully consumed with processing exception (#893)
(cherry picked from commit c047c2a446716c90f9f198abb16fca66199ea2e1)
(cherry picked from commit 143a8c0d33bba236e8edca9d13b1b8e2f94e58c1)
---
.../org/apache/cxf/jaxrs/impl/ResponseImpl.java | 3 +
.../apache/cxf/jaxrs/impl/ResponseImplTest.java | 83 +++++++++++++++++++++-
2 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java
index f157c2a..a5c0d31 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java
@@ -152,6 +152,9 @@ public final class ResponseImpl extends Response {
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 {
diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/ResponseImplTest.java b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/ResponseImplTest.java
index d140070..d71400f 100644
--- a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/ResponseImplTest.java
+++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/ResponseImplTest.java
@@ -25,6 +25,7 @@ import java.io.InputStream;
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.Map;
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.Response.StatusType;
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 javax.xml.transform.dom.DOMResult;
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 class ResponseImplTest {
response.close();
}
-
+
@Test
public void testReadDataSource() throws IOException {
final String str = "ouch";
@@ -683,6 +690,80 @@ public class ResponseImplTest {
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;