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