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