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 2002/01/10 00:29:29 UTC

cvs commit: jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/filters ChunkedOutputFilter.java

remm        02/01/09 15:29:29

  Modified:    http11/src/java/org/apache/coyote/http11 Constants.java
                        Http11Connector.java
               http11/src/java/org/apache/coyote/http11/filters
                        ChunkedOutputFilter.java
  Log:
  - Add support for output chunking (input chunking is much harder to do OTOH).
  - Improve response processing, so that the response to 2 pipelined GETs is now
    correct.
  - Content delimitation on input is untested at the moment, and pipelining still could
    have bugs with the buffer management (only two out of three buffers are in use in the simple test).
  
  Revision  Changes    Path
  1.5       +7 -0      jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Constants.java
  
  Index: Constants.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Constants.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Constants.java	9 Jan 2002 12:57:49 -0000	1.4
  +++ Constants.java	9 Jan 2002 23:29:29 -0000	1.5
  @@ -78,6 +78,13 @@
   
   
       /**
  +     * Server string.
  +     */
  +    public static final String SERVER = 
  +        "Apache Coyote HTTP/1.1 Connector [1.0]";
  +
  +
  +    /**
        * CR.
        */
       public static final byte CR = (byte) '\r';
  
  
  
  1.8       +55 -15    jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11Connector.java
  
  Index: Http11Connector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11Connector.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Http11Connector.java	9 Jan 2002 12:57:49 -0000	1.7
  +++ Http11Connector.java	9 Jan 2002 23:29:29 -0000	1.8
  @@ -67,6 +67,7 @@
   
   import org.apache.tomcat.util.buf.ByteChunk;
   import org.apache.tomcat.util.buf.MessageBytes;
  +import org.apache.tomcat.util.http.FastHttpDateFormat;
   import org.apache.tomcat.util.http.MimeHeaders;
   
   import org.apache.coyote.ActionHook;
  @@ -265,7 +266,6 @@
                   
                   inputBuffer.parseHeaders();
               } catch (EOFException e) {
  -                e.printStackTrace();
                   error = true;
                   break;
               } catch (InterruptedIOException e) {
  @@ -350,6 +350,8 @@
               // Send a 100 status back if it makes sense (response not committed
               // yet, and client specified an expectation for 100-continue)
   
  +            // FIXME
  +
           } else if (actionCode == ActionCode.ACTION_CLOSE) {
   
               // Close
  @@ -414,10 +416,10 @@
           boolean http11 = true;
           contentDelimitation = false;
   
  -        MessageBytes protocol = request.protocol();
  -        if (protocol.equals(Constants.HTTP_11)) {
  +        MessageBytes protocolMB = request.protocol();
  +        if (protocolMB.equals(Constants.HTTP_11)) {
               http11 = true;
  -        } else if (protocol.equals(Constants.HTTP_10)) {
  +        } else if (protocolMB.equals(Constants.HTTP_10)) {
               http11 = false;
               keepAlive = false;
           } else {
  @@ -427,6 +429,8 @@
               response.setStatus(505);
           }
   
  +        MessageBytes methodMB = request.method();
  +
           // Check connection header
           MessageBytes connectionValueMB = 
               request.getMimeHeaders().getValue("connection");
  @@ -464,6 +468,15 @@
               inputBuffer.addActiveFilter
                   (inputFilters[Constants.IDENTITY_FILTER]);
               contentDelimitation = true;
  +        } else {
  +            // If method is GET or HEAD, prevent from reading any content
  +            if ((methodMB.equals("GET"))
  +                || (methodMB.equals("HEAD"))
  +                || (methodMB.equals("TRACE"))) {
  +                inputBuffer.addActiveFilter
  +                    (inputFilters[Constants.VOID_FILTER]);
  +                contentDelimitation = true;
  +            }
           }
   
           // Parse transfer-encoding header
  @@ -484,7 +497,7 @@
                       // Unsupported transfer encoding
                       error = true;
                       // Send 501; Unimplemented
  -                    response.setStatus(502);
  +                    response.setStatus(501);
                   }
                   startPos = commaPos + 1;
                   commaPos = transferEncodingValue.indexOf(',', startPos);
  @@ -495,7 +508,7 @@
                   // Unsupported transfer encoding
                   error = true;
                   // Send 501; Unimplemented
  -                response.setStatus(502);
  +                response.setStatus(501);
               }
           }
   
  @@ -518,16 +531,49 @@
        */
       protected void prepareResponse() {
   
  +        boolean http11 = true;
  +        boolean http09 = false;
           contentDelimitation = false;
   
  -        OutputFilter[] outputFilters = outputBuffer.getFilters();
  +        MessageBytes protocolMB = request.protocol();
  +        if (protocolMB.equals(Constants.HTTP_11)) {
  +            http11 = true;
  +        } else if (protocolMB.equals(Constants.HTTP_10)) {
  +            http11 = false;
  +        } else {
  +            // FIXME: Check for HTTP/0.9
  +        }
   
  -        outputBuffer.addActiveFilter
  -            (outputFilters[Constants.IDENTITY_FILTER]);
  +        OutputFilter[] outputFilters = outputBuffer.getFilters();
   
           int contentLength = request.getContentLength();
           if (contentLength != -1) {
  +            outputBuffer.addActiveFilter
  +                (outputFilters[Constants.IDENTITY_FILTER]);
               contentDelimitation = true;
  +        } else {
  +            if (http11) {
  +                outputBuffer.addActiveFilter
  +                    (outputFilters[Constants.CHUNKED_FILTER]);
  +                contentDelimitation = true;
  +                response.addHeader("Transfer-Encoding", "chunked");
  +            }
  +        }
  +
  +        // Add date header
  +        response.addHeader("Date", FastHttpDateFormat.getCurrentDate());
  +
  +        // Add server header
  +        response.addHeader("Server", Constants.SERVER);
  +
  +        // Add transfer encoding header
  +        // FIXME
  +
  +        if (!contentDelimitation) {
  +            // Mark as close the connection after the request, and add the 
  +            // connection: close header
  +            keepAlive = false;
  +            response.addHeader("Connection", "close");
           }
   
           // Build the response header
  @@ -539,12 +585,6 @@
               outputBuffer.sendHeader(headers.getName(i), headers.getValue(i));
           }
           outputBuffer.endHeaders();
  -
  -        if (!contentDelimitation) {
  -            // Mark as close the connection after the request, and add the 
  -            // connection: close header
  -            keepAlive = false;
  -        }
   
       }
   
  
  
  
  1.2       +48 -4     jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java
  
  Index: ChunkedOutputFilter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ChunkedOutputFilter.java	24 Dec 2001 20:44:40 -0000	1.1
  +++ ChunkedOutputFilter.java	9 Jan 2002 23:29:29 -0000	1.2
  @@ -62,6 +62,7 @@
   import java.io.IOException;
   
   import org.apache.tomcat.util.buf.ByteChunk;
  +import org.apache.tomcat.util.buf.HexUtils;
   
   import org.apache.coyote.OutputBuffer;
   import org.apache.coyote.Response;
  @@ -82,11 +83,33 @@
       protected static final ByteChunk ENCODING = new ByteChunk();
   
   
  +    /**
  +     * End chunk.
  +     */
  +    protected static final ByteChunk END_CHUNK = new ByteChunk();
  +
  +
       // ----------------------------------------------------- Static Initializer
   
   
       static {
           ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME.length());
  +        String endChunkValue = "0\r\n\r\n";
  +        END_CHUNK.setBytes(endChunkValue.getBytes(), 
  +                           0, endChunkValue.length());
  +    }
  +
  +
  +    // ------------------------------------------------------------ Constructor
  +
  +
  +    /**
  +     * Default constructor.
  +     */
  +    public ChunkedOutputFilter() {
  +        chunkLength = new byte[10];
  +        chunkLength[8] = (byte) '\r';
  +        chunkLength[9] = (byte) '\n';
       }
   
   
  @@ -99,6 +122,18 @@
       protected OutputBuffer buffer;
   
   
  +    /**
  +     * Buffer used for chunk length conversion.
  +     */
  +    protected byte[] chunkLength = new byte[10];
  +
  +
  +    /**
  +     * Chunk header.
  +     */
  +    protected ByteChunk chunkHeader = new ByteChunk();
  +
  +
       // ------------------------------------------------------------- Properties
   
   
  @@ -116,11 +151,19 @@
           int result = chunk.getLength();
   
           if (result <= 0) {
  -            return -1;
  +            return 0;
           }
   
  -        // Write chunk header
  -        // FIXME
  +        // Calculate chunk header
  +        int pos = 7;
  +        int current = result;
  +        while (current > 0) {
  +            int digit = current % 16;
  +            current = current / 16;
  +            chunkLength[pos--] = HexUtils.HEX[digit];
  +        }
  +        chunkHeader.setBytes(chunkLength, pos + 1, 9 - pos);
  +        buffer.doWrite(chunkHeader);
   
           buffer.doWrite(chunk);
   
  @@ -157,7 +200,8 @@
           throws IOException {
   
           // Write end chunk
  -        // FIXME
  +        buffer.doWrite(END_CHUNK);
  +        
           return 0;
   
       }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>