tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cos...@locus.apache.org
Subject cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/xml XmlMapper.java
Date Tue, 22 Feb 2000 21:06:48 GMT
costin      00/02/22 13:06:47

  Modified:    .        build.xml
               src/etc  server.xml
               src/j2ee/org/apache/tomcat/server HttpServer.java
               src/share/org/apache/tomcat/context AutoSetup.java
               src/share/org/apache/tomcat/core Context.java
                        ContextManager.java ServletContextFacade.java
                        ServletWrapper.java
               src/share/org/apache/tomcat/logging Logger.java
                        TomcatLogger.java
               src/share/org/apache/tomcat/request SecurityCheck.java
               src/share/org/apache/tomcat/service TcpEndpoint.java
                        TcpEndpointConnector.java
               src/share/org/apache/tomcat/service/http
                        HttpConnectionHandler.java
               src/share/org/apache/tomcat/task ApacheConfig.java
               src/share/org/apache/tomcat/util ThreadPool.java
               src/share/org/apache/tomcat/util/xml XmlMapper.java
  Added:       src/share/org/apache/tomcat/service PoolTcpConnector.java
                        PoolTcpEndpoint.java SimpleTcpConnector.java
                        SimpleTcpEndpoint.java
  Removed:     src/share/org/apache/tomcat/service/http HttpAdapter.java
  Log:
  - Moved the thread pooling endpoint in PoolTcpEndpoint, the original
  in SimpleTcpEndpoint. TcpEndpoint is now an abstract class, you need to
  use one subclass.
  
  - made SimpleTcpEndpoint the default, there are some problems with Pool on
  JDK1.2/Linux and it's safer to use the simpler ( Pool is much faster and should
  be used in production mode )
  
  - Removed HttpAdapter, use the TcpEndpoint with http adapter. ( HttpAdapter
  was a shortcut for that, we want to be able to fine tune http endpoint
  and connector )
  
  - Logger - added a "customOutput" property, don't try to do any formatting
  if it is set ( no timestamp, no prefix or suffix ).
  
  - Changed "visible" log messages to use the xml style. This will allow
  easy post-processing of logs, nice HTML display, filtering, etc.
  
  Revision  Changes    Path
  1.33      +12 -0     jakarta-tomcat/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/build.xml,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- build.xml	2000/02/18 18:14:49	1.32
  +++ build.xml	2000/02/22 21:06:32	1.33
  @@ -71,6 +71,13 @@
              destdir="${tomcat.build}/webapps/ROOT/WEB-INF/classes"
              classpath="${tomcat.build}/classes"/>
   
  +    <!-- admin context -->
  +    <mkdir dir="${tomcat.build}/webapps/admin"/>
  +    <copydir src="src/admin" dest="${tomcat.build}/webapps/admin"/>
  +    <javac srcdir="src/admin/WEB-INF/classes"
  +           destdir="${tomcat.build}/webapps/admin/WEB-INF/classes"
  +           classpath="${tomcat.build}/classes"/>
  +
       <!-- Test application -->
       <mkdir dir="${tomcat.build}/webapps/test"/>
       <copydir src="src/tests/webpages" dest="${tomcat.build}/webapps/test"/>
  @@ -118,6 +125,11 @@
              basedir="${tomcat.home}/webapps/examples"
              items="." /> 
       <deltree dir="${tomcat.home}/webapps/examples"/>
  +
  +    <jar   jarfile="${tomcat.home}/webapps/admin.war"
  +           basedir="${tomcat.home}/webapps/admin"
  +           items="." /> 
  +    <deltree dir="${tomcat.home}/webapps/admin"/>
   
       <jar   jarfile="${tomcat.home}/webapps/ROOT.war"
              basedir="${tomcat.home}/webapps/ROOT"
  
  
  
  1.10      +7 -16     jakarta-tomcat/src/etc/server.xml
  
  Index: server.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/etc/server.xml,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- server.xml	2000/02/18 18:14:49	1.9
  +++ server.xml	2000/02/22 21:06:33	1.10
  @@ -19,22 +19,12 @@
               DEBUG
            -->
   
  -    <Logger name="log:cm" 
  -	    verbosityLevel = "DEBUG" 
  -	    timestamp = "no" />
  +    <Logger name="tc_log" 
  +            customOutput="yes" />
   
  -    <Logger name="log:context" 
  -	    verbosityLevel = "DEBUG" 
  -	    timestamp = "no"/>
  -
  -    <Logger name="log:servlet" 
  +    <Logger name="servlet_log" 
               path="logs/servlet.log"
  -	    verbosityLevel = "DEBUG" 
  -	    timestamp = "no" />
  -
  -    <Logger name="log:startup"
  -            verbosityLevel = "DEBUG"
  -	    timestamp = "no" />
  +            customOutput="yes" />
   
       <Logger name="JASPER_LOG" 
   	    path="logs/jasper.log"
  @@ -53,11 +43,12 @@
           <RequestInterceptor className="org.apache.tomcat.request.SecurityCheck" />
           <RequestInterceptor className="org.apache.tomcat.request.FixHeaders" />
   
  -        <Connector className="org.apache.tomcat.service.http.HttpAdapter">
  +        <Connector className="org.apache.tomcat.service.SimpleTcpConnector">
  +            <Parameter name="handler" value="org.apache.tomcat.service.http.HttpConnectionHandler"/>
               <Parameter name="port" value="8080"/>
           </Connector>
   
  -        <Connector className="org.apache.tomcat.service.TcpEndpointConnector">
  +        <Connector className="org.apache.tomcat.service.SimpleTcpConnector">
               <Parameter name="handler" value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
               <Parameter name="port" value="8007"/>
           </Connector>
  
  
  
  1.2       +8 -5      jakarta-tomcat/src/j2ee/org/apache/tomcat/server/HttpServer.java
  
  Index: HttpServer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/j2ee/org/apache/tomcat/server/HttpServer.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- HttpServer.java	2000/02/11 00:22:36	1.1
  +++ HttpServer.java	2000/02/22 21:06:35	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/j2ee/org/apache/tomcat/server/HttpServer.java,v 1.1 2000/02/11 00:22:36 costin Exp $
  - * $Revision: 1.1 $
  - * $Date: 2000/02/11 00:22:36 $
  + * $Header: /home/cvs/jakarta-tomcat/src/j2ee/org/apache/tomcat/server/HttpServer.java,v 1.2 2000/02/22 21:06:35 costin Exp $
  + * $Revision: 1.2 $
  + * $Date: 2000/02/22 21:06:35 $
    *
    * ====================================================================
    *
  @@ -65,7 +65,8 @@
   package org.apache.tomcat.server;
   
   import org.apache.tomcat.core.*;
  -import org.apache.tomcat.service.http.HttpAdapter;
  +import org.apache.tomcat.service.http.*;
  +import org.apache.tomcat.service.*;
   import org.apache.tomcat.net.*;
   import org.apache.tomcat.util.*;
   import java.io.*;
  @@ -396,7 +397,9 @@
   	    // find a connector for the vhost:port combination
   	    // Use props and CONNECTOR_PROP to load configuration info
   	    // default is HttpServerConnector
  -	    addConnector(  new HttpAdapter() );
  +	    SimpleTcpConnector sc=new SimpleTcpConnector();
  +	    sc.setTcpConnectionHandler( new HttpConnectionHandler());
  +	    addConnector(  sc );
   	}
       }
   }
  
  
  
  1.7       +9 -5      jakarta-tomcat/src/share/org/apache/tomcat/context/AutoSetup.java
  
  Index: AutoSetup.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/context/AutoSetup.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- AutoSetup.java	2000/02/14 04:59:37	1.6
  +++ AutoSetup.java	2000/02/22 21:06:36	1.7
  @@ -79,10 +79,11 @@
    * @author costin@dnt.ro
    */
   public class AutoSetup extends BaseInterceptor {
  -
  +    int debug=0;
  +    
       public AutoSetup() {
       }
  -	
  +
       public void engineInit(ContextManager cm) throws TomcatException {
   	String home=cm.getHome();
   	File webappD=new File(home + "/webapps");
  @@ -135,13 +136,16 @@
   		ctx.setContextManager( cm );
   		ctx.setPath(path);
   		ctx.setDocBase(  "webapps/" + name);
  -		ctx.log("Automatic addContext webapps/" + name + ")");
  +		if( debug > 0) ctx.log("<l:autoLoadContext docBase=\"webapps/" + name + "\" />");
   		cm.addContext(ctx);
   	    } else {
   		//System.out.println("Already set up: " + path + " " + cm.getContext(path));
   	    }
  -
  -		
   	}
       }
  +
  +    public void setDebug( int i ) {
  +	debug=i;
  +    }
  +
   }
  
  
  
  1.60      +16 -26    jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java
  
  Index: Context.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java,v
  retrieving revision 1.59
  retrieving revision 1.60
  diff -u -r1.59 -r1.60
  --- Context.java	2000/02/18 18:14:50	1.59
  +++ Context.java	2000/02/22 21:06:36	1.60
  @@ -561,42 +561,32 @@
   	return debug;
       }
   
  -    boolean firstLog = true;
  -    Logger cLog = null;
  -    Logger csLog = null;
  -
  -    /** Internla log method
  +    /** Internal log method
        */
       public final void log(String msg) {
  -	if (firstLog == true) {
  -	    cLog = Logger.getLogger("log:context");
  -	    csLog = Logger.getLogger("log:servlet");
  -	    firstLog = false;
  -	}
  -	if (cLog != null)
  -	    cLog.log("Context(" + path  + "): " + msg, Logger.DEBUG);
  +	// XXX \n
  +	// Custom output -
  +	if( msg.startsWith( "<l:" ))
  +	    contextM.doLog( msg );
  +	else
  +	    contextM.doLog("<l:ctx path=\"" + path  + "\" >" + msg + "</l:ctx>");
       }
   
  +    boolean firstLog = true;
  +    Logger csLog = null;
  +
       /** User-level log method ( called from a servlet)
        */
  -    public void logServlet( String msg ) {
  -	if (firstLog == true) {
  -	    cLog = Logger.getLogger("log:context");
  -	    csLog = Logger.getLogger("log:servlet");
  -	    firstLog = false;
  -	}
  -	if (csLog != null)
  -	    csLog.log("Context(" + path  + "): " + msg, Logger.DEBUG);
  -    }
  -
       public void logServlet( String msg , Throwable t ) {
   	if (firstLog == true) {
  -	    cLog = Logger.getLogger("log:context");
  -	    csLog = Logger.getLogger("log:servlet");
  +	    csLog = Logger.getLogger("servlet_log");
  +	    csLog.setCustomOutput("true");
  +	    csLog.setVerbosityLevel(Logger.INFORMATION);
   	    firstLog = false;
  +	}
  +	if (csLog != null) {
  +	    csLog.log("<l:context path=\"" + path  + "\" >" + msg + "</l:context>");
   	}
  -	if (csLog != null)
  -	    csLog.log("Context(" + path  + "): " + msg, t, Logger.DEBUG);
       }
       
       public String toString() {
  
  
  
  1.51      +30 -22    jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java
  
  Index: ContextManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java,v
  retrieving revision 1.50
  retrieving revision 1.51
  diff -u -r1.50 -r1.51
  --- ContextManager.java	2000/02/18 18:14:50	1.50
  +++ ContextManager.java	2000/02/22 21:06:37	1.51
  @@ -147,7 +147,9 @@
       public void setDefaults() {
   	if(connectors.size()==0) {
   	    if(debug>5) log("Setting default adapter");
  -	    addServerConnector(  new org.apache.tomcat.service.http.HttpAdapter() );
  +	    org.apache.tomcat.service.SimpleTcpConnector sc=new org.apache.tomcat.service.SimpleTcpConnector();
  +	    sc.setTcpConnectionHandler( new org.apache.tomcat.service.http.HttpConnectionHandler());
  +	    addServerConnector(  sc );
   	}
   	
   	if( contextInterceptors.size()==0) {
  @@ -181,6 +183,8 @@
        *  and configured. 
        */
       public void init()  throws TomcatException {
  +	String cp=System.getProperty( "java.class.path");
  +	log( "<l:tomcat home=\"" + home + "\" classPath=\"" + cp + "\" />");
   	//	long time=System.currentTimeMillis();
   	ContextInterceptor cI[]=getContextInterceptors();
   	for( int i=0; i< cI.length; i++ ) {
  @@ -275,7 +279,7 @@
   	// it will replace existing context - it's better than  IllegalStateException.
   	String path=ctx.getPath();
   	if( getContext( path ) != null ) {
  -	    if(debug>0) log("Warning: replacing context for " + path, Logger.WARNING);
  +	    if(debug>0) log("Warning: replacing context for " + path);
   	    removeContext(path);
   	}
   
  @@ -284,7 +288,7 @@
   	    cI[i].addContext( this, ctx );
   	}
   	
  -	log(" adding " + ctx + " " + ctx.getPath() + " " +  ctx.getDocBase(), Logger.INFORMATION);
  +	ctx.log("<l:addContext path=\"" +  ctx.getPath() + "\"  docBase=\"" + ctx.getDocBase() + "\" />");
   
   	contexts.put( path, ctx );
       }
  @@ -338,7 +342,7 @@
        * @param con The new server connector
        */
       public synchronized void addServerConnector( ServerConnector con ) {
  -	log(" adding connector " + con.getClass().getName(), Logger.INFORMATION);
  +	if(debug>0) log("<l:addConnector javaClass=\"" + con.getClass().getName() + "\" />");
   	con.setContextManager( this );
   	connectors.addElement( con );
       }
  @@ -348,7 +352,7 @@
       }
       
       public void addRequestInterceptor( RequestInterceptor ri ) {
  -	if(debug>0) log(" adding request intereptor " + ri.getClass().getName(), Logger.INFORMATION);
  +	if(debug>0) log("<l:requestInterceptor javaClass=\"" + ri.getClass().getName() + "\" />");
   	requestInterceptors.addElement( ri );
   	if( ri instanceof ContextInterceptor )
   	    contextInterceptors.addElement( ri );
  @@ -465,7 +469,7 @@
        * WorkDir property - where all temporary files will be created
        */ 
       public void setWorkDir( String wd ) {
  -	if(debug>0) log("set work dir " + wd, Logger.INFORMATION);
  +	if(debug>0) log("set work dir " + wd);
   	this.workDir=wd;
       }
   
  @@ -483,6 +487,7 @@
       public void service( Request rrequest, Response rresponse ) {
   	//	log( "New  request " + rrequest );
   	try {
  +	    //	    System.out.print("A");
   	    rrequest.setContextManager( this );
   	    rrequest.setResponse(rresponse);
   	    rresponse.setRequest(rrequest);
  @@ -507,7 +512,7 @@
   	} catch (Throwable t) {
   	    handleError( rrequest, rresponse, t, 0 );
   	}
  -
  +	//	System.out.print("B");
   	try {
   	    rresponse.finish();
   	    rrequest.recycle();
  @@ -516,6 +521,7 @@
   	    if(debug>0) log( "Error closing request " + ex);
   	}
   	//	log( "Done with request " + rrequest );
  +	//	System.out.print("C");
   	return;
       }
   
  @@ -525,7 +531,7 @@
        */
       int processRequest( Request req ) {
   	req.setContextManager( this );
  -	if(debug>0) log("ProcessRequest: "+req.toString(), Logger.DEBUG);
  +	if(debug>0) log("ProcessRequest: "+req.toString());
   
   	for( int i=0; i< requestInterceptors.size(); i++ ) {
   	    ((RequestInterceptor)requestInterceptors.elementAt(i)).contextMap( req );
  @@ -535,7 +541,7 @@
   	    ((RequestInterceptor)requestInterceptors.elementAt(i)).requestMap( req );
   	}
   
  -	if(debug>0) log("After processing: "+req.toString(), Logger.DEBUG);
  +	if(debug>0) log("After processing: "+req.toString());
   
   	return 0;
       }
  @@ -700,27 +706,29 @@
   	debug=level;
       }
   
  +    public final void log(String msg) {
  +	if( msg.startsWith( "<l:" ))
  +	    doLog( msg );
  +	else
  +	    doLog("<l:tc>" + msg + "</l:tc>");
  +    }
  +
       boolean firstLog = true;
       Logger cmLog = null;
       
  -    public final void log(String msg) {
  +    public final void doLog(String msg) {
   	if (firstLog == true) {
  -	    cmLog = Logger.getLogger("log:cm");
  +	    cmLog = Logger.getLogger("tc_log");
  +	    cmLog.setCustomOutput("true");
  +	    cmLog.setVerbosityLevel(Logger.INFORMATION);
   	    firstLog = false;
   	}
   
  -	if (cmLog != null)
  -	    cmLog.log(msg, Logger.DEBUG);
  -    }
  -
  -    public final void log(String msg, int level) {
  -	if (firstLog == true) {
  -	    cmLog = Logger.getLogger("log:cm");
  -	    firstLog = false;
  +	if (cmLog != null) {
  +	    // customOutput !
  +	    cmLog.log(msg + "\n");
  +	    // XXX \n should be added to logger, portable
   	}
  -
  -	if (cmLog != null)
  -	    cmLog.log(msg, level);
       }
       
   }
  
  
  
  1.17      +1 -1      jakarta-tomcat/src/share/org/apache/tomcat/core/ServletContextFacade.java
  
  Index: ServletContextFacade.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletContextFacade.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- ServletContextFacade.java	2000/02/18 18:14:50	1.16
  +++ ServletContextFacade.java	2000/02/22 21:06:38	1.17
  @@ -162,7 +162,7 @@
       }
   
       public void log(String msg) {
  -	context.logServlet( msg );
  +	context.logServlet( msg, null );
       }
   
       public String getInitParameter(String name) {
  
  
  
  1.31      +5 -3      jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java
  
  Index: ServletWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- ServletWrapper.java	2000/02/18 00:17:48	1.30
  +++ ServletWrapper.java	2000/02/22 21:06:38	1.31
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java,v 1.30 2000/02/18 00:17:48 costin Exp $
  - * $Revision: 1.30 $
  - * $Date: 2000/02/18 00:17:48 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java,v 1.31 2000/02/22 21:06:38 costin Exp $
  + * $Revision: 1.31 $
  + * $Date: 2000/02/22 21:06:38 $
    *
    * ====================================================================
    *
  @@ -386,7 +386,9 @@
   		    servlet.service(req.getFacade(), res.getFacade());
   		}
   	    } else {
  +		//System.out.print("X");
   		servlet.service(req.getFacade(), res.getFacade());
  +		//System.out.print("Y");
   	    }
   	    
   	    for( int i=cI.length-1; i>=0; i-- ) {
  
  
  
  1.4       +12 -2     jakarta-tomcat/src/share/org/apache/tomcat/logging/Logger.java
  
  Index: Logger.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/logging/Logger.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Logger.java	2000/02/13 06:47:40	1.3
  +++ Logger.java	2000/02/22 21:06:40	1.4
  @@ -89,7 +89,6 @@
        * @param	verbosityLevel	what type of message is this? 
        *				(WARNING/DEBUG/INFO etc)
        */
  -     
       public static void log(String logName, String message, 
   			   int verbosityLevel) 
       {
  @@ -105,7 +104,6 @@
        * @param	name		the name of the logger. 
        * @param	message		the message to log. 
        */
  -     
       public static void log(String logName, String message)
       {
   	Logger logger = getLogger(logName);
  @@ -285,6 +283,10 @@
   	    timeStamp = false;
       }
   
  +    public  boolean isTimestamp() {
  +	return timeStamp;
  +    }
  +    
       /**
        * Set the default output stream that is used by all logging
        * channels. 
  @@ -307,6 +309,14 @@
   	loggers.remove(logger.getName());
       }
   
  +    public void setCustomOutput( String value ) {
  +	if ("true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value))
  +	    custom = true;
  +	else if ("false".equalsIgnoreCase(value) || "no".equalsIgnoreCase(value))
  +	    custom = false;
  +    }
  +
  +    protected boolean custom;
       protected Writer sink = defaultSink;
       protected String name;
       
  
  
  
  1.4       +8 -1      jakarta-tomcat/src/share/org/apache/tomcat/logging/TomcatLogger.java
  
  Index: TomcatLogger.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/logging/TomcatLogger.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TomcatLogger.java	2000/02/13 20:49:42	1.3
  +++ TomcatLogger.java	2000/02/22 21:06:40	1.4
  @@ -83,7 +83,9 @@
   	Throwable t;
   	
   	LogEntry(String message, Throwable t) {
  -	    this.date = System.currentTimeMillis();
  +	    // avoid expensive system call
  +	    if (TomcatLogger.this.timeStamp)
  +		this.date = System.currentTimeMillis();
   	    this.message = message;
   	    this.t = t;
   	}
  @@ -100,6 +102,11 @@
   	 * Format the log message nicely into a string.
   	 */
   	public String toString() {
  +
  +	    // custom output - do nothing
  +	    if( TomcatLogger.this.custom )
  +		return message;
  +	    
   	    StringWriter sw = new StringWriter();
   	    PrintWriter w = new PrintWriter(sw);
   
  
  
  
  1.6       +13 -7     jakarta-tomcat/src/share/org/apache/tomcat/request/SecurityCheck.java
  
  Index: SecurityCheck.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/request/SecurityCheck.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- SecurityCheck.java	2000/02/17 21:19:02	1.5
  +++ SecurityCheck.java	2000/02/22 21:06:43	1.6
  @@ -80,7 +80,8 @@
    */
   public class SecurityCheck extends  BaseInterceptor {
       MemoryRealm memoryRealm;
  -
  +    int debug=0;
  +    
       public SecurityCheck() {
       }
   	
  @@ -108,16 +109,16 @@
   	    // I don't understand the spec enough, so I can't comment the code 
   
   	    String form=ctx.getFormLoginPage();
  -	    ctx.log( "Adding form login " + form );
  +	    if( debug > 0 ) ctx.log( "Adding form login " + form );
   	    if( form!= null ) {
   		int lastS=form.lastIndexOf( "/" );
   		if( lastS<=0 ) {
   		    ctx.addServletMapping( "/j_security_check", "tomcat.jcheck" );
  -		    ctx.log( "Map  /j_security_check to tomcat.jcheck" );
  +		    if( debug > 0 ) ctx.log( "Map  /j_security_check to tomcat.jcheck" );
   		}  else {
   		    String dir=form.substring( 0, lastS);
   		    ctx.addServletMapping( dir + "/j_security_check", "tomcat.jcheck");
  -		    ctx.log( "Map " + dir + "/j_security_check to tomcat.jcheck");
  +		    if( debug > 0 ) ctx.log( "Map " + dir + "/j_security_check to tomcat.jcheck");
   		}
   	    }
   	}
  @@ -218,6 +219,10 @@
   	// XXX check transport
       }
   
  +    public void setDebug( int d ) {
  +	debug=d;
  +    }
  +    
       static int base64[]= {
   	    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
   	    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  @@ -279,13 +284,14 @@
       // String role -> Vector users
       Hashtable roles=new Hashtable();
       Context ctx;
  +    int debug=0;
       
       MemoryRealm(Context ctx) {
   	this.ctx=ctx;
       }
   
       public void addUser(String name, String pass, String groups ) {
  -	ctx.log( "Add user " + name + " " + pass + " " + groups );
  +	if( debug > 0 )  ctx.log( "Add user " + name + " " + pass + " " + groups );
   	passwords.put( name, pass );
   	addRole( groups, name );
       }
  @@ -300,13 +306,13 @@
       }
       
       public boolean checkPassword( String user, String pass ) {
  -	ctx.log( "check " + user+ " " + pass + " " + passwords.get( user ));
  +	if( debug > 0 ) ctx.log( "check " + user+ " " + pass + " " + passwords.get( user ));
   	return pass.equals( (String)passwords.get( user ) );
       }
   
       public boolean userInRole( String user, String role ) {
   	Vector users=(Vector)roles.get(role);
  -	ctx.log( "check role " + user+ " " + role + " "  );
  +	if( debug > 0 ) ctx.log( "check role " + user+ " " + role + " "  );
   	if(users==null) return false;
   	return users.indexOf( user ) >=0 ;
       }
  
  
  
  1.10      +7 -270    jakarta-tomcat/src/share/org/apache/tomcat/service/TcpEndpoint.java
  
  Index: TcpEndpoint.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/TcpEndpoint.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- TcpEndpoint.java	2000/02/17 23:37:49	1.9
  +++ TcpEndpoint.java	2000/02/22 21:06:45	1.10
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/TcpEndpoint.java,v 1.9 2000/02/17 23:37:49 costin Exp $
  - * $Revision: 1.9 $
  - * $Date: 2000/02/17 23:37:49 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/TcpEndpoint.java,v 1.10 2000/02/22 21:06:45 costin Exp $
  + * $Revision: 1.10 $
  + * $Date: 2000/02/22 21:06:45 $
    *
    * ====================================================================
    *
  @@ -92,15 +92,13 @@
    * @author Costin@eng.sun.com
    * @author Gal Shachor [shachor@il.ibm.com]
    */
  -public class TcpEndpoint  { // implements Endpoint {
  +public abstract class TcpEndpoint  { // implements Endpoint {
   
       private StringManager sm = StringManager.getManager("org.apache.tomcat.service");
   
       private static final int BACKLOG = 100;
       private static final int TIMEOUT = 1000;
   
  -    private boolean isPool = true;
  -
       private int backlog = BACKLOG;
       private int timeout = TIMEOUT;
   
  @@ -115,46 +113,7 @@
       Runnable listener;
       boolean running = true;
   
  -    ThreadPool tp;
  -
  -    public TcpEndpoint() {
  -        tp = new ThreadPool();
  -    }
  -
       // -------------------- Configuration --------------------
  -
  -    public void setPoolOn(boolean isPool) {
  -        this.isPool = isPool;
  -    }
  -
  -    public boolean isPoolOn() {
  -        return isPool;
  -    }
  -
  -    public void setMaxThreads(int maxThreads) {
  -        tp.setMaxThreads(maxThreads);
  -    }
  -
  -    public int getMaxThreads() {
  -        return tp.getMaxThreads();
  -    }
  -
  -    public void setMaxSpareThreads(int maxThreads) {
  -        tp.setMaxSpareThreads(maxThreads);
  -    }
  -
  -    public int getMaxSpareThreads() {
  -        return tp.getMaxSpareThreads();
  -    }
  -
  -    public void setMinSpareThreads(int minThreads) {
  -        tp.setMinSpareThreads(minThreads);
  -    }
  -
  -    public int getMinSpareThreads() {
  -        return tp.getMinSpareThreads();
  -    }
  -
       public int getPort() {
   	    return port;
       }
  @@ -211,231 +170,9 @@
       public void setTimeout(int timeout) {
   	    this.timeout = timeout;
       }
  -
  -    // -------------------- Public methods --------------------
   
  -    public void startEndpoint() throws IOException, InstantiationException {
  -	    try {
  -	        if(factory==null)
  -		        factory=ServerSocketFactory.getDefault();
  -	        if(serverSocket==null) {
  -		        if (inet != null) {
  -		            serverSocket = factory.createSocket(port, backlog);
  -    		    } else {
  -	    	        serverSocket = factory.createSocket(port, backlog, inet);
  -		        }
  -	        }
  -	        if(isPool) {
  -    	        tp.start();
  -    	    }
  -	    } catch( IOException ex ) {
  -	        // throw?
  -	        // ex.printStackTrace();
  -	        running=false;
  -            throw ex;
  -	        // throw new HttpServerException(msg);
  -	    } catch( InstantiationException ex1 ) {
  -	        // throw?
  -	        // ex1.printStackTrace();
  -	        running=false;
  -            throw ex1;
  -	        // throw new HttpServerException(msg);
  -	    }
  -	    running=true;
  -	    System.out.println("Starting tcp endpoint on " + port + " with " + handler.getClass().getName());
  -        if(isPool) {
  -    	    listener = new TcpWorkerThread(this);
  -            tp.runIt(listener);
  -        } else {
  -    	    listener = new TcpListenerThread( this );
  -	        Thread thread = new Thread(listener);
  -	        thread.start();
  -	    }
  -    }
  -
  -    public void stopEndpoint() {
  -        tp.shutdown();
  -	    running=false;
  -	    try {
  -	        serverSocket.close(); // XXX?
  -	    } catch(Exception e) {
  -	    }
  -	    serverSocket = null;
  -    }
  -
  -    // -------------------- Private methods
  -
  -    void processSocket(Socket s) throws IOException
  -    {
  -    	// XXX reuse, pools, etc
  -
  -    	// XXX set socket options
  -    	// 	s.setSoLinger( true, 100);
  -    	//	s.setSoTimeout( 1000 );
  -
  -    	TcpConnection con=new TcpConnection();
  -    	con.setEndpoint(this);
  -    	con.setSocket( s );
  -    	TcpConnectionHandler handler = getConnectionHandler();
  -    	TcpConnectionThread handlerThread=new TcpConnectionThread(handler, con);
  -
  -   	    new Thread(handlerThread).start();
  -    }
  -
  -    void acceptConnections() {
  -    	try {
  -    	    if(running == false)
  -        		return;
  -
  -    	    if(null!= serverSocket) {
  -        		Socket socket = acceptSocket();
  -    	    	if(running != false) {
  -        		    processSocket(socket);
  -        		}
  -    	    }
  -    	} catch(Throwable e) {
  -    	    running = false;
  -    	    String msg = sm.getString("endpoint.err.fatal",
  -    				                  serverSocket, e);
  -    	    e.printStackTrace(); // something very wrong happened - better know what
  -    	    System.err.println(msg);
  -    	}
  -    }
  -
  -    Socket acceptSocket() {
  -        Socket accepted = null;
  -    	try {
  -    	    if(running == true) {
  -        	    if(null!= serverSocket) {
  -            		accepted = serverSocket.accept();
  -    	        	if(running == false) {
  -    	        	    if(null != accepted) {
  -        		            accepted.close();  // rude, but unlikely!
  -        		            accepted = null;
  -        		        }
  -    		        }
  -    	        }
  -    	    }
  -    	} catch(InterruptedIOException iioe) {
  -    	    // normal part -- should happen regularly so
  -    	    // that the endpoint can release if the server
  -    	    // is shutdown.
  -    	    // you know, i really wish that there was a
  -    	    // way for the socket to timeout without
  -    	    // tripping an exception. Exceptions are so
  -    	    // 'spensive.
  -    	} catch (SocketException e) {
  -    	    if (running != false) {
  -        		running = false;
  -        		String msg = sm.getString("endpoint.err.fatal",
  -    					                  serverSocket, e);
  -    	    	e.printStackTrace(); // something very wrong happened - better know what
  -    		    System.err.println(msg);
  -    	    }
  -    	} catch(Throwable e) {
  -    	    running = false;
  -    	    String msg = sm.getString("endpoint.err.fatal",
  -    				                  serverSocket, e);
  -    	    e.printStackTrace(); // something very wrong happened - better know what
  -    	    System.err.println(msg);
  -    	}
  -
  -    	return accepted;
  -    }
  -}
  -
  -// -------------------- Threads --------------------
  -// XXX add a more efficient model - use thread pools, use a Queue, etc
  -
  -// Keep the thread model in one place !
  -
  -/*
  - * I switched the threading model here.
  - *
  - * We used to have a "listener" thread and a "connection"
  - * thread, this results in code simplicity but also a needless
  - * thread switch.
  - *
  - * Instead I am now using a pool of threads, all the threads are
  - * simmetric in their execution and no thread switch is needed.
  - */
  -class TcpWorkerThread implements Runnable {
  -    TcpEndpoint endpoint;
  -    Vector connectionCache;
  -
  -    public TcpWorkerThread(TcpEndpoint endpoint) {
  -	    this.endpoint = endpoint;
  -	    connectionCache = new Vector(endpoint.getMaxThreads());
  -	    for(int i = 0 ; i < endpoint.getMaxThreads()/2 ; i++) {
  -	        connectionCache.addElement(new TcpConnection());
  -	    }
  -    }
  -
  -    public void run() {
  -	    while(endpoint.running) {
  -		//		System.out.println("XXX accept socket");
  -	        Socket s = endpoint.acceptSocket();
  -		//		System.out.println("XXX accepted " + s );
  -	        if(null != s) {
  -	            // Continue accepting on another thread...
  -	            endpoint.tp.runIt(this);
  -
  -	            TcpConnection con = null;
  -	            try {
  -                	// XXX set socket options
  -                	// 	s.setSoLinger( true, 100);
  -                	//	s.setSoTimeout( 1000 );
  -                    try {
  -                        con = (TcpConnection)connectionCache.lastElement();
  -                        connectionCache.removeElementAt(connectionCache.size() - 1);
  -                    } catch(Throwable t) {
  -                        con = new TcpConnection();
  -                    }
  -
  -                	con.setEndpoint(endpoint);
  -                	con.setSocket(s);
  -                	endpoint.getConnectionHandler().processConnection(con, null);
  -                } finally {
  -                    con.recycle();
  -                    connectionCache.addElement(con);
  -                }
  -		    //		System.out.println("XXX done " + s  );
  -                break;
  -	        }
  -	    }
  -	    //	    System.out.println("End thread "   );
  -    }
  -}
  -
  -// Listener thread
  -class TcpListenerThread implements Runnable {
  -    TcpEndpoint endpoint;
  -
  -    public TcpListenerThread( TcpEndpoint endpoint) {
  -    	this.endpoint=endpoint;
  -    }
  -
  -    public void run() {
  -	    while (endpoint.running) {
  -	        endpoint.acceptConnections();
  -    	}
  -	    //endpoint.manager.notifyEndpointDown(this);
  -    }
  -}
  -
  -// Worker Thread
  -// call handleConnection() in a new thread
  -// XXX thread reuse!
  -class TcpConnectionThread implements Runnable {
  -    TcpConnectionHandler handler;
  -    TcpConnection connection;
  +    // -------------------- Abstract methods --------------------
   
  -    public TcpConnectionThread( TcpConnectionHandler handler, TcpConnection connection) {
  -    	this.handler=handler;
  -	    this.connection=connection;
  -    }
  -
  -    public void run() {
  -	    handler.processConnection(connection, null);
  -    }
  +    public abstract void startEndpoint() throws IOException, InstantiationException;
  +    public abstract void stopEndpoint();
   }
  
  
  
  1.5       +19 -88    jakarta-tomcat/src/share/org/apache/tomcat/service/TcpEndpointConnector.java
  
  Index: TcpEndpointConnector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/TcpEndpointConnector.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TcpEndpointConnector.java	2000/02/17 10:37:42	1.4
  +++ TcpEndpointConnector.java	2000/02/22 21:06:45	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/TcpEndpointConnector.java,v 1.4 2000/02/17 10:37:42 shachor Exp $
  - * $Revision: 1.4 $
  - * $Date: 2000/02/17 10:37:42 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/TcpEndpointConnector.java,v 1.5 2000/02/22 21:06:45 costin Exp $
  + * $Revision: 1.5 $
  + * $Date: 2000/02/22 21:06:45 $
    *
    * ====================================================================
    *
  @@ -71,16 +71,6 @@
   import java.net.*;
   import java.util.*;
   
  -//import org.apache.tomcat.server.HttpServer;
  -
  -/* Similar with MPM module in Apache2.0. Handles all the details related with
  -   "tcp server" functionality - thread management, accept policy, etc.
  -   It should do nothing more - as soon as it get a socket ( and all socket options
  -   are set, etc), it just handle the stream to ConnectionHandler.processConnection. (costin)
  -*/
  -
  -
  -
   /**
    * Connector for a TCP-based connector using the API in tomcat.service.
    * You need to set a "connection.handler" property with the class name of
  @@ -89,7 +79,7 @@
    * @author costin@eng.sun.com
    * @author Gal Shachor [shachor@il.ibm.com]
    */
  -public class TcpEndpointConnector  implements ServerConnector {
  +public abstract  class TcpEndpointConnector  implements ServerConnector {
       // Attributes we accept ( to support the old model of
       // configuration, will be deprecated )
       public static final String VHOST_PORT="vhost_port";
  @@ -104,20 +94,10 @@
       public static final String PORT = "port";
       public static final String HANDLER = "handler";
   
  -    /*
  -     * Threading and mod_mpm style properties.
  -     */
  -    public static final String THREAD_POOL = "thread_pool";
  -    public static final String MAX_THREADS = "max_threads";
  -    public static final String MAX_SPARE_THREADS = "max_spare_threads";
  -    public static final String MIN_SPARE_THREADS = "min_spare_threads";
  -    public static final String BACKLOG = "backlog";
  -
       // XXX define ConnectorException
       // XXX replace strings with sm.get...
       // XXX replace static strings with constants
       String handlerClassName;
  -    TcpEndpoint ep;
       TcpConnectionHandler con;
   
       ContextManager cm;
  @@ -125,54 +105,17 @@
       private InetAddress address;
       private int port;
   
  -    private int backlog = -1;
  -    private boolean usePools = true;
  -    private int maxThreads = -1;
  -    private int maxSpareThreads = -1;
  -    private int minSpareThreads = -1;
  -
       int vport;
   
       private ServerSocketFactory socketFactory;
       private ServerSocket serverSocket;
   
       boolean running = true;
  -
  -    public TcpEndpointConnector() {
  -    	ep = new TcpEndpoint();
  -    }
   
  -    public void start() throws Exception {
  -    	if(con==null)
  -    	    throw new Exception( "Invalid ConnectionHandler");
  -
  -	    con.setAttribute("context.manager",cm );
  -    	ep.setPort(port);
  -    	ep.setPoolOn(usePools);
  -    	if(backlog > 0) {
  -    	    ep.setBacklog(backlog);
  -    	}
  -    	if(maxThreads > 0) {
  -    	    ep.setMaxThreads(maxThreads);
  -    	}
  -    	if(maxSpareThreads > 0) {
  -    	    ep.setMaxSpareThreads(maxSpareThreads);
  -    	}
  -    	if(minSpareThreads > 0) {
  -    	    ep.setMinSpareThreads(minSpareThreads);
  -    	}
  -
  -	    if(socketFactory != null) {
  -	        ep.setServerSocketFactory( socketFactory );
  -	    }
  -	    ep.setConnectionHandler( con );
  -	    ep.startEndpoint();
  -    }
  -
  -    public void stop() throws Exception {
  -    	ep.stopEndpoint();
  -    }
  -
  +    public abstract void start() throws Exception;
  +    
  +    public abstract void stop() throws Exception;
  +    
       public void setContextManager( ContextManager ctx ) {
   	    this.cm=ctx;
       }
  @@ -202,23 +145,11 @@
       	    setPort( value );
       	} else if(HANDLER.equals(prop)) {
       	    try {
  -        		Class chC=Class.forName( value );
  +		Class chC=Class.forName( value );
       	    	con=(TcpConnectionHandler)chC.newInstance();
       	    } catch( Exception ex) {
  -        		ex.printStackTrace();
  +		ex.printStackTrace();
       	    }
  -    	} else if(THREAD_POOL.equals(prop)) {
  -    	    if(value.equalsIgnoreCase("off")) {
  -    	        usePools = false;
  -    	    }
  -    	} else if(MAX_THREADS.equals(prop)) {
  -    	    maxThreads = string2Int(value);
  -    	} else if(MAX_SPARE_THREADS.equals(prop)) {
  -    	    maxSpareThreads = string2Int(value);
  -    	} else if(MIN_SPARE_THREADS.equals(prop)) {
  -    	    minSpareThreads = string2Int(value);
  -    	} else if(BACKLOG.equals(prop)) {
  -    	    backlog = string2Int(value);
       	}
       }
   
  @@ -226,17 +157,17 @@
       public void setAttribute( String prop, Object value) {
       	if(VHOST_NAME.equals(prop) ) {
   	        //vhost=(String)value;
  -	    } else if(VHOST_PORT.equals(prop) ) {
  -	        vport=((Integer)value).intValue();
  -	    } else if(VHOST_ADDRESS.equals(prop)) {
  -	        address=(InetAddress)value;
  -	    } else if(SERVER.equals(prop)) {
  +	} else if(VHOST_PORT.equals(prop) ) {
  +	    vport=((Integer)value).intValue();
  +	} else if(VHOST_ADDRESS.equals(prop)) {
  +	    address=(InetAddress)value;
  +	} else if(SERVER.equals(prop)) {
       	    //server=(HttpServer)value;
  -	    } else if(SOCKET_FACTORY.equals(prop)) {
  +	} else if(SOCKET_FACTORY.equals(prop)) {
       	    socketFactory=(ServerSocketFactory)value;
  -	    }
  +	}
       }
  -
  +    
       public Object getAttribute( String prop ) {
   	    return null;
       }
  @@ -248,4 +179,4 @@
   	        return 0;
       	}
       }
  -}
  \ No newline at end of file
  +}
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/service/PoolTcpConnector.java
  
  Index: PoolTcpConnector.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/PoolTcpConnector.java,v 1.1 2000/02/22 21:06:43 costin Exp $
   * $Revision: 1.1 $
   * $Date: 2000/02/22 21:06:43 $
   *
   * ====================================================================
   *
   * 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.service;
  
  import org.apache.tomcat.util.*;
  import org.apache.tomcat.core.*;
  import org.apache.tomcat.net.*;
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  //import org.apache.tomcat.server.HttpServer;
  
  /* Similar with MPM module in Apache2.0. Handles all the details related with
     "tcp server" functionality - thread management, accept policy, etc.
     It should do nothing more - as soon as it get a socket ( and all socket options
     are set, etc), it just handle the stream to ConnectionHandler.processConnection. (costin)
  */
  
  
  
  /**
   * Connector for a TCP-based connector using the API in tomcat.service.
   * You need to set a "connection.handler" property with the class name of
   * the TCP connection handler
   *
   * @author costin@eng.sun.com
   * @author Gal Shachor [shachor@il.ibm.com]
   */
  public class PoolTcpConnector  extends TcpEndpointConnector  implements ServerConnector {
      // Attributes we accept ( to support the old model of
      // configuration, will be deprecated )
      public static final String VHOST_PORT="vhost_port";
      public static final String VHOST_NAME="vhost_name";
  
      // needed only as a "hack" to HttpServerConnector
      public static final String SERVER="server";
      public static final String VHOST_ADDRESS="vhost_address";
      public static final String SOCKET_FACTORY="socketFactory";
  
  
      public static final String PORT = "port";
      public static final String HANDLER = "handler";
  
      /*
       * Threading and mod_mpm style properties.
       */
      public static final String THREAD_POOL = "thread_pool";
      public static final String MAX_THREADS = "max_threads";
      public static final String MAX_SPARE_THREADS = "max_spare_threads";
      public static final String MIN_SPARE_THREADS = "min_spare_threads";
      public static final String BACKLOG = "backlog";
  
      // XXX define ConnectorException
      // XXX replace strings with sm.get...
      // XXX replace static strings with constants
      String handlerClassName;
      PoolTcpEndpoint ep;
      TcpConnectionHandler con;
  
      ContextManager cm;
  
      private InetAddress address;
      private int port;
  
      private int backlog = -1;
      private boolean usePools = true;
      private int maxThreads = -1;
      private int maxSpareThreads = -1;
      private int minSpareThreads = -1;
  
      int vport;
  
      private ServerSocketFactory socketFactory;
      private ServerSocket serverSocket;
  
      boolean running = true;
  
      public PoolTcpConnector() {
      	ep = new PoolTcpEndpoint();
      }
  
      public void start() throws Exception {
      	if(con==null)
      	    throw new Exception( "Invalid ConnectionHandler");
  
  	    con.setAttribute("context.manager",cm );
      	ep.setPort(port);
      	ep.setPoolOn(usePools);
      	if(backlog > 0) {
      	    ep.setBacklog(backlog);
      	}
      	if(maxThreads > 0) {
      	    ep.setMaxThreads(maxThreads);
      	}
      	if(maxSpareThreads > 0) {
      	    ep.setMaxSpareThreads(maxSpareThreads);
      	}
      	if(minSpareThreads > 0) {
      	    ep.setMinSpareThreads(minSpareThreads);
      	}
  
  	if(socketFactory != null) {
  	    ep.setServerSocketFactory( socketFactory );
  	}
  	ep.setConnectionHandler( con );
  	ep.startEndpoint();
  	System.out.println("Starting tcp endpoint on " + port + " with " + con.getClass().getName());
      }
  
      public void stop() throws Exception {
      	ep.stopEndpoint();
      }
  
      public void setContextManager( ContextManager ctx ) {
  	    this.cm=ctx;
      }
  
      public void setTcpConnectionHandler( TcpConnectionHandler handler) {
      	this.con=handler;
      }
  
      public TcpConnectionHandler getTcpConnectionHandler() {
  	    return con;
      }
  
      public void setPort( int port ) {
      	this.port=port;
      }
  
      public void setPort(  String portS ) {
  	    this.port=string2Int( portS );
      }
  
      public int getPort() {
      	return port;
      }
  
      public void setProperty( String prop, String value) {
      	if(PORT.equals(prop) ) {
      	    setPort( value );
      	} else if(HANDLER.equals(prop)) {
      	    try {
          		Class chC=Class.forName( value );
      	    	con=(TcpConnectionHandler)chC.newInstance();
      	    } catch( Exception ex) {
          		ex.printStackTrace();
      	    }
      	} else if(THREAD_POOL.equals(prop)) {
      	    if(value.equalsIgnoreCase("off")) {
      	        usePools = false;
      	    }
      	} else if(MAX_THREADS.equals(prop)) {
      	    maxThreads = string2Int(value);
      	} else if(MAX_SPARE_THREADS.equals(prop)) {
      	    maxSpareThreads = string2Int(value);
      	} else if(MIN_SPARE_THREADS.equals(prop)) {
      	    minSpareThreads = string2Int(value);
      	} else if(BACKLOG.equals(prop)) {
      	    backlog = string2Int(value);
      	}
      }
  
      // XXX use constants, remove dep on HttpServer
      public void setAttribute( String prop, Object value) {
      	if(VHOST_NAME.equals(prop) ) {
  	        //vhost=(String)value;
  	    } else if(VHOST_PORT.equals(prop) ) {
  	        vport=((Integer)value).intValue();
  	    } else if(VHOST_ADDRESS.equals(prop)) {
  	        address=(InetAddress)value;
  	    } else if(SERVER.equals(prop)) {
      	    //server=(HttpServer)value;
  	    } else if(SOCKET_FACTORY.equals(prop)) {
      	    socketFactory=(ServerSocketFactory)value;
  	    }
      }
  
      public Object getAttribute( String prop ) {
  	    return null;
      }
  
      private int string2Int( String val) {
      	try {
  	        return Integer.parseInt(val);
      	} catch (NumberFormatException nfe) {
  	        return 0;
      	}
      }
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/service/PoolTcpEndpoint.java
  
  Index: PoolTcpEndpoint.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/PoolTcpEndpoint.java,v 1.1 2000/02/22 21:06:44 costin Exp $
   * $Revision: 1.1 $
   * $Date: 2000/02/22 21:06:44 $
   *
   * ====================================================================
   *
   * 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.service;
  
  import org.apache.tomcat.util.*;
  import org.apache.tomcat.net.*;
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  /* Similar with MPM module in Apache2.0. Handles all the details related with
     "tcp server" functionality - thread management, accept policy, etc.
     It should do nothing more - as soon as it get a socket ( and all socket options
     are set, etc), it just handle the stream to ConnectionHandler.processConnection. (costin)
  */
  
  
  
  /**
   * Handle incoming TCP connections.
   *
   * This class implement a simple server model: one listener thread accepts on a socket and
   * creates a new worker thread for each incoming connection.
   *
   * More advanced Endpoints will reuse the threads, use queues, etc.
   *
   * @author James Duncan Davidson [duncan@eng.sun.com]
   * @author Jason Hunter [jch@eng.sun.com]
   * @author James Todd [gonzo@eng.sun.com]
   * @author Costin@eng.sun.com
   * @author Gal Shachor [shachor@il.ibm.com]
   */
  public class PoolTcpEndpoint extends TcpEndpoint  { // implements Endpoint {
  
      private StringManager sm = StringManager.getManager("org.apache.tomcat.service");
  
      private static final int BACKLOG = 100;
      private static final int TIMEOUT = 1000;
  
      private boolean isPool = true;
  
      private int backlog = BACKLOG;
      private int timeout = TIMEOUT;
  
      TcpConnectionHandler handler;
  
      private InetAddress inet;
      private int port;
  
      private ServerSocketFactory factory;
      private ServerSocket serverSocket;
  
      Runnable listener;
      boolean running = true;
  
      ThreadPool tp;
  
      public PoolTcpEndpoint() {
  	tp = new ThreadPool();
      }
  
      // -------------------- Configuration --------------------
  
      public void setPoolOn(boolean isPool) {
          this.isPool = isPool;
      }
  
      public boolean isPoolOn() {
          return isPool;
      }
  
      public void setMaxThreads(int maxThreads) {
          tp.setMaxThreads(maxThreads);
      }
  
      public int getMaxThreads() {
          return tp.getMaxThreads();
      }
  
      public void setMaxSpareThreads(int maxThreads) {
          tp.setMaxSpareThreads(maxThreads);
      }
  
      public int getMaxSpareThreads() {
          return tp.getMaxSpareThreads();
      }
  
      public void setMinSpareThreads(int minThreads) {
          tp.setMinSpareThreads(minThreads);
      }
  
      public int getMinSpareThreads() {
          return tp.getMinSpareThreads();
      }
  
      public int getPort() {
  	    return port;
      }
  
      public void setPort(int port ) {
  	    this.port=port;
      }
  
      public InetAddress getAddress() {
  	    return inet;
      }
  
      public void setAddress(InetAddress inet) {
  	    this.inet=inet;
      }
  
      public void setServerSocket(ServerSocket ss) {
  	    serverSocket = ss;
      }
  
      public void setServerSocketFactory(  ServerSocketFactory factory ) {
  	    this.factory=factory;
      }
  
      public void setConnectionHandler( TcpConnectionHandler handler ) {
      	this.handler=handler;
      }
  
      public TcpConnectionHandler getConnectionHandler() {
  	    return handler;
      }
  
      /**
       * Allows the server developer to specify the backlog that
       * should be used for server sockets. By default, this value
       * is 100.
       */
      public void setBacklog(int backlog) {
  	    this.backlog = backlog;
      }
  
      public int getBacklog() {
          return backlog;
      }
  
      /**
       * Sets the timeout in ms of the server sockets created by this
       * server. This method allows the developer to make servers
       * more or less responsive to having their server sockets
       * shut down.
       *
       * <p>By default this value is 1000ms.
       */
      public void setTimeout(int timeout) {
  	    this.timeout = timeout;
      }
  
      // -------------------- Public methods --------------------
  
      public void startEndpoint() throws IOException, InstantiationException {
  	    try {
  	        if(factory==null)
  		        factory=ServerSocketFactory.getDefault();
  	        if(serverSocket==null) {
  		        if (inet != null) {
  		            serverSocket = factory.createSocket(port, backlog);
      		    } else {
  	    	        serverSocket = factory.createSocket(port, backlog, inet);
  		        }
  	        }
  	        if(isPool) {
  		    tp.start();
  		}
  	    } catch( IOException ex ) {
  	        // throw?
  	        // ex.printStackTrace();
  	        running=false;
              throw ex;
  	        // throw new HttpServerException(msg);
  	    } catch( InstantiationException ex1 ) {
  	        // throw?
  	        // ex1.printStackTrace();
  	        running=false;
              throw ex1;
  	        // throw new HttpServerException(msg);
  	    }
  	    running=true;
          if(isPool) {
      	    listener = new TcpWorkerThread(this);
              tp.runIt(listener);
          } else {
      	    System.out.println("XXX Error - need pool !");
  	}
      }
  
      public void stopEndpoint() {
          tp.shutdown();
  	running=false;
  	try {
  	    serverSocket.close(); // XXX?
  	} catch(Exception e) {
  	}
  	serverSocket = null;
      }
  
      // -------------------- Private methods
  
      Socket acceptSocket() {
          Socket accepted = null;
      	try {
      	    if(running == true) {
          	    if(null!= serverSocket) {
              		accepted = serverSocket.accept();
      	        	if(running == false) {
      	        	    if(null != accepted) {
          		            accepted.close();  // rude, but unlikely!
          		            accepted = null;
          		        }
      		        }
      	        }
      	    }
      	} catch(InterruptedIOException iioe) {
      	    // normal part -- should happen regularly so
      	    // that the endpoint can release if the server
      	    // is shutdown.
      	    // you know, i really wish that there was a
      	    // way for the socket to timeout without
      	    // tripping an exception. Exceptions are so
      	    // 'spensive.
      	} catch (SocketException e) {
      	    if (running != false) {
          		running = false;
          		String msg = sm.getString("endpoint.err.fatal",
      					                  serverSocket, e);
      	    	e.printStackTrace(); // something very wrong happened - better know what
      		    System.err.println(msg);
      	    }
      	} catch(Throwable e) {
      	    running = false;
      	    String msg = sm.getString("endpoint.err.fatal",
      				                  serverSocket, e);
      	    e.printStackTrace(); // something very wrong happened - better know what
      	    System.err.println(msg);
      	}
  
      	return accepted;
      }
  }
  
  // -------------------- Threads --------------------
  // XXX add a more efficient model - use thread pools, use a Queue, etc
  
  // Keep the thread model in one place !
  
  /*
   * I switched the threading model here.
   *
   * We used to have a "listener" thread and a "connection"
   * thread, this results in code simplicity but also a needless
   * thread switch.
   *
   * Instead I am now using a pool of threads, all the threads are
   * simmetric in their execution and no thread switch is needed.
   */
  class TcpWorkerThread implements Runnable {
      PoolTcpEndpoint endpoint;
      Vector connectionCache;
  
      public TcpWorkerThread(PoolTcpEndpoint endpoint) {
  	    this.endpoint = endpoint;
  	    connectionCache = new Vector(endpoint.getMaxThreads());
  	    for(int i = 0 ; i < endpoint.getMaxThreads()/2 ; i++) {
  	        connectionCache.addElement(new TcpConnection());
  	    }
      }
  
      public void run() {
  	    while(endpoint.running) {
  		//		System.out.println("XXX accept socket");
  	        Socket s = endpoint.acceptSocket();
  		//		System.out.print("Ac");
  		//		System.out.println("XXX accepted " + s );
  	        if(null != s) {
  	            // Continue accepting on another thread...
  		    //		    System.out.print("Ar");
  	            endpoint.tp.runIt(this);
  		    //  System.out.print("Ri");
  	            TcpConnection con = null;
  	            try {
                  	// XXX set socket options
                  	// 	s.setSoLinger( true, 100);
                  	//	s.setSoTimeout( 1000 );
  			try {
  			    con = (TcpConnection)connectionCache.lastElement();
  			    connectionCache.removeElementAt(connectionCache.size() - 1);
  			} catch(Throwable t) {
  			    con = new TcpConnection();
  			}
  
                  	con.setEndpoint(endpoint);
                  	con.setSocket(s);
                  	endpoint.getConnectionHandler().processConnection(con, null);
                  } finally {
                      con.recycle();
                      connectionCache.addElement(con);
                  }
  		    //		System.out.println("XXX done " + s  );
                  break;
  	        }
  	    }
  	    //	    System.out.println("End thread "   );
      }
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/service/SimpleTcpConnector.java
  
  Index: SimpleTcpConnector.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/SimpleTcpConnector.java,v 1.1 2000/02/22 21:06:44 costin Exp $
   * $Revision: 1.1 $
   * $Date: 2000/02/22 21:06:44 $
   *
   * ====================================================================
   *
   * 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.service;
  
  import org.apache.tomcat.util.*;
  import org.apache.tomcat.core.*;
  import org.apache.tomcat.net.*;
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  //import org.apache.tomcat.server.HttpServer;
  
  /* Similar with MPM module in Apache2.0. Handles all the details related with
     "tcp server" functionality - thread management, accept policy, etc.
     It should do nothing more - as soon as it get a socket ( and all socket options
     are set, etc), it just handle the stream to ConnectionHandler.processConnection. (costin)
  */
  
  
  
  /**
   * Connector for a TCP-based connector using the API in tomcat.service.
   * You need to set a "connection.handler" property with the class name of
   * the TCP connection handler
   *
   * @author costin@eng.sun.com
   * @author Gal Shachor [shachor@il.ibm.com]
   */
  public class SimpleTcpConnector  extends TcpEndpointConnector implements ServerConnector  {
      // Attributes we accept ( to support the old model of
      // configuration, will be deprecated )
      public static final String VHOST_PORT="vhost_port";
      public static final String VHOST_NAME="vhost_name";
  
      // needed only as a "hack" to HttpServerConnector
      public static final String SERVER="server";
      public static final String VHOST_ADDRESS="vhost_address";
      public static final String SOCKET_FACTORY="socketFactory";
  
  
      public static final String PORT = "port";
      public static final String HANDLER = "handler";
  
      // XXX define ConnectorException
      // XXX replace strings with sm.get...
      // XXX replace static strings with constants
      String handlerClassName;
      SimpleTcpEndpoint ep;
      TcpConnectionHandler con;
  
      ContextManager cm;
  
      private InetAddress address;
      private int port;
  
      int vport;
  
      private ServerSocketFactory socketFactory;
      private ServerSocket serverSocket;
  
      boolean running = true;
  
      public SimpleTcpConnector() {
      	ep = new SimpleTcpEndpoint();
      }
  
      public void start() throws Exception {
      	if(con==null)
      	    throw new Exception( "Invalid ConnectionHandler");
  
  	con.setAttribute("context.manager",cm );
      	ep.setPort(port);
  	if(socketFactory != null) {
  	    ep.setServerSocketFactory( socketFactory );
  	}
  	ep.setConnectionHandler( con );
  	ep.startEndpoint();
  	cm.log("<l:startEndpoint port=\"" + port + "\" handler=\"" + con.getClass().getName() + "\" />");
      }
  
      public void stop() throws Exception {
      	ep.stopEndpoint();
      }
  
      public void setContextManager( ContextManager ctx ) {
  	    this.cm=ctx;
      }
  
      public void setTcpConnectionHandler( TcpConnectionHandler handler) {
      	this.con=handler;
      }
  
      public TcpConnectionHandler getTcpConnectionHandler() {
  	    return con;
      }
  
      public void setPort( int port ) {
      	this.port=port;
      }
  
      public void setPort(  String portS ) {
  	    this.port=string2Int( portS );
      }
  
      public int getPort() {
      	return port;
      }
  
      public void setProperty( String prop, String value) {
      	if(PORT.equals(prop) ) {
      	    setPort( value );
      	} else if(HANDLER.equals(prop)) {
      	    try {
  		Class chC=Class.forName( value );
      	    	con=(TcpConnectionHandler)chC.newInstance();
      	    } catch( Exception ex) {
  		ex.printStackTrace();
      	    }
      	}
      }
  
      // XXX use constants, remove dep on HttpServer
      public void setAttribute( String prop, Object value) {
      	if(VHOST_NAME.equals(prop) ) {
  	        //vhost=(String)value;
  	} else if(VHOST_PORT.equals(prop) ) {
  	    vport=((Integer)value).intValue();
  	} else if(VHOST_ADDRESS.equals(prop)) {
  	    address=(InetAddress)value;
  	} else if(SERVER.equals(prop)) {
      	    //server=(HttpServer)value;
  	} else if(SOCKET_FACTORY.equals(prop)) {
      	    socketFactory=(ServerSocketFactory)value;
  	}
      }
      
      public Object getAttribute( String prop ) {
  	    return null;
      }
  
      private int string2Int( String val) {
      	try {
  	        return Integer.parseInt(val);
      	} catch (NumberFormatException nfe) {
  	        return 0;
      	}
      }
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/service/SimpleTcpEndpoint.java
  
  Index: SimpleTcpEndpoint.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/SimpleTcpEndpoint.java,v 1.1 2000/02/22 21:06:44 costin Exp $
   * $Revision: 1.1 $
   * $Date: 2000/02/22 21:06:44 $
   *
   * ====================================================================
   *
   * 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.service;
  
  import org.apache.tomcat.util.*;
  import org.apache.tomcat.net.*;
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  /* Similar with MPM module in Apache2.0. Handles all the details related with
     "tcp server" functionality - thread management, accept policy, etc.
     It should do nothing more - as soon as it get a socket ( and all socket options
     are set, etc), it just handle the stream to ConnectionHandler.processConnection. (costin)
  */
  
  
  
  /**
   * Handle incoming TCP connections.
   *
   * This class implement a simple server model: one listener thread accepts on a socket and
   * creates a new worker thread for each incoming connection.
   *
   * More advanced Endpoints will reuse the threads, use queues, etc.
   *
   * @author James Duncan Davidson [duncan@eng.sun.com]
   * @author Jason Hunter [jch@eng.sun.com]
   * @author James Todd [gonzo@eng.sun.com]
   * @author Costin@eng.sun.com
   * @author Gal Shachor [shachor@il.ibm.com]
   */
  public class SimpleTcpEndpoint  extends TcpEndpoint { // implements Endpoint {
  
      private StringManager sm = StringManager.getManager("org.apache.tomcat.service");
  
      private static final int BACKLOG = 100;
      private static final int TIMEOUT = 1000;
  
      private int backlog = BACKLOG;
      private int timeout = TIMEOUT;
  
      TcpConnectionHandler handler;
  
      private InetAddress inet;
      private int port;
  
      private ServerSocketFactory factory;
      private ServerSocket serverSocket;
  
      Runnable listener;
      boolean running = true;
  
      public SimpleTcpEndpoint() {
      }
  
      // -------------------- Configuration --------------------
  
      public int getPort() {
  	    return port;
      }
  
      public void setPort(int port ) {
  	    this.port=port;
      }
  
      public InetAddress getAddress() {
  	    return inet;
      }
  
      public void setAddress(InetAddress inet) {
  	    this.inet=inet;
      }
  
      public void setServerSocket(ServerSocket ss) {
  	    serverSocket = ss;
      }
  
      public void setServerSocketFactory(  ServerSocketFactory factory ) {
  	    this.factory=factory;
      }
  
      public void setConnectionHandler( TcpConnectionHandler handler ) {
      	this.handler=handler;
      }
  
      public TcpConnectionHandler getConnectionHandler() {
  	    return handler;
      }
  
      /**
       * Allows the server developer to specify the backlog that
       * should be used for server sockets. By default, this value
       * is 100.
       */
      public void setBacklog(int backlog) {
  	    this.backlog = backlog;
      }
  
      public int getBacklog() {
          return backlog;
      }
  
      /**
       * Sets the timeout in ms of the server sockets created by this
       * server. This method allows the developer to make servers
       * more or less responsive to having their server sockets
       * shut down.
       *
       * <p>By default this value is 1000ms.
       */
      public void setTimeout(int timeout) {
  	    this.timeout = timeout;
      }
  
      // -------------------- Public methods --------------------
  
      public void startEndpoint() throws IOException, InstantiationException {
  	try {
  	    if(factory==null)
  		factory=ServerSocketFactory.getDefault();
  	    if(serverSocket==null) {
  		if (inet != null) {
  		    serverSocket = factory.createSocket(port, backlog);
  		} else {
  		    serverSocket = factory.createSocket(port, backlog, inet);
  		}
  	    }
  	} catch( IOException ex ) {
  	    // throw?
  	    // ex.printStackTrace();
  	    running=false;
              throw ex;
  	    // throw new HttpServerException(msg);
  	} catch( InstantiationException ex1 ) {
  	    // throw?
  	    // ex1.printStackTrace();
  	    running=false;
              throw ex1;
  	    // throw new HttpServerException(msg);
  	}
  	running=true;
  	listener = new TcpListenerThread( this );
  	Thread thread = new Thread(listener);
  	thread.start();
      }
      
      public void stopEndpoint() {
      	running=false;
  	try {
  	    serverSocket.close(); // XXX?
  	} catch(Exception e) {
  	}
  	serverSocket = null;
      }
      
      // -------------------- Private methods
  
      void processSocket(Socket s) throws IOException
      {
      	// XXX reuse, pools, etc
  
      	// XXX set socket options
      	// 	s.setSoLinger( true, 100);
      	//	s.setSoTimeout( 1000 );
  
      	TcpConnection con=new TcpConnection();
      	con.setEndpoint(this);
      	con.setSocket( s );
      	TcpConnectionHandler handler = getConnectionHandler();
      	TcpConnectionThread handlerThread=new TcpConnectionThread(handler, con);
  	
  	new Thread(handlerThread).start();
      }
  
      void acceptConnections() {
      	try {
      	    if(running == false)
  		return;
  	    
      	    if(null!= serverSocket) {
  		Socket socket = acceptSocket();
      	    	if(running != false) {
  		    processSocket(socket);
  		}
      	    }
      	} catch(Throwable e) {
      	    running = false;
      	    String msg = sm.getString("endpoint.err.fatal",
  				      serverSocket, e);
      	    e.printStackTrace(); // something very wrong happened - better know what
      	    System.err.println(msg);
      	}
      }
  
      Socket acceptSocket() {
          Socket accepted = null;
      	try {
      	    if(running == true) {
  		if(null!= serverSocket) {
  		    accepted = serverSocket.accept();
  		    if(running == false) {
  			if(null != accepted) {
  			    accepted.close();  // rude, but unlikely!
  			    accepted = null;
  			}
  		    }
      	        }
      	    }
      	} catch(InterruptedIOException iioe) {
      	    // normal part -- should happen regularly so
      	    // that the endpoint can release if the server
      	    // is shutdown.
      	    // you know, i really wish that there was a
      	    // way for the socket to timeout without
      	    // tripping an exception. Exceptions are so
      	    // 'spensive.
      	} catch (SocketException e) {
      	    if (running != false) {
  		running = false;
  		String msg = sm.getString("endpoint.err.fatal",
  					  serverSocket, e);
      	    	e.printStackTrace(); // something very wrong happened - better know what
  		System.err.println(msg);
      	    }
      	} catch(Throwable e) {
      	    running = false;
      	    String msg = sm.getString("endpoint.err.fatal",
  				      serverSocket, e);
      	    e.printStackTrace(); // something very wrong happened - better know what
      	    System.err.println(msg);
      	}
  	
      	return accepted;
      }
  }
  
  // -------------------- Threads --------------------
  // XXX add a more efficient model - use thread pools, use a Queue, etc
  
  // Keep the thread model in one place !
  
  // Listener thread
  class TcpListenerThread implements Runnable {
      SimpleTcpEndpoint endpoint;
      
      public TcpListenerThread( SimpleTcpEndpoint endpoint) {
      	this.endpoint=endpoint;
      }
      
      public void run() {
  	while (endpoint.running) {
  	    endpoint.acceptConnections();
      	}
  	//endpoint.manager.notifyEndpointDown(this);
      }
  }
  
  // Worker Thread
  // call handleConnection() in a new thread
  // XXX thread reuse!
  class TcpConnectionThread implements Runnable {
      TcpConnectionHandler handler;
      TcpConnection connection;
      
      public TcpConnectionThread( TcpConnectionHandler handler, TcpConnection connection) {
      	this.handler=handler;
  	this.connection=connection;
      }
      
      public void run() {
  	handler.processConnection(connection, null);
      }
  }
  
  
  
  1.15      +18 -12    jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpConnectionHandler.java
  
  Index: HttpConnectionHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpConnectionHandler.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- HttpConnectionHandler.java	2000/02/18 18:14:51	1.14
  +++ HttpConnectionHandler.java	2000/02/22 21:06:46	1.15
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpConnectionHandler.java,v 1.14 2000/02/18 18:14:51 costin Exp $
  - * $Revision: 1.14 $
  - * $Date: 2000/02/18 18:14:51 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpConnectionHandler.java,v 1.15 2000/02/22 21:06:46 costin Exp $
  + * $Revision: 1.15 $
  + * $Date: 2000/02/22 21:06:46 $
    *
    * ====================================================================
    *
  @@ -105,7 +105,9 @@
   
   	//	System.out.println("New Connection");
   	try {
  +	    //	    System.out.print("1");
   	    socket=connection.getSocket();
  +	    //	    System.out.print("2");
   	    InputStream in=socket.getInputStream();
   	    OutputStream out=socket.getOutputStream();
   
  @@ -119,9 +121,9 @@
   	    
   	    reqA.setSocket( socket );
   	    resA.setOutputStream( out );
  -
  +	    //	    System.out.print("7");
   	    reqA.readNextRequest(resA);
  -
  +	    //	    System.out.print("8");
   	    // XXX temporary fix for getServerName
   	    String hostHeader = reqA.getHeader("host");
   	    //  if it's not null, Request.getServerName() will take care
  @@ -140,7 +142,9 @@
   		reqA.setServerName(hostHeader);
                }
       
  +	    //	    System.out.print("3");
   	    contextM.service( reqA, resA );
  +	    //	    System.out.print("4");
   	    try {
                  InputStream is = socket.getInputStream();
                  int available = is.available ();
  @@ -152,13 +156,14 @@
                  if (available > 1) {
                      is.skip (available);
                  }
  -	   }catch(NullPointerException npe) {
  -	       // do nothing - we are just cleaning up, this is
  -	       // a workaround for Netscape \n\r in POST - it is supposed
  -	       // to be ignored
  -	   } catch(java.net.SocketException ex) {
  -	       // do nothing - same
  -	   }
  +	    }catch(NullPointerException npe) {
  +		// do nothing - we are just cleaning up, this is
  +		// a workaround for Netscape \n\r in POST - it is supposed
  +		// to be ignored
  +	    } catch(java.net.SocketException ex) {
  +		// do nothing - same
  +	    }
  +	    //	    System.out.print("5");
   	} catch (Exception e) {
   	    contextM.log( "Error reading request " + e.getMessage());
   	} finally {
  @@ -166,6 +171,7 @@
   	    try { socket.close (); }
   	    catch (IOException e) { /* ignore */ }
           }
  +	//	System.out.print("6");
       }
   
   
  
  
  
  1.4       +1 -1      jakarta-tomcat/src/share/org/apache/tomcat/task/ApacheConfig.java
  
  Index: ApacheConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/task/ApacheConfig.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ApacheConfig.java	2000/02/08 12:49:38	1.3
  +++ ApacheConfig.java	2000/02/22 21:06:46	1.4
  @@ -87,7 +87,7 @@
   	    String tomcatHome= cm.getHome();
   	    String apacheHome=findApache();
   	    
  -	    System.out.println("Tomcat home= " + tomcatHome);
  +	    //System.out.println("Tomcat home= " + tomcatHome);
   	    
   	    FileWriter configW=new FileWriter( tomcatHome + APACHE_CONFIG);
   	    PrintWriter pw=new PrintWriter( configW );
  
  
  
  1.2       +6 -6      jakarta-tomcat/src/share/org/apache/tomcat/util/ThreadPool.java
  
  Index: ThreadPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/ThreadPool.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ThreadPool.java	2000/02/17 10:36:48	1.1
  +++ ThreadPool.java	2000/02/22 21:06:47	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/ThreadPool.java,v 1.1 2000/02/17 10:36:48 shachor Exp $
  - * $Revision: 1.1 $
  - * $Date: 2000/02/17 10:36:48 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/ThreadPool.java,v 1.2 2000/02/22 21:06:47 costin Exp $
  + * $Revision: 1.2 $
  + * $Date: 2000/02/22 21:06:47 $
    *
    * ====================================================================
    *
  @@ -136,7 +136,7 @@
           if(0 == currentThreadCount) {
               throw new IllegalStateException();
           }
  -
  +	//	System.out.print("K");
           if(currentThreadsUsed == currentThreadCount) {
               if(currentThreadCount < maxThreads) {
                   int toOpen = currentThreadCount + minSpareThreads;
  @@ -154,7 +154,7 @@
                   }
               }
           }
  -
  +	//System.out.print("L");
   
           ControlRunnable c = (ControlRunnable)pool.lastElement();
           pool.removeElement(c);
  @@ -305,4 +305,4 @@
               shouldTerminate = true;
           }
       }
  -}
  \ No newline at end of file
  +}
  
  
  
  1.9       +4 -4      jakarta-tomcat/src/share/org/apache/tomcat/util/xml/XmlMapper.java
  
  Index: XmlMapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/xml/XmlMapper.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- XmlMapper.java	2000/02/18 18:14:52	1.8
  +++ XmlMapper.java	2000/02/22 21:06:47	1.9
  @@ -13,8 +13,6 @@
   import org.xml.sax.helpers.*;
   import org.w3c.dom.*;
   
  -import org.apache.tomcat.logging.Logger;
  -
   /** 
    * SAX Handler - it will read the XML and construct java objects
    *
  @@ -144,9 +142,11 @@
       public int getDebug() {
   	return debug;
       }
  -    
  +
       public void log(String msg) {
  -	Logger.log("STARTUP_LOG", msg);
  +	// log is for debug only, it should't be enabled for anything else
  +	// ( no dependency on Logger or any external tomcat package )
  +	System.out.println("XmlMapper: " + msg);
       }
   
       /** read an XML file, construct and return the object hierarchy
  
  
  

Mime
View raw message