danmil      01/01/10 18:34:20

  Modified:    src/share/org/apache/tomcat/modules/server Ajp13.java
  Log:
     - Fixed the problems with multipart form encodings.  Bug Reports #536 +
       #542 and a bunch of others.  File upload is now working.
  
     - In doRead(), replaced byte-by-byte copy with System.arraycopy().
  
     - Clarified Ajp13 protocol: if the container tries to read
       past the end of the input stream, the server sends an empty packet back.
  
  Revision  Changes    Path
  1.8       +78 -28    
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.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Ajp13.java        2000/12/26 23:35:34     1.7
  +++ Ajp13.java        2001/01/11 02:34:20     1.8
  @@ -184,6 +184,9 @@
   
       public void recycle() 
       {
  +      // This is a touch cargo-cultish, but I think wise.
  +      blen = 0; 
  +      pos = 0;
       }
       
       /**
  @@ -257,7 +260,7 @@
           req.serverName().setString( msg.getString());
           req.setServerPort(          msg.getInt());
   
  -     isSSL = (msg.getByte() != 0);
  +     isSSL = msg.getBool();
   
        // Decode headers
        MimeHeaders headers = req.getMimeHeaders();
  @@ -358,6 +361,7 @@
            }
            
            blen = msg.peekInt();
  +         pos = 0;
            msg.getBytes(bodyBuff);
        }
       
  @@ -374,7 +378,9 @@
       public int doRead() throws IOException 
       {
           if(pos >= blen) {
  -            refillReadBuffer();
  +            if( ! refillReadBuffer()) {
  +             return -1;
  +         }
           }
           return bodyBuff[pos++];
       }
  @@ -386,30 +392,61 @@
        * @param off The offset in the buffer at which to start filling.
        * @param len The number of bytes to copy into the buffer.
        *
  -     * @return The number of bytes actually copied into the buffer.
  +     * @return The number of bytes actually copied into the buffer, or -1
  +     * if the end of the stream has been reached.
        *
        * @see Ajp13Request#doRead
        */
       public int doRead(byte[] b, int off, int len) throws IOException 
       {
  -        // XXX Rewrite to use System.arrayCopy (please!)
  -        for(int i = off ; i < (len + off) ; i++) {
  -            int a = doRead();
  -            if(-1 == a) {
  -                return i-off;
  -            }
  -            b[i] = (byte)a;
  -        }
  -        
  -        return len;
  +     if(pos >= blen) {
  +         if( ! refillReadBuffer()) {
  +             return -1;
  +         }
  +     }
  +
  +     if(pos + len <= blen) { // Fear the off by one error
  +         // Sanity check b.length > off + len?
  +         System.arraycopy(bodyBuff, pos, b, off, len);
  +         pos += len;
  +         return len;
  +     }
  +
  +     // Not enough data (blen < pos + len)
  +     int toCopy = len;
  +     while(toCopy > 0) {
  +         int bytesRemaining = blen - pos;
  +         if(bytesRemaining < 0) 
  +             bytesRemaining = 0;
  +         int c = bytesRemaining < toCopy ? bytesRemaining : toCopy;
  +
  +         System.arraycopy(bodyBuff, pos, b, off, c);
  +
  +         toCopy    -= c;
  +
  +         off       += c;
  +         pos       += c; // In case we exactly consume the buffer
  +
  +         if(toCopy > 0) 
  +             if( ! refillReadBuffer()) { // Resets blen and pos
  +                 break;
  +             }
  +     }
  +
  +     return len - toCopy;
       }
       
       /**
        * Get more request body data from the web server and store it in the 
        * internal buffer.
  +     *
  +     * @return true if there is more data, false if not.    
        */
  -    private void refillReadBuffer() throws IOException 
  +    private boolean refillReadBuffer() throws IOException 
       {
  +     // If the server returns an empty packet, assume that that end of
  +     // the stream has been reached (yuck -- fix protocol??).
  +
        // Why not use outBuf??
        inBuf.reset();
        inBuf.appendByte(JK_AJP13_GET_BODY_CHUNK);
  @@ -424,6 +461,8 @@
        blen = inBuf.peekInt();
        pos = 0;
        inBuf.getBytes(bodyBuff);
  +
  +     return (blen > 0);
       }    
   
       // ==================== Servlet Output Support =================
  @@ -442,18 +481,18 @@
           outBuf.appendInt(status);
           outBuf.appendString(""); // Http Status Message -- broken.
           
  -        outBuf.appendInt(headers.size());
  +     int numHeaders = headers.size();
  +        outBuf.appendInt(numHeaders);
           
  -        Enumeration e = headers.names();
  -        while(e.hasMoreElements()) {
  -            String headerName = (String)e.nextElement();            
  -            int sc = headerNameToSc(headerName);
  +     for( int i=0 ; i < numHeaders ; i++ ) {
  +         String headerName = headers.getName(i).toString();
  +         int sc = headerNameToSc(headerName);
               if(-1 != sc) {
                   outBuf.appendInt(sc);
               } else {
                   outBuf.appendString(headerName);
               }
  -            outBuf.appendString(headers.getHeader(headerName));
  +            outBuf.appendString(headers.getValue(i).toString());
           }
   
           outBuf.end();
  @@ -520,13 +559,13 @@
   
       /**
        * Signal the web server that the servlet has finished handling this
  -     * request.  
  +     * request, and that the connection can be reused.
        */
       public void finish() throws IOException 
       {
        outBuf.reset();
           outBuf.appendByte(JK_AJP13_END_RESPONSE);
  -        outBuf.appendByte((byte)1);        
  +        outBuf.appendBool(true); // Reuse this connection
           outBuf.end();
           send(outBuf);
       }
  @@ -590,7 +629,7 @@
            // XXX log
            // XXX Return an error code?
        }
  -     //      msg.dump( "Incoming");
  +     // msg.dump( "Incoming");
        return rd;
       }
   
  @@ -723,6 +762,10 @@
            buff[pos++] = val;
        }
        
  +     public void appendBool( boolean val) {
  +         buff[pos++] = (byte) (val ? 1 : 0);
  +     }
  +
        /**
         * Write a String out at the current write position.  Strings are
         * encoded with the length in two bytes first, then the string, and
  @@ -754,7 +797,7 @@
         * terminating \0 (which is <B>not</B> included in the encoded
         * length).
         *
  -      * @param b The array from whcih to copy bytes.
  +      * @param b The array from which to copy bytes.
         * @param off The offset into the array at which to start copying
         * @param len The number of bytes to copy.  
         */
  @@ -805,6 +848,10 @@
            return buff[pos];
        }
   
  +     public boolean getBool() {
  +         return (getByte() == (byte) 1);
  +     }
  +
        public static final String DEFAULT_CHAR_ENCODING = "8859_1";
   
        /**
  @@ -858,11 +905,14 @@
        }
   
        private void hexLine( int start ) {
  -         for( int i=start; i< start+16; i++ ) {
  +         for( int i=start; i< start+16 ; i++ ) {
  +           if( i < len + 4)
                System.out.print( hex( buff[i] ) + " ");
  +           else 
  +             System.out.print( "   " );
            }
            System.out.print(" | ");
  -         for( int i=start; i< start+16; i++ ) {
  +         for( int i=start; i < start+16 && i < len + 4; i++ ) {
                if( Character.isLetterOrDigit( (char)buff[i] ))
                    System.out.print( new Character((char)buff[i]) );
                else
  @@ -872,9 +922,9 @@
        }
       
        public void dump(String msg) {
  -         System.out.println( msg + ": " + buff + " " + pos +"/" + len);
  +         System.out.println( msg + ": " + buff + " " + pos +"/" + (len + 4));
   
  -         for( int j=0; j<len + 16; j+=16 )
  +         for( int j=0; j < len + 4; j+=16 )
                hexLine( j );
        
            System.out.println();
  
  
  

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

Reply via email to