Browse Source

Pull request #8386: REPORT-90265 apache commons fileupload升级到1.5

Merge in CORE/base-third from ~YUAN.WANG/base-third:release/10.0 to release/10.0

* commit 'f5eace782d040a0334be490f05519d231b63c8c7':
  REPORT-90265 apache commons fileupload升级到1.5
release/10.0
Yuan.Wang-王垣 2 years ago
parent
commit
1e786fa328
  1. 2
      fine-commons-fileupload/README.md
  2. 10
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DefaultFileItem.java
  3. 7
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DefaultFileItemFactory.java
  4. 4
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DiskFileUpload.java
  5. 51
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileCountLimitExceededException.java
  6. 14
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItem.java
  7. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemFactory.java
  8. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemHeaders.java
  9. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemHeadersSupport.java
  10. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemIterator.java
  11. 4
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemStream.java
  12. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUpload.java
  13. 92
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUploadBase.java
  14. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileUploadException.java
  15. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/InvalidFileNameException.java
  16. 79
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/MultipartStream.java
  17. 28
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/ParameterParser.java
  18. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/ProgressListener.java
  19. 4
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/RequestContext.java
  20. 251
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/disk/DiskFileItem.java
  21. 37
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/disk/DiskFileItemFactory.java
  22. 19
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/portlet/PortletFileUpload.java
  23. 16
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/portlet/PortletRequestContext.java
  24. 10
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/FileCleanerCleanup.java
  25. 19
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/ServletFileUpload.java
  26. 16
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/servlet/ServletRequestContext.java
  27. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/Closeable.java
  28. 9
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/FileItemHeadersImpl.java
  29. 19
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/LimitedInputStream.java
  30. 15
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/Streams.java
  31. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/MimeUtility.java
  32. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/ParseException.java
  33. 2
      fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/mime/QuotedPrintableDecoder.java

2
fine-commons-fileupload/README.md

@ -1,2 +1,2 @@
apache commons fileupload https://archive.apache.org/dist/commons/fileupload/source/ apache commons fileupload https://archive.apache.org/dist/commons/fileupload/source/
1.3.3 1.5

10
fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/DefaultFileItem.java

@ -16,9 +16,10 @@
*/ */
package com.fr.third.org.apache.commons.fileupload; package com.fr.third.org.apache.commons.fileupload;
import java.io.File;
import com.fr.third.org.apache.commons.fileupload.disk.DiskFileItem; import com.fr.third.org.apache.commons.fileupload.disk.DiskFileItem;
import java.io.File;
/** /**
* <p> The default implementation of the * <p> The default implementation of the
* {@link FileItem FileItem} interface. * {@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 * {@link #getInputStream()} and process the file without attempting to load
* it into memory, which may come handy with large files. * it into memory, which may come handy with large files.
* *
* @version $Id$
*
* @deprecated 1.1 Use <code>DiskFileItem</code> instead. * @deprecated 1.1 Use <code>DiskFileItem</code> instead.
*/ */
@Deprecated @Deprecated
@ -42,11 +41,6 @@ public class DefaultFileItem
// ----------------------------------------------------------- Constructors // ----------------------------------------------------------- Constructors
/**
* The UID to use when serializing this instance.
*/
private static final long serialVersionUID = 4088572813833518255L;
/** /**
* Constructs a new <code>DefaultFileItem</code> instance. * Constructs a new <code>DefaultFileItem</code> instance.
* *

7
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; package com.fr.third.org.apache.commons.fileupload;
import java.io.File;
import com.fr.third.org.apache.commons.fileupload.disk.DiskFileItemFactory; import com.fr.third.org.apache.commons.fileupload.disk.DiskFileItemFactory;
import java.io.File;
/** /**
* <p>The default {@link FileItemFactory} * <p>The default {@link FileItemFactory}
* implementation. This implementation creates * 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 * disk, is configurable, as is the directory in which temporary files will be
* created.</p> * created.</p>
* *
* If not otherwise configured, the default configuration values are as * <p>If not otherwise configured, the default configuration values are as
* follows: * follows:
* <ul> * <ul>
* <li>Size threshold is 10KB.</li> * <li>Size threshold is 10KB.</li>
@ -36,8 +37,6 @@ import com.fr.third.org.apache.commons.fileupload.disk.DiskFileItemFactory;
* <code>System.getProperty("java.io.tmpdir")</code>.</li> * <code>System.getProperty("java.io.tmpdir")</code>.</li>
* </ul> * </ul>
* *
* @version $Id$
*
* @deprecated 1.1 Use <code>DiskFileItemFactory</code> instead. * @deprecated 1.1 Use <code>DiskFileItemFactory</code> instead.
*/ */
@Deprecated @Deprecated

4
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; package com.fr.third.org.apache.commons.fileupload;
import javax.servlet.http.HttpServletRequest;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletRequest;
/** /**
* <p>High level API for processing file uploads.</p> * <p>High level API for processing file uploads.</p>
@ -34,8 +34,6 @@ import javax.servlet.http.HttpServletRequest;
* depending on their size, and will be available as {@link * depending on their size, and will be available as {@link
* FileItem}s.</p> * FileItem}s.</p>
* *
* @version $Id$
*
* @deprecated 1.1 Use <code>ServletFileUpload</code> together with * @deprecated 1.1 Use <code>ServletFileUpload</code> together with
* <code>DiskFileItemFactory</code> instead. * <code>DiskFileItemFactory</code> instead.
*/ */

51
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;
}
}

