}
request.setAttribute(WEBSITE_ATTRIBUTE, webSite);
request.setCharacterEncoding(Utils.SYSTEM_CHARSET);
HttpServletRequest httpReq = webSite.wrapRequest(request);
Path pagePath = webSite.getRequestedPath(httpReq);
/* This is needed to avoid source code disclosure in virtual sites */
if (webSite instanceof VirtualWebSite) {
String uri = httpReq.getRequestURI().toLowerCase();
if (uri.endsWith(".jsp/")) {
httpRes.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
if (! pagePath.isContainedIn(webSite.getAdminPath()) &&
uri.endsWith(".jsp") && !WebUtils.verifyJSP(webSite, pagePath)) {
httpRes.sendError(HttpServletResponse.SC_FORBIDDEN,
"Execution of this page is not allowed");
return;
}
}
if (webSite.isDirectory(pagePath)) {
Path wPath = webSite.findCurrentWelcome(pagePath);
Configuration conf = webSite.getConfiguration();
if (conf == null || conf.isAlwaysDenyDirectoryListings()) {
if (wPath != null) {
redirect(httpReq, httpRes, wPath);
} else {
httpRes.sendError(HttpServletResponse.SC_FORBIDDEN,
"Directory listing denied");
}
return;
}
}
SiteMap siteMap = null;
PageInfo pageInfo = null;
boolean isAdminPage = false;
boolean isGuest = true;
String pageCharset = null;
if (webSite.getCMSPath() != null) {
if (pagePath.isContainedIn(webSite.getVirtualSitesPath()) ||
pagePath.isContainedIn(webSite.getPrivatePath())) {
httpRes.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
siteMap = webSite.getSiteMap();
isAdminPage = pagePath.isContainedIn(webSite.getAdminPath());
HttpSession session = httpReq.getSession();
if (webSite.getConfiguration().isSearchMovedPages() &&
!(isAdminPage || webSite.getFile(pagePath).exists())) {
Path redirPath = siteMap.getRedirMatch(pagePath);
if (redirPath != null) {
blockRemoteCaching(httpRes);
httpRes.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
httpRes.setHeader("Location", httpReq.getContextPath() + "/" + redirPath);
return;
}
}
UserInfo userInfo = (session == null) ? null :
(UserInfo) session.getAttribute("userInfo");
isGuest = userInfo == null || userInfo.isGuest();
// See if should redirect to one of the available languages
if (isGuest && webSite.getConfiguration().isRedirectRoot() &&
siteMap.getPathInMenu(pagePath).isRoot()) {
Path redirPath = getPreferredLanguage(httpReq);
if (redirPath != null) {
WebUtils.setBlockCache(httpReq);
redirect(httpReq, httpRes, redirPath);
return;
}
}
// Deal with all pages
if (FileTypes.isPage(pagePath.getLastElement())) {
// Block direct requests of modules from non authenticated users
/* if (isGuest && webSite.isInsideModules(pagePath) &&
pagePath.getLastElement().equalsIgnoreCase(SiteMap.MODULE_INCLUDE_FILE)) {
httpRes.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
} */
// disallow access to guests if required by configuration
if (isGuest && webSite.getConfiguration().isPasswordProtected() &&
!pagePath.isChildOf(webSite.getAdminPath())) {
httpRes.sendError(HttpServletResponse.SC_FORBIDDEN,
"You don't have enough privileges");
return;
}
WebUtils.updateLastModifiedTime(httpReq, webSite.getFile(pagePath));
blockRemoteCaching(httpRes);
// Find a theme for this page
Path themePath = null;
String themeParameter = request.getParameter(THEME_FILE_ATTRIBUTE);
if (themeParameter != null) {
themePath = (Path) siteMap.getThemesMap().get(themeParameter);
}
if (themePath == null || !webSite.getFile(themePath).exists()) {
themePath = webSite.getThemePath(pagePath);
}
if (themePath != null) { // there is a theme for this page
if (themePath.isContainedIn(webSite.getCustomThemesPath()) &&
!WebUtils.verifyJSP(webSite, themePath.add("main.jsp"))) {
if (isAdminPage) {
webSite.setLastAdminThemeBlock(System.currentTimeMillis());
}
httpRes.sendError(HttpServletResponse.SC_FORBIDDEN,
"Current theme is not allowed");
return;
}
request.setAttribute(THEME_PATH_ATTRIBUTE, themePath);
// pages in /admin do not need a decorator to be specified:
if (!isAdminPage || themeParameter != null) {
request.setAttribute(THEME_FILE_ATTRIBUTE, "/" +
webSite.getServedPath(themePath) + "/" +
SiteMap.THEME_DECORATOR);
}
}
/* Since a real page has been requested, disable hotlinking prevention
for this session
if (session != null && webSite.getConfiguration().isPreventHotlinking() &&
session.getAttribute(HOTLINKING_ALLOWED) == null && !isAdminPage) {
session.setAttribute(HOTLINKING_ALLOWED, HOTLINKING_ALLOWED);
} */
}
if (webSite.getConfiguration().isPreventHotlinking() &&
FileTypes.isPreventHotlinking(pagePath.getLastElement()) /*&&
(session == null || session.getAttribute(HOTLINKING_ALLOWED) == null)*/) {
String agent = httpReq.getHeader("user-agent");
if (agent == null || agent.toLowerCase().indexOf("java") < 0) {
try {
String domain = WebUtils.get2ndLevelDomain(httpReq);
if (domain != null) {
String referrer = httpReq.getHeader("referer");
try {
referrer = new URL(referrer).getHost();
} catch (Exception ex) {
referrer = null;
}
if (referrer == null || referrer.indexOf(domain) < 0) {
httpRes.sendRedirect(httpReq.getContextPath() + "/" +
webSite.getAdminPath() + "/hotlinking.jsp?path=" + pagePath);
return;
}
}
} catch (MalformedURLException ex) {}
}
}
pageInfo = siteMap.getPageInfo(pagePath);
if (pageInfo != null) { // this page is contained in the site map
if (isGuest) {
pageInfo.addHit();
}
if (pageInfo.getCharset() != null) {
pageCharset = pageInfo.getCharset();
}
} else { // not a page in the site map
// Let's try to apply the right charset to JavaScript lang files
if (isAdminPage && pagePath.getLastElement().endsWith(".js") &&
userInfo != null && userInfo.canDo(UserInfo.CAN_BROWSE_FILES)) {
String script = null;
if (pagePath.isContainedIn(webSite.getAdminScriptsPath().add("tiny_mce"))) {
script = "TinyMCE";
} else if (pagePath.isContainedIn(webSite.getAdminScriptsPath().add("jscalendar"))) {
script = "DHTMLCalendar";
}
if (script != null) {
Locale locale = Utils.getLocale(userInfo.getPreferredLocaleCode());
ResourceBundle bundle =
ResourceBundle.getBundle("org/meshcms/webui/Locales", locale);
String s = bundle.getString(script + "LangCode");
if (!Utils.isNullOrEmpty(s) && pagePath.getLastElement().equals(s + ".js")) {
s = bundle.getString(script + "LangCharset");
if (!Utils.isNullOrEmpty(s)) {
pageCharset = s;
}
}
}
} // end of JavaScript stuff
}
} // end of CMS stuff
String mimeType = sc.getMimeType(pagePath.getLastElement());
if (mimeType == null) {
mimeType = "text/html";
}
httpRes.setContentType(mimeType + "; charset=" +
Utils.noNull(pageCharset, Utils.SYSTEM_CHARSET));
try {
// Cache management
if (isGuest && pageInfo != null &&
httpReq.getMethod().equalsIgnoreCase("get") &&
Utils.isNullOrEmpty(httpReq.getQueryString()) &&
webSite.isVisuallyEditable(pagePath)) {
int cacheType = webSite.getConfiguration().getCacheType();
// Let's see if the browser supports GZIP
String ae = httpReq.getHeader("Accept-Encoding");
boolean gzip = ae != null && ae.toLowerCase().indexOf("gzip") > -1;
InputStream in = null;
if (cacheType == Configuration.IN_MEMORY_CACHE ||
cacheType == Configuration.MIXED_CACHE) {
byte[] pageBytes = siteMap.getCached(pageInfo.getPath());
// a cached page too small is suspicious
if (pageBytes != null && pageBytes.length > 256) {
in = new ByteArrayInputStream(pageBytes);
}
}
if (cacheType == Configuration.ON_DISK_CACHE ||
(in == null && cacheType == Configuration.MIXED_CACHE)) {
File cacheFile = WebUtils.getCacheFile(webSite, siteMap, pagePath);
if (cacheFile != null) {
in = new FileInputStream(cacheFile);
if (cacheType == Configuration.MIXED_CACHE) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Utils.copyStream(in, baos, true);
byte[] b = baos.toByteArray();
siteMap.cache(pageInfo.getPath(), b);
in = new ByteArrayInputStream(b);
}
}
}
// if a valid cached version has been found, use it
if (in != null) {
ServletOutputStream sos = response.getOutputStream();
if (gzip) {
httpRes.setHeader("Content-Encoding", "gzip");
} else {
// uncompress the page on the fly for that spider or old browser
in = new GZIPInputStream(in);
}
Utils.copyStream(in, sos, false);
sos.flush();
return;
}
// otherwise, if cache is enabled, store the generated page
if (cacheType != Configuration.NO_CACHE) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = new GZIPOutputStream(baos);
CacheResponseWrapper wrapper = new CacheResponseWrapper(httpRes, os);
chain.doFilter(httpReq, wrapper);
wrapper.finishResponse();
// os.flush();
/* If WebUtils.setBlockCache has not been called while creating
the page, it can be cached */
if (!WebUtils.isCacheBlocked(httpReq)) {
if (cacheType == Configuration.IN_MEMORY_CACHE ||
cacheType == Configuration.MIXED_CACHE) {
siteMap.cache(pageInfo.getPath(), baos.toByteArray());
}
if (cacheType == Configuration.ON_DISK_CACHE ||
cacheType == Configuration.MIXED_CACHE) {
File cacheFile = webSite.getRepositoryFile
(siteMap.getServedPath(pagePath), CACHE_FILE_NAME);
cacheFile.getParentFile().mkdirs();
Utils.writeFully(cacheFile, baos.toByteArray());
}
}
return;
}
} // end of cache management
chain.doFilter(httpReq, httpRes);
webSite.updateSiteMap(false); // better here than nowhere :)
} catch (Exception ex) {
if (isAdminPage) {
webSite.setLastAdminThemeBlock(System.currentTimeMillis());
}
Path wPath = webSite.findCurrentWelcome(pagePath);
if (wPath != null && !wPath.equals(pagePath)) {
redirect(httpReq, httpRes, wPath);
return;
}
sc.log("--------\n\nIMPORTANT: an exception has been caught while serving " +