You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2001/01/22 05:55:40 UTC

cvs commit: jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/connector/http HttpRequestStream.java

remm        01/01/21 20:55:40

  Modified:    catalina/src/share/org/apache/catalina/connector/http
                        HttpRequestStream.java
  Log:
  - Fix for yet another input chunking issue. This time, it's when uploading
    large resources when using chunking.
    Note : The fix should also vastly improve performance.
    Bug reported by Michael Smith <ms...@xn.com.au> (originally reported
    as a Slide HTTP client bug).
  
  Revision  Changes    Path
  1.7       +109 -52   jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/connector/http/HttpRequestStream.java
  
  Index: HttpRequestStream.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/connector/http/HttpRequestStream.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- HttpRequestStream.java	2000/12/14 07:49:16	1.6
  +++ HttpRequestStream.java	2001/01/22 04:55:40	1.7
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/connector/http/HttpRequestStream.java,v 1.6 2000/12/14 07:49:16 remm Exp $
  - * $Revision: 1.6 $
  - * $Date: 2000/12/14 07:49:16 $
  + * $Header: /home/cvs/jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/connector/http/HttpRequestStream.java,v 1.7 2001/01/22 04:55:40 remm Exp $
  + * $Revision: 1.7 $
  + * $Date: 2001/01/22 04:55:40 $
    *
    * ====================================================================
    * 
  @@ -202,56 +202,8 @@
               
               if ((chunkBuffer == null)
                   || (chunkPos >= chunkLength)) {
  -                
  -                chunkPos = 0;
  -                
  -                try {
  -                    chunkLength = 
  -                        Integer.parseInt(readLineFromStream().trim(), 16);
  -                } catch (NumberFormatException e) {
  -                    // Critical error, unable to parse the chunk length
  -                    chunkLength = 0;
  -                    chunk = false;
  -                    close();
  -                    return -1;
  -                }
  -                
  -                if (chunkLength == 0) {
  -                    
  -                    // Skipping trailing headers, if any
  -                    String trailingLine = readLineFromStream();
  -                    while (!trailingLine.equals(""))
  -                        trailingLine = readLineFromStream();
  -                    endChunk = true;
  +                if (!fillChunkBuffer())
                       return (-1);
  -                    // TODO : Should the stream be automatically closed ?
  -                    
  -                } else {
  -                    
  -                    if ((chunkBuffer == null)
  -                        || (chunkLength > chunkBuffer.length))
  -                        chunkBuffer = new byte[chunkLength];
  -                    
  -                    // Now read the whole chunk into the buffer
  -                    
  -                    int nbRead = 0;
  -                    int currentRead = 0;
  -                    
  -                    while (nbRead < chunkLength) {
  -                        currentRead = 
  -                            stream.read(chunkBuffer, nbRead, 
  -                                       chunkLength - nbRead);
  -                        if (currentRead == -1)
  -                            throw new IOException
  -                                (sm.getString("requestStream.read.error"));
  -                        nbRead += currentRead;
  -                    }
  -                    
  -                    // Skipping the CRLF
  -                    readLineFromStream();
  -                    
  -                }
  -                
               }
               
               return (chunkBuffer[chunkPos++]);
  @@ -265,7 +217,112 @@
       }
   
   
  +    /**
  +     * Read up to <code>len</code> bytes of data from the input stream
  +     * into an array of bytes.  An attempt is made to read as many as
  +     * <code>len</code> bytes, but a smaller number may be read,
  +     * possibly zero.  The number of bytes actually read is returned as
  +     * an integer.  This method blocks until input data is available,
  +     * end of file is detected, or an exception is thrown.
  +     *
  +     * @param b The buffer into which the data is read
  +     * @param off The start offset into array <code>b</code> at which
  +     *  the data is written
  +     * @param len The maximum number of bytes to read
  +     *
  +     * @exception IOException if an input/output error occurs
  +     */
  +    public int read(byte b[], int off, int len) throws IOException {
  +        if (chunk) {
  +            
  +            int avail = chunkLength - chunkPos;
  +            if (avail == 0)
  +                fillChunkBuffer();
  +            avail = chunkLength - chunkPos;
  +            if (avail == 0)
  +                return (-1);
  +            
  +            int toCopy = avail;
  +            if (avail > len)
  +                toCopy = len;
  +            System.arraycopy(chunkBuffer, chunkPos, b, off, toCopy);
  +            chunkPos += toCopy;
  +            return toCopy;
  +            
  +        } else {
  +            return super.read(b, off, len);
  +        }
  +    }
  +    
  +    
       // -------------------------------------------------------- Private Methods
  +    
  +    
  +    /**
  +     * Fill the chunk buffer.
  +     */
  +    private synchronized boolean fillChunkBuffer() 
  +        throws IOException {
  +        
  +        chunkPos = 0;
  +        
  +        try {
  +            String numberValue = readLineFromStream().trim();
  +            chunkLength = 
  +                Integer.parseInt(numberValue, 16);
  +        } catch (NumberFormatException e) {
  +            // Critical error, unable to parse the chunk length
  +            chunkLength = 0;
  +            chunk = false;
  +            close();
  +            return false;
  +        }
  +        
  +        if (chunkLength == 0) {
  +                    
  +            // Skipping trailing headers, if any
  +            String trailingLine = readLineFromStream();
  +            while (!trailingLine.equals(""))
  +                trailingLine = readLineFromStream();
  +            endChunk = true;
  +            return false;
  +            // TODO : Should the stream be automatically closed ?
  +            
  +        } else {
  +            
  +            if ((chunkBuffer == null)
  +                || (chunkLength > chunkBuffer.length))
  +                chunkBuffer = new byte[chunkLength];
  +            
  +            // Now read the whole chunk into the buffer
  +            
  +            int nbRead = 0;
  +            int currentRead = 0;
  +            
  +            while (nbRead < chunkLength) {
  +                try {
  +                    currentRead = 
  +                        stream.read(chunkBuffer, nbRead, 
  +                                    chunkLength - nbRead);
  +                } catch (Throwable t) {
  +                    t.printStackTrace();
  +                    throw new IOException();
  +                }
  +                if (currentRead < 0) {
  +                    throw new IOException
  +                        (sm.getString("requestStream.read.error"));
  +                }
  +                nbRead += currentRead;
  +            }
  +            
  +            // Skipping the CRLF
  +            String blank = readLineFromStream();
  +            
  +        }
  +        
  +        return true;
  +        
  +    }
       
   
       /**