package org.activityinfo.server.report.output; /* * #%L * ActivityInfo Server * %% * Copyright (C) 2009 - 2013 UNICEF * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import com.google.common.annotations.VisibleForTesting; import com.google.common.io.ByteStreams; import com.google.common.io.InputSupplier; import com.google.inject.Inject; import org.activityinfo.server.util.blob.BlobNotFoundException; import org.activityinfo.server.util.blob.BlobService; import javax.inject.Singleton; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; /** * Serves up temporary files created during the rendering process. The actual * blob is identified by a secure hexadecimal id, but a friendly filename can be * appended to the uri, which is the best cross-browser way to indicate the file * name to be saved as. For example: * <p/> * <blockquote> * http://www.activityinfo.org/generated/1b391a99c2b49a2c/Untitled%20 * Report%2020130426_0446.rtf </blockquote> * <p/> * In this URL, the text following the 1b391a99c2b49a2c/ is ignored, but used by * all browsers to suggest the file name to save. */ @Singleton public class TempStorageServlet extends HttpServlet { private final BlobService blobService; @Inject public TempStorageServlet(BlobService blobService) { super(); this.blobService = blobService; } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String keyName = parseBlobKey(req.getRequestURI()); InputSupplier<? extends InputStream> inputSupplier; try { inputSupplier = blobService.get("/temp/" + keyName); } catch (BlobNotFoundException e) { resp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } resp.setHeader("Content-Type", mimeTypeFromUri(req.getRequestURI().toLowerCase())); resp.setHeader("Content-Disposition", "attachment"); ByteStreams.copy(inputSupplier, resp.getOutputStream()); } private String mimeTypeFromUri(String uri) { if (uri.endsWith(".rtf")) { return "application/rtf"; } else if (uri.endsWith(".pdf")) { return "application/pdf"; } else if (uri.endsWith(".png")) { return "image/png"; } else if (uri.endsWith(".html")) { return "text/html"; } else if (uri.endsWith(".ppt")) { return "application/vnd.ms-powerpoint"; } else if (uri.endsWith(".xls")) { return "application/vnd.ms-excel"; } else { return "application/octet-stream"; } } @VisibleForTesting static String parseBlobKey(String uri) { String prefix = "/generated/"; int start = uri.indexOf(prefix); if (start == -1) { throw new IllegalArgumentException(uri); } start += prefix.length(); int keyEnd = uri.indexOf('/', start + 1); if (keyEnd == -1) { throw new IllegalArgumentException(uri); } return uri.substring(start, keyEnd); } }