/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.webserver;
import com.liferay.portal.kernel.image.SpriteProcessor;
import com.liferay.portal.kernel.servlet.HttpHeaders;
import com.liferay.portal.kernel.servlet.ServletResponseUtil;
import com.liferay.portal.kernel.util.JavaConstants;
import com.liferay.portal.kernel.util.MimeTypesUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.util.PropsValues;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLDecoder;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Raymond Augé
*/
public class DynamicResourceServlet extends WebServerServlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
_tempDir = (File)getServletContext().getAttribute(
JavaConstants.JAVAX_SERVLET_CONTEXT_TEMPDIR);
}
@Override
public void service(
HttpServletRequest request, HttpServletResponse response)
throws IOException {
String servletPath = request.getServletPath();
String pathInfo = URLDecoder.decode(
request.getPathInfo(), StringPool.UTF8);
String path = servletPath.concat(pathInfo);
if (!isAllowedPath(path)) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
File rootDir = _tempDir;
File file = new File(rootDir, path);
if (servletPath.equals(SpriteProcessor.PATH)) {
String spriteRootDirName = PropsValues.SPRITE_ROOT_DIR;
if (Validator.isNotNull(spriteRootDirName)) {
rootDir = new File(spriteRootDirName);
file = new File(rootDir, pathInfo);
}
}
String canonicalPath = file.getCanonicalPath();
if (!file.exists() || file.isDirectory() || !file.canRead() ||
file.isHidden() ||
!canonicalPath.startsWith(rootDir.getCanonicalPath())) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
long lastModified = file.lastModified();
if (lastModified > 0) {
long ifModifiedSince = request.getDateHeader(
HttpHeaders.IF_MODIFIED_SINCE);
if ((ifModifiedSince > 0) && (ifModifiedSince == lastModified)) {
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
}
if (lastModified > 0) {
response.setDateHeader(HttpHeaders.LAST_MODIFIED, lastModified);
}
String fileName = file.getName();
// Determine proper content type
String contentType = MimeTypesUtil.getContentType(fileName);
// Send file
if (isSupportsRangeHeader(contentType)) {
ServletResponseUtil.sendFileWithRangeHeader(
request, response, fileName, new FileInputStream(file),
file.length(), contentType);
}
else {
ServletResponseUtil.sendFile(
request, response, fileName, new FileInputStream(file),
file.length(), contentType);
}
}
protected boolean isAllowedPath(String path) {
for (String allowedPath :
PropsValues.DYNAMIC_RESOURCE_SERVLET_ALLOWED_PATHS) {
if (path.startsWith(allowedPath)) {
return true;
}
}
return false;
}
private File _tempDir;
}