Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion commons-fileupload2-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<commons.jacoco.instructionRatio>0.43</commons.jacoco.instructionRatio>
<commons.jacoco.methodRatio>0.40</commons.jacoco.methodRatio>
<commons.jacoco.branchRatio>0.43</commons.jacoco.branchRatio>
<commons.jacoco.lineRatio>0.42</commons.jacoco.lineRatio>
<commons.jacoco.lineRatio>0.41</commons.jacoco.lineRatio>
<commons.jacoco.complexityRatio>0.37</commons.jacoco.complexityRatio>
</properties>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@
import java.util.Objects;
import java.util.function.Function;
import java.util.function.LongSupplier;
import java.util.regex.Pattern;

public abstract class AbstractRequestContext<T> implements RequestContext {
/**
* the Content-Type Pattern for multipart/related Requests
*/
private static final Pattern MULTIPART_RELATED =
Pattern.compile("^\\s*multipart/related.*", Pattern.CASE_INSENSITIVE);

/**
* Supplies the content length default.
Expand Down Expand Up @@ -79,4 +85,7 @@ public String toString() {
return String.format("%s [ContentLength=%s, ContentType=%s]", getClass().getSimpleName(), getContentLength(), getContentType());
}

protected boolean isMultipartRelated(String contentType) {
return MULTIPART_RELATED.matcher(contentType).matches();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
* The iterator returned by {@link AbstractFileUpload#getItemIterator(RequestContext)}.
*/
class FileItemInputIteratorImpl implements FileItemInputIterator {

/**
* The file uploads processing utility.
*
Expand Down Expand Up @@ -96,6 +95,11 @@ class FileItemInputIteratorImpl implements FileItemInputIterator {
*/
private boolean eof;

/**
* is the Request of type <code>multipart/related</code>
*/
private final boolean multipartRelated;

/**
* Constructs a new instance.
*
Expand All @@ -109,6 +113,7 @@ class FileItemInputIteratorImpl implements FileItemInputIterator {
this.sizeMax = fileUploadBase.getSizeMax();
this.fileSizeMax = fileUploadBase.getFileSizeMax();
this.requestContext = Objects.requireNonNull(requestContext, "requestContext");
this.multipartRelated = this.requestContext.isMultipartRelated();
this.skipPreamble = true;
findNextItem();
}
Expand Down Expand Up @@ -147,7 +152,16 @@ private boolean findNextItem() throws FileUploadException, IOException {
continue;
}
final var headers = fileUpload.getParsedHeaders(multi.readHeaders());
if (currentFieldName == null) {
if (multipartRelated) {
currentFieldName = "";
currentItem = new FileItemInputImpl(
this, null, null, headers.getHeader(AbstractFileUpload.CONTENT_TYPE),
false, getContentLength(headers));
currentItem.setHeaders(headers);
progressNotifier.noteItem();
itemValid = true;
return true;
} else if (currentFieldName == null) {
// We're parsing the outer multipart
final var fieldName = fileUpload.getFieldName(headers);
if (fieldName != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,10 @@ default Charset getCharset() throws UnsupportedCharsetException {
*/
InputStream getInputStream() throws IOException;

/**
* Is the Request of type <code>multipart/related</code>?
*
* @return the Request is of type <code>multipart/related</code>
*/
boolean isMultipartRelated();
}
Original file line number Diff line number Diff line change
Expand Up @@ -393,4 +393,53 @@ public void testIE5MacBug() throws FileUploadException {
assertTrue(field2.isFormField());
assertEquals("fieldValue2", field2.getString());
}

/**
* 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 testMultipleRelated() throws Exception {
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 text =
"-----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-attachment@some.domain.org>\r\n" +
"\r\n" +
"some text/plain content\r\n" +
"-----1234--\r\n";

final var bytes = text.getBytes(StandardCharsets.US_ASCII);
final var fileItems = parseUpload(upload, bytes, "multipart/related; boundary=---1234;" +
" type=\"application/xop+xml\"; start-info=\"application/soap+xml\"");
assertEquals(2, fileItems.size());

final var part1 = fileItems.get(0);
assertNull(part1.getFieldName());
assertFalse(part1.isFormField());
assertEquals(soapEnvelope, part1.getString());

final var 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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,13 @@ public InputStream getInputStream() throws IOException {
return getRequest().getInputStream();
}

/**
* Is the Request of type <code>multipart/related</code>?
*
* @return the Request is of type <code>multipart/related</code>
*/
@Override
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add since Javadoc tag.

public boolean isMultipartRelated() {
return isMultipartRelated(getRequest().getContentType());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,13 @@ public InputStream getInputStream() throws IOException {
return getRequest().getInputStream();
}

/**
* Is the Request of type <code>multipart/related</code>?
*
* @return the Request is of type <code>multipart/related</code>
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add since Javadoc tag.

@Override
public boolean isMultipartRelated() {
return isMultipartRelated(getRequest().getContentType());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,13 @@ public InputStream getInputStream() throws IOException {
return getRequest().getInputStream();
}

/**
* Is the Request of type <code>multipart/related</code>?
*
* @return the Request is of type <code>multipart/related</code>
*/
@Override
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add since Javadoc tag.

public boolean isMultipartRelated() {
return isMultipartRelated(getRequest().getContentType());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,13 @@ public InputStream getInputStream() throws IOException {
return getRequest().getPortletInputStream();
}

/**
* Is the Request of type <code>multipart/related</code>?
*
* @return the Request is of type <code>multipart/related</code>
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add since Javadoc tag.

@Override
public boolean isMultipartRelated() {
return isMultipartRelated(getRequest().getContentType());
}
}
4 changes: 4 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@
<name>Martin Grigorov</name>
<email>mgrigorov@apache.org</email>
</contributor>
<contributor>
<name>mufasa1976</name>
<email>mufasa1976@coolstuff.software</email>
</contributor>
</contributors>

<scm>
Expand Down
1 change: 1 addition & 0 deletions src/changes/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ The <action> type attribute can be add,update,fix,remove.
<action dev="ggregory" type="fix" due-to="Gregor Dschung">[site] Fix instantiation of DiskFileItemFactory in migration guide #273.</action>
<action issue="FILEUPLOAD-355" dev="ggregory" type="fix" due-to="Ana, Gary Gregory">[site] Update code example: Use IOUtils instead of Streams utils class.</action>
<!-- ADD -->
<action dev="mufasa1976" type="add">handle multipart/related Requests without content-disposition header</action>
<!-- UDPATE -->
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 66 to 69 #283, #294.</action>
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump commons-io:commons-io from 2.16.0 to 2.16.1 #297.</action>
Expand Down