1
14
15 package com.liferay.portal.servlet.filters.virtualhost;
16
17 import com.liferay.portal.LayoutFriendlyURLException;
18 import com.liferay.portal.kernel.log.Log;
19 import com.liferay.portal.kernel.log.LogFactoryUtil;
20 import com.liferay.portal.kernel.struts.LastPath;
21 import com.liferay.portal.kernel.util.StringBundler;
22 import com.liferay.portal.kernel.util.StringPool;
23 import com.liferay.portal.kernel.util.StringUtil;
24 import com.liferay.portal.kernel.util.Validator;
25 import com.liferay.portal.model.Group;
26 import com.liferay.portal.model.LayoutSet;
27 import com.liferay.portal.model.impl.LayoutImpl;
28 import com.liferay.portal.service.GroupLocalServiceUtil;
29 import com.liferay.portal.servlet.AbsoluteRedirectsResponse;
30 import com.liferay.portal.servlet.I18nServlet;
31 import com.liferay.portal.servlet.filters.BasePortalFilter;
32 import com.liferay.portal.util.PortalInstances;
33 import com.liferay.portal.util.PortalUtil;
34 import com.liferay.portal.util.PropsValues;
35 import com.liferay.portal.util.WebKeys;
36
37 import java.util.Set;
38
39 import javax.servlet.FilterChain;
40 import javax.servlet.FilterConfig;
41 import javax.servlet.RequestDispatcher;
42 import javax.servlet.ServletContext;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.servlet.http.HttpServletResponse;
45 import javax.servlet.http.HttpSession;
46
47
63 public class VirtualHostFilter extends BasePortalFilter {
64
65 public void init(FilterConfig filterConfig) {
66 super.init(filterConfig);
67
68 _servletContext = filterConfig.getServletContext();
69 }
70
71 protected boolean isValidFriendlyURL(String friendlyURL) {
72 friendlyURL = friendlyURL.toLowerCase();
73
74 if (PortalInstances.isVirtualHostsIgnorePath(friendlyURL) ||
75 friendlyURL.startsWith(
76 PortalUtil.getPathFriendlyURLPrivateGroup() +
77 StringPool.SLASH) ||
78 friendlyURL.startsWith(
79 PortalUtil.getPathFriendlyURLPublic() + StringPool.SLASH) ||
80 friendlyURL.startsWith(
81 PortalUtil.getPathFriendlyURLPrivateUser() +
82 StringPool.SLASH) ||
83 friendlyURL.startsWith(_PATH_C) ||
84 friendlyURL.startsWith(_PATH_COMBO) ||
85 friendlyURL.startsWith(_PATH_DELEGATE) ||
86 friendlyURL.startsWith(_PATH_DISPLAY_CHART) ||
87 friendlyURL.startsWith(_PATH_DOCUMENTS) ||
88 friendlyURL.startsWith(_PATH_DTD) ||
89 friendlyURL.startsWith(_PATH_FACEBOOK) ||
90 friendlyURL.startsWith(_PATH_GOOGLE_GADGET) ||
91 friendlyURL.startsWith(_PATH_HTML) ||
92 friendlyURL.startsWith(_PATH_IMAGE) ||
93 friendlyURL.startsWith(_PATH_LANGUAGE) ||
94 friendlyURL.startsWith(_PATH_NETVIBES) ||
95 friendlyURL.startsWith(_PATH_PBHS) ||
96 friendlyURL.startsWith(_PATH_POLLER) ||
97 friendlyURL.startsWith(_PATH_SHAREPOINT) ||
98 friendlyURL.startsWith(_PATH_SITEMAP_XML) ||
99 friendlyURL.startsWith(_PATH_SOFTWARE_CATALOG) ||
100 friendlyURL.startsWith(_PATH_VTI) ||
101 friendlyURL.startsWith(_PATH_WAP) ||
102 friendlyURL.startsWith(_PATH_WIDGET) ||
103 friendlyURL.startsWith(_PATH_XMLRPC)) {
104
105 return false;
106 }
107
108 int code = LayoutImpl.validateFriendlyURL(friendlyURL);
109
110 if ((code > -1) &&
111 (code != LayoutFriendlyURLException.ENDS_WITH_SLASH)) {
112
113 return false;
114 }
115
116 return true;
117 }
118
119 protected boolean isValidRequestURL(StringBuffer requestURL) {
120 if (requestURL == null) {
121 return false;
122 }
123
124 String url = requestURL.toString();
125
126 for (String extension : PropsValues.VIRTUAL_HOSTS_IGNORE_EXTENSIONS) {
127 if (url.endsWith(extension)) {
128 return false;
129 }
130 }
131
132 return true;
133 }
134
135 protected void processFilter(
136 HttpServletRequest request, HttpServletResponse response,
137 FilterChain filterChain)
138 throws Exception {
139
140 request.setCharacterEncoding(StringPool.UTF8);
141
143
145 response = new AbsoluteRedirectsResponse(request, response);
146
147
150 long companyId = PortalInstances.getCompanyId(request);
151
152 if (_log.isDebugEnabled()) {
153 _log.debug("Company id " + companyId);
154 }
155
156 PortalUtil.getCurrentCompleteURL(request);
157 PortalUtil.getCurrentURL(request);
158
159 HttpSession session = request.getSession();
160
161 Boolean httpsInitial = (Boolean)session.getAttribute(
162 WebKeys.HTTPS_INITIAL);
163
164 if (httpsInitial == null) {
165 httpsInitial = Boolean.valueOf(request.isSecure());
166
167 session.setAttribute(WebKeys.HTTPS_INITIAL, httpsInitial);
168
169 if (_log.isDebugEnabled()) {
170 _log.debug("Setting httpsInitial to " + httpsInitial);
171 }
172 }
173
174 if (!isFilterEnabled()) {
175 processFilter(
176 VirtualHostFilter.class, request, response, filterChain);
177
178 return;
179 }
180
181 StringBuffer requestURL = request.getRequestURL();
182
183 if (_log.isDebugEnabled()) {
184 _log.debug("Received " + requestURL);
185 }
186
187 if (!isValidRequestURL(requestURL)) {
188 processFilter(
189 VirtualHostFilter.class, request, response, filterChain);
190
191 return;
192 }
193
194 String contextPath = PortalUtil.getPathContext();
195
196 String friendlyURL = request.getRequestURI();
197
198 if ((Validator.isNotNull(contextPath)) &&
199 (friendlyURL.indexOf(contextPath) != -1)) {
200
201 friendlyURL = friendlyURL.substring(contextPath.length());
202 }
203
204 friendlyURL = StringUtil.replace(
205 friendlyURL, StringPool.DOUBLE_SLASH, StringPool.SLASH);
206
207 String i18nLanguageId = null;
208
209 Set<String> languageIds = I18nServlet.getLanguageIds();
210
211 for (String languageId : languageIds) {
212 if (friendlyURL.startsWith(languageId)) {
213 int pos = friendlyURL.indexOf(StringPool.SLASH, 1);
214
215 if (((pos != -1) && (pos != languageId.length())) ||
216 ((pos == -1) && !friendlyURL.equals(languageId))) {
217
218 continue;
219 }
220
221 if (pos == -1) {
222 i18nLanguageId = friendlyURL;
223 friendlyURL = StringPool.SLASH;
224 }
225 else {
226 i18nLanguageId = friendlyURL.substring(0, pos);
227 friendlyURL = friendlyURL.substring(pos);
228 }
229
230 break;
231 }
232 }
233
234 if (_log.isDebugEnabled()) {
235 _log.debug("Friendly URL " + friendlyURL);
236 }
237
238 if (!friendlyURL.equals(StringPool.SLASH) &&
239 !isValidFriendlyURL(friendlyURL)) {
240
241 _log.debug("Friendly URL is not valid");
242
243 processFilter(
244 VirtualHostFilter.class, request, response, filterChain);
245
246 return;
247 }
248
249 LayoutSet layoutSet = (LayoutSet)request.getAttribute(
250 WebKeys.VIRTUAL_HOST_LAYOUT_SET);
251
252 if (_log.isDebugEnabled()) {
253 _log.debug("Layout set " + layoutSet);
254 }
255
256 if (layoutSet != null) {
257 try {
258 LastPath lastPath = new LastPath(
259 contextPath, friendlyURL, request.getParameterMap());
260
261 request.setAttribute(WebKeys.LAST_PATH, lastPath);
262
263 StringBundler prefix = new StringBundler(2);
264
265 Group group = GroupLocalServiceUtil.getGroup(
266 layoutSet.getGroupId());
267
268 if (layoutSet.isPrivateLayout()) {
269 if (group.isUser()) {
270 prefix.append(_PRIVATE_USER_SERVLET_MAPPING);
271 }
272 else {
273 prefix.append(_PRIVATE_GROUP_SERVLET_MAPPING);
274 }
275 }
276 else {
277 prefix.append(_PUBLIC_GROUP_SERVLET_MAPPING);
278 }
279
280 prefix.append(group.getFriendlyURL());
281
282 StringBundler forwardURL = new StringBundler(6);
283
284 if (i18nLanguageId != null) {
285 forwardURL.append(i18nLanguageId);
286 }
287
288 if (friendlyURL.startsWith(
289 PropsValues.WIDGET_SERVLET_MAPPING)) {
290
291 forwardURL.append(PropsValues.WIDGET_SERVLET_MAPPING);
292
293 friendlyURL = StringUtil.replaceFirst(
294 friendlyURL, PropsValues.WIDGET_SERVLET_MAPPING,
295 StringPool.BLANK);
296 }
297
298 long plid = PortalUtil.getPlidFromFriendlyURL(
299 companyId, friendlyURL);
300
301 if (plid <= 0) {
302 forwardURL.append(prefix);
303 }
304
305 forwardURL.append(friendlyURL);
306
307 if (_log.isDebugEnabled()) {
308 _log.debug("Forward to " + forwardURL);
309 }
310
311 RequestDispatcher requestDispatcher =
312 _servletContext.getRequestDispatcher(forwardURL.toString());
313
314 requestDispatcher.forward(request, response);
315
316 return;
317 }
318 catch (Exception e) {
319 _log.error(e, e);
320 }
321 }
322
323 processFilter(VirtualHostFilter.class, request, response, filterChain);
324 }
325
326 private static final String _PATH_C = "/c/";
327
328 private static final String _PATH_COMBO = "/combo/";
329
330 private static final String _PATH_DELEGATE = "/delegate/";
331
332 private static final String _PATH_DISPLAY_CHART = "/display_chart";
333
334 private static final String _PATH_DOCUMENTS = "/documents/";
335
336 private static final String _PATH_DTD = "/dtd/";
337
338 private static final String _PATH_FACEBOOK = "/facebook/";
339
340 private static final String _PATH_GOOGLE_GADGET = "/google_gadget/";
341
342 private static final String _PATH_HTML = "/html/";
343
344 private static final String _PATH_IMAGE = "/image/";
345
346 private static final String _PATH_LANGUAGE = "/language/";
347
348 private static final String _PATH_NETVIBES = "/netvibes/";
349
350 private static final String _PATH_PBHS = "/pbhs/";
351
352 private static final String _PATH_POLLER = "/poller/";
353
354 private static final String _PATH_SHAREPOINT = "/sharepoint/";
355
356 private static final String _PATH_SITEMAP_XML = "/sitemap.xml";
357
358 private static final String _PATH_SOFTWARE_CATALOG = "/software_catalog";
359
360 private static final String _PATH_VTI = "/_vti_";
361
362 private static final String _PATH_WAP = "/wap/";
363
364 private static final String _PATH_WIDGET = "/widget/";
365
366 private static final String _PATH_XMLRPC = "/xmlrpc/";
367
368 private static final String _PRIVATE_GROUP_SERVLET_MAPPING =
369 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
370
371 private static final String _PRIVATE_USER_SERVLET_MAPPING =
372 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
373
374 private static final String _PUBLIC_GROUP_SERVLET_MAPPING =
375 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
376
377 private static Log _log = LogFactoryUtil.getLog(VirtualHostFilter.class);
378
379 private ServletContext _servletContext;
380
381 }