This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch 1.x in repository https://gitbox.apache.org/repos/asf/commons-fileupload.git
The following commit(s) were added to refs/heads/1.x by this push: new feeece42 [1.x] Enable multipart/related on FileUpload (#314) feeece42 is described below commit feeece42789c469ad268230b8a0f979e8e145052 Author: mufasa1976 <mufasa1...@users.noreply.github.com> AuthorDate: Mon May 20 18:28:48 2024 +0200 [1.x] Enable multipart/related on FileUpload (#314) * added ability to use content-type: multipart/related * reformatted a part from the new test * added line-break on test * set field multipartRelated to be final * removed unnecessary condition * added as a contributor * small polishings due to code review * Javadoc --------- Co-authored-by: Gary Gregory <garydgreg...@users.noreply.github.com> --- pom.xml | 4 ++ .../apache/commons/fileupload/FileUploadBase.java | 28 +++++++++++-- .../apache/commons/fileupload/FileUploadTest.java | 49 ++++++++++++++++++++++ 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 5378aacc..6e3ff724 100644 --- a/pom.xml +++ b/pom.xml @@ -177,6 +177,10 @@ <name>fangwentong</name> <email>fangwentong2...@gmail.com</email> </contributor> + <contributor> + <name>mufasa1976</name> + <email>mufasa1976@coolstuff.software</email> + </contributor> </contributors> <scm> diff --git a/src/main/java/org/apache/commons/fileupload/FileUploadBase.java b/src/main/java/org/apache/commons/fileupload/FileUploadBase.java index 09679a1d..cd3893ed 100644 --- a/src/main/java/org/apache/commons/fileupload/FileUploadBase.java +++ b/src/main/java/org/apache/commons/fileupload/FileUploadBase.java @@ -138,6 +138,13 @@ public abstract class FileUploadBase { */ public static final String MULTIPART_MIXED = "multipart/mixed"; + /** + * HTTP content type header for multiple related data. + * + * @since 1.6.0 + */ + public static final String MULTIPART_RELATED = "multipart/related"; + /** * The maximum length of a single header line that will be parsed * (1024 bytes). @@ -954,6 +961,11 @@ public abstract class FileUploadBase { */ private boolean eof; + /** + * Is this a multipart/related Request. + */ + private final boolean multipartRelated; + /** * Creates a new instance. * @@ -972,10 +984,11 @@ public abstract class FileUploadBase { if (null == contentType || !contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART)) { throw new InvalidContentTypeException( - format("the request doesn't contain a %s or %s stream, content type header is %s", - MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType)); + format("the request neither contains a %s nor a %s nor a %s stream, content type header is %s", + MULTIPART_FORM_DATA, MULTIPART_MIXED, MULTIPART_RELATED, contentType)); } + multipartRelated = contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART_RELATED); @SuppressWarnings("deprecation") // still has to be backward compatible final int contentLengthInt = ctx.getContentLength(); @@ -1068,7 +1081,16 @@ public abstract class FileUploadBase { continue; } final FileItemHeaders headers = getParsedHeaders(multi.readHeaders()); - if (currentFieldName == null) { + if (multipartRelated) { + currentFieldName = ""; + currentItem = new FileItemStreamImpl( + null, null, headers.getHeader(CONTENT_TYPE), + false, getContentLength(headers)); + currentItem.setHeaders(headers); + notifier.noteItem(); + itemValid = true; + return true; + } else if (currentFieldName == null) { // We're parsing the outer multipart final String fieldName = getFieldName(headers); if (fieldName != null) { diff --git a/src/test/java/org/apache/commons/fileupload/FileUploadTest.java b/src/test/java/org/apache/commons/fileupload/FileUploadTest.java index 439c8660..04438021 100644 --- a/src/test/java/org/apache/commons/fileupload/FileUploadTest.java +++ b/src/test/java/org/apache/commons/fileupload/FileUploadTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.List; import org.apache.commons.fileupload.portlet.PortletFileUploadTest; @@ -394,4 +395,52 @@ public class FileUploadTest { } } } + + /** + * Test for multipart/related without any content-disposition Header. + * This kind of Content-Type is commonly used by SOAP-Requests with Attachments (MTOM) + */ + @Test + public void testMultipartRelated() throws FileUploadException { + final String soapEnvelope = + "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">\r\n" + + " <soap:Header></soap:Header>\r\n" + + " <soap:Body>\r\n" + + " <ns1:Test xmlns:ns1=\"http://www.test.org/some-test-namespace\">\r\n" + + " <ns1:Attachment>\r\n" + + " <xop:Include xmlns:xop=\"http://www.w3.org/2004/08/xop/include\"" + + " href=\"ref-to-attachment%40some.domain.org\"/>\r\n" + + " </ns1:Attachment>\r\n" + + " </ns1:Test>\r\n" + + " </soap:Body>\r\n" + + "</soap:Envelope>"; + + final String content = "-----1234\r\n" + + "content-type: application/xop+xml; type=\"application/soap+xml\"\r\n" + + "\r\n" + + soapEnvelope + "\r\n" + + "-----1234\r\n" + + "Content-type: text/plain\r\n" + + "content-id: <ref-to-attachm...@some.domain.org>\r\n" + + "\r\n" + + "some text/plain content\r\n" + + "-----1234--\r\n"; + + final List<FileItem> fileItems = Util.parseUpload(upload, content.getBytes(StandardCharsets.US_ASCII), + "multipart/related; boundary=---1234;" + + " type=\"application/xop+xml\"; start-info=\"application/soap+xml\""); + assertEquals(2, fileItems.size()); + + final FileItem part1 = fileItems.get(0); + assertNull(part1.getFieldName()); + assertFalse(part1.isFormField()); + assertEquals(soapEnvelope, part1.getString()); + + final FileItem part2 = fileItems.get(1); + assertNull(part2.getFieldName()); + assertFalse(part2.isFormField()); + assertEquals("some text/plain content", part2.getString()); + assertEquals("text/plain", part2.getContentType()); + assertNull(part2.getName()); + } }