/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wms.animate; import java.io.IOException; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.geoserver.filters.GeoServerFilter; import org.geotools.util.logging.Logging; /** * GIF Animated reflecting service request filter. * <p> * Modifies requests against the WMS animate reflector service endpoints * in order to address <a href="https://osgeo-org.atlassian.net/browse/GEOS-6006">GEOS-6006</a> * </p> * * @author Tom Kunicki, Boundless */ public class AnimatorFilter implements GeoServerFilter { private static final Logger LOGGER = Logging.getLogger(AnimatorFilter.class); private final static String ENDPOINT = "animate"; private final static String REQUEST = "Request"; private final static String GETMAP = "GetMap"; /** * * @param config * @throws ServletException */ @Override public void init(FilterConfig config) throws ServletException { // nothing to do } /** * Removes KVP argument <code>Request=GetMap</code> <i>(case independent)</i> if present * for calls against <code>.../animate</code> service endpoints. * * @param request current HTTP request * @param response current HTTP response * @param chain currently executing filter chain * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request instanceof HttpServletRequest) { HttpServletRequest requestHTTP = (HttpServletRequest)request; if (requestNeedsWrapper(requestHTTP)) { LOGGER.log(Level.FINER, "Modified request to {0}, removed \"Request\" KVP argument (GEOS-6006)", requestHTTP.getRequestURI()); request = new RequestWrapper(requestHTTP); } } chain.doFilter(request, response); } /** * */ @Override public void destroy() { // nothing to do... } private boolean requestNeedsWrapper(HttpServletRequest request) { if (request.getRequestURI().endsWith(ENDPOINT)) { Enumeration<String> names = request.getParameterNames(); while (names.hasMoreElements()) { String name = names.nextElement(); if (REQUEST.equalsIgnoreCase(name) && GETMAP.equalsIgnoreCase(request.getParameter(name))) { return true; } } } return false; } private static class RequestWrapper extends HttpServletRequestWrapper { private RequestWrapper(HttpServletRequest wrapped) { super(wrapped); } @Override public Enumeration getParameterNames() { return Collections.enumeration(getParameterMap().keySet()); } @Override public Map<String,String[]> getParameterMap() { Map<String, String[]> original = super.getParameterMap(); Map filtered = new HashMap<String, String[]>(); for (Map.Entry<String, String[]> entry : original.entrySet()) { String key = entry.getKey(); if (!REQUEST.equalsIgnoreCase(key)) { filtered.put(key, entry.getValue()); } } return filtered; } @Override public String[] getParameterValues(String name) { if (REQUEST.equalsIgnoreCase(name)) { return null; } return super.getParameterValues(name); } @Override public String getParameter(String name) { if (REQUEST.equalsIgnoreCase(name)) { return null; } return super.getParameter(name); } } }