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