001
014
015 package com.liferay.portal.servlet.filters.virtualhost;
016
017 import com.liferay.portal.LayoutFriendlyURLException;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.struts.LastPath;
021 import com.liferay.portal.kernel.util.CharPool;
022 import com.liferay.portal.kernel.util.StringBundler;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.kernel.util.Validator;
026 import com.liferay.portal.model.Group;
027 import com.liferay.portal.model.LayoutSet;
028 import com.liferay.portal.model.impl.LayoutImpl;
029 import com.liferay.portal.service.GroupLocalServiceUtil;
030 import com.liferay.portal.servlet.AbsoluteRedirectsResponse;
031 import com.liferay.portal.servlet.I18nServlet;
032 import com.liferay.portal.servlet.filters.BasePortalFilter;
033 import com.liferay.portal.util.PortalInstances;
034 import com.liferay.portal.util.PortalUtil;
035 import com.liferay.portal.util.PropsValues;
036 import com.liferay.portal.util.WebKeys;
037
038 import java.util.Set;
039
040 import javax.servlet.FilterChain;
041 import javax.servlet.FilterConfig;
042 import javax.servlet.RequestDispatcher;
043 import javax.servlet.ServletContext;
044 import javax.servlet.http.HttpServletRequest;
045 import javax.servlet.http.HttpServletResponse;
046 import javax.servlet.http.HttpSession;
047
048
062 public class VirtualHostFilter extends BasePortalFilter {
063
064 public void init(FilterConfig filterConfig) {
065 super.init(filterConfig);
066
067 _servletContext = filterConfig.getServletContext();
068 }
069
070 protected boolean isValidFriendlyURL(String friendlyURL) {
071 friendlyURL = friendlyURL.toLowerCase();
072
073 if (PortalInstances.isVirtualHostsIgnorePath(friendlyURL) ||
074 friendlyURL.startsWith(
075 _PRIVATE_GROUP_SERVLET_MAPPING + StringPool.SLASH) ||
076 friendlyURL.startsWith(
077 _PUBLIC_GROUP_SERVLET_MAPPING + StringPool.SLASH) ||
078 friendlyURL.startsWith(
079 _PRIVATE_USER_SERVLET_MAPPING + StringPool.SLASH) ||
080 friendlyURL.startsWith(_PATH_C) ||
081 friendlyURL.startsWith(_PATH_COMBO) ||
082 friendlyURL.startsWith(_PATH_DELEGATE) ||
083 friendlyURL.startsWith(_PATH_DISPLAY_CHART) ||
084 friendlyURL.startsWith(_PATH_DOCUMENTS) ||
085 friendlyURL.startsWith(_PATH_DTD) ||
086 friendlyURL.startsWith(_PATH_FACEBOOK) ||
087 friendlyURL.startsWith(_PATH_GOOGLE_GADGET) ||
088 friendlyURL.startsWith(_PATH_HTML) ||
089 friendlyURL.startsWith(_PATH_IMAGE) ||
090 friendlyURL.startsWith(_PATH_LANGUAGE) ||
091 friendlyURL.startsWith(_PATH_NETVIBES) ||
092 friendlyURL.startsWith(_PATH_PBHS) ||
093 friendlyURL.startsWith(_PATH_POLLER) ||
094 friendlyURL.startsWith(_PATH_SHAREPOINT) ||
095 friendlyURL.startsWith(_PATH_SITEMAP_XML) ||
096 friendlyURL.startsWith(_PATH_SOFTWARE_CATALOG) ||
097 friendlyURL.startsWith(_PATH_VTI) ||
098 friendlyURL.startsWith(_PATH_WAP) ||
099 friendlyURL.startsWith(_PATH_WIDGET) ||
100 friendlyURL.startsWith(_PATH_XMLRPC)) {
101
102 return false;
103 }
104
105 int code = LayoutImpl.validateFriendlyURL(friendlyURL);
106
107 if ((code > -1) &&
108 (code != LayoutFriendlyURLException.ENDS_WITH_SLASH)) {
109
110 return false;
111 }
112
113 return true;
114 }
115
116 protected boolean isValidRequestURL(StringBuffer requestURL) {
117 if (requestURL == null) {
118 return false;
119 }
120
121 String url = requestURL.toString();
122
123 for (String extension : PropsValues.VIRTUAL_HOSTS_IGNORE_EXTENSIONS) {
124 if (url.endsWith(extension)) {
125 return false;
126 }
127 }
128
129 return true;
130 }
131
132 protected void processFilter(
133 HttpServletRequest request, HttpServletResponse response,
134 FilterChain filterChain)
135 throws Exception {
136
137 request.setCharacterEncoding(StringPool.UTF8);
138
139
140
141
142 response = new AbsoluteRedirectsResponse(request, response);
143
144
145
146
147 long companyId = PortalInstances.getCompanyId(request);
148
149 if (_log.isDebugEnabled()) {
150 _log.debug("Company id " + companyId);
151 }
152
153 PortalUtil.getCurrentCompleteURL(request);
154 PortalUtil.getCurrentURL(request);
155
156 HttpSession session = request.getSession();
157
158 Boolean httpsInitial = (Boolean)session.getAttribute(
159 WebKeys.HTTPS_INITIAL);
160
161 if (httpsInitial == null) {
162 httpsInitial = Boolean.valueOf(request.isSecure());
163
164 session.setAttribute(WebKeys.HTTPS_INITIAL, httpsInitial);
165
166 if (_log.isDebugEnabled()) {
167 _log.debug("Setting httpsInitial to " + httpsInitial);
168 }
169 }
170
171 if (!isFilterEnabled()) {
172 processFilter(
173 VirtualHostFilter.class, request, response, filterChain);
174
175 return;
176 }
177
178 StringBuffer requestURL = request.getRequestURL();
179
180 if (_log.isDebugEnabled()) {
181 _log.debug("Received " + requestURL);
182 }
183
184 if (!isValidRequestURL(requestURL)) {
185 processFilter(
186 VirtualHostFilter.class, request, response, filterChain);
187
188 return;
189 }
190
191 String contextPath = PortalUtil.getPathContext();
192
193 String originalFriendlyURL = request.getRequestURI();
194
195 String friendlyURL = originalFriendlyURL;
196
197 if ((Validator.isNotNull(contextPath)) &&
198 (friendlyURL.indexOf(contextPath) != -1)) {
199
200 friendlyURL = friendlyURL.substring(contextPath.length());
201 }
202
203 friendlyURL = StringUtil.replace(
204 friendlyURL, StringPool.DOUBLE_SLASH, StringPool.SLASH);
205
206 String i18nLanguageId = null;
207
208 Set<String> languageIds = I18nServlet.getLanguageIds();
209
210 for (String languageId : languageIds) {
211 if (friendlyURL.startsWith(languageId)) {
212 int pos = friendlyURL.indexOf(CharPool.SLASH, 1);
213
214 if (((pos != -1) && (pos != languageId.length())) ||
215 ((pos == -1) && !friendlyURL.equals(languageId))) {
216
217 continue;
218 }
219
220 if (pos == -1) {
221 i18nLanguageId = friendlyURL;
222 friendlyURL = StringPool.SLASH;
223 }
224 else {
225 i18nLanguageId = friendlyURL.substring(0, pos);
226 friendlyURL = friendlyURL.substring(pos);
227 }
228
229 break;
230 }
231 }
232
233 friendlyURL = StringUtil.replace(
234 friendlyURL, PropsValues.WIDGET_SERVLET_MAPPING, StringPool.BLANK);
235
236 if (_log.isDebugEnabled()) {
237 _log.debug("Friendly URL " + friendlyURL);
238 }
239
240 if (!friendlyURL.equals(StringPool.SLASH) &&
241 !isValidFriendlyURL(friendlyURL)) {
242
243 _log.debug("Friendly URL is not valid");
244
245 processFilter(
246 VirtualHostFilter.class, request, response, filterChain);
247
248 return;
249 }
250
251 LayoutSet layoutSet = (LayoutSet)request.getAttribute(
252 WebKeys.VIRTUAL_HOST_LAYOUT_SET);
253
254 if (_log.isDebugEnabled()) {
255 _log.debug("Layout set " + layoutSet);
256 }
257
258 if (layoutSet != null) {
259 try {
260 LastPath lastPath = new LastPath(
261 contextPath, friendlyURL, request.getParameterMap());
262
263 request.setAttribute(WebKeys.LAST_PATH, lastPath);
264
265 StringBundler prefix = new StringBundler(2);
266
267 Group group = GroupLocalServiceUtil.getGroup(
268 layoutSet.getGroupId());
269
270 if (layoutSet.isPrivateLayout()) {
271 if (group.isUser()) {
272 prefix.append(_PRIVATE_USER_SERVLET_MAPPING);
273 }
274 else {
275 prefix.append(_PRIVATE_GROUP_SERVLET_MAPPING);
276 }
277 }
278 else {
279 prefix.append(_PUBLIC_GROUP_SERVLET_MAPPING);
280 }
281
282 prefix.append(group.getFriendlyURL());
283
284 StringBundler forwardURL = new StringBundler(6);
285
286 if (i18nLanguageId != null) {
287 forwardURL.append(i18nLanguageId);
288 }
289
290 if (originalFriendlyURL.startsWith(
291 PropsValues.WIDGET_SERVLET_MAPPING)) {
292
293 forwardURL.append(PropsValues.WIDGET_SERVLET_MAPPING);
294
295 friendlyURL = StringUtil.replaceFirst(
296 friendlyURL, PropsValues.WIDGET_SERVLET_MAPPING,
297 StringPool.BLANK);
298 }
299
300 long plid = PortalUtil.getPlidFromFriendlyURL(
301 companyId, friendlyURL);
302
303 if (plid <= 0) {
304 forwardURL.append(prefix);
305 }
306
307 forwardURL.append(friendlyURL);
308
309 if (_log.isDebugEnabled()) {
310 _log.debug("Forward to " + forwardURL);
311 }
312
313 RequestDispatcher requestDispatcher =
314 _servletContext.getRequestDispatcher(forwardURL.toString());
315
316 requestDispatcher.forward(request, response);
317
318 return;
319 }
320 catch (Exception e) {
321 _log.error(e, e);
322 }
323 }
324
325 processFilter(VirtualHostFilter.class, request, response, filterChain);
326 }
327
328 private static final String _PATH_C = "/c/";
329
330 private static final String _PATH_COMBO = "/combo/";
331
332 private static final String _PATH_DELEGATE = "/delegate/";
333
334 private static final String _PATH_DISPLAY_CHART = "/display_chart";
335
336 private static final String _PATH_DOCUMENTS = "/documents/";
337
338 private static final String _PATH_DTD = "/dtd/";
339
340 private static final String _PATH_FACEBOOK = "/facebook/";
341
342 private static final String _PATH_GOOGLE_GADGET = "/google_gadget/";
343
344 private static final String _PATH_HTML = "/html/";
345
346 private static final String _PATH_IMAGE = "/image/";
347
348 private static final String _PATH_LANGUAGE = "/language/";
349
350 private static final String _PATH_NETVIBES = "/netvibes/";
351
352 private static final String _PATH_PBHS = "/pbhs/";
353
354 private static final String _PATH_POLLER = "/poller/";
355
356 private static final String _PATH_SHAREPOINT = "/sharepoint/";
357
358 private static final String _PATH_SITEMAP_XML = "/sitemap.xml";
359
360 private static final String _PATH_SOFTWARE_CATALOG = "/software_catalog";
361
362 private static final String _PATH_VTI = "/_vti_";
363
364 private static final String _PATH_WAP = "/wap/";
365
366 private static final String _PATH_WIDGET = "/widget/";
367
368 private static final String _PATH_XMLRPC = "/xmlrpc/";
369
370 private static final String _PRIVATE_GROUP_SERVLET_MAPPING =
371 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
372
373 private static final String _PRIVATE_USER_SERVLET_MAPPING =
374 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
375
376 private static final String _PUBLIC_GROUP_SERVLET_MAPPING =
377 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
378
379 private static Log _log = LogFactoryUtil.getLog(VirtualHostFilter.class);
380
381 private ServletContext _servletContext;
382
383 }