Repository: cxf Updated Branches: refs/heads/master 3812fe232 -> ebf24b72c
[CXF-5842] Make sure the cache gets cleaned up if it fails to cache the input Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/ebf24b72 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/ebf24b72 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/ebf24b72 Branch: refs/heads/master Commit: ebf24b72c0468195f129aa6fd3b10c571592d216 Parents: 3812fe2 Author: Daniel Kulp <[email protected]> Authored: Wed Jul 9 10:58:33 2014 -0400 Committer: Daniel Kulp <[email protected]> Committed: Wed Jul 9 11:28:27 2014 -0400 ---------------------------------------------------------------------- .../cxf/attachment/AttachmentDataSource.java | 28 ++++++-- .../cxf/jaxrs/ext/MessageContextImpl.java | 2 +- .../cxf/systest/jaxrs/JAXRSMultipartTest.java | 67 +++++++++++++++++++- .../cxf/systest/jaxrs/MultipartServer.java | 1 + .../cxf/systest/jaxrs/resources/attachmentData | 2 +- 5 files changed, 90 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/ebf24b72/core/src/main/java/org/apache/cxf/attachment/AttachmentDataSource.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/attachment/AttachmentDataSource.java b/core/src/main/java/org/apache/cxf/attachment/AttachmentDataSource.java index 42194f5..d1b64b8 100644 --- a/core/src/main/java/org/apache/cxf/attachment/AttachmentDataSource.java +++ b/core/src/main/java/org/apache/cxf/attachment/AttachmentDataSource.java @@ -26,6 +26,7 @@ import java.io.OutputStream; import javax.activation.DataSource; import org.apache.cxf.helpers.IOUtils; +import org.apache.cxf.io.CacheSizeExceededException; import org.apache.cxf.io.CachedOutputStream; import org.apache.cxf.message.Message; @@ -49,12 +50,27 @@ public class AttachmentDataSource implements DataSource { if (cache == null) { cache = new CachedOutputStream(); AttachmentUtil.setStreamedAttachmentProperties(message, cache); - IOUtils.copy(ins, cache); - cache.lockOutputStream(); - ins.close(); - ins = null; - if (delegate != null) { - delegate.setInputStream(cache.getInputStream()); + try { + IOUtils.copy(ins, cache); + cache.lockOutputStream(); + if (delegate != null) { + delegate.setInputStream(cache.getInputStream()); + } + } catch (CacheSizeExceededException cee) { + cache.close(); + cache = null; + throw cee; + } catch (IOException cee) { + cache.close(); + cache = null; + throw cee; + } finally { + try { + ins.close(); + } catch (Exception ex) { + //ignore + } + ins = null; } } } http://git-wip-us.apache.org/repos/asf/cxf/blob/ebf24b72/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java index acd96d8..b1fec9b 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java @@ -76,7 +76,7 @@ public class MessageContextImpl implements MessageContext { return createAttachments(key.toString()); } catch (CacheSizeExceededException e) { m.getExchange().put("cxf.io.cacheinput", Boolean.FALSE); - throw new WebApplicationException(413); + throw new WebApplicationException(e, 413); } } if (keyValue.equals("WRITE-" + Message.ATTACHMENTS)) { http://git-wip-us.apache.org/repos/asf/cxf/blob/ebf24b72/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java ---------------------------------------------------------------------- diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java index 9832202..e89a3ea 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java @@ -22,7 +22,9 @@ package org.apache.cxf.systest.jaxrs; import java.awt.Image; import java.io.ByteArrayInputStream; import java.io.File; +import java.io.IOException; import java.io.InputStream; +import java.io.PushbackInputStream; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; @@ -50,6 +52,7 @@ import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource; import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; import org.apache.commons.httpclient.methods.multipart.Part; +import org.apache.cxf.helpers.FileUtils; import org.apache.cxf.helpers.IOUtils; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; @@ -140,6 +143,60 @@ public class JAXRSMultipartTest extends AbstractBusClientServerTestBase { doAddBook(address, "attachmentData", 200); } + + int countTempFiles() { + File file = FileUtils.getDefaultTempDir(); + File files[] = file.listFiles(); + if (files == null) { + return 0; + } + int count = 0; + for (File f : files) { + if (f.isFile()) { + count++; + } + } + return count; + } + @Test + public void testBookAsMassiveAttachment() throws Exception { + //CXF-5842 + int orig = countTempFiles(); + String address = "http://localhost:" + PORT + "/bookstore/books/attachments"; + InputStream is = + getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/attachmentData"); + //create a stream that sticks a bunch of data for the attachement to cause the + //server to buffer the attachment to disk. + PushbackInputStream buf = new PushbackInputStream(is, 1024 * 20) { + int bcount = -1; + @Override + public int read(byte b[], int offset, int len) throws IOException { + if (bcount >= 0 && bcount < 1024 * 50) { + for (int x = 0; x < len; x++) { + b[offset + x] = (byte)x; + } + bcount += len; + return len; + } + int i = super.read(b, offset, len); + for (int x = 0; x < i - 5; x++) { + if (b[x + offset] == '*' + && b[x + offset + 1] == '*' + && b[x + offset + 2] == 'D' + && b[x + offset + 3] == '*' + && b[x + offset + 4] == '*') { + super.unread(b, x + offset + 5, i - x - 5); + i = x; + bcount = 0; + } + } + return i; + } + }; + doAddBook("multipart/related", address, buf, 413); + assertEquals(orig, countTempFiles()); + } + @Test public void testBookJSONForm() throws Exception { String address = "http://localhost:" + PORT + "/bookstore/books/jsonform"; @@ -888,13 +945,19 @@ public class JAXRSMultipartTest extends AbstractBusClientServerTestBase { } private void doAddBook(String type, String address, String resourceName, int status) throws Exception { + InputStream is = + getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/" + resourceName); + doAddBook(type, address, is, status); + } + private void doAddBook(String type, String address, InputStream is, int status) throws Exception { + PostMethod post = new PostMethod(address); String ct = type + "; type=\"text/xml\"; " + "start=\"rootPart\"; " + "boundary=\"----=_Part_4_701508.1145579811786\""; post.setRequestHeader("Content-Type", ct); - InputStream is = - getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/" + resourceName); + + RequestEntity entity = new InputStreamRequestEntity(is); post.setRequestEntity(entity); HttpClient httpclient = new HttpClient(); http://git-wip-us.apache.org/repos/asf/cxf/blob/ebf24b72/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java ---------------------------------------------------------------------- diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java index 0eb365f..0bf1718 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java @@ -39,6 +39,7 @@ public class MultipartServer extends AbstractBusTestServerBase { Map<String, Object> props = new HashMap<String, Object>(); props.put(AttachmentDeserializer.ATTACHMENT_MAX_SIZE, String.valueOf(1024 * 10)); + props.put(AttachmentDeserializer.ATTACHMENT_MEMORY_THRESHOLD, String.valueOf(1024 * 5)); sf.setProperties(props); //default lifecycle is per-request, change it to singleton sf.setResourceProvider(MultipartStore.class, http://git-wip-us.apache.org/repos/asf/cxf/blob/ebf24b72/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentData ---------------------------------------------------------------------- diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentData b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentData index acca093..d82aa8e 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentData +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentData @@ -9,7 +9,7 @@ Content-Type: image/jpeg Content-Transfer-Encoding: binary Content-ID: <foo> -foobar +**D** ------=_Part_4_701508.1145579811786-- Content-Type: application/xml Content-ID: <book2>
