tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hgo...@apache.org
Subject cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/server Ajp13.java
Date Fri, 14 Sep 2001 16:01:21 GMT
hgomez      01/09/14 09:01:21

  Modified:    src/share/org/apache/tomcat/modules/server Ajp13.java
  Log:
  Solid reworks to better handle comm part.
  We don't try to handle partial packet, use
  of readN to ensure having all data in packets
  (even in header which is 4 bytes long)
  
  Revision  Changes    Path
  1.26      +88 -20    jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp13.java
  
  Index: Ajp13.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp13.java,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- Ajp13.java	2001/09/12 21:35:46	1.25
  +++ Ajp13.java	2001/09/14 16:01:21	1.26
  @@ -107,6 +107,14 @@
       public static final byte JK_AJP13_FORWARD_REQUEST   = 2;
       public static final byte JK_AJP13_SHUTDOWN          = 7;
   	
  +    // Error code for Ajp13
  +    public static final int  JK_AJP13_BAD_HEADER        = -100;
  +    public static final int  JK_AJP13_NO_HEADER         = -101;
  +    public static final int  JK_AJP13_COMM_CLOSED       = -102;
  +    public static final int  JK_AJP13_COMM_BROKEN       = -103;
  +    public static final int  JK_AJP13_BAD_BODY          = -104;
  +    public static final int  JK_AJP13_INCOMPLETE_BODY   = -105;
  +
       // 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;
  @@ -186,13 +194,14 @@
   
       OutputStream out;
       InputStream in;
  +    int dL=0;
   
       // Buffer used of output body and headers
       OutputBuffer headersWriter=new OutputBuffer(MAX_PACKET_SIZE);
       Ajp13Packet outBuf = new Ajp13Packet( headersWriter );
       // Buffer used for input body
       Ajp13Packet inBuf  = new Ajp13Packet( MAX_PACKET_SIZE );
  -    // Boffer used for request head ( and headers )
  +    // Buffer used for request head ( and headers )
       Ajp13Packet hBuf=new Ajp13Packet( MAX_PACKET_SIZE );
   
       // Holds incoming reads of request body data (*not* header data)
  @@ -254,9 +263,10 @@
   	// XXX The return values are awful.
   
   	int err = receive(hBuf);
  -	if(err < 0) {
  +
  +    // if any error, just drop the ajp13 connection
  +	if (err < 0) 
   	    return 500;
  -	}
   	
   	int type = (int)hBuf.getByte();
   	switch(type) {
  @@ -674,6 +684,47 @@
       // ========= Internal Packet-Handling Methods =================
   
       /**
  +     * Read N bytes from the InputStream, and ensure we got them all
  +     * Under heavy load we could experience many fragmented packets
  +     * just read Unix Network Programming to recall that a call to
  +     * read didn't ensure you got all the data you want
  +     *
  +     * from read() Linux manual
  +     *
  +     * On success, the number of bytes read is returned (zero indicates end of file), 
  +     * and the file position is advanced by this number.
  +     * It is not an error if this number is smaller than the number of bytes requested;

  +     * this may happen for example because fewer bytes
  +     * are actually available right now (maybe because we were close to end-of-file, 
  +     * or because we are reading from a pipe, or  from  a
  +     * terminal),  or  because  read()  was interrupted by a signal.  
  +     * On error, -1 is returned, and errno is set appropriately. In this
  +     * case it is left unspecified whether the file position (if any) changes.
  +     *
  +     **/
  +    private int readN(InputStream in, byte[] b, int offset, int len) throws IOException
{
  +        int pos = 0;
  +        int got;
  +
  +        while(pos < len) {
  +            got = in.read(b, pos + offset, len - pos);
  +
  +            if (dL > 10) d("read got # " + got);
  +
  +            // connection just closed by remote
  +            if (got == 0)
  +                return JK_AJP13_COMM_CLOSED;
  +
  +            // connection dropped by remote
  +            if (got < 0)
  +                return JK_AJP13_COMM_BROKEN;
  +
  +            pos += got;
  +        }
  +        return pos;
  +     }
  +       
  +    /**
        * Read in a packet from the web server and store it in the passed-in
        * <CODE>Ajp13Packet</CODE> object.
        *
  @@ -690,26 +741,40 @@
   	// returned -- should probably return true/false instead.
   	byte b[] = msg.getBuff();
   	
  -	int rd = in.read( b, 0, H_SIZE );
  -	if(rd <= 0) {
  -	    return rd;
  -	}
  -	
  +	int rd = readN(in, b, 0, H_SIZE );
  +
  +    // XXX - connection closed (JK_AJP13_COMM_CLOSED)
  +    //     - connection broken (JK_AJP13_COMM_BROKEN)
  +    //
  +    if(rd < 0) {
  +        // if (rd != JK_AJP13_COMM_CLOSED)
  +        //    d("can't read header: " + rd);
  +         return rd;
  +    }
  +        
   	int len = msg.checkIn();
  -	
  +
  +    // XXX - check if we received a non AJP13 packet
  +    if (len < 0) {
  +        return JK_AJP13_BAD_HEADER;
  +    }
  +
   	// XXX check if enough space - it's assert()-ed !!!
   
    	int total_read = 0;
  -  	while (total_read < len) {
  -	    rd = in.read( b, 4 + total_read, len - total_read);
  -            if (rd == -1) {
  - 		System.out.println( "Incomplete read, deal with it " + len + " " + rd);
  -                break;
  -		// XXX log
  -		// XXX Return an error code?
  -	    }
  -     	    total_read += rd;
  -	}
  + 
  +    total_read = readN(in, b, H_SIZE, len);
  +
  +    if (total_read < 0) {
  +        d("can't read body, waited #" + len);
  +        return JK_AJP13_BAD_BODY;
  +    }
  +
  +    if (total_read != len) {
  +        d( "incomplete read, waited #" + len + " got only " + total_read);
  +        return JK_AJP13_INCOMPLETE_BODY; 
  +    }
  +
   	if( dL>0 ) msg.dump("Ajp13.receive() " + rd + " " + len );
   	return total_read;
       }
  @@ -743,8 +808,11 @@
   	    in.close();
   	}
       }
  +
  +    public void setDebug(int i) {
  +        dL = i;
  +    }
   
  -    private static final int dL=0;
       private void d(String s ) {
   	System.err.println( "Ajp13: " + s );
       }
  
  
  

Mime
View raw message