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/modules/server Ajp12.java Ajp12Interceptor.java PoolTcpConnector.java
Date Fri, 29 Dec 2000 19:59:20 GMT
costin      00/12/29 11:59:20

  Modified:    src/share/org/apache/tomcat/startup StopTomcat.java
               src/share/org/apache/tomcat/modules/server Ajp12.java
                        Ajp12Interceptor.java PoolTcpConnector.java
  Log:
  Small change in the stop protocol: added a "secret" ( used only for stopping,
  all other Ajp12 requests are equivalent with HTTP requests, and need no
  secret ). The secret is optional ( for backward compatibility - "useSecret"
  attribute will enable its use ).
  
  There are 2 choices for secret - the user can set it ( secret="xxxx" ), or
  ( much better ) let the server generate it ( using the simple Math.random() -
  IMHO still better than "changeit" ). The server will save the random secret
  in a "stop.id" file, in conf ( XXX should it be work/private ? ). Since read
  access to that directory would allow reading of server.xml too - the method
  is equivalent.
  
  The main advantage is that the user doesn't have to configure anything.
  
  Another small usability improvement - now it's possible to do
  "java -jar stop-tomcat.jar " ( or double-click the jar - no scripts
  needed on JDK1.2 machines, the scripts only needed for 1.1 )
  
  Revision  Changes    Path
  1.2       +117 -69   jakarta-tomcat/src/share/org/apache/tomcat/startup/StopTomcat.java
  
  Index: StopTomcat.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/startup/StopTomcat.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- StopTomcat.java	2000/12/29 00:20:22	1.1
  +++ StopTomcat.java	2000/12/29 19:59:19	1.2
  @@ -58,20 +58,14 @@
    */
   package org.apache.tomcat.startup;
   
  -import org.apache.tomcat.core.*;
  -import org.apache.tomcat.util.*;
  -import org.apache.tomcat.helper.*;
  -import org.apache.tomcat.util.xml.*;
  -import org.apache.tomcat.util.log.*;
  +import org.apache.tomcat.util.StringManager;
   import java.io.*;
   import java.net.*;
   import java.util.*;
   
  -// Used to stop tomcat
  -//import org.apache.tomcat.service.PoolTcpConnector;
  -//import org.apache.tomcat.service.connector.Ajp12ConnectionHandler;
  -import org.apache.tomcat.modules.server.Ajp12Interceptor;
  +// Depends: StringManager, resources
   
  +
   /**
    * This task will stop tomcat
    *
  @@ -84,7 +78,6 @@
   
       String configFile;
       String tomcatHome;
  -    Log loghelper = new Log("tc_log", "StopTomcat");
       
       public StopTomcat() 
       {
  @@ -113,15 +106,15 @@
       }
   
       // -------------------- Ant execute --------------------
  +
       public void execute() throws Exception {
   	System.out.println(sm.getString("tomcat.stop"));
   	try {
   	    stopTomcat(); // stop serving
   	}
  -	catch (TomcatException te) {
  -	    if (te.getRootCause() instanceof java.net.ConnectException)
  -		System.out.println(sm.getString("tomcat.connectexception"));
  -	    else
  +	catch (java.net.ConnectException ex) {
  +	    System.out.println(sm.getString("tomcat.connectexception"));
  +	} catch (Exception te ) {
   		throw te;
   	}
   	return;
  @@ -129,75 +122,130 @@
   
       // -------------------- Implementation --------------------
       
  -    /** Stop tomcat using the configured cm
  -     *  The manager is set up using the same configuration file, so
  -     *  it will have the same port as the original instance ( no need
  -     *  for a "log" file).
  -     *  It uses the Ajp12 connector, which has a built-in "stop" method,
  -     *  that will change when we add real callbacks ( it's equivalent
  -     *  with the previous RMI method from almost all points of view )
  -     */
  -    void stopTomcat() throws TomcatException {
  -	XmlMapper xh=new XmlMapper();
  -	xh.setDebug( 0 );
  -	ContextManager cm=new ContextManager();
  +    void stopTomcat() throws Exception {
  +	String tchome=getTomcatInstall();
  +	int port=8007;
  +	InetAddress address=null;
   	
  -	ServerXmlHelper sxml=new ServerXmlHelper();
  -
  -	sxml.setConnectorHelper( xh );
  -	String tchome=sxml.getTomcatInstall();
  -	// load server.xml
  -	File f = null;
  -	if (configFile != null)
  -	    f=new File(configFile);
  -	else
  -	    f=new File(tchome, DEFAULT_CONFIG);
  -	cm.setInstallDir( tchome);
  -
   	try {
  -	    xh.readXml(f,cm);
  -	} catch( Exception ex ) {
  -	    throw new TomcatException("Fatal exception reading " + f, ex);
  +	    BufferedReader rd=new BufferedReader
  +		( new FileReader( tchome + "/conf/ajp12.id"));
  +	    String portLine=rd.readLine();
  +	    
  +	    try {
  +		port=Integer.parseInt( portLine );
  +	    } catch(NumberFormatException ex ) {
  +		ex.printStackTrace();
  +	    }
  +	    String addLine=rd.readLine();
  +	    if( addLine!=null && !"".equals( addLine )) {
  +		try {
  +		    address=InetAddress.getByName( addLine );
  +		} catch( UnknownHostException ex ) {
  +		    ex.printStackTrace();
  +		}
  +	    }
  +	    String secret=rd.readLine();
  +	    if( "".equals( secret ) )
  +		secret=null;
  +
  +	    System.out.println("Stoping tomcat on " + address + ":" +port +" "
  +			       + secret);
  +	    stopTomcat( address,port, secret );
  +	    
  +	} catch( IOException ex ) {
  +	    ex.printStackTrace();
   	}
  -	
  -	execute( cm );     
  +
       }
       
  +    public String getTomcatInstall() {
  +	// Use the "tomcat.home" property to resolve the default filename
  +	String tchome = System.getProperty("tomcat.home");
  +	if (tchome == null) {
  +	    System.out.println(sm.getString("tomcat.nohome"));
  +	    tchome = ".";
  +	    // Assume current working directory
  +	}
  +	return tchome;
  +    }
       
  -    /** This particular implementation will search for an AJP12
  -	connector ( that have a special stop command ).
  -    */
  -    public void execute(ContextManager cm)
  -	throws TomcatException 
  +    /**
  +     *  This particular implementation will search for an AJP12
  +     * 	connector ( that have a special stop command ).
  +     */
  +    public void stopTomcat(InetAddress address, int portInt, String secret )
  +	throws IOException 
       {
  -	// Find Ajp12 connector
  -	int portInt=8007;
  -	InetAddress address=null;
  -	BaseInterceptor ci[]=cm.getContainer().getInterceptors();
  -	for( int i=0; i<ci.length; i++ ) {
  -	    Object con=ci[i];
  -	    if( con instanceof  Ajp12Interceptor ) {
  -		Ajp12Interceptor tcpCon=(Ajp12Interceptor) con;
  -		portInt=tcpCon.getPort();
  -		address=tcpCon.getAddress();
  -	    }
  -	}
  -
   	// use Ajp12 to stop the server...
   	try {
   	    if (address == null)
   		address = InetAddress.getLocalHost();
   	    Socket socket = new Socket(address, portInt);
   	    OutputStream os=socket.getOutputStream();
  -	    byte stopMessage[]=new byte[2];
  -	    stopMessage[0]=(byte)254;
  -	    stopMessage[1]=(byte)15;
  -	    os.write( stopMessage );
  -	    socket.close();
  -	} catch(Exception ex ) {
  -	    throw new TomcatException("Error stopping Tomcat with Ajp12 on " +
  -				      address + ":" + portInt, ex);
  +	    sendAjp12Stop( os, secret );
  +	    os.flush();
  +	    os.close();
  +	    //	    socket.close();
  +	} catch(IOException ex ) {
  +	    System.out.println("Error stopping Tomcat with Ajp12 on " +
  +				      address + ":" + portInt + " " + ex);
  +	    throw ex;
   	}
       }
  +
  +    /** Small AJP12 client util
  +     */
  +    public void sendAjp12Stop( OutputStream os, String secret )
  +	throws IOException
  +    {
  +	byte stopMessage[]=new byte[2];
  +	stopMessage[0]=(byte)254;
  +	stopMessage[1]=(byte)15;
  +	os.write( stopMessage );
  +	if(secret!=null ) 
  +	    sendAjp12String( os, secret );
  +    }
  +
  +    /** Small AJP12 client util
  +     */
  +    public void sendAjp12String( OutputStream os, String s )
  +	throws IOException
  +    {
  +	int len=s.length();
  +	os.write( len/256 );
  +	os.write( len%256 );
  +	os.write( s.getBytes() );// works only for ascii
  +    }
       
  +    /** Process arguments - set object properties from the list of args.
  +     */
  +    public  boolean processArgs(String[] args) {
  +	for (int i = 0; i < args.length; i++) {
  +	    String arg = args[i];
  +            
  +	    if (arg.equals("-h") || arg.equals("-home")) {
  +		i++;
  +		if (i < args.length)
  +		    System.getProperties().put("tomcat.home", args[i]);
  +		else
  +		    return false;
  +	    }
  +	}
  +	return true;
  +    }
  +
  +    public static void main(String args[] ) {
  +	try {
  +	    StopTomcat tomcat=new StopTomcat();
  +	    tomcat.processArgs( args );
  +	    tomcat.execute();
  +	} catch(Exception ex ) {
  +	    System.out.println(sm.getString("tomcat.fatal"));
  +	    ex.printStackTrace();
  +	    System.exit(1);
  +	}
  +    }
  +
  +
   }
  
  
  
  1.11      +13 -3     jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp12.java
  
  Index: Ajp12.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp12.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- Ajp12.java	2000/12/26 23:35:34	1.10
  +++ Ajp12.java	2000/12/29 19:59:19	1.11
  @@ -79,6 +79,7 @@
       boolean shutdown=false;
       boolean isPing=false;
       boolean doLog;
  +    String secret=null;
   
       public Ajp12() {
       }
  @@ -102,6 +103,10 @@
   	sin = s.getInputStream();
   	ajpin = new BufferedInputStream(sin);
       }
  +
  +    public void setSecret( String s ) {
  +	secret=s;
  +    }
       
       public void readNextRequest(Request req) throws IOException {
   	String dummy,token1,token2;
  @@ -241,11 +246,15 @@
   			    // not corrupted
   			    InetAddress serverAddr = socket.getLocalAddress();
   			    InetAddress clientAddr = socket.getInetAddress();
  -			    sin.close();
   			    if ( (signal== 15) &&
   				 isSameAddress(serverAddr, clientAddr) ) {
  -				// Shutdown - probably apache was stoped with
  -				// apachectl stop
  +				if( secret!=null ) {
  +				    String stopMsg=readString(ajpin, "");
  +				    if( ! secret.equals( stopMsg ) ) {
  +					req.getContextManager().log("Attempt to stop with the wrong secret");
  +					return;
  +				    }
  +				}
   				req.getContextManager().stop();
   				// same behavior as in past, because it seems
   				// that stopping everything doesn't work -
  @@ -256,6 +265,7 @@
   				shutdown=true;
   				return;
   			    }
  +			    sin.close();
   			} catch (Exception ignored) {
   			    req.getContextManager().log("Ignored exception " +
   						      "processing signal " +
  
  
  
  1.9       +40 -21    jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp12Interceptor.java
  
  Index: Ajp12Interceptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp12Interceptor.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Ajp12Interceptor.java	2000/12/29 01:34:42	1.8
  +++ Ajp12Interceptor.java	2000/12/29 19:59:19	1.9
  @@ -77,6 +77,8 @@
   public class Ajp12Interceptor extends PoolTcpConnector
       implements  TcpConnectionHandler{
       private boolean tomcatAuthentication=true;
  +    String secret;
  +    
       public Ajp12Interceptor() {
   	super();
       }
  @@ -86,30 +88,41 @@
   	ep.setConnectionHandler( this );
       }
   
  +    /** Enable the use of a stop secret. The secret will be
  +     *  randomly generated.
  +     */
  +    public void setUseSecret(boolean b ) {
  +	secret=Double.toString(Math.random());
  +    }
  +
  +    /** Explicitely set the stop secret
  +     */
  +    public void setSecret( String s ) {
  +	secret=s;
  +    }
  +    
       public void engineInit(ContextManager cm )
   	throws TomcatException
       {
  -	super.engineInit( cm );
  -	BaseInterceptor ci[]=cm.getContainer().getInterceptors();
  -	for( int i=0; i<ci.length; i++ ) {
  -	    Object con=ci[i];
  -	    if( con instanceof  Ajp12Interceptor ) {
  -		Ajp12Interceptor tcpCon=(Ajp12Interceptor) con;
  -		int portInt=tcpCon.getPort();
  -		InetAddress address=tcpCon.getAddress();
  -		try {
  -		    PrintWriter stopF=new PrintWriter
  -			(new FileWriter(cm.getHome() + "/conf/ajp12.id"));
  -		    stopF.println( portInt );
  -		    if( address==null )
  -			stopF.println( "" );
  -		    else
  -			stopF.println( address.toString() );
  -		    stopF.close();
  -		} catch( IOException ex ) {
  -		    log( "Can't create ajp12.id " + ex );
  -		}
  -	    }
  +	super.engineInit(cm);
  +	Ajp12Interceptor tcpCon=this;
  +	int portInt=tcpCon.getPort();
  +	InetAddress address=tcpCon.getAddress();
  +	try {
  +	    PrintWriter stopF=new PrintWriter
  +		(new FileWriter(cm.getHome() + "/conf/ajp12.id"));
  +	    stopF.println( portInt );
  +	    if( address==null )
  +		stopF.println( "" );
  +	    else
  +		stopF.println( address.toString() );
  +	    if( secret !=null )
  +		stopF.println( secret );
  +	    else
  +		stopF.println();
  +	    stopF.close();
  +	} catch( IOException ex ) {
  +	    log( "Can't create ajp12.id " + ex );
   	}
       }
   
  @@ -118,6 +131,7 @@
       public Object[] init() {
   	Object thData[]=new Object[2];
   	AJP12Request reqA=new AJP12Request();
  +	reqA.setSecret( secret );
   	AJP12Response resA=new AJP12Response();
   	cm.initRequest( reqA, resA );
   	thData[0]=reqA;
  @@ -159,6 +173,7 @@
   
   	    if( reqA==null || resA==null ) {
   		reqA = new AJP12Request();
  +		reqA.setSecret( secret );
                   ((AJP12Request)reqA).setTomcatAuthentication(
                                           isTomcatAuthentication());
   		resA=new AJP12Response();
  @@ -195,6 +210,10 @@
       public AJP12Request() {
       }
   
  +    void setSecret( String s ) {
  +	ajp12.setSecret( s );
  +    }
  +    
       public boolean internalAjp() {
   	return ajp12.isPing ||
   	    ajp12.shutdown;
  
  
  
  1.3       +9 -0      jakarta-tomcat/src/share/org/apache/tomcat/modules/server/PoolTcpConnector.java
  
  Index: PoolTcpConnector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/server/PoolTcpConnector.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PoolTcpConnector.java	2000/09/29 21:09:47	1.2
  +++ PoolTcpConnector.java	2000/12/29 19:59:19	1.3
  @@ -106,6 +106,15 @@
   
   	try {
   	    localInit();
  +	} catch( Exception ex ) {
  +	    throw new TomcatException( ex );
  +	}
  +    }
  +
  +    /** Called when the ContextManger is started
  +     */
  +    public void engineStart(ContextManager cm) throws TomcatException {
  +	try {
   	    if( socketFactory!=null ) {
   		Enumeration attE=attributes.keys();
   		while( attE.hasMoreElements() ) {
  
  
  

Mime
View raw message