1
22
23 package com.liferay.filters.strip;
24
25 import com.liferay.portal.kernel.util.GetterUtil;
26 import com.liferay.portal.kernel.util.JavaConstants;
27 import com.liferay.portal.kernel.util.ParamUtil;
28 import com.liferay.util.Http;
29 import com.liferay.util.SystemProperties;
30 import com.liferay.util.servlet.ServletResponseUtil;
31
32 import java.io.IOException;
33
34 import javax.servlet.Filter;
35 import javax.servlet.FilterChain;
36 import javax.servlet.FilterConfig;
37 import javax.servlet.ServletException;
38 import javax.servlet.ServletRequest;
39 import javax.servlet.ServletResponse;
40 import javax.servlet.http.HttpServletRequest;
41 import javax.servlet.http.HttpServletResponse;
42
43 import org.apache.commons.logging.Log;
44 import org.apache.commons.logging.LogFactory;
45
46
52 public class StripFilter implements Filter {
53
54 public static final boolean USE_FILTER = GetterUtil.getBoolean(
55 SystemProperties.get(StripFilter.class.getName()), true);
56
57 public static final String ENCODING = GetterUtil.getString(
58 SystemProperties.get("file.encoding"), "UTF-8");
59
60 public void init(FilterConfig config) {
61 }
62
63 public void doFilter(
64 ServletRequest req, ServletResponse res, FilterChain chain)
65 throws IOException, ServletException {
66
67 if (_log.isDebugEnabled()) {
68 if (USE_FILTER) {
69 _log.debug("Strip is enabled");
70 }
71 else {
72 _log.debug("Strip is disabled");
73 }
74 }
75
76 HttpServletRequest httpReq = (HttpServletRequest)req;
77 HttpServletResponse httpRes = (HttpServletResponse)res;
78
79 String completeURL = Http.getCompleteURL(httpReq);
80
81 if (USE_FILTER && isStrip(httpReq) && !isInclude(httpReq) &&
82 !isAlreadyFiltered(httpReq)) {
83
84 if (_log.isDebugEnabled()) {
85 _log.debug("Stripping " + completeURL);
86 }
87
88 httpReq.setAttribute(_ALREADY_FILTERED, Boolean.TRUE);
89
90 StripResponse stripResponse = new StripResponse(httpRes);
91
92 chain.doFilter(req, stripResponse);
93
94 String contentType = GetterUtil.getString(
95 stripResponse.getContentType());
96
97 byte[] oldByteArray = stripResponse.getData();
98
99 if ((oldByteArray != null) && (oldByteArray.length > 0)) {
100 byte[] newByteArray = new byte[oldByteArray.length];
101 int newByteArrayPos = 0;
102
103 if (_log.isDebugEnabled()) {
104 _log.debug("Stripping content of type " + contentType);
105 }
106
107 if (contentType.toLowerCase().indexOf("text/") != -1) {
108 boolean ignore = false;
109 char prevChar = '\n';
110
111 for (int i = 0; i < oldByteArray.length; i++) {
112 byte b = oldByteArray[i];
113 char c = (char)b;
114
115 if (c == '<') {
116
117
119 if (!ignore) {
120
121
123 if ((i + 4) < oldByteArray.length) {
124 char c1 = (char)oldByteArray[i + 1];
125 char c2 = (char)oldByteArray[i + 2];
126 char c3 = (char)oldByteArray[i + 3];
127 char c4 = (char)oldByteArray[i + 4];
128
129 if (((c1 == 'p') || (c1 == 'P')) &&
130 ((c2 == 'r') || (c2 == 'R')) &&
131 ((c3 == 'e') || (c3 == 'E')) &&
132 ((c4 == '>'))) {
133
134 ignore = true;
135 }
136 }
137
138
140 if (!ignore &&
141 ((i + 9) < oldByteArray.length)) {
142
143 char c1 = (char)oldByteArray[i + 1];
144 char c2 = (char)oldByteArray[i + 2];
145 char c3 = (char)oldByteArray[i + 3];
146 char c4 = (char)oldByteArray[i + 4];
147 char c5 = (char)oldByteArray[i + 5];
148 char c6 = (char)oldByteArray[i + 6];
149 char c7 = (char)oldByteArray[i + 7];
150 char c8 = (char)oldByteArray[i + 8];
151 char c9 = (char)oldByteArray[i + 9];
152
153 if (((c1 == 't') || (c1 == 'T')) &&
154 ((c2 == 'e') || (c2 == 'E')) &&
155 ((c3 == 'x') || (c3 == 'X')) &&
156 ((c4 == 't') || (c4 == 'T')) &&
157 ((c5 == 'a') || (c5 == 'A')) &&
158 ((c6 == 'r') || (c6 == 'R')) &&
159 ((c7 == 'e') || (c7 == 'E')) &&
160 ((c8 == 'a') || (c8 == 'A')) &&
161 ((c9 == ' '))) {
162
163 ignore = true;
164 }
165 }
166 }
167 else if (ignore) {
168
169
171 if ((i + 5) < oldByteArray.length) {
172 char c1 = (char)oldByteArray[i + 1];
173 char c2 = (char)oldByteArray[i + 2];
174 char c3 = (char)oldByteArray[i + 3];
175 char c4 = (char)oldByteArray[i + 4];
176 char c5 = (char)oldByteArray[i + 5];
177
178 if (((c1 == '/')) &&
179 ((c2 == 'p') || (c2 == 'P')) &&
180 ((c3 == 'r') || (c3 == 'R')) &&
181 ((c4 == 'e') || (c4 == 'E')) &&
182 ((c5 == '>'))) {
183
184 ignore = false;
185 }
186 }
187
188
190 if (ignore &&
191 ((i + 10) < oldByteArray.length)) {
192
193 char c1 = (char)oldByteArray[i + 1];
194 char c2 = (char)oldByteArray[i + 2];
195 char c3 = (char)oldByteArray[i + 3];
196 char c4 = (char)oldByteArray[i + 4];
197 char c5 = (char)oldByteArray[i + 5];
198 char c6 = (char)oldByteArray[i + 6];
199 char c7 = (char)oldByteArray[i + 7];
200 char c8 = (char)oldByteArray[i + 8];
201 char c9 = (char)oldByteArray[i + 9];
202 char c10 = (char)oldByteArray[i + 10];
203
204 if (((c1 == '/')) &&
205 ((c2 == 't') || (c2 == 'T')) &&
206 ((c3 == 'e') || (c3 == 'E')) &&
207 ((c4 == 'x') || (c4 == 'X')) &&
208 ((c5 == 't') || (c5 == 'T')) &&
209 ((c6 == 'a') || (c6 == 'A')) &&
210 ((c7 == 'r') || (c7 == 'R')) &&
211 ((c8 == 'e') || (c8 == 'E')) &&
212 ((c9 == 'a') || (c9 == 'A')) &&
213 ((c10 == '>'))) {
214
215 ignore = false;
216 }
217 }
218 }
219 }
220
221 if ((!ignore) &&
222 ((c == '\n') || (c == '\r') || (c == '\t'))) {
223
224 if ((i + 1) == oldByteArray.length) {
225 }
226
227 if ((prevChar == '\n') || (prevChar == '\r')) {
228 }
229 else {
230 if (c != '\t') {
231 prevChar = c;
232 }
233
234 newByteArray[newByteArrayPos++] = b;
235 }
236 }
237 else {
238 prevChar = c;
239
240 newByteArray[newByteArrayPos++] = b;
241 }
242 }
243 }
244 else {
245 newByteArray = oldByteArray;
246 newByteArrayPos = oldByteArray.length;
247 }
248
249 ServletResponseUtil.write(
250 httpRes, newByteArray, newByteArrayPos);
251 }
252 }
253 else {
254 if (_log.isDebugEnabled()) {
255 _log.debug("Not stripping " + completeURL);
256 }
257
258 chain.doFilter(req, res);
259 }
260 }
261
262 public void destroy() {
263 }
264
265 protected boolean isAlreadyFiltered(HttpServletRequest req) {
266 if (req.getAttribute(_ALREADY_FILTERED) != null) {
267 return true;
268 }
269 else {
270 return false;
271 }
272 }
273
274 protected boolean isInclude(HttpServletRequest req) {
275 String uri = (String)req.getAttribute(
276 JavaConstants.JAVAX_SERVLET_INCLUDE_REQUEST_URI);
277
278 if (uri == null) {
279 return false;
280 }
281 else {
282 return true;
283 }
284 }
285
286 protected boolean isStrip(HttpServletRequest req) {
287 if (!ParamUtil.get(req, _STRIP, true)) {
288 return false;
289 }
290 else {
291
292
297 boolean action = ParamUtil.getBoolean(req, "p_p_action");
298 String windowState = ParamUtil.getString(req, "p_p_state");
299
300 if (action && windowState.equals("exclusive")) {
301 return false;
302 }
303 else {
304 return true;
305 }
306 }
307 }
308
309 private static final String _ALREADY_FILTERED =
310 StripFilter.class.getName() + "_ALREADY_FILTERED";
311
312 private static final String _STRIP = "strip";
313
314 private static Log _log = LogFactory.getLog(StripFilter.class);
315
316 }