package tachyon.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.io.ByteStreams;
import tachyon.Constants;
import tachyon.TachyonURI;
import tachyon.client.InStream;
import tachyon.client.ReadType;
import tachyon.client.TachyonFile;
import tachyon.client.TachyonFS;
import tachyon.master.MasterInfo;
import tachyon.thrift.ClientFileInfo;
import tachyon.thrift.FileDoesNotExistException;
import tachyon.thrift.InvalidPathException;
/**
* Servlet for downloading a file
*/
public class WebInterfaceDownloadServlet extends HttpServlet {
private static final long serialVersionUID = 7329267100965731815L;
private static final Logger LOG = LoggerFactory.getLogger(Constants.LOGGER_TYPE);
private final transient MasterInfo mMasterInfo;
public WebInterfaceDownloadServlet(MasterInfo masterInfo) {
mMasterInfo = masterInfo;
}
/**
* Prepares for downloading a file
*
* @param request The HttpServletRequest object
* @param response The HttpServletReponse object
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String requestPath = request.getParameter("path");
if (requestPath == null || requestPath.isEmpty()) {
requestPath = TachyonURI.SEPARATOR;
}
TachyonURI currentPath = new TachyonURI(requestPath);
try {
ClientFileInfo clientFileInfo = mMasterInfo.getClientFileInfo(currentPath);
if (null == clientFileInfo) {
throw new FileDoesNotExistException(currentPath.toString());
}
downloadFile(new TachyonURI(clientFileInfo.getPath()), request, response);
} catch (FileDoesNotExistException fdne) {
request.setAttribute("invalidPathError", "Error: Invalid Path " + fdne.getMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
} catch (InvalidPathException ipe) {
request.setAttribute("invalidPathError", "Error: Invalid Path " + ipe.getLocalizedMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
}
}
/**
* This function prepares for downloading a file.
*
* @param path The path of the file to download
* @param request The HttpServletRequest object
* @param response The HttpServletResponse object
* @throws FileDoesNotExistException
* @throws IOException
*/
private void downloadFile(TachyonURI path, HttpServletRequest request,
HttpServletResponse response) throws FileDoesNotExistException, IOException {
String masterAddress =
Constants.HEADER + mMasterInfo.getMasterAddress().getHostName() + ":"
+ mMasterInfo.getMasterAddress().getPort();
TachyonFS tachyonClient = TachyonFS.get(new TachyonURI(masterAddress));
TachyonFile tFile = tachyonClient.getFile(path);
if (tFile == null) {
throw new FileDoesNotExistException(path.toString());
}
long len = tFile.length();
String fileName = path.getName();
response.setContentType("application/octet-stream");
if (len <= Integer.MAX_VALUE) {
response.setContentLength((int) len);
} else {
response.addHeader("Content-Length", Long.toString(len));
}
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
InStream is = null;
ServletOutputStream out = null;
try {
is = tFile.getInStream(ReadType.NO_CACHE);
out = response.getOutputStream();
ByteStreams.copy(is, out);
} finally {
if (out != null) {
out.flush();
out.close();
}
if (is != null) {
is.close();
}
}
try {
tachyonClient.close();
} catch (IOException e) {
LOG.error(e.getMessage());
}
}
}