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/09 22:08:59 UTC

cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp Constants.java WarpConfigurationHandler.java WarpConnector.java WarpPacket.java WarpRequest.java WarpRequestHandler.java WarpResponse.java

pier        01/08/09 13:08:59

  Modified:    catalina/src/share/org/apache/catalina/connector/warp
                        Constants.java WarpConfigurationHandler.java
                        WarpConnector.java WarpPacket.java WarpRequest.java
                        WarpRequestHandler.java WarpResponse.java
  Log:
  Sources integration for Tomcat 4.0 beta 7.
  
  Revision  Changes    Path
  1.3       +205 -5    jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/Constants.java
  
  Index: Constants.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/Constants.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Constants.java	2001/07/22 20:25:08	1.2
  +++ Constants.java	2001/08/09 20:08:58	1.3
  @@ -71,7 +71,7 @@
       /**
        * The WARP protocol minor version.
        */
  -    public static final int VERS_MINOR=9;
  +    public static final int VERS_MINOR=10;
   
       /**
        * INVALID: The packet type hasn't been set yet.
  @@ -113,6 +113,36 @@
       public static final int TYPE_CONF_WELCOME=0x01;
   
       /**
  +     * CONF_ENUM: The client requests to the server to enumerate all
  +     * web-applications available for a specified virtual host. In response
  +     * to this request, the server replies with a set of CONF_ENUM messages
  +     * terminated by a CONF_ENUM_DONE message.
  +     * <br>
  +     * Payload description:<br>
  +     * [string] The virtual host name.<br>
  +     * [ushort] The virtual host port.<br>
  +     */
  +    public static final int TYPE_CONF_ENUM=0x02;
  +
  +    /**
  +     * CONF_ENUM_APPL: The server specifies the name of a web-application
  +     * available for deployment in response to a CONF_ENUMERATE message.
  +     * <br>
  +     * Payload description:<br>
  +     * [string] The web-application name.<br>
  +     */
  +    public static final int TYPE_CONF_ENUM_APPL=0x03;
  +
  +    /**
  +     * CONF_ENUM_DONE: The server specifies all web-application names
  +     * available for deployment for the host specified in the CONF_ENUM
  +     * message have been transfered.
  +     * <br>
  +     * No payload:<br>
  +     */
  +    public static final int TYPE_CONF_ENUM_DONE=0x04;
  +
  +    /**
        * CONF_DEPLOY: The client attempts deploy a web application.
        * <br>
        * Payload description:<br>
  @@ -121,7 +151,7 @@
        * [ushort] The virtual host port.<br>
        * [string] The web-application URL path.<br>
        */
  -    public static final int TYPE_CONF_DEPLOY=0x02;
  +    public static final int TYPE_CONF_DEPLOY=0x05;
   
       /**
        * CONF_APPLIC: The server replies to a CONF_DEPLOY message with the web
  @@ -130,16 +160,56 @@
        * Payload description:<br>
        * [integer] The web application unique id for this server.<br>
        * [string] The web application real path (where it's expanded).<br>
  +     */
  +    public static final int TYPE_CONF_APPLIC=0x06;
  +
  +    /**
  +     * CONF_MAP: The client requests to the server to enumerate all mappings
  +     * for a specified web-application. The server replies to this message
  +     * with a serie of MAP_ALLOW and MAP_DENY packets, terminated by a
  +     * MAP_DONE packet.
  +     * <br>
  +     * Payload description:<br>
  +     * [integer] The web application unique id for this server.<br>
  +     */
  +    public static final int TYPE_CONF_MAP=0x07;
  +
  +    /**
  +     * CONF_MAP_ALLOW: The server replies to a CONF_MAP message with this
  +     * packet to indicate a mapping to a static page, or a resource that
  +     * can be served autonomously by the remote end (the web server).
  +     * <br>
  +     * Payload description:<br>
  +     * [string] An url-pattern as defined by the Servlet specification.
        */
  -    public static final int TYPE_CONF_APPLIC=0x03;
  +    public static final int TYPE_CONF_MAP_ALLOW=0x08;
   
       /**
  +     * CONF_MAP_DENY: The server replies to a CONF_MAP message with this
  +     * packet to indicate a mapping to a resource that must be served by
  +     * the server (servlet container).
  +     * <br>
  +     * Payload description:<br>
  +     * [string] An url-pattern as defined by the Servlet specification.
  +     */
  +    public static final int TYPE_CONF_MAP_DENY=0x09;
  +
  +    /**
  +     * CONF_MAP_DONE: The server replies to a CONF_MAP message with this
  +     * packet to indicate that all servlet mappings have been successfully
  +     * transfered to the other end
  +     * <br>
  +     * No payload:<br>
  +     */
  +    public static final int TYPE_CONF_MAP_DONE=0x0a;
  +
  +    /**
        * CONF_DONE: Client issues this message when all configurations have been
        * processed.
        * <br>
        * No payload:<br>
        */
  -    public static final int TYPE_CONF_DONE=0x04;
  +    public static final int TYPE_CONF_DONE=0x0e;
   
       /**
        * CONF_PROCEED: Server issues this message in response to a CONF_DONE
  @@ -147,20 +217,150 @@
        * <br>
        * No payload:<br>
        */
  -    public static final int TYPE_CONF_PROCEED=0x05;
  +    public static final int TYPE_CONF_PROCEED=0x0f;
   
  +    /**
  +     * REQ_INIT: The client requests to the WARP server that a request is
  +     * about to be processed.
  +     * <br>
  +     * Payload description:<br>
  +     * [integer] The web-application unique ID for this server.<br>
  +     * [string] The HTTP method used for this request.<br>
  +     * [string] The request URI.<br>
  +     * [string] The request query arguments.<br>
  +     * [string] The request protocol (HTTP/1.0, HTTP/1.1...).<br>
  +     */
       public static final int TYPE_REQ_INIT=0x10;
  +
  +    /**
  +     * REQ_CONTENT: The mime content type and length of this request.
  +     * <br>
  +     * Payload description:<br>
  +     * [string] The MIME content type of this reques.<br>
  +     * [integer] The content length of this request.<br>
  +     */
       public static final int TYPE_REQ_CONTENT=0x11;
  +
  +    /**
  +     * REQ_SCHEME: The scheme description of this request.
  +     * <br>
  +     * Payload description:<br>
  +     * [string] The scheme (part before :// in the URL) of this request.<br>
  +     */
       public static final int TYPE_REQ_SCHEME=0x12;
  +
  +    /**
  +     * REQ_AUTH: Authentication information of the HTTP remote peer.
  +     * <br>
  +     * Payload description:<br>
  +     * [string] The remote-user name.<br>
  +     * [string] The authentication information.<br>
  +     */
       public static final int TYPE_REQ_AUTH=0x13;
  +
  +    /**
  +     * REQ_HEADER: An HTTP request header.
  +     * <br>
  +     * Payload description:<br>
  +     * [string] The header name.<br>
  +     * [string] The header value.<br>
  +     */
       public static final int TYPE_REQ_HEADER=0x14;
  +
  +    /**
  +     * REQ_SERVER: The HTTP server information.
  +     * <br>
  +     * Payload description:<br>
  +     * [string] The HTTP server host name.
  +     * [string] The HTTP server IP address.
  +     * [ushort] The port receiving the HTTP request.
  +     */
  +    public static final int TYPE_REQ_SERVER=0x15;
  +
  +    /**
  +     * REQ_CLIENT: The HTTP client (remote peer) information.
  +     * <br>
  +     * Payload description:<br>
  +     * [string] The HTTP client host name.
  +     * [string] The HTTP client IP address.
  +     * [ushort] The remote port originating the HTTP request.
  +     */
  +    public static final int TYPE_REQ_CLIENT=0x16;
  +
  +    /**
  +     * REQ_PROCEED: The client finished transmitting the request. The server
  +     * can now proceed and process the request.
  +     * <br>
  +     * No payload.<br>
  +     */
       public static final int TYPE_REQ_PROCEED=0x1f;
   
  +    /**
  +     * RES_STATUS: The server replies with the HTTP response status for the
  +     * request.
  +     * <br>
  +     * Payload description:<br>
  +     * [ushort] The HTTP status of the response.<br>
  +     * [string] The HTTP response message.<br>
  +     */
       public static final int TYPE_RES_STATUS=0x20;
  +
  +    /**
  +     * RES_HEADER: An HTTP MIME response header to send to the client.
  +     * <br>
  +     * Payload description:<br>
  +     * [string] The MIME header name.<br>
  +     * [string] The MIME header value.<br>
  +     */
       public static final int TYPE_RES_HEADER=0x21;
  +
  +    /**
  +     * RES_COMMIT: The server indicates that the first part of the response
  +     * (HTTP status line and MIME headers) are to be committed to the client
  +     * (remote peer).
  +     * <br>
  +     * No payload.<br>
  +     */
       public static final int TYPE_RES_COMMIT=0x2f;
  +
  +    /**
  +     * RES_BODY: The HTTP response body.
  +     * <br>
  +     * Payload description:<br>
  +     * [raw] A chunk of the response body.<br>
  +     */
       public static final int TYPE_RES_BODY=0x30;
  +
  +    /**
  +     * RES_DONE: The server finished transmitting the response.
  +     * <br>
  +     * No payload.<br>
  +     */
       public static final int TYPE_RES_DONE=0x3f;
   
  +    /**
  +     * CBK_READ: A request callback. The WARP server queries the WARP client
  +     * (HTTP server) to transmit a chunk of the request body.
  +     * <br>
  +     * Payload description:<br>
  +     * [ushort] The number of bytes the server needs to transmit.<br>
  +     */
  +    public static final int TYPE_CBK_READ=0x40;
   
  +    /**
  +     * CBK_DATA: As requested by the WARP server, the WARP client (HTTP
  +     * server) transmits a chunk of the request body.
  +     * <br>
  +     * Payload description:<br>
  +     * [raw] A chunk of the request body.<br>
  +     */
  +    public static final int TYPE_CBK_DATA=0x41;
  +
  +    /**
  +     * CBK_DATA: The WARP client (HTTP server) informs the WARP server that
  +     * the request body has been fully transmitted.
  +     * <br>
  +     * No payload.<br>
  +     */
  +    public static final int TYPE_CBK_DONE=0x42;
   }
  
  
  
  1.3       +106 -10   jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpConfigurationHandler.java
  
  Index: WarpConfigurationHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpConfigurationHandler.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- WarpConfigurationHandler.java	2001/07/22 20:25:08	1.2
  +++ WarpConfigurationHandler.java	2001/08/09 20:08:58	1.3
  @@ -64,11 +64,18 @@
   import org.apache.catalina.Context;
   import org.apache.catalina.Deployer;
   import org.apache.catalina.Host;
  +import org.apache.catalina.Wrapper;
   import org.apache.catalina.core.StandardHost;
   import org.apache.catalina.core.StandardContext;
  +import org.apache.catalina.deploy.FilterMap;
  +import org.apache.catalina.deploy.SecurityConstraint;
  +import org.apache.catalina.deploy.SecurityCollection;
   
   public class WarpConfigurationHandler {
   
  +    private static final String DEFAULT_SERVLET = 
  +        "org.apache.catalina.servlets.DefaultServlet";
  +
       /* ==================================================================== */
       /* Constructor                                                          */
       /* ==================================================================== */
  @@ -118,18 +125,107 @@
                           packet.setType(Constants.TYPE_ERROR);
                           packet.writeString(msg);
                           connection.send(packet);
  -                    } else {
  -                        int k=connection.getConnector().applicationId(context);
  -                        packet.setType(Constants.TYPE_CONF_APPLIC);
  -                        packet.writeInteger(k);
  -                        packet.writeString(context.getDocBase());
  +                        break;
  +                    }
  +                    int k=connection.getConnector().applicationId(context);
  +                    packet.setType(Constants.TYPE_CONF_APPLIC);
  +                    packet.writeInteger(k);
  +                    packet.writeString(context.getDocBase());
  +                    connection.send(packet);
  +                    if (Constants.DEBUG)
  +                        logger.debug("Application \""+appl+"\" deployed "+
  +                                     "under <http://"+host+":"+port+path+
  +                                     "> with root="+context.getDocBase()+
  +                                     " ID="+k);
  +                    break;
  +                }
  +
  +                case Constants.TYPE_CONF_MAP: {
  +                    int id=packet.readInteger();
  +                    Context context=connection.getConnector()
  +                                    .applicationContext(id);
  +
  +                    if (context==null) {
  +                        String msg="Invalid application ID for mappings "+id;
  +                        logger.log(msg);
  +                        packet.reset();
  +                        packet.setType(Constants.TYPE_ERROR);
  +                        packet.writeString(msg);
                           connection.send(packet);
  -                        if (Constants.DEBUG)
  -                            logger.debug("Application \""+appl+"\" deployed "+
  -                                         "under <http://"+host+":"+port+path+
  -                                         "> with root="+context.getDocBase()+
  -                                         " ID="+k);
  +                        break;
                       }
  +
  +                    String smap[]=context.findServletMappings();
  +                    if (smap!=null) {
  +                        for (int x=0; x<smap.length; x++) {
  +                            Container c=context.findChild(
  +                                context.findServletMapping(smap[x]));
  +                            packet.reset();
  +                            packet.setType(Constants.TYPE_CONF_MAP_DENY);
  +                            packet.writeString(smap[x]);
  +
  +                            if (c instanceof Wrapper) {
  +                                String servlet=((Wrapper)c).getServletClass();
  +                                if (DEFAULT_SERVLET.equals(servlet)) {
  +                                    packet.setType(
  +                                        Constants.TYPE_CONF_MAP_ALLOW);
  +                                    if (Constants.DEBUG)
  +                                        logger.debug("Servlet mapping \""+
  +                                                     smap[x]+"\" allowed");
  +                                } else if (Constants.DEBUG) {
  +                                    logger.debug("Servlet mapping \""+smap[x]+
  +                                                 "\" denied");
  +                                }
  +                            }
  +                            connection.send(packet);
  +                        }
  +                    }
  +
  +                    FilterMap fmap[]=context.findFilterMaps();
  +                    if (fmap!=null) {
  +                        logger.log("Filter mappings ("+fmap.length+")");
  +                        for (int x=0; x<fmap.length; x++) {
  +                            String map=fmap[x].getURLPattern();
  +                            if (map!=null) {
  +                                if (Constants.DEBUG)
  +                                    logger.debug("Filter mapping \""+map+
  +                                                 "\" denied");
  +                                packet.reset();
  +                                packet.setType(Constants.TYPE_CONF_MAP_DENY);
  +                                packet.writeString(map);
  +                                connection.send(packet);
  +                            }
  +                        }
  +                    }
  +
  +                    SecurityConstraint scon[]=context.findConstraints();
  +                    if (scon!=null) {
  +                        for (int x=0; x<scon.length; x++) {
  +                            SecurityCollection col[]=scon[x].findCollections();
  +                            if (col!=null) {
  +                                for (int y=0; y<col.length; y++) {
  +                                    String patt[]=col[y].findPatterns();
  +                                    if (patt!=null) {
  +                                        for (int q=0; q<patt.length; q++) {
  +                                            packet.reset();
  +                                            packet.setType(
  +                                                Constants.TYPE_CONF_MAP_DENY);
  +                                            packet.writeString(patt[x]);
  +                                            connection.send(packet);
  +                                            if (Constants.DEBUG) {
  +                                                logger.debug("Seurity "+
  +                                                    " mapping \""+patt[x]+
  +                                                    "\"");
  +                                            }
  +                                        }
  +                                    }
  +                                }
  +                            }
  +                        }
  +                    }
  +                    packet.reset();
  +                    packet.setType(Constants.TYPE_CONF_MAP_DONE);
  +                    connection.send(packet);
                       break;
                   }
   
  
  
  
  1.15      +1 -0      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpConnector.java
  
  Index: WarpConnector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpConnector.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- WarpConnector.java	2001/07/22 22:49:50	1.14
  +++ WarpConnector.java	2001/08/09 20:08:58	1.15
  @@ -462,6 +462,7 @@
        * Start accepting connections by this <code>Connector</code>.
        */
       public void start() throws LifecycleException {
  +        if (!initialized) this.initialize();
           if (started) throw new LifecycleException("Already started");
   
           // Can't get a hold of a server socket
  
  
  
  1.8       +3 -2      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpPacket.java
  
  Index: WarpPacket.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpPacket.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- WarpPacket.java	2001/07/22 20:25:08	1.7
  +++ WarpPacket.java	2001/08/09 20:08:58	1.8
  @@ -66,11 +66,11 @@
       protected int size=0;
   
       /* Pointer to the last byte read in the buffer */
  -    private int pointer=0;
  +    protected int pointer=0;
       /* Type of this packet */
       private int type=-1;
       /* Maximum value for a 16 bit unsigned value (0x0ffff +1) */
  -    private static final int MAX_LENGTH=65536;
  +    private static final int MAX_LENGTH=65535;
   
       /**
        * Construct a new WarpPacket instance.
  @@ -158,6 +158,7 @@
        */
       public void writeString(String string) {
           try {
  +            if (string==null) string="";
               byte temp[]=string.getBytes("UTF-8");
               if ((this.size+temp.length+2)>MAX_LENGTH)
                   throw new ArrayIndexOutOfBoundsException("Too much data");
  
  
  
  1.8       +92 -0     jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpRequest.java
  
  Index: WarpRequest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpRequest.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- WarpRequest.java	2001/07/22 20:25:08	1.7
  +++ WarpRequest.java	2001/08/09 20:08:58	1.8
  @@ -56,15 +56,25 @@
    * ========================================================================= */
   package org.apache.catalina.connector.warp;
   
  +import java.io.*;
  +
   import org.apache.catalina.Context;
   import org.apache.catalina.Host;
   import org.apache.catalina.connector.HttpRequestBase;
   
   public class WarpRequest extends HttpRequestBase {
  +    /** The local stream */
  +    private Stream localstream;
  +
  +    /** The connection to which we are associated */
  +    private WarpConnection connection;
  +
       private Host host=null;
   
       public WarpRequest() {
           super();
  +        this.localstream=new Stream(this);
  +        this.setStream(this.localstream);
       }
   
       public void setHost(Host host) {
  @@ -73,5 +83,87 @@
   
       public Host getHost() {
           return(this.host);
  +    }
  +
  +    /**
  +     * Recycle this <code>WarpResponse</code> instance.
  +     */
  +    public void recycle() {
  +        // Recycle our parent
  +        super.recycle();
  +        // Recycle the stream
  +        this.localstream.recycle();
  +        // Tell the parent that a stream is already in use.
  +        this.setStream(localstream);
  +    }
  +
  +    /**
  +     * Associate this <code>WarpResponse</code> instance with a specific
  +     * <code>WarpConnection</code> instance.
  +     */
  +    public void setConnection(WarpConnection connection) {
  +        this.connection=connection;
  +    }
  +
  +    /**
  +     * Return the <code>WarpConnection</code> associated this instance of
  +     * <code>WarpResponse</code>.
  +     */
  +    public WarpConnection getConnection() {
  +        return(this.connection);
  +    }
  +
  +    protected class Stream extends InputStream {
  +
  +        /** The response associated with this stream instance. */
  +        private WarpRequest request=null;
  +        /** The packet used by this stream instance. */
  +        private WarpPacket packet=null;
  +        /** Wether <code>close()</code> was called or not. */
  +        private boolean closed=false;
  +
  +        protected Stream(WarpRequest request) {
  +            super();
  +            this.request=request;
  +            this.packet=new WarpPacket();
  +            this.packet.setType(Constants.TYPE_CBK_DATA);
  +        }
  +        
  +        public int read()
  +        throws IOException {
  +            if (closed) throw new IOException("Stream closed");
  +
  +            if (packet.getType()==Constants.TYPE_CBK_DONE) return(-1);
  +
  +            if (packet.getType()!=Constants.TYPE_CBK_DATA)
  +                throw new IOException("Invalid WARP packet type for body");
  +
  +            if (this.packet.pointer<this.packet.size)
  +                return((int)this.packet.buffer[this.packet.pointer++]);
  +
  +            this.packet.reset();
  +            this.packet.setType(Constants.TYPE_CBK_READ);
  +            this.packet.writeUnsignedShort(65535);
  +            this.request.getConnection().send(packet);
  +            packet.reset();
  +
  +            this.request.getConnection().recv(packet);
  +            return(this.read());
  +        }
  +        
  +        public void close()
  +        throws IOException {
  +            if (closed) throw new IOException("Stream closed");
  +            this.packet.reset();
  +            this.packet.setType(Constants.TYPE_CBK_DONE);
  +            this.closed=true;
  +        }
  +
  +        public void recycle() {
  +            this.packet.reset();
  +            this.packet.setType(Constants.TYPE_CBK_DATA);
  +            this.closed=false;
  +        }
  +
       }
   }
  
  
  
  1.11      +212 -5    jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpRequestHandler.java
  
  Index: WarpRequestHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpRequestHandler.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- WarpRequestHandler.java	2001/07/22 20:25:08	1.10
  +++ WarpRequestHandler.java	2001/08/09 20:08:58	1.11
  @@ -59,15 +59,27 @@
   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;
   import org.apache.catalina.Deployer;
  +import org.apache.catalina.Globals;
   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                                                          */
       /* ==================================================================== */
  @@ -86,6 +98,7 @@
           response.setRequest(request);
           response.setConnection(connection);
           response.setPacket(packet);
  +        request.setConnection(connection);
   
           // Prepare the Proceed packet
           packet.reset();
  @@ -114,9 +127,11 @@
                       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);
                       if (ctx!=null) {
                           request.setContext(ctx);
  @@ -140,7 +155,7 @@
                   case Constants.TYPE_REQ_SCHEME: {
                       String schm=packet.readString();
                       if (Constants.DEBUG)
  -                        logger.debug("Request schere="+schm);
  +                        logger.debug("Request scheme="+schm);
                       request.setScheme(schm);
                       break;
                   }
  @@ -158,9 +173,31 @@
                   case Constants.TYPE_REQ_HEADER: {
                       String hnam=packet.readString();
                       String hval=packet.readString();
  +                    this.processHeader(logger,request,hnam,hval);
  +                    break;
  +                }
  +
  +                case Constants.TYPE_REQ_SERVER: {
  +                    String host=packet.readString();
  +                    String addr=packet.readString();
  +                    int port=packet.readUnsignedShort();
  +                    if (Constants.DEBUG)
  +                        logger.debug("Server detail "+host+":"+port+
  +                                     " ("+addr+")");
  +                    request.setServerName(host);
  +                    request.setServerPort(port);
  +                    break;
  +                }
  +
  +                case Constants.TYPE_REQ_CLIENT: {
  +                    String host=packet.readString();
  +                    String addr=packet.readString();
  +                    int port=packet.readUnsignedShort();
                       if (Constants.DEBUG)
  -                        logger.debug("Request header "+hnam+": "+hval);
  -                    request.addHeader(hnam,hval);
  +                        logger.debug("Client detail "+host+":"+port+
  +                                     " ("+addr+")");
  +                    request.setRemoteHost(host);
  +                    request.setRemoteAddr(addr);
                       break;
                   }
   
  @@ -191,4 +228,174 @@
               }
           }
       }
  +
  +    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(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++) {
  +                if (cookies[i].getName().equals
  +                    (Globals.SESSION_COOKIE_NAME)) {
  +                    // Override anything requested in the URL
  +                    if (!req.isRequestedSessionIdFromCookie()) {
  +                        // Accept only the first session id cookie
  +                        req.setRequestedSessionId
  +                            (cookies[i].getValue());
  +                        req.setRequestedSessionCookie(true);
  +                        req.setRequestedSessionURL(false);
  +                        if (Constants.DEBUG) {
  +                            logger.debug("Requested cookie session id is " +
  +                                ((HttpServletRequest) req.getRequest())
  +                                .getRequestedSessionId());
  +                        }
  +                    }
  +                }
  +                if (Constants.DEBUG) {
  +                    logger.debug("Adding cookie "+cookies[i].getName()+"="+
  +                        cookies[i].getValue());
  +                }
  +                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);
  +            }
  +        }
  +    }
  +
  +
   }
  
  
  
  1.7       +1 -1      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpResponse.java
  
  Index: WarpResponse.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/warp/WarpResponse.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- WarpResponse.java	2001/07/22 20:25:08	1.6
  +++ WarpResponse.java	2001/08/09 20:08:58	1.7
  @@ -164,7 +164,6 @@
   
           this.packet.reset();
           this.packet.setType(Constants.TYPE_RES_STATUS);
  -        this.packet.writeString(request.getRequest().getProtocol());
           this.packet.writeUnsignedShort(status);
           this.packet.writeString(message);
           this.connection.send(this.packet);
  @@ -276,6 +275,7 @@
           public void write(int b)
           throws IOException {
               if (closed) throw new IOException("Stream closed");
  +            if (packet.size>=packet.buffer.length) this.flush();
               packet.buffer[packet.size++]=(byte)b;
           }