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() ) {
  
  
  

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

Reply via email to