You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2019/12/06 19:42:58 UTC
[tomcat] 03/09: Merge in FileUpload changes to 2317552 (2019-12-06,
2.0-SNAPSHOT)
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit ee7666aab2cf4e12f0eadc9864b742866a4061a1
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Dec 6 15:30:48 2019 +0000
Merge in FileUpload changes to 2317552 (2019-12-06, 2.0-SNAPSHOT)
---
MERGE.txt | 2 +-
java/org/apache/catalina/connector/Request.java | 6 +-
.../util/http/fileupload/FileItemIterator.java | 49 +-
.../util/http/fileupload/FileUploadBase.java | 702 +--------------------
.../util/http/fileupload/MultipartStream.java | 10 +-
.../util/http/fileupload/disk/DiskFileItem.java | 3 +-
.../http/fileupload/impl/FileItemIteratorImpl.java | 339 ++++++++++
.../http/fileupload/impl/FileItemStreamImpl.java | 222 +++++++
.../impl/FileSizeLimitExceededException.java | 94 +++
.../fileupload/impl/FileUploadIOException.java | 63 ++
.../fileupload/impl/IOFileUploadException.java | 62 ++
.../impl/InvalidContentTypeException.java | 62 ++
.../util/http/fileupload/impl/SizeException.java | 75 +++
.../impl/SizeLimitExceededException.java | 43 ++
webapps/docs/changelog.xml | 4 +
15 files changed, 1032 insertions(+), 704 deletions(-)
diff --git a/MERGE.txt b/MERGE.txt
index b4bd507..893ac89 100644
--- a/MERGE.txt
+++ b/MERGE.txt
@@ -51,7 +51,7 @@ FileUpload
Sub-tree:
src/main/java/org/apache/commons/fileupload2
The SHA1 ID for the most recent commit to be merged to Tomcat is:
-9958ea2426ec5682a7c929a13372c04426ee3818 (2019-08-01)
+2317552993fd5180a84083d599b8cbdb05a07bab (2019-12-06)
Note: Tomcat's copy of fileupload also includes classes copied manually from
Commons IO.
diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java
index 61dea52..3c04c1c 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -105,10 +105,10 @@ import org.apache.tomcat.util.http.Parameters.FailReason;
import org.apache.tomcat.util.http.ServerCookie;
import org.apache.tomcat.util.http.ServerCookies;
import org.apache.tomcat.util.http.fileupload.FileItem;
-import org.apache.tomcat.util.http.fileupload.FileUploadBase;
-import org.apache.tomcat.util.http.fileupload.FileUploadBase.InvalidContentTypeException;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
+import org.apache.tomcat.util.http.fileupload.impl.InvalidContentTypeException;
+import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
import org.apache.tomcat.util.http.parser.AcceptLanguage;
@@ -2906,7 +2906,7 @@ public class Request implements HttpServletRequest {
} catch (InvalidContentTypeException e) {
parameters.setParseFailedReason(FailReason.INVALID_CONTENT_TYPE);
partsParseException = new ServletException(e);
- } catch (FileUploadBase.SizeException e) {
+ } catch (SizeLimitExceededException e) {
parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);
checkSwallowInput();
partsParseException = new IllegalStateException(e);
diff --git a/java/org/apache/tomcat/util/http/fileupload/FileItemIterator.java b/java/org/apache/tomcat/util/http/fileupload/FileItemIterator.java
index 4f331ad..9665312 100644
--- a/java/org/apache/tomcat/util/http/fileupload/FileItemIterator.java
+++ b/java/org/apache/tomcat/util/http/fileupload/FileItemIterator.java
@@ -17,12 +17,56 @@
package org.apache.tomcat.util.http.fileupload;
import java.io.IOException;
+import java.util.List;
+
+import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
+import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException;
/**
* An iterator, as returned by
* {@link FileUploadBase#getItemIterator(RequestContext)}.
*/
public interface FileItemIterator {
+ /** Returns the maximum size of a single file. An {@link FileSizeLimitExceededException}
+ * will be thrown, if there is an uploaded file, which is exceeding this value.
+ * By default, this value will be copied from the {@link FileUploadBase#getFileSizeMax()
+ * FileUploadBase} object, however, the user may replace the default value with a
+ * request specific value by invoking {@link #setFileSizeMax(long)} on this object.
+ * @return The maximum size of a single, uploaded file. The value -1 indicates "unlimited".
+ */
+ public long getFileSizeMax();
+
+ /** Sets the maximum size of a single file. An {@link FileSizeLimitExceededException}
+ * will be thrown, if there is an uploaded file, which is exceeding this value.
+ * By default, this value will be copied from the {@link FileUploadBase#getFileSizeMax()
+ * FileUploadBase} object, however, the user may replace the default value with a
+ * request specific value by invoking {@link #setFileSizeMax(long)} on this object, so
+ * there is no need to configure it here.
+ * <em>Note:</em>Changing this value doesn't affect files, that have already been uploaded.
+ * @param pFileSizeMax The maximum size of a single, uploaded file. The value -1 indicates "unlimited".
+ */
+ public void setFileSizeMax(long pFileSizeMax);
+
+ /** Returns the maximum size of the complete HTTP request. A {@link SizeLimitExceededException}
+ * will be thrown, if the HTTP request will exceed this value.
+ * By default, this value will be copied from the {@link FileUploadBase#getSizeMax()
+ * FileUploadBase} object, however, the user may replace the default value with a
+ * request specific value by invoking {@link #setSizeMax(long)} on this object.
+ * @return The maximum size of the complete HTTP requqest. The value -1 indicates "unlimited".
+ */
+ public long getSizeMax();
+
+ /** Returns the maximum size of the complete HTTP request. A {@link SizeLimitExceededException}
+ * will be thrown, if the HTTP request will exceed this value.
+ * By default, this value will be copied from the {@link FileUploadBase#getSizeMax()
+ * FileUploadBase} object, however, the user may replace the default value with a
+ * request specific value by invoking {@link #setSizeMax(long)} on this object.
+ * <em>Note:</em> Setting the maximum size on this object will work only, if the iterator is not
+ * yet initialized. In other words: If the methods {@link #hasNext()}, {@link #next()} have not
+ * yet been invoked.
+ * @param pSizeMax The maximum size of the complete HTTP request. The value -1 indicates "unlimited".
+ */
+ public void setSizeMax(long pSizeMax);
/**
* Returns, whether another instance of {@link FileItemStream}
@@ -34,7 +78,7 @@ public interface FileItemIterator {
* @return True, if one or more additional file items
* are available, otherwise false.
*/
- boolean hasNext() throws FileUploadException, IOException;
+ public boolean hasNext() throws FileUploadException, IOException;
/**
* Returns the next available {@link FileItemStream}.
@@ -47,6 +91,7 @@ public interface FileItemIterator {
* @return FileItemStream instance, which provides
* access to the next file item.
*/
- FileItemStream next() throws FileUploadException, IOException;
+ public FileItemStream next() throws FileUploadException, IOException;
+ public List<FileItem> getFileItems() throws FileUploadException, IOException;
}
diff --git a/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java b/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
index 486434a..4a68be2 100644
--- a/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
+++ b/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
@@ -17,19 +17,18 @@
package org.apache.tomcat.util.http.fileupload;
import java.io.IOException;
-import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.NoSuchElementException;
-import org.apache.tomcat.util.http.fileupload.MultipartStream.ItemInputStream;
-import org.apache.tomcat.util.http.fileupload.util.Closeable;
+import org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl;
+import org.apache.tomcat.util.http.fileupload.impl.FileItemStreamImpl;
+import org.apache.tomcat.util.http.fileupload.impl.FileUploadIOException;
+import org.apache.tomcat.util.http.fileupload.impl.IOFileUploadException;
import org.apache.tomcat.util.http.fileupload.util.FileItemHeadersImpl;
-import org.apache.tomcat.util.http.fileupload.util.LimitedInputStream;
import org.apache.tomcat.util.http.fileupload.util.Streams;
@@ -253,7 +252,7 @@ public abstract class FileUploadBase {
public FileItemIterator getItemIterator(RequestContext ctx)
throws FileUploadException, IOException {
try {
- return new FileItemIteratorImpl(ctx);
+ return new FileItemIteratorImpl(this, ctx);
} catch (FileUploadIOException e) {
// unwrap encapsulated SizeException
throw (FileUploadException) e.getCause();
@@ -286,7 +285,7 @@ public abstract class FileUploadBase {
while (iter.hasNext()) {
final FileItemStream item = iter.next();
// Don't use getName() here to prevent an InvalidFileNameException.
- final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name;
+ final String fileName = ((FileItemStreamImpl) item).getName();
FileItem fileItem = fac.createItem(item.getFieldName(), item.getContentType(),
item.isFormField(), fileName);
items.add(fileItem);
@@ -363,7 +362,7 @@ public abstract class FileUploadBase {
*
* @return The boundary, as a byte array.
*/
- protected byte[] getBoundary(String contentType) {
+ public byte[] getBoundary(String contentType) {
ParameterParser parser = new ParameterParser();
parser.setLowerCaseNames(true);
// Parameter parser can handle null input
@@ -387,7 +386,7 @@ public abstract class FileUploadBase {
*
* @return The file name for the current <code>encapsulation</code>.
*/
- protected String getFileName(FileItemHeaders headers) {
+ public String getFileName(FileItemHeaders headers) {
return getFileName(headers.getHeader(CONTENT_DISPOSITION));
}
@@ -429,7 +428,7 @@ public abstract class FileUploadBase {
*
* @return The field name for the current <code>encapsulation</code>.
*/
- protected String getFieldName(FileItemHeaders headers) {
+ public String getFieldName(FileItemHeaders headers) {
return getFieldName(headers.getHeader(CONTENT_DISPOSITION));
}
@@ -467,7 +466,7 @@ public abstract class FileUploadBase {
*
* @return A <code>Map</code> containing the parsed HTTP request headers.
*/
- protected FileItemHeaders getParsedHeaders(String headerPart) {
+ public FileItemHeaders getParsedHeaders(String headerPart) {
final int len = headerPart.length();
FileItemHeadersImpl headers = newFileItemHeaders();
int start = 0;
@@ -549,687 +548,6 @@ public abstract class FileUploadBase {
}
/**
- * The iterator, which is returned by
- * {@link FileUploadBase#getItemIterator(RequestContext)}.
- */
- private class FileItemIteratorImpl implements FileItemIterator {
-
- /**
- * Default implementation of {@link FileItemStream}.
- */
- class FileItemStreamImpl implements FileItemStream {
-
- /**
- * The file items content type.
- */
- private final String contentType;
-
- /**
- * The file items field name.
- */
- private final String fieldName;
-
- /**
- * The file items file name.
- */
- private final String name;
-
- /**
- * Whether the file item is a form field.
- */
- private final boolean formField;
-
- /**
- * The file items input stream.
- */
- private final InputStream stream;
-
- /**
- * The headers, if any.
- */
- private FileItemHeaders headers;
-
- /**
- * Creates a new instance.
- *
- * @param pName The items file name, or null.
- * @param pFieldName The items field name.
- * @param pContentType The items content type, or null.
- * @param pFormField Whether the item is a form field.
- * @param pContentLength The items content length, if known, or -1
- * @throws IOException Creating the file item failed.
- */
- FileItemStreamImpl(String pName, String pFieldName,
- String pContentType, boolean pFormField,
- long pContentLength) throws IOException {
- name = pName;
- fieldName = pFieldName;
- contentType = pContentType;
- formField = pFormField;
- if (fileSizeMax != -1) { // Check if limit is already exceeded
- if (pContentLength != -1
- && pContentLength > fileSizeMax) {
- FileSizeLimitExceededException e =
- new FileSizeLimitExceededException(
- String.format("The field %s exceeds its maximum permitted size of %s bytes.",
- fieldName, Long.valueOf(fileSizeMax)),
- pContentLength, fileSizeMax);
- e.setFileName(pName);
- e.setFieldName(pFieldName);
- throw new FileUploadIOException(e);
- }
- }
- // OK to construct stream now
- final ItemInputStream itemStream = multi.newInputStream();
- InputStream istream = itemStream;
- if (fileSizeMax != -1) {
- istream = new LimitedInputStream(istream, fileSizeMax) {
- @Override
- protected void raiseError(long pSizeMax, long pCount)
- throws IOException {
- itemStream.close(true);
- FileSizeLimitExceededException e =
- new FileSizeLimitExceededException(
- String.format("The field %s exceeds its maximum permitted size of %s bytes.",
- fieldName, Long.valueOf(pSizeMax)),
- pCount, pSizeMax);
- e.setFieldName(fieldName);
- e.setFileName(name);
- throw new FileUploadIOException(e);
- }
- };
- }
- stream = istream;
- }
-
- /**
- * Returns the items content type, or null.
- *
- * @return Content type, if known, or null.
- */
- @Override
- public String getContentType() {
- return contentType;
- }
-
- /**
- * Returns the items field name.
- *
- * @return Field name.
- */
- @Override
- public String getFieldName() {
- return fieldName;
- }
-
- /**
- * Returns the items file name.
- *
- * @return File name, if known, or null.
- * @throws InvalidFileNameException The file name contains a NUL character,
- * which might be an indicator of a security attack. If you intend to
- * use the file name anyways, catch the exception and use
- * InvalidFileNameException#getName().
- */
- @Override
- public String getName() {
- return Streams.checkFileName(name);
- }
-
- /**
- * Returns, whether this is a form field.
- *
- * @return True, if the item is a form field,
- * otherwise false.
- */
- @Override
- public boolean isFormField() {
- return formField;
- }
-
- /**
- * Returns an input stream, which may be used to
- * read the items contents.
- *
- * @return Opened input stream.
- * @throws IOException An I/O error occurred.
- */
- @Override
- public InputStream openStream() throws IOException {
- if (((Closeable) stream).isClosed()) {
- throw new FileItemStream.ItemSkippedException();
- }
- return stream;
- }
-
- /**
- * Closes the file item.
- *
- * @throws IOException An I/O error occurred.
- */
- void close() throws IOException {
- stream.close();
- }
-
- /**
- * Returns the file item headers.
- *
- * @return The items header object
- */
- @Override
- public FileItemHeaders getHeaders() {
- return headers;
- }
-
- /**
- * Sets the file item headers.
- *
- * @param pHeaders The items header object
- */
- @Override
- public void setHeaders(FileItemHeaders pHeaders) {
- headers = pHeaders;
- }
-
- }
-
- /**
- * The multi part stream to process.
- */
- private final MultipartStream multi;
-
- /**
- * The notifier, which used for triggering the
- * {@link ProgressListener}.
- */
- private final MultipartStream.ProgressNotifier notifier;
-
- /**
- * The boundary, which separates the various parts.
- */
- private final byte[] boundary;
-
- /**
- * The item, which we currently process.
- */
- private FileItemStreamImpl currentItem;
-
- /**
- * The current items field name.
- */
- private String currentFieldName;
-
- /**
- * Whether we are currently skipping the preamble.
- */
- private boolean skipPreamble;
-
- /**
- * Whether the current item may still be read.
- */
- private boolean itemValid;
-
- /**
- * Whether we have seen the end of the file.
- */
- private boolean eof;
-
- /**
- * Creates a new instance.
- *
- * @param ctx The request context.
- * @throws FileUploadException An error occurred while
- * parsing the request.
- * @throws IOException An I/O error occurred.
- */
- FileItemIteratorImpl(RequestContext ctx)
- throws FileUploadException, IOException {
- if (ctx == null) {
- throw new NullPointerException("ctx parameter");
- }
-
- String contentType = ctx.getContentType();
- if ((null == contentType)
- || (!contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART))) {
- throw new InvalidContentTypeException(String.format(
- "the request doesn't contain a %s or %s stream, content type header is %s",
- MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType));
- }
-
-
- final long requestSize = ((UploadContext) ctx).contentLength();
-
- InputStream input; // N.B. this is eventually closed in MultipartStream processing
- if (sizeMax >= 0) {
- if (requestSize != -1 && requestSize > sizeMax) {
- throw new SizeLimitExceededException(String.format(
- "the request was rejected because its size (%s) exceeds the configured maximum (%s)",
- Long.valueOf(requestSize), Long.valueOf(sizeMax)),
- requestSize, sizeMax);
- }
- // N.B. this is eventually closed in MultipartStream processing
- input = new LimitedInputStream(ctx.getInputStream(), sizeMax) {
- @Override
- protected void raiseError(long pSizeMax, long pCount)
- throws IOException {
- FileUploadException ex = new SizeLimitExceededException(
- String.format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",
- Long.valueOf(pCount), Long.valueOf(pSizeMax)),
- pCount, pSizeMax);
- throw new FileUploadIOException(ex);
- }
- };
- } else {
- input = ctx.getInputStream();
- }
-
- String charEncoding = headerEncoding;
- if (charEncoding == null) {
- charEncoding = ctx.getCharacterEncoding();
- }
-
- boundary = getBoundary(contentType);
- if (boundary == null) {
- IOUtils.closeQuietly(input); // avoid possible resource leak
- throw new FileUploadException("the request was rejected because no multipart boundary was found");
- }
-
- notifier = new MultipartStream.ProgressNotifier(listener, requestSize);
- try {
- multi = new MultipartStream(input, boundary, notifier);
- } catch (IllegalArgumentException iae) {
- IOUtils.closeQuietly(input); // avoid possible resource leak
- throw new InvalidContentTypeException(
- String.format("The boundary specified in the %s header is too long", CONTENT_TYPE), iae);
- }
- multi.setHeaderEncoding(charEncoding);
-
- skipPreamble = true;
- findNextItem();
- }
-
- /**
- * Called for finding the next item, if any.
- *
- * @return True, if an next item was found, otherwise false.
- * @throws IOException An I/O error occurred.
- */
- private boolean findNextItem() throws IOException {
- if (eof) {
- return false;
- }
- if (currentItem != null) {
- currentItem.close();
- currentItem = null;
- }
- for (;;) {
- boolean nextPart;
- if (skipPreamble) {
- nextPart = multi.skipPreamble();
- } else {
- nextPart = multi.readBoundary();
- }
- if (!nextPart) {
- if (currentFieldName == null) {
- // Outer multipart terminated -> No more data
- eof = true;
- return false;
- }
- // Inner multipart terminated -> Return to parsing the outer
- multi.setBoundary(boundary);
- currentFieldName = null;
- continue;
- }
- FileItemHeaders headers = getParsedHeaders(multi.readHeaders());
- if (currentFieldName == null) {
- // We're parsing the outer multipart
- String fieldName = getFieldName(headers);
- if (fieldName != null) {
- String subContentType = headers.getHeader(CONTENT_TYPE);
- if (subContentType != null
- && subContentType.toLowerCase(Locale.ENGLISH)
- .startsWith(MULTIPART_MIXED)) {
- currentFieldName = fieldName;
- // Multiple files associated with this field name
- byte[] subBoundary = getBoundary(subContentType);
- multi.setBoundary(subBoundary);
- skipPreamble = true;
- continue;
- }
- String fileName = getFileName(headers);
- currentItem = new FileItemStreamImpl(fileName,
- fieldName, headers.getHeader(CONTENT_TYPE),
- fileName == null, getContentLength(headers));
- currentItem.setHeaders(headers);
- notifier.noteItem();
- itemValid = true;
- return true;
- }
- } else {
- String fileName = getFileName(headers);
- if (fileName != null) {
- currentItem = new FileItemStreamImpl(fileName,
- currentFieldName,
- headers.getHeader(CONTENT_TYPE),
- false, getContentLength(headers));
- currentItem.setHeaders(headers);
- notifier.noteItem();
- itemValid = true;
- return true;
- }
- }
- multi.discardBodyData();
- }
- }
-
- private long getContentLength(FileItemHeaders pHeaders) {
- try {
- return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH));
- } catch (Exception e) {
- return -1;
- }
- }
-
- /**
- * Returns, whether another instance of {@link FileItemStream}
- * is available.
- *
- * @throws FileUploadException Parsing or processing the
- * file item failed.
- * @throws IOException Reading the file item failed.
- * @return True, if one or more additional file items
- * are available, otherwise false.
- */
- @Override
- public boolean hasNext() throws FileUploadException, IOException {
- if (eof) {
- return false;
- }
- if (itemValid) {
- return true;
- }
- try {
- return findNextItem();
- } catch (FileUploadIOException e) {
- // unwrap encapsulated SizeException
- throw (FileUploadException) e.getCause();
- }
- }
-
- /**
- * Returns the next available {@link FileItemStream}.
- *
- * @throws java.util.NoSuchElementException No more items are
- * available. Use {@link #hasNext()} to prevent this exception.
- * @throws FileUploadException Parsing or processing the
- * file item failed.
- * @throws IOException Reading the file item failed.
- * @return FileItemStream instance, which provides
- * access to the next file item.
- */
- @Override
- public FileItemStream next() throws FileUploadException, IOException {
- if (eof || (!itemValid && !hasNext())) {
- throw new NoSuchElementException();
- }
- itemValid = false;
- return currentItem;
- }
-
- }
-
- /**
- * This exception is thrown for hiding an inner
- * {@link FileUploadException} in an {@link IOException}.
- */
- public static class FileUploadIOException extends IOException {
-
- private static final long serialVersionUID = -3082868232248803474L;
-
- public FileUploadIOException() {
- super();
- }
-
- public FileUploadIOException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public FileUploadIOException(String message) {
- super(message);
- }
-
- public FileUploadIOException(Throwable cause) {
- super(cause);
- }
- }
-
- /**
- * Thrown to indicate that the request is not a multipart request.
- */
- public static class InvalidContentTypeException
- extends FileUploadException {
-
- /**
- * The exceptions UID, for serializing an instance.
- */
- private static final long serialVersionUID = -9073026332015646668L;
-
- /**
- * Constructs a <code>InvalidContentTypeException</code> with no
- * detail message.
- */
- public InvalidContentTypeException() {
- super();
- }
-
- /**
- * Constructs an <code>InvalidContentTypeException</code> with
- * the specified detail message.
- *
- * @param message The detail message.
- */
- public InvalidContentTypeException(String message) {
- super(message);
- }
-
- /**
- * Constructs an <code>InvalidContentTypeException</code> with
- * the specified detail message and cause.
- *
- * @param msg The detail message.
- * @param cause the original cause
- *
- * @since 1.3.1
- */
- public InvalidContentTypeException(String msg, Throwable cause) {
- super(msg, cause);
- }
- }
-
- /**
- * Thrown to indicate an IOException.
- */
- public static class IOFileUploadException extends FileUploadException {
-
- private static final long serialVersionUID = -5858565745868986701L;
-
- public IOFileUploadException() {
- super();
- }
-
- public IOFileUploadException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public IOFileUploadException(String message) {
- super(message);
- }
-
- public IOFileUploadException(Throwable cause) {
- super(cause);
- }
- }
-
- /**
- * This exception is thrown, if a requests permitted size
- * is exceeded.
- */
- public abstract static class SizeException extends FileUploadException {
-
- /**
- * Serial version UID, being used, if serialized.
- */
- private static final long serialVersionUID = -8776225574705254126L;
-
- /**
- * The actual size of the request.
- */
- private final long actual;
-
- /**
- * The maximum permitted size of the request.
- */
- private final long permitted;
-
- /**
- * Creates a new instance.
- *
- * @param message The detail message.
- * @param actual The actual number of bytes in the request.
- * @param permitted The requests size limit, in bytes.
- */
- protected SizeException(String message, long actual, long permitted) {
- super(message);
- this.actual = actual;
- this.permitted = permitted;
- }
-
- /**
- * Retrieves the actual size of the request.
- *
- * @return The actual size of the request.
- * @since 1.3
- */
- public long getActualSize() {
- return actual;
- }
-
- /**
- * Retrieves the permitted size of the request.
- *
- * @return The permitted size of the request.
- * @since 1.3
- */
- public long getPermittedSize() {
- return permitted;
- }
-
- }
-
- /**
- * Thrown to indicate that the request size exceeds the configured maximum.
- */
- public static class SizeLimitExceededException
- extends SizeException {
-
- /**
- * The exceptions UID, for serializing an instance.
- */
- private static final long serialVersionUID = -2474893167098052828L;
-
- /**
- * Constructs a <code>SizeExceededException</code> with
- * the specified detail message, and actual and permitted sizes.
- *
- * @param message The detail message.
- * @param actual The actual request size.
- * @param permitted The maximum permitted request size.
- */
- public SizeLimitExceededException(String message, long actual,
- long permitted) {
- super(message, actual, permitted);
- }
-
- }
-
- /**
- * Thrown to indicate that A files size exceeds the configured maximum.
- */
- public static class FileSizeLimitExceededException
- extends SizeException {
-
- /**
- * The exceptions UID, for serializing an instance.
- */
- private static final long serialVersionUID = 8150776562029630058L;
-
- /**
- * File name of the item, which caused the exception.
- */
- private String fileName;
-
- /**
- * Field name of the item, which caused the exception.
- */
- private String fieldName;
-
- /**
- * Constructs a <code>SizeExceededException</code> with
- * the specified detail message, and actual and permitted sizes.
- *
- * @param message The detail message.
- * @param actual The actual request size.
- * @param permitted The maximum permitted request size.
- */
- public FileSizeLimitExceededException(String message, long actual,
- long permitted) {
- super(message, actual, permitted);
- }
-
- /**
- * Returns the file name of the item, which caused the
- * exception.
- *
- * @return File name, if known, or null.
- */
- public String getFileName() {
- return fileName;
- }
-
- /**
- * Sets the file name of the item, which caused the
- * exception.
- *
- * @param pFileName the file name of the item, which caused the exception.
- */
- public void setFileName(String pFileName) {
- fileName = pFileName;
- }
-
- /**
- * Returns the field name of the item, which caused the
- * exception.
- *
- * @return Field name, if known, or null.
- */
- public String getFieldName() {
- return fieldName;
- }
-
- /**
- * Sets the field name of the item, which caused the
- * exception.
- *
- * @param pFieldName the field name of the item,
- * which caused the exception.
- */
- public void setFieldName(String pFieldName) {
- fieldName = pFieldName;
- }
-
- }
-
- /**
* Returns the progress listener.
*
* @return The progress listener, if any, or null.
diff --git a/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java b/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
index 351fa02..c3616c3 100644
--- a/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
+++ b/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
@@ -22,7 +22,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
-import org.apache.tomcat.util.http.fileupload.FileUploadBase.FileUploadIOException;
+import org.apache.tomcat.util.http.fileupload.impl.FileUploadIOException;
import org.apache.tomcat.util.http.fileupload.util.Closeable;
import org.apache.tomcat.util.http.fileupload.util.Streams;
@@ -115,7 +115,7 @@ public class MultipartStream {
* @param pListener The listener to invoke.
* @param pContentLength The expected content length.
*/
- ProgressNotifier(ProgressListener pListener, long pContentLength) {
+ public ProgressNotifier(ProgressListener pListener, long pContentLength) {
listener = pListener;
contentLength = pContentLength;
}
@@ -136,7 +136,7 @@ public class MultipartStream {
/**
* Called to indicate, that a new file item has been detected.
*/
- void noteItem() {
+ public void noteItem() {
++items;
notifyListener();
}
@@ -332,7 +332,7 @@ public class MultipartStream {
*
* @see #MultipartStream(InputStream, byte[], int, ProgressNotifier)
*/
- MultipartStream(InputStream input,
+ public MultipartStream(InputStream input,
byte[] boundary,
ProgressNotifier pNotifier) {
this(input, boundary, DEFAULT_BUFSIZE, pNotifier);
@@ -576,7 +576,7 @@ public class MultipartStream {
* Creates a new {@link ItemInputStream}.
* @return A new instance of {@link ItemInputStream}.
*/
- ItemInputStream newInputStream() {
+ public ItemInputStream newInputStream() {
return new ItemInputStream();
}
diff --git a/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java b/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java
index b94a960..67f5e0c 100644
--- a/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java
+++ b/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java
@@ -546,7 +546,7 @@ public class DiskFileItem
* Removes the file contents from the temporary storage.
*/
@Override
- protected void finalize() {
+ protected void finalize() throws Throwable {
if (dfos == null || dfos.isInMemory()) {
return;
}
@@ -555,6 +555,7 @@ public class DiskFileItem
if (outputFile != null && outputFile.exists()) {
outputFile.delete();
}
+ super.finalize();
}
/**
diff --git a/java/org/apache/tomcat/util/http/fileupload/impl/FileItemIteratorImpl.java b/java/org/apache/tomcat/util/http/fileupload/impl/FileItemIteratorImpl.java
new file mode 100644
index 0000000..bef13aa
--- /dev/null
+++ b/java/org/apache/tomcat/util/http/fileupload/impl/FileItemIteratorImpl.java
@@ -0,0 +1,339 @@
+/*
+ * 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.tomcat.util.http.fileupload.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+
+import org.apache.tomcat.util.http.fileupload.FileItem;
+import org.apache.tomcat.util.http.fileupload.FileItemHeaders;
+import org.apache.tomcat.util.http.fileupload.FileItemIterator;
+import org.apache.tomcat.util.http.fileupload.FileItemStream;
+import org.apache.tomcat.util.http.fileupload.FileUploadBase;
+import org.apache.tomcat.util.http.fileupload.FileUploadException;
+import org.apache.tomcat.util.http.fileupload.IOUtils;
+import org.apache.tomcat.util.http.fileupload.MultipartStream;
+import org.apache.tomcat.util.http.fileupload.ProgressListener;
+import org.apache.tomcat.util.http.fileupload.RequestContext;
+import org.apache.tomcat.util.http.fileupload.UploadContext;
+import org.apache.tomcat.util.http.fileupload.util.LimitedInputStream;
+
+/**
+ * The iterator, which is returned by
+ * {@link FileUploadBase#getItemIterator(RequestContext)}.
+ */
+public class FileItemIteratorImpl implements FileItemIterator {
+ private final FileUploadBase fileUploadBase;
+ private final RequestContext ctx;
+ private long sizeMax, fileSizeMax;
+
+
+ @Override
+ public long getSizeMax() {
+ return sizeMax;
+ }
+
+ @Override
+ public void setSizeMax(long sizeMax) {
+ this.sizeMax = sizeMax;
+ }
+
+ @Override
+ public long getFileSizeMax() {
+ return fileSizeMax;
+ }
+
+ @Override
+ public void setFileSizeMax(long fileSizeMax) {
+ this.fileSizeMax = fileSizeMax;
+ }
+
+ /**
+ * The multi part stream to process.
+ */
+ private MultipartStream multiPartStream;
+
+ /**
+ * The notifier, which used for triggering the
+ * {@link ProgressListener}.
+ */
+ private MultipartStream.ProgressNotifier progressNotifier;
+
+ /**
+ * The boundary, which separates the various parts.
+ */
+ private byte[] multiPartBoundary;
+
+ /**
+ * The item, which we currently process.
+ */
+ private FileItemStreamImpl currentItem;
+
+ /**
+ * The current items field name.
+ */
+ private String currentFieldName;
+
+ /**
+ * Whether we are currently skipping the preamble.
+ */
+ private boolean skipPreamble;
+
+ /**
+ * Whether the current item may still be read.
+ */
+ private boolean itemValid;
+
+ /**
+ * Whether we have seen the end of the file.
+ */
+ private boolean eof;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param pFileUploadBase Upload instance
+ * @param pRequestContext The request context.
+ * @throws FileUploadException An error occurred while
+ * parsing the request.
+ * @throws IOException An I/O error occurred.
+ */
+ public FileItemIteratorImpl(FileUploadBase pFileUploadBase, RequestContext pRequestContext)
+ throws FileUploadException, IOException {
+ fileUploadBase = pFileUploadBase;
+ sizeMax = fileUploadBase.getSizeMax();
+ fileSizeMax = fileUploadBase.getFileSizeMax();
+ ctx = pRequestContext;
+ if (ctx == null) {
+ throw new NullPointerException("ctx parameter");
+ }
+
+
+ skipPreamble = true;
+ findNextItem();
+ }
+
+ protected void init(FileUploadBase fileUploadBase, @SuppressWarnings("unused") RequestContext pRequestContext)
+ throws FileUploadException, IOException {
+ String contentType = ctx.getContentType();
+ if ((null == contentType)
+ || (!contentType.toLowerCase(Locale.ENGLISH).startsWith(FileUploadBase.MULTIPART))) {
+ throw new InvalidContentTypeException(
+ String.format("the request doesn't contain a %s or %s stream, content type header is %s",
+ FileUploadBase.MULTIPART_FORM_DATA, FileUploadBase.MULTIPART_MIXED, contentType));
+ }
+
+ final long requestSize = ((UploadContext) ctx).contentLength();
+
+ InputStream input; // N.B. this is eventually closed in MultipartStream processing
+ if (sizeMax >= 0) {
+ if (requestSize != -1 && requestSize > sizeMax) {
+ throw new SizeLimitExceededException(
+ String.format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",
+ Long.valueOf(requestSize), Long.valueOf(sizeMax)),
+ requestSize, sizeMax);
+ }
+ // N.B. this is eventually closed in MultipartStream processing
+ input = new LimitedInputStream(ctx.getInputStream(), sizeMax) {
+ @Override
+ protected void raiseError(long pSizeMax, long pCount)
+ throws IOException {
+ FileUploadException ex = new SizeLimitExceededException(
+ String.format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",
+ Long.valueOf(pCount), Long.valueOf(pSizeMax)),
+ pCount, pSizeMax);
+ throw new FileUploadIOException(ex);
+ }
+ };
+ } else {
+ input = ctx.getInputStream();
+ }
+
+ String charEncoding = fileUploadBase.getHeaderEncoding();
+ if (charEncoding == null) {
+ charEncoding = ctx.getCharacterEncoding();
+ }
+
+ multiPartBoundary = fileUploadBase.getBoundary(contentType);
+ if (multiPartBoundary == null) {
+ IOUtils.closeQuietly(input); // avoid possible resource leak
+ throw new FileUploadException("the request was rejected because no multipart boundary was found");
+ }
+
+ progressNotifier = new MultipartStream.ProgressNotifier(fileUploadBase.getProgressListener(), requestSize);
+ try {
+ multiPartStream = new MultipartStream(input, multiPartBoundary, progressNotifier);
+ } catch (IllegalArgumentException iae) {
+ IOUtils.closeQuietly(input); // avoid possible resource leak
+ throw new InvalidContentTypeException(
+ String.format("The boundary specified in the %s header is too long", FileUploadBase.CONTENT_TYPE), iae);
+ }
+ multiPartStream.setHeaderEncoding(charEncoding);
+ }
+
+ public MultipartStream getMultiPartStream() throws FileUploadException, IOException {
+ if (multiPartStream == null) {
+ init(fileUploadBase, ctx);
+ }
+ return multiPartStream;
+ }
+
+ /**
+ * Called for finding the next item, if any.
+ *
+ * @return True, if an next item was found, otherwise false.
+ * @throws IOException An I/O error occurred.
+ */
+ private boolean findNextItem() throws FileUploadException, IOException {
+ if (eof) {
+ return false;
+ }
+ if (currentItem != null) {
+ currentItem.close();
+ currentItem = null;
+ }
+ final MultipartStream multi = getMultiPartStream();
+ for (;;) {
+ boolean nextPart;
+ if (skipPreamble) {
+ nextPart = multi.skipPreamble();
+ } else {
+ nextPart = multi.readBoundary();
+ }
+ if (!nextPart) {
+ if (currentFieldName == null) {
+ // Outer multipart terminated -> No more data
+ eof = true;
+ return false;
+ }
+ // Inner multipart terminated -> Return to parsing the outer
+ multi.setBoundary(multiPartBoundary);
+ currentFieldName = null;
+ continue;
+ }
+ FileItemHeaders headers = fileUploadBase.getParsedHeaders(multi.readHeaders());
+ if (currentFieldName == null) {
+ // We're parsing the outer multipart
+ String fieldName = fileUploadBase.getFieldName(headers);
+ if (fieldName != null) {
+ String subContentType = headers.getHeader(FileUploadBase.CONTENT_TYPE);
+ if (subContentType != null
+ && subContentType.toLowerCase(Locale.ENGLISH)
+ .startsWith(FileUploadBase.MULTIPART_MIXED)) {
+ currentFieldName = fieldName;
+ // Multiple files associated with this field name
+ byte[] subBoundary = fileUploadBase.getBoundary(subContentType);
+ multi.setBoundary(subBoundary);
+ skipPreamble = true;
+ continue;
+ }
+ String fileName = fileUploadBase.getFileName(headers);
+ currentItem = new FileItemStreamImpl(this, fileName,
+ fieldName, headers.getHeader(FileUploadBase.CONTENT_TYPE),
+ fileName == null, getContentLength(headers));
+ currentItem.setHeaders(headers);
+ progressNotifier.noteItem();
+ itemValid = true;
+ return true;
+ }
+ } else {
+ String fileName = fileUploadBase.getFileName(headers);
+ if (fileName != null) {
+ currentItem = new FileItemStreamImpl(this, fileName,
+ currentFieldName,
+ headers.getHeader(FileUploadBase.CONTENT_TYPE),
+ false, getContentLength(headers));
+ currentItem.setHeaders(headers);
+ progressNotifier.noteItem();
+ itemValid = true;
+ return true;
+ }
+ }
+ multi.discardBodyData();
+ }
+ }
+
+ private long getContentLength(FileItemHeaders pHeaders) {
+ try {
+ return Long.parseLong(pHeaders.getHeader(FileUploadBase.CONTENT_LENGTH));
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ /**
+ * Returns, whether another instance of {@link FileItemStream}
+ * is available.
+ *
+ * @throws FileUploadException Parsing or processing the
+ * file item failed.
+ * @throws IOException Reading the file item failed.
+ * @return True, if one or more additional file items
+ * are available, otherwise false.
+ */
+ @Override
+ public boolean hasNext() throws FileUploadException, IOException {
+ if (eof) {
+ return false;
+ }
+ if (itemValid) {
+ return true;
+ }
+ try {
+ return findNextItem();
+ } catch (FileUploadIOException e) {
+ // unwrap encapsulated SizeException
+ throw (FileUploadException) e.getCause();
+ }
+ }
+
+ /**
+ * Returns the next available {@link FileItemStream}.
+ *
+ * @throws java.util.NoSuchElementException No more items are
+ * available. Use {@link #hasNext()} to prevent this exception.
+ * @throws FileUploadException Parsing or processing the
+ * file item failed.
+ * @throws IOException Reading the file item failed.
+ * @return FileItemStream instance, which provides
+ * access to the next file item.
+ */
+ @Override
+ public FileItemStream next() throws FileUploadException, IOException {
+ if (eof || (!itemValid && !hasNext())) {
+ throw new NoSuchElementException();
+ }
+ itemValid = false;
+ return currentItem;
+ }
+
+ @Override
+ public List<FileItem> getFileItems() throws FileUploadException, IOException {
+ final List<FileItem> items = new ArrayList<>();
+ while (hasNext()) {
+ final FileItemStream fis = next();
+ final FileItem fi = fileUploadBase.getFileItemFactory().createItem(fis.getFieldName(), fis.getContentType(), fis.isFormField(), fis.getName());
+ items.add(fi);
+ }
+ return items;
+ }
+
+}
\ No newline at end of file
diff --git a/java/org/apache/tomcat/util/http/fileupload/impl/FileItemStreamImpl.java b/java/org/apache/tomcat/util/http/fileupload/impl/FileItemStreamImpl.java
new file mode 100644
index 0000000..58c0089
--- /dev/null
+++ b/java/org/apache/tomcat/util/http/fileupload/impl/FileItemStreamImpl.java
@@ -0,0 +1,222 @@
+/*
+ * 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.tomcat.util.http.fileupload.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.tomcat.util.http.fileupload.FileItemHeaders;
+import org.apache.tomcat.util.http.fileupload.FileItemStream;
+import org.apache.tomcat.util.http.fileupload.FileUploadException;
+import org.apache.tomcat.util.http.fileupload.InvalidFileNameException;
+import org.apache.tomcat.util.http.fileupload.MultipartStream.ItemInputStream;
+import org.apache.tomcat.util.http.fileupload.util.Closeable;
+import org.apache.tomcat.util.http.fileupload.util.LimitedInputStream;
+import org.apache.tomcat.util.http.fileupload.util.Streams;
+
+
+/**
+ * Default implementation of {@link FileItemStream}.
+ */
+public class FileItemStreamImpl implements FileItemStream {
+ private final FileItemIteratorImpl fileItemIteratorImpl;
+
+ /**
+ * The file items content type.
+ */
+ private final String contentType;
+
+ /**
+ * The file items field name.
+ */
+ private final String fieldName;
+
+ /**
+ * The file items file name.
+ */
+ final String name;
+
+ /**
+ * Whether the file item is a form field.
+ */
+ private final boolean formField;
+
+ /**
+ * The file items input stream.
+ */
+ private final InputStream stream;
+
+ /**
+ * Whether the file item was already opened.
+ */
+ private boolean opened;
+
+ /**
+ * The headers, if any.
+ */
+ private FileItemHeaders headers;
+
+ /**
+ * Creates a new instance.
+ * @param pFileItemIterator Iterator for all files in this upload
+ * @param pName The items file name, or null.
+ * @param pFieldName The items field name.
+ * @param pContentType The items content type, or null.
+ * @param pFormField Whether the item is a form field.
+ * @param pContentLength The items content length, if known, or -1
+ * @throws FileUploadException If an error is encountered processing the request
+ * @throws IOException Creating the file item failed.
+ */
+ public FileItemStreamImpl(FileItemIteratorImpl pFileItemIterator, String pName, String pFieldName,
+ String pContentType, boolean pFormField,
+ long pContentLength) throws FileUploadException, IOException {
+ fileItemIteratorImpl = pFileItemIterator;
+ name = pName;
+ fieldName = pFieldName;
+ contentType = pContentType;
+ formField = pFormField;
+ final long fileSizeMax = fileItemIteratorImpl.getFileSizeMax();
+ if (fileSizeMax != -1) { // Check if limit is already exceeded
+ if (pContentLength != -1
+ && pContentLength > fileSizeMax) {
+ FileSizeLimitExceededException e =
+ new FileSizeLimitExceededException(
+ String.format("The field %s exceeds its maximum permitted size of %s bytes.",
+ fieldName, Long.valueOf(fileSizeMax)),
+ pContentLength, fileSizeMax);
+ e.setFileName(pName);
+ e.setFieldName(pFieldName);
+ throw new FileUploadIOException(e);
+ }
+ }
+ // OK to construct stream now
+ final ItemInputStream itemStream = fileItemIteratorImpl.getMultiPartStream().newInputStream();
+ InputStream istream = itemStream;
+ if (fileSizeMax != -1) {
+ istream = new LimitedInputStream(istream, fileSizeMax) {
+ @Override
+ protected void raiseError(long pSizeMax, long pCount)
+ throws IOException {
+ itemStream.close(true);
+ FileSizeLimitExceededException e =
+ new FileSizeLimitExceededException(
+ String.format("The field %s exceeds its maximum permitted size of %s bytes.",
+ fieldName, Long.valueOf(pSizeMax)),
+ pCount, pSizeMax);
+ e.setFieldName(fieldName);
+ e.setFileName(name);
+ throw new FileUploadIOException(e);
+ }
+ };
+ }
+ stream = istream;
+ }
+
+ /**
+ * Returns the items content type, or null.
+ *
+ * @return Content type, if known, or null.
+ */
+ @Override
+ public String getContentType() {
+ return contentType;
+ }
+
+ /**
+ * Returns the items field name.
+ *
+ * @return Field name.
+ */
+ @Override
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ /**
+ * Returns the items file name.
+ *
+ * @return File name, if known, or null.
+ * @throws InvalidFileNameException The file name contains a NUL character,
+ * which might be an indicator of a security attack. If you intend to
+ * use the file name anyways, catch the exception and use
+ * InvalidFileNameException#getName().
+ */
+ @Override
+ public String getName() {
+ return Streams.checkFileName(name);
+ }
+
+ /**
+ * Returns, whether this is a form field.
+ *
+ * @return True, if the item is a form field,
+ * otherwise false.
+ */
+ @Override
+ public boolean isFormField() {
+ return formField;
+ }
+
+ /**
+ * Returns an input stream, which may be used to
+ * read the items contents.
+ *
+ * @return Opened input stream.
+ * @throws IOException An I/O error occurred.
+ */
+ @Override
+ public InputStream openStream() throws IOException {
+ if (opened) {
+ throw new IllegalStateException(
+ "The stream was already opened.");
+ }
+ if (((Closeable) stream).isClosed()) {
+ throw new FileItemStream.ItemSkippedException();
+ }
+ return stream;
+ }
+
+ /**
+ * Closes the file item.
+ *
+ * @throws IOException An I/O error occurred.
+ */
+ public void close() throws IOException {
+ stream.close();
+ }
+
+ /**
+ * Returns the file item headers.
+ *
+ * @return The items header object
+ */
+ @Override
+ public FileItemHeaders getHeaders() {
+ return headers;
+ }
+
+ /**
+ * Sets the file item headers.
+ *
+ * @param pHeaders The items header object
+ */
+ @Override
+ public void setHeaders(FileItemHeaders pHeaders) {
+ headers = pHeaders;
+ }
+
+}
\ No newline at end of file
diff --git a/java/org/apache/tomcat/util/http/fileupload/impl/FileSizeLimitExceededException.java b/java/org/apache/tomcat/util/http/fileupload/impl/FileSizeLimitExceededException.java
new file mode 100644
index 0000000..748f343
--- /dev/null
+++ b/java/org/apache/tomcat/util/http/fileupload/impl/FileSizeLimitExceededException.java
@@ -0,0 +1,94 @@
+/*
+ * 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.tomcat.util.http.fileupload.impl;
+
+/**
+ * Thrown to indicate that A files size exceeds the configured maximum.
+ */
+public class FileSizeLimitExceededException
+ extends SizeException {
+
+ /**
+ * The exceptions UID, for serializing an instance.
+ */
+ private static final long serialVersionUID = 8150776562029630058L;
+
+ /**
+ * File name of the item, which caused the exception.
+ */
+ private String fileName;
+
+ /**
+ * Field name of the item, which caused the exception.
+ */
+ private String fieldName;
+
+ /**
+ * Constructs a <code>SizeExceededException</code> with
+ * the specified detail message, and actual and permitted sizes.
+ *
+ * @param message The detail message.
+ * @param actual The actual request size.
+ * @param permitted The maximum permitted request size.
+ */
+ public FileSizeLimitExceededException(String message, long actual,
+ long permitted) {
+ super(message, actual, permitted);
+ }
+
+ /**
+ * Returns the file name of the item, which caused the
+ * exception.
+ *
+ * @return File name, if known, or null.
+ */
+ public String getFileName() {
+ return fileName;
+ }
+
+ /**
+ * Sets the file name of the item, which caused the
+ * exception.
+ *
+ * @param pFileName the file name of the item, which caused the exception.
+ */
+ public void setFileName(String pFileName) {
+ fileName = pFileName;
+ }
+
+ /**
+ * Returns the field name of the item, which caused the
+ * exception.
+ *
+ * @return Field name, if known, or null.
+ */
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ /**
+ * Sets the field name of the item, which caused the
+ * exception.
+ *
+ * @param pFieldName the field name of the item,
+ * which caused the exception.
+ */
+ public void setFieldName(String pFieldName) {
+ fieldName = pFieldName;
+ }
+
+}
\ No newline at end of file
diff --git a/java/org/apache/tomcat/util/http/fileupload/impl/FileUploadIOException.java b/java/org/apache/tomcat/util/http/fileupload/impl/FileUploadIOException.java
new file mode 100644
index 0000000..305378a
--- /dev/null
+++ b/java/org/apache/tomcat/util/http/fileupload/impl/FileUploadIOException.java
@@ -0,0 +1,63 @@
+/*
+ * 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.tomcat.util.http.fileupload.impl;
+
+import java.io.IOException;
+
+import org.apache.tomcat.util.http.fileupload.FileUploadException;
+
+/**
+ * This exception is thrown for hiding an inner
+ * {@link FileUploadException} in an {@link IOException}.
+ */
+public class FileUploadIOException extends IOException {
+
+ /**
+ * The exceptions UID, for serializing an instance.
+ */
+ private static final long serialVersionUID = -7047616958165584154L;
+
+ /**
+ * The exceptions cause; we overwrite the parent
+ * classes field, which is available since Java
+ * 1.4 only.
+ */
+ private final FileUploadException cause;
+
+ /**
+ * Creates a <code>FileUploadIOException</code> with the
+ * given cause.
+ *
+ * @param pCause The exceptions cause, if any, or null.
+ */
+ public FileUploadIOException(FileUploadException pCause) {
+ // We're not doing super(pCause) cause of 1.3 compatibility.
+ cause = pCause;
+ }
+
+ /**
+ * Returns the exceptions cause.
+ *
+ * @return The exceptions cause, if any, or null.
+ */
+ @SuppressWarnings("sync-override") // Field is final
+ @Override
+ public Throwable getCause() {
+ return cause;
+ }
+
+}
\ No newline at end of file
diff --git a/java/org/apache/tomcat/util/http/fileupload/impl/IOFileUploadException.java b/java/org/apache/tomcat/util/http/fileupload/impl/IOFileUploadException.java
new file mode 100644
index 0000000..ad141e5
--- /dev/null
+++ b/java/org/apache/tomcat/util/http/fileupload/impl/IOFileUploadException.java
@@ -0,0 +1,62 @@
+/*
+ * 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.tomcat.util.http.fileupload.impl;
+
+import java.io.IOException;
+
+import org.apache.tomcat.util.http.fileupload.FileUploadException;
+
+/**
+ * Thrown to indicate an IOException.
+ */
+public class IOFileUploadException extends FileUploadException {
+
+ /**
+ * The exceptions UID, for serializing an instance.
+ */
+ private static final long serialVersionUID = 1749796615868477269L;
+
+ /**
+ * The exceptions cause; we overwrite the parent
+ * classes field, which is available since Java
+ * 1.4 only.
+ */
+ private final IOException cause;
+
+ /**
+ * Creates a new instance with the given cause.
+ *
+ * @param pMsg The detail message.
+ * @param pException The exceptions cause.
+ */
+ public IOFileUploadException(String pMsg, IOException pException) {
+ super(pMsg);
+ cause = pException;
+ }
+
+ /**
+ * Returns the exceptions cause.
+ *
+ * @return The exceptions cause, if any, or null.
+ */
+ @SuppressWarnings("sync-override") // Field is final
+ @Override
+ public Throwable getCause() {
+ return cause;
+ }
+
+}
\ No newline at end of file
diff --git a/java/org/apache/tomcat/util/http/fileupload/impl/InvalidContentTypeException.java b/java/org/apache/tomcat/util/http/fileupload/impl/InvalidContentTypeException.java
new file mode 100644
index 0000000..124f002
--- /dev/null
+++ b/java/org/apache/tomcat/util/http/fileupload/impl/InvalidContentTypeException.java
@@ -0,0 +1,62 @@
+/*
+ * 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.tomcat.util.http.fileupload.impl;
+
+import org.apache.tomcat.util.http.fileupload.FileUploadException;
+
+/**
+ * Thrown to indicate that the request is not a multipart request.
+ */
+public class InvalidContentTypeException
+ extends FileUploadException {
+
+ /**
+ * The exceptions UID, for serializing an instance.
+ */
+ private static final long serialVersionUID = -9073026332015646668L;
+
+ /**
+ * Constructs a <code>InvalidContentTypeException</code> with no
+ * detail message.
+ */
+ public InvalidContentTypeException() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>InvalidContentTypeException</code> with
+ * the specified detail message.
+ *
+ * @param message The detail message.
+ */
+ public InvalidContentTypeException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs an <code>InvalidContentTypeException</code> with
+ * the specified detail message and cause.
+ *
+ * @param msg The detail message.
+ * @param cause the original cause
+ *
+ * @since 1.3.1
+ */
+ public InvalidContentTypeException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+}
\ No newline at end of file
diff --git a/java/org/apache/tomcat/util/http/fileupload/impl/SizeException.java b/java/org/apache/tomcat/util/http/fileupload/impl/SizeException.java
new file mode 100644
index 0000000..c37d644
--- /dev/null
+++ b/java/org/apache/tomcat/util/http/fileupload/impl/SizeException.java
@@ -0,0 +1,75 @@
+/*
+ * 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.tomcat.util.http.fileupload.impl;
+
+import org.apache.tomcat.util.http.fileupload.FileUploadException;
+
+/**
+ * This exception is thrown, if a requests permitted size
+ * is exceeded.
+ */
+abstract class SizeException extends FileUploadException {
+
+ /**
+ * Serial version UID, being used, if serialized.
+ */
+ private static final long serialVersionUID = -8776225574705254126L;
+
+ /**
+ * The actual size of the request.
+ */
+ private final long actual;
+
+ /**
+ * The maximum permitted size of the request.
+ */
+ private final long permitted;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param message The detail message.
+ * @param actual The actual number of bytes in the request.
+ * @param permitted The requests size limit, in bytes.
+ */
+ protected SizeException(String message, long actual, long permitted) {
+ super(message);
+ this.actual = actual;
+ this.permitted = permitted;
+ }
+
+ /**
+ * Retrieves the actual size of the request.
+ *
+ * @return The actual size of the request.
+ * @since 1.3
+ */
+ public long getActualSize() {
+ return actual;
+ }
+
+ /**
+ * Retrieves the permitted size of the request.
+ *
+ * @return The permitted size of the request.
+ * @since 1.3
+ */
+ public long getPermittedSize() {
+ return permitted;
+ }
+
+}
\ No newline at end of file
diff --git a/java/org/apache/tomcat/util/http/fileupload/impl/SizeLimitExceededException.java b/java/org/apache/tomcat/util/http/fileupload/impl/SizeLimitExceededException.java
new file mode 100644
index 0000000..0b6a7a9
--- /dev/null
+++ b/java/org/apache/tomcat/util/http/fileupload/impl/SizeLimitExceededException.java
@@ -0,0 +1,43 @@
+/*
+ * 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.tomcat.util.http.fileupload.impl;
+
+/**
+ * Thrown to indicate that the request size exceeds the configured maximum.
+ */
+public class SizeLimitExceededException
+ extends SizeException {
+
+ /**
+ * The exceptions UID, for serializing an instance.
+ */
+ private static final long serialVersionUID = -2474893167098052828L;
+
+ /**
+ * Constructs a <code>SizeExceededException</code> with
+ * the specified detail message, and actual and permitted sizes.
+ *
+ * @param message The detail message.
+ * @param actual The actual request size.
+ * @param permitted The maximum permitted request size.
+ */
+ public SizeLimitExceededException(String message, long actual,
+ long permitted) {
+ super(message, actual, permitted);
+ }
+
+}
\ No newline at end of file
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index d93a21c..66e4c0e 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -212,6 +212,10 @@
Update the internal fork of Apache Commons Codec to 9637dd4 (2019-12-06,
1.14-SNAPSHOT). Code clean-up and a fix for CODEC-265. (markt)
</add>
+ <add>
+ Update the internal fork of Apache Commons FileUpload to 2317552
+ (2019-12-06, 2.0-SNAPSHOT). Refactoring. (markt)
+ </add>
</changelog>
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org