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 javax.servlet.http.HttpServletResponse;
031    import java.io.IOException;
032    import java.io.File;
033    import java.util.Locale;
034    
035    
036    /**
037     * This filter handles multipart request. It must be enabled in the web.xml of your web application.
038     * Usage:
039     * <p/>
040     * <p><blockquote><pre>
041     * &lt;filter&gt;
042     * &lt;filter-name&gt;multipartFormdataFilter&lt;/filter-name&gt;
043     * &lt;filter-class&gt;org.apache.myfaces.tobago.webapp.TobagoMultipartFormdataFilter&lt;/filter-class&gt;
044     * &lt;init-param&gt;
045     * &lt;description&gt;Set the size limit for uploaded files. Default value is 1 MB.
046     * Format: 10 = 10 bytes
047     * 10k = 10 KB
048     * 10m = 10 MB
049     * 1g = 1 GB
050     * &lt;/description&gt;
051     * &lt;param-name&gt;uploadMaxFileSize&lt;/param-name&gt;
052     * &lt;param-value&gt;20m&lt;/param-value&gt;
053     * &lt;/init-param&gt;
054     * &lt;init-param&gt;
055     * &lt;description&gt;Set the upload repository path for uploaded files.
056     * Default value is java.io.tmpdir.&lt;/description&gt;
057     * &lt;param-name&gt;uploadRepositoryPath&lt;/param-name&gt;
058     * &lt;param-value&gt;/tmp&lt;/param-value&gt;
059     * &lt;/init-param&gt;
060     * &lt;/filter&gt;
061     * &lt;filter-mapping&gt;
062     * &lt;filter-name&gt;multipartFormdataFilter&lt;/filter-name&gt;
063     * &lt;url-pattern&gt;/faces/*&lt;/url-pattern&gt;
064     * &lt;/filter-mapping&gt;
065     * </pre></blockquote><p>
066     */
067    public class TobagoMultipartFormdataFilter implements Filter {
068    
069      private static final Log LOG = LogFactory.getLog(TobagoMultipartFormdataFilter.class);
070    
071      private String repositoryPath = System.getProperty("java.io.tmpdir");
072      private long maxSize = TobagoMultipartFormdataRequest.ONE_MB;
073    
074      public void init(FilterConfig filterConfig) throws ServletException {
075        String repositoryPath = filterConfig.getInitParameter("uploadRepositoryPath");
076        if (repositoryPath != null) {
077          File file = new File(repositoryPath);
078          if (!file.exists()) {
079            LOG.error("Given repository Path for " + getClass().getName() + " " + repositoryPath + " doesn't exists");
080          } else if (!file.isDirectory()) {
081            LOG.error("Given repository Path for " + getClass().getName() + " " + repositoryPath + " is not a directory");
082          } else {
083            this.repositoryPath = repositoryPath;
084          }
085        }
086    
087        LOG.info("Configure uploadRepositryPath for " + getClass().getName() + " to " + this.repositoryPath);
088    
089        maxSize = TobagoMultipartFormdataRequest.getMaxSize(filterConfig.getInitParameter("uploadMaxFileSize"));
090    
091        LOG.info("Configure uploadMaxFileSize for " + getClass().getName() + " to " + this.maxSize);
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        ServletResponse wrappedResponse;
121        if (response instanceof HttpServletResponse) {
122          wrappedResponse = new TobagoResponse((HttpServletResponse) response);
123        } else {
124          wrappedResponse = response;
125        }
126    
127        chain.doFilter(wrapper, wrappedResponse);
128      }
129    
130      public void destroy() {
131      }
132    
133    }