001    package org.apache.myfaces.tobago.webapp;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one or more
005     * contributor license agreements.  See the NOTICE file distributed with
006     * this work for additional information regarding copyright ownership.
007     * The ASF licenses this file to You under the Apache License, Version 2.0
008     * (the "License"); you may not use this file except in compliance with
009     * the License.  You may obtain a copy of the License at
010     *
011     *      http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing, software
014     * distributed under the License is distributed on an "AS IS" BASIS,
015     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016     * See the License for the specific language governing permissions and
017     * limitations under the License.
018     */
019    
020    import org.apache.commons.logging.Log;
021    import org.apache.commons.logging.LogFactory;
022    
023    import javax.servlet.Filter;
024    import javax.servlet.FilterChain;
025    import javax.servlet.FilterConfig;
026    import javax.servlet.ServletException;
027    import javax.servlet.ServletRequest;
028    import javax.servlet.ServletResponse;
029    import javax.servlet.http.HttpServletRequest;
030    import java.io.IOException;
031    import java.io.File;
032    import java.util.Locale;
033    
034    
035    /**
036     * This filter handles multipart request. It must be enabled in the web.xml of your web application.
037     * Usage:
038     * <p/>
039     * <p><blockquote><pre>
040     * &lt;filter&gt;
041     * &lt;filter-name&gt;multipartFormdataFilter&lt;/filter-name&gt;
042     * &lt;filter-class&gt;org.apache.myfaces.tobago.webapp.TobagoMultipartFormdataFilter&lt;/filter-class&gt;
043     * &lt;init-param&gt;
044     * &lt;description&gt;Set the size limit for uploaded files. Default value is 1 MB.
045     * Format: 10 = 10 bytes
046     * 10k = 10 KB
047     * 10m = 10 MB
048     * 1g = 1 GB
049     * &lt;/description&gt;
050     * &lt;param-name&gt;uploadMaxFileSize&lt;/param-name&gt;
051     * &lt;param-value&gt;20m&lt;/param-value&gt;
052     * &lt;/init-param&gt;
053     * &lt;init-param&gt;
054     * &lt;description&gt;Set the upload repository path for uploaded files.
055     * Default value is java.io.tmpdir.&lt;/description&gt;
056     * &lt;param-name&gt;uploadRepositoryPath&lt;/param-name&gt;
057     * &lt;param-value&gt;/tmp&lt;/param-value&gt;
058     * &lt;/init-param&gt;
059     * &lt;/filter&gt;
060     * &lt;filter-mapping&gt;
061     * &lt;filter-name&gt;multipartFormdataFilter&lt;/filter-name&gt;
062     * &lt;url-pattern&gt;/faces/*&lt;/url-pattern&gt;
063     * &lt;/filter-mapping&gt;
064     * </pre></blockquote><p>
065     */
066    public class TobagoMultipartFormdataFilter implements Filter {
067    
068      private static final Log LOG = LogFactory.getLog(TobagoMultipartFormdataFilter.class);
069    
070      private String repositoryPath = System.getProperty("java.io.tmpdir");
071      private long maxSize = TobagoMultipartFormdataRequest.ONE_MB;
072    
073      public void init(FilterConfig filterConfig) throws ServletException {
074        String repositoryPath = filterConfig.getInitParameter("uploadRepositoryPath");
075        if (repositoryPath != null) {
076          File file = new File(repositoryPath);
077          if (!file.exists()) {
078            LOG.error("Given repository Path for " + getClass().getName() + " " + repositoryPath + " doesn't exists");
079          } else if (!file.isDirectory()) {
080            LOG.error("Given repository Path for " + getClass().getName() + " " + repositoryPath + " is not a directory");
081          } else {
082            this.repositoryPath = repositoryPath;
083          }
084        }
085    
086    
087        maxSize = TobagoMultipartFormdataRequest.getMaxSize(filterConfig.getInitParameter("uploadMaxFileSize"));
088        if (LOG.isInfoEnabled()) {
089          LOG.info("Configure uploadRepositryPath for " + getClass().getName() + " to " + this.repositoryPath);
090          LOG.info("Configure uploadMaxFileSize for " + getClass().getName() + " to " + this.maxSize);
091        }
092    
093      }
094    
095      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
096          throws IOException, ServletException {
097        ServletRequest wrapper;
098        if (request instanceof HttpServletRequest) {
099          if (request instanceof TobagoMultipartFormdataRequest) {
100            wrapper = request;
101          } else {
102            String contentType = request.getContentType();
103            if (contentType != null
104                && contentType.toLowerCase(Locale.ENGLISH).startsWith("multipart/form-data")) {
105              if (LOG.isDebugEnabled()) {
106                LOG.debug("Wrapping " + request.getClass().getName()
107                    + " with ContentType=\"" + contentType + "\" "
108                    + "into TobagoMultipartFormdataRequest");
109              }
110              wrapper = new TobagoMultipartFormdataRequest(
111                  (HttpServletRequest) request, repositoryPath, maxSize);
112            } else {
113              wrapper = request;
114            }
115          }
116        } else {
117          LOG.error("Not implemented for non HttpServletRequest");
118          wrapper = request;
119        }
120    
121        chain.doFilter(wrapper, response);
122      }
123    
124      public void destroy() {
125      }
126    
127    }