[ 
https://issues.apache.org/jira/browse/FILEUPLOAD-144?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12527547
 ] 

Laurent Goncalves commented on FILEUPLOAD-144:
----------------------------------------------

I think I've found the problem :

The browser sends the request slowly.

There is a special case which leads to a bug in the 
MultipartStream$ItemInputStream.makeAvailable() method :
The buffer is filled with request's data ending on a part of the boundary. The 
end of the buffer only contains the begining of the boundary.
1.The findSeparator method can't see a boundary in the buffer (true because it 
is a part of the boundary), so it sets the "pos" to "-1"
2. Because there is no "available" byte in the buffer, the method 
makeAvailable() is called
3. The makeAvailable() method copy unread part of the end of the buffer at the 
begining and call a read on the input Stream.
here is the problem
4. Thus the browser sends data slowly, the read() method only returns 19 bytes. 
19 in my case, but the bug appear if the read method doesn't returns enough 
bytes to complete the boundary.
5. The makeAvailable() method call the findSeparator() method which returns 
again pos=-1 because there isn't yet a complete boundary in the buffer
6. The makeAvailable() method call available() method which returns 0 because 
pos=-1 again
7. As makeAvailable() returns 0 the read() method returns -1 whereas it isn't 
the end of the stream !

To correct the bug, I've changed the makeAvailable() method to force a loop on 
the reading of the input stream in this case.
This is the new method :
        /**
         * Attempts to read more data.
         * @return Number of available bytes
         * @throws IOException An I/O error occurred.
         */
        private int makeAvailable() throws IOException {
            if (pos != -1) {
                return 0;
            }

            // Move the data to the beginning of the buffer.
            total += tail - head - pad;
            System.arraycopy(buffer, tail - pad, buffer, 0, pad);

            // Refill buffer with new data.
            head = 0;
            // **************** correction : the read is in a do/while 
structure to loop
            int bytesRead = 0;
            do
            {
               bytesRead = input.read(buffer, pad, bufSize - pad);
            // **************** end of the first part of the correction
               if (bytesRead == -1) {
                   // The last pad amount is left in the buffer.
                   // Boundary can't be in there so signal an error
                   // condition.
                   throw new MalformedStreamException(
                   "Stream ended unexpectedly");
               }
               notifier.noteBytesRead(bytesRead);
               tail = pad + bytesRead;
               findSeparator();
           // ****************  2nd part : the loop 
               //separator was not found, it denotes a miss in the buffer
               // force other buffer's reading until end of stream or first 
separator found
            }
            while (pos == -1 && bytesRead >= 0);
          // ****************  end of correction
               
            return available();
        }


> Parameters values are lost
> --------------------------
>
>                 Key: FILEUPLOAD-144
>                 URL: https://issues.apache.org/jira/browse/FILEUPLOAD-144
>             Project: Commons FileUpload
>          Issue Type: Bug
>    Affects Versions: 1.2
>         Environment: JBoss 4 / XP / Servlet / both Firefox and IE
>            Reporter: Vera Mickael
>            Priority: Critical
>         Attachments: test.fileupload.zip
>
>
> When parsing a request with the streaming API, some parameters loose their 
> values. I can easily reproduce the problem when a lot of parameters are 
> submitted (about 400 in a table). My code is as follows :
>             final FileItemStream itemStream = anItemIterator.next();
>             final String fieldName = itemStream.getFieldName();
>             System.out.print("Field " + fieldName);
>             InputStream stream = itemStream.openStream();
>             final String value = Streams.asString(stream, "UTF-8");
> The last statement sometimes returns a value and sometimes not. Sometimes I 
> can retreive all parameters, sometimes I loose 3 or 4 parameters. I 
> reproduced the problem on two computers. I have a very small application with 
> a servlet of 69 lines that reproduces the problem, the project is attached to 
> this issue. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to