You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@locus.apache.org on 2000/12/29 20:59:20 UTC
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/server Ajp12.java Ajp12Interceptor.java PoolTcpConnector.java
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() ) {