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...@apache.org on 2002/02/06 18:48:22 UTC

cvs commit: jakarta-tomcat-connectors/jk/java/org/apache/jk/common HandlerRequest.java

costin      02/02/06 09:48:22

  Modified:    jk/java/org/apache/jk/common HandlerRequest.java
  Log:
  Few big changes here:
  
  - added support for 'secret' - as a normal request attributes. If
  the handler is configured to require a secret, it'll block any request
  without one. If not - older mod_jk's will work. ( I'll commit the change
  on the C code for both mod_jk and mod_jk2 )
  
  - added support for 'ajp13.id' - similar with what ajp12interceptor is
  doing in 3.3. This will save the connection info ( including secret )
  for easy reading by caller. ( not completed )
  
  - add useSecret option - it'll automatically generate a secret, no
  config needed ( and no need to ask the user to change the pass
  regularily - we'll do it on each server restart ). Mod_jk will just
  read the file.
  
  - added support for the shutdown message ( not completed )
  
  The request handler will call 'container' as the next handler,
  unless overriden. It'll also check if a dispathcer is
  present and register the messages it supports ( right now it's
  the only handler, so dispatcher is optional )
  
  Revision  Changes    Path
  1.4       +188 -64   jakarta-tomcat-connectors/jk/java/org/apache/jk/common/HandlerRequest.java
  
  Index: HandlerRequest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/java/org/apache/jk/common/HandlerRequest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- HandlerRequest.java	26 Jan 2002 14:14:35 -0000	1.3
  +++ HandlerRequest.java	6 Feb 2002 17:48:22 -0000	1.4
  @@ -60,8 +60,8 @@
   package org.apache.jk.common;
   
   import java.io.*;
  -import java.net.Socket;
  -import java.util.Enumeration;
  +import java.net.*;
  +import java.util.*;
   import java.security.*;
   import java.security.cert.*;
   
  @@ -91,13 +91,15 @@
    * @author Keith Wannamaker [Keith@Wannamaker.org]
    * @author Costin Manolache
    */
  -public class HandlerRequest extends Handler
  +public class HandlerRequest extends JkHandler
   {
       // XXX Will move to a registry system.
       
       // Prefix codes for message types from server to container
       public static final byte JK_AJP13_FORWARD_REQUEST   = 2;
   
  +    public static final byte JK_AJP13_SHUTDOWN   = 7;
  +
       // Prefix codes for message types from container to server
       public static final byte JK_AJP13_SEND_BODY_CHUNK   = 3;
       public static final byte JK_AJP13_SEND_HEADERS      = 4;
  @@ -128,6 +130,7 @@
       public static final byte SC_A_SSL_CIPHER    = 8;
       public static final byte SC_A_SSL_SESSION   = 9;
       public static final byte SC_A_SSL_KEYSIZE   = 11;
  +    public static final byte SC_A_SECRET        = 12;
   
       // Used for attributes which are not in the list above
       public static final byte SC_A_REQ_ATTRIBUTE = 10; 
  @@ -200,55 +203,179 @@
       {
       }
   
  +    HandlerDispatch dispatch;
  +
       public void init() {
  -	// register incoming message handlers
  -	we.registerMessageType( JK_AJP13_FORWARD_REQUEST,
  -                                "JK_AJP13_FORWARD_REQUEST",
  -                                this, null); // 2
  -
  -	// register outgoing messages handler
  -	we.registerMessageType( JK_AJP13_SEND_BODY_CHUNK, // 3
  -                                "JK_AJP13_SEND_BODY_CHUNK",
  -                                this,null );
  -	we.registerMessageType( JK_AJP13_SEND_HEADERS,  // 4
  -                                "JK_AJP13_SEND_HEADERS",
  -                                this,null );
  -	we.registerMessageType( JK_AJP13_END_RESPONSE, // 5
  -                                "JK_AJP13_END_RESPONSE",
  -                                this,null );
  -	we.registerMessageType( JK_AJP13_GET_BODY_CHUNK, // 6
  -                                "JK_AJP13_GET_BODY_CHUNK",
  -                                this, null );
  +        dispatch=(HandlerDispatch)wEnv.getHandler( "dispatch" );
  +        if( dispatch != null ) {
  +            // register incoming message handlers
  +            dispatch.registerMessageType( JK_AJP13_FORWARD_REQUEST,
  +                                          "JK_AJP13_FORWARD_REQUEST",
  +                                          this, null); // 2
  +            
  +            dispatch.registerMessageType( JK_AJP13_FORWARD_REQUEST,
  +                                          "JK_AJP13_SHUTDOWN",
  +                                          this, null); // 7
  +            
  +            // register outgoing messages handler
  +            dispatch.registerMessageType( JK_AJP13_SEND_BODY_CHUNK, // 3
  +                                          "JK_AJP13_SEND_BODY_CHUNK",
  +                                          this,null );
  +        }
  +
  +        bodyNote=wEnv.getNoteId( WorkerEnv.ENDPOINT_NOTE, "jkInputStream" );
  +        tmpBufNote=wEnv.getNoteId( WorkerEnv.ENDPOINT_NOTE, "tmpBuf" );
  +        secretNote=wEnv.getNoteId( WorkerEnv.ENDPOINT_NOTE, "secret" );
  +        
  +        if( next==null )
  +            next=wEnv.getHandler( "container" );
  +
  +        // should happen on start()
  +        generateAjp13Id();
  +    }
  +
  +    public void setSecret( String s ) {
  +        requiredSecret=s;
  +    }
  +
  +    public void setUseSecret( boolean b ) {
  +        requiredSecret=Double.toString(Math.random());
  +    }
  +
  +    public void setDecodedUri( boolean b ) {
  +	decoded=b;
  +    }
  +
  +    public boolean isTomcatAuthentication() {
  +        return tomcatAuthentication;
  +    }
  +
  +    public void setTomcatAuthentication(boolean newTomcatAuthentication) {
  +        tomcatAuthentication = newTomcatAuthentication;
  +    }
  +
  +    // -------------------- Ajp13.id --------------------
  +
  +    private void generateAjp13Id() {
  +        int portInt=8009; // tcpCon.getPort();
  +        InetAddress address=null; // tcpCon.getAddress();
  +
  +        File f1=new File( wEnv.getJkHome() );
  +        
  +        File sf=new File( f1, "conf/ajp13.id");
  +        
  +        if( dL > 0) d( "Using stop file: "+sf);
  +
  +        try {
  +            Properties props=new Properties();
  +
  +            props.put( "port", Integer.toString( portInt ));
  +            if( address!=null ) {
  +                props.put( "address", address.getHostAddress() );
  +            }
  +            if( requiredSecret !=null ) {
  +                props.put( "secret", requiredSecret );
  +            }
  +
  +            FileOutputStream stopF=new FileOutputStream( sf );
  +            props.save( stopF, "Automatically generated, don't edit" );
  +        } catch( IOException ex ) {
  +            d( "Can't create stop file: "+sf );
  +            ex.printStackTrace();
  +        }
       }
       
       // -------------------- Incoming message --------------------
  -    int reqNote=4;
  -    int postMsgNote=5;
  -    int tmpBufNote=6;
  +    String requiredSecret=null;
  +    int bodyNote;
  +    int tmpBufNote;
  +    int secretNote;
   
  -    public int callback(int type, Channel ch, Endpoint ep, Msg msg)
  +    boolean decoded=true;
  +    boolean tomcatAuthentication;
  +    
  +    public int invoke(Msg msg, MsgContext ep ) 
           throws IOException
       {
  +        int type=msg.getByte();
   
  -        // FORWARD_REQUEST handler
  -        BaseRequest req=(BaseRequest)ep.getNote( reqNote );
  -        if( req==null ) {
  -            req=new BaseRequest();
  -            ep.setNote( reqNote, req );
  +        MessageBytes tmpMB=(MessageBytes)ep.getNote( tmpBufNote );
  +        if( tmpMB==null ) {
  +            tmpMB=new MessageBytes();
  +            ep.setNote( tmpBufNote, tmpMB);
           }
   
  -        decodeRequest( msg, req, ch, ep );
  +        switch( type ) {
  +        case JK_AJP13_FORWARD_REQUEST:
  +            decodeRequest( msg, ep, tmpMB );
  +
  +            if( requiredSecret != null ) {
  +                String epSecret=(String)ep.getNote( secretNote );
  +                if( epSecret==null || ! requiredSecret.equals( epSecret ) )
  +                    return ERROR;
  +            }
  +            /* XXX it should be computed from request, by workerEnv */
  +            if(dL >0 )
  +                d("Calling next " + next.getName() + " " +
  +                  next.getClass().getName());
  +            
  +            return next.invoke( msg, ep );
  +            
  +        case JK_AJP13_SHUTDOWN:
  +            String epSecret=null;
  +            if( msg.getLen() > 3 ) {
  +                // we have a secret
  +                msg.getBytes( tmpMB );
  +                epSecret=tmpMB.toString();
  +            }
  +            
  +            if( requiredSecret != null &&
  +                requiredSecret.equals( epSecret ) ) {
  +                d("Received wrong secret, no shutdown ");
  +                return ERROR;
  +            }
  +
  +            // XXX add isSameAddress check
  +            Channel ch=ep.getChannel();
  +            if( ch instanceof ChannelSocket ) {
  +                if( ! ((ChannelSocket)ch).isSameAddress(ep) ) {
  +                    d("Shutdown request not from 'same address' ");
  +                    return ERROR;
  +                }
  +            }
  +
  +            // forward to the default handler - it'll do the shutdown
  +            next.invoke( msg, ep );
  +
  +            d("Exiting");
  +            System.exit(0);
  +            
  +	    return OK;
  +	}
   
  -        /* XXX it should be computed from request, by workerEnv */
  -        worker.service( req, ch, ep );
           return OK;
       }
   
  -    private int decodeRequest( Msg msg, BaseRequest req, Channel ch,
  -                               Endpoint ep )
  +    private int decodeRequest( Msg msg, MsgContext ep, MessageBytes tmpMB )
           throws IOException
       {
  +        // FORWARD_REQUEST handler
  +        BaseRequest req=(BaseRequest)ep.getRequest();
  +        if( req==null ) {
  +            req=new BaseRequest();
  +            ep.setRequest( req );
  +        }
  +
  +        JkInputStream jkBody=(JkInputStream)ep.getNote( bodyNote );
  +        if( jkBody==null ) {
  +            jkBody=new JkInputStream();
  +            jkBody.setMsgContext( ep );
   
  +            ep.setNote( bodyNote, jkBody );
  +        }
  +
  +        jkBody.recycle();
  +        
           // Translate the HTTP method code to a String.
           byte methodCode = msg.getByte();
           String mName=methodTransArray[(int)methodCode - 1];
  @@ -266,9 +393,9 @@
           boolean isSSL = msg.getByte() != 0;
           if( isSSL ) req.setSecure( true );
   
  -        decodeHeaders( ep, msg, req );
  +        decodeHeaders( ep, msg, req, tmpMB );
   
  -        decodeAttributes( ep, msg, req );
  +        decodeAttributes( ep, msg, req, tmpMB );
   
           if(req.getSecure() ) {
               req.setScheme(req.SCHEME_HTTPS);
  @@ -279,15 +406,10 @@
   
   	// Check to see if there should be a body packet coming along
   	// immediately after
  -    	if(req.getContentLength() > 0) {
  -            Msg postMsg=(Msg)ep.getNote( postMsgNote );
  -            if( postMsg==null ) {
  -                postMsg=new MsgAjp();
  -                ep.setNote( postMsgNote, postMsg );
  -            }
  -        
  -	    /* Read present data */
  -	    int err = ch.receive(postMsg, ep);
  +        int cl=req.getContentLength();
  +    	if(cl > 0) {
  +            jkBody.setContentLength( cl );
  +            jkBody.receive();
       	}
       
           if (dL > 5) {
  @@ -297,14 +419,10 @@
           return OK;
       }
           
  -    private int decodeAttributes( Endpoint ep, Msg msg, BaseRequest req ) {
  +    private int decodeAttributes( MsgContext ep, Msg msg, BaseRequest req,
  +                                  MessageBytes tmpMB) {
           boolean moreAttr=true;
   
  -        MessageBytes tmpMB=(MessageBytes)ep.getNote( tmpBufNote );
  -        if( tmpMB==null ) {
  -            tmpMB=new MessageBytes();
  -            ep.setNote( tmpBufNote, tmpMB);
  -        }
           while( moreAttr ) {
               byte attributeCode=msg.getByte();
               if( attributeCode == SC_A_ARE_DONE )
  @@ -341,7 +459,12 @@
                   break;
   		
   	    case SC_A_REMOTE_USER  :
  -                msg.getBytes(req.remoteUser());
  +                if( tomcatAuthentication ) {
  +                    // ignore server
  +                    msg.getBytes( tmpMB );
  +                } else {
  +                    msg.getBytes(req.remoteUser());
  +                }
                   break;
   		
   	    case SC_A_AUTH_TYPE    :
  @@ -395,25 +518,26 @@
   		req.setAttribute("javax.servlet.request.ssl_session",
   				  tmpMB.toString());
                   break;
  -		
  +                
  +	    case SC_A_SECRET  :
  +                msg.getBytes(tmpMB);
  +                String secret=tmpMB.toString();
  +                d("Secret: " + secret );
  +                // endpoint note
  +                ep.setNote( secretNote, secret );
  +                break;
   	    default:
  -		return 500; // Error
  +		break; // ignore, we don't know about it - backward compat
   	    }
           }
           return 200;
       }
       
  -    private void decodeHeaders( Endpoint ep, Msg msg, BaseRequest req ) {
  +    private void decodeHeaders( MsgContext ep, Msg msg, BaseRequest req,
  +                                MessageBytes tmpMB ) {
           // Decode headers
           MimeHeaders headers = req.headers();
   
  -        MessageBytes tmpMB=(MessageBytes)ep.getNote( tmpBufNote );
  -        if( tmpMB==null ) {
  -            tmpMB=new MessageBytes();
  -            ep.setNote( tmpBufNote, tmpMB);
  -        }
  -
  -        
   	int hCount = msg.getInt();
           for(int i = 0 ; i < hCount ; i++) {
               String hName = null;
  @@ -458,7 +582,7 @@
           }
       }
   
  -    private static final int dL=0;
  +    private static final int dL=4;
       private static void d(String s ) {
           System.err.println( "HandlerRequest: " + s );
       }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>