/** * This file Copyright (c) 2010-2012 Magnolia International * Ltd. (http://www.magnolia-cms.com). All rights reserved. * * * This file is dual-licensed under both the Magnolia * Network Agreement and the GNU General Public License. * You may elect to use one or the other of these licenses. * * This file is distributed in the hope that it will be * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT. * Redistribution, except as permitted by whichever of the GPL * or MNA you select, is prohibited. * * 1. For the GPL license (GPL), you can redistribute and/or * modify this file under the terms of the GNU General * Public License, Version 3, as published by the Free Software * Foundation. You should have received a copy of the GNU * General Public License, Version 3 along with this program; * if not, write to the Free Software Foundation, Inc., 51 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * 2. For the Magnolia Network Agreement (MNA), this file * and the accompanying materials are made available under the * terms of the MNA which accompanies this distribution, and * is available at http://www.magnolia-cms.com/mna.html * * Any modifications to this file must keep this entire header * intact. * */ package info.magnolia.cms.util; import java.util.Enumeration; import java.util.LinkedHashMap; import javax.servlet.FilterConfig; import javax.servlet.ServletConfig; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestWrapper; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; /** * Utility methods for operations related to Servlet API. * * @author tmattsson * @see info.magnolia.cms.util.RequestHeaderUtil */ public abstract class ServletUtil { public static final String FORWARD_REQUEST_URI_ATTRIBUTE = "javax.servlet.forward.request_uri"; public static final String FORWARD_QUERY_STRING_ATTRIBUTE = "javax.servlet.forward.query_string"; public static final String INCLUDE_REQUEST_URI_ATTRIBUTE = "javax.servlet.include.request_uri"; public static final String ERROR_REQUEST_STATUS_CODE_ATTRIBUTE = "javax.servlet.error.status_code"; /** * Returns the init parameters for a {@link javax.servlet.ServletConfig} object as a Map, preserving the order in which they are exposed * by the {@link javax.servlet.ServletConfig} object. */ public static LinkedHashMap<String, String> initParametersToMap(ServletConfig config) { LinkedHashMap<String, String> initParameters = new LinkedHashMap<String, String>(); Enumeration parameterNames = config.getInitParameterNames(); while (parameterNames.hasMoreElements()) { String parameterName = (String) parameterNames.nextElement(); initParameters.put(parameterName, config.getInitParameter(parameterName)); } return initParameters; } /** * Returns the init parameters for a {@link javax.servlet.FilterConfig} object as a Map, preserving the order in which they are exposed * by the {@link javax.servlet.FilterConfig} object. */ public static LinkedHashMap<String, String> initParametersToMap(FilterConfig config) { LinkedHashMap<String, String> initParameters = new LinkedHashMap<String, String>(); Enumeration parameterNames = config.getInitParameterNames(); while (parameterNames.hasMoreElements()) { String parameterName = (String) parameterNames.nextElement(); initParameters.put(parameterName, config.getInitParameter(parameterName)); } return initParameters; } /** * Finds a request wrapper object inside the chain of request wrappers. */ public static <T extends ServletRequest> T getWrappedRequest(ServletRequest request, Class<T> clazz) { while (request != null) { if (clazz.isAssignableFrom(request.getClass())) { return (T) request; } request = (request instanceof ServletRequestWrapper) ? ((ServletRequestWrapper) request).getRequest() : null; } return null; } /** * Returns true if the request has a content type that indicates that is a multipart request. */ public static boolean isMultipart(HttpServletRequest request) { String contentType = request.getContentType(); return contentType != null && contentType.toLowerCase().startsWith("multipart/"); } /** * Returns true if the request is currently processing a forward operation. This method will return false after * an include operation has begun and will return true after that include operations has completed. */ public static boolean isForward(HttpServletRequest request) { return request.getAttribute(FORWARD_REQUEST_URI_ATTRIBUTE) != null && !isInclude(request); } /** * Returns true if the request is currently processing an include operation. */ public static boolean isInclude(HttpServletRequest request) { return request.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE) != null; } /** * Returns true if the request is rendering an error page, either due to a call to sendError() or an exception * being thrown in a filter or a servlet that reached the container. Will return true also after an include() or * forward() while rendering the error page. */ public static boolean isError(HttpServletRequest request) { return request.getAttribute(ERROR_REQUEST_STATUS_CODE_ATTRIBUTE) != null; } /** * Returns the dispatcher type of the request, the dispatcher type is defined to be identical to the semantics of * filter mappings in web.xml. */ public static DispatcherType getDispatcherType(HttpServletRequest request) { // The order of these tests is important. if (request.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE) != null) { return DispatcherType.INCLUDE; } if (request.getAttribute(FORWARD_REQUEST_URI_ATTRIBUTE) != null) { return DispatcherType.FORWARD; } if (request.getAttribute(ERROR_REQUEST_STATUS_CODE_ATTRIBUTE) != null) { return DispatcherType.ERROR; } return DispatcherType.REQUEST; } /** * Returns the original request uri. The If the request has been forwarded it finds the original request uri from * request attributes. The returned uri is not decoded. */ public static String getOriginalRequestURI(HttpServletRequest request) { if (request.getAttribute(FORWARD_REQUEST_URI_ATTRIBUTE) != null) { return (String) request.getAttribute(FORWARD_REQUEST_URI_ATTRIBUTE); } return request.getRequestURI(); } /** * Returns the original request url. If the request has been forwarded it reconstructs the url from request * attributes. The returned url is not decoded. */ public static String getOriginalRequestURLIncludingQueryString(HttpServletRequest request) { if (request.getAttribute(FORWARD_REQUEST_URI_ATTRIBUTE) != null) { StringBuilder builder = new StringBuilder(); String scheme = request.getScheme(); builder.append(scheme).append("://").append(request.getServerName()); int port = request.getServerPort(); if ((scheme.equalsIgnoreCase("http") && port == 80) || (scheme.equalsIgnoreCase("https") && port == 443)) { // adding port is not necessary } else { builder.append(":").append(port); } String requestUri = (String) request.getAttribute(FORWARD_REQUEST_URI_ATTRIBUTE); builder.append(requestUri); String queryString = (String) request.getAttribute(FORWARD_QUERY_STRING_ATTRIBUTE); if (StringUtils.isNotEmpty(queryString)) { builder.append("?").append(queryString); } return builder.toString(); } StringBuilder builder = new StringBuilder(); builder.append(request.getRequestURL()); String queryString = request.getQueryString(); if (StringUtils.isNotEmpty(queryString)) { builder.append("?").append(queryString); } return builder.toString(); } /** * Returns the request uri for the request. If the request is an include it will return the uri being included. The * returned uri is not decoded. */ public static String getRequestUri(HttpServletRequest request) { if (request.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE) != null) return (String) request.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE); return request.getRequestURI(); } }