You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2021/09/29 17:37:26 UTC
[cxf] 01/03: [CXF-7396] Close some input streams/readers when
copying from various source objects to output
This is an automated email from the ASF dual-hosted git repository.
dkulp pushed a commit to branch 3.4.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 69590fe82d3dc1a1e0d7c42753c2465a1380abea
Author: Daniel Kulp <dk...@apache.org>
AuthorDate: Tue Aug 17 16:54:09 2021 -0400
[CXF-7396] Close some input streams/readers when copying from various source objects to output
(cherry picked from commit 148f59425afbe5c95786d5f65912cd7c3c1fcc9c)
---
.../databinding/source/XMLStreamDataWriter.java | 29 +++++++--
.../apache/cxf/systest/jaxws/ClientServerTest.java | 69 ++++++++++++++++++++++
2 files changed, 94 insertions(+), 4 deletions(-)
diff --git a/core/src/main/java/org/apache/cxf/databinding/source/XMLStreamDataWriter.java b/core/src/main/java/org/apache/cxf/databinding/source/XMLStreamDataWriter.java
index 1a388a7..fa01975 100644
--- a/core/src/main/java/org/apache/cxf/databinding/source/XMLStreamDataWriter.java
+++ b/core/src/main/java/org/apache/cxf/databinding/source/XMLStreamDataWriter.java
@@ -18,7 +18,9 @@
*/
package org.apache.cxf.databinding.source;
+import java.io.Closeable;
import java.io.IOException;
+import java.io.InputStream;
import java.util.Collection;
import java.util.logging.Logger;
@@ -28,6 +30,7 @@ import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.Validator;
@@ -67,22 +70,24 @@ public class XMLStreamDataWriter implements DataWriter<XMLStreamWriter> {
@SuppressWarnings("PMD.UseTryWithResources")
public void write(Object obj, XMLStreamWriter writer) {
- try {
+ Closeable toClose = null;
+ try {
if (obj instanceof DataSource) {
DataSource ds = (DataSource)obj;
+ InputStream is = ds.getInputStream();
+ toClose = is;
if (schema != null) {
- DOMSource domSource = new DOMSource(StaxUtils.read(ds.getInputStream()));
+ DOMSource domSource = new DOMSource(StaxUtils.read(is));
Validator schemaValidator = schema.newValidator();
schemaValidator.setErrorHandler(
new MtomValidationErrorHandler(schemaValidator.getErrorHandler(), domSource.getNode()));
schemaValidator.validate(domSource);
StaxUtils.copy(domSource, writer);
} else {
- XMLStreamReader reader = StaxUtils.createXMLStreamReader(ds.getInputStream());
+ XMLStreamReader reader = StaxUtils.createXMLStreamReader(is);
StaxUtils.copy(reader, writer);
reader.close();
}
-
} else if (obj instanceof Node) {
if (obj instanceof DocumentFragment) {
obj = org.apache.cxf.helpers.DOMUtils.getDomDocumentFragment((DocumentFragment)obj);
@@ -111,6 +116,14 @@ public class XMLStreamDataWriter implements DataWriter<XMLStreamWriter> {
&& ((DOMSource) s).getNode() == null) {
return;
}
+ if (s instanceof StreamSource) {
+ StreamSource ss = (StreamSource)s;
+ if (ss.getInputStream() != null) {
+ toClose = ss.getInputStream();
+ } else {
+ toClose = ss.getReader();
+ }
+ }
StaxUtils.copy(s, writer);
}
} catch (XMLStreamException e) {
@@ -121,6 +134,14 @@ public class XMLStreamDataWriter implements DataWriter<XMLStreamWriter> {
} catch (SAXException e) {
throw new Fault("COULD_NOT_WRITE_XML_STREAM_CAUSED_BY", LOG, e,
e.getClass().getCanonicalName(), e.getMessage());
+ } finally {
+ if (toClose != null) {
+ try {
+ toClose.close();
+ } catch (IOException ex) {
+ //likely already closed, not something we need to worry about
+ }
+ }
}
}
diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
index 912aa8a..72b37e6 100644
--- a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
+++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
@@ -20,6 +20,7 @@
package org.apache.cxf.systest.jaxws;
import java.io.ByteArrayInputStream;
+import java.io.File;
import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@@ -53,6 +54,8 @@ import javax.xml.ws.soap.SOAPFaultException;
import org.w3c.dom.Document;
+import com.google.common.io.Files;
+
import org.apache.cxf.Bus;
import org.apache.cxf.bus.CXFBusFactory;
import org.apache.cxf.common.logging.LogUtils;
@@ -61,6 +64,8 @@ import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.dynamic.DynamicClientFactory;
import org.apache.cxf.ext.logging.LoggingFeature;
import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.helpers.FileUtils;
+import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.jaxws.DispatchImpl;
import org.apache.cxf.message.Message;
import org.apache.cxf.staxutils.StaxUtils;
@@ -1001,6 +1006,70 @@ public class ClientServerTest extends AbstractBusClientServerTestBase {
assertEquals(requestString, StaxUtils.toString(response));
}
+
+ @Test
+ public void testEchoProviderThresholdAsync() throws Exception {
+ final File f = Files.createTempDir();
+ LOG.info("Using temp folder: " + f.getAbsolutePath());
+
+ System.setProperty("org.apache.cxf.io.CachedOutputStream.OutputDirectory", f.getAbsolutePath());
+ CachedOutputStream.setDefaultThreshold(5);
+
+ String requestString = "<echo/>";
+ Service service = Service.create(serviceName);
+ service.addPort(fakePortName, javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING,
+ "http://localhost:" + PORT + "/SoapContext/AsyncEchoProvider");
+ Dispatch<StreamSource> dispatcher = service.createDispatch(fakePortName,
+ StreamSource.class,
+ Service.Mode.PAYLOAD);
+ dispatcher.getRequestContext().put("javax.xml.ws.client.receiveTimeout", "5000");
+
+ StreamSource request = new StreamSource(new ByteArrayInputStream(requestString.getBytes()));
+ StreamSource response = dispatcher.invoke(request);
+
+ assertEquals(requestString, StaxUtils.toString(response));
+
+ //give the server side a little time to process it's part and close the files
+ if (f.list().length > 0) {
+ Thread.sleep(500);
+ }
+
+ assertEquals("Expected no files but there is at list one", 0, f.list().length);
+ FileUtils.removeDir(f);
+ }
+
+ @Test
+ public void testEchoProviderThresholdAsyncThrows() throws Exception {
+ final File f = Files.createTempDir();
+ LOG.info("Using temp folder: " + f.getAbsolutePath());
+
+ System.setProperty("org.apache.cxf.io.CachedOutputStream.OutputDirectory", f.getAbsolutePath());
+ CachedOutputStream.setDefaultThreshold(5);
+
+ String requestString = "<echo/>";
+ Service service = Service.create(serviceName);
+ service.addPort(fakePortName, javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING,
+ "http://localhost:" + PORT + "/SoapContext/AsyncEchoProvider");
+ Dispatch<StreamSource> dispatcher = service.createDispatch(fakePortName,
+ StreamSource.class,
+ Service.Mode.PAYLOAD);
+ dispatcher.getRequestContext().put("javax.xml.ws.client.receiveTimeout", "500");
+
+ try {
+ StreamSource request = new StreamSource(new ByteArrayInputStream(requestString.getBytes()));
+ StreamSource response = dispatcher.invoke(request);
+ assertEquals(requestString, StaxUtils.toString(response));
+ } catch (final WebServiceException ex) {
+ ((DispatchImpl<StreamSource>)dispatcher).getClient().close();
+ }
+ //give the server side a little time to process it's part and close the files
+ if (f.list().length > 0) {
+ Thread.sleep(500);
+ }
+
+ assertEquals("Expected no files but there is at list one", 0, f.list().length);
+ FileUtils.removeDir(f);
+ }
@Test
public void testEchoProviderAsyncDecoupledEndpoints() throws Exception {