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 processFilter(
187 VirtualHostFilter.class, request, response, filterChain);
188
189 return;
190 }
191
192 LayoutSet layoutSet = (LayoutSet)servletRequest.getAttribute(
193 WebKeys.VIRTUAL_HOST_LAYOUT_SET);
194
195 if (_log.isDebugEnabled()) {
196 _log.debug("Layout set " + layoutSet);
197 }
198
199 if (layoutSet != null) {
200 try {
201 LastPath lastPath = new LastPath(
202 contextPath, friendlyURL, servletRequest.getParameterMap());
203
204 servletRequest.setAttribute(WebKeys.LAST_PATH, lastPath);
205
206 StringBuilder prefix = new StringBuilder();
207
208 Group group = GroupLocalServiceUtil.getGroup(
209 layoutSet.getGroupId());
210
211 if (layoutSet.isPrivateLayout()) {
212 if (group.isUser()) {
213 prefix.append(_PRIVATE_USER_SERVLET_MAPPING);
214 }
215 else {
216 prefix.append(_PRIVATE_GROUP_SERVLET_MAPPING);
217 }
218 }
219 else {
220 prefix.append(_PUBLIC_GROUP_SERVLET_MAPPING);
221 }
222
223 prefix.append(group.getFriendlyURL());
224
225 StringBuilder redirect = new StringBuilder();
226
227 if (i18nLanguageId != null) {
228 redirect.append(i18nLanguageId);
229 }
230
231 if (friendlyURL.startsWith(
232 PropsValues.WIDGET_SERVLET_MAPPING)) {
233
234 redirect.append(PropsValues.WIDGET_SERVLET_MAPPING);
235
236 friendlyURL = StringUtil.replaceFirst(
237 friendlyURL, PropsValues.WIDGET_SERVLET_MAPPING,
238 StringPool.BLANK);
239 }
240
241 long plid = PortalUtil.getPlidFromFriendlyURL(
242 companyId, friendlyURL);
243
244 if (plid <= 0) {
245 redirect.append(prefix);
246 }
247
248 redirect.append(friendlyURL);
249
250 String query = request.getQueryString();
251
252 if (query != null) {
253 redirect.append(StringPool.QUESTION);
254 redirect.append(query);
255 }
256
257 if (_log.isDebugEnabled()) {
258 _log.debug("Redirect to " + redirect);
259 }
260
261 RequestDispatcher requestDispatcher =
262 _servletContext.getRequestDispatcher(redirect.toString());
263
264 requestDispatcher.forward(servletRequest, response);
265
266 return;
267 }
268 catch (Exception e) {
269 _log.error(e, e);
270 }
271 }
272
273 processFilter(VirtualHostFilter.class, request, response, filterChain);
274 }
275
276 protected boolean isValidFriendlyURL(String friendlyURL) {
277 friendlyURL = friendlyURL.toLowerCase();
278
279 if (PortalInstances.isVirtualHostsIgnorePath(friendlyURL) ||
280 friendlyURL.startsWith(
281 PortalUtil.getPathFriendlyURLPrivateGroup() +
282 StringPool.SLASH) ||
283 friendlyURL.startsWith(
284 PortalUtil.getPathFriendlyURLPublic() + StringPool.SLASH) ||
285 friendlyURL.startsWith(
286 PortalUtil.getPathFriendlyURLPrivateUser() +
287 StringPool.SLASH) ||
288 friendlyURL.startsWith(_PATH_C) ||
289 friendlyURL.startsWith(_PATH_DELEGATE) ||
290 friendlyURL.startsWith(_PATH_HTML) ||
291 friendlyURL.startsWith(_PATH_IMAGE) ||
292 friendlyURL.startsWith(_PATH_LANGUAGE) ||
293 friendlyURL.startsWith(_PATH_SITEMAP_XML) ||
294 friendlyURL.startsWith(_PATH_SOFTWARE_CATALOG) ||
295 friendlyURL.startsWith(_PATH_WAP) ||
296 friendlyURL.startsWith(_PATH_WSRP)) {
297
298 return false;
299 }
300
301 int code = LayoutImpl.validateFriendlyURL(friendlyURL);
302
303 if ((code > -1) &&
304 (code != LayoutFriendlyURLException.ENDS_WITH_SLASH)) {
305
306 return false;
307 }
308
309 return true;
310 }
311
312 protected boolean isValidRequestURL(StringBuffer requestURL) {
313 if (requestURL == null) {
314 return false;
315 }
316
317 String url = requestURL.toString();
318
319 if (url.endsWith(_EXT_C) || url.endsWith(_EXT_CSS) ||
320 url.endsWith(_EXT_GIF) || url.endsWith(_EXT_IMAGE_COMPANY_LOGO) ||
321 url.endsWith(_EXT_ICO) || url.endsWith(_EXT_JS) ||
322 url.endsWith(_EXT_JPEG) || url.endsWith(_EXT_JSP) ||
323 url.endsWith(_EXT_PORTAL_LAYOUT) ||
324 url.endsWith(_EXT_PORTAL_LOGIN) ||
325 url.endsWith(_EXT_PORTAL_LOGOUT) || url.endsWith(_EXT_PNG)) {
326
327 return false;
328 }
329 else {
330 return true;
331 }
332 }
333
334 protected void processFilter(
335 HttpServletRequest request, HttpServletResponse response,
336 FilterChain filterChain) {
337 }
338
339 private static Log _log = LogFactoryUtil.getLog(VirtualHostFilter.class);
340
341 private static String _EXT_C = "/c";
342
343 private static String _EXT_CSS = ".css";
344
345 private static String _EXT_GIF = ".gif";
346
347 private static String _EXT_IMAGE_COMPANY_LOGO = "/image/company_logo";
348
349 private static String _EXT_ICO = ".ico";
350
351 private static String _EXT_JS = ".js";
352
353 private static String _EXT_JPEG = ".jpeg";
354
355 private static String _EXT_JSP = ".jsp";
356
357 private static String _EXT_PORTAL_LAYOUT = "/portal/layout";
358
359 private static String _EXT_PORTAL_LOGIN = "/portal/login";
360
361 private static String _EXT_PORTAL_LOGOUT = "/portal/logout";
362
363 private static String _EXT_PNG = ".png";
364
365 private static String _PATH_C = "/c/";
366
367 private static String _PATH_DELEGATE = "/delegate/";
368
369 private static String _PATH_HTML = "/html/";
370
371 private static String _PATH_IMAGE = "/image/";
372
373 private static String _PATH_LANGUAGE = "/language/";
374
375 private static String _PATH_SITEMAP_XML = "/sitemap.xml";
376
377 private static String _PATH_SOFTWARE_CATALOG = "/software_catalog/";
378
379 private static String _PATH_WAP = "/wap/";
380
381 private static String _PATH_WSRP = "/wsrp/";
382
383 private static String _PRIVATE_GROUP_SERVLET_MAPPING =
384 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
385
386 private static String _PRIVATE_USER_SERVLET_MAPPING =
387 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
388
389 private static String _PUBLIC_GROUP_SERVLET_MAPPING =
390 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
391
392 private ServletContext _servletContext;
393
394 }