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
69 public class VirtualHostFilter extends BasePortalFilter {
70
71 public void init(FilterConfig filterConfig) {
72 super.init(filterConfig);
73
74 _servletContext = filterConfig.getServletContext();
75 }
76
77 protected boolean isValidFriendlyURL(String friendlyURL) {
78 friendlyURL = friendlyURL.toLowerCase();
79
80 if (PortalInstances.isVirtualHostsIgnorePath(friendlyURL) ||
81 friendlyURL.startsWith(
82 PortalUtil.getPathFriendlyURLPrivateGroup() +
83 StringPool.SLASH) ||
84 friendlyURL.startsWith(
85 PortalUtil.getPathFriendlyURLPublic() + StringPool.SLASH) ||
86 friendlyURL.startsWith(
87 PortalUtil.getPathFriendlyURLPrivateUser() +
88 StringPool.SLASH) ||
89 friendlyURL.startsWith(_PATH_C) ||
90 friendlyURL.startsWith(_PATH_DELEGATE) ||
91 friendlyURL.startsWith(_PATH_HTML) ||
92 friendlyURL.startsWith(_PATH_IMAGE) ||
93 friendlyURL.startsWith(_PATH_LANGUAGE) ||
94 friendlyURL.startsWith(_PATH_SITEMAP_XML) ||
95 friendlyURL.startsWith(_PATH_SOFTWARE_CATALOG) ||
96 friendlyURL.startsWith(_PATH_WAP) ||
97 friendlyURL.startsWith(_PATH_WSRP)) {
98
99 return false;
100 }
101
102 int code = LayoutImpl.validateFriendlyURL(friendlyURL);
103
104 if ((code > -1) &&
105 (code != LayoutFriendlyURLException.ENDS_WITH_SLASH)) {
106
107 return false;
108 }
109
110 return true;
111 }
112
113 protected boolean isValidRequestURL(StringBuffer requestURL) {
114 if (requestURL == null) {
115 return false;
116 }
117
118 String url = requestURL.toString();
119
120 for (String extension : PropsValues.VIRTUAL_HOSTS_IGNORE_EXTENSIONS) {
121 if (url.endsWith(extension)) {
122 return false;
123 }
124 }
125
126 return true;
127 }
128
129 protected void processFilter(
130 HttpServletRequest request, HttpServletResponse response,
131 FilterChain filterChain)
132 throws Exception {
133
134 request.setCharacterEncoding(StringPool.UTF8);
135
137
139 response = new AbsoluteRedirectsResponse(request, response);
140
141
144 long companyId = PortalInstances.getCompanyId(request);
145
146 if (_log.isDebugEnabled()) {
147 _log.debug("Company id " + companyId);
148 }
149
150 PortalUtil.getCurrentCompleteURL(request);
151 PortalUtil.getCurrentURL(request);
152
153 HttpSession session = request.getSession();
154
155 Boolean httpsInitial = (Boolean)session.getAttribute(
156 WebKeys.HTTPS_INITIAL);
157
158 if (httpsInitial == null) {
159 httpsInitial = Boolean.valueOf(request.isSecure());
160
161 session.setAttribute(WebKeys.HTTPS_INITIAL, httpsInitial);
162
163 if (_log.isDebugEnabled()) {
164 _log.debug("Setting httpsInitial to " + httpsInitial);
165 }
166 }
167
168 if (!isFilterEnabled()) {
169 processFilter(
170 VirtualHostFilter.class, request, response, filterChain);
171
172 return;
173 }
174
175 StringBuffer requestURL = request.getRequestURL();
176
177 if (_log.isDebugEnabled()) {
178 _log.debug("Received " + requestURL);
179 }
180
181 if (!isValidRequestURL(requestURL)) {
182 processFilter(
183 VirtualHostFilter.class, request, response, filterChain);
184
185 return;
186 }
187
188 String contextPath = PortalUtil.getPathContext();
189
190 String friendlyURL = request.getRequestURI();
191
192 if ((Validator.isNotNull(contextPath)) &&
193 (friendlyURL.indexOf(contextPath) != -1)) {
194
195 friendlyURL = friendlyURL.substring(contextPath.length());
196 }
197
198 friendlyURL = StringUtil.replace(
199 friendlyURL, StringPool.DOUBLE_SLASH, StringPool.SLASH);
200
201 String i18nLanguageId = null;
202
203 Set<String> languageIds = I18nServlet.getLanguageIds();
204
205 for (String languageId : languageIds) {
206 if (friendlyURL.startsWith(languageId)) {
207 int pos = friendlyURL.indexOf(StringPool.SLASH, 1);
208
209 if (pos == -1) {
210 continue;
211 }
212
213 i18nLanguageId = friendlyURL.substring(0, pos);
214 friendlyURL = friendlyURL.substring(pos);
215
216 break;
217 }
218 }
219
220 if (_log.isDebugEnabled()) {
221 _log.debug("Friendly URL " + friendlyURL);
222 }
223
224 if (!friendlyURL.equals(StringPool.SLASH) &&
225 !isValidFriendlyURL(friendlyURL)) {
226
227 _log.debug("Friendly URL is not valid");
228
229 processFilter(
230 VirtualHostFilter.class, request, response, filterChain);
231
232 return;
233 }
234
235 LayoutSet layoutSet = (LayoutSet)request.getAttribute(
236 WebKeys.VIRTUAL_HOST_LAYOUT_SET);
237
238 if (_log.isDebugEnabled()) {
239 _log.debug("Layout set " + layoutSet);
240 }
241
242 if (layoutSet != null) {
243 try {
244 LastPath lastPath = new LastPath(
245 contextPath, friendlyURL, request.getParameterMap());
246
247 request.setAttribute(WebKeys.LAST_PATH, lastPath);
248
249 StringBuilder prefix = new StringBuilder();
250
251 Group group = GroupLocalServiceUtil.getGroup(
252 layoutSet.getGroupId());
253
254 if (layoutSet.isPrivateLayout()) {
255 if (group.isUser()) {
256 prefix.append(_PRIVATE_USER_SERVLET_MAPPING);
257 }
258 else {
259 prefix.append(_PRIVATE_GROUP_SERVLET_MAPPING);
260 }
261 }
262 else {
263 prefix.append(_PUBLIC_GROUP_SERVLET_MAPPING);
264 }
265
266 prefix.append(group.getFriendlyURL());
267
268 StringBuilder forwardURL = new StringBuilder();
269
270 if (i18nLanguageId != null) {
271 forwardURL.append(i18nLanguageId);
272 }
273
274 if (friendlyURL.startsWith(
275 PropsValues.WIDGET_SERVLET_MAPPING)) {
276
277 forwardURL.append(PropsValues.WIDGET_SERVLET_MAPPING);
278
279 friendlyURL = StringUtil.replaceFirst(
280 friendlyURL, PropsValues.WIDGET_SERVLET_MAPPING,
281 StringPool.BLANK);
282 }
283
284 long plid = PortalUtil.getPlidFromFriendlyURL(
285 companyId, friendlyURL);
286
287 if (plid <= 0) {
288 forwardURL.append(prefix);
289 }
290
291 forwardURL.append(friendlyURL);
292
293 if (_log.isDebugEnabled()) {
294 _log.debug("Forward to " + forwardURL);
295 }
296
297 RequestDispatcher requestDispatcher =
298 _servletContext.getRequestDispatcher(forwardURL.toString());
299
300 requestDispatcher.forward(request, response);
301
302 return;
303 }
304 catch (Exception e) {
305 _log.error(e, e);
306 }
307 }
308
309 processFilter(VirtualHostFilter.class, request, response, filterChain);
310 }
311
312 private static Log _log = LogFactoryUtil.getLog(VirtualHostFilter.class);
313
314 private static String _PATH_C = "/c/";
315
316 private static String _PATH_DELEGATE = "/delegate/";
317
318 private static String _PATH_HTML = "/html/";
319
320 private static String _PATH_IMAGE = "/image/";
321
322 private static String _PATH_LANGUAGE = "/language/";
323
324 private static String _PATH_SITEMAP_XML = "/sitemap.xml";
325
326 private static String _PATH_SOFTWARE_CATALOG = "/software_catalog/";
327
328 private static String _PATH_WAP = "/wap/";
329
330 private static String _PATH_WSRP = "/wsrp/";
331
332 private static String _PRIVATE_GROUP_SERVLET_MAPPING =
333 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
334
335 private static String _PRIVATE_USER_SERVLET_MAPPING =
336 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
337
338 private static String _PUBLIC_GROUP_SERVLET_MAPPING =
339 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
340
341 private ServletContext _servletContext;
342
343 }