0001: /*
0002: * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/HttpRequestBase.java,v 1.39 2002/04/22 00:00:50 glenn Exp $
0003: * $Revision: 1.39 $
0004: * $Date: 2002/04/22 00:00:50 $
0005: *
0006: * ====================================================================
0007: *
0008: * The Apache Software License, Version 1.1
0009: *
0010: * Copyright (c) 1999 The Apache Software Foundation. All rights
0011: * reserved.
0012: *
0013: * Redistribution and use in source and binary forms, with or without
0014: * modification, are permitted provided that the following conditions
0015: * are met:
0016: *
0017: * 1. Redistributions of source code must retain the above copyright
0018: * notice, this list of conditions and the following disclaimer.
0019: *
0020: * 2. Redistributions in binary form must reproduce the above copyright
0021: * notice, this list of conditions and the following disclaimer in
0022: * the documentation and/or other materials provided with the
0023: * distribution.
0024: *
0025: * 3. The end-user documentation included with the redistribution, if
0026: * any, must include the following acknowlegement:
0027: * "This product includes software developed by the
0028: * Apache Software Foundation (http://www.apache.org/)."
0029: * Alternately, this acknowlegement may appear in the software itself,
0030: * if and wherever such third-party acknowlegements normally appear.
0031: *
0032: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
0033: * Foundation" must not be used to endorse or promote products derived
0034: * from this software without prior written permission. For written
0035: * permission, please contact apache@apache.org.
0036: *
0037: * 5. Products derived from this software may not be called "Apache"
0038: * nor may "Apache" appear in their names without prior written
0039: * permission of the Apache Group.
0040: *
0041: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0042: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0043: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0044: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0045: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0046: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0047: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0048: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0049: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0050: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0051: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0052: * SUCH DAMAGE.
0053: * ====================================================================
0054: *
0055: * This software consists of voluntary contributions made by many
0056: * individuals on behalf of the Apache Software Foundation. For more
0057: * information on the Apache Software Foundation, please see
0058: * <http://www.apache.org/>.
0059: *
0060: * [Additional notices, if required by prior licensing conditions]
0061: *
0062: */
0063:
0064: package org.apache.catalina.connector;
0065:
0066: import java.io.IOException;
0067: import java.io.UnsupportedEncodingException;
0068: import java.security.AccessController;
0069: import java.security.Principal;
0070: import java.security.PrivilegedAction;
0071: import java.text.ParseException;
0072: import java.text.SimpleDateFormat;
0073: import java.util.ArrayList;
0074: import java.util.Date;
0075: import java.util.Enumeration;
0076: import java.util.HashMap;
0077: import java.util.Hashtable;
0078: import java.util.Locale;
0079: import java.util.Map;
0080: import javax.servlet.RequestDispatcher;
0081: import javax.servlet.ServletRequest;
0082: import javax.servlet.ServletInputStream;
0083: import javax.servlet.http.Cookie;
0084: import javax.servlet.http.HttpServletRequest;
0085: import javax.servlet.http.HttpSession;
0086: import org.apache.catalina.Globals;
0087: import org.apache.catalina.HttpRequest;
0088: import org.apache.catalina.Logger;
0089: import org.apache.catalina.Manager;
0090: import org.apache.catalina.Realm;
0091: import org.apache.catalina.Session;
0092: import org.apache.catalina.util.Enumerator;
0093: import org.apache.catalina.util.ParameterMap;
0094: import org.apache.catalina.util.RequestUtil;
0095: import org.apache.catalina.util.StringParser;
0096:
0097: /**
0098: * Convenience base implementation of the <b>HttpRequest</b> interface, which
0099: * can be used for the Request implementation required by most Connectors that
0100: * implement the HTTP protocol. Only the connector-specific methods need to
0101: * be implemented.
0102: *
0103: * @author Craig R. McClanahan
0104: * @version $Revision: 1.39 $ $Date: 2002/04/22 00:00:50 $
0105: * @deprecated
0106: */
0107:
0108: public class HttpRequestBase extends RequestBase implements
0109: HttpRequest, HttpServletRequest {
0110:
0111: protected class PrivilegedGetSession implements PrivilegedAction {
0112:
0113: private boolean create;
0114:
0115: PrivilegedGetSession(boolean create) {
0116: this .create = create;
0117: }
0118:
0119: public Object run() {
0120: return doGetSession(create);
0121: }
0122:
0123: }
0124:
0125: // ----------------------------------------------------- Instance Variables
0126:
0127: /**
0128: * The authentication type used for this request.
0129: */
0130: protected String authType = null;
0131:
0132: /**
0133: * The context path for this request.
0134: */
0135: protected String contextPath = "";
0136:
0137: /**
0138: * The set of cookies associated with this Request.
0139: */
0140: protected ArrayList cookies = new ArrayList();
0141:
0142: /**
0143: * An empty collection to use for returning empty Enumerations. Do not
0144: * add any elements to this collection!
0145: */
0146: protected static ArrayList empty = new ArrayList();
0147:
0148: /**
0149: * The set of SimpleDateFormat formats to use in getDateHeader().
0150: */
0151: protected SimpleDateFormat formats[] = {
0152: new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz",
0153: Locale.US),
0154: new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz",
0155: Locale.US),
0156: new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US) };
0157:
0158: /**
0159: * The facade associated with this request.
0160: */
0161: protected HttpRequestFacade facade = new HttpRequestFacade(this );
0162:
0163: /**
0164: * The HTTP headers associated with this Request, keyed by name. The
0165: * values are ArrayLists of the corresponding header values.
0166: */
0167: protected HashMap headers = new HashMap();
0168:
0169: /**
0170: * Descriptive information about this HttpRequest implementation.
0171: */
0172: protected static final String info = "org.apache.catalina.connector.HttpRequestBase/1.0";
0173:
0174: /**
0175: * The request method associated with this Request.
0176: */
0177: protected String method = null;
0178:
0179: /**
0180: * The parsed parameters for this request. This is populated only if
0181: * parameter information is requested via one of the
0182: * <code>getParameter()</code> family of method calls. The key is the
0183: * parameter name, while the value is a String array of values for this
0184: * parameter.
0185: * <p>
0186: * <strong>IMPLEMENTATION NOTE</strong> - Once the parameters for a
0187: * particular request are parsed and stored here, they are not modified.
0188: * Therefore, application level access to the parameters need not be
0189: * synchronized.
0190: */
0191: protected ParameterMap parameters = null;
0192:
0193: /**
0194: * Have the parameters for this request been parsed yet?
0195: */
0196: protected boolean parsed = false;
0197:
0198: /**
0199: * The path information for this request.
0200: */
0201: protected String pathInfo = null;
0202:
0203: /**
0204: * The query string for this request.
0205: */
0206: protected String queryString = null;
0207:
0208: /**
0209: * Was the requested session ID received in a cookie?
0210: */
0211: protected boolean requestedSessionCookie = false;
0212:
0213: /**
0214: * The requested session ID (if any) for this request.
0215: */
0216: protected String requestedSessionId = null;
0217:
0218: /**
0219: * Was the requested session ID received in a URL?
0220: */
0221: protected boolean requestedSessionURL = false;
0222:
0223: /**
0224: * The request URI associated with this request.
0225: */
0226: protected String requestURI = null;
0227:
0228: /**
0229: * The decoded request URI associated with this request.
0230: */
0231: protected String decodedRequestURI = null;
0232:
0233: /**
0234: * Was this request received on a secure channel?
0235: */
0236: protected boolean secure = false;
0237:
0238: /**
0239: * The servlet path for this request.
0240: */
0241: protected String servletPath = null;
0242:
0243: /**
0244: * The currently active session for this request.
0245: */
0246: protected Session session = null;
0247:
0248: /**
0249: * The Principal who has been authenticated for this Request.
0250: */
0251: protected Principal userPrincipal = null;
0252:
0253: // ------------------------------------------------------------- Properties
0254:
0255: /**
0256: * Return descriptive information about this Request implementation and
0257: * the corresponding version number, in the format
0258: * <code><description>/<version></code>.
0259: */
0260: public String getInfo() {
0261:
0262: return (info);
0263:
0264: }
0265:
0266: /**
0267: * Return the <code>ServletRequest</code> for which this object
0268: * is the facade. This method must be implemented by a subclass.
0269: */
0270: public ServletRequest getRequest() {
0271:
0272: return (facade);
0273:
0274: }
0275:
0276: // --------------------------------------------------------- Public Methods
0277:
0278: /**
0279: * Add a Cookie to the set of Cookies associated with this Request.
0280: *
0281: * @param cookie The new cookie
0282: */
0283: public void addCookie(Cookie cookie) {
0284:
0285: synchronized (cookies) {
0286: cookies.add(cookie);
0287: }
0288:
0289: }
0290:
0291: /**
0292: * Add a Header to the set of Headers associated with this Request.
0293: *
0294: * @param name The new header name
0295: * @param value The new header value
0296: */
0297: public void addHeader(String name, String value) {
0298:
0299: name = name.toLowerCase();
0300: synchronized (headers) {
0301: ArrayList values = (ArrayList) headers.get(name);
0302: if (values == null) {
0303: values = new ArrayList();
0304: headers.put(name, values);
0305: }
0306: values.add(value);
0307: }
0308:
0309: }
0310:
0311: /**
0312: * Add a parameter name and corresponding set of values to this Request.
0313: * (This is used when restoring the original request on a form based
0314: * login).
0315: *
0316: * @param name Name of this request parameter
0317: * @param values Corresponding values for this request parameter
0318: */
0319: public void addParameter(String name, String values[]) {
0320:
0321: synchronized (parameters) {
0322: parameters.put(name, values);
0323: }
0324:
0325: }
0326:
0327: /**
0328: * Clear the collection of Cookies associated with this Request.
0329: */
0330: public void clearCookies() {
0331:
0332: synchronized (cookies) {
0333: cookies.clear();
0334: }
0335:
0336: }
0337:
0338: /**
0339: * Clear the collection of Headers associated with this Request.
0340: */
0341: public void clearHeaders() {
0342:
0343: headers.clear();
0344:
0345: }
0346:
0347: /**
0348: * Clear the collection of Locales associated with this Request.
0349: */
0350: public void clearLocales() {
0351:
0352: locales.clear();
0353:
0354: }
0355:
0356: /**
0357: * Clear the collection of parameters associated with this Request.
0358: */
0359: public void clearParameters() {
0360:
0361: if (parameters != null) {
0362: parameters.setLocked(false);
0363: parameters.clear();
0364: } else {
0365: parameters = new ParameterMap();
0366: }
0367:
0368: }
0369:
0370: /**
0371: * Release all object references, and initialize instance variables, in
0372: * preparation for reuse of this object.
0373: */
0374: public void recycle() {
0375:
0376: super .recycle();
0377: authType = null;
0378: contextPath = "";
0379: cookies.clear();
0380: headers.clear();
0381: method = null;
0382: if (parameters != null) {
0383: parameters.setLocked(false);
0384: parameters.clear();
0385: }
0386: parsed = false;
0387: pathInfo = null;
0388: queryString = null;
0389: requestedSessionCookie = false;
0390: requestedSessionId = null;
0391: requestedSessionURL = false;
0392: requestURI = null;
0393: decodedRequestURI = null;
0394: secure = false;
0395: servletPath = null;
0396: session = null;
0397: userPrincipal = null;
0398:
0399: }
0400:
0401: /**
0402: * Set the authentication type used for this request, if any; otherwise
0403: * set the type to <code>null</code>. Typical values are "BASIC",
0404: * "DIGEST", or "SSL".
0405: *
0406: * @param authType The authentication type used
0407: */
0408: public void setAuthType(String authType) {
0409:
0410: this .authType = authType;
0411:
0412: }
0413:
0414: /**
0415: * Set the context path for this Request. This will normally be called
0416: * when the associated Context is mapping the Request to a particular
0417: * Wrapper.
0418: *
0419: * @param path The context path
0420: */
0421: public void setContextPath(String path) {
0422:
0423: if (path == null)
0424: this .contextPath = "";
0425: else
0426: this .contextPath = path;
0427:
0428: }
0429:
0430: /**
0431: * Set the HTTP request method used for this Request.
0432: *
0433: * @param method The request method
0434: */
0435: public void setMethod(String method) {
0436:
0437: this .method = method;
0438:
0439: }
0440:
0441: /**
0442: * Set the path information for this Request. This will normally be called
0443: * when the associated Context is mapping the Request to a particular
0444: * Wrapper.
0445: *
0446: * @param path The path information
0447: */
0448: public void setPathInfo(String path) {
0449:
0450: this .pathInfo = path;
0451:
0452: }
0453:
0454: /**
0455: * Set the query string for this Request. This will normally be called
0456: * by the HTTP Connector, when it parses the request headers.
0457: *
0458: * @param query The query string
0459: */
0460: public void setQueryString(String query) {
0461:
0462: this .queryString = query;
0463:
0464: }
0465:
0466: /**
0467: * Set a flag indicating whether or not the requested session ID for this
0468: * request came in through a cookie. This is normally called by the
0469: * HTTP Connector, when it parses the request headers.
0470: *
0471: * @param flag The new flag
0472: */
0473: public void setRequestedSessionCookie(boolean flag) {
0474:
0475: this .requestedSessionCookie = flag;
0476:
0477: }
0478:
0479: /**
0480: * Set the requested session ID for this request. This is normally called
0481: * by the HTTP Connector, when it parses the request headers.
0482: *
0483: * @param id The new session id
0484: */
0485: public void setRequestedSessionId(String id) {
0486:
0487: this .requestedSessionId = id;
0488:
0489: }
0490:
0491: /**
0492: * Set a flag indicating whether or not the requested session ID for this
0493: * request came in through a URL. This is normally called by the
0494: * HTTP Connector, when it parses the request headers.
0495: *
0496: * @param flag The new flag
0497: */
0498: public void setRequestedSessionURL(boolean flag) {
0499:
0500: this .requestedSessionURL = flag;
0501:
0502: }
0503:
0504: /**
0505: * Set the unparsed request URI for this Request. This will normally
0506: * be called by the HTTP Connector, when it parses the request headers.
0507: *
0508: * @param uri The request URI
0509: */
0510: public void setRequestURI(String uri) {
0511:
0512: this .requestURI = uri;
0513:
0514: }
0515:
0516: /**
0517: * Set the flag indicating whether this Request was received on a secure
0518: * communications link or not. This will normally be called by the HTTP
0519: * Connector, when it parses the request headers.
0520: *
0521: * @param secure The new secure flag
0522: */
0523: public void setSecure(boolean secure) {
0524:
0525: this .secure = secure;
0526:
0527: }
0528:
0529: /**
0530: * Set the servlet path for this Request. This will normally be called
0531: * when the associated Context is mapping the Request to a particular
0532: * Wrapper.
0533: *
0534: * @param path The servlet path
0535: */
0536: public void setServletPath(String path) {
0537:
0538: this .servletPath = path;
0539:
0540: }
0541:
0542: /**
0543: * Set the Principal who has been authenticated for this Request. This
0544: * value is also used to calculate the value to be returned by the
0545: * <code>getRemoteUser()</code> method.
0546: *
0547: * @param principal The user Principal
0548: */
0549: public void setUserPrincipal(Principal principal) {
0550:
0551: this .userPrincipal = principal;
0552:
0553: }
0554:
0555: // ------------------------------------------------------ Protected Methods
0556:
0557: /**
0558: * Parse the parameters of this request, if it has not already occurred.
0559: * If parameters are present in both the query string and the request
0560: * content, they are merged.
0561: */
0562: protected void parseParameters() {
0563:
0564: if (parsed)
0565: return;
0566:
0567: ParameterMap results = parameters;
0568: if (results == null)
0569: results = new ParameterMap();
0570: results.setLocked(false);
0571:
0572: String encoding = getCharacterEncoding();
0573: if (encoding == null)
0574: encoding = "ISO-8859-1";
0575:
0576: // Parse any parameters specified in the query string
0577: String queryString = getQueryString();
0578: try {
0579: RequestUtil.parseParameters(results, queryString, encoding);
0580: } catch (UnsupportedEncodingException e) {
0581: ;
0582: }
0583:
0584: // Parse any parameters specified in the input stream
0585: String contentType = getContentType();
0586: if (contentType == null)
0587: contentType = "";
0588: int semicolon = contentType.indexOf(';');
0589: if (semicolon >= 0) {
0590: contentType = contentType.substring(0, semicolon).trim();
0591: } else {
0592: contentType = contentType.trim();
0593: }
0594: if ("POST".equals(getMethod())
0595: && (getContentLength() > 0)
0596: && (this .stream == null)
0597: && "application/x-www-form-urlencoded"
0598: .equals(contentType)) {
0599:
0600: try {
0601: int max = getContentLength();
0602: int len = 0;
0603: byte buf[] = new byte[getContentLength()];
0604: ServletInputStream is = getInputStream();
0605: while (len < max) {
0606: int next = is.read(buf, len, max - len);
0607: if (next < 0) {
0608: break;
0609: }
0610: len += next;
0611: }
0612: is.close();
0613: if (len < max) {
0614: // FIX ME, mod_jk when sending an HTTP POST will sometimes
0615: // have an actual content length received < content length.
0616: // Checking for a read of -1 above prevents this code from
0617: // going into an infinite loop. But the bug must be in mod_jk.
0618: // Log additional data when this occurs to help debug mod_jk
0619: StringBuffer msg = new StringBuffer();
0620: msg
0621: .append("HttpRequestBase.parseParameters content length mismatch\n");
0622: msg.append(" URL: ");
0623: msg.append(getRequestURL());
0624: msg.append(" Content Length: ");
0625: msg.append(max);
0626: msg.append(" Read: ");
0627: msg.append(len);
0628: msg.append("\n Bytes Read: ");
0629: if (len > 0) {
0630: msg.append(new String(buf, 0, len));
0631: }
0632: log(msg.toString());
0633: throw new RuntimeException(
0634: sm
0635: .getString("httpRequestBase.contentLengthMismatch"));
0636: }
0637: RequestUtil.parseParameters(results, buf, encoding);
0638: } catch (UnsupportedEncodingException ue) {
0639: ;
0640: } catch (IOException e) {
0641: throw new RuntimeException(sm
0642: .getString("httpRequestBase.contentReadFail")
0643: + e.getMessage());
0644: }
0645: }
0646:
0647: // Store the final results
0648: results.setLocked(true);
0649: parsed = true;
0650: parameters = results;
0651:
0652: }
0653:
0654: // ------------------------------------------------- ServletRequest Methods
0655:
0656: /**
0657: * Return the value of the specified request parameter, if any; otherwise,
0658: * return <code>null</code>. If there is more than one value defined,
0659: * return only the first one.
0660: *
0661: * @param name Name of the desired request parameter
0662: */
0663: public String getParameter(String name) {
0664:
0665: parseParameters();
0666: String values[] = (String[]) parameters.get(name);
0667: if (values != null)
0668: return (values[0]);
0669: else
0670: return (null);
0671:
0672: }
0673:
0674: /**
0675: * Returns a <code>Map</code> of the parameters of this request.
0676: * Request parameters are extra information sent with the request.
0677: * For HTTP servlets, parameters are contained in the query string
0678: * or posted form data.
0679: *
0680: * @return A <code>Map</code> containing parameter names as keys
0681: * and parameter values as map values.
0682: */
0683: public Map getParameterMap() {
0684:
0685: parseParameters();
0686: return (this .parameters);
0687:
0688: }
0689:
0690: /**
0691: * Return the names of all defined request parameters for this request.
0692: */
0693: public Enumeration getParameterNames() {
0694:
0695: parseParameters();
0696: return (new Enumerator(parameters.keySet()));
0697:
0698: }
0699:
0700: /**
0701: * Return the defined values for the specified request parameter, if any;
0702: * otherwise, return <code>null</code>.
0703: *
0704: * @param name Name of the desired request parameter
0705: */
0706: public String[] getParameterValues(String name) {
0707:
0708: parseParameters();
0709: String values[] = (String[]) parameters.get(name);
0710: if (values != null)
0711: return (values);
0712: else
0713: return (null);
0714:
0715: }
0716:
0717: /**
0718: * Return a RequestDispatcher that wraps the resource at the specified
0719: * path, which may be interpreted as relative to the current request path.
0720: *
0721: * @param path Path of the resource to be wrapped
0722: */
0723: public RequestDispatcher getRequestDispatcher(String path) {
0724:
0725: if (context == null)
0726: return (null);
0727:
0728: // If the path is already context-relative, just pass it through
0729: if (path == null)
0730: return (null);
0731: else if (path.startsWith("/"))
0732: return (context.getServletContext()
0733: .getRequestDispatcher(path));
0734:
0735: // Convert a request-relative path to a context-relative one
0736: String servletPath = (String) getAttribute(Globals.SERVLET_PATH_ATTR);
0737: if (servletPath == null)
0738: servletPath = getServletPath();
0739:
0740: int pos = servletPath.lastIndexOf('/');
0741: String relative = null;
0742: if (pos >= 0) {
0743: relative = RequestUtil.normalize(servletPath.substring(0,
0744: pos + 1)
0745: + path);
0746: } else {
0747: relative = RequestUtil.normalize(servletPath + path);
0748: }
0749:
0750: return (context.getServletContext()
0751: .getRequestDispatcher(relative));
0752:
0753: }
0754:
0755: /**
0756: * Was this request received on a secure connection?
0757: */
0758: public boolean isSecure() {
0759:
0760: return (secure);
0761:
0762: }
0763:
0764: // --------------------------------------------- HttpServletRequest Methods
0765:
0766: /**
0767: * Return the authentication type used for this Request.
0768: */
0769: public String getAuthType() {
0770:
0771: return (authType);
0772:
0773: }
0774:
0775: /**
0776: * Return the portion of the request URI used to select the Context
0777: * of the Request.
0778: */
0779: public String getContextPath() {
0780:
0781: return (contextPath);
0782:
0783: }
0784:
0785: /**
0786: * Return the set of Cookies received with this Request.
0787: */
0788: public Cookie[] getCookies() {
0789:
0790: synchronized (cookies) {
0791: if (cookies.size() < 1)
0792: return (null);
0793: Cookie results[] = new Cookie[cookies.size()];
0794: return ((Cookie[]) cookies.toArray(results));
0795: }
0796:
0797: }
0798:
0799: /**
0800: * Return the value of the specified date header, if any; otherwise
0801: * return -1.
0802: *
0803: * @param name Name of the requested date header
0804: *
0805: * @exception IllegalArgumentException if the specified header value
0806: * cannot be converted to a date
0807: */
0808: public long getDateHeader(String name) {
0809:
0810: String value = getHeader(name);
0811: if (value == null)
0812: return (-1L);
0813:
0814: // Work around a bug in SimpleDateFormat in pre-JDK1.2b4
0815: // (Bug Parade bug #4106807)
0816: value += " ";
0817:
0818: // Attempt to convert the date header in a variety of formats
0819: for (int i = 0; i < formats.length; i++) {
0820: try {
0821: Date date = formats[i].parse(value);
0822: return (date.getTime());
0823: } catch (ParseException e) {
0824: ;
0825: }
0826: }
0827: throw new IllegalArgumentException(value);
0828:
0829: }
0830:
0831: /**
0832: * Return the first value of the specified header, if any; otherwise,
0833: * return <code>null</code>
0834: *
0835: * @param name Name of the requested header
0836: */
0837: public String getHeader(String name) {
0838:
0839: name = name.toLowerCase();
0840: synchronized (headers) {
0841: ArrayList values = (ArrayList) headers.get(name);
0842: if (values != null)
0843: return ((String) values.get(0));
0844: else
0845: return (null);
0846: }
0847:
0848: }
0849:
0850: /**
0851: * Return all of the values of the specified header, if any; otherwise,
0852: * return an empty enumeration.
0853: *
0854: * @param name Name of the requested header
0855: */
0856: public Enumeration getHeaders(String name) {
0857:
0858: name = name.toLowerCase();
0859: synchronized (headers) {
0860: ArrayList values = (ArrayList) headers.get(name);
0861: if (values != null)
0862: return (new Enumerator(values));
0863: else
0864: return (new Enumerator(empty));
0865: }
0866:
0867: }
0868:
0869: /**
0870: * Return the names of all headers received with this request.
0871: */
0872: public Enumeration getHeaderNames() {
0873:
0874: synchronized (headers) {
0875: return (new Enumerator(headers.keySet()));
0876: }
0877:
0878: }
0879:
0880: /**
0881: * Return the value of the specified header as an integer, or -1 if there
0882: * is no such header for this request.
0883: *
0884: * @param name Name of the requested header
0885: *
0886: * @exception IllegalArgumentException if the specified header value
0887: * cannot be converted to an integer
0888: */
0889: public int getIntHeader(String name) {
0890:
0891: String value = getHeader(name);
0892: if (value == null)
0893: return (-1);
0894: else
0895: return (Integer.parseInt(value));
0896:
0897: }
0898:
0899: /**
0900: * Return the HTTP request method used in this Request.
0901: */
0902: public String getMethod() {
0903:
0904: return (method);
0905:
0906: }
0907:
0908: /**
0909: * Return the path information associated with this Request.
0910: */
0911: public String getPathInfo() {
0912:
0913: return (pathInfo);
0914:
0915: }
0916:
0917: /**
0918: * Return the extra path information for this request, translated
0919: * to a real path.
0920: */
0921: public String getPathTranslated() {
0922:
0923: if (context == null)
0924: return (null);
0925:
0926: if (pathInfo == null)
0927: return (null);
0928: else
0929: return (context.getServletContext().getRealPath(pathInfo));
0930:
0931: }
0932:
0933: /**
0934: * Return the query string associated with this request.
0935: */
0936: public String getQueryString() {
0937:
0938: return (queryString);
0939:
0940: }
0941:
0942: /**
0943: * Return the name of the remote user that has been authenticated
0944: * for this Request.
0945: */
0946: public String getRemoteUser() {
0947:
0948: if (userPrincipal != null)
0949: return (userPrincipal.getName());
0950: else
0951: return (null);
0952:
0953: }
0954:
0955: /**
0956: * Return the session identifier included in this request, if any.
0957: */
0958: public String getRequestedSessionId() {
0959:
0960: return (requestedSessionId);
0961:
0962: }
0963:
0964: /**
0965: * Return the request URI for this request.
0966: */
0967: public String getRequestURI() {
0968:
0969: return (requestURI);
0970:
0971: }
0972:
0973: /**
0974: * Set the decoded request URI.
0975: *
0976: * @param uri The decoded request URI
0977: */
0978: public void setDecodedRequestURI(String uri) {
0979:
0980: this .decodedRequestURI = uri;
0981:
0982: }
0983:
0984: /**
0985: * Return the URL decoded request URI.
0986: */
0987: public String getDecodedRequestURI() {
0988:
0989: if (decodedRequestURI == null)
0990: decodedRequestURI = RequestUtil.URLDecode(getRequestURI());
0991:
0992: return decodedRequestURI;
0993:
0994: }
0995:
0996: /**
0997: * Reconstructs the URL the client used to make the request.
0998: * The returned URL contains a protocol, server name, port
0999: * number, and server path, but it does not include query
1000: * string parameters.
1001: * <p>
1002: * Because this method returns a <code>StringBuffer</code>,
1003: * not a <code>String</code>, you can modify the URL easily,
1004: * for example, to append query parameters.
1005: * <p>
1006: * This method is useful for creating redirect messages and
1007: * for reporting errors.
1008: *
1009: * @return A <code>StringBuffer</code> object containing the
1010: * reconstructed URL
1011: */
1012: public StringBuffer getRequestURL() {
1013:
1014: StringBuffer url = new StringBuffer();
1015: String scheme = getScheme();
1016: int port = getServerPort();
1017: if (port < 0)
1018: port = 80; // Work around java.net.URL bug
1019:
1020: url.append(scheme);
1021: url.append("://");
1022: url.append(getServerName());
1023: if ((scheme.equals("http") && (port != 80))
1024: || (scheme.equals("https") && (port != 443))) {
1025: url.append(':');
1026: url.append(port);
1027: }
1028: url.append(getRequestURI());
1029:
1030: return (url);
1031:
1032: }
1033:
1034: /**
1035: * Return the portion of the request URI used to select the servlet
1036: * that will process this request.
1037: */
1038: public String getServletPath() {
1039:
1040: return (servletPath);
1041:
1042: }
1043:
1044: /**
1045: * Return the session associated with this Request, creating one
1046: * if necessary.
1047: */
1048: public HttpSession getSession() {
1049:
1050: return (getSession(true));
1051:
1052: }
1053:
1054: /**
1055: * Return the session associated with this Request, creating one
1056: * if necessary and requested.
1057: *
1058: * @param create Create a new session if one does not exist
1059: */
1060: public HttpSession getSession(boolean create) {
1061: if (System.getSecurityManager() != null) {
1062: PrivilegedGetSession dp = new PrivilegedGetSession(create);
1063: return (HttpSession) AccessController.doPrivileged(dp);
1064: }
1065: return doGetSession(create);
1066: }
1067:
1068: private HttpSession doGetSession(boolean create) {
1069: // There cannot be a session if no context has been assigned yet
1070: if (context == null)
1071: return (null);
1072:
1073: // Return the current session if it exists and is valid
1074: if ((session != null) && !session.isValid())
1075: session = null;
1076: if (session != null)
1077: return (session.getSession());
1078:
1079: // Return the requested session if it exists and is valid
1080: Manager manager = null;
1081: if (context != null)
1082: manager = context.getManager();
1083: if (manager == null)
1084: return (null); // Sessions are not supported
1085: if (requestedSessionId != null) {
1086: try {
1087: session = manager.findSession(requestedSessionId);
1088: } catch (IOException e) {
1089: session = null;
1090: }
1091: if ((session != null) && !session.isValid())
1092: session = null;
1093: if (session != null) {
1094: return (session.getSession());
1095: }
1096: }
1097:
1098: // Create a new session if requested and the response is not committed
1099: if (!create)
1100: return (null);
1101: if ((context != null) && (response != null)
1102: && context.getCookies()
1103: && response.getResponse().isCommitted()) {
1104: throw new IllegalStateException(sm
1105: .getString("httpRequestBase.createCommitted"));
1106: }
1107:
1108: session = manager.createSession();
1109: if (session != null)
1110: return (session.getSession());
1111: else
1112: return (null);
1113:
1114: }
1115:
1116: /**
1117: * Return <code>true</code> if the session identifier included in this
1118: * request came from a cookie.
1119: */
1120: public boolean isRequestedSessionIdFromCookie() {
1121:
1122: if (requestedSessionId != null)
1123: return (requestedSessionCookie);
1124: else
1125: return (false);
1126:
1127: }
1128:
1129: /**
1130: * Return <code>true</code> if the session identifier included in this
1131: * request came from the request URI.
1132: */
1133: public boolean isRequestedSessionIdFromURL() {
1134:
1135: if (requestedSessionId != null)
1136: return (requestedSessionURL);
1137: else
1138: return (false);
1139:
1140: }
1141:
1142: /**
1143: * Return <code>true</code> if the session identifier included in this
1144: * request came from the request URI.
1145: *
1146: * @deprecated As of Version 2.1 of the Java Servlet API, use
1147: * <code>isRequestedSessionIdFromURL()</code> instead.
1148: */
1149: public boolean isRequestedSessionIdFromUrl() {
1150:
1151: return (isRequestedSessionIdFromURL());
1152:
1153: }
1154:
1155: /**
1156: * Return <code>true</code> if the session identifier included in this
1157: * request identifies a valid session.
1158: */
1159: public boolean isRequestedSessionIdValid() {
1160:
1161: if (requestedSessionId == null)
1162: return (false);
1163: if (context == null)
1164: return (false);
1165: Manager manager = context.getManager();
1166: if (manager == null)
1167: return (false);
1168: Session session = null;
1169: try {
1170: session = manager.findSession(requestedSessionId);
1171: } catch (IOException e) {
1172: session = null;
1173: }
1174: if ((session != null) && session.isValid())
1175: return (true);
1176: else
1177: return (false);
1178:
1179: }
1180:
1181: /**
1182: * Return <code>true</code> if the authenticated user principal
1183: * possesses the specified role name.
1184: *
1185: * @param role Role name to be validated
1186: */
1187: public boolean isUserInRole(String role) {
1188:
1189: // Have we got an authenticated principal at all?
1190: if (userPrincipal == null)
1191: return (false);
1192:
1193: // Identify the Realm we will use for checking role assignmenets
1194: if (context == null)
1195: return (false);
1196: Realm realm = context.getRealm();
1197: if (realm == null)
1198: return (false);
1199:
1200: // Check for a role alias defined in a <security-role-ref> element
1201: if (wrapper != null) {
1202: String realRole = wrapper.findSecurityReference(role);
1203: if ((realRole != null)
1204: && realm.hasRole(userPrincipal, realRole))
1205: return (true);
1206: }
1207:
1208: // Check for a role defined directly as a <security-role>
1209: return (realm.hasRole(userPrincipal, role));
1210:
1211: }
1212:
1213: /**
1214: * Return the principal that has been authenticated for this Request.
1215: */
1216: public Principal getUserPrincipal() {
1217:
1218: return (userPrincipal);
1219:
1220: }
1221:
1222: private void log(String message) {
1223: Logger logger = context.getLogger();
1224: logger.log(message);
1225: }
1226:
1227: private void log(String message, Throwable throwable) {
1228: Logger logger = context.getLogger();
1229: logger.log(message, throwable);
1230: }
1231:
1232: }
|