Package winstone

Source Code of winstone.WinstoneRequest

/*
* Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
* Distributed under the terms of either:
* - the common development and distribution license (CDDL), v1.0; or
* - the GNU Lesser General Public License, v2.1 or later
*/
package winstone;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TimeZone;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


/**
* Implements the request interface required by the servlet spec.
*
* @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
* @version $Id: WinstoneRequest.java,v 1.38 2007/10/28 16:29:02 rickknowles Exp $
*/
public class WinstoneRequest implements HttpServletRequest {
    protected static DateFormat headerDF = new SimpleDateFormat(
            "EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
    protected static Random rnd = null;
    static {
        headerDF.setTimeZone(TimeZone.getTimeZone("GMT"));
        rnd = new Random(System.currentTimeMillis());
    }

    // Request header constants
    static final String CONTENT_LENGTH_HEADER = "Content-Length";
    static final String CONTENT_TYPE_HEADER = "Content-Type";
    static final String AUTHORIZATION_HEADER = "Authorization";
    static final String LOCALE_HEADER = "Accept-Language";
    static final String HOST_HEADER = "Host";
    static final String IN_COOKIE_HEADER1 = "Cookie";
    static final String IN_COOKIE_HEADER2 = "Cookie2";
    static final String METHOD_HEAD = "HEAD";
    static final String METHOD_GET = "GET";
    static final String METHOD_POST = "POST";
    static final String POST_PARAMETERS = "application/x-www-form-urlencoded";

    protected Map attributes;
    protected Map parameters;
    protected Stack attributesStack;
    protected Stack parametersStack;
//    protected Map forwardedParameters;

    protected String headers[];
    protected Cookie cookies[];
   
    protected String method;
    protected String scheme;
    protected String serverName;
    protected String requestURI;
    protected String servletPath;
    protected String pathInfo;
    protected String queryString;
    protected String protocol;
    protected int contentLength;
    protected String contentType;
    protected String encoding;
   
    protected int serverPort;
    protected String remoteIP;
    protected String remoteName;
    protected int remotePort;
    protected String localAddr;
    protected String localName;
    protected int localPort;
    protected Boolean parsedParameters;
    protected Map requestedSessionIds;
    protected Map currentSessionIds;
    protected String deadRequestedSessionId;
    protected List locales;
    protected String authorization;
    protected boolean isSecure;
   
    protected WinstoneInputStream inputData;
    protected BufferedReader inputReader;
    protected ServletConfiguration servletConfig;
    protected WebAppConfiguration webappConfig;
    protected HostGroup hostGroup;

    protected AuthenticationPrincipal authenticatedUser;
    protected ServletRequestAttributeListener requestAttributeListeners[];
    protected ServletRequestListener requestListeners[];
   
    private MessageDigest md5Digester;
   
    private Set usedSessions;
   
    /**
     * InputStream factory method.
     */
    public WinstoneRequest() throws IOException {
        this.attributes = new Hashtable();
        this.parameters = new Hashtable();
        this.locales = new ArrayList();
        this.attributesStack = new Stack();
        this.parametersStack = new Stack();
//        this.forwardedParameters = new Hashtable();
        this.requestedSessionIds = new Hashtable();
        this.currentSessionIds = new Hashtable();
        this.usedSessions = new HashSet();
        this.contentLength = -1;
        this.isSecure = false;
        try {
            this.md5Digester = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException err) {
            throw new WinstoneException(
                    "MD5 digester unavailable - what the ...?");
        }
    }

    /**
     * Resets the request to be reused
     */
    public void cleanUp() {
        this.requestListeners = null;
        this.requestAttributeListeners = null;
        this.attributes.clear();
        this.parameters.clear();
        this.attributesStack.clear();
        this.parametersStack.clear();
//        this.forwardedParameters.clear();
        this.usedSessions.clear();
        this.headers = null;
        this.cookies = null;
        this.method = null;
        this.scheme = null;
        this.serverName = null;
        this.requestURI = null;
        this.servletPath = null;
        this.pathInfo = null;
        this.queryString = null;
        this.protocol = null;
        this.contentLength = -1;
        this.contentType = null;
        this.encoding = null;
        this.inputData = null;
        this.inputReader = null;
        this.servletConfig = null;
        this.webappConfig = null;
        this.hostGroup = null;
        this.serverPort = -1;
        this.remoteIP = null;
        this.remoteName = null;
        this.remotePort = -1;
        this.localAddr = null;
        this.localName = null;
        this.localPort = -1;
        this.parsedParameters = null;
        this.requestedSessionIds.clear();
        this.currentSessionIds.clear();
        this.deadRequestedSessionId = null;
        this.locales.clear();
        this.authorization = null;
        this.isSecure = false;
        this.authenticatedUser = null;
    }

    /**
     * Steps through the header array, searching for the first header matching
     */
    private String extractFirstHeader(String name) {
        for (int n = 0; n < this.headers.length; n++) {
            if (this.headers[n].toUpperCase().startsWith(name.toUpperCase() + ':')) {
                return this.headers[n].substring(name.length() + 1).trim(); // 1 for colon
            }
        }
        return null;
    }

    private Collection extractHeaderNameList() {
        Collection headerNames = new HashSet();
        for (int n = 0; n < this.headers.length; n++) {
            String name = this.headers[n];
            int colonPos = name.indexOf(':');
            headerNames.add(name.substring(0, colonPos));
        }
        return headerNames;
    }

    public Map getAttributes() {
        return this.attributes;
    }

    public Map getParameters() {
        return this.parameters;
    }
//
//    public Map getForwardedParameters() {
//        return this.forwardedParameters;
//    }

    public Stack getAttributesStack() {
        return this.attributesStack;
    }
   
    public Stack getParametersStack() {
        return this.parametersStack;
    }
   
    public Map getCurrentSessionIds() {
        return this.currentSessionIds;
    }
   
    public Map getRequestedSessionIds() {
        return this.requestedSessionIds;
    }
   
    public String getDeadRequestedSessionId() {
        return this.deadRequestedSessionId;
    }

    public HostGroup getHostGroup() {
        return this.hostGroup;
    }

    public WebAppConfiguration getWebAppConfig() {
        return this.webappConfig;
    }

    public ServletConfiguration getServletConfig() {
        return this.servletConfig;
    }

    public String getEncoding() {
        return this.encoding;
    }

    public Boolean getParsedParameters() {
        return this.parsedParameters;
    }

    public List getListLocales() {
        return this.locales;
    }

    public void setInputStream(WinstoneInputStream inputData) {
        this.inputData = inputData;
    }

    public void setHostGroup(HostGroup hostGroup) {
        this.hostGroup = hostGroup;
    }

    public void setWebAppConfig(WebAppConfiguration webappConfig) {
        this.webappConfig = webappConfig;
    }

    public void setServletConfig(ServletConfiguration servletConfig) {
        this.servletConfig = servletConfig;
    }

    public void setServerPort(int port) {
        this.serverPort = port;
    }

    public void setRemoteIP(String remoteIP) {
        this.remoteIP = remoteIP;
    }

    public void setRemoteName(String name) {
        this.remoteName = name;
    }

    public void setRemotePort(int port) {
        this.remotePort = port;
    }

    public void setLocalAddr(String ip) {
        this.localName = ip;
    }

    public void setLocalName(String name) {
        this.localName = name;
    }

    public void setLocalPort(int port) {
        this.localPort = port;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public void setIsSecure(boolean isSecure) {
        this.isSecure = isSecure;
    }

    public void setQueryString(String queryString) {
        this.queryString = queryString;
    }

    public void setServerName(String name) {
        this.serverName = name;
    }

    public void setRequestURI(String requestURI) {
        this.requestURI = requestURI;
    }

    public void setScheme(String scheme) {
        this.scheme = scheme;
    }

    public void setServletPath(String servletPath) {
        this.servletPath = servletPath;
    }

    public void setPathInfo(String pathInfo) {
        this.pathInfo = pathInfo;
    }

    public void setProtocol(String protocolString) {
        this.protocol = protocolString;
    }

    public void setRemoteUser(AuthenticationPrincipal user) {
        this.authenticatedUser = user;
    }

    public void setContentLength(int len) {
        this.contentLength = len;
    }

    public void setContentType(String type) {
        this.contentType = type;
    }

    public void setAuthorization(String auth) {
        this.authorization = auth;
    }

    public void setLocales(List locales) {
        this.locales = locales;
    }

    public void setCurrentSessionIds(Map currentSessionIds) {
        this.currentSessionIds = currentSessionIds;
    }
   
    public void setRequestedSessionIds(Map requestedSessionIds) {
        this.requestedSessionIds = requestedSessionIds;
    }

    public void setDeadRequestedSessionId(String deadRequestedSessionId) {
        this.deadRequestedSessionId = deadRequestedSessionId;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    public void setParsedParameters(Boolean parsed) {
        this.parsedParameters = parsed;
    }

    public void setRequestListeners(ServletRequestListener rl[]) {
        this.requestListeners = rl;
    }

    public void setRequestAttributeListeners(
            ServletRequestAttributeListener ral[]) {
        this.requestAttributeListeners = ral;
    }

    /**
     * Gets parameters from the url encoded parameter string
     */
    public static void extractParameters(String urlEncodedParams,
            String encoding, Map outputParams, boolean overwrite) {
        Logger.log(Logger.DEBUG, Launcher.RESOURCES,
                "WinstoneRequest.ParsingParameters", new String[] {
                        urlEncodedParams, encoding });
        StringTokenizer st = new StringTokenizer(urlEncodedParams, "&", false);
        Set overwrittenParamNames = null;
        while (st.hasMoreTokens()) {
            String token = st.nextToken();
            int equalPos = token.indexOf('=');
            try {
                String decodedNameDefault = decodeURLToken(equalPos == -1 ? token
                        : token.substring(0, equalPos));
                String decodedValueDefault = (equalPos == -1 ? ""
                        : decodeURLToken(token.substring(equalPos + 1)));
                String decodedName = (encoding == null ? decodedNameDefault
                        : new String(decodedNameDefault.getBytes("8859_1"), encoding));
                String decodedValue = (encoding == null ? decodedValueDefault
                        : new String(decodedValueDefault.getBytes("8859_1"), encoding));

                Object already = null;
                if (overwrite) {
                    if (overwrittenParamNames == null) {
                        overwrittenParamNames = new HashSet();
                    }
                    if (!overwrittenParamNames.contains(decodedName)) {
                        overwrittenParamNames.add(decodedName);
                        outputParams.remove(decodedName);
                    }
                }
                already = outputParams.get(decodedName);
                if (already == null) {
                    outputParams.put(decodedName, decodedValue);
                } else if (already instanceof String) {
                    String pair[] = new String[2];
                    pair[0] = (String) already;
                    pair[1] = decodedValue;
                    outputParams.put(decodedName, pair);
                } else if (already instanceof String[]) {
                    String alreadyArray[] = (String[]) already;
                    String oneMore[] = new String[alreadyArray.length + 1];
                    System.arraycopy(alreadyArray, 0, oneMore, 0,
                            alreadyArray.length);
                    oneMore[oneMore.length - 1] = decodedValue;
                    outputParams.put(decodedName, oneMore);
                } else {
                    Logger.log(Logger.WARNING, Launcher.RESOURCES,
                            "WinstoneRequest.UnknownParameterType",
                            decodedName + " = " + decodedValue.getClass());
                }
            } catch (UnsupportedEncodingException err) {
                Logger.log(Logger.ERROR, Launcher.RESOURCES,
                        "WinstoneRequest.ErrorParameters", err);
            }
        }
    }

    /**
     * For decoding the URL encoding used on query strings
     */
    public static String decodeURLToken(String in) {
        StringBuffer workspace = new StringBuffer();
        for (int n = 0; n < in.length(); n++) {
            char thisChar = in.charAt(n);
            if (thisChar == '+')
                workspace.append(' ');
            else if (thisChar == '%') {
                String token = in.substring(Math.min(n + 1, in.length()),
                        Math.min(n + 3, in.length()));
                try {
                    int decoded = Integer.parseInt(token, 16);
                    workspace.append((char) decoded);
                    n += 2;
                } catch (RuntimeException err) {
                    Logger.log(Logger.WARNING, Launcher.RESOURCES, "WinstoneRequest.InvalidURLTokenChar", token);
                    workspace.append(thisChar);
                }
            } else
                workspace.append(thisChar);
        }
        return workspace.toString();
    }
   
    public void discardRequestBody() {
        if (getContentLength() > 0) {
            try {
                Logger.log(Logger.DEBUG, Launcher.RESOURCES, "WinstoneResponse.ForceBodyParsing");
                // If body not parsed
                if ((this.parsedParameters == null) ||
                        (this.parsedParameters.equals(Boolean.FALSE))) {
                    // read full stream length
                    try {
                        InputStream in = getInputStream();
                        byte buffer[] = new byte[2048];
                        while (in.read(buffer) != -1);
                    } catch (IllegalStateException err) {
                        Reader in = getReader();
                        char buffer[] = new char[2048];
                        while (in.read(buffer) != -1);
                    }
                }
            } catch (IOException err) {
                Logger.log(Logger.DEBUG, Launcher.RESOURCES, "WinstoneResponse.ErrorForceBodyParsing", err);
            }
        }
    }   

    /**
     * This takes the parameters in the body of the request and puts them into
     * the parameters map.
     */
    public void parseRequestParameters() {
        if ((parsedParameters != null) && !parsedParameters.booleanValue()) {
            Logger.log(Logger.WARNING, Launcher.RESOURCES,
                    "WinstoneRequest.BothMethods");
            this.parsedParameters = Boolean.TRUE;
        } else if (parsedParameters == null) {
            Map workingParameters = new HashMap();
            try {
                // Parse query string from request
                if ((method.equals(METHOD_GET) || method.equals(METHOD_HEAD) ||
                        method.equals(METHOD_POST))
                        && (this.queryString != null)) {
                    extractParameters(this.queryString, this.encoding, workingParameters, false);
                    Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
                            "WinstoneRequest.ParamLine", "" + workingParameters);
                }
                
                if (method.equals(METHOD_POST) && (contentType != null)
                        && (contentType.equals(POST_PARAMETERS)
                        || contentType.startsWith(POST_PARAMETERS + ";"))) {
                    Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
                            "WinstoneRequest.ParsingBodyParameters");

                    // Parse params
                    byte paramBuffer[] = new byte[contentLength];
                    int readCount = this.inputData.read(paramBuffer);
                    if (readCount != contentLength)
                        Logger.log(Logger.WARNING, Launcher.RESOURCES,
                                "WinstoneRequest.IncorrectContentLength",
                                new String[] { contentLength + "",
                                        readCount + "" });
                    String paramLine = (this.encoding == null ? new String(
                            paramBuffer) : new String(paramBuffer,
                            this.encoding));
                    extractParameters(paramLine.trim(), this.encoding, workingParameters, false);
                    Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
                            "WinstoneRequest.ParamLine", "" + workingParameters);
                }
               
                this.parameters.putAll(workingParameters);
                this.parsedParameters = Boolean.TRUE;
            } catch (Throwable err) {
                Logger.log(Logger.ERROR, Launcher.RESOURCES,
                        "WinstoneRequest.ErrorBodyParameters", err);
                this.parsedParameters = null;
            }
        }
    }

