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) throws ServletException {
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.getCurrentCompleteURL(request);
114 PortalUtil.getCurrentURL(request);
115
116 HttpSession session = request.getSession();
117
118 Boolean httpsInitial = (Boolean)session.getAttribute(
119 WebKeys.HTTPS_INITIAL);
120
121 if (httpsInitial == null) {
122 httpsInitial = Boolean.valueOf(request.isSecure());
123
124 session.setAttribute(WebKeys.HTTPS_INITIAL, httpsInitial);
125
126 if (_log.isDebugEnabled()) {
127 _log.debug("Setting httpsInitial to " + httpsInitial);
128 }
129 }
130
131 if (!isFilterEnabled()) {
132 processFilter(
133 VirtualHostFilter.class, request, response, filterChain);
134
135 return;
136 }
137
138 StringBuffer requestURL = request.getRequestURL();
139
140 if (_log.isDebugEnabled()) {
141 _log.debug("Received " + requestURL);
142 }
143
144 if (!isValidRequestURL(requestURL)) {
145 processFilter(
146 VirtualHostFilter.class, request, response, filterChain);
147
148 return;
149 }
150
151 String contextPath = PortalUtil.getPathContext();
152
153 String friendlyURL = request.getRequestURI();
154
155 if ((Validator.isNotNull(contextPath)) &&
156 (friendlyURL.indexOf(contextPath) != -1)) {
157
158 friendlyURL = friendlyURL.substring(contextPath.length());
159 }
160
161 friendlyURL = StringUtil.replace(
162 friendlyURL, StringPool.DOUBLE_SLASH, StringPool.SLASH);
163
164 String i18nLanguageId = null;
165
166 Set<String> languageIds = I18nServlet.getLanguageIds();
167
168 for (String languageId : languageIds) {
169 if (friendlyURL.startsWith(languageId)) {
170 int pos = friendlyURL.indexOf(StringPool.SLASH, 1);
171
172 i18nLanguageId = friendlyURL.substring(0, pos);
173 friendlyURL = friendlyURL.substring(pos);
174
175 break;
176 }
177 }
178
179 if (_log.isDebugEnabled()) {
180 _log.debug("Friendly URL " + friendlyURL);
181 }
182
183 if (!friendlyURL.equals(StringPool.SLASH) &&
184 !isValidFriendlyURL(friendlyURL)) {
185
186 _log.debug("Friendly URL is not valid");
187
188 processFilter(
189 VirtualHostFilter.class, request, response, filterChain);
190
191 return;
192 }
193
194 LayoutSet layoutSet = (LayoutSet)servletRequest.getAttribute(
195 WebKeys.VIRTUAL_HOST_LAYOUT_SET);
196
197 if (_log.isDebugEnabled()) {
198 _log.debug("Layout set " + layoutSet);
199 }
200
201 if (layoutSet != null) {
202 try {
203 LastPath lastPath = new LastPath(
204 contextPath, friendlyURL, servletRequest.getParameterMap());
205
206 servletRequest.setAttribute(WebKeys.LAST_PATH, lastPath);
207
208 StringBuilder prefix = new StringBuilder();
209
210 Group group = GroupLocalServiceUtil.getGroup(
211 layoutSet.getGroupId());
212
213 if (layoutSet.isPrivateLayout()) {
214 if (group.isUser()) {
215 prefix.append(_PRIVATE_USER_SERVLET_MAPPING);
216 }
217 else {
218 prefix.append(_PRIVATE_GROUP_SERVLET_MAPPING);
219 }
220 }
221 else {
222 prefix.append(_PUBLIC_GROUP_SERVLET_MAPPING);
223 }
224
225 prefix.append(group.getFriendlyURL());
226
227 StringBuilder forwardURL = new StringBuilder();
228
229 if (i18nLanguageId != null) {
230 forwardURL.append(i18nLanguageId);
231 }
232
233 if (friendlyURL.startsWith(
234 PropsValues.WIDGET_SERVLET_MAPPING)) {
235
236 forwardURL.append(PropsValues.WIDGET_SERVLET_MAPPING);
237
238 friendlyURL = StringUtil.replaceFirst(
239 friendlyURL, PropsValues.WIDGET_SERVLET_MAPPING,
240 StringPool.BLANK);
241 }
242
243 long plid = PortalUtil.getPlidFromFriendlyURL(
244 companyId, friendlyURL);
245
246 if (plid <= 0) {
247 forwardURL.append(prefix);
248 }
249
250 forwardURL.append(friendlyURL);
251
252 if (_log.isDebugEnabled()) {
253 _log.debug("Forward to " + forwardURL);
254 }
255
256 RequestDispatcher requestDispatcher =
257 _servletContext.getRequestDispatcher(forwardURL.toString());
258
259 requestDispatcher.forward(servletRequest, response);
260
261 return;
262 }
263 catch (Exception e) {
264 _log.error(e, e);
265 }
266 }
267
268 processFilter(VirtualHostFilter.class, request, response, filterChain);
269 }
270
271 protected boolean isValidFriendlyURL(String friendlyURL) {
272 friendlyURL = friendlyURL.toLowerCase();
273
274 if (PortalInstances.isVirtualHostsIgnorePath(friendlyURL) ||
275 friendlyURL.startsWith(
276 PortalUtil.getPathFriendlyURLPrivateGroup() +
277 StringPool.SLASH) ||
278 friendlyURL.startsWith(
279 PortalUtil.getPathFriendlyURLPublic() + StringPool.SLASH) ||
280 friendlyURL.startsWith(
281 PortalUtil.getPathFriendlyURLPrivateUser() +
282 StringPool.SLASH) ||
283 friendlyURL.startsWith(_PATH_C) ||
284 friendlyURL.startsWith(_PATH_DELEGATE) ||
285 friendlyURL.startsWith(_PATH_HTML) ||
286 friendlyURL.startsWith(_PATH_IMAGE) ||
287 friendlyURL.startsWith(_PATH_LANGUAGE) ||
288 friendlyURL.startsWith(_PATH_SITEMAP_XML) ||
289 friendlyURL.startsWith(_PATH_SOFTWARE_CATALOG) ||
290 friendlyURL.startsWith(_PATH_WAP) ||
291 friendlyURL.startsWith(_PATH_WSRP)) {
292
293 return false;
294 }
295
296 int code = LayoutImpl.validateFriendlyURL(friendlyURL);
297
298 if ((code > -1) &&
299 (code != LayoutFriendlyURLException.ENDS_WITH_SLASH)) {
300
301 return false;
302 }
303
304 return true;
305 }
306
307 protected boolean isValidRequestURL(StringBuffer requestURL) {
308 if (requestURL == null) {
309 return false;
310 }
311
312 String url = requestURL.toString();
313
314 if (url.endsWith(_EXT_C) || url.endsWith(_EXT_CSS) ||
315 url.endsWith(_EXT_GIF) || url.endsWith(_EXT_IMAGE_COMPANY_LOGO) ||
316 url.endsWith(_EXT_ICO) || url.endsWith(_EXT_JS) ||
317 url.endsWith(_EXT_JPEG) || url.endsWith(_EXT_JSP) ||
318 url.endsWith(_EXT_PORTAL_LAYOUT) ||
319 url.endsWith(_EXT_PORTAL_LOGIN) ||
320 url.endsWith(_EXT_PORTAL_LOGOUT) || url.endsWith(_EXT_PNG)) {
321
322 return false;
323 }
324 else {
325 return true;
326 }
327 }
328
329 protected void processFilter(
330 HttpServletRequest request, HttpServletResponse response,
331 FilterChain filterChain) {
332 }
333
334 private static Log _log = LogFactoryUtil.getLog(VirtualHostFilter.class);
335
336 private static String _EXT_C = "/c";
337
338 private static String _EXT_CSS = ".css";
339
340 private static String _EXT_GIF = ".gif";
341
342 private static String _EXT_IMAGE_COMPANY_LOGO = "/image/company_logo";
343
344 private static String _EXT_ICO = ".ico";
345
346 private static String _EXT_JS = ".js";
347
348 private static String _EXT_JPEG = ".jpeg";
349
350 private static String _EXT_JSP = ".jsp";
351
352 private static String _EXT_PORTAL_LAYOUT = "/portal/layout";
353
354 private static String _EXT_PORTAL_LOGIN = "/portal/login";
355
356 private static String _EXT_PORTAL_LOGOUT = "/portal/logout";
357
358 private static String _EXT_PNG = ".png";
359
360 private static String _PATH_C = "/c/";
361
362 private static String _PATH_DELEGATE = "/delegate/";
363
364 private static String _PATH_HTML = "/html/";
365
366 private static String _PATH_IMAGE = "/image/";
367
368 private static String _PATH_LANGUAGE = "/language/";
369
370 private static String _PATH_SITEMAP_XML = "/sitemap.xml";
371
372 private static String _PATH_SOFTWARE_CATALOG = "/software_catalog/";
373
374 private static String _PATH_WAP = "/wap/";
375
376 private static String _PATH_WSRP = "/wsrp/";
377
378 private static String _PRIVATE_GROUP_SERVLET_MAPPING =
379 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
380
381 private static String _PRIVATE_USER_SERVLET_MAPPING =
382 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
383
384 private static String _PUBLIC_GROUP_SERVLET_MAPPING =
385 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
386
387 private ServletContext _servletContext;
388
389 }