tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From craig...@locus.apache.org
Subject cvs commit: jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/test Constants.java HttpConnector.java HttpProcessor.java HttpRequestImpl.java HttpResponseImpl.java LocalStrings.properties
Date Fri, 21 Apr 2000 19:50:38 GMT
craigmcc    00/04/21 12:50:38

  Modified:    proposals/catalina/src/conf server.xml
  Added:       proposals/catalina/src/share/org/apache/tomcat/connector/test
                        Constants.java HttpConnector.java
                        HttpProcessor.java HttpRequestImpl.java
                        HttpResponseImpl.java LocalStrings.properties
  Removed:     proposals/catalina/src/share/org/apache/tomcat/connector/http
                        Constants.java HttpConnector.java
                        HttpProcessor.java HttpRequestImpl.java
                        HttpResponseImpl.java LocalStrings.properties
  Log:
  Move package org.apache.tomcat.connector.http to become package
  org.apache.tomcat.connector.test, in preparation for a real HTTP/1.1
  implementation.
  
  Revision  Changes    Path
  1.4       +1 -1      jakarta-tomcat/proposals/catalina/src/conf/server.xml
  
  Index: server.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/conf/server.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- server.xml	2000/04/17 02:34:33	1.3
  +++ server.xml	2000/04/21 19:50:30	1.4
  @@ -6,7 +6,7 @@
   
     <!-- Define all the connectors to associate with the following container -->
   
  -  <Connector className="org.apache.tomcat.connector.http.HttpConnector"
  +  <Connector className="org.apache.tomcat.connector.test.HttpConnector"
                acceptCount="10" maxProcessors="20" port="8080"/>
   
     <!-- Define the top level container in our container hierarchy -->
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/test/Constants.java
  
  Index: Constants.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/test/Constants.java,v 1.1 2000/04/21 19:50:36 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/04/21 19:50:36 $
   *
   * ====================================================================
   *
   * 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 apache@apache.org.
   *
   * 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.tomcat.connector.test;
  
  
  /**
   * Static constants for this package.
   */
  
  public final class Constants {
  
      public static final String Package = "org.apache.tomcat.connector.test";
      public static final String ServerInfo =
  	"Tomcat (Catalina)/0.1";
  
  }
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/test/HttpConnector.java
  
  Index: HttpConnector.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/test/HttpConnector.java,v 1.1 2000/04/21 19:50:36 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/04/21 19:50:36 $
   *
   * ====================================================================
   *
   * 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 apache@apache.org.
   *
   * 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.tomcat.connector.test;
  
  
  import java.io.IOException;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.util.Stack;
  import org.apache.tomcat.Connector;
  import org.apache.tomcat.Container;
  import org.apache.tomcat.HttpRequest;
  import org.apache.tomcat.HttpResponse;
  import org.apache.tomcat.Lifecycle;
  import org.apache.tomcat.LifecycleEvent;
  import org.apache.tomcat.LifecycleException;
  import org.apache.tomcat.LifecycleListener;
  import org.apache.tomcat.Logger;
  import org.apache.tomcat.Request;
  import org.apache.tomcat.Response;
  import org.apache.tomcat.connector.ConnectorBase;
  import org.apache.tomcat.util.LifecycleSupport;
  import org.apache.tomcat.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: 2000/04/21 19:50:36 $
   */
  
  
  public final class HttpConnector
      extends ConnectorBase
      implements Lifecycle, Runnable {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The accept count for this Connector.
       */
      private int acceptCount = 10;
  
  
      /**
       * The current number of processors that have been created.
       */
      private int curProcessors = 0;
  
  
      /**
       * Descriptive information about this Connector implementation.
       */
      private static final String info =
  	"org.apache.tomcat.connector.test.HttpConnector/1.0";
  
  
      /**
       * The lifecycle event support for this component.
       */
      protected LifecycleSupport lifecycle = new LifecycleSupport(this);
  
  
      /**
       * The maximum number of processors allowed, or <0 for unlimited.
       */
      private int maxProcessors = -1;
  
  
      /**
       * 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 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 String threadSync = "";
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * 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;
  
      }
  
  
      /**
       * Is this connector available for processing requests?
       */
      public boolean isAvailable() {
  
  	return (started);
  
      }
  
  
      /**
       * Return the current number of processors that have been created.
       */
      public int getCurProcessors() {
  
  	return (curProcessors);
  
      }
  
  
      /**
       * Return descriptive information about this Connector implementation.
       */
      public String getInfo() {
  
  	return (info);
  
      }
  
  
      /**
       * 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 thread name of our background thread.
       */
      public String getThreadName() {
  
  	return (threadName);
  
      }
  
  
      /**
       * Set the thread name of our background thread.
       *
       * @param name The new thread name
       */
      public void setThreadName(String name) {
  
  	this.threadName = name;
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Instantiate and return a new Request object suitable for specifying
       * the contents of a Request to the responsible Container.  This method
       * must be implemented by a subclass.
       */
      public Request newRequest() {
  
  	HttpRequestImpl request = new HttpRequestImpl();
  	request.setConnector(this);
  	return (request);
  
      }
  
  
      /**
       * Instantiate and return a new Response object suitable for receiving
       * the contents of a Response from the responsible Container.  This method
       * must be implemented by a subclass.
       */
      public Response newResponse() {
  
  	HttpResponseImpl response = new HttpResponseImpl();
  	response.setConnector(this);
  	return (response);
  
      }
  
  
      // -------------------------------------------------------- Package Methods
  
  
      /**
       * Recycle the specified Processor.
       *
       * @param processor The processor to be recycled
       */
      void recycle(HttpProcessor processor) {
  
  	processors.push(processor);
  
      }
  
  
      /**
       * Recycle the specified Request.
       *
       * @param request The request to be recycled
       */
      void recycle(HttpRequest request) {
  
  	request.recycle();
  	requests.push(request);
  
      }
  
  
      /**
       * Recycle the specified Response.
       *
       * @param response The response to be recycled
       */
      void recycle(HttpResponse response) {
  
  	response.recycle();
  	responses.push(response);
  
      }
  
  
      // -------------------------------------------------------- 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());
  	    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);
  
      }
  
  
      /**
       * 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);
  
      }
  
  
      /**
       * Instantiate and return a new processor suitable for receiving
       * and processing HTTP requests.
       */
      private HttpProcessor newProcessor() {
  
  	HttpProcessor processor = new HttpProcessor(this, curProcessors++);
  	if (processor instanceof Lifecycle) {
  	    try {
  		((Lifecycle) processor).start();
  	    } catch (LifecycleException e) {
  		log("newProcessor: ", e);
  	    }
  	}
  	return (processor);
  
      }
  
  
      // ---------------------------------------------- Background Thread Methods
  
  
      /**
       * The background thread that listens for incoming TCP/IP connections and
       * hands them off to an appropriate processor.
       */
      public void run() {
  
  	while (!stopped) {
  
  	    // Accept the next incoming connection from the server socket
  	    Socket socket = null;
  	    try {
  		socket = serverSocket.accept();
  	    } catch (IOException e) {
  		if (!stopped)
  		    log("accept: ", e);
  		break;
  	    }
  
  	    // Hand this socket off to an appropriate processor
  	    HttpProcessor processor = createProcessor();
  	    if (processor == null) {
  		try {
  		    log("select: No processor available");
  		    socket.close();
  		} catch (IOException e) {
  		    ;
  		}
  		continue;
  	    }
  	    processor.process(socket);
  
  	}
  
  	threadSync.notifyAll();
  
      }
  
  
      /**
       * Start the background processing thread.
       */
      private void threadStart() {
  
  	if (threadName == null)
  	    setThreadName("HttpConnector[" + port + "]");
  
  	log("Starting");
  
  	thread = new Thread(this, threadName);
  	thread.setDaemon(true);
  	thread.start();
  
      }
  
  
      /**
       * Stop the background processing thread.
       */
      private void threadStop() {
  
  	log("Stopping");
  
  	stopped = true;
  	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"));
  	started = true;
  	lifecycle.fireLifecycleEvent(START_EVENT, null);
  
  	// Establish a server socket on the specified port
  	try {
  	    serverSocket = new ServerSocket(port, acceptCount);
  	} catch (IOException e) {
  	    throw new LifecycleException("HttpConnector[" + port + "]", e);
  	}
  
  	// Start our background thread
  	threadStart();
  
      }
  
  
      /**
       * 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"));
  	started = false;
  	lifecycle.fireLifecycleEvent(STOP_EVENT, null);
  
  	// Gracefully shut down all processors we have created
  	;	// FIXME
  
  	// 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/proposals/catalina/src/share/org/apache/tomcat/connector/test/HttpProcessor.java
  
  Index: HttpProcessor.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/test/HttpProcessor.java,v 1.1 2000/04/21 19:50:36 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/04/21 19:50:36 $
   *
   * ====================================================================
   *
   * 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 apache@apache.org.
   *
   * 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.tomcat.connector.test;
  
  
  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 javax.servlet.ServletException;
  import javax.servlet.http.Cookie;
  import javax.servlet.http.HttpServletResponse;
  import org.apache.tomcat.Connector;
  import org.apache.tomcat.Container;
  import org.apache.tomcat.HttpRequest;
  import org.apache.tomcat.HttpResponse;
  import org.apache.tomcat.Lifecycle;
  import org.apache.tomcat.LifecycleEvent;
  import org.apache.tomcat.LifecycleException;
  import org.apache.tomcat.LifecycleListener;
  import org.apache.tomcat.Logger;
  import org.apache.tomcat.util.RequestUtil;
  import org.apache.tomcat.util.LifecycleSupport;
  import org.apache.tomcat.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: 2000/04/21 19:50:36 $
   */
  
  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.id = id;
  	request = (HttpRequest) connector.newRequest();
  	response = (HttpResponse) connector.newResponse();
      }
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The HttpConnector with which this processor is associated.
       */
      private HttpConnector connector = null;
  
  
      /**
       * The identifier of this processor, unique per connector.
       */
      private int id = 0;
  
  
      /**
       * The input stream associated with this request.
       */
      private InputStream input = null;
  
  
      /**
       * 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 =
  	";" + org.apache.tomcat.connector.Constants.SessionParameter + "=";
  
  
      /**
       * The output stream associated with this request.
       */
      private OutputStream output = null;
  
  
      /**
       * 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.  If this is
       * <code>null</code>, this processor is available.
       */
      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 String threadSync = "";
  
  
      // -------------------------------------------------------- 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
       */
      void process(Socket socket) {
  
  	this.socket = socket;
  	notify();
  
      }
  
  
      // -------------------------------------------------------- Private Methods
  
  
      /**
       * 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.
       *
       * @exception IOException if an input/output error occurs
       * @exception ServletException if a parsing error occurs
       */
      private void parseConnection() throws IOException, ServletException {
  
  	((HttpRequestImpl) request).setInet(socket.getInetAddress());
  	request.setServerPort(connector.getPort());
  
      }
  
  
      /**
       * Parse the incoming HTTP request headers, and set the appropriate
       * request headers.
       *
       * @exception IOException if an input/output error occurs
       * @exception ServletException if a parsing error occurs
       */
      private void parseHeaders() throws IOException, ServletException {
  
  	while (true) {
  
  	    // Read the next header line
  	    String line = read();
  	    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();
  
  	    // Set the corresponding request headers
  	    if (match.equals("authorization")) {
  		// FIXME - Don't want to include this but it needs visibility
  		request.addHeader(name, value);
  	    } else if (match.equals("accept-language")) {
  		request.addHeader(name, value);
  		// FIXME - Also parse and add locales to the request
  	    } else if (match.equals("cookie")) {
  		Cookie cookies[] = RequestUtil.parseCookieHeader(value);
  		for (int i = 0; i < cookies.length; i++) {
  		    if (cookies[i].getName().equals
  			(org.apache.tomcat.connector.Constants.SessionCookie)) {
  			// Override anything requested in the URL
  			request.setRequestedSessionId(cookies[i].getValue());
  			request.setRequestedSessionCookie(true);
  			request.setRequestedSessionURL(false);
  		    } else
  			request.addCookie(cookies[i]);
  		}
  	    } 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);
  	    } else if (match.equals("content-type")) {
  		request.setContentType(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);
  		}
  	    } else {
  		request.addHeader(name, value);
  	    }
  	}
  
      }
  
  
      /**
       * Parse the incoming HTTP request and set the corresponding HTTP request
       * properties.
       *
       * @exception IOException if an input/output error occurs
       * @exception ServletException if a parsing error occurs
       */
      private void parseRequest() throws IOException, ServletException {
  
  	// Parse the incoming request line
  	String line = 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));
  	    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;
  	} 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
  
      }
  
  
      /**
       * 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.
       */
      private void process() {
  
  	boolean ok = true;
  
  	// Construct and initialize the objects we will need
  	try {
  	    input = socket.getInputStream();
  	    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();
  		parseRequest();
  		if (!request.getRequest().getProtocol().startsWith("HTTP/0"))
  		    parseHeaders();
  	    }
  	} 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 request
  	try {
  	    if (output != null)
  		output.flush();
  	} catch (IOException e) {
  	    ;
  	}
  	try {
  	    socket.close();
  	} catch (IOException 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.
       *
       * @returns The lline that was read, or <code>null</code> if end-of-file
       *  was encountered
       *
       * @exception IOException if an input/output error occurs
       */
      private String read() 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);
  	}
  	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() {
  
  	while (!stopped) {
  
  	    // Wait for the next socket to be assigned
  	    try {
  		wait();
  	    } catch (InterruptedException e) {
  		;
  	    }
  	    if (socket == null)
  		continue;
  
  	    // Process the request from this socket
  	    process();
  
  	    // Finish up this request
  	    request.recycle();
  	    response.recycle();
  	    connector.recycle(this);
  
  	}
  
  	threadSync.notifyAll();
  
      }
  
  
      /**
       * Start the background processing thread.
       */
      private void threadStart() {
  
  	if (threadName == null)
  	    threadName = connector.getThreadName() + "[" + id + "]";
  
  	log("Starting");
  
  	thread = new Thread(this, threadName);
  	thread.setDaemon(true);
  	thread.start();
  
      }
  
  
      /**
       * Stop the background processing thread.
       */
      private void threadStop() {
  
  	log("Stopping");
  
  	stopped = true;
  	process(null);
  	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.start"));
  	started = true;
  	lifecycle.fireLifecycleEvent(START_EVENT, null);
  
  	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.stop"));
  	started = false;
  	lifecycle.fireLifecycleEvent(STOP_EVENT, null);
  
  	threadStop();
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/test/HttpRequestImpl.java
  
  Index: HttpRequestImpl.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/test/HttpRequestImpl.java,v 1.1 2000/04/21 19:50:36 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/04/21 19:50:36 $
   *
   * ====================================================================
   *
   * 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 apache@apache.org.
   *
   * 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.tomcat.connector.test;
  
  
  import java.net.InetAddress;
  import org.apache.tomcat.connector.HttpRequestBase;
  
  
  /**
   * Implementation of <b>HttpRequest</b> specific to the HTTP connector.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/04/21 19:50:36 $
   */
  
  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.tomcat.connector.test.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;
  	((HttpConnector) connector).recycle(this);
  
      }
  
  
      // ------------------------------------------------- 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/proposals/catalina/src/share/org/apache/tomcat/connector/test/HttpResponseImpl.java
  
  Index: HttpResponseImpl.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/test/HttpResponseImpl.java,v 1.1 2000/04/21 19:50:36 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/04/21 19:50:36 $
   *
   * ====================================================================
   *
   * 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 apache@apache.org.
   *
   * 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.tomcat.connector.test;
  
  
  import org.apache.tomcat.connector.HttpResponseBase;
  
  
  /**
   * Implementation of <b>HttpResponse</b> specific to the HTTP connector.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/04/21 19:50:36 $
   */
  
  final class HttpResponseImpl
      extends HttpResponseBase {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * Descriptive information about this Response implementation.
       */
      protected static final String info =
  	"org.apache.tomcat.connector.test.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();
  	((HttpConnector) connector).recycle(this);
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/test/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  httpConnector.alreadyStarted=HTTP connector has already been started
  httpConnector.notStarted=HTTP connector 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.uri=Missing HTTP request URI
  httpProcessor.start=HTTP processor has already been started
  httpProcessor.stop=HTTP processor has already been stopped
  
  
  

Mime
View raw message