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());
+    }
 }

Reply via email to