14
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.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
/** /**
@ -34,7 +33,7 @@ import java.io.UnsupportedEncodingException;
* {@link ServletFileUpload * {@link ServletFileUpload
* #parseRequest(javax.servlet.http.HttpServletRequest)}), you may * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may
* either request all contents of the file at once using {@link #get()} or * 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 * {@link #getInputStream()} and process the file without attempting to load
* it into memory, which may come handy with large files. * 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 * implementation of this interface to also implement
* <code>javax.activation.DataSource</code> with minimal additional work. * <code>javax.activation.DataSource</code> with minimal additional work.
* *
* @version $Id$
* @since 1.3 additionally implements FileItemHeadersSupport * @since 1.3 additionally implements FileItemHeadersSupport
*/ */
public interface FileItem extends Serializable, FileItemHeadersSupport { public interface FileItem extends FileItemHeadersSupport {
// ------------------------------- Methods from javax.activation.DataSource // ------------------------------- 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. * 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. * used to retrieve the contents of the file.
* *
* @throws IOException if an error occurs. * @throws IOException if an error occurs.
@ -195,10 +193,10 @@ public interface FileItem extends Serializable, FileItemHeadersSupport {
void setFormField(boolean state); 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. * 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. * for storing the contensts of the file.
* *
* @throws IOException if an error occurs. * @throws IOException if an error occurs.

2
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;
* <p>A factory interface for creating {@link FileItem} instances. Factories * <p>A factory interface for creating {@link FileItem} instances. Factories
* can provide their own custom configuration, over and above that provided * can provide their own custom configuration, over and above that provided
* by the default file upload implementation.</p> * by the default file upload implementation.</p>
*
* @version $Id$
*/ */
public interface FileItemFactory { public interface FileItemFactory {

2
fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/FileItemHeaders.java

@ -24,8 +24,6 @@ import java.util.Iterator;
* request.</p> * request.</p>
* *
* @since 1.2.1 * @since 1.2.1
*
* @version $Id$
*/ */
public interface FileItemHeaders { public interface FileItemHeaders {

2
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 FileItem
* @see FileItemStream * @see FileItemStream
*
* @version $Id$
*/ */
public interface FileItemHeadersSupport { public interface FileItemHeadersSupport {

2
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 * An iterator, as returned by
* {@link FileUploadBase#getItemIterator(RequestContext)}. * {@link FileUploadBase#getItemIterator(RequestContext)}.
*
* @version $Id$
*/ */
public interface FileItemIterator { public interface FileItemIterator {

4
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 * its associated instances of {@link FileItemStream}: By invoking
* {@link java.util.Iterator#hasNext()} on the iterator, you discard all data, * {@link java.util.Iterator#hasNext()} on the iterator, you discard all data,
* which hasn't been read so far from the previous data.</p> * which hasn't been read so far from the previous data.</p>
*
* @version $Id$
*/ */
public interface FileItemStream extends FileItemHeadersSupport { public interface FileItemStream extends FileItemHeadersSupport {
@ -42,7 +40,7 @@ public interface FileItemStream extends FileItemHeadersSupport {
* {@link java.util.Iterator#hasNext()} has been invoked on the * {@link java.util.Iterator#hasNext()} has been invoked on the
* iterator, which created the {@link FileItemStream}. * 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 * The exceptions serial version UID, which is being used

2
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;
* <p>How the data for individual parts is stored is determined by the factory * <p>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 * used to create them; a given part may be in memory, on disk, or somewhere
* else.</p> * else.</p>
*
* @version $Id$
*/ */
public class FileUpload public class FileUpload
extends FileUploadBase { extends FileUploadBase {

92
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; 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.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@ -29,15 +36,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import javax.servlet.http.HttpServletRequest; import static java.lang.String.format;
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;
/** /**
* <p>High level API for processing file uploads.</p> * <p>High level API for processing file uploads.</p>
@ -52,8 +51,6 @@ import com.fr.third.org.apache.commons.fileupload.util.Streams;
* <p>How the data for individual parts is stored is determined by the factory * <p>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 * used to create them; a given part may be in memory, on disk, or somewhere
* else.</p> * else.</p>
*
* @version $Id$
*/ */
public abstract class FileUploadBase { public abstract class FileUploadBase {
@ -166,6 +163,12 @@ public abstract class FileUploadBase {
*/ */
private long fileSizeMax = -1; 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. * The content encoding to use when reading part headers.
*/ */
@ -242,6 +245,25 @@ public abstract class FileUploadBase {
this.fileSizeMax = fileSizeMax; 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 * Retrieves the character encoding used when reading the headers of an
* individual part. When not specified, or <code>null</code>, the request * individual part. When not specified, or <code>null</code>, the request
@ -333,10 +355,15 @@ public abstract class FileUploadBase {
try { try {
FileItemIterator iter = getItemIterator(ctx); FileItemIterator iter = getItemIterator(ctx);
FileItemFactory fac = getFileItemFactory(); FileItemFactory fac = getFileItemFactory();
final byte[] buffer = new byte[Streams.DEFAULT_BUFFER_SIZE];
if (fac == null) { if (fac == null) {
throw new NullPointerException("No FileItemFactory has been set."); throw new NullPointerException("No FileItemFactory has been set.");
} }
while (iter.hasNext()) { while (iter.hasNext()) {
if (items.size() == fileCountMax) {
// The next item will exceed the limit.
throw new FileCountLimitExceededException(ATTACHMENT, getFileCountMax());
}
final FileItemStream item = iter.next(); final FileItemStream item = iter.next();
// Don't use getName() here to prevent an InvalidFileNameException. // Don't use getName() here to prevent an InvalidFileNameException.
final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name; final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name;
@ -344,7 +371,7 @@ public abstract class FileUploadBase {
item.isFormField(), fileName); item.isFormField(), fileName);
items.add(fileItem); items.add(fileItem);
try { try {
Streams.copy(item.openStream(), fileItem.getOutputStream(), true); Streams.copy(item.openStream(), fileItem.getOutputStream(), true, buffer);
} catch (FileUploadIOException e) { } catch (FileUploadIOException e) {
throw (FileUploadException) e.getCause(); throw (FileUploadException) e.getCause();
} catch (IOException e) { } catch (IOException e) {
@ -365,8 +392,8 @@ public abstract class FileUploadBase {
for (FileItem fileItem : items) { for (FileItem fileItem : items) {
try { try {
fileItem.delete(); fileItem.delete();
} catch (Throwable e) { } catch (Exception ignored) {
// ignore it // ignored TODO perhaps add to tracker delete failure list somehow?
} }
} }
} }
@ -765,9 +792,7 @@ public abstract class FileUploadBase {
fieldName = pFieldName; fieldName = pFieldName;
contentType = pContentType; contentType = pContentType;
formField = pFormField; formField = pFormField;
final ItemInputStream itemStream = multi.newInputStream(); if (fileSizeMax != -1) { // Check if limit is already exceeded
InputStream istream = itemStream;
if (fileSizeMax != -1) {
if (pContentLength != -1 if (pContentLength != -1
&& pContentLength > fileSizeMax) { && pContentLength > fileSizeMax) {
FileSizeLimitExceededException e = FileSizeLimitExceededException e =
@ -779,6 +804,11 @@ public abstract class FileUploadBase {
e.setFieldName(pFieldName); e.setFieldName(pFieldName);
throw new FileUploadIOException(e); 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) { istream = new LimitedInputStream(istream, fileSizeMax) {
@Override @Override
protected void raiseError(long pSizeMax, long pCount) protected void raiseError(long pSizeMax, long pCount)
@ -803,6 +833,7 @@ public abstract class FileUploadBase {
* *
* @return Content type, if known, or null. * @return Content type, if known, or null.
*/ */
@Override
public String getContentType() { public String getContentType() {
return contentType; return contentType;
} }
@ -812,6 +843,7 @@ public abstract class FileUploadBase {
* *
* @return Field name. * @return Field name.
*/ */
@Override
public String getFieldName() { public String getFieldName() {
return fieldName; return fieldName;
} }
@ -825,6 +857,7 @@ public abstract class FileUploadBase {
* use the file name anyways, catch the exception and use * use the file name anyways, catch the exception and use
* InvalidFileNameException#getName(). * InvalidFileNameException#getName().
*/ */
@Override
public String getName() { public String getName() {
return Streams.checkFileName(name); return Streams.checkFileName(name);
} }
@ -835,6 +868,7 @@ public abstract class FileUploadBase {
* @return True, if the item is a form field, * @return True, if the item is a form field,
* otherwise false. * otherwise false.
*/ */
@Override
public boolean isFormField() { public boolean isFormField() {
return formField; return formField;
} }
@ -846,13 +880,14 @@ public abstract class FileUploadBase {
* @return Opened input stream. * @return Opened input stream.
* @throws IOException An I/O error occurred. * @throws IOException An I/O error occurred.
*/ */
@Override
public InputStream openStream() throws IOException { public InputStream openStream() throws IOException {
if (opened) { if (opened) {
throw new IllegalStateException( throw new IllegalStateException(
"The stream was already opened."); "The stream was already opened.");
} }
if (((Closeable) stream).isClosed()) { if (((Closeable) stream).isClosed()) {
throw new FileItemStream.ItemSkippedException(); throw new ItemSkippedException();
} }
return stream; return stream;
} }
@ -871,6 +906,7 @@ public abstract class FileUploadBase {
* *
* @return The items header object * @return The items header object
*/ */
@Override
public FileItemHeaders getHeaders() { public FileItemHeaders getHeaders() {
return headers; return headers;
} }
@ -880,6 +916,7 @@ public abstract class FileUploadBase {
* *
* @param pHeaders The items header object * @param pHeaders The items header object
*/ */
@Override
public void setHeaders(FileItemHeaders pHeaders) { public void setHeaders(FileItemHeaders pHeaders) {
headers = pHeaders; headers = pHeaders;
} }
@ -949,7 +986,6 @@ public abstract class FileUploadBase {
MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType)); MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType));
} }
InputStream input = ctx.getInputStream();
@SuppressWarnings("deprecation") // still has to be backward compatible @SuppressWarnings("deprecation") // still has to be backward compatible
final int contentLengthInt = ctx.getContentLength(); final int contentLengthInt = ctx.getContentLength();
@ -960,6 +996,7 @@ public abstract class FileUploadBase {
: contentLengthInt; : contentLengthInt;
// CHECKSTYLE:ON // CHECKSTYLE:ON
InputStream input; // N.B. this is eventually closed in MultipartStream processing
if (sizeMax >= 0) { if (sizeMax >= 0) {
if (requestSize != -1 && requestSize > sizeMax) { if (requestSize != -1 && requestSize > sizeMax) {
throw new SizeLimitExceededException( throw new SizeLimitExceededException(
@ -967,7 +1004,8 @@ public abstract class FileUploadBase {
Long.valueOf(requestSize), Long.valueOf(sizeMax)), Long.valueOf(requestSize), Long.valueOf(sizeMax)),
requestSize, sizeMax); requestSize, sizeMax);
} }
input = new LimitedInputStream(input, sizeMax) { // N.B. this is eventually closed in MultipartStream processing
input = new LimitedInputStream(ctx.getInputStream(), sizeMax) {
@Override @Override
protected void raiseError(long pSizeMax, long pCount) protected void raiseError(long pSizeMax, long pCount)
throws IOException { throws IOException {
@ -978,6 +1016,8 @@ public abstract class FileUploadBase {
throw new FileUploadIOException(ex); throw new FileUploadIOException(ex);
} }
}; };
} else {
input = ctx.getInputStream();
} }
String charEncoding = headerEncoding; String charEncoding = headerEncoding;
@ -987,6 +1027,7 @@ public abstract class FileUploadBase {
boundary = getBoundary(contentType); boundary = getBoundary(contentType);
if (boundary == null) { if (boundary == null) {
IOUtils.closeQuietly(input); // avoid possible resource leak
throw new FileUploadException("the request was rejected because no multipart boundary was found"); throw new FileUploadException("the request was rejected because no multipart boundary was found");
} }
@ -994,6 +1035,7 @@ public abstract class FileUploadBase {
try { try {
multi = new MultipartStream(input, boundary, notifier); multi = new MultipartStream(input, boundary, notifier);
} catch (IllegalArgumentException iae) { } catch (IllegalArgumentException iae) {
IOUtils.closeQuietly(input); // avoid possible resource leak
throw new InvalidContentTypeException( throw new InvalidContentTypeException(
format("The boundary specified in the %s header is too long", CONTENT_TYPE), iae); 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 * @return True, if one or more additional file items
* are available, otherwise false. * are available, otherwise false.
*/ */
@Override
public boolean hasNext() throws FileUploadException, IOException { public boolean hasNext() throws FileUploadException, IOException {
if (eof) { if (eof) {
return false; return false;
@ -1113,7 +1156,7 @@ public abstract class FileUploadBase {
/** /**
* Returns the next available {@link FileItemStream}. * 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. * available. Use {@link #hasNext()} to prevent this exception.
* @throws FileUploadException Parsing or processing the * @throws FileUploadException Parsing or processing the
* file item failed. * file item failed.
@ -1121,6 +1164,7 @@ public abstract class FileUploadBase {
* @return FileItemStream instance, which provides * @return FileItemStream instance, which provides
* access to the next file item. * access to the next file item.
*/ */
@Override
public FileItemStream next() throws FileUploadException, IOException { public FileItemStream next() throws FileUploadException, IOException {
if (eof || (!itemValid && !hasNext())) { if (eof || (!itemValid && !hasNext())) {
throw new NoSuchElementException(); throw new NoSuchElementException();
@ -1361,7 +1405,7 @@ public abstract class FileUploadBase {
/** /**
* @deprecated 1.2 Replaced by * @deprecated 1.2 Replaced by
* {@code SizeLimitExceededException(String, long, long)} * {@link #SizeLimitExceededException(String, long, long)}
*/ */
@Deprecated @Deprecated
public SizeLimitExceededException() { public SizeLimitExceededException() {
@ -1370,7 +1414,7 @@ public abstract class FileUploadBase {
/** /**
* @deprecated 1.2 Replaced by * @deprecated 1.2 Replaced by
* {@code #SizeLimitExceededException(String, long, long)} * {@link #SizeLimitExceededException(String, long, long)}
* @param message The exceptions detail message. * @param message The exceptions detail message.
*/ */
@Deprecated @Deprecated

2
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. * Exception for errors encountered while processing the request.
*
* @version $Id$
*/ */
public class FileUploadException extends Exception { public class FileUploadException extends Exception {

2
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 * checks for the extension ".png"), while, depending on the underlying
* C library, it might create a file named "foo.exe", as the NUL * C library, it might create a file named "foo.exe", as the NUL
* character is the string terminator in C. * character is the string terminator in C.
*
* @version $Id$
*/ */
public class InvalidFileNameException extends RuntimeException { public class InvalidFileNameException extends RuntimeException {

79
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; 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.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -24,9 +26,7 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import com.fr.third.org.apache.commons.fileupload.FileUploadBase.FileUploadIOException; import static java.lang.String.format;
import com.fr.third.org.apache.commons.fileupload.util.Closeable;
import com.fr.third.org.apache.commons.fileupload.util.Streams;
/** /**
* <p> Low level API for processing file uploads. * <p> 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 * // a read or write error occurred
* } * }
* </pre> * </pre>
*
* @version $Id$
*/ */
public class MultipartStream { 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 * The amount of data, in bytes, that must be kept in the buffer in order
* to detect delimiters reliably. * to detect delimiters reliably.
*/ */
private int keepRegion; private final int keepRegion;
/** /**
* The byte sequence that partitions the stream. * 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. * The length of the buffer used for processing the request.
@ -339,12 +342,14 @@ public class MultipartStream {
this.notifier = pNotifier; this.notifier = pNotifier;
this.boundary = new byte[this.boundaryLength]; this.boundary = new byte[this.boundaryLength];
this.boundaryTable = new int[this.boundaryLength + 1];
this.keepRegion = this.boundary.length; this.keepRegion = this.boundary.length;
System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0,
BOUNDARY_PREFIX.length); BOUNDARY_PREFIX.length);
System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length,
boundary.length); boundary.length);
computeBoundaryTable();
head = 0; head = 0;
tail = 0; tail = 0;
@ -506,6 +511,31 @@ public class MultipartStream {
} }
System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length,
boundary.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 {
* <p>Arbitrary large amounts of data can be processed by this * <p>Arbitrary large amounts of data can be processed by this
* method using a constant size buffer. (see {@link * method using a constant size buffer. (see {@link
* #MultipartStream(InputStream,byte[],int, * #MultipartStream(InputStream,byte[],int,
* MultipartStream.ProgressNotifier) constructor}). * ProgressNotifier) constructor}).
* *
* @param output The <code>Stream</code> to write data into. May * @param output The <code>Stream</code> to write data into. May
* be null, in which case this method is equivalent * be null, in which case this method is equivalent
@ -589,8 +619,7 @@ public class MultipartStream {
*/ */
public int readBodyData(OutputStream output) public int readBodyData(OutputStream output)
throws MalformedStreamException, IOException { throws MalformedStreamException, IOException {
final InputStream istream = newInputStream(); return (int) Streams.copy(newInputStream(), output, false); // N.B. Streams.copy closes the input stream
return (int) Streams.copy(istream, output, false);
} }
/** /**
@ -629,6 +658,7 @@ public class MultipartStream {
// First delimiter may be not preceeded with a CRLF. // First delimiter may be not preceeded with a CRLF.
System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2); System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2);
boundaryLength = boundary.length - 2; boundaryLength = boundary.length - 2;
computeBoundaryTable();
try { try {
// Discard all data up to the delimiter. // Discard all data up to the delimiter.
discardBodyData(); discardBodyData();
@ -644,6 +674,7 @@ public class MultipartStream {
boundaryLength = boundary.length; boundaryLength = boundary.length;
boundary[0] = CR; boundary[0] = CR;
boundary[1] = LF; boundary[1] = LF;
computeBoundaryTable();
} }
} }
@ -699,22 +730,19 @@ public class MultipartStream {
* not found. * not found.
*/ */
protected int findSeparator() { protected int findSeparator() {
int first;
int match = 0; int bufferPos = this.head;
int maxpos = tail - boundaryLength; int tablePos = 0;
for (first = head; first <= maxpos && match != boundaryLength; first++) {
first = findByte(boundary[0], first); while (bufferPos < this.tail) {
if (first == -1 || first > maxpos) { while (tablePos >= 0 && buffer[bufferPos] != boundary[tablePos]) {
return -1; 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; return -1;
} }
@ -1023,6 +1051,7 @@ public class MultipartStream {
* *
* @return True, if the stream is closed, otherwise false. * @return True, if the stream is closed, otherwise false.
*/ */
@Override
public boolean isClosed() { public boolean isClosed() {
return closed; return closed;
} }

28
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; 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.io.UnsupportedEncodingException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; 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. * 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;
* <p> * <p>
* <code>param1 = value; param2 = "anything goes; really"; param3</code> * <code>param1 = value; param2 = "anything goes; really"; param3</code>
* </p> * </p>
*
* @version $Id$
*/ */
public class ParameterParser { public class ParameterParser {
@ -78,8 +76,8 @@ public class ParameterParser {
/** /**
* Are there any characters left to parse? * Are there any characters left to parse?
* *
* @return <tt>true</tt> if there are unparsed characters, * @return {@code true} if there are unparsed characters,
* <tt>false</tt> otherwise. * {@code false} otherwise.
*/ */
private boolean hasChar() { private boolean hasChar() {
return this.pos < this.len; return this.pos < this.len;
@ -90,8 +88,8 @@ public class ParameterParser {
* leading and trailing blanks as well as enclosing quotation marks, * leading and trailing blanks as well as enclosing quotation marks,
* when necessary. * when necessary.
* *
* @param quoted <tt>true</tt> if quotation marks are expected, * @param quoted {@code true} if quotation marks are expected,
* <tt>false</tt> otherwise. * {@code false} otherwise.
* @return the token * @return the token
*/ */
private String getToken(boolean quoted) { private String getToken(boolean quoted) {
@ -124,8 +122,8 @@ public class ParameterParser {
* @param ch the character to test for presense in the array of characters * @param ch the character to test for presense in the array of characters
* @param charray the array of characters to test against * @param charray the array of characters to test against
* *
* @return <tt>true</tt> if the character is present in the array of * @return {@code true} if the character is present in the array of
* characters, <tt>false</tt> otherwise. * characters, {@code false} otherwise.
*/ */
private boolean isOneOf(char ch, final char[] charray) { private boolean isOneOf(char ch, final char[] charray) {
boolean result = false; boolean result = false;
@ -195,12 +193,12 @@ public class ParameterParser {
} }
/** /**
* Returns <tt>true</tt> if parameter names are to be converted to lower * Returns {@code true} if parameter names are to be converted to lower
* case when name/value pairs are parsed. * case when name/value pairs are parsed.
* *
* @return <tt>true</tt> if parameter names are to be * @return {@code true} if parameter names are to be
* converted to lower case when name/value pairs are parsed. * converted to lower case when name/value pairs are parsed.
* Otherwise returns <tt>false</tt> * Otherwise returns {@code false}
*/ */
public boolean isLowerCaseNames() { public boolean isLowerCaseNames() {
return this.lowerCaseNames; return this.lowerCaseNames;
@ -210,9 +208,9 @@ public class ParameterParser {
* Sets the flag if parameter names are to be converted to lower case when * Sets the flag if parameter names are to be converted to lower case when
* name/value pairs are parsed. * name/value pairs are parsed.
* *
* @param b <tt>true</tt> if parameter names are to be * @param b {@code true} if parameter names are to be
* converted to lower case when name/value pairs are parsed. * converted to lower case when name/value pairs are parsed.
* <tt>false</tt> otherwise. * {@code false} otherwise.
*/ */
public void setLowerCaseNames(boolean b) { public void setLowerCaseNames(boolean b) {
this.lowerCaseNames = b; this.lowerCaseNames = b;

2
fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/ProgressListener.java

@ -19,8 +19,6 @@ package com.fr.third.org.apache.commons.fileupload;
/** /**
* The {@link ProgressListener} may be used to display a progress bar * The {@link ProgressListener} may be used to display a progress bar
* or do stuff like that. * or do stuff like that.
*
* @version $Id$
*/ */
public interface ProgressListener { public interface ProgressListener {

4
fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/RequestContext.java

@ -16,8 +16,8 @@
*/ */
package com.fr.third.org.apache.commons.fileupload; package com.fr.third.org.apache.commons.fileupload;
import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
/** /**
* <p>Abstracts access to the request information needed for file uploads. This * <p>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.</p> * handled by FileUpload, such as servlets and portlets.</p>
* *
* @since FileUpload 1.1 * @since FileUpload 1.1
*
* @version $Id$
*/ */
public interface RequestContext { public interface RequestContext {

251
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; 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.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import com.fr.third.org.apache.commons.fileupload.FileItem; import static java.lang.String.format;
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;
/** /**
* <p> The default implementation of the * <p> The default implementation of the
@ -50,47 +45,34 @@ import com.fr.third.org.apache.commons.io.output.DeferredFileOutputStream;
* *
* <p> After retrieving an instance of this class from a {@link * <p> After retrieving an instance of this class from a {@link
* DiskFileItemFactory} instance (see * DiskFileItemFactory} instance (see
* {@link ServletFileUpload * {@link com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload
* #parseRequest(javax.servlet.http.HttpServletRequest)}), you may * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may
* either request all contents of file at once using {@link #get()} or * 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 * {@link #getInputStream()} and process the file without attempting to load
* it into memory, which may come handy with large files. * it into memory, which may come handy with large files.
* *
* <p>Temporary files, which are created for file items, should be * <p>Temporary files, which are created for file items, should be
* deleted later on. The best way to do this is using a * 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, * {@link DiskFileItemFactory}. However, if you do use such a tracker,
* then you must consider the following: Temporary files are automatically * then you must consider the following: Temporary files are automatically
* deleted as soon as they are no longer needed. (More precisely, when the * 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 * 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. * there are files to be tracked.
* It might make sense to terminate that thread, for example, if * It might make sense to terminate that thread, for example, if
* your web application ends. See the section on "Resource cleanup" * your web application ends. See the section on "Resource cleanup"
* in the users guide of commons-fileupload.</p> * in the users guide of commons-fileupload.</p>
* *
* @since FileUpload 1.1 * @since FileUpload 1.1
*
* @version $Id$
*/ */
public class DiskFileItem public class DiskFileItem
implements FileItem { 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 // ----------------------------------------------------- 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 * Default content charset to be used when no explicit charset
* parameter is provided by the sender. Media subtypes of the * parameter is provided by the sender. Media subtypes of the
@ -166,14 +148,15 @@ public class DiskFileItem
private transient File tempFile; 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 // ----------------------------------------------------------- Constructors
@ -208,14 +191,15 @@ public class DiskFileItem
// ------------------------------- Methods from javax.activation.DataSource // ------------------------------- 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. * 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. * used to retrieve the contents of the file.
* *
* @throws IOException if an error occurs. * @throws IOException if an error occurs.
*/ */
@Override
public InputStream getInputStream() public InputStream getInputStream()
throws IOException { throws IOException {
if (!isInMemory()) { if (!isInMemory()) {
@ -235,6 +219,7 @@ public class DiskFileItem
* @return The content type passed by the agent or <code>null</code> if * @return The content type passed by the agent or <code>null</code> if
* not defined. * not defined.
*/ */
@Override
public String getContentType() { public String getContentType() {
return contentType; return contentType;
} }
@ -258,11 +243,12 @@ public class DiskFileItem
* Returns the original filename in the client's filesystem. * Returns the original filename in the client's filesystem.
* *
* @return 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 * which might be an indicator of a security attack. If you intend to
* use the file name anyways, catch the exception and use * 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() { public String getName() {
return Streams.checkFileName(fileName); return Streams.checkFileName(fileName);
} }
@ -276,6 +262,7 @@ public class DiskFileItem
* @return <code>true</code> if the file contents will be read * @return <code>true</code> if the file contents will be read
* from memory; <code>false</code> otherwise. * from memory; <code>false</code> otherwise.
*/ */
@Override
public boolean isInMemory() { public boolean isInMemory() {
if (cachedContent != null) { if (cachedContent != null) {
return true; return true;
@ -288,6 +275,7 @@ public class DiskFileItem
* *
* @return The size of the file, in bytes. * @return The size of the file, in bytes.
*/ */
@Override
public long getSize() { public long getSize() {
if (size >= 0) { if (size >= 0) {
return size; return size;
@ -305,11 +293,13 @@ public class DiskFileItem
* contents of the file were not yet cached in memory, they will be * contents of the file were not yet cached in memory, they will be
* loaded from the disk storage and cached. * 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() { public byte[] get() {
if (isInMemory()) { if (isInMemory()) {
if (cachedContent == null) { if (cachedContent == null && dfos != null) {
cachedContent = dfos.getData(); cachedContent = dfos.getData();
} }
return cachedContent; return cachedContent;
@ -319,18 +309,12 @@ public class DiskFileItem
InputStream fis = null; InputStream fis = null;
try { try {
fis = new BufferedInputStream(new FileInputStream(dfos.getFile())); fis = new FileInputStream(dfos.getFile());
fis.read(fileData); IOUtils.readFully(fis, fileData);
} catch (IOException e) { } catch (IOException e) {
fileData = null; fileData = null;
} finally { } finally {
if (fis != null) { IOUtils.closeQuietly(fis);
try {
fis.close();
} catch (IOException e) {
// ignore
}
}
} }
return fileData; return fileData;
@ -348,6 +332,7 @@ public class DiskFileItem
* @throws UnsupportedEncodingException if the requested character * @throws UnsupportedEncodingException if the requested character
* encoding is not available. * encoding is not available.
*/ */
@Override
public String getString(final String charset) public String getString(final String charset)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
return new String(get(), charset); return new String(get(), charset);
@ -362,11 +347,12 @@ public class DiskFileItem
* *
* @return The contents of the file, as a string. * @return The contents of the file, as a string.
*/ */
@Override
public String getString() { public String getString() {
byte[] rawdata = get(); byte[] rawdata = get();
String charset = getCharSet(); String charset = getCharSet();
if (charset == null) { if (charset == null) {
charset = DEFAULT_CHARSET; charset = defaultCharset;
} }
try { try {
return new String(rawdata, charset); return new String(rawdata, charset);
@ -395,16 +381,16 @@ public class DiskFileItem
* *
* @throws Exception if an error occurs. * @throws Exception if an error occurs.
*/ */
@Override
public void write(File file) throws Exception { public void write(File file) throws Exception {
if (isInMemory()) { if (isInMemory()) {
FileOutputStream fout = null; FileOutputStream fout = null;
try { try {
fout = new FileOutputStream(file); fout = new FileOutputStream(file);
fout.write(get()); fout.write(get());
} finally {
if (fout != null) {
fout.close(); fout.close();
} } finally {
IOUtils.closeQuietly(fout);
} }
} else { } else {
File outputFile = getStoreLocation(); File outputFile = getStoreLocation();
@ -416,32 +402,10 @@ public class DiskFileItem
* in a temporary location so move it to the * in a temporary location so move it to the
* desired file. * desired file.
*/ */
if (!outputFile.renameTo(file)) { if (file.exists()) {
BufferedInputStream in = null; file.delete();
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
}
}
}
} }
FileUtils.moveFile(outputFile, file);
} else { } else {
/* /*
* For whatever reason we cannot write the * 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 * collected, this method can be used to ensure that this is done at an
* earlier time, thus preserving system resources. * earlier time, thus preserving system resources.
*/ */
@Override
public void delete() { public void delete() {
cachedContent = null; cachedContent = null;
File outputFile = getStoreLocation(); File outputFile = getStoreLocation();
if (outputFile != null && outputFile.exists()) { if (outputFile != null && !isInMemory() && outputFile.exists()) {
outputFile.delete(); outputFile.delete();
} }
} }
@ -474,9 +439,10 @@ public class DiskFileItem
* *
* @return The name of the form field. * @return The name of the form field.
* *
* @see #setFieldName(java.lang.String) * @see #setFieldName(String)
* *
*/ */
@Override
public String getFieldName() { public String getFieldName() {
return fieldName; return fieldName;
} }
@ -489,6 +455,7 @@ public class DiskFileItem
* @see #getFieldName() * @see #getFieldName()
* *
*/ */
@Override
public void setFieldName(String fieldName) { public void setFieldName(String fieldName) {
this.fieldName = fieldName; this.fieldName = fieldName;
} }
@ -503,6 +470,7 @@ public class DiskFileItem
* @see #setFormField(boolean) * @see #setFormField(boolean)
* *
*/ */
@Override
public boolean isFormField() { public boolean isFormField() {
return isFormField; return isFormField;
} }
@ -517,19 +485,21 @@ public class DiskFileItem
* @see #isFormField() * @see #isFormField()
* *
*/ */
@Override
public void setFormField(boolean state) { public void setFormField(boolean state) {
isFormField = 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. * 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. * for storing the contents of the file.
* *
* @throws IOException if an error occurs. * @throws IOException if an error occurs.
*/ */
@Override
public OutputStream getOutputStream() public OutputStream getOutputStream()
throws IOException { throws IOException {
if (dfos == null) { if (dfos == null) {
@ -542,11 +512,11 @@ public class DiskFileItem
// --------------------------------------------------------- Public methods // --------------------------------------------------------- Public methods
/** /**
* Returns the {@link java.io.File} object for the <code>FileItem</code>'s * Returns the {@link File} object for the <code>FileItem</code>'s
* data's temporary location on the disk. Note that for * data's temporary location on the disk. Note that for
* <code>FileItem</code>s that have their data stored in memory, * <code>FileItem</code>s that have their data stored in memory,
* this method will return <code>null</code>. When handling large * this method will return <code>null</code>. 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 * move the file to new location without copying the data, if the
* source and destination locations reside within the same logical * source and destination locations reside within the same logical
* volume. * volume.
@ -558,6 +528,9 @@ public class DiskFileItem
if (dfos == null) { if (dfos == null) {
return null; return null;
} }
if (isInMemory()) {
return null;
}
return dfos.getFile(); return dfos.getFile();
} }
@ -568,6 +541,9 @@ public class DiskFileItem
*/ */
@Override @Override
protected void finalize() { protected void finalize() {
if (dfos == null || dfos.isInMemory()) {
return;
}
File outputFile = dfos.getFile(); File outputFile = dfos.getFile();
if (outputFile != null && outputFile.exists()) { 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 * named temporary file in the configured repository path. The lifetime of
* the file is tied to the lifetime of the <code>FileItem</code> instance; * the file is tied to the lifetime of the <code>FileItem</code> instance;
* the file will be deleted when the instance is garbage collected. * the file will be deleted when the instance is garbage collected.
* <p>
* <b>Note: Subclasses that override this method must ensure that they return the
* same File each time.</b>
* *
* @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() { protected File getTempFile() {
if (tempFile == null) { if (tempFile == null) {
@ -601,7 +580,7 @@ public class DiskFileItem
/** /**
* Returns an identifier that is unique within the class loader used to * 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. * @return A String with the non-random looking instance identifier.
*/ */
@ -630,83 +609,11 @@ public class DiskFileItem
Boolean.valueOf(isFormField()), getFieldName()); 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. * Returns the file item headers.
* @return The file items headers. * @return The file items headers.
*/ */
@Override
public FileItemHeaders getHeaders() { public FileItemHeaders getHeaders() {
return headers; return headers;
} }
@ -715,8 +622,26 @@ public class DiskFileItem
* Sets the file item headers. * Sets the file item headers.
* @param pHeaders The file items headers. * @param pHeaders The file items headers.
*/ */
@Override
public void setHeaders(FileItemHeaders pHeaders) { public void setHeaders(FileItemHeaders pHeaders) {
headers = 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;
}
} }

37
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; 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.FileItemFactory;
import com.fr.third.org.apache.commons.fileupload.FileItem;
import com.fr.third.org.apache.commons.io.FileCleaningTracker; import com.fr.third.org.apache.commons.io.FileCleaningTracker;
import java.io.File;
/** /**
* <p>The default {@link FileItemFactory} * <p>The default {@link FileItemFactory}
* implementation. This implementation creates * 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, * {@link DiskFileItemFactory}. However, if you do use such a tracker,
* then you must consider the following: Temporary files are automatically * then you must consider the following: Temporary files are automatically
* deleted as soon as they are no longer needed. (More precisely, when the * 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 * 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 * automatically by the {@link FileCleaningTracker} when there are files to be
* tracked. * tracked.
@ -66,8 +66,6 @@ import com.fr.third.org.apache.commons.io.FileCleaningTracker;
* in the users guide of commons-fileupload.</p> * in the users guide of commons-fileupload.</p>
* *
* @since FileUpload 1.1 * @since FileUpload 1.1
*
* @version $Id$
*/ */
public class DiskFileItemFactory implements FileItemFactory { public class DiskFileItemFactory implements FileItemFactory {
@ -97,6 +95,12 @@ public class DiskFileItemFactory implements FileItemFactory {
*/ */
private FileCleaningTracker fileCleaningTracker; 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 // ----------------------------------------------------------- Constructors
/** /**
@ -130,7 +134,7 @@ public class DiskFileItemFactory implements FileItemFactory {
* *
* @return The directory in which temporary files will be located. * @return The directory in which temporary files will be located.
* *
* @see #setRepository(java.io.File) * @see #setRepository(File)
* *
*/ */
public File getRepository() { public File getRepository() {
@ -190,10 +194,12 @@ public class DiskFileItemFactory implements FileItemFactory {
* *
* @return The newly created file item. * @return The newly created file item.
*/ */
@Override
public FileItem createItem(String fieldName, String contentType, public FileItem createItem(String fieldName, String contentType,
boolean isFormField, String fileName) { boolean isFormField, String fileName) {
DiskFileItem result = new DiskFileItem(fieldName, contentType, DiskFileItem result = new DiskFileItem(fieldName, contentType,
isFormField, fileName, sizeThreshold, repository); isFormField, fileName, sizeThreshold, repository);
result.setDefaultCharset(defaultCharset);
FileCleaningTracker tracker = getFileCleaningTracker(); FileCleaningTracker tracker = getFileCleaningTracker();
if (tracker != null) { if (tracker != null) {
tracker.track(result.getTempFile(), result); tracker.track(result.getTempFile(), result);
@ -224,4 +230,21 @@ public class DiskFileItemFactory implements FileItemFactory {
fileCleaningTracker = pTracker; 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;
}
} }

19
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; 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.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.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.FileUploadException;
import com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload; 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;
/** /**
* <p>High level API for processing file uploads.</p> * <p>High level API for processing file uploads.</p>
@ -46,8 +45,6 @@ import com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload;
* else.</p> * else.</p>
* *
* @since FileUpload 1.1 * @since FileUpload 1.1
*
* @version $Id$
*/ */
public class PortletFileUpload extends FileUpload { public class PortletFileUpload extends FileUpload {

16
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; 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.IOException;
import java.io.InputStream; import java.io.InputStream;
import javax.portlet.ActionRequest; import static java.lang.String.format;
import com.fr.third.org.apache.commons.fileupload.FileUploadBase;
import com.fr.third.org.apache.commons.fileupload.UploadContext;
/** /**
* <p>Provides access to the request information needed for a request made to * <p>Provides access to the request information needed for a request made to
* a portlet.</p> * a portlet.</p>
* *
* @since FileUpload 1.1 * @since FileUpload 1.1
*
* @version $Id$
*/ */
public class PortletRequestContext implements UploadContext { public class PortletRequestContext implements UploadContext {
@ -63,6 +60,7 @@ public class PortletRequestContext implements UploadContext {
* *
* @return The character encoding for the request. * @return The character encoding for the request.
*/ */
@Override
public String getCharacterEncoding() { public String getCharacterEncoding() {
return request.getCharacterEncoding(); return request.getCharacterEncoding();
} }
@ -72,6 +70,7 @@ public class PortletRequestContext implements UploadContext {
* *
* @return The content type of the request. * @return The content type of the request.
*/ */
@Override
public String getContentType() { public String getContentType() {
return request.getContentType(); return request.getContentType();
} }
@ -82,6 +81,7 @@ public class PortletRequestContext implements UploadContext {
* @return The content length of the request. * @return The content length of the request.
* @deprecated 1.3 Use {@link #contentLength()} instead * @deprecated 1.3 Use {@link #contentLength()} instead
*/ */
@Override
@Deprecated @Deprecated
public int getContentLength() { public int getContentLength() {
return request.getContentLength(); return request.getContentLength();
@ -93,6 +93,7 @@ public class PortletRequestContext implements UploadContext {
* @return The content length of the request. * @return The content length of the request.
* @since 1.3 * @since 1.3
*/ */
@Override
public long contentLength() { public long contentLength() {
long size; long size;
try { try {
@ -110,6 +111,7 @@ public class PortletRequestContext implements UploadContext {
* *
* @throws IOException if a problem occurs. * @throws IOException if a problem occurs.
*/ */
@Override
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
return request.getPortletInputStream(); return request.getPortletInputStream();
} }

10
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; 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.ServletContext;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import com.fr.third.org.apache.commons.io.FileCleaningTracker;
/** /**
* A servlet context listener, which ensures that the * A servlet context listener, which ensures that the
* {@link FileCleaningTracker}'s reaper thread is terminated, * {@link FileCleaningTracker}'s reaper thread is terminated,
* when the web application is destroyed. * when the web application is destroyed.
*
* @version $Id$
*/ */
public class FileCleanerCleanup implements ServletContextListener { public class FileCleanerCleanup implements ServletContextListener {
@ -70,6 +68,7 @@ public class FileCleanerCleanup implements ServletContextListener {
* @param sce The servlet context, used for calling * @param sce The servlet context, used for calling
* {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. * {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}.
*/ */
@Override
public void contextInitialized(ServletContextEvent sce) { public void contextInitialized(ServletContextEvent sce) {
setFileCleaningTracker(sce.getServletContext(), setFileCleaningTracker(sce.getServletContext(),
new FileCleaningTracker()); new FileCleaningTracker());
@ -82,6 +81,7 @@ public class FileCleanerCleanup implements ServletContextListener {
* @param sce The servlet context, used for calling * @param sce The servlet context, used for calling
* {@link #getFileCleaningTracker(ServletContext)}. * {@link #getFileCleaningTracker(ServletContext)}.
*/ */
@Override
public void contextDestroyed(ServletContextEvent sce) { public void contextDestroyed(ServletContextEvent sce) {
getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); getFileCleaningTracker(sce.getServletContext()).exitWhenFinished();
} }

19
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; 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.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.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.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;
/** /**
* <p>High level API for processing file uploads.</p> * <p>High level API for processing file uploads.</p>
@ -42,8 +41,6 @@ import com.fr.third.org.apache.commons.fileupload.FileUploadException;
* <p>How the data for individual parts is stored is determined by the factory * <p>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 * used to create them; a given part may be in memory, on disk, or somewhere
* else.</p> * else.</p>
*
* @version $Id$
*/ */
public class ServletFileUpload extends FileUpload { public class ServletFileUpload extends FileUpload {

16
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; 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.IOException;
import java.io.InputStream; import java.io.InputStream;
import javax.servlet.http.HttpServletRequest; import static java.lang.String.format;
import com.fr.third.org.apache.commons.fileupload.FileUploadBase;
import com.fr.third.org.apache.commons.fileupload.UploadContext;
/** /**
* <p>Provides access to the request information needed for a request made to * <p>Provides access to the request information needed for a request made to
* an HTTP servlet.</p> * an HTTP servlet.</p>
* *
* @since FileUpload 1.1 * @since FileUpload 1.1
*
* @version $Id$
*/ */
public class ServletRequestContext implements UploadContext { public class ServletRequestContext implements UploadContext {
@ -61,6 +58,7 @@ public class ServletRequestContext implements UploadContext {
* *
* @return The character encoding for the request. * @return The character encoding for the request.
*/ */
@Override
public String getCharacterEncoding() { public String getCharacterEncoding() {
return request.getCharacterEncoding(); return request.getCharacterEncoding();
} }
@ -70,6 +68,7 @@ public class ServletRequestContext implements UploadContext {
* *
* @return The content type of the request. * @return The content type of the request.
*/ */
@Override
public String getContentType() { public String getContentType() {
return request.getContentType(); return request.getContentType();
} }
@ -80,6 +79,7 @@ public class ServletRequestContext implements UploadContext {
* @return The content length of the request. * @return The content length of the request.
* @deprecated 1.3 Use {@link #contentLength()} instead * @deprecated 1.3 Use {@link #contentLength()} instead
*/ */
@Override
@Deprecated @Deprecated
public int getContentLength() { public int getContentLength() {
return request.getContentLength(); return request.getContentLength();
@ -91,6 +91,7 @@ public class ServletRequestContext implements UploadContext {
* @return The content length of the request. * @return The content length of the request.
* @since 1.3 * @since 1.3
*/ */
@Override
public long contentLength() { public long contentLength() {
long size; long size;
try { try {
@ -108,6 +109,7 @@ public class ServletRequestContext implements UploadContext {
* *
* @throws IOException if a problem occurs. * @throws IOException if a problem occurs.
*/ */
@Override
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
return request.getInputStream(); return request.getInputStream();
} }

2
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. * Interface of an object, which may be closed.
*
* @version $Id$
*/ */
public interface Closeable { public interface Closeable {

9
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; package com.fr.third.org.apache.commons.fileupload.util;
import com.fr.third.org.apache.commons.fileupload.FileItemHeaders;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -25,14 +27,10 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import com.fr.third.org.apache.commons.fileupload.FileItemHeaders;
/** /**
* Default implementation of the {@link FileItemHeaders} interface. * Default implementation of the {@link FileItemHeaders} interface.
* *
* @since 1.2.1 * @since 1.2.1
*
* @version $Id$
*/ */
public class FileItemHeadersImpl implements FileItemHeaders, Serializable { public class FileItemHeadersImpl implements FileItemHeaders, Serializable {
@ -50,6 +48,7 @@ public class FileItemHeadersImpl implements FileItemHeaders, Serializable {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getHeader(String name) { public String getHeader(String name) {
String nameLower = name.toLowerCase(Locale.ENGLISH); String nameLower = name.toLowerCase(Locale.ENGLISH);
List<String> headerValueList = headerNameToValueListMap.get(nameLower); List<String> headerValueList = headerNameToValueListMap.get(nameLower);
@ -62,6 +61,7 @@ public class FileItemHeadersImpl implements FileItemHeaders, Serializable {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Iterator<String> getHeaderNames() { public Iterator<String> getHeaderNames() {
return headerNameToValueListMap.keySet().iterator(); return headerNameToValueListMap.keySet().iterator();
} }
@ -69,6 +69,7 @@ public class FileItemHeadersImpl implements FileItemHeaders, Serializable {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Iterator<String> getHeaders(String name) { public Iterator<String> getHeaders(String name) {
String nameLower = name.toLowerCase(Locale.ENGLISH); String nameLower = name.toLowerCase(Locale.ENGLISH);
List<String> headerValueList = headerNameToValueListMap.get(nameLower); List<String> headerValueList = headerNameToValueListMap.get(nameLower);

19
fine-commons-fileupload/src/main/java/com/fr/third/org/apache/commons/fileupload/util/LimitedInputStream.java

@ -23,8 +23,6 @@ import java.io.InputStream;
/** /**
* An input stream, which limits its data size. This stream is * An input stream, which limits its data size. This stream is
* used, if the content length is unknown. * used, if the content length is unknown.
*
* @version $Id$
*/ */
public abstract class LimitedInputStream extends FilterInputStream implements Closeable { public abstract class LimitedInputStream extends FilterInputStream implements Closeable {
@ -93,8 +91,8 @@ public abstract class LimitedInputStream extends FilterInputStream implements Cl
* *
* @return the next byte of data, or <code>-1</code> if the end of the * @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached. * stream is reached.
* @exception IOException if an I/O error occurs. * @throws IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in * @see FilterInputStream#in
*/ */
@Override @Override
public int read() throws IOException { 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 * @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of * <code>-1</code> if there is no more data because the end of
* the stream has been reached. * the stream has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>. * @throws NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative, * @throws IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than * <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code> * <code>b.length - off</code>
* @exception IOException if an I/O error occurs. * @throws IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in * @see FilterInputStream#in
*/ */
@Override @Override
public int read(byte[] b, int off, int len) throws IOException { 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. * @return True, if the stream is closed, otherwise false.
* @throws IOException An I/O error occurred. * @throws IOException An I/O error occurred.
*/ */
@Override
public boolean isClosed() throws IOException { public boolean isClosed() throws IOException {
return closed; return closed;
} }
@ -155,8 +154,8 @@ public abstract class LimitedInputStream extends FilterInputStream implements Cl
* This * This
* method simply performs <code>in.close()</code>. * method simply performs <code>in.close()</code>.
* *
* @exception IOException if an I/O error occurs. * @throws IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in * @see FilterInputStream#in
*/ */
@Override @Override
public void close() throws IOException { public void close() throws IOException {

15
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; 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.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; 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. * Utility class for working with streams.
*
* @version $Id$
*/ */
public final class Streams { public final class Streams {
@ -44,7 +41,7 @@ public final class Streams {
* Default buffer size for use in * Default buffer size for use in
* {@link #copy(InputStream, OutputStream, boolean)}. * {@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} * Copies the contents of the given {@link InputStream}
@ -130,7 +127,7 @@ public final class Streams {
/** /**
* This convenience method allows to read a * 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 * content into a string. The platform's default character encoding
* is used for converting bytes into characters. * is used for converting bytes into characters.
* *
@ -147,7 +144,7 @@ public final class Streams {
/** /**
* This convenience method allows to read a * 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. * content into a string, using the given character encoding.
* *
* @param inputStream The input stream to read. * @param inputStream The input stream to read.

2
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). // 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. // now pull out the encoding token the same way.
int encodingPos = word.indexOf('?', charsetPos + 1); int encodingPos = word.indexOf('?', charsetPos + 1);

2
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. * @param message the detail message.
*/ */
public ParseException(String message) { ParseException(String message) {
super(message); super(message);
} }

2
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. * @param out The output stream used to return the decoded data.
* *
* @return the number of bytes produced. * @return the number of bytes produced.
* @exception IOException * @throws IOException
*/ */
public static int decode(byte[] data, OutputStream out) throws IOException { public static int decode(byte[] data, OutputStream out) throws IOException {
int off = 0; int off = 0;

Loading…
Cancel
Save