package org.dcache.services.httpd.handlers; import com.google.common.base.Joiner; import com.google.common.collect.Iterables; import com.google.common.io.Files; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.net.FileNameMap; import java.net.URLConnection; import java.util.Arrays; import dmg.util.HttpException; import dmg.util.HttpRequest; import org.dcache.services.httpd.util.StandardHttpRequest; /** * Provides HTML or .css content from static file. * * @author arossi */ public class PathHandler extends AbstractHandler { private static final FileNameMap mimeTypeMap = URLConnection.getFileNameMap(); private final File path; public PathHandler(File path) { this.path = path; } @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { try { HttpRequest proxy = new StandardHttpRequest(request, response); sendFile(path, proxy); } catch (Exception t) { throw new ServletException("PathHandler failure", t); } } private void sendFile(File base, HttpRequest proxy) throws Exception { String filename; String[] tokens = proxy.getRequestTokens(); if (tokens.length < 2) { filename = "index.html"; } else { filename = Joiner.on("/").join(Iterables.skip(Arrays.asList(tokens), 1)); } final File f = base.isFile() ? base : new File(base, filename); if (!f.getCanonicalFile().getAbsolutePath().startsWith( base.getCanonicalFile().getAbsolutePath())) { throw new HttpException(HttpServletResponse.SC_FORBIDDEN, "Forbidden"); } if (!f.isFile()) { throw new HttpException(HttpServletResponse.SC_NOT_FOUND, "Not found : " + filename); } try { proxy.setContentType(getContentTypeFor(filename)); Files.copy(f, proxy.getOutputStream()); } finally { proxy.getOutputStream().flush(); } } private String getContentTypeFor(String fileName) { if (fileName.endsWith(".html")) { return "text/html"; } else if (fileName.endsWith(".css")) { return "text/css"; } else { return mimeTypeMap.getContentTypeFor(fileName); } } }