/* * Copyright 2012 Axel Winkler, Daniel Dunér * * This file is part of Daxplore Presenter. * * Daxplore Presenter 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. * * Daxplore Presenter 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. * * You should have received a copy of the GNU Lesser General Public License * along with Daxplore Presenter. If not, see <http://www.gnu.org/licenses/>. */ package org.daxplore.presenter.server.servlets; import java.io.IOException; import java.io.OutputStream; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.daxplore.presenter.server.servlets.png.OnePixel; import org.daxplore.presenter.server.servlets.png.PngWriter; import org.daxplore.presenter.server.throwable.BadRequestException; import org.daxplore.presenter.server.throwable.InternalServerException; /** * A servlet that supplies 1x1 px images in colors, based on file name. * * <p>New pixel-sized images are generated on the fly. Request an image using * the format <hexvalue>.png, for example FF0000.png for a completely red * pixel.</p> */ @SuppressWarnings("serial") public class GetPixelServlet extends HttpServlet { private static Logger logger = Logger.getLogger(GetPixelServlet.class.getName()); private final int CACHE_DURATION_IN_SECOND = 60 * 60 * 24 * 14; // 14 days private final long CACHE_DURATION_IN_MS = CACHE_DURATION_IN_SECOND * 1000; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { boolean hasalpha = false; String uri = request.getRequestURI().substring(7); // "/pixel/".length // ([0-9a-fA-F]{6})((?:[0-9a-fA-F]{2})?)[.](png|gif|jpg|jpeg) with alpha // ([0-9a-fA-F]{6})[.](png|gif|jpg|jpeg) without alpha Pattern p = Pattern.compile("([0-9a-fA-F]{6})((?:[0-9a-fA-F]{2})?)[.](png)"); String color = "000000"; String alpha = "00"; Matcher m = p.matcher(uri); if (m.matches()) { // System.out.println("color: " + m.group(1)); color = m.group(1); if (!m.group(2).equals("")) { alpha = m.group(2); hasalpha = true; // System.out.println("alpha: " + m.group(2)); } // System.out.println("filetype: " + m.group(3)); } else { throw new BadRequestException("Bad pixel request"); } response.setContentType("image/png"); long now = System.currentTimeMillis(); response.addHeader("Cache-Control", "max-age=" + CACHE_DURATION_IN_SECOND); Date created = new Date(1000 * 1306274400L); // Wed May 25 00:00:00 CEST 2011 as Unix Epoch in millis response.setDateHeader("Last-Modified", created.getTime()); response.setDateHeader("Expires", now + CACHE_DURATION_IN_MS); OnePixel pixel; if (hasalpha) { pixel = new OnePixel(color, alpha); } else { pixel = new OnePixel(color); } PngWriter pngw = new PngWriter(hasalpha); try (OutputStream respWriter = response.getOutputStream()){ byte[] bytes = pngw.generateImage(pixel); respWriter.write(bytes); } catch (IOException e) { throw new InternalServerException("Failed to generate a pixel", e); } } catch (BadRequestException e) { logger.log(Level.WARNING, e.getMessage(), e); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); } catch (InternalServerException e) { logger.log(Level.SEVERE, e.getMessage(), e); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } catch (Exception e) { logger.log(Level.SEVERE, "Unexpected exception: " + e.getMessage(), e); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } }