You are viewing a plain text version of this content. The canonical link for it is here.
Posted to adffaces-commits@incubator.apache.org by aw...@apache.org on 2006/08/11 16:13:42 UTC

svn commit: r430814 - /incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/share/util/MultipartFormHandler.java

Author: awiner
Date: Fri Aug 11 09:13:41 2006
New Revision: 430814

URL: http://svn.apache.org/viewvc?rev=430814&view=rev
Log:
Check in patch for ADFFACES-120:  Bugs in MultiPartFormHandler

Modified:
    incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/share/util/MultipartFormHandler.java

Modified: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/share/util/MultipartFormHandler.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/share/util/MultipartFormHandler.java?rev=430814&r1=430813&r2=430814&view=diff
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/share/util/MultipartFormHandler.java (original)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/share/util/MultipartFormHandler.java Fri Aug 11 09:13:41 2006
@@ -238,7 +238,7 @@
     throws IOException
   {
     byte[] data  = _lineBuffer;
-    int    bytes = _readLine(_in, data, 0, data.length);
+    int    bytes = _readLine(data, 0, data.length);
 
     String line = null;
     if (bytes < 0)
@@ -250,14 +250,12 @@
     {
       line = _dataToString(data, 0, bytes, decodeEncoding, stripNewLines);
     }
-
     return line;
   }
 
   // This is a replacement for ServletInputStream.readLine().  We use
   // this utility method instead as we don't always have a ServletInputStream.
   private int _readLine(
-    InputStream in,
     byte[]      buffer,
     int         offset,
     int         length
@@ -274,7 +272,7 @@
     // enough to fill the incoming buffer or finish up a line.
     // However, if the input stream is itself buffered, this would
     // be of doubtful value.
-    while ((c = in.read()) != -1)
+    while ((c = _in.read()) != -1)
     {
       buffer[offset++] = (byte)c;
       count++;
@@ -284,16 +282,17 @@
         break;
 
       // Out of space; we're done too.
-      if (count == length)
+      // Read one character less so that we can account for CR
+      if (count == length-1)
       {
         // If we've found a CR, then we're not quite done;  we'd
-        // better read over the next character (which must be a LF);
+        // better read over the next character (which might be a LF);
         // othewise, the LF gets processed as a bonus newline.
         if (c == '\r')
         {
-          int nextchar = in.read();
-          assert ((nextchar == -1) ||
-                                             (nextchar == '\n'));
+          int nextchar = _in.read();
+          buffer[offset++] = (byte)nextchar;
+          count++;
         }
 
         break;
@@ -301,7 +300,6 @@
     }
 
     _totalBytesRead += count;
-
     return (count > 0) ? count : -1;
   }
 
@@ -360,17 +358,22 @@
       }
       else
       {
-        // -= Simon Lessard =- 
-        // TODO:  Check if a non deprecated constructor
-        //                           would do the trick
-        return new String(data, 0, start, bytes);
+        try
+        {
+          return new String(data, start, bytes, "ISO-8859-1");
+        }
+        catch (UnsupportedEncodingException uee)
+        {
+          // Shouldn't happen - we trap unsupported encodings
+          // in setCharacterEncoding()... but fall through anyway
+          assert false;
+        }
       }
     }
 
     return "";
   }
 
-
   // Parse out the boundary text from the content type
   static private String _parseBoundary(String contentType)
   {
@@ -473,7 +476,6 @@
       return _contentType;
     }
 
