001: /*
002: * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: */
007: package winstone.auth;
008:
009: import java.io.BufferedReader;
010: import java.io.IOException;
011: import java.io.InputStreamReader;
012: import java.io.UnsupportedEncodingException;
013: import java.text.DateFormat;
014: import java.text.SimpleDateFormat;
015: import java.util.Collections;
016: import java.util.Enumeration;
017: import java.util.HashMap;
018: import java.util.Hashtable;
019: import java.util.Locale;
020: import java.util.Map;
021: import java.util.TimeZone;
022: import java.util.Vector;
023:
024: import javax.servlet.ServletInputStream;
025: import javax.servlet.http.HttpServletRequest;
026: import javax.servlet.http.HttpServletRequestWrapper;
027:
028: import winstone.Launcher;
029: import winstone.Logger;
030: import winstone.WinstoneException;
031: import winstone.WinstoneInputStream;
032: import winstone.WinstoneRequest;
033:
034: /**
035: * This is used by the ACL filter to allow a retry by using a key lookup
036: * on old request. It's only used when retrying an old request that was blocked
037: * by the ACL filter.
038: *
039: * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
040: * @version $Id: RetryRequestWrapper.java,v 1.3 2007/02/26 00:28:05 rickknowles Exp $
041: */
042: public class RetryRequestWrapper extends HttpServletRequestWrapper {
043: protected static final DateFormat headerDF = new SimpleDateFormat(
044: "EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
045:
046: static {
047: headerDF.setTimeZone(TimeZone.getTimeZone("GMT"));
048: }
049:
050: private final static String METHOD_HEAD = "GET";
051: private final static String METHOD_GET = "GET";
052: private final static String METHOD_POST = "POST";
053: private final static String POST_PARAMETERS = "application/x-www-form-urlencoded";
054:
055: private RetryRequestParams oldRequest;
056:
057: // PARAMETER/BODY RELATED FUNCTIONS
058: private String encoding;
059: private Map parsedParams;
060: private ServletInputStream inData;
061:
062: /**
063: * Constructor - this populates the wrapper from the object in session
064: */
065: public RetryRequestWrapper(HttpServletRequest request,
066: RetryRequestParams oldRequest) throws IOException {
067: super (request);
068: this .oldRequest = oldRequest;
069: this .encoding = this .oldRequest.getEncoding();
070: }
071:
072: private boolean hasBeenForwarded() {
073: return (super .getAttribute("javax.servlet.forward.request_uri") != null);
074: }
075:
076: public String getScheme() {
077: if (hasBeenForwarded()) {
078: return super .getScheme();
079: } else {
080: return this .oldRequest.getScheme();
081: }
082: }
083:
084: public String getMethod() {
085: if (hasBeenForwarded()) {
086: return super .getMethod();
087: } else {
088: return this .oldRequest.getMethod();
089: }
090: }
091:
092: public String getContextPath() {
093: if (hasBeenForwarded()) {
094: return super .getContextPath();
095: } else {
096: return this .oldRequest.getContextPath();
097: }
098: }
099:
100: public String getServletPath() {
101: if (hasBeenForwarded()) {
102: return super .getServletPath();
103: } else {
104: return this .oldRequest.getServletPath();
105: }
106: }
107:
108: public String getPathInfo() {
109: if (hasBeenForwarded()) {
110: return super .getPathInfo();
111: } else {
112: return this .oldRequest.getPathInfo();
113: }
114: }
115:
116: public String getQueryString() {
117: if (hasBeenForwarded()) {
118: return super .getQueryString();
119: } else {
120: return this .oldRequest.getQueryString();
121: }
122: }
123:
124: public String getRequestURI() {
125: if (hasBeenForwarded()) {
126: return super .getRequestURI();
127: } else {
128: String contextPath = this .oldRequest.getContextPath();
129: String servletPath = this .oldRequest.getServletPath();
130: String pathInfo = this .oldRequest.getPathInfo();
131: String queryString = this .oldRequest.getQueryString();
132: return contextPath
133: + servletPath
134: + ((pathInfo == null) ? "" : pathInfo)
135: + ((queryString == null) ? "" : ("?" + queryString));
136: }
137: }
138:
139: public String getCharacterEncoding() {
140: if (hasBeenForwarded()) {
141: return super .getCharacterEncoding();
142: } else {
143: return this .oldRequest.getEncoding();
144: }
145: }
146:
147: public void setCharacterEncoding(String encoding)
148: throws UnsupportedEncodingException {
149: if (hasBeenForwarded()) {
150: super .setCharacterEncoding(encoding);
151: } else {
152: this .encoding = encoding;
153: }
154: }
155:
156: public int getContentLength() {
157: if (hasBeenForwarded()) {
158: return super .getContentLength();
159: } else {
160: return this .oldRequest.getContentLength();
161: }
162: }
163:
164: public String getContentType() {
165: if (hasBeenForwarded()) {
166: return super .getContentType();
167: } else {
168: return this .oldRequest.getContentType();
169: }
170: }
171:
172: public Locale getLocale() {
173: if (hasBeenForwarded()) {
174: return super .getLocale();
175: } else {
176: return this .oldRequest.getLocale();
177: }
178: }
179:
180: public Enumeration getLocales() {
181: if (hasBeenForwarded()) {
182: return super .getLocales();
183: } else {
184: return this .oldRequest.getLocales().elements();
185: }
186: }
187:
188: // -------------------------------------------------------------------
189: // HEADER RELATED FUNCTIONS
190: public long getDateHeader(String name) {
191: if (hasBeenForwarded()) {
192: return super .getDateHeader(name);
193: } else {
194: String dateHeader = getHeader(name);
195: if (dateHeader == null) {
196: return -1;
197: } else {
198: try {
199: synchronized (headerDF) {
200: return headerDF.parse(dateHeader).getTime();
201: }
202: } catch (java.text.ParseException err) {
203: throw new IllegalArgumentException(
204: "Illegal date format: " + dateHeader);
205: }
206: }
207: }
208: }
209:
210: public int getIntHeader(String name) {
211: if (hasBeenForwarded()) {
212: return super .getIntHeader(name);
213: } else {
214: String header = getHeader(name);
215: return header == null ? -1 : Integer.parseInt(header);
216: }
217: }
218:
219: public String getHeader(String name) {
220: if (hasBeenForwarded()) {
221: return super .getHeader(name);
222: } else {
223: Enumeration e = getHeaders(name);
224: return (e != null) && e.hasMoreElements() ? (String) e
225: .nextElement() : null;
226: }
227: }
228:
229: public Enumeration getHeaderNames() {
230: if (hasBeenForwarded()) {
231: return super .getHeaderNames();
232: } else {
233: return Collections.enumeration(this .oldRequest.getHeaders()
234: .keySet());
235: }
236: }
237:
238: public Enumeration getHeaders(String name) {
239: if (hasBeenForwarded()) {
240: return super .getHeaders(name);
241: } else {
242: Vector result = (Vector) this .oldRequest.getHeaders().get(
243: name.toLowerCase());
244: return result == null ? null : result.elements();
245: }
246: }
247:
248: public String getParameter(String name) {
249: if (hasBeenForwarded()) {
250: return super .getParameter(name);
251: } else {
252: parseRequestParameters();
253: Object param = this .parsedParams.get(name);
254: if (param == null) {
255: return null;
256: } else if (param instanceof String) {
257: return (String) param;
258: } else if (param instanceof String[]) {
259: return ((String[]) param)[0];
260: } else {
261: return param.toString();
262: }
263: }
264: }
265:
266: public Enumeration getParameterNames() {
267: if (hasBeenForwarded()) {
268: return super .getParameterNames();
269: } else {
270: parseRequestParameters();
271: return Collections.enumeration(this .parsedParams.keySet());
272: }
273: }
274:
275: public String[] getParameterValues(String name) {
276: if (hasBeenForwarded()) {
277: return super .getParameterValues(name);
278: } else {
279: parseRequestParameters();
280: Object param = this .parsedParams.get(name);
281: if (param == null) {
282: return null;
283: } else if (param instanceof String) {
284: return new String[] { (String) param };
285: } else if (param instanceof String[]) {
286: return (String[]) param;
287: } else {
288: throw new WinstoneException(Launcher.RESOURCES
289: .getString(
290: "WinstoneRequest.UnknownParameterType",
291: name + " - " + param.getClass()));
292: }
293: }
294: }
295:
296: public Map getParameterMap() {
297: if (hasBeenForwarded()) {
298: return super .getParameterMap();
299: } else {
300: Hashtable paramMap = new Hashtable();
301: for (Enumeration names = this .getParameterNames(); names
302: .hasMoreElements();) {
303: String name = (String) names.nextElement();
304: paramMap.put(name, getParameterValues(name));
305: }
306: return paramMap;
307: }
308: }
309:
310: public BufferedReader getReader() throws IOException {
311: if (hasBeenForwarded()) {
312: return super .getReader();
313: } else if (getCharacterEncoding() != null) {
314: return new BufferedReader(new InputStreamReader(
315: getInputStream(), this .encoding));
316: } else {
317: return new BufferedReader(new InputStreamReader(
318: getInputStream()));
319: }
320: }
321:
322: public ServletInputStream getInputStream() throws IOException {
323: if (hasBeenForwarded()) {
324: return super .getInputStream();
325: } else if (this .parsedParams != null) {
326: Logger.log(Logger.WARNING, Launcher.RESOURCES,
327: "WinstoneRequest.BothMethods");
328: }
329:
330: if (this .inData == null) {
331: this .inData = new WinstoneInputStream(this .oldRequest
332: .getBodyContent());
333: }
334:
335: return this .inData;
336: }
337:
338: // -------------------------------------------------------------------
339:
340: /**
341: * This takes the parameters in the body of the request and puts them into
342: * the parameters map.
343: */
344: private void parseRequestParameters() {
345: if (inData != null) {
346: Logger.log(Logger.WARNING, Launcher.RESOURCES,
347: "WinstoneRequest.BothMethods");
348: }
349:
350: if (this .parsedParams == null) {
351: String contentType = this .oldRequest.getContentType();
352: String queryString = this .oldRequest.getQueryString();
353: String method = this .oldRequest.getMethod();
354: Map workingParameters = new HashMap();
355: try {
356: // Parse query string from request
357: if ((method.equals(METHOD_GET)
358: || method.equals(METHOD_HEAD) || method
359: .equals(METHOD_POST))
360: && (queryString != null)) {
361: WinstoneRequest.extractParameters(queryString,
362: this .encoding, workingParameters, false);
363: }
364:
365: if (method.equals(METHOD_POST)
366: && (contentType != null)
367: && (contentType.equals(POST_PARAMETERS) || contentType
368: .startsWith(POST_PARAMETERS + ";"))) {
369: // Parse params
370: String paramLine = (this .encoding == null ? new String(
371: this .oldRequest.getBodyContent())
372: : new String(this .oldRequest
373: .getBodyContent(), this .encoding));
374: WinstoneRequest.extractParameters(paramLine.trim(),
375: this .encoding, workingParameters, false);
376: }
377:
378: this .parsedParams = workingParameters;
379: } catch (UnsupportedEncodingException err) {
380: Logger.log(Logger.ERROR, Launcher.RESOURCES,
381: "WinstoneRequest.ErrorBodyParameters", err);
382: this.parsedParams = null;
383: }
384: }
385: }
386: }
|