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.io.IOException;
45
46 import java.util.Set;
47
48 import javax.servlet.FilterChain;
49 import javax.servlet.FilterConfig;
50 import javax.servlet.RequestDispatcher;
51 import javax.servlet.ServletContext;
52 import javax.servlet.ServletException;
53 import javax.servlet.ServletRequest;
54 import javax.servlet.ServletResponse;
55 import javax.servlet.http.HttpServletRequest;
56 import javax.servlet.http.HttpServletResponse;
57 import javax.servlet.http.HttpSession;
58
59
75 public class VirtualHostFilter extends BasePortalFilter {
76
77 public void init(FilterConfig filterConfig) {
78 super.init(filterConfig);
79
80 _servletContext = filterConfig.getServletContext();
81 }
82
83 public void doFilter(
84 ServletRequest servletRequest, ServletResponse servletResponse,
85 FilterChain filterChain)
86 throws IOException, ServletException {
87
88 if (_log.isDebugEnabled()) {
89 if (isFilterEnabled()) {
90 _log.debug(VirtualHostFilter.class + " is enabled");
91 }
92 else {
93 _log.debug(VirtualHostFilter.class + " is disabled");
94 }
95 }
96
97 HttpServletRequest request = (HttpServletRequest)servletRequest;
98 HttpServletResponse response = (HttpServletResponse)servletResponse;
99
100 request.setCharacterEncoding(StringPool.UTF8);
101
103
105 response = new AbsoluteRedirectsResponse(request, response);
106
107
110 long companyId = PortalInstances.getCompanyId(request);
111
112 if (_log.isDebugEnabled()) {
113 _log.debug("Company id " + companyId);
114 }
115
116 PortalUtil.getCurrentURL(request);
117
118 HttpSession session = request.getSession();
119
120 Boolean httpsInitial = (Boolean)session.getAttribute(
121 WebKeys.HTTPS_INITIAL);
122
123 if (httpsInitial == null) {
124 httpsInitial = Boolean.valueOf(request.isSecure());
125
126 session.setAttribute(WebKeys.HTTPS_INITIAL, httpsInitial);
127
128 if (_log.isDebugEnabled()) {
129 _log.debug("Setting httpsInitial to " + httpsInitial);
130 }
131 }
132
133 if (!isFilterEnabled()) {
134 processFilter(
135 VirtualHostFilter.class, request, response, filterChain);
136
137 return;
138 }
139
140 StringBuffer requestURL = request.getRequestURL();
141
142 if (_log.isDebugEnabled()) {
143 _log.debug("Received " + requestURL);
144 }
145
146 if (!isValidRequestURL(requestURL)) {
147 processFilter(
148 VirtualHostFilter.class, request, response, filterChain);
149
150 return;
151 }
152
153 String contextPath = PortalUtil.getPathContext();
154
155 String friendlyURL = request.getRequestURI();
156
157 if ((Validator.isNotNull(contextPath)) &&
158 (friendlyURL.indexOf(contextPath) != -1)) {
159
160 friendlyURL = friendlyURL.substring(contextPath.length());
161 }
162
163 friendlyURL = StringUtil.replace(
164 friendlyURL, StringPool.DOUBLE_SLASH, StringPool.SLASH);
165
166 String i18nLanguageId = null;
167
168 Set<String> languageIds = I18nServlet.getLanguageIds();
169
170 for (String languageId : languageIds) {
171 if (friendlyURL.startsWith(languageId)) {
172 int pos = friendlyURL.indexOf(StringPool.SLASH, 1);
173
174 i18nLanguageId = friendlyURL.substring(0, pos);
175 friendlyURL = friendlyURL.substring(pos);
176
177 break;
178 }
179 }
180
181 if (_log.isDebugEnabled()) {
182 _log.debug("Friendly URL " + friendlyURL);
183 }
184
185 if (!isValidFriendlyURL(friendlyURL)) {
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 redirect = new StringBuilder();
228
229 if (i18nLanguageId != null) {
230 redirect.append(i18nLanguageId);
231 }
232
233 if (friendlyURL.startsWith(
234 PropsValues.WIDGET_SERVLET_MAPPING)) {
235
236 redirect.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 redirect.append(prefix);
248 }
249
250 redirect.append(friendlyURL);
251
252 String query = request.getQueryString();
253
254 if (query != null) {
255 redirect.append(StringPool.QUESTION);
256 redirect.append(query);
257 }
258
259 if (_log.isDebugEnabled()) {
260 _log.debug("Redirect to " + redirect);
261 }
262
263 RequestDispatcher requestDispatcher =
264 _servletContext.getRequestDispatcher(redirect.toString());
265
266 requestDispatcher.forward(servletRequest, response);
267
268 return;
269 }
270 catch (Exception e) {
271 _log.error(e, e);
272 }
273 }
274
275 processFilter(VirtualHostFilter.class, request, response, filterChain);
276 }
277
278 protected boolean isValidFriendlyURL(String friendlyURL) {
279 friendlyURL = friendlyURL.toLowerCase();
280
281 if (PortalInstances.isVirtualHostsIgnorePath(friendlyURL) ||
282 friendlyURL.startsWith(
283 PortalUtil.getPathFriendlyURLPrivateGroup() +
284 StringPool.SLASH) ||
285 friendlyURL.startsWith(
286 PortalUtil.getPathFriendlyURLPublic() + StringPool.SLASH) ||
287 friendlyURL.startsWith(
288 PortalUtil.getPathFriendlyURLPrivateUser() +
289 StringPool.SLASH) ||
290 friendlyURL.startsWith(_PATH_C) ||
291 friendlyURL.startsWith(_PATH_DELEGATE) ||
292 friendlyURL.startsWith(_PATH_HTML) ||
293 friendlyURL.startsWith(_PATH_IMAGE) ||
294 friendlyURL.startsWith(_PATH_LANGUAGE) ||
295 friendlyURL.startsWith(_PATH_SITEMAP_XML) ||
296 friendlyURL.startsWith(_PATH_SOFTWARE_CATALOG) ||
297 friendlyURL.startsWith(_PATH_WAP) ||
298 friendlyURL.startsWith(_PATH_WSRP)) {
299
300 return false;
301 }
302
303 int code = LayoutImpl.validateFriendlyURL(friendlyURL);
304
305 if ((code > -1) &&
306 (code != LayoutFriendlyURLException.ENDS_WITH_SLASH)) {
307
308 return false;
309 }
310
311 return true;
312 }
313
314 protected boolean isValidRequestURL(StringBuffer requestURL) {
315 if (requestURL == null) {
316 return false;
317 }
318
319 String url = requestURL.toString();
320
321 if (url.endsWith(_EXT_C) || url.endsWith(_EXT_CSS) ||
322 url.endsWith(_EXT_GIF) || url.endsWith(_EXT_IMAGE_COMPANY_LOGO) ||
323 url.endsWith(_EXT_ICO) || url.endsWith(_EXT_JS) ||
324 url.endsWith(_EXT_JPEG) || url.endsWith(_EXT_JSP) ||
325 url.endsWith(_EXT_PORTAL_LAYOUT) ||
326 url.endsWith(_EXT_PORTAL_LOGIN) ||
327 url.endsWith(_EXT_PORTAL_LOGOUT) || url.endsWith(_EXT_PNG)) {
328
329 return false;
330 }
331 else {
332 return true;
333 }
334 }
335
336 protected void processFilter(
337 HttpServletRequest request, HttpServletResponse response,
338 FilterChain filterChain) {
339 }
340
341 private static Log _log = LogFactoryUtil.getLog(VirtualHostFilter.class);
342
343 private static String _EXT_C = "/c";
344
345 private static String _EXT_CSS = ".css";
346
347 private static String _EXT_GIF = ".gif";
348
349 private static String _EXT_IMAGE_COMPANY_LOGO = "/image/company_logo";
350
351 private static String _EXT_ICO = ".ico";
352
353 private static String _EXT_JS = ".js";
354
355 private static String _EXT_JPEG = ".jpeg";
356
357 private static String _EXT_JSP = ".jsp";
358
359 private static String _EXT_PORTAL_LAYOUT = "/portal/layout";
360
361 private static String _EXT_PORTAL_LOGIN = "/portal/login";
362
363 private static String _EXT_PORTAL_LOGOUT = "/portal/logout";
364
365 private static String _EXT_PNG = ".png";
366
367 private static String _PATH_C = "/c/";
368
369 private static String _PATH_DELEGATE = "/delegate/";
370
371 private static String _PATH_HTML = "/html/";
372
373 private static String _PATH_IMAGE = "/image/";
374
375 private static String _PATH_LANGUAGE = "/language/";
376
377 private static String _PATH_SITEMAP_XML = "/sitemap.xml";
378
379 private static String _PATH_SOFTWARE_CATALOG = "/software_catalog/";
380
381 private static String _PATH_WAP = "/wap/";
382
383 private static String _PATH_WSRP = "/wsrp/";
384
385 private static String _PRIVATE_GROUP_SERVLET_MAPPING =
386 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
387
388 private static String _PRIVATE_USER_SERVLET_MAPPING =
389 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
390
391 private static String _PUBLIC_GROUP_SERVLET_MAPPING =
392 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
393
394 private ServletContext _servletContext;
395
396 }