remm        01/01/22 19:55:55

  Added:       catalina/src/share/org/apache/catalina/connector/http10
                        Constants.java HttpConnector.java
                        HttpProcessor.java HttpRequestImpl.java
                        HttpResponseImpl.java LocalStrings.properties
  Log:
  - Rename "test" connector to "http10" connector.
  - Added a socket timeout, and a connection timeout parameter
    (which default to 30s).
  
  Revision  Changes    Path
  1.1                  
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/Constants.java
  
  Index: Constants.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/Constants.java,v
 1.1 2001/01/23 03:55:54 remm Exp $
   * $Revision: 1.1 $
   * $Date: 2001/01/23 03:55:54 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  
  
  package org.apache.catalina.connector.http10;
  
  
  import org.apache.catalina.Globals;
  
  
  /**
   * Static constants for this package.
   */
  
  public final class Constants {
  
      public static final String Package = 
          "org.apache.catalina.connector.http10";
      public static final String ServerInfo =
        Globals.SERVER_INFO + " (HTTP/1.0 Connector)";
      public static final int DEFAULT_CONNECTION_TIMEOUT = 30000;
  
  }
  
  
  
  1.1                  
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/HttpConnector.java
  
  Index: HttpConnector.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/HttpConnector.java,v
 1.1 2001/01/23 03:55:54 remm Exp $
   * $Revision: 1.1 $
   * $Date: 2001/01/23 03:55:54 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  
  package org.apache.catalina.connector.http10;
  
  
  import java.io.IOException;
  import java.net.InetAddress;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.util.Stack;
  import java.util.Vector;
  import org.apache.catalina.Connector;
  import org.apache.catalina.Container;
  import org.apache.catalina.HttpRequest;
  import org.apache.catalina.HttpResponse;
  import org.apache.catalina.Lifecycle;
  import org.apache.catalina.LifecycleEvent;
  import org.apache.catalina.LifecycleException;
  import org.apache.catalina.LifecycleListener;
  import org.apache.catalina.Logger;
  import org.apache.catalina.Request;
  import org.apache.catalina.Response;
  import org.apache.catalina.net.DefaultServerSocketFactory;
  import org.apache.catalina.net.ServerSocketFactory;
  import org.apache.catalina.util.LifecycleSupport;
  import org.apache.catalina.util.StringManager;
  
  
  /**
   * Simple implementation of an HTTP/1.0 Connector, for testing and debugging
   * purposes.  Not intended to be the final solution.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2001/01/23 03:55:54 $
   */
  
  
  public final class HttpConnector
      implements Connector, Lifecycle, Runnable {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The accept count for this Connector.
       */
      private int acceptCount = 10;
  
  
      /**
       * The IP address on which to bind, if any.  If <code>null</code>, all
       * addresses on the server will be bound.
       */
      private String address = null;
  
  
      /**
       * The input buffer size we should create on input streams.
       */
      private int bufferSize = 2048;
  
  
      /**
       * The Container used for processing requests received by this Connector.
       */
      protected Container container = null;
  
  
      /**
       * The set of processors that have ever been created.
       */
      private Vector created = new Vector();
  
  
      /**
       * The current number of processors that have been created.
       */
      private int curProcessors = 0;
  
  
      /**
       * The debugging detail level for this component.
       */
      private int debug = 0;
  
  
      /**
       * The server socket factory for this component.
       */
      private ServerSocketFactory factory = null;
  
  
      /**
       * Descriptive information about this Connector implementation.
       */
      private static final String info =
        "org.apache.catalina.connector.http10.HttpConnector/1.0";
  
  
      /**
       * The lifecycle event support for this component.
       */
      protected LifecycleSupport lifecycle = new LifecycleSupport(this);
  
  
      /**
       * Timeout value on the incoming connection.
       * Note : a negative value of 0 means no timeout.
       */
      private int connectionTimeout = Constants.DEFAULT_CONNECTION_TIMEOUT;
  
  
      /**
       * The minimum number of processors to start at initialization time.
       */
      protected int minProcessors = 5;
  
  
      /**
       * The maximum number of processors allowed, or <0 for unlimited.
       */
      private int maxProcessors = 20;
  
  
      /**
       * The port number on which we listen for HTTP requests.
       */
      private int port = 8080;
  
  
      /**
       * The set of processors that have been created but are not currently
       * being used to process a request.
       */
      private Stack processors = new Stack();
  
  
      /**
       * The request scheme that will be set on all requests received
       * through this connector.
       */
      private String scheme = "http";
  
  
      /**
       * The secure connection flag that will be set on all requests received
       * through this connector.
       */
      private boolean secure = false;
  
  
      /**
       * The server socket through which we listen for incoming TCP connections.
       */
      private ServerSocket serverSocket = null;
  
  
      /**
       * The string manager for this package.
       */
      private StringManager sm =
        StringManager.getManager(Constants.Package);
  
  
      /**
       * Has this component been started yet?
       */
      private boolean started = false;
  
  
      /**
       * The shutdown signal to our background thread
       */
      private boolean stopped = false;
  
  
      /**
       * The background thread.
       */
      private Thread thread = null;
  
  
      /**
       * The name to register for the background thread.
       */
      private String threadName = null;
  
  
      /**
       * The thread synchronization object.
       */
      private Object threadSync = new Object();
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * Return the connection timeout for this Connector.
       */
      public int getConnectionTimeout() {
  
        return (connectionTimeout);
  
      }
  
  
      /**
       * Set the connection timeout for this Connector.
       *
       * @param count The new connection timeout
       */
      public void setConnectionTimeout(int connectionTimeout) {
  
        this.connectionTimeout = connectionTimeout;
  
      }
  
  
      /**
       * Return the accept count for this Connector.
       */
      public int getAcceptCount() {
  
        return (acceptCount);
  
      }
  
  
      /**
       * Set the accept count for this Connector.
       *
       * @param count The new accept count
       */
      public void setAcceptCount(int count) {
  
        this.acceptCount = count;
  
      }
  
  
      /**
       * Return the bind IP address for this Connector.
       */
      public String getAddress() {
  
        return (this.address);
  
      }
  
  
      /**
       * Set the bind IP address for this Connector.
       *
       * @param address The bind IP address
       */
      public void setAddress(String address) {
  
        this.address = address;
  
      }
  
  
      /**
       * Is this connector available for processing requests?
       */
      public boolean isAvailable() {
  
        return (started);
  
      }
  
  
      /**
       * Return the input buffer size for this Connector.
       */
      public int getBufferSize() {
  
        return (this.bufferSize);
  
      }
  
  
      /**
       * Set the input buffer size for this Connector.
       *
       * @param bufferSize The new input buffer size.
       */
      public void setBufferSize(int bufferSize) {
  
        this.bufferSize = bufferSize;
  
      }
  
  
      /**
       * Return the Container used for processing requests received by this
       * Connector.
       */
      public Container getContainer() {
  
        return (container);
  
      }
  
  
      /**
       * Set the Container used for processing requests received by this
       * Connector.
       *
       * @param container The new Container to use
       */
      public void setContainer(Container container) {
  
        this.container = container;
  
      }
  
  
      /**
       * Return the current number of processors that have been created.
       */
      public int getCurProcessors() {
  
        return (curProcessors);
  
      }
  
  
      /**
       * Return the debugging detail level for this component.
       */
      public int getDebug() {
  
          return (debug);
  
      }
  
  
      /**
       * Set the debugging detail level for this component.
       *
       * @param debug The new debugging detail level
       */
      public void setDebug(int debug) {
  
          this.debug = debug;
  
      }
  
  
      /**
       * Return the server socket factory used by this Container.
       */
      public ServerSocketFactory getFactory() {
  
          if (this.factory == null) {
              synchronized (this) {
                  this.factory = new DefaultServerSocketFactory();
              }
          }
          return (this.factory);
  
      }
  
  
      /**
       * Set the server socket factory used by this Container.
       *
       * @param factory The new server socket factory
       */
      public void setFactory(ServerSocketFactory factory) {
  
          this.factory = factory;
  
      }
  
  
      /**
       * Return descriptive information about this Connector implementation.
       */
      public String getInfo() {
  
        return (info);
  
      }
  
  
      /**
       * Return the minimum number of processors to start at initialization.
       */
      public int getMinProcessors() {
  
        return (minProcessors);
  
      }
  
  
      /**
       * Set the minimum number of processors to start at initialization.
       *
       * @param minProcessors The new minimum processors
       */
      public void setMinProcessors(int minProcessors) {
  
        this.minProcessors = minProcessors;
  
      }
  
  
      /**
       * Return the maximum number of processors allowed, or <0 for unlimited.
       */
      public int getMaxProcessors() {
  
        return (maxProcessors);
  
      }
  
  
      /**
       * Set the maximum number of processors allowed, or <0 for unlimited.
       *
       * @param maxProcessors The new maximum processors
       */
      public void setMaxProcessors(int maxProcessors) {
  
        this.maxProcessors = maxProcessors;
  
      }
  
  
      /**
       * Return the port number on which we listen for HTTP requests.
       */
      public int getPort() {
  
        return (this.port);
  
      }
  
  
      /**
       * Set the port number on which we listen for HTTP requests.
       *
       * @param port The new port number
       */
      public void setPort(int port) {
  
        this.port = port;
  
      }
  
  
      /**
       * Return the scheme that will be assigned to requests received
       * through this connector.  Default value is "http".
       */
      public String getScheme() {
  
        return (this.scheme);
  
      }
  
  
      /**
       * Set the scheme that will be assigned to requests received through
       * this connector.
       *
       * @param scheme The new scheme
       */
      public void setScheme(String scheme) {
  
        this.scheme = scheme;
  
      }
  
  
      /**
       * Return the secure connection flag that will be assigned to requests
       * received through this connector.  Default value is "false".
       */
      public boolean getSecure() {
  
        return (this.secure);
  
      }
  
  
      /**
       * Set the secure connection flag that will be assigned to requests
       * received through this connector.
       *
       * @param secure The new secure connection flag
       */
      public void setSecure(boolean secure) {
  
        this.secure = secure;
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Create (or allocate) and return a Request object suitable for
       * specifying the contents of a Request to the responsible Container.
       */
      public Request createRequest() {
  
        HttpRequestImpl request = new HttpRequestImpl();
        request.setConnector(this);
        return (request);
  
      }
  
  
      /**
       * Create (or allocate) and return a Response object suitable for
       * receiving the contents of a Response from the responsible Container.
       */
      public Response createResponse() {
  
        HttpResponseImpl response = new HttpResponseImpl();
        response.setConnector(this);
        return (response);
  
      }
  
  
      // -------------------------------------------------------- Package Methods
  
  
      /**
       * Recycle the specified Processor so that it can be used again.
       *
       * @param processor The processor to be recycled
       */
      void recycle(HttpProcessor processor) {
  
          processors.push(processor);
  
      }
  
  
      // -------------------------------------------------------- Private Methods
  
  
      /**
       * Create (or allocate) and return an available processor for use in
       * processing a specific HTTP request, if possible.  If the maximum
       * allowed processors have already been created and are in use, return
       * <code>null</code> instead.
       */
      private HttpProcessor createProcessor() {
  
        synchronized (processors) {
            if (processors.size() > 0)
                return ((HttpProcessor) processors.pop());
            if ((maxProcessors > 0) && (curProcessors < maxProcessors))
                return (newProcessor());
            else
                return (null);
        }
  
      }
  
  
      /**
       * Log a message on the Logger associated with our Container (if any).
       *
       * @param message Message to be logged
       */
      private void log(String message) {
  
        Logger logger = container.getLogger();
        if (logger != null)
            logger.log(threadName + " " + message);
        else
            System.out.println(threadName + " " + message);
  
      }
  
  
      /**
       * Log a message on the Logger associated with our Container (if any).
       *
       * @param message Message to be logged
       * @param throwable Associated exception
       */
      private void log(String message, Throwable throwable) {
  
        Logger logger = container.getLogger();
        if (logger != null)
            logger.log(threadName + " " + message, throwable);
        else {
            System.out.println(threadName + " " + message);
            throwable.printStackTrace(System.out);
        }
  
      }
  
  
      /**
       * Create and return a new processor suitable for processing HTTP
       * requests and returning the corresponding responses.
       */
      private HttpProcessor newProcessor() {
  
          HttpProcessor processor = new HttpProcessor(this, curProcessors++);
        if (processor instanceof Lifecycle) {
            try {
                ((Lifecycle) processor).start();
            } catch (LifecycleException e) {
                log("newProcessor", e);
                return (null);
            }
        }
        created.addElement(processor);
        return (processor);
  
      }
  
  
      /**
       * Open and return the server socket for this Connector.  If an IP
       * address has been specified, the socket will be opened only on that
       * address; otherwise it will be opened on all addresses.
       *
       * @exception IOException if an input/output error occurs
       */
      private ServerSocket open() throws IOException {
  
          // Acquire the server socket factory for this Connector
          ServerSocketFactory factory = getFactory();
  
        // If no address is specified, open a connection on all addresses
          if (address == null) {
            log(sm.getString("httpConnector.allAddresses"));
              return (factory.createSocket(port, acceptCount));
        }
  
        // Open a server socket on the specified address
        InetAddress[] addresses =
            InetAddress.getAllByName(InetAddress.getLocalHost().getHostName());
        int i;
        for (i = 0; i < addresses.length; i++) {
            if (addresses[i].getHostAddress().equals(address))
                break;
        }
        if (i < addresses.length) {
            log(sm.getString("httpConnector.anAddress", address));
              return (factory.createSocket(port, acceptCount, addresses[i]));
        } else {
            log(sm.getString("httpConnector.noAddress", address));
              return (factory.createSocket(port, acceptCount));
        }
  
      }
  
  
      // ---------------------------------------------- Background Thread Methods
  
  
      /**
       * The background thread that listens for incoming TCP/IP connections and
       * hands them off to an appropriate processor.
       */
      public void run() {
  
          // Loop until we receive a shutdown command
        while (!stopped) {
  
            // Accept the next incoming connection from the server socket
            Socket socket = null;
            try {
                socket = serverSocket.accept();
                  if (connectionTimeout > 0)
                      socket.setSoTimeout(connectionTimeout);
            } catch (IOException e) {
                if (started && !stopped)
                    log("accept: ", e);
                break;
            }
  
            // Hand this socket off to an appropriate processor
            HttpProcessor processor = createProcessor();
            if (processor == null) {
                try {
                    log(sm.getString("httpConnector.noProcessor"));
                    socket.close();
                } catch (IOException e) {
                    ;
                }
                continue;
            }
            processor.assign(socket);
  
            // The processor will recycle itself when it finishes
  
        }
  
        // Notify the threadStop() method that we have shut ourselves down
        synchronized (threadSync) {
            threadSync.notifyAll();
        }
  
      }
  
  
      /**
       * Start the background processing thread.
       */
      private void threadStart() {
  
        log(sm.getString("httpConnector.starting"));
  
        thread = new Thread(this, threadName);
        thread.setDaemon(true);
        thread.start();
  
      }
  
  
      /**
       * Stop the background processing thread.
       */
      private void threadStop() {
  
        log(sm.getString("httpConnector.stopping"));
  
        stopped = true;
        synchronized (threadSync) {
            try {
                threadSync.wait(5000);
            } catch (InterruptedException e) {
                ;
            }
        }
        thread = null;
  
      }
  
  
      // ------------------------------------------------------ Lifecycle Methods
  
  
      /**
       * Add a lifecycle event listener to this component.
       *
       * @param listener The listener to add
       */
      public void addLifecycleListener(LifecycleListener listener) {
  
        lifecycle.addLifecycleListener(listener);
  
      }
  
  
      /**
       * Remove a lifecycle event listener from this component.
       *
       * @param listener The listener to add
       */
      public void removeLifecycleListener(LifecycleListener listener) {
  
        lifecycle.removeLifecycleListener(listener);
  
      }
  
  
      /**
       * Begin processing requests via this Connector.
       *
       * @exception LifecycleException if a fatal startup error occurs
       */
      public void start() throws LifecycleException {
  
        // Validate and update our current state
        if (started)
            throw new LifecycleException
                (sm.getString("httpConnector.alreadyStarted"));
          threadName = "HttpConnector[" + port + "]";
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;
  
        // Establish a server socket on the specified port
        try {
            serverSocket = open();
        } catch (IOException e) {
            throw new LifecycleException(threadName + ".open", e);
        }
  
        // Start our background thread
        threadStart();
  
        // Create the specified minimum number of processors
        while (curProcessors < minProcessors) {
            if ((maxProcessors > 0) && (curProcessors >= maxProcessors))
                break;
            HttpProcessor processor = newProcessor();
            recycle(processor);
        }
  
      }
  
  
      /**
       * Terminate processing requests via this Connector.
       *
       * @exception LifecycleException if a fatal shutdown error occurs
       */
      public void stop() throws LifecycleException {
  
        // Validate and update our current state
        if (!started)
            throw new LifecycleException
                (sm.getString("httpConnector.notStarted"));
        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;
  
        // Gracefully shut down all processors we have created
        for (int i = created.size() - 1; i >= 0; i--) {
            HttpProcessor processor = (HttpProcessor) created.elementAt(i);
            if (processor instanceof Lifecycle) {
                try {
                    ((Lifecycle) processor).stop();
                } catch (LifecycleException e) {
                    log("HttpConnector.stop", e);
                }
            }
        }
  
        // Close the server socket we were using
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                ;
            }
            serverSocket = null;
        }
  
        // Stop our background thread
        threadStop();
  
      }
  
  
  }
  
  
  
  1.1                  
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/HttpProcessor.java
  
  Index: HttpProcessor.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/HttpProcessor.java,v
 1.1 2001/01/23 03:55:54 remm Exp $
   * $Revision: 1.1 $
   * $Date: 2001/01/23 03:55:54 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  
  package org.apache.catalina.connector.http10;
  
  
  import java.io.BufferedInputStream;
  import java.io.InputStream;
  import java.io.IOException;
  import java.io.OutputStream;
  import java.net.InetAddress;
  import java.net.Socket;
  import java.util.NoSuchElementException;
  import java.util.StringTokenizer;
  import java.util.Locale;
  import java.util.Hashtable;
  import java.util.Vector;
  import java.util.Enumeration;
  import javax.servlet.ServletException;
  import javax.servlet.http.Cookie;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import org.apache.catalina.Connector;
  import org.apache.catalina.Container;
  import org.apache.catalina.Globals;
  import org.apache.catalina.HttpRequest;
  import org.apache.catalina.HttpResponse;
  import org.apache.catalina.Lifecycle;
  import org.apache.catalina.LifecycleEvent;
  import org.apache.catalina.LifecycleException;
  import org.apache.catalina.LifecycleListener;
  import org.apache.catalina.Logger;
  import org.apache.catalina.util.RequestUtil;
  import org.apache.catalina.util.LifecycleSupport;
  import org.apache.catalina.util.StringManager;
  
  
  /**
   * Implementation of a request processor (and its associated thread) that may
   * be used by an HttpConnector to process individual requests.  The connector
   * will allocate a processor from its pool, assign a particular socket to it,
   * and the processor will then execute the processing required to complete
   * the request.  When the processor is completed, it will recycle itself.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2001/01/23 03:55:54 $
   */
  
  final class HttpProcessor
      implements Lifecycle, Runnable {
  
  
      // ----------------------------------------------------------- Constructors
  
  
      /**
       * Construct a new HttpProcessor associated with the specified connector.
       *
       * @param connector HttpConnector that owns this processor
       * @param id Identifier of this HttpProcessor (unique per connector)
       */
      public HttpProcessor(HttpConnector connector, int id) {
  
        super();
        this.connector = connector;
        this.debug = connector.getDebug();
        this.id = id;
        this.request = (HttpRequest) connector.createRequest();
        this.response = (HttpResponse) connector.createResponse();
        this.threadName =
          "HttpProcessor[" + connector.getPort() + "][" + id + "]";
  
      }
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * Is there a new socket available?
       */
      private boolean available = false;
  
  
      /**
       * The HttpConnector with which this processor is associated.
       */
      private HttpConnector connector = null;
  
  
      /**
       * The debugging detail level for this component.
       */
      private int debug = 0;
  
  
      /**
       * The identifier of this processor, unique per connector.
       */
      private int id = 0;
  
  
      /**
       * The lifecycle event support for this component.
       */
      private LifecycleSupport lifecycle = new LifecycleSupport(this);
  
  
      /**
       * The match string for identifying a session ID parameter.
       */
      private static final String match =
        ";" + Globals.SESSION_PARAMETER_NAME + "=";
  
  
      /**
       * The HTTP request object we will pass to our associated container.
       */
      private HttpRequest request = null;
  
  
      /**
       * The HTTP response object we will pass to our associated container.
       */
      private HttpResponse response = null;
  
  
      /**
       * The string manager for this package.
       */
      protected StringManager sm =
        StringManager.getManager(Constants.Package);
  
  
      /**
       * The socket we are currently processing a request for.  This object
       * is used for inter-thread communication only.
       */
      private Socket socket = null;
  
  
      /**
       * Has this component been started yet?
       */
      private boolean started = false;
  
  
      /**
       * The shutdown signal to our background thread
       */
      private boolean stopped = false;
  
  
      /**
       * The background thread.
       */
      private Thread thread = null;
  
  
      /**
       * The name to register for the background thread.
       */
      private String threadName = null;
  
  
      /**
       * The thread synchronization object.
       */
      private Object threadSync = new Object();
  
  
      // -------------------------------------------------------- Package Methods
  
  
      /**
       * Process an incoming TCP/IP connection on the specified socket.  Any
       * exception that occurs during processing must be logged and swallowed.
       * <b>NOTE</b>:  This method is called from our Connector's thread.  We
       * must assign it to our own thread so that multiple simultaneous
       * requests can be handled.
       *
       * @param socket TCP socket to process
       */
      synchronized void assign(Socket socket) {
  
          // Wait for the Processor to get the previous Socket
          while (available) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
          }
  
        // Store the newly available Socket and notify our thread
        this.socket = socket;
        available = true;
        notifyAll();
  
        if ((debug >= 1) && (socket != null))
            log(" An incoming request is being assigned");
  
      }
  
  
      // -------------------------------------------------------- Private Methods
  
  
      /**
       * Await a newly assigned Socket from our Connector, or <code>null</code>
       * if we are supposed to shut down.
       */
      private synchronized Socket await() {
  
          // Wait for the Connector to provide a new Socket
          while (!available) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
          }
  
        // Notify the Connector that we have received this Socket
        Socket socket = this.socket;
        available = false;
        notifyAll();
  
        if ((debug >= 1) && (socket != null))
            log("  The incoming request has been awaited");
  
        return (socket);
  
      }
  
  
  
      /**
       * Log a message on the Logger associated with our Container (if any)
       *
       * @param message Message to be logged
       */
      private void log(String message) {
  
        Logger logger = connector.getContainer().getLogger();
        if (logger != null)
            logger.log(threadName + " " + message);
  
      }
  
  
      /**
       * Log a message on the Logger associated with our Container (if any)
       *
       * @param message Message to be logged
       * @param throwable Associated exception
       */
      private void log(String message, Throwable throwable) {
  
        Logger logger = connector.getContainer().getLogger();
        if (logger != null)
            logger.log(threadName + " " + message, throwable);
  
      }
  
  
      /**
       * Parse and record the connection parameters related to this request.
       *
       * @param socket The socket on which we are connected
       *
       * @exception IOException if an input/output error occurs
       * @exception ServletException if a parsing error occurs
       */
      private void parseConnection(Socket socket)
          throws IOException, ServletException {
  
        if (debug >= 2)
            log("  parseConnection: address=" + socket.getInetAddress() +
                ", port=" + connector.getPort());
        ((HttpRequestImpl) request).setInet(socket.getInetAddress());
        request.setServerPort(connector.getPort());
          request.setSocket(socket);
  
      }
  
  
      /**
       * Parse the incoming HTTP request headers, and set the appropriate
       * request headers.
       *
       * @param input The input stream connected to our socket
       *
       * @exception IOException if an input/output error occurs
       * @exception ServletException if a parsing error occurs
       */
      private void parseHeaders(InputStream input)
          throws IOException, ServletException {
  
        while (true) {
  
            // Read the next header line
            String line = read(input);
            if ((line == null) || (line.length() < 1))
                break;
  
            // Parse the header name and value
            int colon = line.indexOf(":");
            if (colon < 0)
                throw new ServletException
                    (sm.getString("httpProcessor.parseHeaders.colon"));
            String name = line.substring(0, colon).trim();
            String match = name.toLowerCase();
            String value = line.substring(colon + 1).trim();
            if (debug >= 1)
                log(" Header " + name + " = " + value);
  
            // Set the corresponding request headers
            if (match.equals("authorization")) {
                request.setAuthorization(value);
                request.addHeader(name, value);
            } else if (match.equals("accept-language")) {
            request.addHeader(name, value);
            //
            // Adapted from old code perhaps maybe optimized
            //
            //
            Hashtable languages = new Hashtable();
            StringTokenizer languageTokenizer = new StringTokenizer(value, ",");
  
            while (languageTokenizer.hasMoreTokens()) {
              String language = languageTokenizer.nextToken().trim();
              int qValueIndex = language.indexOf(';');
              int qIndex = language.indexOf('q');
              int equalIndex = language.indexOf('=');
              Double qValue = new Double(1);
  
              if (qValueIndex > -1 && qValueIndex < qIndex && qIndex < equalIndex) {
                String qValueStr = language.substring(qValueIndex + 1);
                language = language.substring(0, qValueIndex);
                qValueStr = qValueStr.trim().toLowerCase();
                qValueIndex = qValueStr.indexOf('=');
                qValue = new Double(0);
                if (qValueStr.startsWith("q") &&
                    qValueIndex > -1) {
                    qValueStr = qValueStr.substring(qValueIndex + 1);
                    try {
                        qValue = new Double(qValueStr.trim());
                    } catch (NumberFormatException nfe) {
                    }
                }
              }
              // XXX
              // may need to handle "*" at some point in time
              if (! language.equals("*")) {
                  String key = qValue.toString();
                  Vector v = (Vector)((languages.containsKey(key)) ? 
languages.get(key) : new Vector());
                  v.addElement(language);
                  languages.put(key, v);
              }
            }
            Vector l = new Vector();
            Enumeration e = languages.keys();
            while (e.hasMoreElements()) {
                String key = (String)e.nextElement();
                Vector v = (Vector)languages.get(key);
                Enumeration le = v.elements();
                while (le.hasMoreElements()) {
                  String language = (String)le.nextElement();
                  String country = "";
                  int countryIndex = language.indexOf("-");
                  if (countryIndex > -1) {
                      country = language.substring(countryIndex + 1).trim();
                      language = language.substring(0, countryIndex).trim();
                  }
                  request.addLocale(new Locale(language, country));
                }
            }
            } else if (match.equals("cookie")) {
                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
                        request.setRequestedSessionId(cookies[i].getValue());
                        request.setRequestedSessionCookie(true);
                        request.setRequestedSessionURL(false);
                        if (debug >= 1)
                          log(" Requested cookie session id is " +
                              ((HttpServletRequest) 
request.getRequest()).getRequestedSessionId());
                          break;  // Accept only the first session id value
  
                    }
                      request.addCookie(cookies[i]);
                }
                // Keep Watchdog from whining by adding the header as well
                // (GetHeaderTest, GetIntHeader_1Test)
                request.addHeader(name, value);
            } else if (match.equals("content-length")) {
                int n = -1;
                try {
                    n = Integer.parseInt(value);
                } catch (Exception e) {
                    throw new ServletException
                        (sm.getString("httpProcessor.parseHeaders.contentLength"));
                }
                request.setContentLength(n);
                request.addHeader(name, value);
            } else if (match.equals("content-type")) {
                request.setContentType(value);
                request.addHeader(name, value);
            } else if (match.equals("host")) {
                int n = value.indexOf(":");
                if (n < 0)
                    request.setServerName(value);
                else {
                    request.setServerName(value.substring(0, n).trim());
                    int port = 80;
                    try {
                        port = Integer.parseInt(value.substring(n+1).trim());
                    } catch (Exception e) {
                        throw new ServletException
                            (sm.getString("httpProcessor.parseHeaders.portNumber"));
                    }
                    request.setServerPort(port);
                }
                request.addHeader(name, value);
            } else {
                request.addHeader(name, value);
            }
        }
  
      }
  
  
      /**
       * Parse the incoming HTTP request and set the corresponding HTTP request
       * properties.
       *
       * @param input The input stream attached to our socket
       *
       * @exception IOException if an input/output error occurs
       * @exception ServletException if a parsing error occurs
       */
      private void parseRequest(InputStream input)
          throws IOException, ServletException {
  
        // Parse the incoming request line
        String line = read(input);
        if (line == null)
            throw new ServletException
                (sm.getString("httpProcessor.parseRequest.read"));
        StringTokenizer st = new StringTokenizer(line);
  
        String method = null;
        try {
            method = st.nextToken();
        } catch (NoSuchElementException e) {
            method = null;
        }
  
        String uri = null;
        try {
            uri = st.nextToken();
            ;   // FIXME - URL decode the URI?
        } catch (NoSuchElementException e) {
            uri = null;
        }
  
        String protocol = null;
        try {
            protocol = st.nextToken();
        } catch (NoSuchElementException e) {
            protocol = "HTTP/0.9";
        }
  
        // Validate the incoming request line
        if (method == null) {
            throw new ServletException
                (sm.getString("httpProcessor.parseRequest.method"));
        } else if (uri == null) {
            throw new ServletException
                (sm.getString("httpProcessor.parseRequest.uri"));
        }
  
        // Parse any query parameters out of the request URI
        int question = uri.indexOf("?");
        if (question >= 0) {
            request.setQueryString(uri.substring(question + 1));
            if (debug >= 1)
                log(" Query string is " +
                    ((HttpServletRequest) request.getRequest()).getQueryString());
            uri = uri.substring(0, question);
        } else
            request.setQueryString(null);
  
        // 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) {
                request.setRequestedSessionId(rest.substring(0, semicolon2));
                rest = rest.substring(semicolon2);
            } else {
                request.setRequestedSessionId(rest);
                rest = "";
            }
            request.setRequestedSessionURL(true);
            uri = uri.substring(0, semicolon) + rest;
            if (debug >= 1)
                log(" Requested URL session id is " +
                    ((HttpServletRequest) 
request.getRequest()).getRequestedSessionId());
        } else {
            request.setRequestedSessionId(null);
            request.setRequestedSessionURL(false);
        }
  
        // Set the corresponding request properties
        ((HttpRequest) request).setMethod(method);
        request.setProtocol(protocol);
        ((HttpRequest) request).setRequestURI(uri);
        request.setSecure(false);       // No SSL support
        request.setScheme("http");      // No SSL support
  
        if (debug >= 1)
            log(" Request is " + method + " for " + uri);
  
      }
  
  
      /**
       * Process an incoming HTTP request on the Socket that has been assigned
       * to this Processor.  Any exceptions that occur during processing must be
       * swallowed and dealt with.
       *
       * @param socket The socket on which we are connected to the client
       */
      private void process(Socket socket) {
  
        boolean ok = true;
        InputStream input = null;
        OutputStream output = null;
  
        // Construct and initialize the objects we will need
        try {
            input = new BufferedInputStream(socket.getInputStream(),
                                            connector.getBufferSize());
            request.setStream(input);
            request.setResponse(response);
            output = socket.getOutputStream();
            response.setStream(output);
            response.setRequest(request);
            ((HttpServletResponse) response.getResponse()).setHeader
                ("Server", Constants.ServerInfo);
        } catch (Exception e) {
            log("process.create", e);
            ok = false;
        }
  
        // Parse the incoming request
        try {
            if (ok) {
                parseConnection(socket);
                parseRequest(input);
                if (!request.getRequest().getProtocol().startsWith("HTTP/0"))
                    parseHeaders(input);
            }
        } catch (Exception e) {
            try {
                log("process.parse", e);
                ((HttpServletResponse) response.getResponse()).sendError
                    (HttpServletResponse.SC_BAD_REQUEST);
            } catch (Exception f) {
                ;
            }
        }
  
        // Ask our Container to process this request
        try {
            if (ok) {
                connector.getContainer().invoke(request, response);
            }
        } catch (ServletException e) {
            log("process.invoke", e);
            try {
                ((HttpServletResponse) response.getResponse()).sendError
                    (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            } catch (Exception f) {
                ;
            }
            ok = false;
        } catch (Throwable e) {
            log("process.invoke", e);
            try {
                ((HttpServletResponse) response.getResponse()).sendError
                    (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            } catch (Exception f) {
                ;
            }
            ok = false;
        }
  
        // Finish up the handling of the response
        try {
            if (ok)
                response.finishResponse();
        } catch (IOException e) {
            log("FIXME-Exception from finishResponse", e);
        }
        try {
            if (output != null)
                output.flush();
        } catch (IOException e) {
            log("FIXME-Exception flushing output", e);
        }
        try {
            if (output != null)
                output.close();
        } catch (IOException e) {
            log("FIXME-Exception closing output", e);
        }
  
        // Finish up the handling of the request
        try {
            if (ok)
                request.finishRequest();
        } catch (IOException e) {
            log("FIXME-Exception from finishRequest", e);
        }
        try {
            if (input != null)
                input.close();
        } catch (IOException e) {
            log("FIXME-Exception closing input", e);
        }
  
        // Finish up the handling of the socket connection itself
        try {
            socket.close();
        } catch (IOException e) {
            log("FIXME-Exception closing socket", e);
        }
        socket = null;
  
      }
  
  
      /**
       * Read a line from the specified input stream, and strip off the
       * trailing carriage return and newline (if any).  Return the remaining
       * characters that were read as a String.
       *
       * @param input The input stream connected to our socket
       *
       * @returns The line that was read, or <code>null</code> if end-of-file
       *  was encountered
       *
       * @exception IOException if an input/output error occurs
       */
      private String read(InputStream input) throws IOException {
  
        StringBuffer sb = new StringBuffer();
        while (true) {
            int ch = input.read();
            if (ch < 0) {
                if (sb.length() == 0) {
                    return (null);
                } else {
                    break;
                }
            } else if (ch == '\r') {
                continue;
            } else if (ch == '\n') {
                break;
            }
            sb.append((char) ch);
        }
        if (debug >= 2)
            log("  Read: " + sb.toString());
        return (sb.toString());
  
      }
  
  
      // ---------------------------------------------- Background Thread Methods
  
  
      /**
       * The background thread that listens for incoming TCP/IP connections and
       * hands them off to an appropriate processor.
       */
      public void run() {
  
          // Process requests until we receive a shutdown signal
        while (!stopped) {
  
            // Wait for the next socket to be assigned
            Socket socket = await();
            if (socket == null)
                continue;
  
            // Process the request from this socket
            process(socket);
  
            // Finish up this request
            request.recycle();
            response.recycle();
            connector.recycle(this);
  
        }
  
        // Tell threadStop() we have shut ourselves down successfully
        synchronized (threadSync) {
            threadSync.notifyAll();
        }
  
      }
  
  
      /**
       * Start the background processing thread.
       */
      private void threadStart() {
  
        log(sm.getString("httpProcessor.starting"));
  
        thread = new Thread(this, threadName);
        thread.setDaemon(true);
        thread.start();
  
        if (debug >= 1)
            log(" Background thread has been started");
  
      }
  
  
      /**
       * Stop the background processing thread.
       */
      private void threadStop() {
  
        log(sm.getString("httpProcessor.stopping"));
  
        stopped = true;
          assign(null);
        synchronized (threadSync) {
            try {
                threadSync.wait(5000);
            } catch (InterruptedException e) {
                ;
            }
        }
        thread = null;
  
      }
  
  
      // ------------------------------------------------------ Lifecycle Methods
  
  
      /**
       * Add a lifecycle event listener to this component.
       *
       * @param listener The listener to add
       */
      public void addLifecycleListener(LifecycleListener listener) {
  
        lifecycle.addLifecycleListener(listener);
  
      }
  
  
      /**
       * Remove a lifecycle event listener from this component.
       *
       * @param listener The listener to add
       */
      public void removeLifecycleListener(LifecycleListener listener) {
  
        lifecycle.removeLifecycleListener(listener);
  
      }
  
  
      /**
       * Start the background thread we will use for request processing.
       *
       * @exception LifecycleException if a fatal startup error occurs
       */
      public void start() throws LifecycleException {
  
        if (started)
            throw new LifecycleException
                (sm.getString("httpProcessor.alreadyStarted"));
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;
  
        threadStart();
  
      }
  
  
      /**
       * Stop the background thread we will use for request processing.
       *
       * @exception LifecycleException if a fatal shutdown error occurs
       */
      public void stop() throws LifecycleException {
  
        if (!started)
            throw new LifecycleException
                (sm.getString("httpProcessor.notStarted"));
        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;
  
        threadStop();
  
      }
  
  
  }
  
  
  
  1.1                  
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/HttpRequestImpl.java
  
  Index: HttpRequestImpl.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/HttpRequestImpl.java,v
 1.1 2001/01/23 03:55:54 remm Exp $
   * $Revision: 1.1 $
   * $Date: 2001/01/23 03:55:54 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  
  
  package org.apache.catalina.connector.http10;
  
  
  import java.net.InetAddress;
  import org.apache.catalina.connector.HttpRequestBase;
  
  
  /**
   * Implementation of <b>HttpRequest</b> specific to the HTTP connector.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2001/01/23 03:55:54 $
   */
  
  final class HttpRequestImpl
      extends HttpRequestBase {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The InetAddress of the remote client of ths request.
       */
      protected InetAddress inet = null;
  
  
      /**
       * Descriptive information about this Request implementation.
       */
      protected static final String info =
        "org.apache.catalina.connector.http10.HttpRequestImpl/1.0";
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * [Package Private] Return the InetAddress of the remote client of
       * this request.
       */
      InetAddress getInet() {
  
        return (inet);
  
      }
  
  
      /**
       * [Package Private] Set the InetAddress of the remote client of
       * this request.
       *
       * @param inet The new InetAddress
       */
      void setInet(InetAddress inet) {
  
        this.inet = inet;
  
      }
  
  
      /**
       * Return descriptive information about this Request implementation and
       * the corresponding version number, in the format
       * <code>&lt;description&gt;/&lt;version&gt;</code>.
       */
      public String getInfo() {
  
        return (info);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Release all object references, and initialize instance variables, in
       * preparation for reuse of this object.
       */
      public void recycle() {
  
        super.recycle();
        inet = null;
  
      }
  
  
      // ------------------------------------------------- ServletRequest Methods
  
  
      /**
       * Return the Internet Protocol (IP) address of the client that sent
       * this request.
       */
      public String getRemoteAddr() {
  
        return (inet.getHostAddress());
  
      }
  
  
      /**
       * Return the fully qualified name of the client that sent this request,
       * or the IP address of the client if the name cannot be determined.
       */
      public String getRemoteHost() {
  
        return (inet.getHostName());
  
      }
  
  
      // --------------------------------------------- HttpServletRequest Methods
  
  
  }
  
  
  
  1.1                  
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/HttpResponseImpl.java
  
  Index: HttpResponseImpl.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/HttpResponseImpl.java,v
 1.1 2001/01/23 03:55:54 remm Exp $
   * $Revision: 1.1 $
   * $Date: 2001/01/23 03:55:54 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  
  
  package org.apache.catalina.connector.http10;
  
  
  import org.apache.catalina.connector.HttpResponseBase;
  
  
  /**
   * Implementation of <b>HttpResponse</b> specific to the HTTP connector.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2001/01/23 03:55:54 $
   */
  
  final class HttpResponseImpl
      extends HttpResponseBase {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * Descriptive information about this Response implementation.
       */
      protected static final String info =
        "org.apache.catalina.connector.http10.HttpResponseImpl/1.0";
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * Return descriptive information about this Response implementation and
       * the corresponding version number, in the format
       * <code>&lt;description&gt;/&lt;version&gt;</code>.
       */
      public String getInfo() {
  
        return (info);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Release all object references, and initialize instance variables, in
       * preparation for reuse of this object.
       */
      public void recycle() {
  
        super.recycle();
  
      }
  
  
  }
  
  
  
  1.1                  
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  httpConnector.alreadyStarted=HTTP connector has already been started
  httpConnector.allAddresses=Opening server socket on all host IP addresses
  httpConnector.anAddress=Opening server socket on host IP address {0}
  httpConnector.noAddress=No host IP address matching {0}, opening on all addresses
  httpConnector.noProcessor=No processor available, rejecting this connection
  httpConnector.notStarted=HTTP connector has not yet been started
  httpConnector.starting=Starting background thread
  httpConnector.stopping=Stopping background thread
  httpProcessor.alreadyStarted=HTTP processor has already been started
  httpProcessor.notStarted=HTTP processor has not yet been started
  httpProcessor.parseHeaders.contentLength=Invalid 'Content-Length' header
  httpProcessor.parseHeaders.colon=Invalid HTTP header format
  httpProcessor.parseHeaders.portNumber=Invalid TCP/IP port number in 'Host' header
  httpProcessor.parseRequest.method=Missing HTTP request method
  httpProcessor.parseRequest.read=Missing HTTP request line
  httpProcessor.parseRequest.uri=Missing HTTP request URI
  httpProcessor.start=HTTP processor has already been started
  httpProcessor.starting=Starting background thread
  httpProcessor.stopping=Stopping background thread
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to