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...@locus.apache.org on 2000/07/03 06:45:41 UTC
cvs commit: jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http HttpRequestStream.java LocalStrings.properties
remm 00/07/02 21:45:40
Modified: proposals/catalina/src/share/org/apache/tomcat/connector/http
HttpRequestStream.java LocalStrings.properties
Log:
- Added support for chunked request entity bodies. The connector
now support almost all the HTTP/1.1 fancy features. The only one
missing is the trailing headers, but there is no way for a servlet to
access them anyway.
Revision Changes Path
1.2 +211 -5 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpRequestStream.java
Index: HttpRequestStream.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpRequestStream.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- HttpRequestStream.java 2000/05/22 04:57:25 1.1
+++ HttpRequestStream.java 2000/07/03 04:45:37 1.2
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpRequestStream.java,v 1.1 2000/05/22 04:57:25 remm Exp $
- * $Revision: 1.1 $
- * $Date: 2000/05/22 04:57:25 $
+ * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpRequestStream.java,v 1.2 2000/07/03 04:45:37 remm Exp $
+ * $Revision: 1.2 $
+ * $Date: 2000/07/03 04:45:37 $
*
* ====================================================================
*
@@ -64,6 +64,7 @@
package org.apache.tomcat.connector.http;
+import java.io.IOException;
import org.apache.tomcat.Request;
import org.apache.tomcat.connector.RequestStream;
@@ -83,11 +84,216 @@
*
* @param request The associated request
*/
- public HttpRequestStream(Request request) {
+ public HttpRequestStream(HttpRequestImpl request) {
super(request);
-
+ String transferEncoding = request.getHeader("Transfer-Encoding");
+
+ if ((transferEncoding != null)
+ && (transferEncoding.indexOf("chunked") != -1)) {
+ chunk = true;
+ }
+
}
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * Use chunking ?
+ */
+ protected boolean chunk = false;
+
+
+ /**
+ * True if the final chunk was found.
+ */
+ protected boolean endChunk = false;
+
+
+ /**
+ * Chunk buffer.
+ */
+ protected byte[] chunkBuffer = null;
+
+
+ /**
+ * Chunk length.
+ */
+ protected int chunkLength = 0;
+
+
+ /**
+ * Chunk buffer position.
+ */
+ protected int chunkPos = 0;
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Close this input stream. No physical level I-O is performed, but
+ * any further attempt to read from this stream will throw an IOException.
+ * If a content length has been set but not all of the bytes have yet been
+ * consumed, the remaining bytes will be swallowed.
+ */
+ public void close()
+ throws IOException {
+
+ if (closed)
+ throw new IOException(sm.getString("requestStream.close.closed"));
+
+ if (chunk) {
+
+ while (!endChunk) {
+ int b = read();
+ if (b < 0)
+ break;
+ }
+
+ } else {
+
+ if (length > 0) {
+ while (count < length) {
+ int b = read();
+ if (b < 0)
+ break;
+ }
+ }
+
+ }
+
+ closed = true;
+
+ }
+
+
+ /**
+ * Read and return a single byte from this input stream, or -1 if end of
+ * file has been encountered.
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ public int read()
+ throws IOException {
+
+ // Has this stream been closed?
+ if (closed)
+ throw new IOException(sm.getString("requestStream.read.closed"));
+
+ if (endChunk)
+ return (-1);
+
+ if (chunk) {
+
+ if ((chunkBuffer == null)
+ || (chunkPos == chunkLength)) {
+
+ chunkPos = 0;
+
+ try {
+ chunkLength = Integer.parseInt(readLine(), 16);
+ } catch (NumberFormatException e) {
+ // Critical error, unable to parse the chunk length
+ chunkLength = 0;
+ chunk = false;
+ close();
+ return -1;
+ }
+
+ if (chunkLength == 0) {
+
+ // TODO : Parse the trailing headers, if any
+ readLine();
+ endChunk = true;
+ 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
+ stream.read();
+ stream.read();
+
+ }
+
+ }
+
+ return (chunkBuffer[chunkPos++]);
+
+ } else {
+
+ // Have we read the specified content length already?
+ if ((length >= 0) && (count >= length))
+ return (-1); // End of file indicator
+
+ // Read and count the next byte, then return it
+ int b = stream.read();
+ if (b >= 0)
+ count++;
+ return (b);
+
+ }
+
+ }
+
+
+ // -------------------------------------------------------- Private Methods
+
+ /**
+ * Reads the input stream, one line at a time. Reads bytes into an array,
+ * until it reads a certain number of bytes or reaches a newline character,
+ * which it reads into the array as well.
+ *
+ * @param input Input stream on which the bytes are read
+ * @return The line that was read, or <code>null</code> if end-of-file
+ * was encountered
+ * @exception IOException if an input or output exception has occurred
+ */
+ private String readLine()
+ throws IOException {
+
+ StringBuffer sb = new StringBuffer();
+ while (true) {
+ int ch = stream.read();
+ if (ch < 0) {
+ if (sb.length() == 0) {
+ return (null);
+ } else {
+ break;
+ }
+ } else if (ch == '\r') {
+ continue;
+ } else if (ch == '\n') {
+ break;
+ }
+ sb.append((char) ch);
+ }
+ return (sb.toString());
+
+ }
+
}
1.8 +3 -0 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/LocalStrings.properties
Index: LocalStrings.properties
===================================================================
RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/LocalStrings.properties,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- LocalStrings.properties 2000/07/02 18:07:03 1.7
+++ LocalStrings.properties 2000/07/03 04:45:37 1.8
@@ -20,3 +20,6 @@
httpProcessor.start=HTTP processor has already been started
httpProcessor.starting=Starting background thread
httpProcessor.stopping=Stopping background thread
+requestStream.close.closed=Request stream has already been closed
+requestStream.read.closed=Unable to read from a closed stream
+requestStream.read.error=Unexpected end of stream
\ No newline at end of file