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 <[EMAIL PROTECTED]> (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; + + } /** --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]