    /**
     * Go through the list of headers, and build the headers/cookies arrays for
     * the request object.
     */
    public void parseHeaders(List headerList) {
        // Iterate through headers
        List outHeaderList = new ArrayList();
        List cookieList = new ArrayList();
        for (Iterator i = headerList.iterator(); i.hasNext();) {
            String header = (String) i.next();
            int colonPos = header.indexOf(':');
            String name = header.substring(0, colonPos);
            String value = header.substring(colonPos + 1).trim();

            // Add it to out headers if it's not a cookie
            outHeaderList.add(header);
//            if (!name.equalsIgnoreCase(IN_COOKIE_HEADER1)
//                    && !name.equalsIgnoreCase(IN_COOKIE_HEADER2))

            if (name.equalsIgnoreCase(AUTHORIZATION_HEADER))
                this.authorization = value;
            else if (name.equalsIgnoreCase(LOCALE_HEADER))
                this.locales = parseLocales(value);
            else if (name.equalsIgnoreCase(CONTENT_LENGTH_HEADER))
                this.contentLength = Integer.parseInt(value);
            else if (name.equalsIgnoreCase(HOST_HEADER)) {
                int nextColonPos = value.indexOf(':');
                if ((nextColonPos == -1) || (nextColonPos == value.length() - 1)) {
                    this.serverName = value;
                    if (this.scheme != null) {
                        if (this.scheme.equals("http")) {
                            this.serverPort = 80;
                        } else if (this.scheme.equals("https")) {
                            this.serverPort = 443;
                        }
                    }
                } else {
                    this.serverName = value.substring(0, nextColonPos);
                    this.serverPort = Integer.parseInt(value.substring(nextColonPos + 1));
                }
            }
            else if (name.equalsIgnoreCase(CONTENT_TYPE_HEADER)) {
                this.contentType = value;
                int semicolon = value.lastIndexOf(';');
                if (semicolon != -1) {
                    String encodingClause = value.substring(semicolon + 1).trim();
                    if (encodingClause.startsWith("charset="))
                        this.encoding = encodingClause.substring(8);
                }
            } else if (name.equalsIgnoreCase(IN_COOKIE_HEADER1)
                    || name.equalsIgnoreCase(IN_COOKIE_HEADER2))
                parseCookieLine(value, cookieList);
        }
        this.headers = (String[]) outHeaderList.toArray(new String[0]);
        if (cookieList.isEmpty()) {
            this.cookies = null;
        } else {
            this.cookies = (Cookie[]) cookieList.toArray(new Cookie[0]);
        }
    }

