/* * Copyright (C) 2014 Intel Corporation * All rights reserved. */ package com.intel.mtwilson.servlet; import com.intel.mtwilson.My; import java.io.*; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletOutputStream; import javax.servlet.ServletException; import org.apache.commons.io.IOUtils; /** * @author jbuhacoff */ public class FileServlet extends HttpServlet { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(FileServlet.class); private String directory = null; private String prefixTarget = null; /** * Only files inside this directory and sub-directories will be served. * The servlet will not access files outside the directory. * @param directory */ public void setDirectory(String directory) { this.directory = directory; } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if( directory == null ) { setDirectory(My.configuration().getPortalHtml5Dir()); log.info("Static content directory: {}", directory); } if( prefixTarget == null ) { File prefixFile = new File(directory); prefixTarget = prefixFile.getCanonicalPath(); } // Get the file to view String path = request.getPathInfo(); if (path == null) { path = ""; } File file = new File(directory, path); // prevent client from using .. to get out of our content folder and to arbitrary files String target = file.getCanonicalPath(); if( !target.startsWith(prefixTarget) ) { response.setStatus(404); return; } // redirect to use trailing slash on directories in order for relative filenames in links to work file = new File(target); if( file.isDirectory() && !path.endsWith("/") ) { String queryString = request.getQueryString() == null ? "" : "?" + request.getQueryString(); if (queryString.contains("\r\n")) { response.setStatus(400); return; } response.sendRedirect(request.getRequestURI() + "/" + queryString); return; } // automatic index file for directories; we don't support listing contents so if the index file is not there the client will get a 404 for the directory if( file.isDirectory() ) { file = new File(target, "index.html"); } if (!file.exists()) { file = new File(target, "index.html5"); } // Get and set the type of the file; relies on the mime types defined in web.xml String contentType = getServletContext().getMimeType(file.getName()); response.setContentType(contentType); // we set the content length only if it's less than max int, to avoid // sending a bogus content length for a huge file (when it matters most!) if( file.length() < Integer.MAX_VALUE ) { response.setContentLength((int)file.length()); } // read the file and send to the client try(FileInputStream in = new FileInputStream(file); ServletOutputStream out = response.getOutputStream()) { IOUtils.copy(in, out); } catch (FileNotFoundException e) { log.info("File not found: {}", file.getAbsolutePath()); response.setStatus(404); } catch (IOException e) { log.error("Cannot retrieve file", e); response.setStatus(500); } catch (IllegalArgumentException iae) { log.error("Illegal arguments specified.", iae); response.setStatus(500); } } }