-
     public long writeFile(OutputStream out)
       throws IOException
     {
@@ -496,109 +498,62 @@
         // =-=AEW Better exception?
         throw new IOException("Input stream has already been requested.");
 
-      byte[] buffer     = __getStreamBuffer();
-      int    bufferSize = buffer.length;
-      int    bufferedBytes = 0;
-      long   position = 0;
       long   totalBytesWritten = 0;
 
-      while (true)
+      // ServletInputStream.readLine() has the annoying habit of adding a \r\n
+      // to the end of the last line.
+      // Since we want a byte-for-byte transfer, don't write the \r\n from the
+      // end of a line until we have verified that we have another line.
+      boolean addCRLF     = false;
+      int  numbuf  = 0;
+      byte[] buffer     = __getStreamBuffer();
+      int    bufferSize = buffer.length;
+      while((numbuf = _readLine(buffer, 0, bufferSize)) != -1)
       {
-        int bytes = _readLine(_in, buffer, bufferedBytes,
-                                 bufferSize - bufferedBytes);
-
-        if (bytes < 0)
+        // Check for boundary
+        if(numbuf > 2 && buffer[0] == '-' && buffer[1] == '-')   // quick pre-check
         {
-          break;
-        }
-        else if (bytes > 0)
-        {
-
-          // Check to see if this is boundary
-          if ((buffer[bufferedBytes] == '-')   &&
-              (buffer[bufferedBytes+1] == '-') &&
-              (bytes > _boundary.length()))
+          String line = _dataToString(buffer, 0, numbuf, false, true);
+          if(line.startsWith(_boundary))
           {
-            String line = _dataToString(buffer, bufferedBytes, bytes, false, true);
-            if (line.startsWith(_boundary))
-            {
               break;
-            }
           }
+        }
 
-          bufferedBytes += bytes;
-
-          // Check if we've reached (or nearly reached)
-          // the end of the buffer.
-          if (bufferedBytes > bufferSize - 2000)
+        // Are we supposed to write \r\n from the last iteration?
+        if(addCRLF)
+        {
+          if(out != null)
           {
-            // Writing to a null output stream;  just
-            // blow off the data
-            if (out == null)
-            {
-              bufferedBytes = 0;
-            }
-            else
-            {
-              // We don't write out the last '\r\n'.  So,
-              // we'll ignore it here, but add it in as the
-              // start of the next pass.
-              boolean addCRLF = false;
-
-              if (bufferedBytes >= 2)
-              {
-                if ((buffer[bufferedBytes - 2] == '\r') &&
-                    (buffer[bufferedBytes - 1] == '\n'))
-                {
-                  bufferedBytes -= 2;
-                  addCRLF = true;
-                }
-              }
-
-              totalBytesWritten += bufferedBytes;
-              if (totalBytesWritten <= _maxAllowedBytes)
-                out.write(buffer, 0, bufferedBytes);
-              position += bufferedBytes;
-
-              if (addCRLF)
-              {
-                bufferedBytes = 2;
-                buffer[0] = (byte) '\r';
-                buffer[1] = (byte) '\n';
-              }
-              else
-              {
-                bufferedBytes = 0;
-              }
-            }
+            out.write('\r');
+            out.write('\n');
+            totalBytesWritten += 2;
           }
+          addCRLF = false;
         }
-      }
-
-      // Anything left in the buffer to write?
-      if ((bufferedBytes > 0) && (out != null))
-      {
-        // If the ending is '\r\n', drop those characters
-        if (bufferedBytes >= 2)
+        // Postpone any ending \r\n until the next iteration
+        if(numbuf >= 2 &&
+           buffer[numbuf - 2] == '\r' &&
+           buffer[numbuf - 1] == '\n')
         {
-          if ((buffer[bufferedBytes - 2] == '\r') &&
-              (buffer[bufferedBytes - 1] == '\n'))
-             bufferedBytes -= 2;
+            numbuf -= 2;    // skip the last 2 chars
+            addCRLF = true;     // make a note to write them on the next iteration
+        }
+        if(out != null)
+        {
+          totalBytesWritten += numbuf;
+          if (totalBytesWritten <= _maxAllowedBytes)
+            out.write(buffer, 0, numbuf);
         }
-
-        totalBytesWritten += bufferedBytes;
-        if (totalBytesWritten <= _maxAllowedBytes)
-          out.write(buffer, 0, bufferedBytes);
-        position += bufferedBytes;
       }
-
+      
       _finished = true;
 
       if (totalBytesWritten >= _maxAllowedBytes)
         throw new EOFException("Uploaded file of length " + totalBytesWritten +
                                " bytes exceeded maximum allowed length ("
                                + _maxAllowedBytes + " bytes)");
-      return position;
+      return totalBytesWritten;
     }
 
     public InputStream getInputStream()
@@ -704,11 +659,9 @@
 
       //Fills up the _buffer parameter with
       //Returns false on EOF
-      private boolean readLine()
+      private void readLine()
         throws IOException
       {
-        boolean addedCRLF = false;
-
         if (_finished)
         {
           throw new IOException("End Of File");
@@ -718,77 +671,44 @@
         {
           _buffer[_end++] = (byte) '\r';
           _buffer[_end++] = (byte) '\n';
-
           _addCRLF = false;
-          addedCRLF = true;
         }
 
-
-        while (_buffer.length > _end + 2000)
-        {
-          //Maximum number of bytes to read
-          int  maxRead = _buffer.length - _end;
-          int bytes = _readLine(_in, _buffer, _end, maxRead);
-
-          if (bytes < 0)
-          {
-            _finished = true;
-            break;
-          }
-          else if (bytes > 0)
+        int  bufferSize = _buffer.length;
+        int  numbuf  = _readLine(_buffer, _end, (bufferSize-_end));
+        if (numbuf < 0)
+        {
+          _finished = true;
+          return;
+        }
+        
+        if(numbuf > 2 && _buffer[_end] == '-' && _buffer[_end+1] == '-')   // quick pre-check
+        {
+          // Check for boundary
+          String line = _dataToString(_buffer, _end, numbuf, false, true);
+          if(line.startsWith(_boundary))
           {
-            int oldEnd = _end;
-            _end += bytes;
-
-            // Check to see if this is boundary
-            if ((_buffer[oldEnd] == '-')   &&
-                (_buffer[oldEnd+1] == '-') &&
-                (bytes > _boundary.length()))
-            {
-              String line = _dataToString(_buffer, oldEnd, bytes, false, true);
-
-              if (line.startsWith(_boundary))
-              {
-                _finished = true;
-                //Skip this last read
-                _end = oldEnd;
-                break;
-              }
-            }
-
+            _finished = true; 
+            return;
           }
+        } 
+        
+        if(numbuf >= 2 &&
+           _buffer[_end+numbuf - 2] == '\r' &&
+           _buffer[_end+numbuf - 1] == '\n')
+        {
+          // Postpone any ending \r\n until the next iteration
+          numbuf -= 2;     // skip the last 2 chars
+          _addCRLF = true; // make a note to write them on the next iteration
         }
-
-        // We don't write out the last '\r\n'.  So,
-        // we'll ignore it here, but add it in as the
-        // start of the next pass.
-
-
-        if (addedCRLF && _finished && _end == 2)
-        {
-          //We added a CRLF, but they are the last two bytes, so
-          //they are not needed
-          _end -= 2;
-        }
-        else if (_end > 1)
-        {
-          if ((_buffer[_end - 2] == '\r') &&
-              (_buffer[_end - 1] == '\n'))
-          {
-            _end -= 2;
-            _addCRLF = true;
-          }
-        }
-
-
-        return _finished;
+        _end += numbuf;
       }
 
       @Override
       public int read(byte[] buffer, int offset, int length)
         throws IOException
       {
-        int bytes;
+        int bytes = -1; // default to EOF
 
         //Either there are more bytes in the stream, or there are more
         //bytes in the cache
@@ -801,27 +721,23 @@
           {
             readLine();
           }
-
-          cachedBytes = _end - _begin;
-
-          bytes = (length > cachedBytes) ? cachedBytes : length;
-
-          System.arraycopy(_buffer, _begin, buffer, offset, bytes);
-          _begin += bytes;
-
-          //If we've written all the data out of the array, then reset
-          //to the beginning of the array
-          if (_begin == _end)
+          if(!_finished)
           {
-            _begin = _end = 0;
+            cachedBytes = _end - _begin;
+  
+            bytes = (length > cachedBytes) ? cachedBytes : length;
+  
+            System.arraycopy(_buffer, _begin, buffer, offset, bytes);
+            _begin += bytes;
+  
+            //If we've written all the data out of the array, then reset
+            //to the beginning of the array
+            if (_begin == _end)
+            {
+              _begin = _end = 0;
+            }
           }
         }
-        else
-        {
-          //Return EOF
-          bytes = -1;
-        }
-
         return bytes;
       }
 
@@ -1013,7 +929,7 @@
     "org.apache.myfaces.trinidadinternal.share.util.MultipartFormHandler.handled";
 
   private static final int _STREAM_BUFFER_SIZE = 65000;
-  private static final int _LINE_BUFFER_SIZE = 1000;
+  private static final int _LINE_BUFFER_SIZE = 8000;
 
   // Use one buffer for each of file streaming and line reading.
   // Not multithread