You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by pi...@apache.org on 2001/08/05 20:33:42 UTC

cvs commit: jakarta-tomcat-connectors/webapp/java WarpRequestHandler.java

pier        01/08/05 11:33:42

  Modified:    webapp/java WarpRequestHandler.java
  Log:
  Compliancy patch:
  
  - Now values of URL-encoded sessions are correctly handled (Thanks to
    Eryq <er...@zeegee.com> for reporting this bug.
  - Locales are set correctly in the request object, parsing the
    Accept-Languages header as done in the HTTP/1.1 connector.
  - The query string is now set to null if there are no query parameters.
  
  With this patch, mod_webapp using WARP runs all WatchDog compliancy tests
  just fine.
  
  Revision  Changes    Path
  1.15      +165 -15   jakarta-tomcat-connectors/webapp/java/WarpRequestHandler.java
  
  Index: WarpRequestHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/webapp/java/WarpRequestHandler.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- WarpRequestHandler.java	2001/07/25 22:32:05	1.14
  +++ WarpRequestHandler.java	2001/08/05 18:33:42	1.15
  @@ -59,7 +59,12 @@
   import java.io.File;
   import java.io.IOException;
   import java.net.URL;
  +import java.util.*;
  +import java.util.Locale;
  +import java.util.TreeMap;
  +
   import javax.servlet.http.Cookie;
  +import javax.servlet.http.HttpServletRequest;
   
   import org.apache.catalina.Container;
   import org.apache.catalina.Context;
  @@ -68,9 +73,13 @@
   import org.apache.catalina.Host;
   import org.apache.catalina.core.StandardHost;
   import org.apache.catalina.util.RequestUtil;
  +import org.apache.catalina.util.StringParser;
   
   public class WarpRequestHandler {
   
  +    private StringParser parser = new StringParser();
  +    private static final String match=";"+Globals.SESSION_PARAMETER_NAME+"=";
  +
       /* ==================================================================== */
       /* Constructor                                                          */
       /* ==================================================================== */
  @@ -118,8 +127,9 @@
                       response.setPacket(packet);
   
                       request.setMethod(meth);
  -                    request.setRequestURI(ruri);
  -                    request.setQueryString(args);
  +                    this.processUri(logger,request,ruri);
  +                    if (args.length()>0) request.setQueryString(args);
  +                    else request.setQueryString(null);
                       request.setProtocol(prot);
                       request.setConnection(connection);
                       Context ctx=connector.applicationContext(id);
  @@ -163,10 +173,7 @@
                   case Constants.TYPE_REQ_HEADER: {
                       String hnam=packet.readString();
                       String hval=packet.readString();
  -                    if (Constants.DEBUG)
  -                        logger.debug("Request header "+hnam+": "+hval);
  -                    request.addHeader(hnam,hval);
  -                    this.processHeader(request,hnam,hval);
  +                    this.processHeader(logger,request,hnam,hval);
                       break;
                   }
   
  @@ -220,9 +227,43 @@
                   }
               }
           }
  +    }
  +
  +    private void processUri(WarpLogger logger, WarpRequest req, String uri) {
  +
  +        // Parse any requested session ID out of the request URI
  +        int semicolon = uri.indexOf(match);
  +        if (semicolon >= 0) {
  +            String rest = uri.substring(semicolon + match.length());
  +            int semicolon2 = rest.indexOf(';');
  +            if (semicolon2 >= 0) {
  +                req.setRequestedSessionId(rest.substring(0, semicolon2));
  +                rest = rest.substring(semicolon2);
  +            } else {
  +                req.setRequestedSessionId(rest);
  +                rest = "";
  +            }
  +            req.setRequestedSessionURL(true);
  +            uri = uri.substring(0, semicolon) + rest;
  +            if (Constants.DEBUG) {
  +                logger.log("Requested URL session id is " +
  +                    ((HttpServletRequest) req.getRequest())
  +                    .getRequestedSessionId());
  +            }
  +        } else {
  +            req.setRequestedSessionId(null);
  +            req.setRequestedSessionURL(false);
  +        }
  +
  +        req.setRequestURI(uri);
       }
  -    
  -    private void processHeader(WarpRequest req, String name, String value) {
  +
  +    private void processHeader(WarpLogger logger, WarpRequest req,
  +                 String name, String value) {
  +
  +        if (Constants.DEBUG)
  +            logger.debug("Request header "+name+": "+value);
  +
           if ("cookie".equalsIgnoreCase(name)) {
               Cookie cookies[] = RequestUtil.parseCookieHeader(value);
               for (int i = 0; i < cookies.length; i++) {
  @@ -235,17 +276,126 @@
                               (cookies[i].getValue());
                           req.setRequestedSessionCookie(true);
                           req.setRequestedSessionURL(false);
  -/*                        if (Constants.DEBUG)
  -                            logger.debug(" Requested cookie session id is " +
  -                                ((HttpServletRequest) request.getRequest())
  +                        if (Constants.DEBUG) {
  +                            logger.debug("Requested cookie session id is " +
  +                                ((HttpServletRequest) req.getRequest())
                                   .getRequestedSessionId());
  -*/                    }
  +                        }
  +                    }
                   }
  -/*                if (Constants.DEBUG)
  -                    logger.debug(" Adding cookie " + cookies[i].getName() + "=" +
  +                if (Constants.DEBUG) {
  +                    logger.debug("Adding cookie "+cookies[i].getName()+"="+
                           cookies[i].getValue());
  -*/                req.addCookie(cookies[i]);
  +                }
  +                req.addCookie(cookies[i]);
  +            }
  +        }
  +        if (name.equalsIgnoreCase("Accept-Language"))
  +            parseAcceptLanguage(logger,req,value);
  +        req.addHeader(name,value);
  +    }
  +
  +    /**
  +     * Parse the value of an <code>Accept-Language</code> header, and add
  +     * the corresponding Locales to the current request.
  +     *
  +     * @param value The value of the <code>Accept-Language</code> header.
  +     */
  +    private void parseAcceptLanguage(WarpLogger logger, WarpRequest request, 
  +                                     String value) {
  +
  +        // Store the accumulated languages that have been requested in
  +        // a local collection, sorted by the quality value (so we can
  +        // add Locales in descending order).  The values will be ArrayLists
  +        // containing the corresponding Locales to be added
  +        TreeMap locales = new TreeMap();
  +
  +        // Preprocess the value to remove all whitespace
  +        int white = value.indexOf(' ');
  +        if (white < 0)
  +            white = value.indexOf('\t');
  +        if (white >= 0) {
  +            StringBuffer sb = new StringBuffer();
  +            int len = value.length();
  +            for (int i = 0; i < len; i++) {
  +                char ch = value.charAt(i);
  +                if ((ch != ' ') && (ch != '\t'))
  +                    sb.append(ch);
  +            }
  +            value = sb.toString();
  +        }
  +
  +        // Process each comma-delimited language specification
  +        parser.setString(value);        // ASSERT: parser is available to us
  +        int length = parser.getLength();
  +        while (true) {
  +
  +            // Extract the next comma-delimited entry
  +            int start = parser.getIndex();
  +            if (start >= length)
  +                break;
  +            int end = parser.findChar(',');
  +            String entry = parser.extract(start, end).trim();
  +            parser.advance();   // For the following entry
  +
  +            // Extract the quality factor for this entry
  +            double quality = 1.0;
  +            int semi = entry.indexOf(";q=");
  +            if (semi >= 0) {
  +                try {
  +                    quality = Double.parseDouble(entry.substring(semi + 3));
  +                } catch (NumberFormatException e) {
  +                    quality = 0.0;
  +                }
  +                entry = entry.substring(0, semi);
  +            }
  +
  +            // Skip entries we are not going to keep track of
  +            if (quality < 0.00005)
  +                continue;       // Zero (or effectively zero) quality factors
  +            if ("*".equals(entry))
  +                continue;       // FIXME - "*" entries are not handled
  +
  +            // Extract the language and country for this entry
  +            String language = null;
  +            String country = null;
  +            int dash = entry.indexOf('-');
  +            if (dash < 0) {
  +                language = entry;
  +                country = "";
  +            } else {
  +                language = entry.substring(0, dash);
  +                country = entry.substring(dash + 1);
               }
  +
  +            // Add a new Locale to the list of Locales for this quality level
  +            Locale locale = new Locale(language, country);
  +            Double key = new Double(-quality);  // Reverse the order
  +            ArrayList values = (ArrayList) locales.get(key);
  +            if (values == null) {
  +                values = new ArrayList();
  +                locales.put(key, values);
  +            }
  +            values.add(locale);
  +
           }
  +
  +        // Process the quality values in highest->lowest order (due to
  +        // negating the Double value when creating the key)
  +        Iterator keys = locales.keySet().iterator();
  +        while (keys.hasNext()) {
  +            Double key = (Double) keys.next();
  +            ArrayList list = (ArrayList) locales.get(key);
  +            Iterator values = list.iterator();
  +            while (values.hasNext()) {
  +                Locale locale = (Locale) values.next();
  +                if (Constants.DEBUG) {
  +                    logger.debug("Adding locale '" + locale + "'");
  +                }
  +                request.addLocale(locale);
  +            }
  +        }
       }
  +
  +
   }