You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2001/01/22 05:55:40 UTC
cvs commit: jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/connector/http HttpRequestStream.java
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 <ms...@xn.com.au> (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;
+
+ }
/**