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