From fb332ce75e1e1949b199214ef12d3d30dbd81e3a Mon Sep 17 00:00:00 2001 From: mufasa1976 Date: Sun, 19 May 2024 16:32:28 +0200 Subject: [PATCH 1/6] added ability to use content-type: multipart/related --- commons-fileupload2-core/pom.xml | 2 +- .../core/AbstractRequestContext.java | 9 ++++ .../core/FileItemInputIteratorImpl.java | 18 ++++++- .../fileupload2/core/RequestContext.java | 6 +++ .../core/AbstractFileUploadTest.java | 50 +++++++++++++++++++ .../JakartaServletRequestContext.java | 9 ++++ .../JakartaServletRequestContext.java | 9 ++++ .../javax/JavaxServletRequestContext.java | 9 ++++ .../portlet/JavaxPortletRequestContext.java | 9 ++++ pom.xml | 4 ++ 10 files changed, 122 insertions(+), 3 deletions(-) diff --git a/commons-fileupload2-core/pom.xml b/commons-fileupload2-core/pom.xml index 5c79664cdb..b8ac85b6f0 100644 --- a/commons-fileupload2-core/pom.xml +++ b/commons-fileupload2-core/pom.xml @@ -42,7 +42,7 @@ 0.43 0.40 0.43 - 0.42 + 0.41 0.37 diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java index f6e96fae07..a73dfe507f 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java @@ -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 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. @@ -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(); + } } diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java index c01f2ae37e..576144e9dc 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java @@ -31,7 +31,6 @@ * The iterator returned by {@link AbstractFileUpload#getItemIterator(RequestContext)}. */ class FileItemInputIteratorImpl implements FileItemInputIterator { - /** * The file uploads processing utility. * @@ -96,6 +95,11 @@ class FileItemInputIteratorImpl implements FileItemInputIterator { */ private boolean eof; + /** + * is the Request of type multipart/related + */ + private final boolean multipartRelated; + /** * Constructs a new instance. * @@ -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(); } @@ -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) { diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/RequestContext.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/RequestContext.java index 1edb7b951f..6853c48a4c 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/RequestContext.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/RequestContext.java @@ -70,4 +70,10 @@ default Charset getCharset() throws UnsupportedCharsetException { */ InputStream getInputStream() throws IOException; + /** + * Is the Request of type multipart/related? + * + * @return the Request is of type multipart/related + */ + boolean isMultipartRelated(); } diff --git a/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java index ef80e45df4..830544eec2 100644 --- a/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java +++ b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java @@ -393,4 +393,54 @@ 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 = + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + ""; + + 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: \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()); + } } diff --git a/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java b/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java index 5b93c90669..8f1bbf0055 100644 --- a/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java +++ b/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java @@ -68,4 +68,13 @@ public InputStream getInputStream() throws IOException { return getRequest().getInputStream(); } + /** + * Is the Request of type multipart/related? + * + * @return the Request is of type multipart/related + */ + @Override + public boolean isMultipartRelated() { + return isMultipartRelated(getRequest().getContentType()); + } } diff --git a/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java b/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java index 2763700a27..704bbcd29c 100644 --- a/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java +++ b/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java @@ -68,4 +68,13 @@ public InputStream getInputStream() throws IOException { return getRequest().getInputStream(); } + /** + * Is the Request of type multipart/related? + * + * @return the Request is of type multipart/related + */ + @Override + public boolean isMultipartRelated() { + return isMultipartRelated(getRequest().getContentType()); + } } diff --git a/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java b/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java index e933b70cdb..bbf1863b68 100644 --- a/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java +++ b/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java @@ -68,4 +68,13 @@ public InputStream getInputStream() throws IOException { return getRequest().getInputStream(); } + /** + * Is the Request of type multipart/related? + * + * @return the Request is of type multipart/related + */ + @Override + public boolean isMultipartRelated() { + return isMultipartRelated(getRequest().getContentType()); + } } diff --git a/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java b/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java index 460a55e65c..36a733a580 100644 --- a/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java +++ b/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java @@ -68,4 +68,13 @@ public InputStream getInputStream() throws IOException { return getRequest().getPortletInputStream(); } + /** + * Is the Request of type multipart/related? + * + * @return the Request is of type multipart/related + */ + @Override + public boolean isMultipartRelated() { + return isMultipartRelated(getRequest().getContentType()); + } } diff --git a/pom.xml b/pom.xml index fcbcea9683..df92078308 100644 --- a/pom.xml +++ b/pom.xml @@ -201,6 +201,10 @@ Martin Grigorov mgrigorov@apache.org + + mufasa1976 + mufasa1976@coolstuff.software + From 148bfafc20f074cfa3ec3d8942ba810969c7770f Mon Sep 17 00:00:00 2001 From: mufasa1976 Date: Mon, 20 May 2024 14:57:42 +0200 Subject: [PATCH 2/6] added entry to src/changes/changes.xml; removed unnecessary paragraph at javadoc --- .../apache/commons/fileupload2/core/AbstractFileUploadTest.java | 1 - src/changes/changes.xml | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java index 830544eec2..a41ad7e40a 100644 --- a/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java +++ b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java @@ -396,7 +396,6 @@ public void testIE5MacBug() throws FileUploadException { /** * Test for multipart/related without any content-disposition Header. - *

* This kind of Content-Type is commonly used by SOAP-Requests with Attachments (MTOM) */ @Test diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 0549af2f4f..b7f551b757 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -48,6 +48,7 @@ The type attribute can be add,update,fix,remove. [site] Fix instantiation of DiskFileItemFactory in migration guide #273. [site] Update code example: Use IOUtils instead of Streams utils class. + handle multipart/related Requests without content-disposition header Bump org.apache.commons:commons-parent from 66 to 69 #283, #294. Bump commons-io:commons-io from 2.16.0 to 2.16.1 #297. From 96e3573bcd042faf93a61c91d65cca87f7e15b3d Mon Sep 17 00:00:00 2001 From: mufasa1976 Date: Mon, 20 May 2024 17:14:25 +0200 Subject: [PATCH 3/6] fixing checkstyle failures --- commons-fileupload2-core/pom.xml | 2 +- .../commons/fileupload2/core/AbstractRequestContext.java | 4 ++-- .../commons/fileupload2/core/FileItemInputIteratorImpl.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/commons-fileupload2-core/pom.xml b/commons-fileupload2-core/pom.xml index b8ac85b6f0..5c79664cdb 100644 --- a/commons-fileupload2-core/pom.xml +++ b/commons-fileupload2-core/pom.xml @@ -42,7 +42,7 @@ 0.43 0.40 0.43 - 0.41 + 0.42 0.37 diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java index a73dfe507f..4940bc47b3 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java @@ -24,7 +24,7 @@ public abstract class AbstractRequestContext implements RequestContext { /** - * the Content-Type Pattern for multipart/related Requests + * the Content-Type Pattern for multipart/related Requests. */ private static final Pattern MULTIPART_RELATED = Pattern.compile("^\\s*multipart/related.*", Pattern.CASE_INSENSITIVE); @@ -85,7 +85,7 @@ public String toString() { return String.format("%s [ContentLength=%s, ContentType=%s]", getClass().getSimpleName(), getContentLength(), getContentType()); } - protected boolean isMultipartRelated(String contentType) { + protected boolean isMultipartRelated(final String contentType) { return MULTIPART_RELATED.matcher(contentType).matches(); } } diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java index 576144e9dc..0475464a63 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java @@ -96,7 +96,7 @@ class FileItemInputIteratorImpl implements FileItemInputIterator { private boolean eof; /** - * is the Request of type multipart/related + * is the Request of type multipart/related. */ private final boolean multipartRelated; From 9945131bb1e9aba26d67878d9476e1a3e80a1e1a Mon Sep 17 00:00:00 2001 From: mufasa1976 Date: Mon, 20 May 2024 19:30:51 +0200 Subject: [PATCH 4/6] fixed findings of review --- .../commons/fileupload2/core/AbstractRequestContext.java | 7 ++++++- .../fileupload2/core/FileItemInputIteratorImpl.java | 2 +- .../apache/commons/fileupload2/core/RequestContext.java | 1 + .../jakarta/servlet5/JakartaServletRequestContext.java | 1 + .../jakarta/servlet6/JakartaServletRequestContext.java | 1 + .../fileupload2/javax/JavaxServletRequestContext.java | 1 + .../fileupload2/portlet/JavaxPortletRequestContext.java | 1 + 7 files changed, 12 insertions(+), 2 deletions(-) diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java index 4940bc47b3..682eaf4a66 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java @@ -24,7 +24,7 @@ public abstract class AbstractRequestContext implements RequestContext { /** - * the Content-Type Pattern for multipart/related Requests. + * The Content-Type Pattern for multipart/related Requests. */ private static final Pattern MULTIPART_RELATED = Pattern.compile("^\\s*multipart/related.*", Pattern.CASE_INSENSITIVE); @@ -85,6 +85,11 @@ public String toString() { return String.format("%s [ContentLength=%s, ContentType=%s]", getClass().getSimpleName(), getContentLength(), getContentType()); } + /** + * Test the given content-type Value if it is of type multipart/related. + * @param contentType content-type to be tested + * @return does the given content-type Value start with multipart/related + */ protected boolean isMultipartRelated(final String contentType) { return MULTIPART_RELATED.matcher(contentType).matches(); } diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java index 0475464a63..ba8041d760 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/FileItemInputIteratorImpl.java @@ -96,7 +96,7 @@ class FileItemInputIteratorImpl implements FileItemInputIterator { private boolean eof; /** - * is the Request of type multipart/related. + * Is the Request of type multipart/related. */ private final boolean multipartRelated; diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/RequestContext.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/RequestContext.java index 6853c48a4c..1684e8174b 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/RequestContext.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/RequestContext.java @@ -74,6 +74,7 @@ default Charset getCharset() throws UnsupportedCharsetException { * Is the Request of type multipart/related? * * @return the Request is of type multipart/related + * @since 2.0.0 */ boolean isMultipartRelated(); } diff --git a/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java b/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java index 8f1bbf0055..5f425d2317 100644 --- a/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java +++ b/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java @@ -72,6 +72,7 @@ public InputStream getInputStream() throws IOException { * Is the Request of type multipart/related? * * @return the Request is of type multipart/related + * @since 2.0.0 */ @Override public boolean isMultipartRelated() { diff --git a/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java b/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java index 704bbcd29c..f0f325a952 100644 --- a/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java +++ b/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java @@ -72,6 +72,7 @@ public InputStream getInputStream() throws IOException { * Is the Request of type multipart/related? * * @return the Request is of type multipart/related + * @since 2.0.0 */ @Override public boolean isMultipartRelated() { diff --git a/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java b/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java index bbf1863b68..804ec33e5e 100644 --- a/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java +++ b/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java @@ -72,6 +72,7 @@ public InputStream getInputStream() throws IOException { * Is the Request of type multipart/related? * * @return the Request is of type multipart/related + * @since 2.0.0 */ @Override public boolean isMultipartRelated() { diff --git a/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java b/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java index 36a733a580..1fb100de7d 100644 --- a/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java +++ b/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java @@ -72,6 +72,7 @@ public InputStream getInputStream() throws IOException { * Is the Request of type multipart/related? * * @return the Request is of type multipart/related + * @since 2.0.0 */ @Override public boolean isMultipartRelated() { From 8cc58ebac4704319ee11cd9edf39be86bd32a834 Mon Sep 17 00:00:00 2001 From: mufasa1976 Date: Mon, 20 May 2024 22:19:44 +0200 Subject: [PATCH 5/6] added MockRequestContextTest --- .../core/AbstractRequestContext.java | 12 +- .../core/MockRequestContextTest.java | 172 ++++++++++++++++++ .../JakartaServletRequestContext.java | 11 -- .../JakartaServletRequestContext.java | 11 -- .../javax/JavaxServletRequestContext.java | 11 -- .../portlet/JavaxPortletRequestContext.java | 11 -- 6 files changed, 179 insertions(+), 49 deletions(-) create mode 100644 commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/MockRequestContextTest.java diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java index 682eaf4a66..175ef2d27d 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractRequestContext.java @@ -86,11 +86,13 @@ public String toString() { } /** - * Test the given content-type Value if it is of type multipart/related. - * @param contentType content-type to be tested - * @return does the given content-type Value start with multipart/related + * Is the Request of type multipart/related? + * + * @return the Request is of type multipart/related + * @since 2.0.0 */ - protected boolean isMultipartRelated(final String contentType) { - return MULTIPART_RELATED.matcher(contentType).matches(); + @Override + public boolean isMultipartRelated() { + return MULTIPART_RELATED.matcher(getContentType()).matches(); } } diff --git a/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/MockRequestContextTest.java b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/MockRequestContextTest.java new file mode 100644 index 0000000000..4c79124fad --- /dev/null +++ b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/MockRequestContextTest.java @@ -0,0 +1,172 @@ +package org.apache.commons.fileupload2.core; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.charset.UnsupportedCharsetException; +import java.util.function.Function; +import java.util.function.LongSupplier; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests for {@link AbstractRequestContext} + */ +public class MockRequestContextTest { + /** + * Test if the content-length Value is numeric. + */ + @Test + public void getContentLengthByParsing() { + final RequestContext request = new MockRequestContext( + x -> "1234", + () -> 5678L, + "Request", + "US-ASCII", + "text/plain", + null); + assertEquals(1234L, request.getContentLength()); + } + + /** + * Test if the content-length Value is not numeric + * and the Default will be taken. + */ + @Test + public void getContentLengthDefaultBecauseOfInvalidNumber() { + final RequestContext request = new MockRequestContext( + x -> "not-a-number", + () -> 5678L, + "Request", + "US-ASCII", + "text/plain", + null); + assertEquals(5678L, request.getContentLength()); + } + + /** + * Test if the given character-encoding is a valid CharEncoding + */ + @Test + public void getCharset() { + final RequestContext request = new MockRequestContext( + x -> "1234", + () -> 5678L, + "Request", + "US-ASCII", + "text/plain", + null); + assertEquals(StandardCharsets.US_ASCII, request.getCharset()); + } + + /** + * Test if the given character-encoding is an invalid CharEncoding + * and leads to {@link UnsupportedCharsetException} + */ + @Test + public void getInvalidCharset() { + final RequestContext request = new MockRequestContext( + x -> "1234", + () -> 5678L, + "Request", + "invalid-charset", + "text/plain", + null); + assertThrows(UnsupportedCharsetException.class, request::getCharset); + } + + /** + * Test the toString() Output + */ + @Test + public void testToString() { + final RequestContext request = new MockRequestContext( + x -> "1234", + () -> 5678L, + "Request", + "US-ASCII", + "text/plain", + null); + assertEquals("MockRequestContext [ContentLength=1234, ContentType=text/plain]", request.toString()); + } + + /** + * Test if the content-type is multipart/related + */ + @Test + public void testIsMultipartRelated() { + final RequestContext request = new MockRequestContext( + x -> "1234", + () -> 5678L, + "Request", + "US-ASCII", + "multipart/related; boundary=---1234; type=\"application/xop+xml\"; start-info=\"application/soap+xml\"", + null); + assertTrue(request.isMultipartRelated()); + } + + /** + * Test if the content-type is not multipart/related + */ + @Test + public void testIsNotMultipartRelated() { + final RequestContext request = new MockRequestContext( + x -> "1234", + () -> 5678L, + "Request", + "US-ASCII", + "text/plain", + null); + assertFalse(request.isMultipartRelated()); + } + + private static final class MockRequestContext extends AbstractRequestContext { + private final String characterEncoding; + private final String contentType; + private final InputStream inputStream; + + private MockRequestContext(Function contentLengthString, + LongSupplier contentLengthDefault, + Object request, + String characterEncoding, + String contentType, + InputStream inputStream) { + super(contentLengthString, contentLengthDefault, request); + this.characterEncoding = characterEncoding; + this.contentType = contentType; + this.inputStream = inputStream; + } + + /** + * Gets the character encoding for the request. + * + * @return The character encoding for the request. + */ + @Override + public String getCharacterEncoding() { + return characterEncoding; + } + + /** + * Gets the content type of the request. + * + * @return The content type of the request. + */ + @Override + public String getContentType() { + return contentType; + } + + /** + * Gets the input stream for the request. + * + * @return The input stream for the request. + */ + @Override + public InputStream getInputStream() { + return inputStream; + } + } +} diff --git a/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java b/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java index 5f425d2317..086aedbe09 100644 --- a/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java +++ b/commons-fileupload2-jakarta-servlet5/src/main/java/org/apache/commons/fileupload2/jakarta/servlet5/JakartaServletRequestContext.java @@ -67,15 +67,4 @@ public String getContentType() { public InputStream getInputStream() throws IOException { return getRequest().getInputStream(); } - - /** - * Is the Request of type multipart/related? - * - * @return the Request is of type multipart/related - * @since 2.0.0 - */ - @Override - public boolean isMultipartRelated() { - return isMultipartRelated(getRequest().getContentType()); - } } diff --git a/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java b/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java index f0f325a952..2984141280 100644 --- a/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java +++ b/commons-fileupload2-jakarta-servlet6/src/main/java/org/apache/commons/fileupload2/jakarta/servlet6/JakartaServletRequestContext.java @@ -67,15 +67,4 @@ public String getContentType() { public InputStream getInputStream() throws IOException { return getRequest().getInputStream(); } - - /** - * Is the Request of type multipart/related? - * - * @return the Request is of type multipart/related - * @since 2.0.0 - */ - @Override - public boolean isMultipartRelated() { - return isMultipartRelated(getRequest().getContentType()); - } } diff --git a/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java b/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java index 804ec33e5e..9cc2af3bfe 100644 --- a/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java +++ b/commons-fileupload2-javax/src/main/java/org/apache/commons/fileupload2/javax/JavaxServletRequestContext.java @@ -67,15 +67,4 @@ public String getContentType() { public InputStream getInputStream() throws IOException { return getRequest().getInputStream(); } - - /** - * Is the Request of type multipart/related? - * - * @return the Request is of type multipart/related - * @since 2.0.0 - */ - @Override - public boolean isMultipartRelated() { - return isMultipartRelated(getRequest().getContentType()); - } } diff --git a/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java b/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java index 1fb100de7d..671b488c46 100644 --- a/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java +++ b/commons-fileupload2-portlet/src/main/java/org/apache/commons/fileupload2/portlet/JavaxPortletRequestContext.java @@ -67,15 +67,4 @@ public String getContentType() { public InputStream getInputStream() throws IOException { return getRequest().getPortletInputStream(); } - - /** - * Is the Request of type multipart/related? - * - * @return the Request is of type multipart/related - * @since 2.0.0 - */ - @Override - public boolean isMultipartRelated() { - return isMultipartRelated(getRequest().getContentType()); - } } From 76a84fa8e99ec3ceb24b1c3115f56b4daa81e359 Mon Sep 17 00:00:00 2001 From: mufasa1976 Date: Mon, 20 May 2024 22:21:01 +0200 Subject: [PATCH 6/6] added License Header --- .../core/MockRequestContextTest.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/MockRequestContextTest.java b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/MockRequestContextTest.java index 4c79124fad..e8a34f82dc 100644 --- a/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/MockRequestContextTest.java +++ b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/MockRequestContextTest.java @@ -1,6 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.commons.fileupload2.core; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.io.InputStream;