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