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     *
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     *
068     *
069     */
070    public class TobagoMultipartFormdataFilter implements Filter {
071    
072      private static final Log LOG = LogFactory.getLog(TobagoMultipartFormdataFilter.class);
073    
074      private String repositoryPath = System.getProperty("java.io.tmpdir");
075      private long maxSize = TobagoMultipartFormdataRequest.ONE_MB;
076    
077      public void init(FilterConfig filterConfig) throws ServletException {
078        String repositoryPath = filterConfig.getInitParameter("uploadRepositoryPath");
079        if (repositoryPath != null) {
080          File file = new File(repositoryPath);
081          if (!file.exists()) {
082            LOG.error("Given repository Path for " + getClass().getName() + " " + repositoryPath + " doesn't exists");
083          } else if (!file.isDirectory()) {
084            LOG.error("Given repository Path for " + getClass().getName() + " " + repositoryPath + " is not a directory");
085          } else {
086            this.repositoryPath = repositoryPath;
087          }
088        }
089    
090        LOG.info("Configure uploadRepositryPath for "+ getClass().getName() + " to "+ this.repositoryPath);
091    
092        maxSize = TobagoMultipartFormdataRequest.getMaxSize(filterConfig.getInitParameter("uploadMaxFileSize"));
093    
094        LOG.info("Configure uploadMaxFileSize for "+ getClass().getName() + " to "+ this.maxSize);
095    
096      }
097    
098      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
099          throws IOException, ServletException {
100        ServletRequest wrapper;
101        if (request instanceof HttpServletRequest) {
102          if (request instanceof TobagoMultipartFormdataRequest) {
103            wrapper = request;
104          } else {
105            String contentType = request.getContentType();
106            if (contentType != null
107                && contentType.toLowerCase(Locale.ENGLISH).startsWith("multipart/form-data")) {
108              if (LOG.isDebugEnabled()) {
109                LOG.debug("Wrapping " + request.getClass().getName()
110                    + " with ContentType=\"" + contentType + "\" "
111                    + "into TobagoMultipartFormdataRequest");
112              }
113              wrapper = new TobagoMultipartFormdataRequest(
114                  (HttpServletRequest) request, repositoryPath, maxSize);
115            } else {
116              wrapper = request;
117            }
118          }
119        } else {
120          LOG.error("Not implemented for non HttpServletRequest");
121          wrapper = request;
122        }
123        ServletResponse wrappedResponse;
124        if (response instanceof HttpServletResponse) {
125          wrappedResponse = new TobagoResponse((HttpServletResponse) response);
126        } else {
127          wrappedResponse = response;
128        }
129    
130        chain.doFilter(wrapper, wrappedResponse);
131      }
132    
133      public void destroy() {
134      }
135    
136    }