Hi, I think I found a problem in the way Tomcat parses the POST Http Request. It might be related to issues n°40860, 31523 and 42347 submitted to bugzilla <https://issues.apache.org/bugzilla>. I am running on a JBoss 4.0.4 GA server on a windows platform. I know it uses a 5.5.x tomcat, but I don't know exactly which version.
Symptoms : When I submit a POST request, sometimes one parameter get lost. I can tell using Eclipse's TCP/IP proxy that the value was submitted in the request. Analysis: The POST request looks like that and is 15kB long: << -----------------------------7de35e1c190e9e Content-Disposition: form-data; name="autoScroll" 0,0 -----------------------------7de35e1c190e9e Content-Disposition: form-data; name="principal:arbre::focused" false -----------------------------7de35e1c190e9e Content-Disposition: form-data; name="principal:arbre::expandedNodes" >> Using remote debugging, I found that a MultipartStream object analyses the request using a 4KB buffer; this buffer is fed by a 8kB buffer used by a ByteChunk object. The pattern "-----------------------------7de35e1c190e9e" is called 'boundary'. and is repeated for each field. I noted that the hex part of the boundary may not be the same length from one POST to another, I think that is why the problem does not always occur. when MultipartStream arrives at the end of its buffer and there is not enough bytes left to read the next boundary, it moves the few unread bytes to the beginning of the buffer, then loads the next chunk of data from the ByteChunk object (see MultipartStream$ItemInputStream.makeAvailable()) ex : the buffer ends with "false\n\r----". These bytes are moved to the start of the buffer, so that the buffer now starts with "false\n\r-----------------------------7de35e1c190e9e[...]" and the code can now read the boundary. In this example, after parsing the first 4096 bytes, we now parse the (4096-11)=4085 next bytes (because we still have the 11 last bytes from the first chunk. At the end of the second chunk : the buffer now ends with something like "0,0\n\r--" (7 bytes) and we need the next chunk of data to read the next boundary. Tomcats asks the ByteChunk object for the next (4096-7) bytes, but there are only 11 available (8kB-4kB-4085 bytes). So MultipartStream only sees a 18 bytes-long data, which is not enough to read the boundary. As a consequence, the field is skipped and is value is lost. So the problem, I think, relies in the ByteChunk.substract method, when the available bytes in the buffer are not enough to fill the MultipartStream need. This method should attempt to read the next chunk of data if available. Solution : Here is the modification I suggest in the code: << public int substract( byte src[], int off, int len ) throws IOException { if ((end - start) == 0) { if (in == null) return -1; int n = in.realReadBytes( buff, 0, buff.length ); if (n < 0) return -1; } int n = len; if (len > getLength()) { n = getLength(); } System.arraycopy(buff, start, src, off, n); start += n; // Start of modification - add if (n<len) { // not enough data in the buffer. We want more! int n2 = substract(src, off+n, len-n); if (n2>0) { return n+n2; } } // End of modification return n; } >> below is a part of the stack trace to the point where I located the problem: Daemon Thread [http-0.0.0.0-8080-5] (Suspended (breakpoint at line 404 in ByteChunk)) ByteChunk.substract(byte[], int, int) line: 404 InputBuffer.read(byte[], int, int) line: 299 CoyoteInputStream.read(byte[], int, int) line: 192 MultipartStream$ItemInputStream.makeAvailable() line: 959 MultipartStream$ItemInputStream.read(byte[], int, int) line: 887 MultipartStream$ItemInputStream(InputStream).read(byte[]) line: 89 Streams.copy(InputStream, OutputStream, boolean, byte[]) line: 94 Streams.copy(InputStream, OutputStream, boolean) line: 64 MultipartStream.readBodyData(OutputStream) line: 593 MultipartStream.discardBodyData() line: 619 MultipartStream.skipPreamble() line: 638 FileUploadBase$FileItemIteratorImpl.findNextItem() line: 844 FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase, RequestContext) line: 825 DiskFileUpload(FileUploadBase).getItemIterator(RequestContext) line: 323 DiskFileUpload(FileUploadBase).parseRequest(RequestContext) line: 341 DiskFileUpload(FileUploadBase).parseRequest(HttpServletRequest) line: 302 MultipartRequestWrapper.parseRequest() line: 85 MultipartRequestWrapper.getParameter(String) line: 181 RequestParameterMap.getAttribute(String) line: 42 Can anybody tell me if this is a known problem? Maybe it has been solved some other way. I know Tomcat 5.5 if rather old... Thanks, Didier DUQUENNOY Consultez nos sites internet : http://www.sofaxis.com http://www.sofcap-sofcah.com Sofaxis disclaimer : http://www.sofaxis.com/disclaimer-1.html --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org