/* * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net> * Distributed under the terms of either: * - the common development and distribution license (CDDL), v1.0; or * - the GNU Lesser General Public License, v2.1 or later */ package winstone.auth; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.Locale; import java.util.Map; import java.util.TimeZone; import java.util.Vector; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import winstone.Launcher; import winstone.Logger; import winstone.WinstoneException; import winstone.WinstoneInputStream; import winstone.WinstoneRequest; /** * This is used by the ACL filter to allow a retry by using a key lookup * on old request. It's only used when retrying an old request that was blocked * by the ACL filter. * * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a> * @version $Id: RetryRequestWrapper.java,v 1.3 2007/02/26 00:28:05 rickknowles Exp $ */ public class RetryRequestWrapper extends HttpServletRequestWrapper { protected static final DateFormat headerDF = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); static { headerDF.setTimeZone(TimeZone.getTimeZone("GMT")); } private final static String METHOD_HEAD = "GET"; private final static String METHOD_GET = "GET"; private final static String METHOD_POST = "POST"; private final static String POST_PARAMETERS = "application/x-www-form-urlencoded"; private RetryRequestParams oldRequest; // PARAMETER/BODY RELATED FUNCTIONS private String encoding; private Map parsedParams; private ServletInputStream inData; /** * Constructor - this populates the wrapper from the object in session */ public RetryRequestWrapper(HttpServletRequest request, RetryRequestParams oldRequest) throws IOException { super(request); this.oldRequest = oldRequest; this.encoding = this.oldRequest.getEncoding(); } private boolean hasBeenForwarded() { return (super.getAttribute("javax.servlet.forward.request_uri") != null); } public String getScheme() { if (hasBeenForwarded()) { return super.getScheme(); } else { return this.oldRequest.getScheme(); } } public String getMethod() { if (hasBeenForwarded()) { return super.getMethod(); } else { return this.oldRequest.getMethod(); } } public String getContextPath() { if (hasBeenForwarded()) { return super.getContextPath(); } else { return this.oldRequest.getContextPath(); } } public String getServletPath() { if (hasBeenForwarded()) { return super.getServletPath(); } else { return this.oldRequest.getServletPath(); } } public String getPathInfo() { if (hasBeenForwarded()) { return super.getPathInfo(); } else { return this.oldRequest.getPathInfo(); } } public String getQueryString() { if (hasBeenForwarded()) { return super.getQueryString(); } else { return this.oldRequest.getQueryString(); } } public String getRequestURI() { if (hasBeenForwarded()) { return super.getRequestURI(); } else { String contextPath = this.oldRequest.getContextPath(); String servletPath = this.oldRequest.getServletPath(); String pathInfo = this.oldRequest.getPathInfo(); String queryString = this.oldRequest.getQueryString(); return contextPath + servletPath + ((pathInfo == null) ? "" : pathInfo) + ((queryString == null) ? "" : ("?" + queryString)); } } public String getCharacterEncoding() { if (hasBeenForwarded()) { return super.getCharacterEncoding(); } else { return this.oldRequest.getEncoding(); } } public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException { if (hasBeenForwarded()) { super.setCharacterEncoding(encoding); } else { this.encoding = encoding; } } public int getContentLength() { if (hasBeenForwarded()) { return super.getContentLength(); } else { return this.oldRequest.getContentLength(); } } public String getContentType() { if (hasBeenForwarded()) { return super.getContentType(); } else { return this.oldRequest.getContentType(); } } public Locale getLocale() { if (hasBeenForwarded()) { return super.getLocale(); } else { return this.oldRequest.getLocale(); } } public Enumeration getLocales() { if (hasBeenForwarded()) { return super.getLocales(); } else { return this.oldRequest.getLocales().elements(); } } // ------------------------------------------------------------------- // HEADER RELATED FUNCTIONS public long getDateHeader(String name) { if (hasBeenForwarded()) { return super.getDateHeader(name); } else { String dateHeader = getHeader(name); if (dateHeader == null) { return -1; } else { try { synchronized (headerDF) { return headerDF.parse(dateHeader).getTime(); } } catch (java.text.ParseException err) { throw new IllegalArgumentException("Illegal date format: " + dateHeader); } } } } public int getIntHeader(String name) { if (hasBeenForwarded()) { return super.getIntHeader(name); } else { String header = getHeader(name); return header == null ? -1 : Integer.parseInt(header); } } public String getHeader(String name) { if (hasBeenForwarded()) { return super.getHeader(name); } else { Enumeration e = getHeaders(name); return (e != null) && e.hasMoreElements() ? (String) e.nextElement() : null; } } public Enumeration getHeaderNames() { if (hasBeenForwarded()) { return super.getHeaderNames(); } else { return Collections.enumeration(this.oldRequest.getHeaders().keySet()); } } public Enumeration getHeaders(String name) { if (hasBeenForwarded()) { return super.getHeaders(name); } else { Vector result = (Vector) this.oldRequest.getHeaders().get(name.toLowerCase()); return result == null ? null : result.elements(); } } public String getParameter(String name) { if (hasBeenForwarded()) { return super.getParameter(name); } else { parseRequestParameters(); Object param = this.parsedParams.get(name); if (param == null) { return null; } else if (param instanceof String) { return (String) param; } else if (param instanceof String[]) { return ((String[]) param)[0]; } else { return param.toString(); } } } public Enumeration getParameterNames() { if (hasBeenForwarded()) { return super.getParameterNames(); } else { parseRequestParameters(); return Collections.enumeration(this.parsedParams.keySet()); } } public String[] getParameterValues(String name) { if (hasBeenForwarded()) { return super.getParameterValues(name); } else { parseRequestParameters(); Object param = this.parsedParams.get(name); if (param == null) { return null; } else if (param instanceof String) { return new String[] {(String) param}; } else if (param instanceof String[]) { return (String[]) param; } else { throw new WinstoneException(Launcher.RESOURCES.getString( "WinstoneRequest.UnknownParameterType", name + " - " + param.getClass())); } } } public Map getParameterMap() { if (hasBeenForwarded()) { return super.getParameterMap(); } else { Hashtable paramMap = new Hashtable(); for (Enumeration names = this.getParameterNames(); names.hasMoreElements();) { String name = (String) names.nextElement(); paramMap.put(name, getParameterValues(name)); } return paramMap; } } public BufferedReader getReader() throws IOException { if (hasBeenForwarded()) { return super.getReader(); } else if (getCharacterEncoding() != null) { return new BufferedReader(new InputStreamReader(getInputStream(), this.encoding)); } else { return new BufferedReader(new InputStreamReader(getInputStream())); } } public ServletInputStream getInputStream() throws IOException { if (hasBeenForwarded()) { return super.getInputStream(); } else if (this.parsedParams != null) { Logger.log(Logger.WARNING, Launcher.RESOURCES, "WinstoneRequest.BothMethods"); } if (this.inData == null) { this.inData = new WinstoneInputStream(this.oldRequest.getBodyContent()); } return this.inData; } // ------------------------------------------------------------------- /** * This takes the parameters in the body of the request and puts them into * the parameters map. */ private void parseRequestParameters() { if (inData != null) { Logger.log(Logger.WARNING, Launcher.RESOURCES, "WinstoneRequest.BothMethods"); } if (this.parsedParams == null) { String contentType = this.oldRequest.getContentType(); String queryString = this.oldRequest.getQueryString(); String method = this.oldRequest.getMethod(); Map workingParameters = new HashMap(); try { // Parse query string from request if ((method.equals(METHOD_GET) || method.equals(METHOD_HEAD) || method.equals(METHOD_POST)) && (queryString != null)) { WinstoneRequest.extractParameters(queryString, this.encoding, workingParameters, false); } if (method.equals(METHOD_POST) && (contentType != null) && (contentType.equals(POST_PARAMETERS) || contentType.startsWith(POST_PARAMETERS + ";"))) { // Parse params String paramLine = (this.encoding == null ? new String(this.oldRequest.getBodyContent()) : new String(this.oldRequest.getBodyContent(), this.encoding)); WinstoneRequest.extractParameters(paramLine.trim(), this.encoding, workingParameters, false); } this.parsedParams = workingParameters; } catch (UnsupportedEncodingException err) { Logger.log(Logger.ERROR, Launcher.RESOURCES, "WinstoneRequest.ErrorBodyParameters", err); this.parsedParams = null; } } } }