/** * Copyright 2011 meltmedia * * Licensed 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.xchain.framework.filter; import javax.servlet.Filter; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.FilterChain; import java.io.File; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.FileUploadException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xchain.framework.servlet.MultipartFormDataServletRequest; /** * @author John Trimble * @author Josh Kennedy */ public class MultipartFormDataFilter implements Filter { public static Logger log = LoggerFactory.getLogger(MultipartFormDataFilter.class); /* maxSize */ public static final String MAX_SIZE_PARAMETER_NAME = "max-size"; /* sizeThreshold */ public static final String SIZE_THRESHOLD_PARAMETER_NAME = "size-threshold"; /* tempDir */ public static final String REPOSITORY_PATH_PARAMETER_NAME = "repository-path"; public static final long DEFAULT_MAX_SIZE = 1000000; public static final int DEFAULT_SIZE_THRESHOLD = 4096; public long maxSize; public int sizeThreashold; public String repositoryPath; public void init(FilterConfig filterConfig) throws javax.servlet.ServletException { // get the systems default temp dir File tempDir = (File)filterConfig.getServletContext().getAttribute("javax.servlet.context.tempdir"); String DEFAULT_REPOSITORY_PATH = (tempDir != null) ? tempDir.getPath() : null; // Read in the max size param value. maxSize = getLongInitParameter( filterConfig, MAX_SIZE_PARAMETER_NAME, DEFAULT_MAX_SIZE ); // Read in the size threshold param value. sizeThreashold = getIntInitParameter( filterConfig, SIZE_THRESHOLD_PARAMETER_NAME, DEFAULT_SIZE_THRESHOLD); // Read in the repository path param value. repositoryPath = getStringInitParameter( filterConfig, REPOSITORY_PATH_PARAMETER_NAME, DEFAULT_REPOSITORY_PATH); if (repositoryPath == null) { throw new ServletException("Unable to determine DEFAULT_REPOSITORY_PATH, please specify a path using the 'repository-path' config param, or ensure that 'javax.servlet.context.tempdir' is set properly."); } log.info("Using max size param of: " + maxSize); log.info("Using threashold size of: " + sizeThreashold); log.info("Using repository path: " + repositoryPath); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws java.io.IOException, javax.servlet.ServletException { if( log.isDebugEnabled() ) { log.debug("Processing multipart form data."); } HttpServletRequest httpServletRequest = (HttpServletRequest)request; HttpServletResponse httpServletResponse = (HttpServletResponse)response; // check the content type. String contentType = httpServletRequest.getHeader("Content-Type"); // if this is a multipart form data request, then wrap the request object. if ( contentType != null && contentType.startsWith("multipart/form-data") && !(request instanceof MultipartFormDataServletRequest) ) { try { request = new MultipartFormDataServletRequest( httpServletRequest, maxSize, sizeThreashold, repositoryPath); } catch( FileUploadException fue ) { if( fue instanceof FileUploadBase.SizeLimitExceededException ) { log.debug("File to large.", fue); httpServletResponse.sendError(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE); return; } // From the apache commons fileupload api: Deprecated. As of commons-fileupload 1.2, the presence of a content-length header is no longer required. // else if( fue instanceof FileUploadBase.UnknownSizeException ) { // httpServletResponse.sendError(HttpServletResponse.SC_LENGTH_REQUIRED); // return; // } else if( fue instanceof FileUploadBase.InvalidContentTypeException ) { log.debug("Invalid content type.", fue); httpServletResponse.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE ); return; } else { if( log.isDebugEnabled() ) log.debug("File upload failed.", fue); throw new ServletException("Could not upload file.", fue); } } } log.debug("Passing to next filter."); // do the chain. filterChain.doFilter(request, response); } public void destroy() { // nothing to do. } protected static long getLongInitParameter( FilterConfig filterConfig, String parameterName, long defaultValue ) throws ServletException { long value = defaultValue; String parameterValue = filterConfig.getInitParameter(parameterName); if( parameterValue != null ) { try { value = Long.parseLong(parameterValue); } catch (NumberFormatException nfe) { throw new ServletException("Could not parse " + parameterName + " parameter for filter " + filterConfig.getFilterName() + ".", nfe); } } return value; } protected static int getIntInitParameter( FilterConfig filterConfig, String parameterName, int defaultValue ) throws ServletException { int value = defaultValue; String parameterValue = filterConfig.getInitParameter(parameterName); if( parameterValue != null ) { try { value = Integer.parseInt(parameterValue); } catch (NumberFormatException nfe) { throw new ServletException("Could not parse " + parameterName + " parameter for filter " + filterConfig.getFilterName() + ".", nfe); } } return value; } protected static String getStringInitParameter( FilterConfig filterConfig, String parameterName, String defaultValue ) throws ServletException { // get the value. String value = defaultValue; String parameterValue = filterConfig.getInitParameter(parameterName); if( parameterValue != null ) { value = parameterValue; } return value; } }