wms-winstone-1.0.5

port 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.RequestDispatcher;
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;
import net.winstone.WinstoneException;
import net.winstone.core.authentication.AuthenticationPrincipal;
import net.winstone.util.SizeRestrictedHashMap;
import net.winstone.util.SizeRestrictedHashtable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WinstoneRequest
  implements HttpServletRequest
{
  protected static Logger logger = LoggerFactory.getLogger(WinstoneRequest.class);
  protected static final DateFormat headerDF = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
  
  static
  {
    headerDF.setTimeZone(TimeZone.getTimeZone("GMT"));
  }
  
  protected static final Random rnd = new Random(System.currentTimeMillis());
  protected Map<String, Object> attributes;
  protected Map<String, String[]> parameters;
  protected Stack<Map<String, Object>> attributesStack;
  protected Stack<Map<String, String[]>> parametersStack;
  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<String, String> requestedSessionIds;
  protected Map<String, String> currentSessionIds;
  protected String deadRequestedSessionId;
  protected List<Locale> 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 final Set<WinstoneSession> usedSessions;
  private final int maxParamAllowed;
  
  public WinstoneRequest(int maxParamAllowed)
    throws IOException
  {
    this.maxParamAllowed = (maxParamAllowed < 1 ? WinstoneConstant.DEFAULT_MAXIMUM_PARAMETER_ALLOWED.intValue() : maxParamAllowed);
    attributes = new HashMap();
    parameters = new SizeRestrictedHashtable(this.maxParamAllowed);
    locales = new ArrayList();
    attributesStack = new Stack();
    parametersStack = new Stack();
    
    requestedSessionIds = new HashMap();
    currentSessionIds = new HashMap();
    usedSessions = new HashSet();
    contentLength = -1;
    isSecure = Boolean.FALSE.booleanValue();
    try
    {
      md5Digester = MessageDigest.getInstance("MD5");
    }
    catch (NoSuchAlgorithmException err)
    {
      throw new WinstoneException("MD5 digester unavailable - what the ...?");
    }
  }
  
  public void cleanUp()
  {
    requestListeners = null;
    requestAttributeListeners = null;
    attributes.clear();
    parameters.clear();
    attributesStack.clear();
    parametersStack.clear();
    
    usedSessions.clear();
    headers = null;
    cookies = null;
    method = null;
    scheme = null;
    serverName = null;
    requestURI = null;
    servletPath = null;
    pathInfo = null;
    queryString = null;
    protocol = null;
    contentLength = -1;
    contentType = null;
    encoding = null;
    inputData = null;
    inputReader = null;
    servletConfig = null;
    webappConfig = null;
    hostGroup = null;
    serverPort = -1;
    remoteIP = null;
    remoteName = null;
    remotePort = -1;
    localAddr = null;
    localName = null;
    localPort = -1;
    parsedParameters = null;
    requestedSessionIds.clear();
    currentSessionIds.clear();
    deadRequestedSessionId = null;
    locales.clear();
    authorization = null;
    isSecure = Boolean.FALSE.booleanValue();
    authenticatedUser = null;
  }
  
  private String extractFirstHeader(String name)
  {
    for (int n = 0; n < headers.length; n++) {
      if (headers[n].toUpperCase().startsWith(name.toUpperCase() + ':')) {
        return headers[n].substring(name.length() + 1).trim();
      }
    }
    return null;
  }
  
  private Collection<String> extractHeaderNameList()
  {
    Collection<String> headerNames = new HashSet();
    for (int n = 0; n < headers.length; n++)
    {
      String name = headers[n];
      int colonPos = name.indexOf(':');
      headerNames.add(name.substring(0, colonPos));
    }
    return headerNames;
  }
  
  public Map<String, Object> getAttributes()
  {
    return attributes;
  }
  
  public Map<String, String[]> getParameters()
  {
    return parameters;
  }
  
  public Stack<Map<String, Object>> getAttributesStack()
  {
    return attributesStack;
  }
  
  public Stack<Map<String, String[]>> getParametersStack()
  {
    return parametersStack;
  }
  
  public Map<String, String> getCurrentSessionIds()
  {
    return currentSessionIds;
  }
  
  public Map<String, String> getRequestedSessionIds()
  {
    return requestedSessionIds;
  }
  
  public String getDeadRequestedSessionId()
  {
    return deadRequestedSessionId;
  }
  
  public HostGroup getHostGroup()
  {
    return hostGroup;
  }
  
  public WebAppConfiguration getWebAppConfig()
  {
    return webappConfig;
  }
  
  public ServletConfiguration getServletConfig()
  {
    return servletConfig;
  }
  
  public String getEncoding()
  {
    return encoding;
  }
  
  public Boolean getParsedParameters()
  {
    return parsedParameters;
  }
  
  public List<Locale> getListLocales()
  {
    return 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)
  {
    serverPort = port;
  }
  
  public void setRemoteIP(String remoteIP)
  {
    this.remoteIP = remoteIP;
  }
  
  public void setRemoteName(String name)
  {
    remoteName = name;
  }
  
  public void setRemotePort(int port)
  {
    remotePort = port;
  }
  
  public void setLocalAddr(String ip)
  {
    localName = ip;
  }
  
  public void setLocalName(String name)
  {
    localName = name;
  }
  
  public void setLocalPort(int port)
  {
    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)
  {
    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)
  {
    protocol = protocolString;
  }
  
  public void setRemoteUser(AuthenticationPrincipal user)
  {
    authenticatedUser = user;
  }
  
  public void setContentLength(int len)
  {
    contentLength = len;
  }
  
  public void setContentType(String type)
  {
    contentType = type;
  }
  
  public void setAuthorization(String auth)
  {
    authorization = auth;
  }
  
  public void setLocales(List<Locale> locales)
  {
    this.locales = locales;
  }
  
  public void setCurrentSessionIds(Map<String, String> currentSessionIds)
  {
    this.currentSessionIds = currentSessionIds;
  }
  
  public void setRequestedSessionIds(Map<String, String> 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)
  {
    parsedParameters = parsed;
  }
  
  public void setRequestListeners(ServletRequestListener[] rl)
  {
    requestListeners = rl;
  }
  
  public void setRequestAttributeListeners(ServletRequestAttributeListener[] ral)
  {
    requestAttributeListeners = ral;
  }
  
  public static void extractParameters(String urlEncodedParams, String encoding, Map<String, String[]> outputParams, boolean overwrite)
  {
    logger.debug("Parsing parameters: {} (using encoding {})", urlEncodedParams, encoding);
    StringTokenizer st = new StringTokenizer(urlEncodedParams, "&", Boolean.FALSE.booleanValue());
    Set<String> overwrittenParamNames = null;
    while (st.hasMoreTokens())
    {
      String token = st.nextToken();
      int equalPos = token.indexOf('=');
      try
      {
        String decodedName = decodeURLToken(equalPos == -1 ? token : token.substring(0, equalPos), encoding == null ? "UTF-8" : encoding);
        String decodedValue = equalPos == -1 ? "" : decodeURLToken(token.substring(equalPos + 1), encoding == null ? "UTF-8" : encoding);
        
        String[] already = null;
        if (overwrite)
        {
          if (overwrittenParamNames == null) {
            overwrittenParamNames = new HashSet();
          }
          if (!overwrittenParamNames.contains(decodedName))
          {
            overwrittenParamNames.add(decodedName);
            outputParams.remove(decodedName);
          }
        }
        already = (String[])outputParams.get(decodedName);
        if (already == null)
        {
          outputParams.put(decodedName, new String[] { decodedValue });
        }
        else
        {
          String[] alreadyArray = 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);
        }
      }
      catch (UnsupportedEncodingException err)
      {
        logger.error("Error parsing request parameters", err);
      }
    }
  }
  
  public static String decodeURLToken(String in)
  {
    try
    {
      return decodeURLToken(in, "UTF-8");
    }
    catch (UnsupportedEncodingException e)
    {
      throw new AssertionError();
    }
  }
  
  public static String decodeURLToken(String in, String encoding)
    throws UnsupportedEncodingException
  {
    return URLDecoder.decode(in, encoding);
  }
  
  public static String decodePathURLToken(String in)
  {
    try
    {
      return decodePathURLToken(in, "UTF-8");
    }
    catch (UnsupportedEncodingException e)
    {
      throw new AssertionError();
    }
  }
  
  public static String decodePathURLToken(String in, String encoding)
    throws UnsupportedEncodingException
  {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    if (in == null) {
      return new String("");
    }
    for (int n = 0; n < in.length(); n++)
    {
      char thisChar = in.charAt(n);
      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);
          baos.write(decoded);
          n += 2;
        }
        catch (RuntimeException err)
        {
          logger.warn("Found an invalid character %{} in url parameter. Echoing through in escaped form", token);
          baos.write(thisChar);
        }
      }
      else
      {
        baos.write(thisChar);
      }
    }
    return new String(baos.toByteArray(), encoding);
  }
  
  public void discardRequestBody()
  {
    if (getContentLength() > 0) {
      try
      {
        logger.debug("Forcing request body parse");
        
        byte[] buffer = new byte['?'];
        while (inputData.read(buffer) != -1) {}
      }
      catch (IOException err)
      {
        logger.error("Forcing request body parse", err);
      }
    }
  }
  
  public void parseRequestParameters()
  {
    if ((parsedParameters != null) && (!parsedParameters.booleanValue()))
    {
      logger.warn("Called getInputStream after getParameter ... error");
      parsedParameters = Boolean.TRUE;
    }
    else if (parsedParameters == null)
    {
      Map<String, String[]> workingParameters = new SizeRestrictedHashMap(maxParamAllowed);
      try
      {
        if (queryString != null)
        {
          extractParameters(queryString, encoding, workingParameters, Boolean.FALSE.booleanValue());
          logger.debug("Param line: " + workingParameters);
        }
        if ((method.equals("POST")) && (contentType != null) && ((contentType.equals("application/x-www-form-urlencoded")) || (contentType.startsWith("application/x-www-form-urlencoded;"))))
        {
          logger.debug("Parsing request body for parameters");
          
          byte[] paramBuffer = new byte[contentLength];
          int readCount = inputData.readAsMuchAsPossible(paramBuffer, 0, contentLength);
          if (readCount != contentLength) {
            logger.warn("Content-length said {}, actual length was {}", Integer.toString(contentLength), Integer.toString(readCount));
          }
          String paramLine = encoding == null ? new String(paramBuffer) : new String(paramBuffer, encoding);
          extractParameters(paramLine.trim(), encoding, workingParameters, Boolean.FALSE.booleanValue());
          logger.debug("Param line: " + workingParameters.toString());
        }
        parameters.putAll(workingParameters);
        parsedParameters = Boolean.TRUE;
      }
      catch (Throwable err)
      {
        logger.error("Error parsing body of the reques", err);
        parsedParameters = null;
      }
    }
  }
  
  public void parseHeaders(List<String> headerList)
  {
    List<String> outHeaderList = new ArrayList();
    List<Cookie> cookieList = new ArrayList();
    for (Iterator<String> 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();
      
      outHeaderList.add(header);
      if (name.equalsIgnoreCase("Authorization"))
      {
        authorization = value;
      }
      else if (name.equalsIgnoreCase("Accept-Language"))
      {
        locales = parseLocales(value);
      }
      else if (name.equalsIgnoreCase("Content-Length"))
      {
        contentLength = Integer.parseInt(value);
      }
      else if (name.equalsIgnoreCase("Host"))
      {
        if ((value.indexOf('[') != -1) && (value.indexOf(']') != -1))
        {
          serverName = value.substring(value.indexOf('['), value.indexOf(']') + 1);
          int nextColonPos = value.indexOf("]:");
          if ((nextColonPos == -1) || (nextColonPos == value.length() - 1))
          {
            if (scheme != null) {
              if (scheme.equals("http")) {
                serverPort = 80;
              } else if (scheme.equals("https")) {
                serverPort = 443;
              }
            }
          }
          else {
            serverPort = Integer.parseInt(value.substring(nextColonPos + 2));
          }
        }
        else
        {
          int nextColonPos = value.indexOf(':');
          if ((nextColonPos == -1) || (nextColonPos == value.length() - 1))
          {
            serverName = value;
            if (scheme != null) {
              if (scheme.equals("http")) {
                serverPort = 80;
              } else if (scheme.equals("https")) {
                serverPort = 443;
              }
            }
          }
          else
          {
            serverName = value.substring(0, nextColonPos);
            serverPort = Integer.parseInt(value.substring(nextColonPos + 1));
          }
        }
      }
      else if (name.equalsIgnoreCase("Content-Type"))
      {
        contentType = value;
        int semicolon = value.lastIndexOf(';');
        if (semicolon != -1)
        {
          String encodingClause = value.substring(semicolon + 1).trim();
          if (encodingClause.startsWith("charset=")) {
            encoding = encodingClause.substring(8);
          }
        }
      }
      else if ((name.equalsIgnoreCase("Cookie")) || (name.equalsIgnoreCase("Cookie2")))
      {
        parseCookieLine(value, cookieList);
      }
    }
    headers = ((String[])outHeaderList.toArray(new String[0]));
    if (cookieList.isEmpty()) {
      cookies = null;
    } else {
      cookies = ((Cookie[])cookieList.toArray(new Cookie[0]));
    }
  }
  
  private static String nextToken(StringTokenizer st)
  {
    if (st.hasMoreTokens()) {
      return st.nextToken();
    }
    return null;
  }
  
  private void parseCookieLine(String headerValue, List<Cookie> cookieList)
  {
    StringTokenizer st = new StringTokenizer(headerValue, ";", Boolean.FALSE.booleanValue());
    int version = 0;
    String cookieLine = nextToken(st);
    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);
    }
    while (cookieLine != null)
    {
      cookieLine = cookieLine.trim();
      int equalPos = cookieLine.indexOf('=');
      if (equalPos == -1)
      {
        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);
        
        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.debug("Found cookie: " + thisCookie.toString());
        if (thisCookie.getName().equals(WinstoneSession.SESSION_COOKIE_NAME))
        {
          HostConfiguration hostConfig = hostGroup.getHostByName(serverName);
          WebAppConfiguration ownerContext = hostConfig.getWebAppBySessionKey(thisCookie.getValue());
          if (ownerContext != null)
          {
            requestedSessionIds.put(ownerContext.getContextPath(), thisCookie.getValue());
            currentSessionIds.put(ownerContext.getContextPath(), thisCookie.getValue());
          }
          else
          {
            deadRequestedSessionId = thisCookie.getValue();
          }
          logger.debug("Found session cookie: {} {}", thisCookie.getValue(), "prefix:" + ownerContext.getContextPath());
        }
      }
    }
  }
  
  private static String extractFromQuotes(String input)
  {
    if ((input != null) && (input.startsWith("\"")) && (input.endsWith("\""))) {
      return input.substring(1, input.length() - 1);
    }
    return input;
  }
  
  private List<Locale> parseLocales(String header)
  {
    StringBuilder lb = new StringBuilder();
    for (int n = 0; n < header.length(); n++)
    {
      char c = header.charAt(n);
      if (!Character.isWhitespace(c)) {
        lb.append(c);
      }
    }
    Map<Float, List<Locale>> localeEntries = new SizeRestrictedHashMap(maxParamAllowed);
    StringTokenizer commaTK = new StringTokenizer(lb.toString(), ",", Boolean.FALSE.booleanValue());
    while (commaTK.hasMoreTokens())
    {
      String clause = commaTK.nextToken();
      
      Float quality = new Float(1.0F);
      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.0F);
        }
        clause = clause.substring(0, pos);
      }
      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);
      
      List<Locale> localeList = (List)localeEntries.get(quality);
      if (localeList == null)
      {
        localeList = new ArrayList();
        localeEntries.put(quality, localeList);
      }
      localeList.add(loc);
    }
    Float[] orderKeys = (Float[])localeEntries.keySet().toArray(new Float[0]);
    Arrays.sort(orderKeys);
    List<Locale> outputLocaleList = new ArrayList();
    Iterator<Locale> i;
    for (int n = 0; n < orderKeys.length; n++)
    {
      int reversedIndex = orderKeys.length - 1 - n;
      if ((orderKeys[reversedIndex].floatValue() > 0.0F) && (orderKeys[reversedIndex].floatValue() <= 1.0F))
      {
        List<Locale> localeList = (List)localeEntries.get(orderKeys[reversedIndex]);
        for (i = localeList.iterator(); i.hasNext();) {
          outputLocaleList.add(i.next());
        }
      }
    }
    return outputLocaleList;
  }
  
  public void addIncludeQueryParameters(String queryString)
  {
    Map<String, String[]> lastParams = new SizeRestrictedHashtable(maxParamAllowed);
    if (!parametersStack.isEmpty()) {
      lastParams.putAll((Map)parametersStack.peek());
    }
    Map<String, String[]> newQueryParams = new SizeRestrictedHashMap(maxParamAllowed);
    if (queryString != null) {
      extractParameters(queryString, encoding, newQueryParams, Boolean.FALSE.booleanValue());
    }
    lastParams.putAll(newQueryParams);
    parametersStack.push(lastParams);
  }
  
  public void addIncludeAttributes(String requestURI, String contextPath, String servletPath, String pathInfo, String queryString)
  {
    Map<String, Object> includeAttributes = new HashMap();
    if (requestURI != null) {
      includeAttributes.put("javax.servlet.include.request_uri", requestURI);
    }
    if (contextPath != null) {
      includeAttributes.put("javax.servlet.include.context_path", contextPath);
    }
    if (servletPath != null) {
      includeAttributes.put("javax.servlet.include.servlet_path", servletPath);
    }
    if (pathInfo != null) {
      includeAttributes.put("javax.servlet.include.path_info", pathInfo);
    }
    if (queryString != null) {
      includeAttributes.put("javax.servlet.include.query_string", queryString);
    }
    attributesStack.push(includeAttributes);
  }
  
  public void removeIncludeQueryString()
  {
    if (!parametersStack.isEmpty()) {
      parametersStack.pop();
    }
  }
  
  public void clearIncludeStackForForward()
  {
    parametersStack.clear();
    attributesStack.clear();
  }
  
  public void setForwardQueryString(String forwardQueryString)
  {
    if (forwardQueryString != null)
    {
      String oldQueryString = queryString == null ? "" : queryString;
      boolean needJoiner = (!forwardQueryString.equals("")) && (!oldQueryString.equals(""));
      queryString = (forwardQueryString + (needJoiner ? "&" : "") + oldQueryString);
      if (parsedParameters != null)
      {
        logger.debug("Parsing parameters: {} (using encoding {})", forwardQueryString, encoding);
        extractParameters(forwardQueryString, encoding, parameters, Boolean.TRUE.booleanValue());
        logger.debug("Param line: {}", parameters != null ? parameters.toString() : "");
      }
    }
  }
  
  public void removeIncludeAttributes()
  {
    if (!attributesStack.isEmpty()) {
      attributesStack.pop();
    }
  }
  
  public Object getAttribute(String name)
  {
    if (!attributesStack.isEmpty())
    {
      Map<String, Object> includedAttributes = (Map)attributesStack.peek();
      Object value = includedAttributes.get(name);
      if (value != null) {
        return value;
      }
    }
    return attributes.get(name);
  }
  
  public Enumeration<String> getAttributeNames()
  {
    Map<String, Object> result = new HashMap(attributes);
    if (!attributesStack.isEmpty())
    {
      Map<String, Object> includedAttributes = (Map)attributesStack.peek();
      result.putAll(includedAttributes);
    }
    return Collections.enumeration(result.keySet());
  }
  
  public void removeAttribute(String name)
  {
    Object value = attributes.get(name);
    if (value == null) {
      return;
    }
    if (requestAttributeListeners != null) {
      for (int n = 0; n < requestAttributeListeners.length; n++)
      {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(getWebAppConfig().getLoader());
        requestAttributeListeners[n].attributeRemoved(new ServletRequestAttributeEvent(webappConfig, this, name, value));
        Thread.currentThread().setContextClassLoader(cl);
      }
    }
    attributes.remove(name);
  }
  
  public void setAttribute(String name, Object o)
  {
    if ((name != null) && (o != null))
    {
      Object oldValue = attributes.get(name);
      attributes.put(name, o);
      if (requestAttributeListeners != null) {
        if (oldValue == null) {
          for (int n = 0; n < requestAttributeListeners.length; n++)
          {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            Thread.currentThread().setContextClassLoader(getWebAppConfig().getLoader());
            requestAttributeListeners[n].attributeAdded(new ServletRequestAttributeEvent(webappConfig, this, name, o));
            Thread.currentThread().setContextClassLoader(cl);
          }
        } else {
          for (int n = 0; n < requestAttributeListeners.length; n++)
          {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            Thread.currentThread().setContextClassLoader(getWebAppConfig().getLoader());
            requestAttributeListeners[n].attributeReplaced(new ServletRequestAttributeEvent(webappConfig, this, name, oldValue));
            Thread.currentThread().setContextClassLoader(cl);
          }
        }
      }
    }
    else if (name != null)
    {
      removeAttribute(name);
    }
  }
  
  public String getCharacterEncoding()
  {
    return encoding;
  }
  
  public void setCharacterEncoding(String encoding)
    throws UnsupportedEncodingException
  {
    "blah".getBytes(encoding);
    if (inputReader == null)
    {
      logger.debug("Setting the request encoding from {} to {}", this.encoding, encoding);
      this.encoding = encoding;
    }
  }
  
  public int getContentLength()
  {
    return contentLength;
  }
  
  public String getContentType()
  {
    return contentType;
  }
  
  public Locale getLocale()
  {
    return locales.isEmpty() ? Locale.getDefault() : (Locale)locales.get(0);
  }
  
  public Enumeration<Locale> getLocales()
  {
    List<Locale> sendLocales = locales;
    if (sendLocales.isEmpty()) {
      sendLocales.add(Locale.getDefault());
    }
    return Collections.enumeration(sendLocales);
  }
  
  public String getProtocol()
  {
    return protocol;
  }
  
  public String getScheme()
  {
    return scheme;
  }
  
  public boolean isSecure()
  {
    return isSecure;
  }
  
  public BufferedReader getReader()
    throws IOException
  {
    if (inputReader != null) {
      return inputReader;
    }
    if (parsedParameters != null) {
      if (parsedParameters.equals(Boolean.TRUE)) {
        logger.warn("Called getReader after getParameter ... error");
      } else {
        throw new IllegalStateException("Called getReader() after getInputStream() on request");
      }
    }
    if (encoding != null) {
      inputReader = new BufferedReader(new InputStreamReader(inputData, encoding));
    } else {
      inputReader = new BufferedReader(new InputStreamReader(inputData));
    }
    parsedParameters = Boolean.FALSE;
    return inputReader;
  }
  
  public ServletInputStream getInputStream()
    throws IOException
  {
    if (inputReader != null) {
      throw new IllegalStateException("Called getInputStream() after getReader() on request");
    }
    if ((parsedParameters != null) && 
      (parsedParameters.equals(Boolean.TRUE))) {
      logger.warn("Called getInputStream after getParameter ... error");
    }
    if ((method.equals("POST")) && ("application/x-www-form-urlencoded".equals(contentType))) {
      parsedParameters = Boolean.FALSE;
    }
    return inputData;
  }
  
  public String getParameter(String name)
  {
    parseRequestParameters();
    String[] param = null;
    if (!parametersStack.isEmpty()) {
      param = (String[])((Map)parametersStack.peek()).get(name);
    }
    if (param == null) {
      param = (String[])parameters.get(name);
    }
    if (param == null) {
      return null;
    }
    return param[0];
  }
  
  public Enumeration<String> getParameterNames()
  {
    parseRequestParameters();
    Set<String> parameterKeys = new HashSet(parameters.keySet());
    if (!parametersStack.isEmpty()) {
      parameterKeys.addAll(((Map)parametersStack.peek()).keySet());
    }
    return Collections.enumeration(parameterKeys);
  }
  
  public String[] getParameterValues(String name)
  {
    parseRequestParameters();
    String[] param = null;
    if (!parametersStack.isEmpty()) {
      param = (String[])((Map)parametersStack.peek()).get(name);
    }
    if (param == null) {
      param = (String[])parameters.get(name);
    }
    if (param == null) {
      return null;
    }
    return param;
  }
  
  public Map<String, Object> getParameterMap()
  {
    Hashtable<String, Object> paramMap = new SizeRestrictedHashtable(maxParamAllowed);
    for (Enumeration<String> names = getParameterNames(); names.hasMoreElements();)
    {
      String name = (String)names.nextElement();
      paramMap.put(name, getParameterValues(name));
    }
    return paramMap;
  }
  
  public String getServerName()
  {
    return serverName;
  }
  
  public int getServerPort()
  {
    return serverPort;
  }
  
  public String getRemoteAddr()
  {
    return remoteIP;
  }
  
  public String getRemoteHost()
  {
    return remoteName;
  }
  
  public int getRemotePort()
  {
    return remotePort;
  }
  
  public String getLocalAddr()
  {
    return localAddr;
  }
  
  public String getLocalName()
  {
    return localName;
  }
  
  public int getLocalPort()
  {
    return localPort;
  }
  
  public RequestDispatcher getRequestDispatcher(String path)
  {
    if (path.startsWith("/")) {
      return webappConfig.getRequestDispatcher(path);
    }
    String fullPath = getServletPath() + (getPathInfo() == null ? "" : getPathInfo());
    int lastSlash = fullPath.lastIndexOf('/');
    String currentDir = lastSlash == -1 ? "/" : fullPath.substring(0, lastSlash + 1);
    return webappConfig.getRequestDispatcher(currentDir + path);
  }
  
  public String getContextPath()
  {
    return webappConfig.getContextPath();
  }
  
  public Cookie[] getCookies()
  {
    return cookies;
  }
  
  public long getDateHeader(String name)
  {
    String dateHeader = getHeader(name);
    if (dateHeader == null) {
      return -1L;
    }
    try
    {
      Date date = null;
      synchronized (headerDF)
      {
        date = headerDF.parse(dateHeader);
      }
      return date.getTime();
    }
    catch (ParseException err)
    {
      throw new IllegalArgumentException("Can't convert to date - " + 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<String> getHeaderNames()
  {
    return Collections.enumeration(extractHeaderNameList());
  }
  
  public Enumeration<String> getHeaders(String name)
  {
    List<String> result = new ArrayList();
    for (int n = 0; n < headers.length; n++) {
      if (headers[n].toUpperCase().startsWith(name.toUpperCase() + ':')) {
        result.add(headers[n].substring(name.length() + 1).trim());
      }
    }
    return Collections.enumeration(result);
  }
  
  public String getMethod()
  {
    return method;
  }
  
  public String getPathInfo()
  {
    return pathInfo;
  }
  
  public String getPathTranslated()
  {
    return webappConfig.getRealPath(pathInfo);
  }
  
  public String getQueryString()
  {
    return queryString;
  }
  
  public String getRequestURI()
  {
    return requestURI;
  }
  
  public String getServletPath()
  {
    return servletPath;
  }
  
  public String getRequestedSessionId()
  {
    String actualSessionId = (String)requestedSessionIds.get(webappConfig.getContextPath());
    if (actualSessionId != null) {
      return actualSessionId;
    }
    return 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());
    
    return url;
  }
  
  public Principal getUserPrincipal()
  {
    return authenticatedUser;
  }
  
  public boolean isUserInRole(String role)
  {
    if (authenticatedUser == null) {
      return Boolean.FALSE.booleanValue();
    }
    if (servletConfig.getSecurityRoleRefs() == null) {
      return authenticatedUser.isUserIsInRole(role);
    }
    String replacedRole = (String)servletConfig.getSecurityRoleRefs().get(role);
    return authenticatedUser.isUserIsInRole(replacedRole == null ? role : replacedRole);
  }
  
  public String getAuthType()
  {
    return authenticatedUser == null ? null : authenticatedUser.getAuthType();
  }
  
  public String getRemoteUser()
  {
    return authenticatedUser == null ? null : authenticatedUser.getName();
  }
  
  public boolean isRequestedSessionIdFromCookie()
  {
    return getRequestedSessionId() != null;
  }
  
  public boolean isRequestedSessionIdFromURL()
  {
    return Boolean.FALSE.booleanValue();
  }
  
  public boolean isRequestedSessionIdValid()
  {
    String requestedId = getRequestedSessionId();
    if (requestedId == null) {
      return Boolean.FALSE.booleanValue();
    }
    WinstoneSession ws = webappConfig.getSessionById(requestedId, Boolean.FALSE.booleanValue());
    return ws != null;
  }
  
  public HttpSession getSession()
  {
    return getSession(Boolean.TRUE.booleanValue());
  }
  
  public HttpSession getSession(boolean create)
  {
    String cookieValue = (String)currentSessionIds.get(webappConfig.getContextPath());
    if (cookieValue == null)
    {
      if (!create) {
        return null;
      }
      cookieValue = makeNewSession().getId();
    }
    WinstoneSession session = webappConfig.getSessionById(cookieValue, Boolean.FALSE.booleanValue());
    if ((create) && (session == null)) {
      session = makeNewSession();
    }
    if (session != null)
    {
      usedSessions.add(session);
      session.addUsed(this);
    }
    return session;
  }
  
  public WinstoneSession makeNewSession()
  {
    String cookieValue = "Winstone_" + remoteIP + "_" + serverPort + "_" + System.currentTimeMillis() + rnd.nextLong();
    byte[] digestBytes = md5Digester.digest(cookieValue.getBytes());
    
    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);
    currentSessionIds.put(webappConfig.getContextPath(), newSessionId);
    return webappConfig.makeNewSession(newSessionId);
  }
  
  public void markSessionsAsRequestFinished(long lastAccessedTime, boolean saveSessions)
  {
    for (Iterator<WinstoneSession> i = usedSessions.iterator(); i.hasNext();)
    {
      WinstoneSession session = (WinstoneSession)i.next();
      session.setLastAccessedDate(lastAccessedTime);
      session.removeUsed(this);
      if (saveSessions) {
        session.saveToTemp();
      }
    }
    usedSessions.clear();
  }
  
  @Deprecated
  public String getRealPath(String path)
  {
    return webappConfig.getRealPath(path);
  }
  
  @Deprecated
  public boolean isRequestedSessionIdFromUrl()
  {
    return isRequestedSessionIdFromURL();
  }
}

/* Location:
 * Qualified Name:     net.winstone.core.WinstoneRequest
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package net.winstone.core;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TimeZone;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import net.winstone.WinstoneResourceBundle;
import net.winstone.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WinstoneResponse
  implements HttpServletResponse
{
  private static final DateFormat HTTP_DF = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
  private static final DateFormat VERSION0_DF = new SimpleDateFormat("EEE, dd-MMM-yy HH:mm:ss z", Locale.US);
  protected static Logger logger = LoggerFactory.getLogger(WinstoneResponse.class);
  
  static
  {
    HTTP_DF.setTimeZone(TimeZone.getTimeZone("GMT"));
    VERSION0_DF.setTimeZone(TimeZone.getTimeZone("GMT"));
  }
  
  public static fin
1 2 3 4 5 6 7 8 9 10 11 12 13 14

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd