This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-fileupload.git
commit 355d264689c8430a4ee7bd8dfd36fcf8d9459bcf Author: Gary Gregory <[email protected]> AuthorDate: Sun Apr 2 11:23:58 2023 -0400 Rework exceptions to use propagated exception causes (introduced in Java 1.4) - All custom exception extend FileUploadException - Simplify and clarify exception hierarchy - All custom exceptions serialVersionUID value is now 2. --- src/changes/changes.xml | 3 + src/checkstyle/fileupload_checks.xml | 3 +- .../commons/fileupload2/FileItemIterator.java | 9 +- .../apache/commons/fileupload2/FileUploadBase.java | 29 +- .../commons/fileupload2/FileUploadException.java | 77 +--- .../commons/fileupload2/MultipartStream.java | 408 +++++++++------------ .../commons/fileupload2/ProgressListener.java | 14 +- .../fileupload2/impl/FileItemIteratorImpl.java | 115 +++--- .../fileupload2/impl/FileItemStreamImpl.java | 93 ++--- .../pub/FileCountLimitExceededException.java | 53 --- ...java => FileUploadByteCountLimitException.java} | 52 +-- ...on.java => FileUploadContentTypeException.java} | 39 +- ...java => FileUploadFileCountLimitException.java} | 80 ++-- .../fileupload2/pub/FileUploadIOException.java | 44 --- ...Exception.java => FileUploadSizeException.java} | 29 +- .../pub/SizeLimitExceededException.java | 43 --- .../fileupload2/servlet/ServletFileUpload.java | 13 +- .../fileupload2/util/LimitedInputStream.java | 12 +- .../apache/commons/fileupload2/util/Streams.java | 8 +- .../org/apache/commons/fileupload2/SizesTest.java | 25 +- .../apache/commons/fileupload2/StreamingTest.java | 4 +- 21 files changed, 393 insertions(+), 760 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index f077bc4..a5a7461 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -51,6 +51,9 @@ The <action> type attribute can be add,update,fix,remove. <action dev="ggregory" type="fix" due-to="Emmanuel Lécharny">Slight optim: resuse the index position instead of recomputing it #49.</action> <action issue="FILEUPLOAD-340" dev="mgrigorov" type="fix">Make commons-fileupload2 a JPMS module by adding module-info.class.</action> <action issue="FILEUPLOAD-341" dev="jochen" type="fix" due-to="Martin Grigorov">Move Exception classes out of the impl package.</action> + <action dev="ggregory" type="fix" due-to="Gary Gregory">Rework exceptions to use propagated exception causes (introduced in Java 1.4).</action> + <action dev="ggregory" type="fix" due-to="Gary Gregory">All custom exception extend FileUploadException.</action> + <action dev="ggregory" type="fix" due-to="Gary Gregory">All custom exceptions serialVersionUID value is now 2.</action> <!-- ADD --> <action dev="ggregory" type="add" due-to="Gary Gregory">Add github/codeql-action from #144.</action> <action dev="jochen" type="add">Add the package org.apache.fileupload2.jaksrvlt, for compliance with Jakarta Servlet API 5.0.</action> diff --git a/src/checkstyle/fileupload_checks.xml b/src/checkstyle/fileupload_checks.xml index de07ed9..686e015 100644 --- a/src/checkstyle/fileupload_checks.xml +++ b/src/checkstyle/fileupload_checks.xml @@ -90,7 +90,7 @@ <!-- Begin Custom for FileUpload --> <module name="LineLength"> - <property name="max" value="120"/> + <property name="max" value="160"/> <property name="ignorePattern" value="^ \* @version .*$"/> </module> @@ -168,7 +168,6 @@ <!-- Checks for whitespace --> <!-- See http://checkstyle.sf.net/config_whitespace.html --> <module name="EmptyForIteratorPad"/> - <module name="NoWhitespaceAfter"/> <module name="NoWhitespaceBefore"/> <module name="OperatorWrap"/> <module name="ParenPad"/> diff --git a/src/main/java/org/apache/commons/fileupload2/FileItemIterator.java b/src/main/java/org/apache/commons/fileupload2/FileItemIterator.java index 129442e..1fa5f5d 100644 --- a/src/main/java/org/apache/commons/fileupload2/FileItemIterator.java +++ b/src/main/java/org/apache/commons/fileupload2/FileItemIterator.java @@ -19,8 +19,9 @@ package org.apache.commons.fileupload2; import java.io.IOException; import java.util.List; -import org.apache.commons.fileupload2.pub.FileSizeLimitExceededException; -import org.apache.commons.fileupload2.pub.SizeLimitExceededException; +import javax.naming.SizeLimitExceededException; + +import org.apache.commons.fileupload2.pub.FileUploadByteCountLimitException; /** * An iterator, as returned by @@ -29,7 +30,7 @@ import org.apache.commons.fileupload2.pub.SizeLimitExceededException; public interface FileItemIterator { List<FileItem> getFileItems() throws FileUploadException, IOException; - /** Returns the maximum size of a single file. An {@link FileSizeLimitExceededException} + /** Returns the maximum size of a single file. An {@link FileUploadByteCountLimitException} * 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 @@ -72,7 +73,7 @@ public interface FileItemIterator { */ FileItemStream next() throws FileUploadException, IOException; - /** Sets the maximum size of a single file. An {@link FileSizeLimitExceededException} + /** Sets the maximum size of a single file. An {@link FileUploadByteCountLimitException} * 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 diff --git a/src/main/java/org/apache/commons/fileupload2/FileUploadBase.java b/src/main/java/org/apache/commons/fileupload2/FileUploadBase.java index e62af9b..193a0b8 100644 --- a/src/main/java/org/apache/commons/fileupload2/FileUploadBase.java +++ b/src/main/java/org/apache/commons/fileupload2/FileUploadBase.java @@ -29,9 +29,7 @@ import java.util.Map; import java.util.Objects; import org.apache.commons.fileupload2.impl.FileItemIteratorImpl; -import org.apache.commons.fileupload2.pub.FileCountLimitExceededException; -import org.apache.commons.fileupload2.pub.FileUploadIOException; -import org.apache.commons.fileupload2.pub.IOFileUploadException; +import org.apache.commons.fileupload2.pub.FileUploadFileCountLimitException; import org.apache.commons.fileupload2.util.FileItemHeadersImpl; import org.apache.commons.fileupload2.util.Streams; @@ -386,14 +384,8 @@ public abstract class FileUploadBase { * error while communicating with the client or a problem while * storing the uploaded content. */ - public FileItemIterator getItemIterator(final RequestContext ctx) - throws FileUploadException, IOException { - try { - return new FileItemIteratorImpl(this, ctx); - } catch (final FileUploadIOException e) { - // unwrap encapsulated SizeException - throw (FileUploadException) e.getCause(); - } + public FileItemIterator getItemIterator(final RequestContext ctx) throws FileUploadException, IOException { + return new FileItemIteratorImpl(this, ctx); } /** @@ -587,27 +579,24 @@ public abstract class FileUploadBase { boolean successful = false; try { final FileItemIterator iter = getItemIterator(ctx); - final FileItemFactory fileItemFactory = Objects.requireNonNull(getFileItemFactory(), - "No FileItemFactory has been set."); + final FileItemFactory fileItemFactory = Objects.requireNonNull(getFileItemFactory(), "No FileItemFactory has been set."); final byte[] buffer = new byte[Streams.DEFAULT_BUFFER_SIZE]; while (iter.hasNext()) { if (items.size() == fileCountMax) { // The next item will exceed the limit. - throw new FileCountLimitExceededException(ATTACHMENT, getFileCountMax()); + throw new FileUploadFileCountLimitException(ATTACHMENT, getFileCountMax(), items.size()); } final FileItemStream item = iter.next(); // Don't use getName() here to prevent an InvalidFileNameException. final String fileName = item.getName(); - final FileItem fileItem = fileItemFactory.createItem(item.getFieldName(), item.getContentType(), - item.isFormField(), fileName); + final FileItem fileItem = fileItemFactory.createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName); items.add(fileItem); try { Streams.copy(item.openStream(), fileItem.getOutputStream(), true, buffer); - } catch (final FileUploadIOException e) { - throw (FileUploadException) e.getCause(); + } catch (final FileUploadException e) { + throw e; } catch (final IOException e) { - throw new IOFileUploadException(format("Processing of %s request failed. %s", - MULTIPART_FORM_DATA, e.getMessage()), e); + throw new FileUploadException(format("Processing of %s request failed. %s", MULTIPART_FORM_DATA, e.getMessage()), e); } final FileItemHeaders fih = item.getHeaders(); fileItem.setHeaders(fih); diff --git a/src/main/java/org/apache/commons/fileupload2/FileUploadException.java b/src/main/java/org/apache/commons/fileupload2/FileUploadException.java index 1ca5f91..5a54592 100644 --- a/src/main/java/org/apache/commons/fileupload2/FileUploadException.java +++ b/src/main/java/org/apache/commons/fileupload2/FileUploadException.java @@ -17,90 +17,41 @@ package org.apache.commons.fileupload2; import java.io.IOException; -import java.io.PrintStream; -import java.io.PrintWriter; /** - * Exception for errors encountered while processing the request. + * Signals errors encountered while processing the request. */ public class FileUploadException extends IOException { /** - * Serial version UID, being used, if the exception - * is serialized. + * Serial version UID, being used, if the exception is serialized. */ - private static final long serialVersionUID = 8881893724388807504L; + private static final long serialVersionUID = 2; /** - * The exceptions cause. We overwrite the cause of - * the super class, which isn't available in Java 1.3. - */ - private final Throwable cause; - - /** - * Constructs a new {@code FileUploadException} without message. + * Constructs a new instance. */ public FileUploadException() { - this(null, null); - } - - /** - * Constructs a new {@code FileUploadException} with specified detail - * message. - * - * @param msg the error message. - */ - public FileUploadException(final String msg) { - this(msg, null); - } - - /** - * Creates a new {@code FileUploadException} with the given - * detail message and cause. - * - * @param msg The exceptions detail message. - * @param cause The exceptions cause. - */ - public FileUploadException(final String msg, final Throwable cause) { - super(msg); - this.cause = cause; - } - - /** - * {@inheritDoc} - */ - @Override - public Throwable getCause() { - return cause; } /** - * Prints this throwable and its backtrace to the specified print stream. + * Constructs an instance with a given detail message. * - * @param stream {@code PrintStream} to use for output + * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) */ - @Override - public void printStackTrace(final PrintStream stream) { - super.printStackTrace(stream); - if (cause != null) { - stream.println("Caused by:"); - cause.printStackTrace(stream); - } + public FileUploadException(final String message) { + super(message); } /** - * Prints this throwable and its backtrace to the specified - * print writer. + * Constructs an instance with the given detail message and cause. * - * @param writer {@code PrintWriter} to use for output + * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) + * @param cause The cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and indicates that the cause + * is nonexistent or unknown.) */ - @Override - public void printStackTrace(final PrintWriter writer) { - super.printStackTrace(writer); - if (cause != null) { - writer.println("Caused by:"); - cause.printStackTrace(writer); - } + public FileUploadException(final String message, final Throwable cause) { + super(message, cause); } } diff --git a/src/main/java/org/apache/commons/fileupload2/MultipartStream.java b/src/main/java/org/apache/commons/fileupload2/MultipartStream.java index c9e3288..b5168e1 100644 --- a/src/main/java/org/apache/commons/fileupload2/MultipartStream.java +++ b/src/main/java/org/apache/commons/fileupload2/MultipartStream.java @@ -24,20 +24,20 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; -import org.apache.commons.fileupload2.pub.FileUploadIOException; +import org.apache.commons.fileupload2.pub.FileUploadSizeException; import org.apache.commons.fileupload2.util.Closeable; import org.apache.commons.fileupload2.util.Streams; /** - * <p> Low level API for processing file uploads. + * <p> + * Signals low-level API for processing file uploads. * - * <p> This class can be used to process data streams conforming to MIME - * 'multipart' format as defined in - * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Arbitrarily - * large amounts of data in the stream can be processed under constant - * memory usage. + * <p> + * This class can be used to process data streams conforming to MIME 'multipart' format as defined in <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC + * 1867</a>. Arbitrarily large amounts of data in the stream can be processed under constant memory usage. * - * <p> The format of the stream is defined in the following way:<br> + * <p> + * The format of the stream is defined in the following way:<br> * * <code> * multipart-body := preamble 1*encapsulation close-delimiter epilogue<br> @@ -54,31 +54,30 @@ import org.apache.commons.fileupload2.util.Streams; * body-data := <arbitrary data><br> * </code> * - * <p>Note that body-data can contain another mulipart entity. There - * is limited support for single pass processing of such nested - * streams. The nested stream is <strong>required</strong> to have a - * boundary token of the same length as the parent stream (see {@link - * #setBoundary(byte[])}). + * <p> + * Note that body-data can contain another mulipart entity. There is limited support for single pass processing of such nested streams. The nested stream is + * <strong>required</strong> to have a boundary token of the same length as the parent stream (see {@link #setBoundary(byte[])}). * - * <p>Here is an example of usage of this class.<br> + * <p> + * Here is an example of usage of this class.<br> * * <pre> - * try { + * try { * MultipartStream multipartStream = new MultipartStream(input, boundary); * boolean nextPart = multipartStream.skipPreamble(); * OutputStream output; - * while(nextPart) { - * String header = multipartStream.readHeaders(); - * // process headers - * // create some output stream - * multipartStream.readBodyData(output); - * nextPart = multipartStream.readBoundary(); + * while (nextPart) { + * String header = multipartStream.readHeaders(); + * // process headers + * // create some output stream + * multipartStream.readBodyData(output); + * nextPart = multipartStream.readBoundary(); * } - * } catch(MultipartStream.MalformedStreamException e) { + * } catch (MultipartStream.MalformedStreamException e) { * // the stream failed to follow required syntax - * } catch(IOException e) { + * } catch (IOException e) { * // a read or write error occurred - * } + * } * </pre> */ public class MultipartStream { @@ -86,34 +85,24 @@ public class MultipartStream { /** * Thrown upon attempt of setting an invalid boundary token. */ - public static class IllegalBoundaryException extends IOException { + public static class FileUploadBoundaryException extends FileUploadException { /** * The UID to use when serializing this instance. */ - private static final long serialVersionUID = -161533165102632918L; + private static final long serialVersionUID = 2; /** - * Constructs an {@code IllegalBoundaryException} with no - * detail message. - */ - public IllegalBoundaryException() { - } - - /** - * Constructs an {@code IllegalBoundaryException} with - * the specified detail message. + * Constructs an instance with the specified detail message. * - * @param message The detail message. + * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) */ - public IllegalBoundaryException(final String message) { + public FileUploadBoundaryException(final String message) { super(message); } } - // ----------------------------------------------------- Manifest constants - /** * An {@link InputStream} for reading an items contents. */ @@ -130,8 +119,7 @@ public class MultipartStream { private long total; /** - * The number of bytes, which must be hold, because - * they might be a part of the boundary. + * The number of bytes, which must be hold, because they might be a part of the boundary. */ private int pad; @@ -153,8 +141,7 @@ public class MultipartStream { } /** - * Returns the number of bytes, which are currently - * available, without blocking. + * Returns the number of bytes, which are currently available, without blocking. * * @throws IOException An I/O error occurs. * @return Number of bytes in the buffer. @@ -180,8 +167,7 @@ public class MultipartStream { /** * Closes the input stream. * - * @param pCloseUnderlying Whether to close the underlying stream - * (hard close) + * @param pCloseUnderlying Whether to close the underlying stream (hard close) * @throws IOException An I/O error occurred. */ public void close(final boolean pCloseUnderlying) throws IOException { @@ -221,8 +207,7 @@ public class MultipartStream { } /** - * Returns the number of bytes, which have been read - * by the stream. + * Returns the number of bytes, which have been read by the stream. * * @return Number of bytes, which have been read so far. */ @@ -285,8 +270,7 @@ public class MultipartStream { /** * Returns the next byte in the stream. * - * @return The next byte in the stream, as a non-negative - * integer, or -1 for EOF. + * @return The next byte in the stream, as a non-negative integer, or -1 for EOF. * @throws IOException An I/O error occurred. */ @Override @@ -308,11 +292,10 @@ public class MultipartStream { /** * Reads bytes into the given buffer. * - * @param b The destination buffer, where to write to. + * @param b The destination buffer, where to write to. * @param off Offset of the first byte in the buffer. * @param len Maximum number of bytes to read. - * @return Number of bytes, which have been actually read, - * or -1 for EOF. + * @return Number of bytes, which have been actually read, or -1 for EOF. * @throws IOException An I/O error occurred. */ @Override @@ -341,8 +324,7 @@ public class MultipartStream { * Skips the given number of bytes. * * @param bytes Number of bytes to skip. - * @return The number of bytes, which have actually been - * skipped. + * @return The number of bytes, which have actually been skipped. * @throws IOException An I/O error occurred. */ @Override @@ -365,8 +347,7 @@ public class MultipartStream { } /** - * Thrown to indicate that the input stream fails to follow the - * required syntax. + * Thrown to indicate that the input stream fails to follow the required syntax. */ public static class MalformedStreamException extends IOException { @@ -376,34 +357,36 @@ public class MultipartStream { private static final long serialVersionUID = 6466926458059796677L; /** - * Constructs a {@code MalformedStreamException} with no - * detail message. + * Constructs an {@code MalformedStreamException} with the specified detail message. + * + * @param message The detail message. */ - public MalformedStreamException() { + public MalformedStreamException(final String message) { + super(message); } /** - * Constructs an {@code MalformedStreamException} with - * the specified detail message. + * Constructs an {@code MalformedStreamException} with the specified detail message. * * @param message The detail message. + * @param cause The cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and indicates that the + * cause is nonexistent or unknown.) */ - public MalformedStreamException(final String message) { - super(message); + public MalformedStreamException(final String message, final Throwable cause) { + super(message, cause); } } /** - * Internal class, which is used to invoke the - * {@link ProgressListener}. + * Internal class, which is used to invoke the {@link ProgressListener}. */ public static class ProgressNotifier { /** * The listener to invoke. */ - private final ProgressListener listener; + private final ProgressListener progressListener; /** * Number of expected bytes, if known, or -1. @@ -421,15 +404,14 @@ public class MultipartStream { private int items; /** - * Creates a new instance with the given listener - * and content length. + * Creates a new instance with the given listener and content length. * - * @param pListener The listener to invoke. - * @param pContentLength The expected content length. + * @param progressListener The listener to invoke. + * @param contentLength The expected content length. */ - public ProgressNotifier(final ProgressListener pListener, final long pContentLength) { - listener = pListener; - contentLength = pContentLength; + public ProgressNotifier(final ProgressListener progressListener, final long contentLength) { + this.progressListener = progressListener; + this.contentLength = contentLength; } /** @@ -438,8 +420,8 @@ public class MultipartStream { * @param pBytes Number of bytes, which have been read. */ void noteBytesRead(final int pBytes) { - /* Indicates, that the given number of bytes have been read from - * the input stream. + /* + * Indicates, that the given number of bytes have been read from the input stream. */ bytesRead += pBytes; notifyListener(); @@ -457,8 +439,8 @@ public class MultipartStream { * Called for notifying the listener. */ private void notifyListener() { - if (listener != null) { - listener.update(bytesRead, contentLength, items); + if (progressListener != null) { + progressListener.update(bytesRead, contentLength, items); } } @@ -480,8 +462,7 @@ public class MultipartStream { public static final byte DASH = 0x2D; /** - * The maximum length of {@code header-part} that will be - * processed (10 kilobytes = 10240 bytes.). + * The maximum length of {@code header-part} that will be processed (10 kilobytes = 10240 bytes.). */ public static final int HEADER_PART_SIZE_MAX = 10240; @@ -491,44 +472,37 @@ public class MultipartStream { protected static final int DEFAULT_BUFSIZE = 4096; /** - * A byte sequence that marks the end of {@code header-part} - * ({@code CRLFCRLF}). + * A byte sequence that marks the end of {@code header-part} ({@code CRLFCRLF}). */ - protected static final byte[] HEADER_SEPARATOR = {CR, LF, CR, LF}; + protected static final byte[] HEADER_SEPARATOR = { CR, LF, CR, LF }; // ----------------------------------------------------------- Data members /** - * A byte sequence that that follows a delimiter that will be - * followed by an encapsulation ({@code CRLF}). + * A byte sequence that that follows a delimiter that will be followed by an encapsulation ({@code CRLF}). */ - protected static final byte[] FIELD_SEPARATOR = {CR, LF}; + protected static final byte[] FIELD_SEPARATOR = { CR, LF }; /** - * A byte sequence that that follows a delimiter of the last - * encapsulation in the stream ({@code --}). + * A byte sequence that that follows a delimiter of the last encapsulation in the stream ({@code --}). */ - protected static final byte[] STREAM_TERMINATOR = {DASH, DASH}; + protected static final byte[] STREAM_TERMINATOR = { DASH, DASH }; /** * A byte sequence that precedes a boundary ({@code CRLF--}). */ - protected static final byte[] BOUNDARY_PREFIX = {CR, LF, DASH, DASH}; + protected static final byte[] BOUNDARY_PREFIX = { CR, LF, DASH, DASH }; /** - * Compares {@code count} first bytes in the arrays - * {@code a} and {@code b}. + * Compares {@code count} first bytes in the arrays {@code a} and {@code b}. * * @param a The first array to compare. * @param b The second array to compare. * @param count How many bytes should be compared. * - * @return {@code true} if {@code count} first bytes in arrays - * {@code a} and {@code b} are equal. + * @return {@code true} if {@code count} first bytes in arrays {@code a} and {@code b} are equal. */ - public static boolean arrayequals(final byte[] a, - final byte[] b, - final int count) { + public static boolean arrayequals(final byte[] a, final byte[] b, final int count) { for (int i = 0; i < count; i++) { if (a[i] != b[i]) { return false; @@ -548,8 +522,7 @@ public class MultipartStream { private int boundaryLength; /** - * The amount of data, in bytes, that must be kept in the buffer in order - * to detect delimiters reliably. + * The amount of data, in bytes, that must be kept in the buffer in order to detect delimiters reliably. */ private final int keepRegion; @@ -576,15 +549,13 @@ public class MultipartStream { // ----------------------------------------------------------- Constructors /** - * The index of first valid character in the buffer. - * <br> + * The index of first valid character in the buffer. <br> * 0 <= head < bufSize */ private int head; /** - * The index of last valid character in the buffer + 1. - * <br> + * The index of last valid character in the buffer + 1. <br> * 0 <= tail <= bufSize */ private int tail; @@ -602,8 +573,7 @@ public class MultipartStream { /** * Creates a new instance. * - * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, - * ProgressNotifier)} + * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, ProgressNotifier)} */ @Deprecated public MultipartStream() { @@ -613,37 +583,32 @@ public class MultipartStream { // --------------------------------------------------------- Public methods /** - * <p> Constructs a {@code MultipartStream} with a default size buffer. + * <p> + * Constructs a {@code MultipartStream} with a default size buffer. * * @param input The {@code InputStream} to serve as a data source. - * @param boundary The token used for dividing the stream into - * {@code encapsulations}. + * @param boundary The token used for dividing the stream into {@code encapsulations}. * - * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, - * ProgressNotifier)}. + * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, ProgressNotifier)}. */ @Deprecated - public MultipartStream(final InputStream input, - final byte[] boundary) { + public MultipartStream(final InputStream input, final byte[] boundary) { this(input, boundary, DEFAULT_BUFSIZE, null); } /** - * <p> Constructs a {@code MultipartStream} with a custom size buffer - * and no progress notifier. + * <p> + * Constructs a {@code MultipartStream} with a custom size buffer and no progress notifier. * - * <p> Note that the buffer must be at least big enough to contain the - * boundary string, plus 4 characters for CR/LF and double dash, plus at - * least one byte of data. Too small a buffer size setting will degrade - * performance. + * <p> + * Note that the buffer must be at least big enough to contain the boundary string, plus 4 characters for CR/LF and double dash, plus at least one byte of + * data. Too small a buffer size setting will degrade performance. * * @param input The {@code InputStream} to serve as a data source. - * @param boundary The token used for dividing the stream into - * {@code encapsulations}. + * @param boundary The token used for dividing the stream into {@code encapsulations}. * @param bufSize The size of the buffer to be used, in bytes. * - * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, - * ProgressNotifier)}. + * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, ProgressNotifier)}. */ @Deprecated public MultipartStream(final InputStream input, final byte[] boundary, final int bufSize) { @@ -651,28 +616,21 @@ public class MultipartStream { } /** - * <p> Constructs a {@code MultipartStream} with a custom size buffer. - * - * <p> Note that the buffer must be at least big enough to contain the - * boundary string, plus 4 characters for CR/LF and double dash, plus at - * least one byte of data. Too small a buffer size setting will degrade - * performance. - * - * @param input The {@code InputStream} to serve as a data source. - * @param boundary The token used for dividing the stream into - * {@code encapsulations}. - * @param bufSize The size of the buffer to be used, in bytes. - * @param pNotifier The notifier, which is used for calling the - * progress listener, if any. + * <p> + * Constructs a {@code MultipartStream} with a custom size buffer. * - * @throws IllegalArgumentException If the buffer size is too small + * <p> + * Note that the buffer must be at least big enough to contain the boundary string, plus 4 characters for CR/LF and double dash, plus at least one byte of + * data. Too small a buffer size setting will degrade performance. * + * @param input The {@code InputStream} to serve as a data source. + * @param boundary The token used for dividing the stream into {@code encapsulations}. + * @param bufferSize The size of the buffer to be used, in bytes. + * @param pNotifier The notifier, which is used for calling the progress listener, if any. + * @throws IllegalArgumentException If the buffer size is too small. * @since 1.3.1 */ - public MultipartStream(final InputStream input, - final byte[] boundary, - final int bufSize, - final ProgressNotifier pNotifier) { + public MultipartStream(final InputStream input, final byte[] boundary, final int bufferSize, final ProgressNotifier pNotifier) { if (boundary == null) { throw new IllegalArgumentException("boundary may not be null"); @@ -680,13 +638,12 @@ public class MultipartStream { // We prepend CR/LF to the boundary to chop trailing CR/LF from // body-data tokens. this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length; - if (bufSize < this.boundaryLength + 1) { - throw new IllegalArgumentException( - "The buffer size specified for the MultipartStream is too small"); + if (bufferSize < this.boundaryLength + 1) { + throw new IllegalArgumentException("The buffer size specified for the MultipartStream is too small"); } this.input = input; - this.bufSize = Math.max(bufSize, boundaryLength * 2); + this.bufSize = Math.max(bufferSize, boundaryLength * 2); this.buffer = new byte[this.bufSize]; this.notifier = pNotifier; @@ -694,10 +651,8 @@ public class MultipartStream { this.boundaryTable = new int[this.boundaryLength + 1]; this.keepRegion = this.boundary.length; - System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, - BOUNDARY_PREFIX.length); - System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, - boundary.length); + System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, BOUNDARY_PREFIX.length); + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, boundary.length); computeBoundaryTable(); head = 0; @@ -705,20 +660,16 @@ public class MultipartStream { } /** - * <p> Constructs a {@code MultipartStream} with a default size buffer. - * - * @param input The {@code InputStream} to serve as a data source. - * @param boundary The token used for dividing the stream into - * {@code encapsulations}. - * @param pNotifier An object for calling the progress listener, if any. - * + * <p> + * Constructs a {@code MultipartStream} with a default size buffer. * + * @param input The {@code InputStream} to serve as a data source. + * @param boundary The token used for dividing the stream into {@code encapsulations}. + * @param progressNotifier An object for calling the progress listener, if any. * @see #MultipartStream(InputStream, byte[], int, ProgressNotifier) */ - public MultipartStream(final InputStream input, - final byte[] boundary, - final ProgressNotifier pNotifier) { - this(input, boundary, DEFAULT_BUFSIZE, pNotifier); + public MultipartStream(final InputStream input, final byte[] boundary, final ProgressNotifier progressNotifier) { + this(input, boundary, DEFAULT_BUFSIZE, progressNotifier); } /** @@ -746,11 +697,11 @@ public class MultipartStream { } /** - * <p> Reads {@code body-data} from the current - * {@code encapsulation} and discards it. + * <p> + * Reads {@code body-data} from the current {@code encapsulation} and discards it. * - * <p>Use this method to skip encapsulations you don't need or don't - * understand. + * <p> + * Use this method to skip encapsulations you don't need or don't understand. * * @return The amount of data discarded. * @@ -762,17 +713,14 @@ public class MultipartStream { } /** - * Searches for a byte of specified value in the {@code buffer}, - * starting at the specified {@code position}. + * Searches for a byte of specified value in the {@code buffer}, starting at the specified {@code position}. * * @param value The value to find. * @param pos The starting position for searching. * - * @return The position of byte found, counting from beginning of the - * {@code buffer}, or {@code -1} if not found. + * @return The position of byte found, counting from beginning of the {@code buffer}, or {@code -1} if not found. */ - protected int findByte(final byte value, - final int pos) { + protected int findByte(final byte value, final int pos) { for (int i = pos; i < tail; i++) { if (buffer[i] == value) { return i; @@ -783,12 +731,9 @@ public class MultipartStream { } /** - * Searches for the {@code boundary} in the {@code buffer} - * region delimited by {@code head} and {@code tail}. + * Searches for the {@code boundary} in the {@code buffer} region delimited by {@code head} and {@code tail}. * - * @return The position of the boundary found, counting from the - * beginning of the {@code buffer}, or {@code -1} if - * not found. + * @return The position of the boundary found, counting from the beginning of the {@code buffer}, or {@code -1} if not found. */ protected int findSeparator() { @@ -809,9 +754,8 @@ public class MultipartStream { } /** - * Retrieves the character encoding used when reading the headers of an - * individual part. When not specified, or {@code null}, the platform - * default encoding is used. + * Retrieves the character encoding used when reading the headers of an individual part. When not specified, or {@code null}, the platform default encoding + * is used. * * @return The encoding used to read part headers. */ @@ -821,6 +765,7 @@ public class MultipartStream { /** * Creates a new {@link ItemInputStream}. + * * @return A new instance of {@link ItemInputStream}. */ public ItemInputStream newInputStream() { @@ -828,42 +773,33 @@ public class MultipartStream { } /** - * <p>Reads {@code body-data} from the current - * {@code encapsulation} and writes its contents into the - * output {@code Stream}. + * <p> + * Reads {@code body-data} from the current {@code encapsulation} and writes its contents into the output {@code Stream}. * - * <p>Arbitrary large amounts of data can be processed by this - * method using a constant size buffer. (see {@link - * #MultipartStream(InputStream,byte[],int, - * MultipartStream.ProgressNotifier) constructor}). + * <p> + * Arbitrary large amounts of data can be processed by this method using a constant size buffer. (see + * {@link #MultipartStream(InputStream,byte[],int, MultipartStream.ProgressNotifier) constructor}). * - * @param output The {@code Stream} to write data into. May - * be null, in which case this method is equivalent - * to {@link #discardBodyData()}. + * @param output The {@code Stream} to write data into. May be null, in which case this method is equivalent to {@link #discardBodyData()}. * * @return the amount of data written. * * @throws MalformedStreamException if the stream ends unexpectedly. * @throws IOException if an i/o error occurs. */ - public int readBodyData(final OutputStream output) - throws MalformedStreamException, IOException { + public int readBodyData(final OutputStream output) throws MalformedStreamException, IOException { return (int) Streams.copy(newInputStream(), output, false); // N.B. Streams.copy closes the input stream } /** - * Skips a {@code boundary} token, and checks whether more - * {@code encapsulations} are contained in the stream. + * Skips a {@code boundary} token, and checks whether more {@code encapsulations} are contained in the stream. * - * @return {@code true} if there are more encapsulations in - * this stream; {@code false} otherwise. + * @return {@code true} if there are more encapsulations in this stream; {@code false} otherwise. * - * @throws FileUploadIOException if the bytes read from the stream exceeded the size limits - * @throws MalformedStreamException if the stream ends unexpectedly or - * fails to follow required syntax. + * @throws FileUploadSizeException if the bytes read from the stream exceeded the size limits + * @throws MalformedStreamException if the stream ends unexpectedly or fails to follow required syntax. */ - public boolean readBoundary() - throws FileUploadIOException, MalformedStreamException { + public boolean readBoundary() throws FileUploadException, MalformedStreamException { final byte[] marker = new byte[2]; final boolean nextChunk; @@ -886,21 +822,19 @@ public class MultipartStream { } else if (arrayequals(marker, FIELD_SEPARATOR, 2)) { nextChunk = true; } else { - throw new MalformedStreamException( - "Unexpected characters follow a boundary"); + throw new MalformedStreamException("Unexpected characters follow a boundary"); } - } catch (final FileUploadIOException e) { - // wraps a SizeException, re-throw as it will be unwrapped later + } catch (final FileUploadSizeException e) { + // wraps a FileUploadSizeException, re-throw as it will be unwrapped later? throw e; } catch (final IOException e) { - throw new MalformedStreamException("Stream ended unexpectedly"); + throw new MalformedStreamException("Stream ended unexpectedly", e); } return nextChunk; } /** - * Reads a byte from the {@code buffer}, and refills it as - * necessary. + * Reads a byte from the {@code buffer}, and refills it as necessary. * * @return The next byte from the input stream. * @@ -924,22 +858,21 @@ public class MultipartStream { } /** - * <p>Reads the {@code header-part} of the current - * {@code encapsulation}. + * <p> + * Reads the {@code header-part} of the current {@code encapsulation}. * - * <p>Headers are returned verbatim to the input stream, including the - * trailing {@code CRLF} marker. Parsing is left to the - * application. + * <p> + * Headers are returned verbatim to the input stream, including the trailing {@code CRLF} marker. Parsing is left to the application. * - * <p><strong>TODO</strong> allow limiting maximum header size to - * protect against abuse. + * <p> + * <strong>TODO</strong> allow limiting maximum header size to protect against abuse. * * @return The {@code header-part} of the current encapsulation. * - * @throws FileUploadIOException if the bytes read from the stream exceeded the size limits. + * @throws FileUploadSizeException if the bytes read from the stream exceeded the size limits. * @throws MalformedStreamException if the stream ends unexpectedly. */ - public String readHeaders() throws FileUploadIOException, MalformedStreamException { + public String readHeaders() throws FileUploadSizeException, MalformedStreamException { int i = 0; byte b; // to support multi-byte characters @@ -948,16 +881,14 @@ public class MultipartStream { while (i < HEADER_SEPARATOR.length) { try { b = readByte(); - } catch (final FileUploadIOException e) { - // wraps a SizeException, re-throw as it will be unwrapped later + } catch (final FileUploadSizeException e) { + // wraps a FileUploadSizeException, re-throw as it will be unwrapped later throw e; } catch (final IOException e) { - throw new MalformedStreamException("Stream ended unexpectedly"); + throw new MalformedStreamException("Stream ended unexpectedly", e); } if (++size > HEADER_PART_SIZE_MAX) { - throw new MalformedStreamException( - format("Header section has more than %s bytes (maybe it is not properly terminated)", - HEADER_PART_SIZE_MAX)); + throw new MalformedStreamException(format("Header section has more than %s bytes (maybe it is not properly terminated)", HEADER_PART_SIZE_MAX)); } if (b == HEADER_SEPARATOR[i]) { i++; @@ -984,39 +915,33 @@ public class MultipartStream { } /** - * <p>Changes the boundary token used for partitioning the stream. + * <p> + * Changes the boundary token used for partitioning the stream. * - * <p>This method allows single pass processing of nested multipart - * streams. + * <p> + * This method allows single pass processing of nested multipart streams. * - * <p>The boundary token of the nested stream is {@code required} - * to be of the same length as the boundary token in parent stream. + * <p> + * The boundary token of the nested stream is {@code required} to be of the same length as the boundary token in parent stream. * - * <p>Restoring the parent stream boundary token after processing of a - * nested stream is left to the application. + * <p> + * Restoring the parent stream boundary token after processing of a nested stream is left to the application. * - * @param boundary The boundary to be used for parsing of the nested - * stream. + * @param boundary The boundary to be used for parsing of the nested stream. * - * @throws IllegalBoundaryException if the {@code boundary} - * has a different length than the one - * being currently parsed. + * @throws FileUploadBoundaryException if the {@code boundary} has a different length than the one being currently parsed. */ - public void setBoundary(final byte[] boundary) - throws IllegalBoundaryException { + public void setBoundary(final byte[] boundary) throws FileUploadBoundaryException { if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) { - throw new IllegalBoundaryException( - "The length of a boundary token cannot be changed"); + throw new FileUploadBoundaryException("The length of a boundary token cannot be changed"); } - System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, - boundary.length); + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, boundary.length); computeBoundaryTable(); } /** - * Specifies the character encoding to be used when reading the headers of - * individual parts. When not specified, or {@code null}, the platform - * default encoding is used. + * Specifies the character encoding to be used when reading the headers of individual parts. When not specified, or {@code null}, the platform default + * encoding is used. * * @param encoding The encoding used to read part headers. */ @@ -1027,8 +952,7 @@ public class MultipartStream { /** * Finds the beginning of the first {@code encapsulation}. * - * @return {@code true} if an {@code encapsulation} was found in - * the stream. + * @return {@code true} if an {@code encapsulation} was found in the stream. * * @throws IOException if an i/o error occurs. */ diff --git a/src/main/java/org/apache/commons/fileupload2/ProgressListener.java b/src/main/java/org/apache/commons/fileupload2/ProgressListener.java index 0288b8e..5acc770 100644 --- a/src/main/java/org/apache/commons/fileupload2/ProgressListener.java +++ b/src/main/java/org/apache/commons/fileupload2/ProgressListener.java @@ -17,21 +17,17 @@ package org.apache.commons.fileupload2; /** - * The {@link ProgressListener} may be used to display a progress bar - * or do stuff like that. + * The {@link ProgressListener} may be used to display a progress bar. */ public interface ProgressListener { /** * Updates the listeners status information. * - * @param pBytesRead The total number of bytes, which have been read - * so far. - * @param pContentLength The total number of bytes, which are being - * read. May be -1, if this number is unknown. - * @param pItems The number of the field, which is currently being - * read. (0 = no item so far, 1 = first item is being read, ...) + * @param bytesRead The total number of bytes, which have been read so far. + * @param contentLength The total number of bytes, which are being read. May be -1, if this number is unknown. + * @param items The number of the field, which is currently being read. (0 = no item so far, 1 = first item is being read, ...) */ - void update(long pBytesRead, long pContentLength, int pItems); + void update(long bytesRead, long contentLength, int items); } diff --git a/src/main/java/org/apache/commons/fileupload2/impl/FileItemIteratorImpl.java b/src/main/java/org/apache/commons/fileupload2/impl/FileItemIteratorImpl.java index 23635cd..9bb2e57 100644 --- a/src/main/java/org/apache/commons/fileupload2/impl/FileItemIteratorImpl.java +++ b/src/main/java/org/apache/commons/fileupload2/impl/FileItemIteratorImpl.java @@ -36,24 +36,24 @@ import org.apache.commons.fileupload2.MultipartStream; import org.apache.commons.fileupload2.ProgressListener; import org.apache.commons.fileupload2.RequestContext; import org.apache.commons.fileupload2.UploadContext; -import org.apache.commons.fileupload2.pub.FileUploadIOException; -import org.apache.commons.fileupload2.pub.InvalidContentTypeException; -import org.apache.commons.fileupload2.pub.SizeLimitExceededException; +import org.apache.commons.fileupload2.pub.FileUploadSizeException; +import org.apache.commons.fileupload2.pub.FileUploadContentTypeException; import org.apache.commons.fileupload2.util.LimitedInputStream; import org.apache.commons.io.IOUtils; /** - * The iterator, which is returned by - * {@link FileUploadBase#getItemIterator(RequestContext)}. + * The iterator, which is returned by {@link FileUploadBase#getItemIterator(RequestContext)}. */ public class FileItemIteratorImpl implements FileItemIterator { /** * The file uploads processing utility. + * * @see FileUploadBase */ private final FileUploadBase fileUploadBase; /** * The request context. + * * @see RequestContext */ private final RequestContext ctx; @@ -66,15 +66,13 @@ public class FileItemIteratorImpl implements FileItemIterator { */ private long fileSizeMax; - /** * The multi part stream to process. */ private MultipartStream multiPartStream; /** - * The notifier, which used for triggering the - * {@link ProgressListener}. + * The notifier, which used for triggering the {@link ProgressListener}. */ private MultipartStream.ProgressNotifier progressNotifier; @@ -113,17 +111,15 @@ public class FileItemIteratorImpl implements FileItemIterator { * * @param fileUploadBase Main processor. * @param requestContext The request context. - * @throws FileUploadException An error occurred while - * parsing the request. - * @throws IOException An I/O error occurred. + * @throws FileUploadException An error occurred while parsing the request. + * @throws IOException An I/O error occurred. */ - public FileItemIteratorImpl(final FileUploadBase fileUploadBase, final RequestContext requestContext) - throws FileUploadException, IOException { + public FileItemIteratorImpl(final FileUploadBase fileUploadBase, final RequestContext requestContext) throws FileUploadException, IOException { this.fileUploadBase = fileUploadBase; - sizeMax = fileUploadBase.getSizeMax(); - fileSizeMax = fileUploadBase.getFileSizeMax(); - ctx = Objects.requireNonNull(requestContext, "requestContext"); - skipPreamble = true; + this.sizeMax = fileUploadBase.getSizeMax(); + this.fileSizeMax = fileUploadBase.getFileSizeMax(); + this.ctx = Objects.requireNonNull(requestContext, "requestContext"); + this.skipPreamble = true; findNextItem(); } @@ -166,9 +162,7 @@ public class FileItemIteratorImpl implements FileItemIterator { final String fieldName = fileUploadBase.getFieldName(headers); if (fieldName != null) { final String subContentType = headers.getHeader(FileUploadBase.CONTENT_TYPE); - if (subContentType != null - && subContentType.toLowerCase(Locale.ENGLISH) - .startsWith(FileUploadBase.MULTIPART_MIXED)) { + if (subContentType != null && subContentType.toLowerCase(Locale.ENGLISH).startsWith(FileUploadBase.MULTIPART_MIXED)) { currentFieldName = fieldName; // Multiple files associated with this field name final byte[] subBoundary = fileUploadBase.getBoundary(subContentType); @@ -177,9 +171,8 @@ public class FileItemIteratorImpl implements FileItemIterator { continue; } final String fileName = fileUploadBase.getFileName(headers); - currentItem = new FileItemStreamImpl(this, fileName, - fieldName, headers.getHeader(FileUploadBase.CONTENT_TYPE), - fileName == null, getContentLength(headers)); + currentItem = new FileItemStreamImpl(this, fileName, fieldName, headers.getHeader(FileUploadBase.CONTENT_TYPE), fileName == null, + getContentLength(headers)); currentItem.setHeaders(headers); progressNotifier.noteItem(); itemValid = true; @@ -188,10 +181,8 @@ public class FileItemIteratorImpl implements FileItemIterator { } else { final String fileName = fileUploadBase.getFileName(headers); if (fileName != null) { - currentItem = new FileItemStreamImpl(this, fileName, - currentFieldName, - headers.getHeader(FileUploadBase.CONTENT_TYPE), - false, getContentLength(headers)); + currentItem = new FileItemStreamImpl(this, fileName, currentFieldName, headers.getHeader(FileUploadBase.CONTENT_TYPE), false, + getContentLength(headers)); currentItem.setHeaders(headers); progressNotifier.noteItem(); itemValid = true; @@ -215,8 +206,7 @@ public class FileItemIteratorImpl implements FileItemIterator { 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()); + final FileItem fi = fileUploadBase.getFileItemFactory().createItem(fis.getFieldName(), fis.getContentType(), fis.isFormField(), fis.getName()); items.add(fi); } return items; @@ -240,14 +230,11 @@ public class FileItemIteratorImpl implements FileItemIterator { } /** - * Returns, whether another instance of {@link FileItemStream} - * is available. + * 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. + * @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 { @@ -257,48 +244,36 @@ public class FileItemIteratorImpl implements FileItemIterator { if (itemValid) { return true; } - try { - return findNextItem(); - } catch (final FileUploadIOException e) { - // unwrap encapsulated SizeException - throw (FileUploadException) e.getCause(); - } + return findNextItem(); } - protected void init(final FileUploadBase fileUploadBase, final RequestContext pRequestContext) - throws FileUploadException, IOException { + protected void init(final FileUploadBase fileUploadBase, final RequestContext pRequestContext) throws FileUploadException, IOException { final String contentType = ctx.getContentType(); - if ((null == contentType) - || (!contentType.toLowerCase(Locale.ENGLISH).startsWith(FileUploadBase.MULTIPART))) { - throw new InvalidContentTypeException( - format("the request doesn't contain a %s or %s stream, content type header is %s", - FileUploadBase.MULTIPART_FORM_DATA, FileUploadBase.MULTIPART_MIXED, contentType)); + if ((null == contentType) || (!contentType.toLowerCase(Locale.ENGLISH).startsWith(FileUploadBase.MULTIPART))) { + throw new FileUploadContentTypeException(format("the request doesn't contain a %s or %s stream, content type header is %s", + FileUploadBase.MULTIPART_FORM_DATA, FileUploadBase.MULTIPART_MIXED, contentType), contentType); } final long contentLengthInt = ((UploadContext) ctx).contentLength(); + // @formatter:off final long requestSize = UploadContext.class.isAssignableFrom(ctx.getClass()) // Inline conditional is OK here CHECKSTYLE:OFF ? ((UploadContext) ctx).contentLength() : contentLengthInt; // CHECKSTYLE:ON - + // @formatter:on final InputStream input; // N.B. this is eventually closed in MultipartStream processing if (sizeMax >= 0) { if (requestSize != -1 && requestSize > sizeMax) { - throw new SizeLimitExceededException( - format("the request was rejected because its size (%s) exceeds the configured maximum (%s)", - requestSize, sizeMax), - requestSize, sizeMax); + throw new FileUploadSizeException( + format("the request was rejected because its size (%s) exceeds the configured maximum (%s)", requestSize, sizeMax), sizeMax, + requestSize); } // N.B. this is eventually closed in MultipartStream processing input = new LimitedInputStream(ctx.getInputStream(), sizeMax) { @Override - protected void raiseError(final long pSizeMax, final long pCount) - throws IOException { - final FileUploadException ex = new SizeLimitExceededException( - format("the request was rejected because its size (%s) exceeds the configured maximum (%s)", - pCount, pSizeMax), - pCount, pSizeMax); - throw new FileUploadIOException(ex); + protected void raiseError(final long pSizeMax, final long pCount) throws IOException { + throw new FileUploadSizeException( + format("The request was rejected because its size (%s) exceeds the configured maximum (%s)", pCount, pSizeMax), pSizeMax, pCount); } }; } else { @@ -319,10 +294,9 @@ public class FileItemIteratorImpl implements FileItemIterator { progressNotifier = new MultipartStream.ProgressNotifier(fileUploadBase.getProgressListener(), requestSize); try { multiPartStream = new MultipartStream(input, multiPartBoundary, progressNotifier); - } catch (final IllegalArgumentException iae) { + } catch (final IllegalArgumentException e) { IOUtils.closeQuietly(input); // avoid possible resource leak - throw new InvalidContentTypeException( - format("The boundary specified in the %s header is too long", FileUploadBase.CONTENT_TYPE), iae); + throw new FileUploadContentTypeException(format("The boundary specified in the %s header is too long", FileUploadBase.CONTENT_TYPE), e); } multiPartStream.setHeaderEncoding(charEncoding); } @@ -330,17 +304,14 @@ public class FileItemIteratorImpl implements FileItemIterator { /** * 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. + * @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())) { + if (eof || (!itemValid && !hasNext())) { throw new NoSuchElementException(); } itemValid = false; diff --git a/src/main/java/org/apache/commons/fileupload2/impl/FileItemStreamImpl.java b/src/main/java/org/apache/commons/fileupload2/impl/FileItemStreamImpl.java index ca23a5b..0d3d260 100644 --- a/src/main/java/org/apache/commons/fileupload2/impl/FileItemStreamImpl.java +++ b/src/main/java/org/apache/commons/fileupload2/impl/FileItemStreamImpl.java @@ -26,13 +26,11 @@ import org.apache.commons.fileupload2.FileItemStream; import org.apache.commons.fileupload2.FileUploadException; import org.apache.commons.fileupload2.InvalidFileNameException; import org.apache.commons.fileupload2.MultipartStream.ItemInputStream; -import org.apache.commons.fileupload2.pub.FileSizeLimitExceededException; -import org.apache.commons.fileupload2.pub.FileUploadIOException; +import org.apache.commons.fileupload2.pub.FileUploadByteCountLimitException; import org.apache.commons.fileupload2.util.Closeable; import org.apache.commons.fileupload2.util.LimitedInputStream; import org.apache.commons.fileupload2.util.Streams; - /** * Default implementation of {@link FileItemStream}. */ @@ -57,7 +55,7 @@ public class FileItemStreamImpl implements FileItemStream { /** * The file items file name. */ - private final String name; + private final String fileName; /** * Whether the file item is a form field. @@ -67,7 +65,7 @@ public class FileItemStreamImpl implements FileItemStream { /** * The file items input stream. */ - private final InputStream stream; + private final InputStream inputStream; /** * The headers, if any. @@ -77,57 +75,42 @@ public class FileItemStreamImpl implements FileItemStream { /** * Creates a new instance. * - * @param pFileItemIterator The {@link FileItemIteratorImpl iterator}, which returned this file - * item. - * @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. + * @param fileItemIterator The {@link FileItemIteratorImpl iterator}, which returned this file item. + * @param pFileName The items file name, or null. + * @param pFieldName The items field name. + * @param contentType The items content type, or null. + * @param formField Whether the item is a form field. + * @param contentLength The items content length, if known, or -1 + * @throws IOException Creating the file item failed. * @throws FileUploadException Parsing the incoming data stream failed. */ - public FileItemStreamImpl(final FileItemIteratorImpl pFileItemIterator, final String pName, final String pFieldName, - final String pContentType, final boolean pFormField, - final long pContentLength) throws FileUploadException, IOException { - fileItemIteratorImpl = pFileItemIterator; - name = pName; - fieldName = pFieldName; - contentType = pContentType; - formField = pFormField; + public FileItemStreamImpl(final FileItemIteratorImpl fileItemIterator, final String pFileName, final String pFieldName, final String contentType, + final boolean formField, final long contentLength) throws FileUploadException, IOException { + this.fileItemIteratorImpl = fileItemIterator; + this.fileName = pFileName; + this.fieldName = pFieldName; + this.contentType = contentType; + this.formField = formField; final long fileSizeMax = fileItemIteratorImpl.getFileSizeMax(); - if (fileSizeMax != -1 && pContentLength != -1 - && pContentLength > fileSizeMax) { - final FileSizeLimitExceededException e = - new FileSizeLimitExceededException( - format("The field %s exceeds its maximum permitted size of %s bytes.", - fieldName, fileSizeMax), - pContentLength, fileSizeMax); - e.setFileName(pName); - e.setFieldName(pFieldName); - throw new FileUploadIOException(e); + if (fileSizeMax != -1 && contentLength != -1 && contentLength > fileSizeMax) { + throw new FileUploadByteCountLimitException( + format("The field %s exceeds its maximum permitted size of %s bytes.", fieldName, fileSizeMax), contentLength, fileSizeMax, pFileName, + pFieldName); } // OK to construct stream now - final ItemInputStream itemStream = fileItemIteratorImpl.getMultiPartStream().newInputStream(); - InputStream istream = itemStream; + final ItemInputStream itemInputStream = fileItemIteratorImpl.getMultiPartStream().newInputStream(); + InputStream istream = itemInputStream; if (fileSizeMax != -1) { istream = new LimitedInputStream(istream, fileSizeMax) { @Override - protected void raiseError(final long pSizeMax, final long pCount) - throws IOException { - itemStream.close(true); - final FileSizeLimitExceededException e = - new FileSizeLimitExceededException( - format("The field %s exceeds its maximum permitted size of %s bytes.", - fieldName, pSizeMax), - pCount, pSizeMax); - e.setFieldName(fieldName); - e.setFileName(name); - throw new FileUploadIOException(e); + protected void raiseError(final long sizeMax, final long count) throws IOException { + itemInputStream.close(true); + throw new FileUploadByteCountLimitException( + format("The field %s exceeds its maximum permitted size of %s bytes.", fieldName, sizeMax), count, sizeMax, fileName, fieldName); } }; } - stream = istream; + this.inputStream = istream; } /** @@ -136,7 +119,7 @@ public class FileItemStreamImpl implements FileItemStream { * @throws IOException An I/O error occurred. */ public void close() throws IOException { - stream.close(); + inputStream.close(); } /** @@ -173,21 +156,18 @@ public class FileItemStreamImpl implements FileItemStream { * 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(). + * @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); + return Streams.checkFileName(fileName); } /** * Returns, whether this is a form field. * - * @return True, if the item is a form field, - * otherwise false. + * @return True, if the item is a form field, otherwise false. */ @Override public boolean isFormField() { @@ -195,18 +175,17 @@ public class FileItemStreamImpl implements FileItemStream { } /** - * Returns an input stream, which may be used to - * read the items contents. + * 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()) { + if (((Closeable) inputStream).isClosed()) { throw new FileItemStream.ItemSkippedException(); } - return stream; + return inputStream; } /** diff --git a/src/main/java/org/apache/commons/fileupload2/pub/FileCountLimitExceededException.java b/src/main/java/org/apache/commons/fileupload2/pub/FileCountLimitExceededException.java deleted file mode 100644 index ac22341..0000000 --- a/src/main/java/org/apache/commons/fileupload2/pub/FileCountLimitExceededException.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.pub; - -import org.apache.commons.fileupload2.FileUploadException; - -/** - * This exception is thrown if a request contains more files than the specified - * limit. - */ -public class FileCountLimitExceededException extends FileUploadException { - - private static final long serialVersionUID = 2408766352570556046L; - - /** - * The limit that was exceeded. - */ - private final long limit; - - /** - * Creates a new instance. - * - * @param message The detail message - * @param limit The limit that was exceeded - */ - public FileCountLimitExceededException(final String message, final long limit) { - super(message); - this.limit = limit; - } - - /** - * Retrieves the limit that was exceeded. - * - * @return The limit that was exceeded by the request - */ - public long getLimit() { - return limit; - } -} diff --git a/src/main/java/org/apache/commons/fileupload2/pub/FileSizeLimitExceededException.java b/src/main/java/org/apache/commons/fileupload2/pub/FileUploadByteCountLimitException.java similarity index 51% rename from src/main/java/org/apache/commons/fileupload2/pub/FileSizeLimitExceededException.java rename to src/main/java/org/apache/commons/fileupload2/pub/FileUploadByteCountLimitException.java index d459532..2060233 100644 --- a/src/main/java/org/apache/commons/fileupload2/pub/FileSizeLimitExceededException.java +++ b/src/main/java/org/apache/commons/fileupload2/pub/FileUploadByteCountLimitException.java @@ -17,42 +17,42 @@ package org.apache.commons.fileupload2.pub; /** - * Thrown to indicate that A files size exceeds the configured maximum. + * Signals that a file size exceeds the configured maximum. */ -public class FileSizeLimitExceededException - extends SizeException { +public class FileUploadByteCountLimitException extends FileUploadSizeException { /** * The exceptions UID, for serializing an instance. */ - private static final long serialVersionUID = 8150776562029630058L; + private static final long serialVersionUID = 2; /** * File name of the item, which caused the exception. */ - private String fileName; + private final String fileName; /** * Field name of the item, which caused the exception. */ - private String fieldName; + private final String fieldName; /** - * Constructs a {@code SizeExceededException} with - * the specified detail message, and actual and permitted sizes. + * Constructs an instance with the specified detail message, and actual and permitted sizes. * - * @param message The detail message. + * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) * @param actual The actual request size. * @param permitted The maximum permitted request size. + * @param fileName File name of the item, which caused the exception. + * @param fieldName Field name of the item, which caused the exception. */ - public FileSizeLimitExceededException(final String message, final long actual, - final long permitted) { - super(message, actual, permitted); + public FileUploadByteCountLimitException(final String message, final long actual, final long permitted, final String fileName, final String fieldName) { + super(message, permitted, actual); + this.fileName = fieldName; + this.fieldName = fieldName; } /** - * Returns the field name of the item, which caused the - * exception. + * Gets the field name of the item, which caused the exception. * * @return Field name, if known, or null. */ @@ -61,8 +61,7 @@ public class FileSizeLimitExceededException } /** - * Returns the file name of the item, which caused the - * exception. + * Gets the file name of the item, which caused the exception. * * @return File name, if known, or null. */ @@ -70,25 +69,4 @@ public class FileSizeLimitExceededException return fileName; } - /** - * 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(final String pFieldName) { - fieldName = pFieldName; - } - - /** - * 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(final String pFileName) { - fileName = pFileName; - } - } diff --git a/src/main/java/org/apache/commons/fileupload2/pub/InvalidContentTypeException.java b/src/main/java/org/apache/commons/fileupload2/pub/FileUploadContentTypeException.java similarity index 51% rename from src/main/java/org/apache/commons/fileupload2/pub/InvalidContentTypeException.java rename to src/main/java/org/apache/commons/fileupload2/pub/FileUploadContentTypeException.java index 5fbb9c7..5c4b221 100644 --- a/src/main/java/org/apache/commons/fileupload2/pub/InvalidContentTypeException.java +++ b/src/main/java/org/apache/commons/fileupload2/pub/FileUploadContentTypeException.java @@ -19,43 +19,44 @@ package org.apache.commons.fileupload2.pub; import org.apache.commons.fileupload2.FileUploadException; /** - * Thrown to indicate that the request is not a multipart request. + * Signals that a request is not a multipart request. */ -public class InvalidContentTypeException - extends FileUploadException { +public class FileUploadContentTypeException extends FileUploadException { /** * The exceptions UID, for serializing an instance. */ - private static final long serialVersionUID = -9073026332015646668L; + private static final long serialVersionUID = 2; /** - * Constructs a {@code InvalidContentTypeException} with no - * detail message. + * The guilty content type. */ - public InvalidContentTypeException() { - } + private String contentType; /** - * Constructs an {@code InvalidContentTypeException} with - * the specified detail message. + * Constructs an instance with the specified detail message. * - * @param message The detail message. + * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) + * @param contentType The guilty content type. */ - public InvalidContentTypeException(final String message) { + public FileUploadContentTypeException(final String message, final String contentType) { super(message); + this.contentType = contentType; } /** - * Constructs an {@code InvalidContentTypeException} with - * the specified detail message and cause. + * Constructs an instance with the specified detail message and cause. * - * @param msg The detail message. + * @param message + * The detail message (which is saved for later retrieval + * by the {@link #getMessage()} method) * @param cause the original cause - * - * @since 1.3.1 */ - public InvalidContentTypeException(final String msg, final Throwable cause) { - super(msg, cause); + public FileUploadContentTypeException(final String message, final Throwable cause) { + super(message, cause); + } + + public String getContentType() { + return contentType; } } diff --git a/src/main/java/org/apache/commons/fileupload2/pub/IOFileUploadException.java b/src/main/java/org/apache/commons/fileupload2/pub/FileUploadFileCountLimitException.java similarity index 58% rename from src/main/java/org/apache/commons/fileupload2/pub/IOFileUploadException.java rename to src/main/java/org/apache/commons/fileupload2/pub/FileUploadFileCountLimitException.java index 9bdc450..666a92b 100644 --- a/src/main/java/org/apache/commons/fileupload2/pub/IOFileUploadException.java +++ b/src/main/java/org/apache/commons/fileupload2/pub/FileUploadFileCountLimitException.java @@ -1,43 +1,37 @@ -/* - * 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.pub; - -import java.io.IOException; - -import org.apache.commons.fileupload2.FileUploadException; - -/** - * Thrown to indicate an IOException. - */ -public class IOFileUploadException extends FileUploadException { - - /** - * The exceptions UID, for serializing an instance. - */ - private static final long serialVersionUID = 1749796615868477269L; - - /** - * Creates a new instance with the given cause. - * - * @param message The detail message. - * @param cause The exceptions cause. - */ - public IOFileUploadException(final String message, final IOException cause) { - super(message, cause); - } - -} +/* + * 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.pub; + +/** + * Signals that a request contains more files than the specified limit. + */ +public class FileUploadFileCountLimitException extends FileUploadSizeException { + + private static final long serialVersionUID = 2; + + /** + * Constructs an instance. + * + * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) + * @param limit The limit that was exceeded. + * @param actual The actual value. + */ + public FileUploadFileCountLimitException(final String message, final long limit, final long actual) { + super(message, limit, actual); + } + +} diff --git a/src/main/java/org/apache/commons/fileupload2/pub/FileUploadIOException.java b/src/main/java/org/apache/commons/fileupload2/pub/FileUploadIOException.java deleted file mode 100644 index cb3d876..0000000 --- a/src/main/java/org/apache/commons/fileupload2/pub/FileUploadIOException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.pub; - -import java.io.IOException; - -import org.apache.commons.fileupload2.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; - - /** - * Creates a {@code FileUploadIOException} with the - * given cause. - * - * @param cause The exceptions cause, if any, or null. - */ - public FileUploadIOException(final FileUploadException cause) { - super(cause); - } - -} diff --git a/src/main/java/org/apache/commons/fileupload2/pub/SizeException.java b/src/main/java/org/apache/commons/fileupload2/pub/FileUploadSizeException.java similarity index 65% rename from src/main/java/org/apache/commons/fileupload2/pub/SizeException.java rename to src/main/java/org/apache/commons/fileupload2/pub/FileUploadSizeException.java index f1cc963..b33fa56 100644 --- a/src/main/java/org/apache/commons/fileupload2/pub/SizeException.java +++ b/src/main/java/org/apache/commons/fileupload2/pub/FileUploadSizeException.java @@ -19,15 +19,14 @@ package org.apache.commons.fileupload2.pub; import org.apache.commons.fileupload2.FileUploadException; /** - * This exception is thrown, if a requests permitted size - * is exceeded. + * Signals that a requests permitted size is exceeded. */ -abstract class SizeException extends FileUploadException { +public class FileUploadSizeException extends FileUploadException { /** * Serial version UID, being used, if serialized. */ - private static final long serialVersionUID = -8776225574705254126L; + private static final long serialVersionUID = 2; /** * The actual size of the request. @@ -40,35 +39,33 @@ abstract class SizeException extends FileUploadException { private final long permitted; /** - * Creates a new instance. + * Constructs an instance. * - * @param message The detail message. - * @param actual The actual number of bytes in the request. - * @param permitted The requests size limit, in bytes. + * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) + * @param permitted The requests size limit. + * @param actual The actual values for the request. */ - protected SizeException(final String message, final long actual, final long permitted) { + public FileUploadSizeException(final String message, final long permitted, final long actual) { super(message); - this.actual = actual; this.permitted = permitted; + this.actual = actual; } /** - * Retrieves the actual size of the request. + * Gets 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. + * Gets the limit size of the request. * - * @return The permitted size of the request. - * @since 1.3 + * @return The limit size of the request. */ - public long getPermittedSize() { + public long getPermitted() { return permitted; } diff --git a/src/main/java/org/apache/commons/fileupload2/pub/SizeLimitExceededException.java b/src/main/java/org/apache/commons/fileupload2/pub/SizeLimitExceededException.java deleted file mode 100644 index c9c7343..0000000 --- a/src/main/java/org/apache/commons/fileupload2/pub/SizeLimitExceededException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.pub; - -/** - * 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} 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(final String message, final long actual, - final long permitted) { - super(message, actual, permitted); - } - -} diff --git a/src/main/java/org/apache/commons/fileupload2/servlet/ServletFileUpload.java b/src/main/java/org/apache/commons/fileupload2/servlet/ServletFileUpload.java index 24e03dd..c7fdf57 100644 --- a/src/main/java/org/apache/commons/fileupload2/servlet/ServletFileUpload.java +++ b/src/main/java/org/apache/commons/fileupload2/servlet/ServletFileUpload.java @@ -50,8 +50,6 @@ public class ServletFileUpload extends FileUpload { */ private static final String POST_METHOD = "POST"; - // ---------------------------------------------------------- Class methods - /** * Utility method that determines whether the request contains multipart * content. @@ -69,8 +67,6 @@ public class ServletFileUpload extends FileUpload { return FileUploadBase.isMultipartContent(new ServletRequestContext(request)); } - // ----------------------------------------------------------- Constructors - /** * Constructs an uninitialized instance of this class. A factory must be * configured, using {@code setFileItemFactory()}, before attempting @@ -110,8 +106,7 @@ public class ServletFileUpload extends FileUpload { * error while communicating with the client or a problem while * storing the uploaded content. */ - public FileItemIterator getItemIterator(final HttpServletRequest request) - throws FileUploadException, IOException { + public FileItemIterator getItemIterator(final HttpServletRequest request) throws FileUploadException, IOException { return super.getItemIterator(new ServletRequestContext(request)); } @@ -128,8 +123,7 @@ public class ServletFileUpload extends FileUpload { * * @since 1.3 */ - public Map<String, List<FileItem>> parseParameterMap(final HttpServletRequest request) - throws FileUploadException { + public Map<String, List<FileItem>> parseParameterMap(final HttpServletRequest request) throws FileUploadException { return parseParameterMap(new ServletRequestContext(request)); } @@ -145,8 +139,7 @@ public class ServletFileUpload extends FileUpload { * @throws FileUploadException if there are problems reading/parsing * the request or storing files. */ - public List<FileItem> parseRequest(final HttpServletRequest request) - throws FileUploadException { + public List<FileItem> parseRequest(final HttpServletRequest request) throws FileUploadException { return parseRequest(new ServletRequestContext(request)); } diff --git a/src/main/java/org/apache/commons/fileupload2/util/LimitedInputStream.java b/src/main/java/org/apache/commons/fileupload2/util/LimitedInputStream.java index 13ed38e..ab02cd9 100644 --- a/src/main/java/org/apache/commons/fileupload2/util/LimitedInputStream.java +++ b/src/main/java/org/apache/commons/fileupload2/util/LimitedInputStream.java @@ -45,12 +45,12 @@ public abstract class LimitedInputStream extends FilterInputStream implements Cl * Creates a new instance. * * @param inputStream The input stream, which shall be limited. - * @param pSizeMax The limit; no more than this number of bytes + * @param sizeMax The limit; no more than this number of bytes * shall be returned by the source stream. */ - public LimitedInputStream(final InputStream inputStream, final long pSizeMax) { + public LimitedInputStream(final InputStream inputStream, final long sizeMax) { super(inputStream); - sizeMax = pSizeMax; + this.sizeMax = sizeMax; } /** @@ -95,12 +95,12 @@ public abstract class LimitedInputStream extends FilterInputStream implements Cl * Called to indicate, that the input streams limit has * been exceeded. * - * @param pSizeMax The input streams limit, in bytes. - * @param pCount The actual number of bytes. + * @param sizeMax The input streams limit, in bytes. + * @param count The actual number of bytes. * @throws IOException The called method is expected * to raise an IOException. */ - protected abstract void raiseError(long pSizeMax, long pCount) + protected abstract void raiseError(long sizeMax, long count) throws IOException; /** diff --git a/src/main/java/org/apache/commons/fileupload2/util/Streams.java b/src/main/java/org/apache/commons/fileupload2/util/Streams.java index e2c925e..0927a72 100644 --- a/src/main/java/org/apache/commons/fileupload2/util/Streams.java +++ b/src/main/java/org/apache/commons/fileupload2/util/Streams.java @@ -144,12 +144,10 @@ public final class Streams { * @return Number of bytes, which have been copied. * @throws IOException An I/O error occurred. */ - public static long copy(final InputStream inputStream, - final OutputStream outputStream, final boolean closeOutputStream, - final byte[] buffer) - throws IOException { + public static long copy(final InputStream inputStream, final OutputStream outputStream, final boolean closeOutputStream, final byte[] buffer) + throws IOException { try (OutputStream out = outputStream; - InputStream in = inputStream) { + InputStream in = inputStream) { long total = 0; for (;;) { final int res = in.read(buffer); diff --git a/src/test/java/org/apache/commons/fileupload2/SizesTest.java b/src/test/java/org/apache/commons/fileupload2/SizesTest.java index 5db2156..574f35c 100644 --- a/src/test/java/org/apache/commons/fileupload2/SizesTest.java +++ b/src/test/java/org/apache/commons/fileupload2/SizesTest.java @@ -31,9 +31,8 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload2.disk.DiskFileItemFactory; -import org.apache.commons.fileupload2.pub.FileSizeLimitExceededException; -import org.apache.commons.fileupload2.pub.FileUploadIOException; -import org.apache.commons.fileupload2.pub.SizeLimitExceededException; +import org.apache.commons.fileupload2.pub.FileUploadSizeException; +import org.apache.commons.fileupload2.pub.FileUploadByteCountLimitException; import org.apache.commons.fileupload2.servlet.ServletFileUpload; import org.apache.commons.fileupload2.util.Streams; import org.junit.jupiter.api.Test; @@ -80,8 +79,8 @@ public class SizesTest { try { upload.parseRequest(req); fail("Expected exception."); - } catch (final FileSizeLimitExceededException e) { - assertEquals(30, e.getPermittedSize()); + } catch (final FileUploadByteCountLimitException e) { + assertEquals(30, e.getPermitted()); } } @@ -124,8 +123,8 @@ public class SizesTest { try { upload.parseRequest(req); fail("Expected exception."); - } catch (final FileSizeLimitExceededException e) { - assertEquals(5, e.getPermittedSize()); + } catch (final FileUploadByteCountLimitException e) { + assertEquals(5, e.getPermitted()); } // provided Content-Length is wrong, actual content is larger -> handled by LimitedInputStream @@ -135,8 +134,8 @@ public class SizesTest { try { upload.parseRequest(req); fail("Expected exception."); - } catch (final FileSizeLimitExceededException e) { - assertEquals(15, e.getPermittedSize()); + } catch (final FileUploadByteCountLimitException e) { + assertEquals(15, e.getPermitted()); } } @@ -214,8 +213,8 @@ public class SizesTest { try { upload.parseRequest(req); fail("Expected exception."); - } catch (final SizeLimitExceededException e) { - assertEquals(200, e.getPermittedSize()); + } catch (final FileUploadSizeException e) { + assertEquals(200, e.getPermitted()); } } @@ -269,7 +268,7 @@ public class SizesTest { try { // the header is still within size max -> this shall still succeed assertTrue(it.hasNext()); - } catch (final SizeLimitExceededException e) { + } catch (final FileUploadSizeException e) { fail(); } @@ -280,7 +279,7 @@ public class SizesTest { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); Streams.copy(stream, baos, true); fail(); - } catch (final FileUploadIOException e) { + } catch (final FileUploadException e) { // expected } } diff --git a/src/test/java/org/apache/commons/fileupload2/StreamingTest.java b/src/test/java/org/apache/commons/fileupload2/StreamingTest.java index d621ba1..f76c9b7 100644 --- a/src/test/java/org/apache/commons/fileupload2/StreamingTest.java +++ b/src/test/java/org/apache/commons/fileupload2/StreamingTest.java @@ -29,10 +29,10 @@ import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.Iterator; import java.util.List; + import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload2.disk.DiskFileItemFactory; -import org.apache.commons.fileupload2.pub.IOFileUploadException; import org.apache.commons.fileupload2.servlet.ServletFileUpload; import org.apache.commons.fileupload2.servlet.ServletRequestContext; import org.junit.jupiter.api.Test; @@ -186,7 +186,7 @@ public class StreamingTest { try { parseUpload(invalidRequest); fail("Expected EndOfStreamException"); - } catch (final IOFileUploadException e) { + } catch (final FileUploadException e) { assertTrue(e.getCause() instanceof MultipartStream.MalformedStreamException); } }
