1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.myfaces.webapp.filter;
20
21 import org.apache.commons.fileupload.FileUpload;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.myfaces.renderkit.html.util.AddResource;
25 import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
26
27 import javax.servlet;
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.HttpServletResponse;
30 import java.io.IOException;
31
32 /**
33 * This filters is mandatory for the use of many components.
34 * It handles the Multipart requests (for file upload)
35 * It's used by the components that need javascript libraries
36 *
37 * @author Sylvain Vieujot (latest modification by $Author: grantsmith $)
38 * @version $Revision: 472792 $ $Date: 2006-11-09 07:34:47 +0100 (Do, 09 Nov 2006) $
39 */
40 public class ExtensionsFilter implements Filter {
41
42 private Log log = LogFactory.getLog(ExtensionsFilter.class);
43
44 private int _uploadMaxFileSize = 100 * 1024 * 1024; // 10 MB
45
46 private int _uploadThresholdSize = 1 * 1024 * 1024; // 1 MB
47
48 private String _uploadRepositoryPath = null; //standard temp directory
49
50 private ServletContext _servletContext;
51
52 public static final String DOFILTER_CALLED = "org.apache.myfaces.component.html.util.ExtensionFilter.doFilterCalled";
53
54 /**
55 * Init method for this filter
56 */
57 public void init(FilterConfig filterConfig) {
58
59 String param = filterConfig.getInitParameter("uploadMaxFileSize");
60
61 _uploadMaxFileSize = resolveSize(param, _uploadMaxFileSize);
62
63 param = filterConfig.getInitParameter("uploadThresholdSize");
64
65 _uploadThresholdSize = resolveSize(param, _uploadThresholdSize);
66
67 _uploadRepositoryPath = filterConfig.getInitParameter("uploadRepositoryPath");
68
69 _servletContext = filterConfig.getServletContext();
70 }
71
72 private int resolveSize(String param, int defaultValue) {
73 int numberParam = defaultValue;
74
75 if (param != null) {
76 param = param.toLowerCase();
77 int factor = 1;
78 String number = param;
79
80 if (param.endsWith("g")) {
81 factor = 1024 * 1024 * 1024;
82 number = param.substring(0, param.length() - 1);
83 } else if (param.endsWith("m")) {
84 factor = 1024 * 1024;
85 number = param.substring(0, param.length() - 1);
86 } else if (param.endsWith("k")) {
87 factor = 1024;
88 number = param.substring(0, param.length() - 1);
89 }
90
91 numberParam = Integer.parseInt(number) * factor;
92 }
93 return numberParam;
94 }
95
96 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
97
98 if(request.getAttribute(DOFILTER_CALLED)!=null)
99 {
100 chain.doFilter(request, response);
101 return;
102 }
103
104 request.setAttribute(DOFILTER_CALLED,"true");
105
106 if (!(response instanceof HttpServletResponse)) {
107 chain.doFilter(request, response);
108 return;
109 }
110
111 HttpServletResponse httpResponse = (HttpServletResponse) response;
112 HttpServletRequest httpRequest = (HttpServletRequest) request;
113
114 HttpServletRequest extendedRequest = httpRequest;
115
116 // For multipart/form-data requests
117 if (FileUpload.isMultipartContent(httpRequest)) {
118 extendedRequest = new MultipartRequestWrapper(httpRequest, _uploadMaxFileSize, _uploadThresholdSize, _uploadRepositoryPath);
119 }
120
121 // Serve resources
122 AddResource addResource;
123
124 try
125 {
126 addResource=AddResourceFactory.getInstance(httpRequest);
127 if( addResource.isResourceUri(_servletContext, httpRequest ) ){
128 addResource.serveResource(_servletContext, httpRequest, httpResponse);
129 return;
130 }
131 }
132 catch(Throwable th)
133 {
134 log.error("Exception wile retrieving addResource",th);
135 throw new ServletException(th);
136 }
137
138 try
139 {
140 addResource.responseStarted();
141
142 if (addResource.requiresBuffer())
143 {
144 ExtensionsResponseWrapper extendedResponse = new ExtensionsResponseWrapper((HttpServletResponse) response);
145
146 // Standard request
147 chain.doFilter(extendedRequest, extendedResponse);
148
149 extendedResponse.finishResponse();
150
151 // write the javascript stuff for myfaces and headerInfo, if needed
152 HttpServletResponse servletResponse = (HttpServletResponse)response;
153
154 // only parse HTML responses
155 if (extendedResponse.getContentType() != null && isValidContentType(extendedResponse.getContentType()))
156 {
157 addResource.parseResponse(extendedRequest, extendedResponse.toString(),
158 servletResponse);
159
160 addResource.writeMyFacesJavascriptBeforeBodyEnd(extendedRequest,
161 servletResponse);
162
163 if( ! addResource.hasHeaderBeginInfos() ){
164 // writes the response if no header info is needed
165 addResource.writeResponse(extendedRequest, servletResponse);
166 return;
167 }
168
169 // Some headerInfo has to be added
170 addResource.writeWithFullHeader(extendedRequest, servletResponse);
171
172 // writes the response
173 addResource.writeResponse(extendedRequest, servletResponse);
174 }
175 else
176 {
177
178 byte[] responseArray = extendedResponse.getBytes();
179
180 if(responseArray.length > 0)
181 {
182 // When not filtering due to not valid content-type, deliver the byte-array instead of a charset-converted string.
183 // Otherwise a binary stream gets corrupted.
184 servletResponse.getOutputStream().write(responseArray);
185 }
186 }
187 }
188 else
189 {
190 chain.doFilter(extendedRequest, response);
191 }
192 }
193 finally
194 {
195 addResource.responseFinished();
196 }
197 }
198
199 public boolean isValidContentType(String contentType)
200 {
201 return contentType.startsWith("text/html") ||
202 contentType.startsWith("text/xml") ||
203 contentType.startsWith("application/xhtml+xml") ||
204 contentType.startsWith("application/xml");
205 }
206
207 /**
208 * Destroy method for this filter
209 */
210 public void destroy() {
211 // NoOp
212 }
213
214
215 }