[
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.