0001: /*
0002: * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
0003: * Distributed under the terms of either:
0004: * - the common development and distribution license (CDDL), v1.0; or
0005: * - the GNU Lesser General Public License, v2.1 or later
0006: */
0007: package winstone;
0008:
0009: import java.io.BufferedReader;
0010: import java.io.IOException;
0011: import java.io.InputStream;
0012: import java.io.InputStreamReader;
0013: import java.io.Reader;
0014: import java.io.UnsupportedEncodingException;
0015: import java.security.MessageDigest;
0016: import java.security.NoSuchAlgorithmException;
0017: import java.security.Principal;
0018: import java.text.DateFormat;
0019: import java.text.SimpleDateFormat;
0020: import java.util.ArrayList;
0021: import java.util.Arrays;
0022: import java.util.Collection;
0023: import java.util.Collections;
0024: import java.util.Date;
0025: import java.util.Enumeration;
0026: import java.util.HashMap;
0027: import java.util.HashSet;
0028: import java.util.Hashtable;
0029: import java.util.Iterator;
0030: import java.util.List;
0031: import java.util.Locale;
0032: import java.util.Map;
0033: import java.util.Random;
0034: import java.util.Set;
0035: import java.util.Stack;
0036: import java.util.StringTokenizer;
0037: import java.util.TimeZone;
0038:
0039: import javax.servlet.ServletInputStream;
0040: import javax.servlet.ServletRequestAttributeEvent;
0041: import javax.servlet.ServletRequestAttributeListener;
0042: import javax.servlet.ServletRequestListener;
0043: import javax.servlet.http.Cookie;
0044: import javax.servlet.http.HttpServletRequest;
0045: import javax.servlet.http.HttpSession;
0046:
0047: /**
0048: * Implements the request interface required by the servlet spec.
0049: *
0050: * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
0051: * @version $Id: WinstoneRequest.java,v 1.38 2007/10/28 16:29:02 rickknowles Exp $
0052: */
0053: public class WinstoneRequest implements HttpServletRequest {
0054: protected static DateFormat headerDF = new SimpleDateFormat(
0055: "EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
0056: protected static Random rnd = null;
0057: static {
0058: headerDF.setTimeZone(TimeZone.getTimeZone("GMT"));
0059: rnd = new Random(System.currentTimeMillis());
0060: }
0061:
0062: // Request header constants
0063: static final String CONTENT_LENGTH_HEADER = "Content-Length";
0064: static final String CONTENT_TYPE_HEADER = "Content-Type";
0065: static final String AUTHORIZATION_HEADER = "Authorization";
0066: static final String LOCALE_HEADER = "Accept-Language";
0067: static final String HOST_HEADER = "Host";
0068: static final String IN_COOKIE_HEADER1 = "Cookie";
0069: static final String IN_COOKIE_HEADER2 = "Cookie2";
0070: static final String METHOD_HEAD = "HEAD";
0071: static final String METHOD_GET = "GET";
0072: static final String METHOD_POST = "POST";
0073: static final String POST_PARAMETERS = "application/x-www-form-urlencoded";
0074:
0075: protected Map attributes;
0076: protected Map parameters;
0077: protected Stack attributesStack;
0078: protected Stack parametersStack;
0079: // protected Map forwardedParameters;
0080:
0081: protected String headers[];
0082: protected Cookie cookies[];
0083:
0084: protected String method;
0085: protected String scheme;
0086: protected String serverName;
0087: protected String requestURI;
0088: protected String servletPath;
0089: protected String pathInfo;
0090: protected String queryString;
0091: protected String protocol;
0092: protected int contentLength;
0093: protected String contentType;
0094: protected String encoding;
0095:
0096: protected int serverPort;
0097: protected String remoteIP;
0098: protected String remoteName;
0099: protected int remotePort;
0100: protected String localAddr;
0101: protected String localName;
0102: protected int localPort;
0103: protected Boolean parsedParameters;
0104: protected Map requestedSessionIds;
0105: protected Map currentSessionIds;
0106: protected String deadRequestedSessionId;
0107: protected List locales;
0108: protected String authorization;
0109: protected boolean isSecure;
0110:
0111: protected WinstoneInputStream inputData;
0112: protected BufferedReader inputReader;
0113: protected ServletConfiguration servletConfig;
0114: protected WebAppConfiguration webappConfig;
0115: protected HostGroup hostGroup;
0116:
0117: protected AuthenticationPrincipal authenticatedUser;
0118: protected ServletRequestAttributeListener requestAttributeListeners[];
0119: protected ServletRequestListener requestListeners[];
0120:
0121: private MessageDigest md5Digester;
0122:
0123: private Set usedSessions;
0124:
0125: /**
0126: * InputStream factory method.
0127: */
0128: public WinstoneRequest() throws IOException {
0129: this .attributes = new Hashtable();
0130: this .parameters = new Hashtable();
0131: this .locales = new ArrayList();
0132: this .attributesStack = new Stack();
0133: this .parametersStack = new Stack();
0134: // this.forwardedParameters = new Hashtable();
0135: this .requestedSessionIds = new Hashtable();
0136: this .currentSessionIds = new Hashtable();
0137: this .usedSessions = new HashSet();
0138: this .contentLength = -1;
0139: this .isSecure = false;
0140: try {
0141: this .md5Digester = MessageDigest.getInstance("MD5");
0142: } catch (NoSuchAlgorithmException err) {
0143: throw new WinstoneException(
0144: "MD5 digester unavailable - what the ...?");
0145: }
0146: }
0147:
0148: /**
0149: * Resets the request to be reused
0150: */
0151: public void cleanUp() {
0152: this .requestListeners = null;
0153: this .requestAttributeListeners = null;
0154: this .attributes.clear();
0155: this .parameters.clear();
0156: this .attributesStack.clear();
0157: this .parametersStack.clear();
0158: // this.forwardedParameters.clear();
0159: this .usedSessions.clear();
0160: this .headers = null;
0161: this .cookies = null;
0162: this .method = null;
0163: this .scheme = null;
0164: this .serverName = null;
0165: this .requestURI = null;
0166: this .servletPath = null;
0167: this .pathInfo = null;
0168: this .queryString = null;
0169: this .protocol = null;
0170: this .contentLength = -1;
0171: this .contentType = null;
0172: this .encoding = null;
0173: this .inputData = null;
0174: this .inputReader = null;
0175: this .servletConfig = null;
0176: this .webappConfig = null;
0177: this .hostGroup = null;
0178: this .serverPort = -1;
0179: this .remoteIP = null;
0180: this .remoteName = null;
0181: this .remotePort = -1;
0182: this .localAddr = null;
0183: this .localName = null;
0184: this .localPort = -1;
0185: this .parsedParameters = null;
0186: this .requestedSessionIds.clear();
0187: this .currentSessionIds.clear();
0188: this .deadRequestedSessionId = null;
0189: this .locales.clear();
0190: this .authorization = null;
0191: this .isSecure = false;
0192: this .authenticatedUser = null;
0193: }
0194:
0195: /**
0196: * Steps through the header array, searching for the first header matching
0197: */
0198: private String extractFirstHeader(String name) {
0199: for (int n = 0; n < this .headers.length; n++) {
0200: if (this .headers[n].toUpperCase().startsWith(
0201: name.toUpperCase() + ':')) {
0202: return this .headers[n].substring(name.length() + 1)
0203: .trim(); // 1 for colon
0204: }
0205: }
0206: return null;
0207: }
0208:
0209: private Collection extractHeaderNameList() {
0210: Collection headerNames = new HashSet();
0211: for (int n = 0; n < this .headers.length; n++) {
0212: String name = this .headers[n];
0213: int colonPos = name.indexOf(':');
0214: headerNames.add(name.substring(0, colonPos));
0215: }
0216: return headerNames;
0217: }
0218:
0219: public Map getAttributes() {
0220: return this .attributes;
0221: }
0222:
0223: public Map getParameters() {
0224: return this .parameters;
0225: }
0226:
0227: //
0228: // public Map getForwardedParameters() {
0229: // return this.forwardedParameters;
0230: // }
0231:
0232: public Stack getAttributesStack() {
0233: return this .attributesStack;
0234: }
0235:
0236: public Stack getParametersStack() {
0237: return this .parametersStack;
0238: }
0239:
0240: public Map getCurrentSessionIds() {
0241: return this .currentSessionIds;
0242: }
0243:
0244: public Map getRequestedSessionIds() {
0245: return this .requestedSessionIds;
0246: }
0247:
0248: public String getDeadRequestedSessionId() {
0249: return this .deadRequestedSessionId;
0250: }
0251:
0252: public HostGroup getHostGroup() {
0253: return this .hostGroup;
0254: }
0255:
0256: public WebAppConfiguration getWebAppConfig() {
0257: return this .webappConfig;
0258: }
0259:
0260: public ServletConfiguration getServletConfig() {
0261: return this .servletConfig;
0262: }
0263:
0264: public String getEncoding() {
0265: return this .encoding;
0266: }
0267:
0268: public Boolean getParsedParameters() {
0269: return this .parsedParameters;
0270: }
0271:
0272: public List getListLocales() {
0273: return this .locales;
0274: }
0275:
0276: public void setInputStream(WinstoneInputStream inputData) {
0277: this .inputData = inputData;
0278: }
0279:
0280: public void setHostGroup(HostGroup hostGroup) {
0281: this .hostGroup = hostGroup;
0282: }
0283:
0284: public void setWebAppConfig(WebAppConfiguration webappConfig) {
0285: this .webappConfig = webappConfig;
0286: }
0287:
0288: public void setServletConfig(ServletConfiguration servletConfig) {
0289: this .servletConfig = servletConfig;
0290: }
0291:
0292: public void setServerPort(int port) {
0293: this .serverPort = port;
0294: }
0295:
0296: public void setRemoteIP(String remoteIP) {
0297: this .remoteIP = remoteIP;
0298: }
0299:
0300: public void setRemoteName(String name) {
0301: this .remoteName = name;
0302: }
0303:
0304: public void setRemotePort(int port) {
0305: this .remotePort = port;
0306: }
0307:
0308: public void setLocalAddr(String ip) {
0309: this .localName = ip;
0310: }
0311:
0312: public void setLocalName(String name) {
0313: this .localName = name;
0314: }
0315:
0316: public void setLocalPort(int port) {
0317: this .localPort = port;
0318: }
0319:
0320: public void setMethod(String method) {
0321: this .method = method;
0322: }
0323:
0324: public void setIsSecure(boolean isSecure) {
0325: this .isSecure = isSecure;
0326: }
0327:
0328: public void setQueryString(String queryString) {
0329: this .queryString = queryString;
0330: }
0331:
0332: public void setServerName(String name) {
0333: this .serverName = name;
0334: }
0335:
0336: public void setRequestURI(String requestURI) {
0337: this .requestURI = requestURI;
0338: }
0339:
0340: public void setScheme(String scheme) {
0341: this .scheme = scheme;
0342: }
0343:
0344: public void setServletPath(String servletPath) {
0345: this .servletPath = servletPath;
0346: }
0347:
0348: public void setPathInfo(String pathInfo) {
0349: this .pathInfo = pathInfo;
0350: }
0351:
0352: public void setProtocol(String protocolString) {
0353: this .protocol = protocolString;
0354: }
0355:
0356: public void setRemoteUser(AuthenticationPrincipal user) {
0357: this .authenticatedUser = user;
0358: }
0359:
0360: public void setContentLength(int len) {
0361: this .contentLength = len;
0362: }
0363:
0364: public void setContentType(String type) {
0365: this .contentType = type;
0366: }
0367:
0368: public void setAuthorization(String auth) {
0369: this .authorization = auth;
0370: }
0371:
0372: public void setLocales(List locales) {
0373: this .locales = locales;
0374: }
0375:
0376: public void setCurrentSessionIds(Map currentSessionIds) {
0377: this .currentSessionIds = currentSessionIds;
0378: }
0379:
0380: public void setRequestedSessionIds(Map requestedSessionIds) {
0381: this .requestedSessionIds = requestedSessionIds;
0382: }
0383:
0384: public void setDeadRequestedSessionId(String deadRequestedSessionId) {
0385: this .deadRequestedSessionId = deadRequestedSessionId;
0386: }
0387:
0388: public void setEncoding(String encoding) {
0389: this .encoding = encoding;
0390: }
0391:
0392: public void setParsedParameters(Boolean parsed) {
0393: this .parsedParameters = parsed;
0394: }
0395:
0396: public void setRequestListeners(ServletRequestListener rl[]) {
0397: this .requestListeners = rl;
0398: }
0399:
0400: public void setRequestAttributeListeners(
0401: ServletRequestAttributeListener ral[]) {
0402: this .requestAttributeListeners = ral;
0403: }
0404:
0405: /**
0406: * Gets parameters from the url encoded parameter string
0407: */
0408: public static void extractParameters(String urlEncodedParams,
0409: String encoding, Map outputParams, boolean overwrite) {
0410: Logger.log(Logger.DEBUG, Launcher.RESOURCES,
0411: "WinstoneRequest.ParsingParameters", new String[] {
0412: urlEncodedParams, encoding });
0413: StringTokenizer st = new StringTokenizer(urlEncodedParams, "&",
0414: false);
0415: Set overwrittenParamNames = null;
0416: while (st.hasMoreTokens()) {
0417: String token = st.nextToken();
0418: int equalPos = token.indexOf('=');
0419: try {
0420: String decodedNameDefault = decodeURLToken(equalPos == -1 ? token
0421: : token.substring(0, equalPos));
0422: String decodedValueDefault = (equalPos == -1 ? ""
0423: : decodeURLToken(token.substring(equalPos + 1)));
0424: String decodedName = (encoding == null ? decodedNameDefault
0425: : new String(decodedNameDefault
0426: .getBytes("8859_1"), encoding));
0427: String decodedValue = (encoding == null ? decodedValueDefault
0428: : new String(decodedValueDefault
0429: .getBytes("8859_1"), encoding));
0430:
0431: Object already = null;
0432: if (overwrite) {
0433: if (overwrittenParamNames == null) {
0434: overwrittenParamNames = new HashSet();
0435: }
0436: if (!overwrittenParamNames.contains(decodedName)) {
0437: overwrittenParamNames.add(decodedName);
0438: outputParams.remove(decodedName);
0439: }
0440: }
0441: already = outputParams.get(decodedName);
0442: if (already == null) {
0443: outputParams.put(decodedName, decodedValue);
0444: } else if (already instanceof String) {
0445: String pair[] = new String[2];
0446: pair[0] = (String) already;
0447: pair[1] = decodedValue;
0448: outputParams.put(decodedName, pair);
0449: } else if (already instanceof String[]) {
0450: String alreadyArray[] = (String[]) already;
0451: String oneMore[] = new String[alreadyArray.length + 1];
0452: System.arraycopy(alreadyArray, 0, oneMore, 0,
0453: alreadyArray.length);
0454: oneMore[oneMore.length - 1] = decodedValue;
0455: outputParams.put(decodedName, oneMore);
0456: } else {
0457: Logger.log(Logger.WARNING, Launcher.RESOURCES,
0458: "WinstoneRequest.UnknownParameterType",
0459: decodedName + " = "
0460: + decodedValue.getClass());
0461: }
0462: } catch (UnsupportedEncodingException err) {
0463: Logger.log(Logger.ERROR, Launcher.RESOURCES,
0464: "WinstoneRequest.ErrorParameters", err);
0465: }
0466: }
0467: }
0468:
0469: /**
0470: * For decoding the URL encoding used on query strings
0471: */
0472: public static String decodeURLToken(String in) {
0473: StringBuffer workspace = new StringBuffer();
0474: for (int n = 0; n < in.length(); n++) {
0475: char this Char = in.charAt(n);
0476: if (this Char == '+')
0477: workspace.append(' ');
0478: else if (this Char == '%') {
0479: String token = in.substring(Math
0480: .min(n + 1, in.length()), Math.min(n + 3, in
0481: .length()));
0482: try {
0483: int decoded = Integer.parseInt(token, 16);
0484: workspace.append((char) decoded);
0485: n += 2;
0486: } catch (RuntimeException err) {
0487: Logger.log(Logger.WARNING, Launcher.RESOURCES,
0488: "WinstoneRequest.InvalidURLTokenChar",
0489: token);
0490: workspace.append(this Char);
0491: }
0492: } else
0493: workspace.append(this Char);
0494: }
0495: return workspace.toString();
0496: }
0497:
0498: public void discardRequestBody() {
0499: if (getContentLength() > 0) {
0500: try {
0501: Logger.log(Logger.DEBUG, Launcher.RESOURCES,
0502: "WinstoneResponse.ForceBodyParsing");
0503: // If body not parsed
0504: if ((this .parsedParameters == null)
0505: || (this .parsedParameters.equals(Boolean.FALSE))) {
0506: // read full stream length
0507: try {
0508: InputStream in = getInputStream();
0509: byte buffer[] = new byte[2048];
0510: while (in.read(buffer) != -1)
0511: ;
0512: } catch (IllegalStateException err) {
0513: Reader in = getReader();
0514: char buffer[] = new char[2048];
0515: while (in.read(buffer) != -1)
0516: ;
0517: }
0518: }
0519: } catch (IOException err) {
0520: Logger.log(Logger.DEBUG, Launcher.RESOURCES,
0521: "WinstoneResponse.ErrorForceBodyParsing", err);
0522: }
0523: }
0524: }
0525:
0526: /**
0527: * This takes the parameters in the body of the request and puts them into
0528: * the parameters map.
0529: */
0530: public void parseRequestParameters() {
0531: if ((parsedParameters != null)
0532: && !parsedParameters.booleanValue()) {
0533: Logger.log(Logger.WARNING, Launcher.RESOURCES,
0534: "WinstoneRequest.BothMethods");
0535: this .parsedParameters = Boolean.TRUE;
0536: } else if (parsedParameters == null) {
0537: Map workingParameters = new HashMap();
0538: try {
0539: // Parse query string from request
0540: if ((method.equals(METHOD_GET)
0541: || method.equals(METHOD_HEAD) || method
0542: .equals(METHOD_POST))
0543: && (this .queryString != null)) {
0544: extractParameters(this .queryString, this .encoding,
0545: workingParameters, false);
0546: Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
0547: "WinstoneRequest.ParamLine", ""
0548: + workingParameters);
0549: }
0550:
0551: if (method.equals(METHOD_POST)
0552: && (contentType != null)
0553: && (contentType.equals(POST_PARAMETERS) || contentType
0554: .startsWith(POST_PARAMETERS + ";"))) {
0555: Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
0556: "WinstoneRequest.ParsingBodyParameters");
0557:
0558: // Parse params
0559: byte paramBuffer[] = new byte[contentLength];
0560: int readCount = this .inputData.read(paramBuffer);
0561: if (readCount != contentLength)
0562: Logger
0563: .log(
0564: Logger.WARNING,
0565: Launcher.RESOURCES,
0566: "WinstoneRequest.IncorrectContentLength",
0567: new String[] {
0568: contentLength + "",
0569: readCount + "" });
0570: String paramLine = (this .encoding == null ? new String(
0571: paramBuffer)
0572: : new String(paramBuffer, this .encoding));
0573: extractParameters(paramLine.trim(), this .encoding,
0574: workingParameters, false);
0575: Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
0576: "WinstoneRequest.ParamLine", ""
0577: + workingParameters);
0578: }
0579:
0580: this .parameters.putAll(workingParameters);
0581: this .parsedParameters = Boolean.TRUE;
0582: } catch (Throwable err) {
0583: Logger.log(Logger.ERROR, Launcher.RESOURCES,
0584: "WinstoneRequest.ErrorBodyParameters", err);
0585: this .parsedParameters = null;
0586: }
0587: }
0588: }
0589:
0590: /**
0591: * Go through the list of headers, and build the headers/cookies arrays for
0592: * the request object.
0593: */
0594: public void parseHeaders(List headerList) {
0595: // Iterate through headers
0596: List outHeaderList = new ArrayList();
0597: List cookieList = new ArrayList();
0598: for (Iterator i = headerList.iterator(); i.hasNext();) {
0599: String header = (String) i.next();
0600: int colonPos = header.indexOf(':');
0601: String name = header.substring(0, colonPos);
0602: String value = header.substring(colonPos + 1).trim();
0603:
0604: // Add it to out headers if it's not a cookie
0605: outHeaderList.add(header);
0606: // if (!name.equalsIgnoreCase(IN_COOKIE_HEADER1)
0607: // && !name.equalsIgnoreCase(IN_COOKIE_HEADER2))
0608:
0609: if (name.equalsIgnoreCase(AUTHORIZATION_HEADER))
0610: this .authorization = value;
0611: else if (name.equalsIgnoreCase(LOCALE_HEADER))
0612: this .locales = parseLocales(value);
0613: else if (name.equalsIgnoreCase(CONTENT_LENGTH_HEADER))
0614: this .contentLength = Integer.parseInt(value);
0615: else if (name.equalsIgnoreCase(HOST_HEADER)) {
0616: int nextColonPos = value.indexOf(':');
0617: if ((nextColonPos == -1)
0618: || (nextColonPos == value.length() - 1)) {
0619: this .serverName = value;
0620: if (this .scheme != null) {
0621: if (this .scheme.equals("http")) {
0622: this .serverPort = 80;
0623: } else if (this .scheme.equals("https")) {
0624: this .serverPort = 443;
0625: }
0626: }
0627: } else {
0628: this .serverName = value.substring(0, nextColonPos);
0629: this .serverPort = Integer.parseInt(value
0630: .substring(nextColonPos + 1));
0631: }
0632: } else if (name.equalsIgnoreCase(CONTENT_TYPE_HEADER)) {
0633: this .contentType = value;
0634: int semicolon = value.lastIndexOf(';');
0635: if (semicolon != -1) {
0636: String encodingClause = value.substring(
0637: semicolon + 1).trim();
0638: if (encodingClause.startsWith("charset="))
0639: this .encoding = encodingClause.substring(8);
0640: }
0641: } else if (name.equalsIgnoreCase(IN_COOKIE_HEADER1)
0642: || name.equalsIgnoreCase(IN_COOKIE_HEADER2))
0643: parseCookieLine(value, cookieList);
0644: }
0645: this .headers = (String[]) outHeaderList.toArray(new String[0]);
0646: if (cookieList.isEmpty()) {
0647: this .cookies = null;
0648: } else {
0649: this .cookies = (Cookie[]) cookieList.toArray(new Cookie[0]);
0650: }
0651: }
0652:
0653: private static String nextToken(StringTokenizer st) {
0654: if (st.hasMoreTokens()) {
0655: return st.nextToken();
0656: } else {
0657: return null;
0658: }
0659: }
0660:
0661: private void parseCookieLine(String headerValue, List cookieList) {
0662: StringTokenizer st = new StringTokenizer(headerValue, ";",
0663: false);
0664: int version = 0;
0665: String cookieLine = nextToken(st);
0666:
0667: // check cookie version flag
0668: if ((cookieLine != null) && cookieLine.startsWith("$Version=")) {
0669: int equalPos = cookieLine.indexOf('=');
0670: try {
0671: version = Integer.parseInt(extractFromQuotes(cookieLine
0672: .substring(equalPos + 1).trim()));
0673: } catch (NumberFormatException err) {
0674: version = 0;
0675: }
0676: cookieLine = nextToken(st);
0677: }
0678:
0679: // process remainder - parameters
0680: while (cookieLine != null) {
0681: cookieLine = cookieLine.trim();
0682: int equalPos = cookieLine.indexOf('=');
0683: if (equalPos == -1) {
0684: // next token
0685: cookieLine = nextToken(st);
0686: } else {
0687: String name = cookieLine.substring(0, equalPos);
0688: String value = extractFromQuotes(cookieLine
0689: .substring(equalPos + 1));
0690: Cookie this Cookie = new Cookie(name, value);
0691: this Cookie.setVersion(version);
0692: this Cookie.setSecure(isSecure());
0693: cookieList.add(this Cookie);
0694:
0695: // check for path / domain / port
0696: cookieLine = nextToken(st);
0697: while ((cookieLine != null)
0698: && cookieLine.trim().startsWith("$")) {
0699: cookieLine = cookieLine.trim();
0700: equalPos = cookieLine.indexOf('=');
0701: String attrValue = equalPos == -1 ? "" : cookieLine
0702: .substring(equalPos + 1).trim();
0703: if (cookieLine.startsWith("$Path")) {
0704: this Cookie
0705: .setPath(extractFromQuotes(attrValue));
0706: } else if (cookieLine.startsWith("$Domain")) {
0707: this Cookie
0708: .setDomain(extractFromQuotes(attrValue));
0709: }
0710: cookieLine = nextToken(st);
0711: }
0712:
0713: Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
0714: "WinstoneRequest.CookieFound", this Cookie
0715: .toString());
0716: if (this Cookie.getName().equals(
0717: WinstoneSession.SESSION_COOKIE_NAME)) {
0718: // Find a context that manages this key
0719: HostConfiguration hostConfig = this .hostGroup
0720: .getHostByName(this .serverName);
0721: WebAppConfiguration ownerContext = hostConfig
0722: .getWebAppBySessionKey(this Cookie
0723: .getValue());
0724: if (ownerContext != null) {
0725: this .requestedSessionIds.put(ownerContext
0726: .getContextPath(), this Cookie
0727: .getValue());
0728: this .currentSessionIds.put(ownerContext
0729: .getContextPath(), this Cookie
0730: .getValue());
0731: }
0732: // If not found, it was probably dead
0733: else {
0734: this .deadRequestedSessionId = this Cookie
0735: .getValue();
0736: }
0737: // this.requestedSessionId = thisCookie.getValue();
0738: // this.currentSessionId = thisCookie.getValue();
0739: Logger
0740: .log(
0741: Logger.FULL_DEBUG,
0742: Launcher.RESOURCES,
0743: "WinstoneRequest.SessionCookieFound",
0744: new String[] {
0745: this Cookie.getValue(),
0746: ownerContext == null ? ""
0747: : "prefix:"
0748: + ownerContext
0749: .getContextPath() });
0750: }
0751: }
0752: }
0753: }
0754:
0755: private static String extractFromQuotes(String input) {
0756: if ((input != null) && input.startsWith("\"")
0757: && input.endsWith("\"")) {
0758: return input.substring(1, input.length() - 1);
0759: } else {
0760: return input;
0761: }
0762: }
0763:
0764: private List parseLocales(String header) {
0765: // Strip out the whitespace
0766: StringBuffer lb = new StringBuffer();
0767: for (int n = 0; n < header.length(); n++) {
0768: char c = header.charAt(n);
0769: if (!Character.isWhitespace(c))
0770: lb.append(c);
0771: }
0772:
0773: // Tokenize by commas
0774: Map localeEntries = new HashMap();
0775: StringTokenizer commaTK = new StringTokenizer(lb.toString(),
0776: ",", false);
0777: for (; commaTK.hasMoreTokens();) {
0778: String clause = commaTK.nextToken();
0779:
0780: // Tokenize by semicolon
0781: Float quality = new Float(1);
0782: if (clause.indexOf(";q=") != -1) {
0783: int pos = clause.indexOf(";q=");
0784: try {
0785: quality = new Float(clause.substring(pos + 3));
0786: } catch (NumberFormatException err) {
0787: quality = new Float(0);
0788: }
0789: clause = clause.substring(0, pos);
0790: }
0791:
0792: // Build the locale
0793: String language = "";
0794: String country = "";
0795: String variant = "";
0796: int dpos = clause.indexOf('-');
0797: if (dpos == -1)
0798: language = clause;
0799: else {
0800: language = clause.substring(0, dpos);
0801: String remainder = clause.substring(dpos + 1);
0802: int d2pos = remainder.indexOf('-');
0803: if (d2pos == -1)
0804: country = remainder;
0805: else {
0806: country = remainder.substring(0, d2pos);
0807: variant = remainder.substring(d2pos + 1);
0808: }
0809: }
0810: Locale loc = new Locale(language, country, variant);
0811:
0812: // Put into list by quality
0813: List localeList = (List) localeEntries.get(quality);
0814: if (localeList == null) {
0815: localeList = new ArrayList();
0816: localeEntries.put(quality, localeList);
0817: }
0818: localeList.add(loc);
0819: }
0820:
0821: // Extract and build the list
0822: Float orderKeys[] = (Float[]) localeEntries.keySet().toArray(
0823: new Float[0]);
0824: Arrays.sort(orderKeys);
0825: List outputLocaleList = new ArrayList();
0826: for (int n = 0; n < orderKeys.length; n++) {
0827: // Skip backwards through the list of maps and add to the output list
0828: int reversedIndex = (orderKeys.length - 1) - n;
0829: if ((orderKeys[reversedIndex].floatValue() <= 0)
0830: || (orderKeys[reversedIndex].floatValue() > 1))
0831: continue;
0832: List localeList = (List) localeEntries
0833: .get(orderKeys[reversedIndex]);
0834: for (Iterator i = localeList.iterator(); i.hasNext();)
0835: outputLocaleList.add(i.next());
0836: }
0837:
0838: return outputLocaleList;
0839: }
0840:
0841: public void addIncludeQueryParameters(String queryString) {
0842: Map lastParams = new Hashtable();
0843: if (!this .parametersStack.isEmpty()) {
0844: lastParams.putAll((Map) this .parametersStack.peek());
0845: }
0846: Map newQueryParams = new HashMap();
0847: if (queryString != null) {
0848: extractParameters(queryString, this .encoding,
0849: newQueryParams, false);
0850: }
0851: lastParams.putAll(newQueryParams);
0852: this .parametersStack.push(lastParams);
0853: }
0854:
0855: public void addIncludeAttributes(String requestURI,
0856: String contextPath, String servletPath, String pathInfo,
0857: String queryString) {
0858: Map includeAttributes = new HashMap();
0859: if (requestURI != null) {
0860: includeAttributes.put(
0861: RequestDispatcher.INCLUDE_REQUEST_URI, requestURI);
0862: }
0863: if (contextPath != null) {
0864: includeAttributes
0865: .put(RequestDispatcher.INCLUDE_CONTEXT_PATH,
0866: contextPath);
0867: }
0868: if (servletPath != null) {
0869: includeAttributes
0870: .put(RequestDispatcher.INCLUDE_SERVLET_PATH,
0871: servletPath);
0872: }
0873: if (pathInfo != null) {
0874: includeAttributes.put(RequestDispatcher.INCLUDE_PATH_INFO,
0875: pathInfo);
0876: }
0877: if (queryString != null) {
0878: includeAttributes
0879: .put(RequestDispatcher.INCLUDE_QUERY_STRING,
0880: queryString);
0881: }
0882: this .attributesStack.push(includeAttributes);
0883: }
0884:
0885: public void removeIncludeQueryString() {
0886: if (!this .parametersStack.isEmpty()) {
0887: this .parametersStack.pop();
0888: }
0889: }
0890:
0891: public void clearIncludeStackForForward() {
0892: this .parametersStack.clear();
0893: this .attributesStack.clear();
0894: }
0895:
0896: public void setForwardQueryString(String forwardQueryString) {
0897: // this.forwardedParameters.clear();
0898:
0899: // Parse query string from include / forward
0900: if (forwardQueryString != null) {
0901: String oldQueryString = this .queryString == null ? ""
0902: : this .queryString;
0903: boolean needJoiner = !forwardQueryString.equals("")
0904: && !oldQueryString.equals("");
0905: this .queryString = forwardQueryString
0906: + (needJoiner ? "&" : "") + oldQueryString;
0907:
0908: if (this .parsedParameters != null) {
0909: Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
0910: "WinstoneRequest.ParsingParameters",
0911: new String[] { forwardQueryString,
0912: this .encoding });
0913: extractParameters(forwardQueryString, this .encoding,
0914: this .parameters, true);
0915: Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
0916: "WinstoneRequest.ParamLine", ""
0917: + this .parameters);
0918: }
0919: }
0920:
0921: }
0922:
0923: public void removeIncludeAttributes() {
0924: if (!this .attributesStack.isEmpty()) {
0925: this .attributesStack.pop();
0926: }
0927: }
0928:
0929: // Implementation methods for the servlet request stuff
0930: public Object getAttribute(String name) {
0931: if (!this .attributesStack.isEmpty()) {
0932: Map includedAttributes = (Map) this .attributesStack.peek();
0933: Object value = includedAttributes.get(name);
0934: if (value != null) {
0935: return value;
0936: }
0937: }
0938: return this .attributes.get(name);
0939: }
0940:
0941: public Enumeration getAttributeNames() {
0942: Map attributes = new HashMap(this .attributes);
0943: if (!this .attributesStack.isEmpty()) {
0944: Map includedAttributes = (Map) this .attributesStack.peek();
0945: attributes.putAll(includedAttributes);
0946: }
0947: return Collections.enumeration(attributes.keySet());
0948: }
0949:
0950: public void removeAttribute(String name) {
0951: Object value = attributes.get(name);
0952: if (value == null)
0953: return;
0954:
0955: // fire event
0956: if (this .requestAttributeListeners != null) {
0957: for (int n = 0; n < this .requestAttributeListeners.length; n++) {
0958: ClassLoader cl = Thread.currentThread()
0959: .getContextClassLoader();
0960: Thread.currentThread().setContextClassLoader(
0961: getWebAppConfig().getLoader());
0962: this .requestAttributeListeners[n]
0963: .attributeRemoved(new ServletRequestAttributeEvent(
0964: this .webappConfig, this , name, value));
0965: Thread.currentThread().setContextClassLoader(cl);
0966: }
0967: }
0968:
0969: this .attributes.remove(name);
0970: }
0971:
0972: public void setAttribute(String name, Object o) {
0973: if ((name != null) && (o != null)) {
0974: Object oldValue = attributes.get(name);
0975: attributes.put(name, o); // make sure it's set at the top level
0976:
0977: // fire event
0978: if (this .requestAttributeListeners != null) {
0979: if (oldValue == null) {
0980: for (int n = 0; n < this .requestAttributeListeners.length; n++) {
0981: ClassLoader cl = Thread.currentThread()
0982: .getContextClassLoader();
0983: Thread.currentThread().setContextClassLoader(
0984: getWebAppConfig().getLoader());
0985: this .requestAttributeListeners[n]
0986: .attributeAdded(new ServletRequestAttributeEvent(
0987: this .webappConfig, this , name,
0988: o));
0989: Thread.currentThread()
0990: .setContextClassLoader(cl);
0991: }
0992: } else {
0993: for (int n = 0; n < this .requestAttributeListeners.length; n++) {
0994: ClassLoader cl = Thread.currentThread()
0995: .getContextClassLoader();
0996: Thread.currentThread().setContextClassLoader(
0997: getWebAppConfig().getLoader());
0998: this .requestAttributeListeners[n]
0999: .attributeReplaced(new ServletRequestAttributeEvent(
1000: this .webappConfig, this , name,
1001: oldValue));
1002: Thread.currentThread()
1003: .setContextClassLoader(cl);
1004: }
1005: }
1006: }
1007: } else if (name != null) {
1008: removeAttribute(name);
1009: }
1010: }
1011:
1012: public String getCharacterEncoding() {
1013: return this .encoding;
1014: }
1015:
1016: public void setCharacterEncoding(String encoding)
1017: throws UnsupportedEncodingException {
1018: "blah".getBytes(encoding); // throws an exception if the encoding is unsupported
1019: if (this .inputReader == null) {
1020: Logger.log(Logger.DEBUG, Launcher.RESOURCES,
1021: "WinstoneRequest.SetCharEncoding", new String[] {
1022: this .encoding, encoding });
1023: this .encoding = encoding;
1024: }
1025: }
1026:
1027: public int getContentLength() {
1028: return this .contentLength;
1029: }
1030:
1031: public String getContentType() {
1032: return this .contentType;
1033: }
1034:
1035: public Locale getLocale() {
1036: return this .locales.isEmpty() ? Locale.getDefault()
1037: : (Locale) this .locales.get(0);
1038: }
1039:
1040: public Enumeration getLocales() {
1041: List sendLocales = this .locales;
1042: if (sendLocales.isEmpty())
1043: sendLocales.add(Locale.getDefault());
1044: return Collections.enumeration(sendLocales);
1045: }
1046:
1047: public String getProtocol() {
1048: return this .protocol;
1049: }
1050:
1051: public String getScheme() {
1052: return this .scheme;
1053: }
1054:
1055: public boolean isSecure() {
1056: return this .isSecure;
1057: }
1058:
1059: public BufferedReader getReader() throws IOException {
1060: if (this .inputReader != null) {
1061: return this .inputReader;
1062: } else {
1063: if (this .parsedParameters != null) {
1064: if (this .parsedParameters.equals(Boolean.TRUE)) {
1065: Logger.log(Logger.WARNING, Launcher.RESOURCES,
1066: "WinstoneRequest.BothMethodsReader");
1067: } else {
1068: throw new IllegalStateException(
1069: Launcher.RESOURCES
1070: .getString("WinstoneRequest.CalledReaderAfterStream"));
1071: }
1072: }
1073: if (this .encoding != null) {
1074: this .inputReader = new BufferedReader(
1075: new InputStreamReader(this .inputData,
1076: this .encoding));
1077: } else {
1078: this .inputReader = new BufferedReader(
1079: new InputStreamReader(this .inputData));
1080: }
1081: this .parsedParameters = new Boolean(false);
1082: return this .inputReader;
1083: }
1084: }
1085:
1086: public ServletInputStream getInputStream() throws IOException {
1087: if (this .inputReader != null) {
1088: throw new IllegalStateException(
1089: Launcher.RESOURCES
1090: .getString("WinstoneRequest.CalledStreamAfterReader"));
1091: }
1092: if (this .parsedParameters != null) {
1093: if (this .parsedParameters.equals(Boolean.TRUE)) {
1094: Logger.log(Logger.WARNING, Launcher.RESOURCES,
1095: "WinstoneRequest.BothMethods");
1096: }
1097: }
1098: this .parsedParameters = new Boolean(false);
1099: return this .inputData;
1100: }
1101:
1102: public String getParameter(String name) {
1103: parseRequestParameters();
1104: Object param = null;
1105: if (!this .parametersStack.isEmpty()) {
1106: param = ((Map) this .parametersStack.peek()).get(name);
1107: }
1108: // if ((param == null) && this.forwardedParameters.get(name) != null) {
1109: // param = this.forwardedParameters.get(name);
1110: // }
1111: if (param == null) {
1112: param = this .parameters.get(name);
1113: }
1114: if (param == null)
1115: return null;
1116: else if (param instanceof String)
1117: return (String) param;
1118: else if (param instanceof String[])
1119: return ((String[]) param)[0];
1120: else
1121: return param.toString();
1122: }
1123:
1124: public Enumeration getParameterNames() {
1125: parseRequestParameters();
1126: Set parameterKeys = new HashSet(this .parameters.keySet());
1127: // parameterKeys.addAll(this.forwardedParameters.keySet());
1128: if (!this .parametersStack.isEmpty()) {
1129: parameterKeys.addAll(((Map) this .parametersStack.peek())
1130: .keySet());
1131: }
1132: return Collections.enumeration(parameterKeys);
1133: }
1134:
1135: public String[] getParameterValues(String name) {
1136: parseRequestParameters();
1137: Object param = null;
1138: if (!this .parametersStack.isEmpty()) {
1139: param = ((Map) this .parametersStack.peek()).get(name);
1140: }
1141: // if ((param == null) && this.forwardedParameters.get(name) != null) {
1142: // param = this.forwardedParameters.get(name);
1143: // }
1144: if (param == null) {
1145: param = this .parameters.get(name);
1146: }
1147: if (param == null)
1148: return null;
1149: else if (param instanceof String) {
1150: return new String[] { (String) param };
1151: } else if (param instanceof String[])
1152: return (String[]) param;
1153: else
1154: throw new WinstoneException(Launcher.RESOURCES.getString(
1155: "WinstoneRequest.UnknownParameterType", name
1156: + " - " + param.getClass()));
1157: }
1158:
1159: public Map getParameterMap() {
1160: Hashtable paramMap = new Hashtable();
1161: for (Enumeration names = this .getParameterNames(); names
1162: .hasMoreElements();) {
1163: String name = (String) names.nextElement();
1164: paramMap.put(name, getParameterValues(name));
1165: }
1166: return paramMap;
1167: }
1168:
1169: public String getServerName() {
1170: return this .serverName;
1171: }
1172:
1173: public int getServerPort() {
1174: return this .serverPort;
1175: }
1176:
1177: public String getRemoteAddr() {
1178: return this .remoteIP;
1179: }
1180:
1181: public String getRemoteHost() {
1182: return this .remoteName;
1183: }
1184:
1185: public int getRemotePort() {
1186: return this .remotePort;
1187: }
1188:
1189: public String getLocalAddr() {
1190: return this .localAddr;
1191: }
1192:
1193: public String getLocalName() {
1194: return this .localName;
1195: }
1196:
1197: public int getLocalPort() {
1198: return this .localPort;
1199: }
1200:
1201: public javax.servlet.RequestDispatcher getRequestDispatcher(
1202: String path) {
1203: if (path.startsWith("/"))
1204: return this .webappConfig.getRequestDispatcher(path);
1205:
1206: // Take the servlet path + pathInfo, and make an absolute path
1207: String fullPath = getServletPath()
1208: + (getPathInfo() == null ? "" : getPathInfo());
1209: int lastSlash = fullPath.lastIndexOf('/');
1210: String currentDir = (lastSlash == -1 ? "/" : fullPath
1211: .substring(0, lastSlash + 1));
1212: return this .webappConfig
1213: .getRequestDispatcher(currentDir + path);
1214: }
1215:
1216: // Now the stuff for HttpServletRequest
1217: public String getContextPath() {
1218: return this .webappConfig.getContextPath();
1219: }
1220:
1221: public Cookie[] getCookies() {
1222: return this .cookies;
1223: }
1224:
1225: public long getDateHeader(String name) {
1226: String dateHeader = getHeader(name);
1227: if (dateHeader == null) {
1228: return -1;
1229: } else
1230: try {
1231: Date date = null;
1232: synchronized (headerDF) {
1233: date = headerDF.parse(dateHeader);
1234: }
1235: return date.getTime();
1236: } catch (java.text.ParseException err) {
1237: throw new IllegalArgumentException(Launcher.RESOURCES
1238: .getString("WinstoneRequest.BadDate",
1239: dateHeader));
1240: }
1241: }
1242:
1243: public int getIntHeader(String name) {
1244: String header = getHeader(name);
1245: return header == null ? -1 : Integer.parseInt(header);
1246: }
1247:
1248: public String getHeader(String name) {
1249: return extractFirstHeader(name);
1250: }
1251:
1252: public Enumeration getHeaderNames() {
1253: return Collections.enumeration(extractHeaderNameList());
1254: }
1255:
1256: public Enumeration getHeaders(String name) {
1257: List headers = new ArrayList();
1258: for (int n = 0; n < this .headers.length; n++)
1259: if (this .headers[n].toUpperCase().startsWith(
1260: name.toUpperCase() + ':'))
1261: headers.add(this .headers[n]
1262: .substring(name.length() + 1).trim()); // 1 for colon
1263: return Collections.enumeration(headers);
1264: }
1265:
1266: public String getMethod() {
1267: return this .method;
1268: }
1269:
1270: public String getPathInfo() {
1271: return this .pathInfo;
1272: }
1273:
1274: public String getPathTranslated() {
1275: return this .webappConfig.getRealPath(this .pathInfo);
1276: }
1277:
1278: public String getQueryString() {
1279: return this .queryString;
1280: }
1281:
1282: public String getRequestURI() {
1283: return this .requestURI;
1284: }
1285:
1286: public String getServletPath() {
1287: return this .servletPath;
1288: }
1289:
1290: public String getRequestedSessionId() {
1291: String actualSessionId = (String) this .requestedSessionIds
1292: .get(this .webappConfig.getContextPath());
1293: if (actualSessionId != null) {
1294: return actualSessionId;
1295: } else {
1296: return this .deadRequestedSessionId;
1297: }
1298: }
1299:
1300: public StringBuffer getRequestURL() {
1301: StringBuffer url = new StringBuffer();
1302: url.append(getScheme()).append("://");
1303: url.append(getServerName());
1304: if (!((getServerPort() == 80) && getScheme().equals("http"))
1305: && !((getServerPort() == 443) && getScheme().equals(
1306: "https")))
1307: url.append(':').append(getServerPort());
1308: url.append(getRequestURI()); // need encoded form, so can't use servlet path + path info
1309: return url;
1310: }
1311:
1312: public Principal getUserPrincipal() {
1313: return this .authenticatedUser;
1314: }
1315:
1316: public boolean isUserInRole(String role) {
1317: if (this .authenticatedUser == null)
1318: return false;
1319: else if (this .servletConfig.getSecurityRoleRefs() == null)
1320: return this .authenticatedUser.isUserIsInRole(role);
1321: else {
1322: String replacedRole = (String) this .servletConfig
1323: .getSecurityRoleRefs().get(role);
1324: return this .authenticatedUser
1325: .isUserIsInRole(replacedRole == null ? role
1326: : replacedRole);
1327: }
1328: }
1329:
1330: public String getAuthType() {
1331: return this .authenticatedUser == null ? null
1332: : this .authenticatedUser.getAuthType();
1333: }
1334:
1335: public String getRemoteUser() {
1336: return this .authenticatedUser == null ? null
1337: : this .authenticatedUser.getName();
1338: }
1339:
1340: public boolean isRequestedSessionIdFromCookie() {
1341: return (getRequestedSessionId() != null);
1342: }
1343:
1344: public boolean isRequestedSessionIdFromURL() {
1345: return false;
1346: }
1347:
1348: public boolean isRequestedSessionIdValid() {
1349: String requestedId = getRequestedSessionId();
1350: if (requestedId == null) {
1351: return false;
1352: }
1353: WinstoneSession ws = this .webappConfig.getSessionById(
1354: requestedId, false);
1355: return (ws != null);
1356: // if (ws == null) {
1357: // return false;
1358: // } else {
1359: // return (validationCheck(ws, System.currentTimeMillis(), false) != null);
1360: // }
1361: }
1362:
1363: public HttpSession getSession() {
1364: return getSession(true);
1365: }
1366:
1367: public HttpSession getSession(boolean create) {
1368: String cookieValue = (String) this .currentSessionIds
1369: .get(this .webappConfig.getContextPath());
1370:
1371: // Handle the null case
1372: if (cookieValue == null) {
1373: if (!create) {
1374: return null;
1375: } else {
1376: cookieValue = makeNewSession().getId();
1377: }
1378: }
1379:
1380: // Now get the session object
1381: WinstoneSession session = this .webappConfig.getSessionById(
1382: cookieValue, false);
1383: if (session != null) {
1384: // long nowDate = System.currentTimeMillis();
1385: // session = validationCheck(session, nowDate, create);
1386: // if (session == null) {
1387: // this.currentSessionIds.remove(this.webappConfig.getContextPath());
1388: // }
1389: }
1390: if (create && (session == null)) {
1391: session = makeNewSession();
1392: }
1393: if (session != null) {
1394: this .usedSessions.add(session);
1395: session.addUsed(this );
1396: }
1397: return session;
1398: }
1399:
1400: /**
1401: * Make a new session, and return the id
1402: */
1403: private WinstoneSession makeNewSession() {
1404: String cookieValue = "Winstone_" + this .remoteIP + "_"
1405: + this .serverPort + "_" + System.currentTimeMillis()
1406: + rnd.nextLong();
1407: byte digestBytes[] = this .md5Digester.digest(cookieValue
1408: .getBytes());
1409:
1410: // Write out in hex format
1411: char outArray[] = new char[32];
1412: for (int n = 0; n < digestBytes.length; n++) {
1413: int hiNibble = (digestBytes[n] & 0xFF) >> 4;
1414: int loNibble = (digestBytes[n] & 0xF);
1415: outArray[2 * n] = (hiNibble > 9 ? (char) (hiNibble + 87)
1416: : (char) (hiNibble + 48));
1417: outArray[2 * n + 1] = (loNibble > 9 ? (char) (loNibble + 87)
1418: : (char) (loNibble + 48));
1419: }
1420:
1421: String newSessionId = new String(outArray);
1422: this .currentSessionIds.put(this .webappConfig.getContextPath(),
1423: newSessionId);
1424: return this .webappConfig.makeNewSession(newSessionId);
1425: }
1426:
1427: public void markSessionsAsRequestFinished(long lastAccessedTime,
1428: boolean saveSessions) {
1429: for (Iterator i = this .usedSessions.iterator(); i.hasNext();) {
1430: WinstoneSession session = (WinstoneSession) i.next();
1431: session.setLastAccessedDate(lastAccessedTime);
1432: session.removeUsed(this );
1433: if (saveSessions) {
1434: session.saveToTemp();
1435: }
1436: }
1437: this .usedSessions.clear();
1438: }
1439:
1440: /**
1441: * @deprecated
1442: */
1443: public String getRealPath(String path) {
1444: return this .webappConfig.getRealPath(path);
1445: }
1446:
1447: /**
1448: * @deprecated
1449: */
1450: public boolean isRequestedSessionIdFromUrl() {
1451: return isRequestedSessionIdFromURL();
1452: }
1453:
1454: }
|