From f5eace782d040a0334be490f05519d231b63c8c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Yuan=2EWang-=E7=8E=8B=E5=9E=A3?= The default implementation of the
* {@link FileItem FileItem} interface.
@@ -32,8 +33,6 @@ import com.fr.third.org.apache.commons.fileupload.disk.DiskFileItem;
* {@link #getInputStream()} and process the file without attempting to load
* it into memory, which may come handy with large files.
*
- * @version $Id$
- *
* @deprecated 1.1 Use The default {@link FileItemFactory}
* implementation. This implementation creates
@@ -28,7 +29,7 @@ import com.fr.third.org.apache.commons.fileupload.disk.DiskFileItemFactory;
* disk, is configurable, as is the directory in which temporary files will be
* created. If not otherwise configured, the default configuration values are as
* follows:
* High level API for processing file uploads.DiskFileItem
instead.
*/
@Deprecated
@@ -42,11 +41,6 @@ public class DefaultFileItem
// ----------------------------------------------------------- Constructors
- /**
- * The UID to use when serializing this instance.
- */
- private static final long serialVersionUID = 4088572813833518255L;
-
/**
* Constructs a new DefaultFileItem
instance.
*
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DefaultFileItemFactory.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DefaultFileItemFactory.java
index edf0e8967..516d64e42 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DefaultFileItemFactory.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DefaultFileItemFactory.java
@@ -16,9 +16,10 @@
*/
package com.fr.third.org.apache.commons.fileupload;
-import java.io.File;
import com.fr.third.org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import java.io.File;
+
/**
*
*
*
- * @version $Id$
- *
* @deprecated 1.1 Use System.getProperty("java.io.tmpdir")
.
* DiskFileItemFactory
instead.
*/
@Deprecated
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DiskFileUpload.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DiskFileUpload.java
index 44ce5e556..bc12aa4fc 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DiskFileUpload.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DiskFileUpload.java
@@ -16,9 +16,9 @@
*/
package com.fr.third.org.apache.commons.fileupload;
+import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.List;
-import javax.servlet.http.HttpServletRequest;
/**
*
ServletFileUpload
together with
* DiskFileItemFactory
instead.
*/
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileCountLimitExceededException.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileCountLimitExceededException.java
new file mode 100644
index 000000000..bc644635f
--- /dev/null
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileCountLimitExceededException.java
@@ -0,0 +1,51 @@
+/*
+ * 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 com.fr.third.org.apache.commons.fileupload;
+
+/**
+ * This exception is thrown if a request contains more files than the specified
+ * limit.
+ */
+public class FileCountLimitExceededException extends FileUploadException {
+
+ private static final long serialVersionUID = 6904179610227521789L;
+
+ /**
+ * 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/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItem.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItem.java
index d7772b2f2..0d83a043d 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItem.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItem.java
@@ -22,7 +22,6 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.Serializable;
import java.io.UnsupportedEncodingException;
/**
@@ -34,7 +33,7 @@ import java.io.UnsupportedEncodingException;
* {@link ServletFileUpload
* #parseRequest(javax.servlet.http.HttpServletRequest)}), you may
* either request all contents of the file at once using {@link #get()} or
- * request an {@link java.io.InputStream InputStream} with
+ * request an {@link InputStream InputStream} with
* {@link #getInputStream()} and process the file without attempting to load
* it into memory, which may come handy with large files.
*
@@ -45,18 +44,17 @@ import java.io.UnsupportedEncodingException;
* implementation of this interface to also implement
* javax.activation.DataSource
with minimal additional work.
*
- * @version $Id$
* @since 1.3 additionally implements FileItemHeadersSupport
*/
-public interface FileItem extends Serializable, FileItemHeadersSupport {
+public interface FileItem extends FileItemHeadersSupport {
// ------------------------------- Methods from javax.activation.DataSource
/**
- * Returns an {@link java.io.InputStream InputStream} that can be
+ * Returns an {@link InputStream InputStream} that can be
* used to retrieve the contents of the file.
*
- * @return An {@link java.io.InputStream InputStream} that can be
+ * @return An {@link InputStream InputStream} that can be
* used to retrieve the contents of the file.
*
* @throws IOException if an error occurs.
@@ -195,10 +193,10 @@ public interface FileItem extends Serializable, FileItemHeadersSupport {
void setFormField(boolean state);
/**
- * Returns an {@link java.io.OutputStream OutputStream} that can
+ * Returns an {@link OutputStream OutputStream} that can
* be used for storing the contents of the file.
*
- * @return An {@link java.io.OutputStream OutputStream} that can be used
+ * @return An {@link OutputStream OutputStream} that can be used
* for storing the contensts of the file.
*
* @throws IOException if an error occurs.
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemFactory.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemFactory.java
index da5782cad..90af20469 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemFactory.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemFactory.java
@@ -20,8 +20,6 @@ package com.fr.third.org.apache.commons.fileupload;
* A factory interface for creating {@link FileItem} instances. Factories * can provide their own custom configuration, over and above that provided * by the default file upload implementation.
- * - * @version $Id$ */ public interface FileItemFactory { diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemHeaders.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemHeaders.java index 19d7d901f..b41da70af 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemHeaders.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemHeaders.java @@ -24,8 +24,6 @@ import java.util.Iterator; * request. * * @since 1.2.1 - * - * @version $Id$ */ public interface FileItemHeaders { diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemHeadersSupport.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemHeadersSupport.java index 5e22af909..58a6f0845 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemHeadersSupport.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemHeadersSupport.java @@ -24,8 +24,6 @@ package com.fr.third.org.apache.commons.fileupload; * * @see FileItem * @see FileItemStream - * - * @version $Id$ */ public interface FileItemHeadersSupport { diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemIterator.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemIterator.java index d03715740..11fc6b0b7 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemIterator.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemIterator.java @@ -21,8 +21,6 @@ import java.io.IOException; /** * An iterator, as returned by * {@link FileUploadBase#getItemIterator(RequestContext)}. - * - * @version $Id$ */ public interface FileItemIterator { diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemStream.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemStream.java index 41433990b..e177e0984 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemStream.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemStream.java @@ -30,8 +30,6 @@ import java.io.InputStream; * its associated instances of {@link FileItemStream}: By invoking * {@link java.util.Iterator#hasNext()} on the iterator, you discard all data, * which hasn't been read so far from the previous data. - * - * @version $Id$ */ public interface FileItemStream extends FileItemHeadersSupport { @@ -42,7 +40,7 @@ public interface FileItemStream extends FileItemHeadersSupport { * {@link java.util.Iterator#hasNext()} has been invoked on the * iterator, which created the {@link FileItemStream}. */ - public static class ItemSkippedException extends IOException { + class ItemSkippedException extends IOException { /** * The exceptions serial version UID, which is being used diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUpload.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUpload.java index f90fa9e18..affea4309 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUpload.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUpload.java @@ -29,8 +29,6 @@ package com.fr.third.org.apache.commons.fileupload; *How the data for individual parts is stored is determined by the factory * used to create them; a given part may be in memory, on disk, or somewhere * else.
- * - * @version $Id$ */ public class FileUpload extends FileUploadBase { diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUploadBase.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUploadBase.java index 44a8f3e32..3921ab267 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUploadBase.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUploadBase.java @@ -16,8 +16,15 @@ */ package com.fr.third.org.apache.commons.fileupload; -import static java.lang.String.format; +import com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload; +import com.fr.third.org.apache.commons.fileupload.servlet.ServletRequestContext; +import com.fr.third.org.apache.commons.fileupload.util.Closeable; +import com.fr.third.org.apache.commons.fileupload.util.FileItemHeadersImpl; +import com.fr.third.org.apache.commons.fileupload.util.LimitedInputStream; +import com.fr.third.org.apache.commons.fileupload.util.Streams; +import com.fr.third.org.apache.commons.io.IOUtils; +import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; @@ -29,15 +36,7 @@ import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; -import javax.servlet.http.HttpServletRequest; - -import com.fr.third.org.apache.commons.fileupload.MultipartStream.ItemInputStream; -import com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload; -import com.fr.third.org.apache.commons.fileupload.servlet.ServletRequestContext; -import com.fr.third.org.apache.commons.fileupload.util.Closeable; -import com.fr.third.org.apache.commons.fileupload.util.FileItemHeadersImpl; -import com.fr.third.org.apache.commons.fileupload.util.LimitedInputStream; -import com.fr.third.org.apache.commons.fileupload.util.Streams; +import static java.lang.String.format; /** *High level API for processing file uploads.
@@ -52,8 +51,6 @@ import com.fr.third.org.apache.commons.fileupload.util.Streams; *How the data for individual parts is stored is determined by the factory * used to create them; a given part may be in memory, on disk, or somewhere * else.
- * - * @version $Id$ */ public abstract class FileUploadBase { @@ -166,6 +163,12 @@ public abstract class FileUploadBase { */ private long fileSizeMax = -1; + /** + * The maximum permitted number of files that may be uploaded in a single + * request. A value of -1 indicates no maximum. + */ + private long fileCountMax = -1; + /** * The content encoding to use when reading part headers. */ @@ -242,6 +245,25 @@ public abstract class FileUploadBase { this.fileSizeMax = fileSizeMax; } + /** + * Returns the maximum number of files allowed in a single request. + * + * @return The maximum number of files allowed in a single request. + */ + public long getFileCountMax() { + return fileCountMax; + } + + /** + * Sets the maximum number of files allowed per request. + * + * @param fileCountMax The new limit. {@code -1} means no limit. + */ + public void setFileCountMax(final long fileCountMax) { + this.fileCountMax = fileCountMax; + } + + /** * Retrieves the character encoding used when reading the headers of an * individual part. When not specified, ornull
, the request
@@ -333,10 +355,15 @@ public abstract class FileUploadBase {
try {
FileItemIterator iter = getItemIterator(ctx);
FileItemFactory fac = getFileItemFactory();
+ final byte[] buffer = new byte[Streams.DEFAULT_BUFFER_SIZE];
if (fac == null) {
throw new NullPointerException("No FileItemFactory has been set.");
}
while (iter.hasNext()) {
+ if (items.size() == fileCountMax) {
+ // The next item will exceed the limit.
+ throw new FileCountLimitExceededException(ATTACHMENT, getFileCountMax());
+ }
final FileItemStream item = iter.next();
// Don't use getName() here to prevent an InvalidFileNameException.
final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name;
@@ -344,7 +371,7 @@ public abstract class FileUploadBase {
item.isFormField(), fileName);
items.add(fileItem);
try {
- Streams.copy(item.openStream(), fileItem.getOutputStream(), true);
+ Streams.copy(item.openStream(), fileItem.getOutputStream(), true, buffer);
} catch (FileUploadIOException e) {
throw (FileUploadException) e.getCause();
} catch (IOException e) {
@@ -365,8 +392,8 @@ public abstract class FileUploadBase {
for (FileItem fileItem : items) {
try {
fileItem.delete();
- } catch (Throwable e) {
- // ignore it
+ } catch (Exception ignored) {
+ // ignored TODO perhaps add to tracker delete failure list somehow?
}
}
}
@@ -765,20 +792,23 @@ public abstract class FileUploadBase {
fieldName = pFieldName;
contentType = pContentType;
formField = pFormField;
- final ItemInputStream itemStream = multi.newInputStream();
- InputStream istream = itemStream;
- if (fileSizeMax != -1) {
+ if (fileSizeMax != -1) { // Check if limit is already exceeded
if (pContentLength != -1
- && pContentLength > fileSizeMax) {
+ && pContentLength > fileSizeMax) {
FileSizeLimitExceededException e =
- new FileSizeLimitExceededException(
- format("The field %s exceeds its maximum permitted size of %s bytes.",
- fieldName, Long.valueOf(fileSizeMax)),
- pContentLength, fileSizeMax);
+ new FileSizeLimitExceededException(
+ 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 MultipartStream.ItemInputStream itemStream = multi.newInputStream();
+ InputStream istream = itemStream;
+ if (fileSizeMax != -1) {
istream = new LimitedInputStream(istream, fileSizeMax) {
@Override
protected void raiseError(long pSizeMax, long pCount)
@@ -803,6 +833,7 @@ public abstract class FileUploadBase {
*
* @return Content type, if known, or null.
*/
+ @Override
public String getContentType() {
return contentType;
}
@@ -812,6 +843,7 @@ public abstract class FileUploadBase {
*
* @return Field name.
*/
+ @Override
public String getFieldName() {
return fieldName;
}
@@ -825,6 +857,7 @@ public abstract class FileUploadBase {
* use the file name anyways, catch the exception and use
* InvalidFileNameException#getName().
*/
+ @Override
public String getName() {
return Streams.checkFileName(name);
}
@@ -835,6 +868,7 @@ public abstract class FileUploadBase {
* @return True, if the item is a form field,
* otherwise false.
*/
+ @Override
public boolean isFormField() {
return formField;
}
@@ -846,13 +880,14 @@ public abstract class FileUploadBase {
* @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();
+ throw new ItemSkippedException();
}
return stream;
}
@@ -871,6 +906,7 @@ public abstract class FileUploadBase {
*
* @return The items header object
*/
+ @Override
public FileItemHeaders getHeaders() {
return headers;
}
@@ -880,6 +916,7 @@ public abstract class FileUploadBase {
*
* @param pHeaders The items header object
*/
+ @Override
public void setHeaders(FileItemHeaders pHeaders) {
headers = pHeaders;
}
@@ -949,7 +986,6 @@ public abstract class FileUploadBase {
MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType));
}
- InputStream input = ctx.getInputStream();
@SuppressWarnings("deprecation") // still has to be backward compatible
final int contentLengthInt = ctx.getContentLength();
@@ -960,6 +996,7 @@ public abstract class FileUploadBase {
: contentLengthInt;
// CHECKSTYLE:ON
+ InputStream input; // N.B. this is eventually closed in MultipartStream processing
if (sizeMax >= 0) {
if (requestSize != -1 && requestSize > sizeMax) {
throw new SizeLimitExceededException(
@@ -967,7 +1004,8 @@ public abstract class FileUploadBase {
Long.valueOf(requestSize), Long.valueOf(sizeMax)),
requestSize, sizeMax);
}
- input = new LimitedInputStream(input, 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 {
@@ -978,6 +1016,8 @@ public abstract class FileUploadBase {
throw new FileUploadIOException(ex);
}
};
+ } else {
+ input = ctx.getInputStream();
}
String charEncoding = headerEncoding;
@@ -987,6 +1027,7 @@ public abstract class FileUploadBase {
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");
}
@@ -994,6 +1035,7 @@ public abstract class FileUploadBase {
try {
multi = new MultipartStream(input, boundary, notifier);
} catch (IllegalArgumentException iae) {
+ IOUtils.closeQuietly(input); // avoid possible resource leak
throw new InvalidContentTypeException(
format("The boundary specified in the %s header is too long", CONTENT_TYPE), iae);
}
@@ -1095,6 +1137,7 @@ public abstract class FileUploadBase {
* @return True, if one or more additional file items
* are available, otherwise false.
*/
+ @Override
public boolean hasNext() throws FileUploadException, IOException {
if (eof) {
return false;
@@ -1113,7 +1156,7 @@ public abstract class FileUploadBase {
/**
* Returns the next available {@link FileItemStream}.
*
- * @throws java.util.NoSuchElementException No more items are
+ * @throws NoSuchElementException No more items are
* available. Use {@link #hasNext()} to prevent this exception.
* @throws FileUploadException Parsing or processing the
* file item failed.
@@ -1121,6 +1164,7 @@ public abstract class FileUploadBase {
* @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();
@@ -1361,7 +1405,7 @@ public abstract class FileUploadBase {
/**
* @deprecated 1.2 Replaced by
- * {@code SizeLimitExceededException(String, long, long)}
+ * {@link #SizeLimitExceededException(String, long, long)}
*/
@Deprecated
public SizeLimitExceededException() {
@@ -1370,7 +1414,7 @@ public abstract class FileUploadBase {
/**
* @deprecated 1.2 Replaced by
- * {@code #SizeLimitExceededException(String, long, long)}
+ * {@link #SizeLimitExceededException(String, long, long)}
* @param message The exceptions detail message.
*/
@Deprecated
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUploadException.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUploadException.java
index 29ec77534..d7025dbf3 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUploadException.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUploadException.java
@@ -21,8 +21,6 @@ import java.io.PrintWriter;
/**
* Exception for errors encountered while processing the request.
- *
- * @version $Id$
*/
public class FileUploadException extends Exception {
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/InvalidFileNameException.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/InvalidFileNameException.java
index e604d90f3..fd17f563e 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/InvalidFileNameException.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/InvalidFileNameException.java
@@ -25,8 +25,6 @@ package com.fr.third.org.apache.commons.fileupload;
* checks for the extension ".png"), while, depending on the underlying
* C library, it might create a file named "foo.exe", as the NUL
* character is the string terminator in C.
- *
- * @version $Id$
*/
public class InvalidFileNameException extends RuntimeException {
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/MultipartStream.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/MultipartStream.java
index 5d1802fa0..d4716d49a 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/MultipartStream.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/MultipartStream.java
@@ -16,7 +16,9 @@
*/
package com.fr.third.org.apache.commons.fileupload;
-import static java.lang.String.format;
+import com.fr.third.org.apache.commons.fileupload.FileUploadBase.FileUploadIOException;
+import com.fr.third.org.apache.commons.fileupload.util.Closeable;
+import com.fr.third.org.apache.commons.fileupload.util.Streams;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -24,9 +26,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
-import com.fr.third.org.apache.commons.fileupload.FileUploadBase.FileUploadIOException;
-import com.fr.third.org.apache.commons.fileupload.util.Closeable;
-import com.fr.third.org.apache.commons.fileupload.util.Streams;
+import static java.lang.String.format;
/**
* Low level API for processing file uploads. @@ -80,8 +80,6 @@ import com.fr.third.org.apache.commons.fileupload.util.Streams; * // a read or write error occurred * } * - * - * @version $Id$ */ public class MultipartStream { @@ -222,12 +220,17 @@ public class MultipartStream { * The amount of data, in bytes, that must be kept in the buffer in order * to detect delimiters reliably. */ - private int keepRegion; + private final int keepRegion; /** * The byte sequence that partitions the stream. */ - private byte[] boundary; + private final byte[] boundary; + + /** + * The table for Knuth-Morris-Pratt search algorithm. + */ + private final int[] boundaryTable; /** * The length of the buffer used for processing the request. @@ -339,12 +342,14 @@ public class MultipartStream { this.notifier = pNotifier; this.boundary = new byte[this.boundaryLength]; + 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); + computeBoundaryTable(); head = 0; tail = 0; @@ -502,10 +507,35 @@ public class MultipartStream { throws IllegalBoundaryException { if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) { throw new IllegalBoundaryException( - "The length of a boundary token can not be changed"); + "The length of a boundary token cannot be changed"); } System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, boundary.length); + computeBoundaryTable(); + } + + /** + * Compute the table used for Knuth-Morris-Pratt search algorithm. + */ + private void computeBoundaryTable() { + int position = 2; + int candidate = 0; + + boundaryTable[0] = -1; + boundaryTable[1] = 0; + + while (position <= boundaryLength) { + if (boundary[position - 1] == boundary[candidate]) { + boundaryTable[position] = candidate + 1; + candidate++; + position++; + } else if (candidate > 0) { + candidate = boundaryTable[candidate]; + } else { + boundaryTable[position] = 0; + position++; + } + } } /** @@ -576,7 +606,7 @@ public class MultipartStream { *
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}).
+ * ProgressNotifier) constructor}).
*
* @param output The Stream
to write data into. May
* be null, in which case this method is equivalent
@@ -589,8 +619,7 @@ public class MultipartStream {
*/
public int readBodyData(OutputStream output)
throws MalformedStreamException, IOException {
- final InputStream istream = newInputStream();
- return (int) Streams.copy(istream, output, false);
+ return (int) Streams.copy(newInputStream(), output, false); // N.B. Streams.copy closes the input stream
}
/**
@@ -629,6 +658,7 @@ public class MultipartStream {
// First delimiter may be not preceeded with a CRLF.
System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2);
boundaryLength = boundary.length - 2;
+ computeBoundaryTable();
try {
// Discard all data up to the delimiter.
discardBodyData();
@@ -644,6 +674,7 @@ public class MultipartStream {
boundaryLength = boundary.length;
boundary[0] = CR;
boundary[1] = LF;
+ computeBoundaryTable();
}
}
@@ -699,23 +730,20 @@ public class MultipartStream {
* not found.
*/
protected int findSeparator() {
- int first;
- int match = 0;
- int maxpos = tail - boundaryLength;
- for (first = head; first <= maxpos && match != boundaryLength; first++) {
- first = findByte(boundary[0], first);
- if (first == -1 || first > maxpos) {
- return -1;
+
+ int bufferPos = this.head;
+ int tablePos = 0;
+
+ while (bufferPos < this.tail) {
+ while (tablePos >= 0 && buffer[bufferPos] != boundary[tablePos]) {
+ tablePos = boundaryTable[tablePos];
}
- for (match = 1; match < boundaryLength; match++) {
- if (buffer[first + match] != boundary[match]) {
- break;
- }
+ bufferPos++;
+ tablePos++;
+ if (tablePos == boundaryLength) {
+ return bufferPos - boundaryLength;
}
}
- if (match == boundaryLength) {
- return first - 1;
- }
return -1;
}
@@ -1023,6 +1051,7 @@ public class MultipartStream {
*
* @return True, if the stream is closed, otherwise false.
*/
+ @Override
public boolean isClosed() {
return closed;
}
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/ParameterParser.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/ParameterParser.java
index 34fa21832..5a79b7d5d 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/ParameterParser.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/ParameterParser.java
@@ -16,13 +16,13 @@
*/
package com.fr.third.org.apache.commons.fileupload;
+import com.fr.third.org.apache.commons.fileupload.util.mime.MimeUtility;
+
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
-import com.fr.third.org.apache.commons.fileupload.util.mime.MimeUtility;
-
/**
* A simple parser intended to parse sequences of name/value pairs.
*
@@ -33,8 +33,6 @@ import com.fr.third.org.apache.commons.fileupload.util.mime.MimeUtility;
*
* param1 = value; param2 = "anything goes; really"; param3
*
Abstracts access to the request information needed for file uploads. This @@ -25,8 +25,6 @@ import java.io.IOException; * handled by FileUpload, such as servlets and portlets.
* * @since FileUpload 1.1 - * - * @version $Id$ */ public interface RequestContext { diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/disk/DiskFileItem.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/disk/DiskFileItem.java index 033b88258..d8e887d5e 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/disk/DiskFileItem.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/disk/DiskFileItem.java @@ -16,33 +16,28 @@ */ package com.fr.third.org.apache.commons.fileupload.disk; -import static java.lang.String.format; +import com.fr.third.org.apache.commons.fileupload.FileItem; +import com.fr.third.org.apache.commons.fileupload.FileItemHeaders; +import com.fr.third.org.apache.commons.fileupload.FileUploadException; +import com.fr.third.org.apache.commons.fileupload.ParameterParser; +import com.fr.third.org.apache.commons.fileupload.util.Streams; +import com.fr.third.org.apache.commons.io.FileUtils; +import com.fr.third.org.apache.commons.io.IOUtils; +import com.fr.third.org.apache.commons.io.output.DeferredFileOutputStream; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Map; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; -import com.fr.third.org.apache.commons.fileupload.FileItem; -import com.fr.third.org.apache.commons.fileupload.FileItemHeaders; -import com.fr.third.org.apache.commons.fileupload.FileUploadException; -import com.fr.third.org.apache.commons.fileupload.InvalidFileNameException; -import com.fr.third.org.apache.commons.fileupload.ParameterParser; -import com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload; -import com.fr.third.org.apache.commons.fileupload.util.Streams; -import com.fr.third.org.apache.commons.io.IOUtils; -import com.fr.third.org.apache.commons.io.output.DeferredFileOutputStream; +import static java.lang.String.format; /** *The default implementation of the @@ -50,47 +45,34 @@ import com.fr.third.org.apache.commons.io.output.DeferredFileOutputStream; * *
After retrieving an instance of this class from a {@link * DiskFileItemFactory} instance (see - * {@link ServletFileUpload + * {@link com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may * either request all contents of file at once using {@link #get()} or - * request an {@link java.io.InputStream InputStream} with + * request an {@link InputStream InputStream} with * {@link #getInputStream()} and process the file without attempting to load * it into memory, which may come handy with large files. * *
Temporary files, which are created for file items, should be * deleted later on. The best way to do this is using a - * {@link org.apache.commons.io.FileCleaningTracker}, which you can set on the + * {@link com.fr.third.org.apache.commons.io.FileCleaningTracker}, which you can set on the * {@link DiskFileItemFactory}. However, if you do use such a tracker, * then you must consider the following: Temporary files are automatically * deleted as soon as they are no longer needed. (More precisely, when the - * corresponding instance of {@link java.io.File} is garbage collected.) + * corresponding instance of {@link File} is garbage collected.) * This is done by the so-called reaper thread, which is started and stopped - * automatically by the {@link org.apache.commons.io.FileCleaningTracker} when + * automatically by the {@link com.fr.third.org.apache.commons.io.FileCleaningTracker} when * there are files to be tracked. * It might make sense to terminate that thread, for example, if * your web application ends. See the section on "Resource cleanup" * in the users guide of commons-fileupload.
* * @since FileUpload 1.1 - * - * @version $Id$ */ public class DiskFileItem implements FileItem { - /** - * Although it implements {@link java.io.Serializable}, a DiskFileItem can actually only be deserialized, - * if this System property is true. - */ - public static final String SERIALIZABLE_PROPERTY = DiskFileItem.class.getName() + ".serializable"; - // ----------------------------------------------------- Manifest constants - /** - * The UID to use when serializing this instance. - */ - private static final long serialVersionUID = 2237570099615271025L; - /** * Default content charset to be used when no explicit charset * parameter is provided by the sender. Media subtypes of the @@ -166,14 +148,15 @@ public class DiskFileItem private transient File tempFile; /** - * File to allow for serialization of the content of this item. + * The file items headers. */ - private File dfosFile; + private FileItemHeaders headers; /** - * The file items headers. + * Default content charset to be used when no explicit charset + * parameter is provided by the sender. */ - private FileItemHeaders headers; + private String defaultCharset = DEFAULT_CHARSET; // ----------------------------------------------------------- Constructors @@ -208,14 +191,15 @@ public class DiskFileItem // ------------------------------- Methods from javax.activation.DataSource /** - * Returns an {@link java.io.InputStream InputStream} that can be + * Returns an {@link InputStream InputStream} that can be * used to retrieve the contents of the file. * - * @return An {@link java.io.InputStream InputStream} that can be + * @return An {@link InputStream InputStream} that can be * used to retrieve the contents of the file. * * @throws IOException if an error occurs. */ + @Override public InputStream getInputStream() throws IOException { if (!isInMemory()) { @@ -235,6 +219,7 @@ public class DiskFileItem * @return The content type passed by the agent ornull
if
* not defined.
*/
+ @Override
public String getContentType() {
return contentType;
}
@@ -258,11 +243,12 @@ public class DiskFileItem
* Returns the original filename in the client's filesystem.
*
* @return The original filename in the client's filesystem.
- * @throws InvalidFileNameException The file name contains a NUL character,
+ * @throws com.fr.third.org.apache.commons.fileupload.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
- * {@link InvalidFileNameException#getName()}.
+ * {@link com.fr.third.org.apache.commons.fileupload.InvalidFileNameException#getName()}.
*/
+ @Override
public String getName() {
return Streams.checkFileName(fileName);
}
@@ -276,6 +262,7 @@ public class DiskFileItem
* @return true
if the file contents will be read
* from memory; false
otherwise.
*/
+ @Override
public boolean isInMemory() {
if (cachedContent != null) {
return true;
@@ -288,6 +275,7 @@ public class DiskFileItem
*
* @return The size of the file, in bytes.
*/
+ @Override
public long getSize() {
if (size >= 0) {
return size;
@@ -305,11 +293,13 @@ public class DiskFileItem
* contents of the file were not yet cached in memory, they will be
* loaded from the disk storage and cached.
*
- * @return The contents of the file as an array of bytes.
+ * @return The contents of the file as an array of bytes
+ * or {@code null} if the data cannot be read
*/
+ @Override
public byte[] get() {
if (isInMemory()) {
- if (cachedContent == null) {
+ if (cachedContent == null && dfos != null) {
cachedContent = dfos.getData();
}
return cachedContent;
@@ -319,18 +309,12 @@ public class DiskFileItem
InputStream fis = null;
try {
- fis = new BufferedInputStream(new FileInputStream(dfos.getFile()));
- fis.read(fileData);
+ fis = new FileInputStream(dfos.getFile());
+ IOUtils.readFully(fis, fileData);
} catch (IOException e) {
fileData = null;
} finally {
- if (fis != null) {
- try {
- fis.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ IOUtils.closeQuietly(fis);
}
return fileData;
@@ -348,6 +332,7 @@ public class DiskFileItem
* @throws UnsupportedEncodingException if the requested character
* encoding is not available.
*/
+ @Override
public String getString(final String charset)
throws UnsupportedEncodingException {
return new String(get(), charset);
@@ -362,11 +347,12 @@ public class DiskFileItem
*
* @return The contents of the file, as a string.
*/
+ @Override
public String getString() {
byte[] rawdata = get();
String charset = getCharSet();
if (charset == null) {
- charset = DEFAULT_CHARSET;
+ charset = defaultCharset;
}
try {
return new String(rawdata, charset);
@@ -395,16 +381,16 @@ public class DiskFileItem
*
* @throws Exception if an error occurs.
*/
+ @Override
public void write(File file) throws Exception {
if (isInMemory()) {
FileOutputStream fout = null;
try {
fout = new FileOutputStream(file);
fout.write(get());
+ fout.close();
} finally {
- if (fout != null) {
- fout.close();
- }
+ IOUtils.closeQuietly(fout);
}
} else {
File outputFile = getStoreLocation();
@@ -416,32 +402,10 @@ public class DiskFileItem
* in a temporary location so move it to the
* desired file.
*/
- if (!outputFile.renameTo(file)) {
- BufferedInputStream in = null;
- BufferedOutputStream out = null;
- try {
- in = new BufferedInputStream(
- new FileInputStream(outputFile));
- out = new BufferedOutputStream(
- new FileOutputStream(file));
- IOUtils.copy(in, out);
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException e) {
- // ignore
- }
- }
- if (out != null) {
- try {
- out.close();
- } catch (IOException e) {
- // ignore
- }
- }
- }
+ if (file.exists()) {
+ file.delete();
}
+ FileUtils.moveFile(outputFile, file);
} else {
/*
* For whatever reason we cannot write the
@@ -460,10 +424,11 @@ public class DiskFileItem
* collected, this method can be used to ensure that this is done at an
* earlier time, thus preserving system resources.
*/
+ @Override
public void delete() {
cachedContent = null;
File outputFile = getStoreLocation();
- if (outputFile != null && outputFile.exists()) {
+ if (outputFile != null && !isInMemory() && outputFile.exists()) {
outputFile.delete();
}
}
@@ -474,9 +439,10 @@ public class DiskFileItem
*
* @return The name of the form field.
*
- * @see #setFieldName(java.lang.String)
+ * @see #setFieldName(String)
*
*/
+ @Override
public String getFieldName() {
return fieldName;
}
@@ -489,6 +455,7 @@ public class DiskFileItem
* @see #getFieldName()
*
*/
+ @Override
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
@@ -503,6 +470,7 @@ public class DiskFileItem
* @see #setFormField(boolean)
*
*/
+ @Override
public boolean isFormField() {
return isFormField;
}
@@ -517,19 +485,21 @@ public class DiskFileItem
* @see #isFormField()
*
*/
+ @Override
public void setFormField(boolean state) {
isFormField = state;
}
/**
- * Returns an {@link java.io.OutputStream OutputStream} that can
+ * Returns an {@link OutputStream OutputStream} that can
* be used for storing the contents of the file.
*
- * @return An {@link java.io.OutputStream OutputStream} that can be used
- * for storing the contensts of the file.
+ * @return An {@link OutputStream OutputStream} that can be used
+ * for storing the contents of the file.
*
* @throws IOException if an error occurs.
*/
+ @Override
public OutputStream getOutputStream()
throws IOException {
if (dfos == null) {
@@ -542,11 +512,11 @@ public class DiskFileItem
// --------------------------------------------------------- Public methods
/**
- * Returns the {@link java.io.File} object for the FileItem
's
+ * Returns the {@link File} object for the FileItem
's
* data's temporary location on the disk. Note that for
* FileItem
s that have their data stored in memory,
* this method will return null
. When handling large
- * files, you can use {@link java.io.File#renameTo(java.io.File)} to
+ * files, you can use {@link File#renameTo(File)} to
* move the file to new location without copying the data, if the
* source and destination locations reside within the same logical
* volume.
@@ -558,6 +528,9 @@ public class DiskFileItem
if (dfos == null) {
return null;
}
+ if (isInMemory()) {
+ return null;
+ }
return dfos.getFile();
}
@@ -568,6 +541,9 @@ public class DiskFileItem
*/
@Override
protected void finalize() {
+ if (dfos == null || dfos.isInMemory()) {
+ return;
+ }
File outputFile = dfos.getFile();
if (outputFile != null && outputFile.exists()) {
@@ -576,12 +552,15 @@ public class DiskFileItem
}
/**
- * Creates and returns a {@link java.io.File File} representing a uniquely
+ * Creates and returns a {@link File File} representing a uniquely
* named temporary file in the configured repository path. The lifetime of
* the file is tied to the lifetime of the FileItem
instance;
* the file will be deleted when the instance is garbage collected.
+ * + * Note: Subclasses that override this method must ensure that they return the + * same File each time. * - * @return The {@link java.io.File File} to be used for temporary storage. + * @return The {@link File File} to be used for temporary storage. */ protected File getTempFile() { if (tempFile == null) { @@ -601,7 +580,7 @@ public class DiskFileItem /** * Returns an identifier that is unique within the class loader used to - * load this class, but does not have random-like apearance. + * load this class, but does not have random-like appearance. * * @return A String with the non-random looking instance identifier. */ @@ -630,83 +609,11 @@ public class DiskFileItem Boolean.valueOf(isFormField()), getFieldName()); } - // -------------------------------------------------- Serialization methods - - /** - * Writes the state of this object during serialization. - * - * @param out The stream to which the state should be written. - * - * @throws IOException if an error occurs. - */ - private void writeObject(ObjectOutputStream out) throws IOException { - // Read the data - if (dfos.isInMemory()) { - cachedContent = get(); - } else { - cachedContent = null; - dfosFile = dfos.getFile(); - } - - // write out values - out.defaultWriteObject(); - } - - /** - * Reads the state of this object during deserialization. - * - * @param in The stream from which the state should be read. - * - * @throws IOException if an error occurs. - * @throws ClassNotFoundException if class cannot be found. - */ - private void readObject(ObjectInputStream in) - throws IOException, ClassNotFoundException { - if (!Boolean.getBoolean(SERIALIZABLE_PROPERTY)) { - throw new IllegalStateException("Property " + SERIALIZABLE_PROPERTY - + " is not true, rejecting to deserialize a DiskFileItem."); - } - // read values - in.defaultReadObject(); - - /* One expected use of serialization is to migrate HTTP sessions - * containing a DiskFileItem between JVMs. Particularly if the JVMs are - * on different machines It is possible that the repository location is - * not valid so validate it. - */ - if (repository != null) { - if (repository.isDirectory()) { - // Check path for nulls - if (repository.getPath().contains("\0")) { - throw new IOException(format( - "The repository [%s] contains a null character", - repository.getPath())); - } - } else { - throw new IOException(format( - "The repository [%s] is not a directory", - repository.getAbsolutePath())); - } - } - - OutputStream output = getOutputStream(); - if (cachedContent != null) { - output.write(cachedContent); - } else { - FileInputStream input = new FileInputStream(dfosFile); - IOUtils.copy(input, output); - dfosFile.delete(); - dfosFile = null; - } - output.close(); - - cachedContent = null; - } - /** * Returns the file item headers. * @return The file items headers. */ + @Override public FileItemHeaders getHeaders() { return headers; } @@ -715,8 +622,26 @@ public class DiskFileItem * Sets the file item headers. * @param pHeaders The file items headers. */ + @Override public void setHeaders(FileItemHeaders pHeaders) { headers = pHeaders; } + /** + * Returns the default charset for use when no explicit charset + * parameter is provided by the sender. + * @return the default charset + */ + public String getDefaultCharset() { + return defaultCharset; + } + + /** + * Sets the default charset for use when no explicit charset + * parameter is provided by the sender. + * @param charset the default charset + */ + public void setDefaultCharset(String charset) { + defaultCharset = charset; + } } diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/disk/DiskFileItemFactory.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/disk/DiskFileItemFactory.java index 8415a79a5..f2d787a39 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/disk/DiskFileItemFactory.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/disk/DiskFileItemFactory.java @@ -16,12 +16,12 @@ */ package com.fr.third.org.apache.commons.fileupload.disk; -import java.io.File; - -import com.fr.third.org.apache.commons.fileupload.FileItem; import com.fr.third.org.apache.commons.fileupload.FileItemFactory; +import com.fr.third.org.apache.commons.fileupload.FileItem; import com.fr.third.org.apache.commons.io.FileCleaningTracker; +import java.io.File; + /** *
The default {@link FileItemFactory} * implementation. This implementation creates @@ -57,7 +57,7 @@ import com.fr.third.org.apache.commons.io.FileCleaningTracker; * {@link DiskFileItemFactory}. However, if you do use such a tracker, * then you must consider the following: Temporary files are automatically * deleted as soon as they are no longer needed. (More precisely, when the - * corresponding instance of {@link java.io.File} is garbage collected.) + * corresponding instance of {@link File} is garbage collected.) * This is done by the so-called reaper thread, which is started and stopped * automatically by the {@link FileCleaningTracker} when there are files to be * tracked. @@ -66,8 +66,6 @@ import com.fr.third.org.apache.commons.io.FileCleaningTracker; * in the users guide of commons-fileupload.
* * @since FileUpload 1.1 - * - * @version $Id$ */ public class DiskFileItemFactory implements FileItemFactory { @@ -97,6 +95,12 @@ public class DiskFileItemFactory implements FileItemFactory { */ private FileCleaningTracker fileCleaningTracker; + /** + * Default content charset to be used when no explicit charset + * parameter is provided by the sender. + */ + private String defaultCharset = DiskFileItem.DEFAULT_CHARSET; + // ----------------------------------------------------------- Constructors /** @@ -130,7 +134,7 @@ public class DiskFileItemFactory implements FileItemFactory { * * @return The directory in which temporary files will be located. * - * @see #setRepository(java.io.File) + * @see #setRepository(File) * */ public File getRepository() { @@ -190,10 +194,12 @@ public class DiskFileItemFactory implements FileItemFactory { * * @return The newly created file item. */ + @Override public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) { DiskFileItem result = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + result.setDefaultCharset(defaultCharset); FileCleaningTracker tracker = getFileCleaningTracker(); if (tracker != null) { tracker.track(result.getTempFile(), result); @@ -224,4 +230,21 @@ public class DiskFileItemFactory implements FileItemFactory { fileCleaningTracker = pTracker; } + /** + * Returns the default charset for use when no explicit charset + * parameter is provided by the sender. + * @return the default charset + */ + public String getDefaultCharset() { + return defaultCharset; + } + + /** + * Sets the default charset for use when no explicit charset + * parameter is provided by the sender. + * @param pCharset the default charset + */ + public void setDefaultCharset(String pCharset) { + defaultCharset = pCharset; + } } diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/portlet/PortletFileUpload.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/portlet/PortletFileUpload.java index d970a040c..5fd1d7180 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/portlet/PortletFileUpload.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/portlet/PortletFileUpload.java @@ -16,19 +16,18 @@ */ package com.fr.third.org.apache.commons.fileupload.portlet; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import javax.portlet.ActionRequest; - -import com.fr.third.org.apache.commons.fileupload.FileItem; import com.fr.third.org.apache.commons.fileupload.FileItemFactory; -import com.fr.third.org.apache.commons.fileupload.FileItemIterator; import com.fr.third.org.apache.commons.fileupload.FileUpload; -import com.fr.third.org.apache.commons.fileupload.FileUploadBase; import com.fr.third.org.apache.commons.fileupload.FileUploadException; import com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload; +import com.fr.third.org.apache.commons.fileupload.FileItem; +import com.fr.third.org.apache.commons.fileupload.FileItemIterator; +import com.fr.third.org.apache.commons.fileupload.FileUploadBase; + +import javax.portlet.ActionRequest; +import java.io.IOException; +import java.util.List; +import java.util.Map; /** *High level API for processing file uploads.
@@ -46,8 +45,6 @@ import com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload; * else. * * @since FileUpload 1.1 - * - * @version $Id$ */ public class PortletFileUpload extends FileUpload { diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/portlet/PortletRequestContext.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/portlet/PortletRequestContext.java index d55305598..3963a2ede 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/portlet/PortletRequestContext.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/portlet/PortletRequestContext.java @@ -16,23 +16,20 @@ */ package com.fr.third.org.apache.commons.fileupload.portlet; -import static java.lang.String.format; +import com.fr.third.org.apache.commons.fileupload.FileUploadBase; +import com.fr.third.org.apache.commons.fileupload.UploadContext; +import javax.portlet.ActionRequest; import java.io.IOException; import java.io.InputStream; -import javax.portlet.ActionRequest; - -import com.fr.third.org.apache.commons.fileupload.FileUploadBase; -import com.fr.third.org.apache.commons.fileupload.UploadContext; +import static java.lang.String.format; /** *Provides access to the request information needed for a request made to * a portlet.
* * @since FileUpload 1.1 - * - * @version $Id$ */ public class PortletRequestContext implements UploadContext { @@ -63,6 +60,7 @@ public class PortletRequestContext implements UploadContext { * * @return The character encoding for the request. */ + @Override public String getCharacterEncoding() { return request.getCharacterEncoding(); } @@ -72,6 +70,7 @@ public class PortletRequestContext implements UploadContext { * * @return The content type of the request. */ + @Override public String getContentType() { return request.getContentType(); } @@ -82,6 +81,7 @@ public class PortletRequestContext implements UploadContext { * @return The content length of the request. * @deprecated 1.3 Use {@link #contentLength()} instead */ + @Override @Deprecated public int getContentLength() { return request.getContentLength(); @@ -93,6 +93,7 @@ public class PortletRequestContext implements UploadContext { * @return The content length of the request. * @since 1.3 */ + @Override public long contentLength() { long size; try { @@ -110,6 +111,7 @@ public class PortletRequestContext implements UploadContext { * * @throws IOException if a problem occurs. */ + @Override public InputStream getInputStream() throws IOException { return request.getPortletInputStream(); } diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/FileCleanerCleanup.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/FileCleanerCleanup.java index 58f75c8a1..ba91464b9 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/FileCleanerCleanup.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/FileCleanerCleanup.java @@ -16,18 +16,16 @@ */ package com.fr.third.org.apache.commons.fileupload.servlet; +import com.fr.third.org.apache.commons.io.FileCleaningTracker; + import javax.servlet.ServletContext; -import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; - -import com.fr.third.org.apache.commons.io.FileCleaningTracker; +import javax.servlet.ServletContextListener; /** * A servlet context listener, which ensures that the * {@link FileCleaningTracker}'s reaper thread is terminated, * when the web application is destroyed. - * - * @version $Id$ */ public class FileCleanerCleanup implements ServletContextListener { @@ -70,6 +68,7 @@ public class FileCleanerCleanup implements ServletContextListener { * @param sce The servlet context, used for calling * {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. */ + @Override public void contextInitialized(ServletContextEvent sce) { setFileCleaningTracker(sce.getServletContext(), new FileCleaningTracker()); @@ -82,6 +81,7 @@ public class FileCleanerCleanup implements ServletContextListener { * @param sce The servlet context, used for calling * {@link #getFileCleaningTracker(ServletContext)}. */ + @Override public void contextDestroyed(ServletContextEvent sce) { getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); } diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/ServletFileUpload.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/ServletFileUpload.java index 94abdbec5..29dd04b59 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/ServletFileUpload.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/ServletFileUpload.java @@ -16,18 +16,17 @@ */ package com.fr.third.org.apache.commons.fileupload.servlet; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -import com.fr.third.org.apache.commons.fileupload.FileItem; import com.fr.third.org.apache.commons.fileupload.FileItemFactory; -import com.fr.third.org.apache.commons.fileupload.FileItemIterator; import com.fr.third.org.apache.commons.fileupload.FileUpload; -import com.fr.third.org.apache.commons.fileupload.FileUploadBase; import com.fr.third.org.apache.commons.fileupload.FileUploadException; +import com.fr.third.org.apache.commons.fileupload.FileItem; +import com.fr.third.org.apache.commons.fileupload.FileItemIterator; +import com.fr.third.org.apache.commons.fileupload.FileUploadBase; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.List; +import java.util.Map; /** *High level API for processing file uploads.
@@ -42,8 +41,6 @@ import com.fr.third.org.apache.commons.fileupload.FileUploadException; *How the data for individual parts is stored is determined by the factory * used to create them; a given part may be in memory, on disk, or somewhere * else.
- * - * @version $Id$ */ public class ServletFileUpload extends FileUpload { diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/ServletRequestContext.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/ServletRequestContext.java index ae4fed385..6997e0e3f 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/ServletRequestContext.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/ServletRequestContext.java @@ -16,23 +16,20 @@ */ package com.fr.third.org.apache.commons.fileupload.servlet; -import static java.lang.String.format; +import com.fr.third.org.apache.commons.fileupload.UploadContext; +import com.fr.third.org.apache.commons.fileupload.FileUploadBase; +import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.InputStream; -import javax.servlet.http.HttpServletRequest; - -import com.fr.third.org.apache.commons.fileupload.FileUploadBase; -import com.fr.third.org.apache.commons.fileupload.UploadContext; +import static java.lang.String.format; /** *Provides access to the request information needed for a request made to * an HTTP servlet.
* * @since FileUpload 1.1 - * - * @version $Id$ */ public class ServletRequestContext implements UploadContext { @@ -61,6 +58,7 @@ public class ServletRequestContext implements UploadContext { * * @return The character encoding for the request. */ + @Override public String getCharacterEncoding() { return request.getCharacterEncoding(); } @@ -70,6 +68,7 @@ public class ServletRequestContext implements UploadContext { * * @return The content type of the request. */ + @Override public String getContentType() { return request.getContentType(); } @@ -80,6 +79,7 @@ public class ServletRequestContext implements UploadContext { * @return The content length of the request. * @deprecated 1.3 Use {@link #contentLength()} instead */ + @Override @Deprecated public int getContentLength() { return request.getContentLength(); @@ -91,6 +91,7 @@ public class ServletRequestContext implements UploadContext { * @return The content length of the request. * @since 1.3 */ + @Override public long contentLength() { long size; try { @@ -108,6 +109,7 @@ public class ServletRequestContext implements UploadContext { * * @throws IOException if a problem occurs. */ + @Override public InputStream getInputStream() throws IOException { return request.getInputStream(); } diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/Closeable.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/Closeable.java index 3128ca2c3..354f89914 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/Closeable.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/Closeable.java @@ -20,8 +20,6 @@ import java.io.IOException; /** * Interface of an object, which may be closed. - * - * @version $Id$ */ public interface Closeable { diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/FileItemHeadersImpl.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/FileItemHeadersImpl.java index 6632cef95..a2ad50e26 100644 --- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/FileItemHeadersImpl.java +++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/FileItemHeadersImpl.java @@ -16,6 +16,8 @@ */ package com.fr.third.org.apache.commons.fileupload.util; +import com.fr.third.org.apache.commons.fileupload.FileItemHeaders; + import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; @@ -25,14 +27,10 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import com.fr.third.org.apache.commons.fileupload.FileItemHeaders; - /** * Default implementation of the {@link FileItemHeaders} interface. * * @since 1.2.1 - * - * @version $Id$ */ public class FileItemHeadersImpl implements FileItemHeaders, Serializable { @@ -50,6 +48,7 @@ public class FileItemHeadersImpl implements FileItemHeaders, Serializable { /** * {@inheritDoc} */ + @Override public String getHeader(String name) { String nameLower = name.toLowerCase(Locale.ENGLISH); List-1
if the end of the
* stream is reached.
- * @exception IOException if an I/O error occurs.
- * @see java.io.FilterInputStream#in
+ * @throws IOException if an I/O error occurs.
+ * @see FilterInputStream#in
*/
@Override
public int read() throws IOException {
@@ -122,12 +120,12 @@ public abstract class LimitedInputStream extends FilterInputStream implements Cl
* @return the total number of bytes read into the buffer, or
* -1
if there is no more data because the end of
* the stream has been reached.
- * @exception NullPointerException If b
is null
.
- * @exception IndexOutOfBoundsException If off
is negative,
+ * @throws NullPointerException If b
is null
.
+ * @throws IndexOutOfBoundsException If off
is negative,
* len
is negative, or len
is greater than
* b.length - off
- * @exception IOException if an I/O error occurs.
- * @see java.io.FilterInputStream#in
+ * @throws IOException if an I/O error occurs.
+ * @see FilterInputStream#in
*/
@Override
public int read(byte[] b, int off, int len) throws IOException {
@@ -145,6 +143,7 @@ public abstract class LimitedInputStream extends FilterInputStream implements Cl
* @return True, if the stream is closed, otherwise false.
* @throws IOException An I/O error occurred.
*/
+ @Override
public boolean isClosed() throws IOException {
return closed;
}
@@ -155,8 +154,8 @@ public abstract class LimitedInputStream extends FilterInputStream implements Cl
* This
* method simply performs in.close()
.
*
- * @exception IOException if an I/O error occurs.
- * @see java.io.FilterInputStream#in
+ * @throws IOException if an I/O error occurs.
+ * @see FilterInputStream#in
*/
@Override
public void close() throws IOException {
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/Streams.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/Streams.java
index b6ca1e7bf..47d5c1ea5 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/Streams.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/Streams.java
@@ -16,19 +16,16 @@
*/
package com.fr.third.org.apache.commons.fileupload.util;
+import com.fr.third.org.apache.commons.fileupload.InvalidFileNameException;
+import com.fr.third.org.apache.commons.io.IOUtils;
+
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import com.fr.third.org.apache.commons.fileupload.FileItemStream;
-import com.fr.third.org.apache.commons.fileupload.InvalidFileNameException;
-import com.fr.third.org.apache.commons.io.IOUtils;
-
/**
* Utility class for working with streams.
- *
- * @version $Id$
*/
public final class Streams {
@@ -44,7 +41,7 @@ public final class Streams {
* Default buffer size for use in
* {@link #copy(InputStream, OutputStream, boolean)}.
*/
- private static final int DEFAULT_BUFFER_SIZE = 8192;
+ public static final int DEFAULT_BUFFER_SIZE = 8192;
/**
* Copies the contents of the given {@link InputStream}
@@ -130,7 +127,7 @@ public final class Streams {
/**
* This convenience method allows to read a
- * {@link FileItemStream}'s
+ * {@link com.fr.third.org.apache.commons.fileupload.FileItemStream}'s
* content into a string. The platform's default character encoding
* is used for converting bytes into characters.
*
@@ -147,7 +144,7 @@ public final class Streams {
/**
* This convenience method allows to read a
- * {@link FileItemStream}'s
+ * {@link com.fr.third.org.apache.commons.fileupload.FileItemStream}'s
* content into a string, using the given character encoding.
*
* @param inputStream The input stream to read.
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/Base64Decoder.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/Base64Decoder.java
index b3c7b5185..4822ba911 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/Base64Decoder.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/Base64Decoder.java
@@ -104,8 +104,8 @@ final class Base64Decoder {
* @throws IOException thrown when the padding is incorrect or the input is truncated.
*/
public static int decode(byte[] data, OutputStream out) throws IOException {
- int outLen = 0;
- byte [] cache = new byte[INPUT_BYTES_PER_CHUNK];
+ int outLen = 0;
+ byte[] cache = new byte[INPUT_BYTES_PER_CHUNK];
int cachedBytes = 0;
for (byte b : data) {
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/MimeUtility.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/MimeUtility.java
index 262a6ea51..cf4d92833 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/MimeUtility.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/MimeUtility.java
@@ -212,7 +212,7 @@ public final class MimeUtility {
}
// pull out the character set information (this is the MIME name at this point).
- String charset = word.substring(2, charsetPos).toLowerCase();
+ String charset = word.substring(2, charsetPos).toLowerCase(Locale.ENGLISH);
// now pull out the encoding token the same way.
int encodingPos = word.indexOf('?', charsetPos + 1);
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/ParseException.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/ParseException.java
index 794a45f1c..6b1ac7c74 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/ParseException.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/ParseException.java
@@ -31,7 +31,7 @@ final class ParseException extends Exception {
*
* @param message the detail message.
*/
- public ParseException(String message) {
+ ParseException(String message) {
super(message);
}
diff --git a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/QuotedPrintableDecoder.java b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/QuotedPrintableDecoder.java
index 33bd50062..c9754b43d 100644
--- a/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/QuotedPrintableDecoder.java
+++ b/fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/QuotedPrintableDecoder.java
@@ -44,7 +44,7 @@ final class QuotedPrintableDecoder {
* @param out The output stream used to return the decoded data.
*
* @return the number of bytes produced.
- * @exception IOException
+ * @throws IOException
*/
public static int decode(byte[] data, OutputStream out) throws IOException {
int off = 0;