    private static String nextToken(StringTokenizer st) {
        if (st.hasMoreTokens()) {
            return st.nextToken();
        } else {
            return null;
        }
    }
   
    private void parseCookieLine(String headerValue, List cookieList) {
        StringTokenizer st = new StringTokenizer(headerValue, ";", false);
        int version = 0;
        String cookieLine = nextToken(st);

        // check cookie version flag
        if ((cookieLine != null) && cookieLine.startsWith("$Version=")) {
            int equalPos = cookieLine.indexOf('=');
            try {
                version = Integer.parseInt(extractFromQuotes(
                        cookieLine.substring(equalPos + 1).trim()));
            } catch (NumberFormatException err) {
                version = 0;
            }
            cookieLine = nextToken(st);
        }

        // process remainder - parameters
        while (cookieLine != null) {
            cookieLine = cookieLine.trim();
            int equalPos = cookieLine.indexOf('=');
            if (equalPos == -1) {
                // next token
                cookieLine = nextToken(st);
            } else {
                String name = cookieLine.substring(0, equalPos);
                String value = extractFromQuotes(cookieLine.substring(equalPos + 1));
                Cookie thisCookie = new Cookie(name, value);
                thisCookie.setVersion(version);
                thisCookie.setSecure(isSecure());
                cookieList.add(thisCookie);

                // check for path / domain / port
                cookieLine = nextToken(st);
                while ((cookieLine != null) && cookieLine.trim().startsWith("$")) {
                    cookieLine = cookieLine.trim();
                    equalPos = cookieLine.indexOf('=');
                    String attrValue = equalPos == -1 ? "" : cookieLine
                            .substring(equalPos + 1).trim();
                    if (cookieLine.startsWith("$Path")) {
                        thisCookie.setPath(extractFromQuotes(attrValue));
                    } else if (cookieLine.startsWith("$Domain")) {
                        thisCookie.setDomain(extractFromQuotes(attrValue));
                    }
                    cookieLine = nextToken(st);
                }

                Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
                        "WinstoneRequest.CookieFound", thisCookie.toString());
                if (thisCookie.getName().equals(WinstoneSession.SESSION_COOKIE_NAME)) {
                    // Find a context that manages this key
                    HostConfiguration hostConfig = this.hostGroup.getHostByName(this.serverName);
                    WebAppConfiguration ownerContext = hostConfig.getWebAppBySessionKey(thisCookie.getValue());
                    if (ownerContext != null) {
                        this.requestedSessionIds.put(ownerContext.getContextPath(),
                                thisCookie.getValue());
                        this.currentSessionIds.put(ownerContext.getContextPath(),
                                thisCookie.getValue());
                    }
                    // If not found, it was probably dead
                    else {
                        this.deadRequestedSessionId = thisCookie.getValue();
                    }
//                    this.requestedSessionId = thisCookie.getValue();
//                    this.currentSessionId = thisCookie.getValue();
                    Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
                            "WinstoneRequest.SessionCookieFound",
                            new String[] {thisCookie.getValue(),
                            ownerContext == null ? "" : "prefix:" + ownerContext.getContextPath()});
                }
            }
        }
    }
   
    private static String extractFromQuotes(String input) {
        if ((input != null) && input.startsWith("\"") && input.endsWith("\"")) {
            return input.substring(1, input.length() - 1);
        } else {
            return input;
        }
    }

    private List parseLocales(String header) {
        // Strip out the whitespace
        StringBuffer lb = new StringBuffer();
        for (int n = 0; n < header.length(); n++) {
            char c = header.charAt(n);
            if (!Character.isWhitespace(c))
                lb.append(c);
        }

        // Tokenize by commas
        Map localeEntries = new HashMap();
        StringTokenizer commaTK = new StringTokenizer(lb.toString(), ",", false);
        for (; commaTK.hasMoreTokens();) {
            String clause = commaTK.nextToken();

            // Tokenize by semicolon
            Float quality = new Float(1);
            if (clause.indexOf(";q=") != -1) {
                int pos = clause.indexOf(";q=");
                try {
                    quality = new Float(clause.substring(pos + 3));
                } catch (NumberFormatException err) {
                    quality = new Float(0);
                }
                clause = clause.substring(0, pos);
            }

            // Build the locale
            String language = "";
            String country = "";
            String variant = "";
            int dpos = clause.indexOf('-');
            if (dpos == -1)
                language = clause;
            else {
                language = clause.substring(0, dpos);
                String remainder = clause.substring(dpos + 1);
                int d2pos = remainder.indexOf('-');
                if (d2pos == -1)
                    country = remainder;
                else {
                    country = remainder.substring(0, d2pos);
                    variant = remainder.substring(d2pos + 1);
                }
            }
            Locale loc = new Locale(language, country, variant);

            // Put into list by quality
            List localeList = (List) localeEntries.get(quality);
            if (localeList == null) {
                localeList = new ArrayList();
                localeEntries.put(quality, localeList);
            }
            localeList.add(loc);
        }

        // Extract and build the list
        Float orderKeys[] = (Float[]) localeEntries.keySet().toArray(new Float[0]);
        Arrays.sort(orderKeys);
        List outputLocaleList = new ArrayList();
        for (int n = 0; n < orderKeys.length; n++) {
            // Skip backwards through the list of maps and add to the output list
            int reversedIndex = (orderKeys.length - 1) - n;
            if ((orderKeys[reversedIndex].floatValue() <= 0)
                    || (orderKeys[reversedIndex].floatValue() > 1))
                continue;
            List localeList = (List) localeEntries.get(orderKeys[reversedIndex]);
            for (Iterator i = localeList.iterator(); i.hasNext();)
                outputLocaleList.add(i.next());
        }

        return outputLocaleList;
    }

    public void addIncludeQueryParameters(String queryString) {
        Map lastParams = new Hashtable();
        if (!this.parametersStack.isEmpty()) {
            lastParams.putAll((Map) this.parametersStack.peek());
        }
        Map newQueryParams = new HashMap();
        if (queryString != null) {
            extractParameters(queryString, this.encoding, newQueryParams, false);
        }
        lastParams.putAll(newQueryParams);
        this.parametersStack.push(lastParams);
    }

    public void addIncludeAttributes(String requestURI, String contextPath,
            String servletPath, String pathInfo, String queryString) {
        Map includeAttributes = new HashMap();
        if (requestURI != null) {
            includeAttributes.put(RequestDispatcher.INCLUDE_REQUEST_URI, requestURI);
        }
        if (contextPath != null) {
            includeAttributes.put(RequestDispatcher.INCLUDE_CONTEXT_PATH, contextPath);
        }
        if (servletPath != null) {
            includeAttributes.put(RequestDispatcher.INCLUDE_SERVLET_PATH, servletPath);
        }
        if (pathInfo != null) {
            includeAttributes.put(RequestDispatcher.INCLUDE_PATH_INFO, pathInfo);
        }
        if (queryString != null) {
            includeAttributes.put(RequestDispatcher.INCLUDE_QUERY_STRING, queryString);
        }
        this.attributesStack.push(includeAttributes);
    }
   
    public void removeIncludeQueryString() {
        if (!this.parametersStack.isEmpty()) {
            this.parametersStack.pop();
        }
    }
   
    public void clearIncludeStackForForward() {
        this.parametersStack.clear();
        this.attributesStack.clear();
    }
   
    public void setForwardQueryString(String forwardQueryString) {
//        this.forwardedParameters.clear();
       
        // Parse query string from include / forward
        if (forwardQueryString != null) {
            String oldQueryString = this.queryString == null ? "" : this.queryString;
            boolean needJoiner = !forwardQueryString.equals("") && !oldQueryString.equals("")
            this.queryString = forwardQueryString + (needJoiner ? "&" : "") + oldQueryString;
           
            if (this.parsedParameters != null) {
                Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
                        "WinstoneRequest.ParsingParameters", new String[] {
                        forwardQueryString, this.encoding });
                extractParameters(forwardQueryString, this.encoding, this.parameters, true);
                Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
                        "WinstoneRequest.ParamLine", "" + this.parameters);
            }
        }

    }
   
    public void removeIncludeAttributes() {
        if (!this.attributesStack.isEmpty()) {
            this.attributesStack.pop();
        }
    }
   
    // Implementation methods for the servlet request stuff
    public Object getAttribute(String name) {
        if (!this.attributesStack.isEmpty()) {
            Map includedAttributes = (Map) this.attributesStack.peek();
            Object value = includedAttributes.get(name);
            if (value != null) {
                return value;
            }
        }
        return this.attributes.get(name);
    }

    public Enumeration getAttributeNames() {
        Map attributes = new HashMap(this.attributes);
        if (!this.attributesStack.isEmpty()) {
            Map includedAttributes = (Map) this.attributesStack.peek();
            attributes.putAll(includedAttributes);
        }
        return Collections.enumeration(attributes.keySet());
    }

    public void removeAttribute(String name) {
        Object value = attributes.get(name);
        if (value == null)
            return;

        // fire event
        if (this.requestAttributeListeners != null) {
            for (int n = 0; n < this.requestAttributeListeners.length; n++) {
                ClassLoader cl = Thread.currentThread().getContextClassLoader();
                Thread.currentThread().setContextClassLoader(getWebAppConfig().getLoader());
                this.requestAttributeListeners[n].attributeRemoved(
                        new ServletRequestAttributeEvent(this.webappConfig,
                                this, name, value));
                Thread.currentThread().setContextClassLoader(cl);
            }
        }
       
        this.attributes.remove(name);
    }

    public void setAttribute(String name, Object o) {
        if ((name != null) && (o != null)) {
            Object oldValue = attributes.get(name);
            attributes.put(name, o); // make sure it's set at the top level

            // fire event
            if (this.requestAttributeListeners != null) {
                if (oldValue == null) {
                    for (int n = 0; n < this.requestAttributeListeners.length; n++) {
                        ClassLoader cl = Thread.currentThread().getContextClassLoader();
                        Thread.currentThread().setContextClassLoader(getWebAppConfig().getLoader());
                        this.requestAttributeListeners[n].attributeAdded(
                                new ServletRequestAttributeEvent(this.webappConfig,
                                        this, name, o));
                        Thread.currentThread().setContextClassLoader(cl);
                    }
                } else {
                    for (int n = 0; n < this.requestAttributeListeners.length; n++) {
                        ClassLoader cl = Thread.currentThread().getContextClassLoader();
                        Thread.currentThread().setContextClassLoader(getWebAppConfig().getLoader());
                        this.requestAttributeListeners[n]
                                .attributeReplaced(new ServletRequestAttributeEvent(
                                        this.webappConfig, this, name, oldValue));
                        Thread.currentThread().setContextClassLoader(cl);
                    }
                }
            }
        } else if (name != null) {
            removeAttribute(name);
        }
    }

    public String getCharacterEncoding() {
        return this.encoding;
    }

    public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException {
        "blah".getBytes(encoding); // throws an exception if the encoding is unsupported
        if (this.inputReader == null) {
            Logger.log(Logger.DEBUG, Launcher.RESOURCES, "WinstoneRequest.SetCharEncoding",
                    new String[] { this.encoding, encoding });
            this.encoding = encoding;
        }
    }

    public int getContentLength() {
        return this.contentLength;
    }

    public String getContentType() {
        return this.contentType;
    }

    public Locale getLocale() {
        return this.locales.isEmpty() ? Locale.getDefault()
                : (Locale) this.locales.get(0);
    }

    public Enumeration getLocales() {
        List sendLocales = this.locales;
        if (sendLocales.isEmpty())
            sendLocales.add(Locale.getDefault());
        return Collections.enumeration(sendLocales);
    }

    public String getProtocol() {
        return this.protocol;
    }

    public String getScheme() {
        return this.scheme;
    }

    public boolean isSecure() {
        return this.isSecure;
    }

    public BufferedReader getReader() throws IOException {
        if (this.inputReader != null) {
            return this.inputReader;
        } else {
            if (this.parsedParameters != null) {
                if (this.parsedParameters.equals(Boolean.TRUE)) {
                    Logger.log(Logger.WARNING, Launcher.RESOURCES, "WinstoneRequest.BothMethodsReader");
                } else {
                    throw new IllegalStateException(Launcher.RESOURCES.getString(
                            "WinstoneRequest.CalledReaderAfterStream"));
                }
            }
            if (this.encoding != null) {
                this.inputReader = new BufferedReader(new InputStreamReader(
                        this.inputData, this.encoding));
            } else {
                this.inputReader = new BufferedReader(new InputStreamReader(
                        this.inputData));
            }
            this.parsedParameters = new Boolean(false);
            return this.inputReader;
        }
    }

    public ServletInputStream getInputStream() throws IOException {
        if (this.inputReader != null) {
            throw new IllegalStateException(Launcher.RESOURCES.getString(
                    "WinstoneRequest.CalledStreamAfterReader"));
        }
        if (this.parsedParameters != null) {
            if (this.parsedParameters.equals(Boolean.TRUE)) {
                Logger.log(Logger.WARNING, Launcher.RESOURCES, "WinstoneRequest.BothMethods");
            }
        }
        this.parsedParameters = new Boolean(false);
        return this.inputData;
    }

    public String getParameter(String name) {
        parseRequestParameters();
        Object param = null;
        if (!this.parametersStack.isEmpty()) {
            param = ((Map) this.parametersStack.peek()).get(name);
        }
//        if ((param == null) && this.forwardedParameters.get(name) != null) {
//            param = this.forwardedParameters.get(name);
//        }
        if (param == null) {
            param = this.parameters.get(name);
        }
        if (param == null)
            return null;
        else if (param instanceof String)
            return (String) param;
        else if (param instanceof String[])
            return ((String[]) param)[0];
        else
            return param.toString();
    }

    public Enumeration getParameterNames() {
        parseRequestParameters();
        Set parameterKeys = new HashSet(this.parameters.keySet());
//        parameterKeys.addAll(this.forwardedParameters.keySet());
        if (!this.parametersStack.isEmpty()) {
            parameterKeys.addAll(((Map) this.parametersStack.peek()).keySet());
        }
        return Collections.enumeration(parameterKeys);
    }

    public String[] getParameterValues(String name) {
        parseRequestParameters();
        Object param = null;
        if (!this.parametersStack.isEmpty()) {
            param = ((Map) this.parametersStack.peek()).get(name);
        }
//        if ((param == null) && this.forwardedParameters.get(name) != null) {
//            param = this.forwardedParameters.get(name);
//        }
        if (param == null) {
            param = this.parameters.get(name);
        }
        if (param == null)
            return null;
        else if (param instanceof String) {
            return new String[] {(String) param};
        } else if (param instanceof String[])
            return (String[]) param;
        else
            throw new WinstoneException(Launcher.RESOURCES.getString(
                    "WinstoneRequest.UnknownParameterType", name + " - "
                            + param.getClass()));
    }

    public Map getParameterMap() {
        Hashtable paramMap = new Hashtable();
        for (Enumeration names = this.getParameterNames(); names
                .hasMoreElements();) {
            String name = (String) names.nextElement();
            paramMap.put(name, getParameterValues(name));
        }
        return paramMap;
    }

    public String getServerName() {
        return this.serverName;
    }

    public int getServerPort() {
        return this.serverPort;
    }

    public String getRemoteAddr() {
        return this.remoteIP;
    }

    public String getRemoteHost() {
        return this.remoteName;
    }

    public int getRemotePort() {
        return this.remotePort;
    }

    public String getLocalAddr() {
        return this.localAddr;
    }

    public String getLocalName() {
        return this.localName;
    }

    public int getLocalPort() {
        return this.localPort;
    }

    public javax.servlet.RequestDispatcher getRequestDispatcher(String path) {
        if (path.startsWith("/"))
            return this.webappConfig.getRequestDispatcher(path);

        // Take the servlet path + pathInfo, and make an absolute path
        String fullPath = getServletPath()
                + (getPathInfo() == null ? "" : getPathInfo());
        int lastSlash = fullPath.lastIndexOf('/');
        String currentDir = (lastSlash == -1 ? "/" : fullPath.substring(0,
                lastSlash + 1));
        return this.webappConfig.getRequestDispatcher(currentDir + path);
    }

    // Now the stuff for HttpServletRequest
    public String getContextPath() {
        return this.webappConfig.getContextPath();
    }

    public Cookie[] getCookies() {
        return this.cookies;
    }

    public long getDateHeader(String name) {
        String dateHeader = getHeader(name);
        if (dateHeader == null) {
            return -1;
        } else try {
            Date date = null;
            synchronized (headerDF) {
                date = headerDF.parse(dateHeader);
            }
            return date.getTime();
        } catch (java.text.ParseException err) {
            throw new IllegalArgumentException(Launcher.RESOURCES.getString(
                    "WinstoneRequest.BadDate", dateHeader));
        }
    }

    public int getIntHeader(String name) {
        String header = getHeader(name);
        return header == null ? -1 : Integer.parseInt(header);
    }

    public String getHeader(String name) {
        return extractFirstHeader(name);
    }

    public Enumeration getHeaderNames() {
        return Collections.enumeration(extractHeaderNameList());
    }

    public Enumeration getHeaders(String name) {
        List headers = new ArrayList();
        for (int n = 0; n < this.headers.length; n++)
            if (this.headers[n].toUpperCase().startsWith(
                    name.toUpperCase() + ':'))
                headers
                        .add(this.headers[n].substring(name.length() + 1)
                                .trim()); // 1 for colon
        return Collections.enumeration(headers);
    }

    public String getMethod() {
        return this.method;
    }

    public String getPathInfo() {
        return this.pathInfo;
    }

    public String getPathTranslated() {
        return this.webappConfig.getRealPath(this.pathInfo);
    }

    public String getQueryString() {
        return this.queryString;
    }

    public String getRequestURI() {
        return this.requestURI;
    }

    public String getServletPath() {
        return this.servletPath;
    }

    public String getRequestedSessionId() {
        String actualSessionId = (String) this.requestedSessionIds.get(this.webappConfig.getContextPath());
        if (actualSessionId != null) {
            return actualSessionId;
        } else {
            return this.deadRequestedSessionId;
        }
    }

    public StringBuffer getRequestURL() {
        StringBuffer url = new StringBuffer();
        url.append(getScheme()).append("://");
        url.append(getServerName());
        if (!((getServerPort() == 80) && getScheme().equals("http"))
                && !((getServerPort() == 443) && getScheme().equals("https")))
            url.append(':').append(getServerPort());
        url.append(getRequestURI()); // need encoded form, so can't use servlet path + path info
        return url;
    }

    public Principal getUserPrincipal() {
        return this.authenticatedUser;
    }

    public boolean isUserInRole(String role) {
        if (this.authenticatedUser == null)
            return false;
        else if (this.servletConfig.getSecurityRoleRefs() == null)
            return this.authenticatedUser.isUserIsInRole(role);
        else {
            String replacedRole = (String) this.servletConfig.getSecurityRoleRefs().get(role);
            return this.authenticatedUser
                    .isUserIsInRole(replacedRole == null ? role : replacedRole);
        }
    }

    public String getAuthType() {
        return this.authenticatedUser == null ? null : this.authenticatedUser
                .getAuthType();
    }

    public String getRemoteUser() {
        return this.authenticatedUser == null ? null : this.authenticatedUser
                .getName();
    }

    public boolean isRequestedSessionIdFromCookie() {
        return (getRequestedSessionId() != null);
    }

    public boolean isRequestedSessionIdFromURL() {
        return false;
    }

    public boolean isRequestedSessionIdValid() {
        String requestedId = getRequestedSessionId();
        if (requestedId == null) {
            return false;
        }
        WinstoneSession ws = this.webappConfig.getSessionById(requestedId, false);
        return (ws != null);
//        if (ws == null) {
//            return false;
//        } else {
//            return (validationCheck(ws, System.currentTimeMillis(), false) != null);
//        }
    }

    public HttpSession getSession() {
        return getSession(true);
    }

    public HttpSession getSession(boolean create) {
        String cookieValue = (String) this.currentSessionIds.get(this.webappConfig.getContextPath());

        // Handle the null case
        if (cookieValue == null) {
            if (!create) {
                return null;
            } else {
                cookieValue = makeNewSession().getId();
            }
        }

        // Now get the session object
        WinstoneSession session = this.webappConfig.getSessionById(cookieValue, false);
        if (session != null) {
//            long nowDate = System.currentTimeMillis();
//            session = validationCheck(session, nowDate, create);
//            if (session == null) {
//                this.currentSessionIds.remove(this.webappConfig.getContextPath());
//            }
        }
        if (create && (session == null)) {
            session = makeNewSession();
        }
        if (session != null) {
            this.usedSessions.add(session);
            session.addUsed(this);
        }
        return session;
    }

    /**
     * Make a new session, and return the id
     */
    private WinstoneSession makeNewSession() {
        String cookieValue = "Winstone_" + this.remoteIP + "_"
                + this.serverPort + "_" + System.currentTimeMillis() + rnd.nextLong();
        byte digestBytes[] = this.md5Digester.digest(cookieValue.getBytes());

        // Write out in hex format
        char outArray[] = new char[32];
        for (int n = 0; n < digestBytes.length; n++) {
            int hiNibble = (digestBytes[n] & 0xFF) >> 4;
            int loNibble = (digestBytes[n] & 0xF);
            outArray[2 * n] = (hiNibble > 9 ? (char) (hiNibble + 87)
                    : (char) (hiNibble + 48));
            outArray[2 * n + 1] = (loNibble > 9 ? (char) (loNibble + 87)
                    : (char) (loNibble + 48));
        }

        String newSessionId = new String(outArray);
        this.currentSessionIds.put(this.webappConfig.getContextPath(), newSessionId);
        return this.webappConfig.makeNewSession(newSessionId);
    }

    public void markSessionsAsRequestFinished(long lastAccessedTime, boolean saveSessions) {
        for (Iterator i = this.usedSessions.iterator(); i.hasNext(); ) {
            WinstoneSession session = (WinstoneSession) i.next();
            session.setLastAccessedDate(lastAccessedTime);
            session.removeUsed(this);
            if (saveSessions) {
                session.saveToTemp();
            }
        }
        this.usedSessions.clear();
    }
   
    /**
     * @deprecated
     */
    public String getRealPath(String path) {
        return this.webappConfig.getRealPath(path);
    }

    /**
     * @deprecated
     */
    public boolean isRequestedSessionIdFromUrl() {
        return isRequestedSessionIdFromURL();
    }

}
TOP

Related Classes of winstone.WinstoneRequest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.