You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2009/06/08 05:28:43 UTC
svn commit: r782515 - in /myfaces/tomahawk/trunk:
core/src/main/java/org/apache/myfaces/component/html/util/
core/src/main/java/org/apache/myfaces/custom/fileupload/
core/src/main/java/org/apache/myfaces/webapp/filter/
core/src/main/java/org/apache/myf...
Author: lu4242
Date: Mon Jun 8 03:28:42 2009
New Revision: 782515
URL: http://svn.apache.org/viewvc?rev=782515&view=rev
Log:
TOMAHAWK-1420 uploadThresholdSize seems to be ignored and TOMAHAWK-1381 HtmlInputFileUpload does not fail gracefully when filesize exceeds uploadMaxFileSize web.xml value (duplicated issue TOMAHAWK-1305 No error when file is uploaded larger than uploadMaxFileSize) (Thanks to Phillip Webb for help with ServletCacheFileSizeErrorsFileUpload code)
Added:
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/portlet/PortletChacheFileSizeErrorsFileUpload.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/servlet/ServletChacheFileSizeErrorsFileUpload.java
myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/fileupload/
myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java (with props)
Modified:
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/component/html/util/MultipartFilter.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/fileupload/HtmlFileUploadRenderer.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/ExtensionsFilter.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/MultipartRequestWrapper.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/MultipartRequestWrapperConfig.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/PortletMultipartRequestWrapper.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/TomahawkFacesContextWrapper.java
Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/component/html/util/MultipartFilter.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/component/html/util/MultipartFilter.java?rev=782515&r1=782514&r2=782515&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/component/html/util/MultipartFilter.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/component/html/util/MultipartFilter.java Mon Jun 8 03:28:42 2009
@@ -29,7 +29,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.fileupload.FileUpload;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.myfaces.webapp.filter.MultipartRequestWrapper;
@@ -45,18 +45,32 @@
public class MultipartFilter implements Filter
{
+ private int uploadMaxSize = 100 * 1024 * 1024; // 100 MB
+
private int uploadMaxFileSize = 100 * 1024 * 1024; // 10 MB
private int uploadThresholdSize = 1 * 1024 * 1024; // 1 MB
private String uploadRepositoryPath = null; //standard temp directory
-
+
+ private boolean cacheFileSizeErrors = false;
public void init(FilterConfig filterConfig)
{
uploadMaxFileSize = resolveSize(filterConfig.getInitParameter("uploadMaxFileSize"), uploadMaxFileSize);
+ String param = filterConfig.getInitParameter("uploadMaxSize");
+ if (param != null)
+ {
+ uploadMaxSize = resolveSize(param, uploadMaxSize);
+ }
+ else
+ {
+ //If not set, default to uploadMaxFileSize
+ uploadMaxSize = resolveSize(param, uploadMaxFileSize);
+ }
uploadThresholdSize = resolveSize(filterConfig.getInitParameter("uploadThresholdSize"), uploadThresholdSize);
uploadRepositoryPath = filterConfig.getInitParameter("uploadRepositoryPath");
+ cacheFileSizeErrors = getBooleanValue(filterConfig.getInitParameter("cacheFileSizeErrors"), false);
}
@@ -88,7 +102,14 @@
}
return numberParam;
}
+
+ private static boolean getBooleanValue(String initParameter, boolean defaultVal)
+ {
+ if(initParameter == null || initParameter.trim().length()==0)
+ return defaultVal;
+ return (initParameter.equalsIgnoreCase("on") || initParameter.equals("1") || initParameter.equalsIgnoreCase("true"));
+ }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
@@ -101,9 +122,10 @@
HttpServletRequest httpRequest = (HttpServletRequest) request;
// For multipart/form-data requests
- if (FileUpload.isMultipartContent(httpRequest))
+ if (ServletFileUpload.isMultipartContent(httpRequest))
{
- chain.doFilter(new MultipartRequestWrapper(httpRequest, uploadMaxFileSize, uploadThresholdSize, uploadRepositoryPath), response);
+ chain.doFilter(new MultipartRequestWrapper(httpRequest, uploadMaxFileSize,
+ uploadThresholdSize, uploadRepositoryPath, uploadMaxSize , cacheFileSizeErrors), response);
} else
{
chain.doFilter(request, response);
Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java?rev=782515&r1=782514&r2=782515&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java Mon Jun 8 03:28:42 2009
@@ -60,6 +60,7 @@
implements UserRoleAware, AlignProperty
{
private static final String SIZE_LIMIT_EXCEEDED = "sizeLimitExceeded";
+ private static final String FILE_SIZE_LIMIT_EXCEEDED = "fileSizeLimitExceeded";
private static final String FILEUPLOAD_MAX_SIZE = "org.apache.myfaces.custom.fileupload.maxSize";
private static final String FILEUPLOAD_EXCEPTION = "org.apache.myfaces.custom.fileupload.exception";
public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlInputFileUpload";
@@ -84,10 +85,17 @@
/**
* This setting was intended to allow control over how the contents of the
* file get temporarily stored during processing.
- * <p>
- * However it appears that this is only half-implemented, and not at all
- * documented. It is therefore recommended that this not be used.
- * </p>
+ * <p> It allows three options<p>
+ * <ul>
+ * <li>"default": The file is handled on memory while the file size is below
+ * uploadThresholdSize value, otherwise is handled on disk or file storage when
+ * decode occur (set submitted value)</li>
+ * <li>"memory": The file is loaded to memory when decode occur
+ * (set submitted value). In other words, before set the uploaded file as
+ * submitted value it is loaded to memory. Use with caution, because it
+ * could cause OutOfMemory exceptions when the uploaded files are too big. </li>
+ * <li>"file": The file is handled on disk or file storage.</li>
+ * </ul>
*
* @JSFProperty
*/
@@ -127,8 +135,10 @@
String exception =
(String) context.getExternalContext().getRequestMap().get(FILEUPLOAD_EXCEPTION);
- if(exception != null ) {
- if(exception.equals(SIZE_LIMIT_EXCEEDED)) {
+ if(exception != null )
+ {
+ if(exception.equals(SIZE_LIMIT_EXCEEDED))
+ {
Integer maxSize =
(Integer) context.getExternalContext().getRequestMap().get(FILEUPLOAD_MAX_SIZE);
MessageUtils.addMessage(FacesMessage.SEVERITY_ERROR,
@@ -136,7 +146,38 @@
maxSize},
getClientId(context), context);
setValid(false);
- }else {
+ }
+ else if (FILE_SIZE_LIMIT_EXCEEDED.equals(exception))
+ {
+ Integer maxSize =
+ (Integer) context.getExternalContext().getRequestMap().get(FILEUPLOAD_MAX_SIZE);
+ if (maxSize != null)
+ {
+ MessageUtils.addMessage(FacesMessage.SEVERITY_ERROR,
+ SIZE_LIMIT_MESSAGE_ID, new Object[] { getId(),
+ maxSize},
+ getClientId(context), context);
+ }
+ else
+ {
+ maxSize = (Integer) context.getExternalContext().getRequestMap().get(
+ "org.apache.myfaces.custom.fileupload."+this.getClientId(context)+".maxSize");
+ if (maxSize != null)
+ {
+ MessageUtils.addMessage(FacesMessage.SEVERITY_ERROR,
+ SIZE_LIMIT_MESSAGE_ID, new Object[] { getId(),
+ maxSize},
+ getClientId(context), context);
+ }
+ //else
+ //{
+ //Ignore because this exception belongs to other component
+ //}
+ }
+ setValid(false);
+ }
+ else
+ {
throw new IllegalStateException("other exceptions not handled yet, exception : "+exception);
}
}
Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/fileupload/HtmlFileUploadRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/fileupload/HtmlFileUploadRenderer.java?rev=782515&r1=782514&r2=782515&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/fileupload/HtmlFileUploadRenderer.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/fileupload/HtmlFileUploadRenderer.java Mon Jun 8 03:28:42 2009
@@ -107,6 +107,49 @@
}
}
+ private void setSubmittedValueForImplementation(
+ FacesContext facesContext, UIComponent uiComponent, FileItem fileItem)
+ {
+ try
+ {
+ UploadedFile upFile;
+ String implementation =
+ ((HtmlInputFileUpload)uiComponent).getStorage();
+ if (implementation == null || implementation.length() == 0)
+ {
+ implementation = "default";
+ }
+ if (("memory").equals(implementation))
+ {
+ upFile = new UploadedFileDefaultMemoryImpl(fileItem);
+ }
+ else if (("default").equals(implementation))
+ {
+ if (fileItem.isInMemory())
+ {
+ upFile = new UploadedFileDefaultMemoryImpl(fileItem);
+ }
+ else
+ {
+ upFile = new UploadedFileDefaultFileImpl(fileItem);
+ }
+ }
+ else //"file" case
+ {
+ upFile = new UploadedFileDefaultFileImpl(fileItem);
+ }
+
+ ((HtmlInputFileUpload)uiComponent).setSubmittedValue(upFile);
+ ((HtmlInputFileUpload)uiComponent).setValid(true);
+ }
+ catch (IOException ioe)
+ {
+ throw new FacesException(
+ "Exception while processing file upload for file-input : "
+ + uiComponent.getClientId(facesContext), ioe);
+ }
+ }
+
/**
* Handle the postback of a form containing a fileUpload component.
* <p>
@@ -136,18 +179,7 @@
}
if (fileItem != null)
{
- try{
- UploadedFile upFile;
- String implementation = ((HtmlInputFileUpload) uiComponent).getStorage();
- if( implementation == null || ("memory").equals( implementation ) )
- upFile = new UploadedFileDefaultMemoryImpl( fileItem );
- else
- upFile = new UploadedFileDefaultFileImpl( fileItem );
- ((HtmlInputFileUpload)uiComponent).setSubmittedValue(upFile);
- ((HtmlInputFileUpload)uiComponent).setValid(true);
- }catch(IOException ioe){
- throw new FacesException("Exception while processing file upload for file-input : " + uiComponent.getClientId(facesContext),ioe);
- }
+ setSubmittedValueForImplementation(facesContext, uiComponent, fileItem);
}
return;
}
@@ -175,18 +207,7 @@
FileItem fileItem = mpReq.getFileItem(paramName);
if (fileItem != null)
{
- try{
- UploadedFile upFile;
- String implementation = ((HtmlInputFileUpload) uiComponent).getStorage();
- if( implementation == null || ("memory").equals( implementation ) )
- upFile = new UploadedFileDefaultMemoryImpl( fileItem );
- else
- upFile = new UploadedFileDefaultFileImpl( fileItem );
- ((HtmlInputFileUpload)uiComponent).setSubmittedValue(upFile);
- ((HtmlInputFileUpload)uiComponent).setValid(true);
- }catch(IOException ioe){
- throw new FacesException("Exception while processing file upload for file-input : " + uiComponent.getClientId(facesContext),ioe);
- }
+ setSubmittedValueForImplementation(facesContext, uiComponent, fileItem);
}
}
}
Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/ExtensionsFilter.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/ExtensionsFilter.java?rev=782515&r1=782514&r2=782515&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/ExtensionsFilter.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/ExtensionsFilter.java Mon Jun 8 03:28:42 2009
@@ -30,7 +30,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.fileupload.FileUpload;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.renderkit.html.util.AddResource;
@@ -142,12 +142,16 @@
public class ExtensionsFilter implements Filter {
private Log log = LogFactory.getLog(ExtensionsFilter.class);
+
+ private int _uploadMaxSize = 100 * 1024 * 1024; // 100 MB
private int _uploadMaxFileSize = 100 * 1024 * 1024; // 100 MB
private int _uploadThresholdSize = 1 * 1024 * 1024; // 1 MB
private String _uploadRepositoryPath = null; //standard temp directory
+
+ private boolean _cacheFileSizeErrors = false;
private ServletContext _servletContext;
@@ -162,6 +166,8 @@
* <li>uploadMaxFileSize</li>
* <li>uploadThresholdSize</li>
* <li>uploadRepositoryPath</li>
+ * <li>uploadMaxSize</li>
+ * <li>cacheFileSizeErrors</li>
* </ul>
* </p>
* <p>
@@ -191,6 +197,17 @@
*
* Sets the directory in which temporary files (ie caches for those uploaded files that
* are larger than uploadThresholdSize) are to be stored.
+ *
+ * <h2>uploadMaxSize</h2>
+ *
+ * Sets the maximum allowable size for the current request. If not set, its value is the
+ * value set on uploadMaxFileSize param.
+ *
+ * <h2>cacheFileSizeErrors</h2>
+ *
+ * Catch and swallow FileSizeLimitExceededExceptions in order to return as
+ * many usable items as possible.
+ *
*/
public void init(FilterConfig filterConfig) {
// Note that the code here to extract FileUpload configuration params is not actually used.
@@ -206,11 +223,25 @@
_uploadMaxFileSize = resolveSize(param, _uploadMaxFileSize);
+ param = filterConfig.getInitParameter("uploadMaxSize");
+
+ if (param != null)
+ {
+ _uploadMaxSize = resolveSize(param, _uploadMaxSize);
+ }
+ else
+ {
+ //If not set, default to uploadMaxFileSize
+ _uploadMaxSize = resolveSize(param, _uploadMaxFileSize);
+ }
+
param = filterConfig.getInitParameter("uploadThresholdSize");
_uploadThresholdSize = resolveSize(param, _uploadThresholdSize);
_uploadRepositoryPath = filterConfig.getInitParameter("uploadRepositoryPath");
+
+ _cacheFileSizeErrors = getBooleanValue(filterConfig.getInitParameter("cacheFileSizeErrors"), false);
_servletContext = filterConfig.getServletContext();
}
@@ -238,6 +269,14 @@
}
return numberParam;
}
+
+ private static boolean getBooleanValue(String initParameter, boolean defaultVal)
+ {
+ if(initParameter == null || initParameter.trim().length()==0)
+ return defaultVal;
+
+ return (initParameter.equalsIgnoreCase("on") || initParameter.equals("1") || initParameter.equalsIgnoreCase("true"));
+ }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
@@ -279,8 +318,9 @@
// For multipart/form-data requests
// This is done by TomahawkFacesContextWrapper
- if (FileUpload.isMultipartContent(httpRequest)) {
- extendedRequest = new MultipartRequestWrapper(httpRequest, _uploadMaxFileSize, _uploadThresholdSize, _uploadRepositoryPath);
+ if (ServletFileUpload.isMultipartContent(httpRequest)) {
+ extendedRequest = new MultipartRequestWrapper(httpRequest, _uploadMaxFileSize,
+ _uploadThresholdSize, _uploadRepositoryPath, _uploadMaxSize, _cacheFileSizeErrors);
}
try
Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/MultipartRequestWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/MultipartRequestWrapper.java?rev=782515&r1=782514&r2=782515&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/MultipartRequestWrapper.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/MultipartRequestWrapper.java Mon Jun 8 03:28:42 2009
@@ -18,6 +18,7 @@
*/
package org.apache.myfaces.webapp.filter;
+import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.Collections;
import java.util.Enumeration;
@@ -29,13 +30,14 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
-import org.apache.commons.fileupload.DefaultFileItemFactory;
-import org.apache.commons.fileupload.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.webapp.filter.servlet.ServletChacheFileSizeErrorsFileUpload;
/**
* @since 1.1.7
@@ -51,52 +53,132 @@
HttpServletRequest request = null;
HashMap parametersMap = null;
- DiskFileUpload fileUpload = null;
+ ServletFileUpload fileUpload = null;
HashMap fileItems = null;
+ int maxFileSize;
int maxSize;
int thresholdSize;
String repositoryPath;
+ boolean cacheFileSizeErrors;
public MultipartRequestWrapper(HttpServletRequest request,
- int maxSize, int thresholdSize,
+ int maxFileSize, int thresholdSize,
String repositoryPath){
super( request );
this.request = request;
- this.maxSize = maxSize;
+ this.maxFileSize = maxFileSize;
this.thresholdSize = thresholdSize;
this.repositoryPath = repositoryPath;
+ //Default values
+ this.maxSize = maxFileSize;
+ this.cacheFileSizeErrors = false;
+ }
+
+ public MultipartRequestWrapper(HttpServletRequest request,
+ int maxFileSize, int thresholdSize,
+ String repositoryPath, int maxRequestSize, boolean cacheFileSizeErrors){
+ super( request );
+ this.request = request;
+ this.maxFileSize = maxFileSize;
+ this.maxSize = maxRequestSize;
+ this.thresholdSize = thresholdSize;
+ this.repositoryPath = repositoryPath;
+ this.cacheFileSizeErrors = cacheFileSizeErrors;
}
private void parseRequest() {
- fileUpload = new DiskFileUpload();
- fileUpload.setFileItemFactory(new DefaultFileItemFactory());
+ if (cacheFileSizeErrors)
+ {
+ fileUpload = new ServletChacheFileSizeErrorsFileUpload();
+ }
+ else
+ {
+ fileUpload = new ServletFileUpload();
+ }
+ //fileUpload.setFileItemFactory(new DefaultFileItemFactory()); //USE DiskFileItemFactory
fileUpload.setSizeMax(maxSize);
+ fileUpload.setFileSizeMax(maxFileSize);
- fileUpload.setSizeThreshold(thresholdSize);
+ //fileUpload.setSizeThreshold(thresholdSize); //Pass thresholdSize as param for DiskFileItemFactory
+ //if(repositoryPath != null && repositoryPath.trim().length()>0)
+ // fileUpload.setRepositoryPath(repositoryPath);
+
if(repositoryPath != null && repositoryPath.trim().length()>0)
- fileUpload.setRepositoryPath(repositoryPath);
+ {
+ fileUpload.setFileItemFactory(
+ new DiskFileItemFactory(thresholdSize,
+ new File(repositoryPath)));
+ }
+ else
+ {
+ fileUpload.setFileItemFactory(
+ new DiskFileItemFactory(thresholdSize,
+ new File(System.getProperty("java.io.tmpdir"))));
+ }
String charset = request.getCharacterEncoding();
fileUpload.setHeaderEncoding(charset);
List requestParameters = null;
- try{
- requestParameters = fileUpload.parseRequest(request);
- } catch (FileUploadBase.SizeLimitExceededException e) {
-
+
+ try
+ {
+ if (cacheFileSizeErrors)
+ {
+ requestParameters = ((ServletChacheFileSizeErrorsFileUpload) fileUpload).
+ parseRequestCatchingFileSizeErrors(request, fileUpload);
+ }
+ else
+ {
+ requestParameters = fileUpload.parseRequest(request);
+ }
+ }
+ catch (FileUploadBase.FileSizeLimitExceededException e)
+ {
+ // Since commons-fileupload does not allow to continue processing files
+ // if this exception is thrown, we can't do anything else.
+ // So, the current request is rejected and we can't restore state, so
+ // this request is dealt like a new request, but note that caching the params
+ // below it is possible to detect if the current request has been aborted
+ // or not.
+ // Note that if cacheFileSizeErrors is true, this is not thrown, so the request
+ // is not aborted unless other different error occur.
request.setAttribute(
- "org.apache.myfaces.custom.fileupload.exception","sizeLimitExceeded");
+ "org.apache.myfaces.custom.fileupload.exception","fileSizeLimitExceeded");
request.setAttribute("org.apache.myfaces.custom.fileupload.maxSize",
- new Integer(maxSize));
+ new Integer((int)maxFileSize));
+
+ if (log.isWarnEnabled())
+ log.warn("FileSizeLimitExceededException while uploading file.", e);
requestParameters = Collections.EMPTY_LIST;
-
- }catch(FileUploadException fue){
- log.error("Exception while uploading file.", fue);
+ }
+ catch (FileUploadBase.SizeLimitExceededException e)
+ {
+ // This exception is thrown when the max request size has been reached.
+ // In this case, the current request is rejected. The current
+ // request is dealt like a new request, but note that caching the params below
+ // params it is possible to detect if the current request has been aborted
+ // or not.
+ request.setAttribute(
+ "org.apache.myfaces.custom.fileupload.exception","sizeLimitExceeded");
+ request.setAttribute("org.apache.myfaces.custom.fileupload.maxSize",
+ new Integer((int)maxSize));
+
+ if (log.isWarnEnabled())
+ log.warn("SizeLimitExceededException while uploading file.", e);
+
requestParameters = Collections.EMPTY_LIST;
}
+ catch(FileUploadException fue)
+ {
+ if (log.isErrorEnabled())
+ log.error("Exception while uploading file.", fue);
+
+ requestParameters = Collections.EMPTY_LIST;
+ }
parametersMap = new HashMap( requestParameters.size() );
fileItems = new HashMap();
Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/MultipartRequestWrapperConfig.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/MultipartRequestWrapperConfig.java?rev=782515&r1=782514&r2=782515&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/MultipartRequestWrapperConfig.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/MultipartRequestWrapperConfig.java Mon Jun 8 03:28:42 2009
@@ -33,14 +33,17 @@
class MultipartRequestWrapperConfig
{
+ private int _uploadMaxSize = 100 * 1024 * 1024; // 10 MB
private int _uploadMaxFileSize = 100 * 1024 * 1024; // 10 MB
private int _uploadThresholdSize = 1 * 1024 * 1024; // 1 MB
private String _uploadRepositoryPath = null; //standard temp directory
+ private boolean _cacheFileSizeErrors = false;
+ private static final String UPLOAD_MAX_SIZE = "org.apache.myfaces.UPLOAD_MAX_SIZE";
private static final String UPLOAD_MAX_FILE_SIZE = "org.apache.myfaces.UPLOAD_MAX_FILE_SIZE";
private static final String UPLOAD_THRESHOLD_SIZE = "org.apache.myfaces.UPLOAD_THRESHOLD_SIZE";
private static final String UPLOAD_MAX_REPOSITORY_PATH = "org.apache.myfaces.UPLOAD_MAX_REPOSITORY_PATH";
-
+ private static final String UPLOAD_CACHE_FILE_SIZE_ERRORS = "org.apache.myfaces.UPLOAD_CACHE_FILE_SIZE_ERRORS";
private static final String MULTIPART_REQUEST_WRAPPER_CONFIG = MultipartRequestWrapperConfig.class.getName();
private MultipartRequestWrapperConfig() {}
@@ -76,6 +79,24 @@
return numberParam;
}
+ private static boolean getBooleanValue(String initParameter, boolean defaultVal)
+ {
+ if(initParameter == null || initParameter.trim().length()==0)
+ return defaultVal;
+
+ return (initParameter.equalsIgnoreCase("on") || initParameter.equals("1") || initParameter.equalsIgnoreCase("true"));
+ }
+
+ public int getUploadMaxSize()
+ {
+ return _uploadMaxSize;
+ }
+
+ public void setUploadMaxSize(int uploadMaxSize)
+ {
+ this._uploadMaxSize = uploadMaxSize;
+ }
+
public int getUploadMaxFileSize()
{
return _uploadMaxFileSize;
@@ -104,7 +125,17 @@
public void setUploadRepositoryPath(String uploadRepositoryPath)
{
this._uploadRepositoryPath = uploadRepositoryPath;
- }
+ }
+
+ public boolean isCacheFileSizeErrors()
+ {
+ return _cacheFileSizeErrors;
+ }
+
+ public void setCacheFileSizeErrors(boolean cacheFileSizeErrors)
+ {
+ this._cacheFileSizeErrors = cacheFileSizeErrors;
+ }
public static MultipartRequestWrapperConfig getMultipartRequestWrapperConfig(
ExternalContext context)
@@ -127,6 +158,21 @@
config._uploadMaxFileSize = resolveSize(param,
config._uploadMaxFileSize);
+
+ param = servletContext
+ .getInitParameter(UPLOAD_MAX_SIZE);
+
+ if (param != null)
+ {
+ config._uploadMaxSize = resolveSize(param,
+ config._uploadMaxSize);
+ }
+ else
+ {
+ //If not set, default to uploadMaxFileSize
+ config._uploadMaxSize = resolveSize(param,
+ config._uploadMaxFileSize);
+ }
param = servletContext.getInitParameter(UPLOAD_THRESHOLD_SIZE);
@@ -135,7 +181,10 @@
config._uploadRepositoryPath = servletContext
.getInitParameter(UPLOAD_MAX_REPOSITORY_PATH);
-
+
+ config._cacheFileSizeErrors = getBooleanValue(servletContext
+ .getInitParameter(UPLOAD_CACHE_FILE_SIZE_ERRORS), false);
+
context.getApplicationMap().put(MULTIPART_REQUEST_WRAPPER_CONFIG,
config);
}
@@ -148,6 +197,21 @@
config._uploadMaxFileSize = resolveSize(param,
config._uploadMaxFileSize);
+
+ param = PortletUtils.getContextInitParameter(
+ portletContext, UPLOAD_MAX_SIZE);
+
+ if (param != null)
+ {
+ config._uploadMaxSize = resolveSize(param,
+ config._uploadMaxSize);
+ }
+ else
+ {
+ //If not set, default to uploadMaxFileSize
+ config._uploadMaxSize = resolveSize(param,
+ config._uploadMaxFileSize);
+ }
param = PortletUtils.getContextInitParameter(
portletContext, UPLOAD_THRESHOLD_SIZE);
@@ -157,10 +221,13 @@
config._uploadRepositoryPath = PortletUtils.getContextInitParameter(
portletContext,UPLOAD_MAX_REPOSITORY_PATH);
+
+ config._cacheFileSizeErrors = getBooleanValue(PortletUtils
+ .getContextInitParameter(portletContext,
+ UPLOAD_CACHE_FILE_SIZE_ERRORS), false);
context.getApplicationMap().put(MULTIPART_REQUEST_WRAPPER_CONFIG,
config);
-
}
}
Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/PortletMultipartRequestWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/PortletMultipartRequestWrapper.java?rev=782515&r1=782514&r2=782515&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/PortletMultipartRequestWrapper.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/PortletMultipartRequestWrapper.java Mon Jun 8 03:28:42 2009
@@ -37,6 +37,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.webapp.filter.portlet.ActionRequestWrapper;
+import org.apache.myfaces.webapp.filter.portlet.PortletChacheFileSizeErrorsFileUpload;
/**
* @since 1.1.8
@@ -54,24 +55,50 @@
HashMap parametersMap = null;
PortletFileUpload fileUpload = null;
HashMap fileItems = null;
+ int maxFileSize;
int maxSize;
int thresholdSize;
String repositoryPath;
+ boolean cacheFileSizeErrors;
public PortletMultipartRequestWrapper(Object request,
- int maxSize, int thresholdSize,
+ int maxFileSize, int thresholdSize,
String repositoryPath){
super((ActionRequest) request );
this.request = (ActionRequest) request;
- this.maxSize = maxSize;
+ this.maxFileSize = maxFileSize;
this.thresholdSize = thresholdSize;
this.repositoryPath = repositoryPath;
+ //Default values
+ this.maxSize = maxFileSize;
+ this.cacheFileSizeErrors = false;
}
+
+ public PortletMultipartRequestWrapper(Object request,
+ int maxFileSize, int thresholdSize,
+ String repositoryPath, int maxRequestSize, boolean cacheFileSizeErrors){
+ super((ActionRequest) request );
+ this.request = (ActionRequest) request;
+ this.maxFileSize = maxFileSize;
+ this.maxSize = maxRequestSize;
+ this.thresholdSize = thresholdSize;
+ this.repositoryPath = repositoryPath;
+ this.cacheFileSizeErrors = cacheFileSizeErrors;
+ }
+
private void parseRequest() {
- fileUpload = new PortletFileUpload();
+ if (cacheFileSizeErrors)
+ {
+ fileUpload = new PortletChacheFileSizeErrorsFileUpload();
+ }
+ else
+ {
+ fileUpload = new PortletFileUpload();
+ }
fileUpload.setSizeMax(maxSize);
+ fileUpload.setFileSizeMax(maxFileSize);
//fileUpload.setSizeThreshold(thresholdSize);
@@ -88,27 +115,69 @@
new DiskFileItemFactory(thresholdSize,
new File(System.getProperty("java.io.tmpdir"))));
}
-
+
String charset = request.getCharacterEncoding();
fileUpload.setHeaderEncoding(charset);
List requestParameters = null;
- try{
- requestParameters = fileUpload.parseRequest(request);
- } catch (FileUploadBase.SizeLimitExceededException e) {
-
+
+ try
+ {
+ if (cacheFileSizeErrors)
+ {
+ requestParameters = ((PortletChacheFileSizeErrorsFileUpload) fileUpload).
+ parseRequestCatchingFileSizeErrors(request, fileUpload);
+ }
+ else
+ {
+ requestParameters = fileUpload.parseRequest(request);
+ }
+ }
+ catch (FileUploadBase.FileSizeLimitExceededException e)
+ {
+ // Since commons-fileupload does not allow to continue processing files
+ // if this exception is thrown, we can't do anything else.
+ // So, the current request is rejected and we can't restore state, so
+ // this request is dealt like a new request, but note that caching the params
+ // below it is possible to detect if the current request has been aborted
+ // or not.
+ // Note that if cacheFileSizeErrors is true, this is not thrown, so the request
+ // is not aborted unless other different error occur.
request.setAttribute(
- "org.apache.myfaces.custom.fileupload.exception","sizeLimitExceeded");
+ "org.apache.myfaces.custom.fileupload.exception","fileSizeLimitExceeded");
request.setAttribute("org.apache.myfaces.custom.fileupload.maxSize",
- new Integer(maxSize));
+ new Integer((int)maxFileSize));
+
+ if (log.isWarnEnabled())
+ log.warn("FileSizeLimitExceededException while uploading file.", e);
requestParameters = Collections.EMPTY_LIST;
-
- }catch(FileUploadException fue){
- log.error("Exception while uploading file.", fue);
+ }
+ catch (FileUploadBase.SizeLimitExceededException e)
+ {
+ // This exception is thrown when the max request size has been reached.
+ // In this case, the current request is rejected. The current
+ // request is dealt like a new request, but note that caching the params below
+ // params it is possible to detect if the current request has been aborted
+ // or not.
+ request.setAttribute(
+ "org.apache.myfaces.custom.fileupload.exception","sizeLimitExceeded");
+ request.setAttribute("org.apache.myfaces.custom.fileupload.maxSize",
+ new Integer((int)maxSize));
+
+ if (log.isWarnEnabled())
+ log.warn("SizeLimitExceededException while uploading file.", e);
+
requestParameters = Collections.EMPTY_LIST;
}
+ catch(FileUploadException fue)
+ {
+ if (log.isErrorEnabled())
+ log.error("Exception while uploading file.", fue);
+
+ requestParameters = Collections.EMPTY_LIST;
+ }
parametersMap = new HashMap( requestParameters.size() );
fileItems = new HashMap();
@@ -239,4 +308,4 @@
{
return WWW_FORM_URLENCODED_TYPE;
}
-}
\ No newline at end of file
+}
Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/TomahawkFacesContextWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/TomahawkFacesContextWrapper.java?rev=782515&r1=782514&r2=782515&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/TomahawkFacesContextWrapper.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/TomahawkFacesContextWrapper.java Mon Jun 8 03:28:42 2009
@@ -34,7 +34,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.fileupload.FileUpload;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.myfaces.renderkit.html.util.AddResource;
import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
import org.apache.myfaces.tomahawk.util.ExternalContextUtils;
@@ -83,6 +83,8 @@
* <li>org.apache.myfaces.UPLOAD_MAX_FILE_SIZE</li>
* <li>org.apache.myfaces.UPLOAD_THRESHOLD_SIZE</li>
* <li>org.apache.myfaces.UPLOAD_MAX_REPOSITORY_PATH</li>
+ * <li>org.apache.myfaces.UPLOAD_MAX_SIZE</li>
+ * <li>org.apache.myfaces.UPLOAD_CACHE_FILE_SIZE_ERRORS</li>
* </ul>
*
* @since 1.1.7
@@ -129,7 +131,8 @@
.getExternalContext());
extendedRequest = new PortletMultipartRequestWrapper( portletRequest, config.getUploadMaxFileSize(),
- config.getUploadThresholdSize(), config.getUploadRepositoryPath());
+ config.getUploadThresholdSize(), config.getUploadRepositoryPath(),
+ config.getUploadMaxSize(), config.isCacheFileSizeErrors());
}
AddResource addResource= AddResourceFactory.getInstance(this);
@@ -160,7 +163,7 @@
boolean multipartContent = false;
- if (FileUpload.isMultipartContent(httpRequest)) {
+ if (ServletFileUpload.isMultipartContent(httpRequest)) {
multipartContent = true;
MultipartRequestWrapperConfig config = MultipartRequestWrapperConfig
@@ -168,7 +171,8 @@
.getExternalContext());
extendedRequest = new MultipartRequestWrapper(httpRequest, config.getUploadMaxFileSize(),
- config.getUploadThresholdSize(), config.getUploadRepositoryPath());
+ config.getUploadThresholdSize(), config.getUploadRepositoryPath(),
+ config.getUploadMaxSize(), config.isCacheFileSizeErrors());
}
Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/portlet/PortletChacheFileSizeErrorsFileUpload.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/portlet/PortletChacheFileSizeErrorsFileUpload.java?rev=782515&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/portlet/PortletChacheFileSizeErrorsFileUpload.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/portlet/PortletChacheFileSizeErrorsFileUpload.java Mon Jun 8 03:28:42 2009
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.webapp.filter.portlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.portlet.ActionRequest;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.FileItemHeaders;
+import org.apache.commons.fileupload.FileItemHeadersSupport;
+import org.apache.commons.fileupload.FileItemIterator;
+import org.apache.commons.fileupload.FileItemStream;
+import org.apache.commons.fileupload.FileUpload;
+import org.apache.commons.fileupload.FileUploadBase;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.RequestContext;
+import org.apache.commons.fileupload.portlet.PortletFileUpload;
+import org.apache.commons.fileupload.portlet.PortletRequestContext;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.fileupload.util.LimitedInputStream;
+import org.apache.commons.fileupload.util.Streams;
+
+/**
+ * Custom implementation of PortletFileUpload intended to parse request but it
+ * catch and swallow FileSizeLimitExceededExceptions in order to return as
+ * many usable items as possible.
+ *
+ * <p>
+ * NOTE: This class should be used(instantiated) only by
+ * PortletMultipartRequestWrapper. By that reason, it could be changed
+ * or removed in the future.
+ * </p>
+ *
+ * @since 1.1.9
+ * @author Phillip Webb
+ * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
+ * @version $Revision: 703744 $ $Date: 2008-10-11 17:28:20 -0500 (Sat, 11 Oct 2008) $
+ *
+ */
+public class PortletChacheFileSizeErrorsFileUpload extends PortletFileUpload
+{
+
+ public PortletChacheFileSizeErrorsFileUpload()
+ {
+ super();
+ }
+
+ public PortletChacheFileSizeErrorsFileUpload(FileItemFactory fileItemFactory)
+ {
+ super(fileItemFactory);
+ }
+
+ /**
+ * Determine the length of an uploaded file as indicated by the header.
+ *
+ * @param pHeaders
+ * @return length or -1
+ */
+ private long getContentLength(FileItemHeaders pHeaders) {
+ try {
+ return Long.parseLong(pHeaders.getHeader(FileUploadBase.CONTENT_LENGTH));
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ /**
+ * Similar to {@link ServletFileUpload#parseRequest(RequestContext)} but will
+ * catch and swallow FileSizeLimitExceededExceptions in order to return as
+ * many usable items as possible.
+ *
+ * @param fileUpload
+ * @return List of {@link FileItem} excluding any that exceed max size.
+ * @throws FileUploadException
+ */
+ public List parseRequestCatchingFileSizeErrors(ActionRequest request, FileUpload fileUpload)
+ throws FileUploadException
+ {
+ try
+ {
+ List items = new ArrayList();
+
+ // The line below throws a SizeLimitExceededException (wrapped by a
+ // FileUploadIOException) if the request is longer than the max size
+ // allowed by fileupload requests (FileUpload.getSizeMax)
+ // But note that if the request does not send proper headers this check
+ // just will not do anything and we still have to check it again.
+ FileItemIterator iter = fileUpload
+ .getItemIterator(new PortletRequestContext(request));
+
+ FileItemFactory fac = fileUpload.getFileItemFactory();
+ if (fac == null)
+ {
+ throw new NullPointerException(
+ "No FileItemFactory has been set.");
+ }
+
+ long maxFileSize = this.getFileSizeMax();
+ long maxSize = this.getSizeMax();
+ boolean checkMaxSize = false;
+
+ if (maxFileSize == -1L)
+ {
+ //The max allowed file size should be approximate to the maxSize
+ maxFileSize = maxSize;
+ }
+ if (maxSize != -1L)
+ {
+ checkMaxSize = true;
+ }
+
+ while (iter.hasNext())
+ {
+ final FileItemStream item = iter.next();
+ FileItem fileItem = fac.createItem(item.getFieldName(), item
+ .getContentType(), item.isFormField(), item.getName());
+
+ long allowedLimit = 0L;
+ try
+ {
+ if (maxFileSize != -1L || checkMaxSize)
+ {
+ if (checkMaxSize)
+ {
+ allowedLimit = maxSize > maxFileSize ? maxFileSize : maxSize;
+ }
+ else
+ {
+ //Just put the limit
+ allowedLimit = maxFileSize;
+ }
+
+ long contentLength = getContentLength(item.getHeaders());
+
+ //If we have a content length in the header we can use it
+ if (contentLength != -1L && contentLength > allowedLimit)
+ {
+ throw new FileUploadIOException(
+ new FileSizeLimitExceededException(
+ "The field "
+ + item.getFieldName()
+ + " exceeds its maximum permitted "
+ + " size of " + allowedLimit
+ + " characters.",
+ contentLength, allowedLimit));
+ }
+
+ //Otherwise we must limit the input as it arrives (NOTE: we cannot rely
+ //on commons upload to throw this exception as it will close the
+ //underlying stream
+ final InputStream itemInputStream = item.openStream();
+
+ InputStream limitedInputStream = new LimitedInputStream(
+ itemInputStream, allowedLimit)
+ {
+ protected void raiseError(long pSizeMax, long pCount)
+ throws IOException
+ {
+ throw new FileUploadIOException(
+ new FileSizeLimitExceededException(
+ "The field "
+ + item.getFieldName()
+ + " exceeds its maximum permitted "
+ + " size of "
+ + pSizeMax
+ + " characters.",
+ pCount, pSizeMax));
+ }
+ };
+
+ //Copy from the limited stream
+ long bytesCopied = Streams.copy(limitedInputStream, fileItem
+ .getOutputStream(), true);
+
+ // Decrement the bytesCopied values from maxSize, so the next file copied
+ // takes into account this value when allowedLimit var is calculated
+ // Note the invariant before the line is maxSize >= bytesCopied, since if this
+ // is not true a FileUploadIOException is thrown first.
+ maxSize -= bytesCopied;
+ }
+ else
+ {
+ //We can just copy the data
+ Streams.copy(item.openStream(), fileItem
+ .getOutputStream(), true);
+ }
+ }
+ catch (FileUploadIOException e)
+ {
+ try
+ {
+ throw (FileUploadException) e.getCause();
+ }
+ catch (FileUploadBase.FileSizeLimitExceededException se)
+ {
+ request
+ .setAttribute(
+ "org.apache.myfaces.custom.fileupload.exception",
+ "fileSizeLimitExceeded");
+ String fieldName = fileItem.getFieldName();
+ request.setAttribute(
+ "org.apache.myfaces.custom.fileupload."+fieldName+".maxSize",
+ new Integer((int)allowedLimit));
+ }
+ }
+ catch (IOException e)
+ {
+ throw new IOFileUploadException("Processing of "
+ + FileUploadBase.MULTIPART_FORM_DATA
+ + " request failed. " + e.getMessage(), e);
+ }
+ if (fileItem instanceof FileItemHeadersSupport)
+ {
+ final FileItemHeaders fih = item.getHeaders();
+ ((FileItemHeadersSupport) fileItem).setHeaders(fih);
+ }
+ if (fileItem != null)
+ {
+ items.add(fileItem);
+ }
+ }
+ return items;
+ }
+ catch (FileUploadIOException e)
+ {
+ throw (FileUploadException) e.getCause();
+ }
+ catch (IOException e)
+ {
+ throw new FileUploadException(e.getMessage(), e);
+ }
+ }
+}
Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/servlet/ServletChacheFileSizeErrorsFileUpload.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/servlet/ServletChacheFileSizeErrorsFileUpload.java?rev=782515&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/servlet/ServletChacheFileSizeErrorsFileUpload.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/webapp/filter/servlet/ServletChacheFileSizeErrorsFileUpload.java Mon Jun 8 03:28:42 2009
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.webapp.filter.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.FileItemHeaders;
+import org.apache.commons.fileupload.FileItemHeadersSupport;
+import org.apache.commons.fileupload.FileItemIterator;
+import org.apache.commons.fileupload.FileItemStream;
+import org.apache.commons.fileupload.FileUpload;
+import org.apache.commons.fileupload.FileUploadBase;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.RequestContext;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.fileupload.servlet.ServletRequestContext;
+import org.apache.commons.fileupload.util.LimitedInputStream;
+import org.apache.commons.fileupload.util.Streams;
+
+/**
+ * Custom implementation of ServletFileUpload intended to parse request but it
+ * catch and swallow FileSizeLimitExceededExceptions in order to return as
+ * many usable items as possible.
+ *
+ * <p>
+ * NOTE: This class should be used(instantiated) only by
+ * ServletMultipartRequestWrapper. By that reason, it could be changed
+ * or removed in the future.
+ * </p>
+ *
+ * @since 1.1.9
+ * @author Phillip Webb
+ * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
+ * @version $Revision: 703744 $ $Date: 2008-10-11 17:28:20 -0500 (Sat, 11 Oct 2008) $
+ *
+ */
+public class ServletChacheFileSizeErrorsFileUpload extends ServletFileUpload
+{
+
+ public ServletChacheFileSizeErrorsFileUpload()
+ {
+ super();
+ }
+
+ public ServletChacheFileSizeErrorsFileUpload(FileItemFactory fileItemFactory)
+ {
+ super(fileItemFactory);
+ }
+
+ /**
+ * Determine the length of an uploaded file as indicated by the header.
+ *
+ * @param pHeaders
+ * @return length or -1
+ */
+ private long getContentLength(FileItemHeaders pHeaders) {
+ try {
+ return Long.parseLong(pHeaders.getHeader(FileUploadBase.CONTENT_LENGTH));
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ /**
+ * Similar to {@link ServletFileUpload#parseRequest(RequestContext)} but will
+ * catch and swallow FileSizeLimitExceededExceptions in order to return as
+ * many usable items as possible.
+ *
+ * @param fileUpload
+ * @return List of {@link FileItem} excluding any that exceed max size.
+ * @throws FileUploadException
+ */
+ public List parseRequestCatchingFileSizeErrors(HttpServletRequest request, FileUpload fileUpload)
+ throws FileUploadException
+ {
+ try
+ {
+ List items = new ArrayList();
+
+ // The line below throws a SizeLimitExceededException (wrapped by a
+ // FileUploadIOException) if the request is longer than the max size
+ // allowed by fileupload requests (FileUpload.getSizeMax)
+ // But note that if the request does not send proper headers this check
+ // just will not do anything and we still have to check it again.
+ FileItemIterator iter = fileUpload
+ .getItemIterator(new ServletRequestContext(request));
+
+ FileItemFactory fac = fileUpload.getFileItemFactory();
+ if (fac == null)
+ {
+ throw new NullPointerException(
+ "No FileItemFactory has been set.");
+ }
+
+ long maxFileSize = this.getFileSizeMax();
+ long maxSize = this.getSizeMax();
+ boolean checkMaxSize = false;
+
+ if (maxFileSize == -1L)
+ {
+ //The max allowed file size should be approximate to the maxSize
+ maxFileSize = maxSize;
+ }
+ if (maxSize != -1L)
+ {
+ checkMaxSize = true;
+ }
+
+ while (iter.hasNext())
+ {
+ final FileItemStream item = iter.next();
+ FileItem fileItem = fac.createItem(item.getFieldName(), item
+ .getContentType(), item.isFormField(), item.getName());
+
+ long allowedLimit = 0L;
+ try
+ {
+ if (maxFileSize != -1L || checkMaxSize)
+ {
+ if (checkMaxSize)
+ {
+ allowedLimit = maxSize > maxFileSize ? maxFileSize : maxSize;
+ }
+ else
+ {
+ //Just put the limit
+ allowedLimit = maxFileSize;
+ }
+
+ long contentLength = getContentLength(item.getHeaders());
+
+ //If we have a content length in the header we can use it
+ if (contentLength != -1L && contentLength > allowedLimit)
+ {
+ throw new FileUploadIOException(
+ new FileSizeLimitExceededException(
+ "The field "
+ + item.getFieldName()
+ + " exceeds its maximum permitted "
+ + " size of " + allowedLimit
+ + " characters.",
+ contentLength, allowedLimit));
+ }
+
+ //Otherwise we must limit the input as it arrives (NOTE: we cannot rely
+ //on commons upload to throw this exception as it will close the
+ //underlying stream
+ final InputStream itemInputStream = item.openStream();
+
+ InputStream limitedInputStream = new LimitedInputStream(
+ itemInputStream, allowedLimit)
+ {
+ protected void raiseError(long pSizeMax, long pCount)
+ throws IOException
+ {
+ throw new FileUploadIOException(
+ new FileSizeLimitExceededException(
+ "The field "
+ + item.getFieldName()
+ + " exceeds its maximum permitted "
+ + " size of "
+ + pSizeMax
+ + " characters.",
+ pCount, pSizeMax));
+ }
+ };
+
+ //Copy from the limited stream
+ long bytesCopied = Streams.copy(limitedInputStream, fileItem
+ .getOutputStream(), true);
+
+ // Decrement the bytesCopied values from maxSize, so the next file copied
+ // takes into account this value when allowedLimit var is calculated
+ // Note the invariant before the line is maxSize >= bytesCopied, since if this
+ // is not true a FileUploadIOException is thrown first.
+ maxSize -= bytesCopied;
+ }
+ else
+ {
+ //We can just copy the data
+ Streams.copy(item.openStream(), fileItem
+ .getOutputStream(), true);
+ }
+ }
+ catch (FileUploadIOException e)
+ {
+ try
+ {
+ throw (FileUploadException) e.getCause();
+ }
+ catch (FileUploadBase.FileSizeLimitExceededException se)
+ {
+ request
+ .setAttribute(
+ "org.apache.myfaces.custom.fileupload.exception",
+ "fileSizeLimitExceeded");
+ String fieldName = fileItem.getFieldName();
+ request.setAttribute(
+ "org.apache.myfaces.custom.fileupload."+fieldName+".maxSize",
+ new Integer((int)allowedLimit));
+ }
+ }
+ catch (IOException e)
+ {
+ throw new IOFileUploadException("Processing of "
+ + FileUploadBase.MULTIPART_FORM_DATA
+ + " request failed. " + e.getMessage(), e);
+ }
+ if (fileItem instanceof FileItemHeadersSupport)
+ {
+ final FileItemHeaders fih = item.getHeaders();
+ ((FileItemHeadersSupport) fileItem).setHeaders(fih);
+ }
+ if (fileItem != null)
+ {
+ items.add(fileItem);
+ }
+ }
+ return items;
+ }
+ catch (FileUploadIOException e)
+ {
+ throw (FileUploadException) e.getCause();
+ }
+ catch (IOException e)
+ {
+ throw new FileUploadException(e.getMessage(), e);
+ }
+ }
+}
Added: myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java?rev=782515&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java (added)
+++ myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java Mon Jun 8 03:28:42 2009
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.fileupload;
+
+import javax.el.ValueExpression;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.component.html.HtmlInputText;
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.component.AlignProperty;
+import org.apache.myfaces.component.UserRoleAware;
+import org.apache.myfaces.component.UserRoleUtils;
+import org.apache.myfaces.shared_tomahawk.util.MessageUtils;
+
+/**
+ * Creates a file-selection widget in the rendered page which allows a user to select
+ * a file for uploading to the server.
+ * <p>
+ * When the page is selected (using a command component such as commandButton), the
+ * currently selected file contents are included in the data posted to the server.
+ * The contents are cached somewhere, and an object of type UploadedFile will then
+ * be assigned to the property pointed to by the "value" expression of this component.
+ * </p>
+ * <p>
+ * You must enable the Tomahawk ExtensionsFilter to make this component work (see web.xml).
+ * </p>
+ * <p>
+ * Also, don't forget to set the form's attribute "enctype" to "multipart/form-data".
+ * See "examples/web/fileupload.jsp" for an example!
+ * </p>
+ * <p>
+ * Unless otherwise specified, all attributes accept static values or EL expressions.
+ * </p>
+ *
+ * @JSFComponent
+ * name = "t:inputFileUpload"
+ * class = "org.apache.myfaces.custom.fileupload.HtmlInputFileUpload"
+ * tagClass = "org.apache.myfaces.custom.fileupload.HtmlInputFileUploadTag"
+ * @since 1.1.7
+ * @author Manfred Geiler (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public abstract class AbstractHtmlInputFileUpload
+ extends HtmlInputText
+ implements UserRoleAware, AlignProperty
+{
+ private static final String SIZE_LIMIT_EXCEEDED = "sizeLimitExceeded";
+ private static final String FILE_SIZE_LIMIT_EXCEEDED = "fileSizeLimitExceeded";
+ private static final String FILEUPLOAD_MAX_SIZE = "org.apache.myfaces.custom.fileupload.maxSize";
+ private static final String FILEUPLOAD_EXCEPTION = "org.apache.myfaces.custom.fileupload.exception";
+ public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlInputFileUpload";
+ public static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.FileUpload";
+ public static final String SIZE_LIMIT_MESSAGE_ID = "org.apache.myfaces.FileUpload.SIZE_LIMIT";
+
+ public AbstractHtmlInputFileUpload()
+ {
+ setRendererType(DEFAULT_RENDERER_TYPE);
+ }
+
+ public void setUploadedFile(UploadedFile upFile)
+ {
+ setValue(upFile);
+ }
+
+ public UploadedFile getUploadedFile()
+ {
+ return (UploadedFile)getValue();
+ }
+
+ /**
+ * This setting was intended to allow control over how the contents of the
+ * file get temporarily stored during processing.
+ * <p> It allows three options<p>
+ * <ul>
+ * <li>"default": The file is handled on memory while the file size is below
+ * uploadThresholdSize value, otherwise is handled on disk or file storage when
+ * decode occur (set submitted value)</li>
+ * <li>"memory": The file is loaded to memory when decode occur
+ * (set submitted value). In other words, before set the uploaded file as
+ * submitted value it is loaded to memory. Use with caution, because it
+ * could cause OutOfMemory exceptions when the uploaded files are too big. </li>
+ * <li>"file": The file is handled on disk or file storage.</li>
+ * </ul>
+ *
+ * @JSFProperty
+ */
+ public abstract String getStorage();
+
+ /**
+ * This property appears to have no purpose at all. It certainly has no
+ * documentation.
+ *
+ * @JSFProperty
+ */
+ public abstract String getAccept();
+
+ /**
+ * An EL expression to which an UploadedFile object will be assigned on postback
+ * if the user specified a file to upload to the server.
+ *
+ * @JSFProperty
+ */
+ public Object getValue()
+ {
+ return super.getValue();
+ }
+
+ public boolean isRendered()
+ {
+ if (!UserRoleUtils.isVisibleOnUserRole(this)) return false;
+ return super.isRendered();
+ }
+
+ protected void validateValue(FacesContext context, Object convertedValue)
+ {
+ super.validateValue(context, convertedValue);
+
+ if (isValid())
+ {
+ String exception =
+ (String) context.getExternalContext().getRequestMap().get(FILEUPLOAD_EXCEPTION);
+
+ if(exception != null )
+ {
+ if(exception.equals(SIZE_LIMIT_EXCEEDED))
+ {
+ Integer maxSize =
+ (Integer) context.getExternalContext().getRequestMap().get(FILEUPLOAD_MAX_SIZE);
+ MessageUtils.addMessage(FacesMessage.SEVERITY_ERROR,
+ SIZE_LIMIT_MESSAGE_ID, new Object[] { getLabel(context, this),
+ maxSize},
+ getClientId(context), context);
+ setValid(false);
+ }
+ else if (FILE_SIZE_LIMIT_EXCEEDED.equals(exception))
+ {
+ Integer maxSize =
+ (Integer) context.getExternalContext().getRequestMap().get(FILEUPLOAD_MAX_SIZE);
+ if (maxSize != null)
+ {
+ MessageUtils.addMessage(FacesMessage.SEVERITY_ERROR,
+ SIZE_LIMIT_MESSAGE_ID, new Object[] { getLabel(context, this),
+ maxSize},
+ getClientId(context), context);
+ }
+ else
+ {
+ maxSize = (Integer) context.getExternalContext().getRequestMap().get(
+ "org.apache.myfaces.custom.fileupload."+this.getClientId(context)+".maxSize");
+ if (maxSize != null)
+ {
+ MessageUtils.addMessage(FacesMessage.SEVERITY_ERROR,
+ SIZE_LIMIT_MESSAGE_ID, new Object[] { getLabel(context, this),
+ maxSize},
+ getClientId(context), context);
+ }
+ //else
+ //{
+ //Ignore because this exception belongs to other component
+ //}
+ }
+ setValid(false);
+ }
+ else
+ {
+ throw new IllegalStateException("other exceptions not handled yet, exception : "+exception);
+ }
+ }
+ }
+ }
+
+ //TODO: Move this method to org.apache.myfaces.shared.util.MessageUtils
+ private static String getLabel(FacesContext facesContext, UIComponent component) {
+ Object label = component.getAttributes().get("label");
+ if(label != null)
+ return label.toString();
+
+ ValueExpression expression = component.getValueExpression("label");
+ if(expression != null)
+ return expression.getExpressionString();
+ //return (String)expression.getValue(facesContext.getELContext());
+
+ //If no label is not specified, use clientId
+ return component.getClientId( facesContext );
+ }
+}
Propchange: myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/fileupload/AbstractHtmlInputFileUpload.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL