Author: fhanik
Date: Fri Oct  9 16:24:43 2009
New Revision: 823608

URL: http://svn.apache.org/viewvc?rev=823608&view=rev
Log:
Abstract out code for output buffer, much easier to read

Added:
    tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java   
(with props)
Modified:
    tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java
    tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
    tomcat/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java

Added: tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java?rev=823608&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java (added)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java Fri 
Oct  9 16:24:43 2009
@@ -0,0 +1,566 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.coyote.http11;
+
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.apache.coyote.ActionCode;
+import org.apache.coyote.OutputBuffer;
+import org.apache.coyote.Response;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.buf.CharChunk;
+import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.HttpMessages;
+import org.apache.tomcat.util.http.MimeHeaders;
+import org.apache.tomcat.util.res.StringManager;
+
+public abstract class AbstractOutputBuffer implements OutputBuffer{
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * Associated Coyote response.
+     */
+    protected Response response;
+
+
+    /**
+     * Headers of the associated request.
+     */
+    protected MimeHeaders headers;
+
+
+    /**
+     * Committed flag.
+     */
+    protected boolean committed;
+
+
+    /**
+     * Finished flag.
+     */
+    protected boolean finished;
+
+
+    /**
+     * The buffer used for header composition.
+     */
+    protected byte[] buf;
+
+
+    /**
+     * Position in the buffer.
+     */
+    protected int pos;
+
+
+
+    /**
+     * Filter library.
+     * Note: Filter[0] is always the "chunked" filter.
+     */
+    protected OutputFilter[] filterLibrary;
+
+
+    /**
+     * Active filter (which is actually the top of the pipeline).
+     */
+    protected OutputFilter[] activeFilters;
+
+
+    /**
+     * Index of the last active filter.
+     */
+    protected int lastActiveFilter;
+
+    /**
+     * Underlying output buffer.
+     */
+    protected OutputBuffer outputStreamOutputBuffer;
+
+    // -------------------------------------------------------------- Variables
+
+
+    /**
+     * The string manager for this package.
+     */
+    protected static StringManager sm =
+        StringManager.getManager(Constants.Package);
+
+    // ------------------------------------------------------------- Properties
+
+
+
+
+
+    /**
+     * Add an output filter to the filter library.
+     */
+    public void addFilter(OutputFilter filter) {
+
+        OutputFilter[] newFilterLibrary = 
+            new OutputFilter[filterLibrary.length + 1];
+        for (int i = 0; i < filterLibrary.length; i++) {
+            newFilterLibrary[i] = filterLibrary[i];
+        }
+        newFilterLibrary[filterLibrary.length] = filter;
+        filterLibrary = newFilterLibrary;
+
+        activeFilters = new OutputFilter[filterLibrary.length];
+
+    }
+
+
+    /**
+     * Get filters.
+     */
+    public OutputFilter[] getFilters() {
+
+        return filterLibrary;
+
+    }
+
+
+    /**
+     * Clear filters.
+     */
+    public void clearFilters() {
+
+        filterLibrary = new OutputFilter[0];
+        lastActiveFilter = -1;
+
+    }
+
+
+    /**
+     * Add an output filter to the filter library.
+     */
+    public void addActiveFilter(OutputFilter filter) {
+
+        if (lastActiveFilter == -1) {
+            filter.setBuffer(outputStreamOutputBuffer);
+        } else {
+            for (int i = 0; i <= lastActiveFilter; i++) {
+                if (activeFilters[i] == filter)
+                    return;
+            }
+            filter.setBuffer(activeFilters[lastActiveFilter]);
+        }
+
+        activeFilters[++lastActiveFilter] = filter;
+
+        filter.setResponse(response);
+
+    }
+
+
+
+    
+ // --------------------------------------------------- OutputBuffer Methods
+
+
+    /**
+     * Write the contents of a byte chunk.
+     * 
+     * @param chunk byte chunk
+     * @return number of bytes written
+     * @throws IOException an undelying I/O error occured
+     */
+    public int doWrite(ByteChunk chunk, Response res) 
+        throws IOException {
+
+        if (!committed) {
+
+            // Send the connector a request for commit. The connector should
+            // then validate the headers, send them (using sendHeaders) and 
+            // set the filters accordingly.
+            response.action(ActionCode.ACTION_COMMIT, null);
+
+        }
+
+        if (lastActiveFilter == -1)
+            return outputStreamOutputBuffer.doWrite(chunk, res);
+        else
+            return activeFilters[lastActiveFilter].doWrite(chunk, res);
+
+    }
+    
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Flush the response.
+     * 
+     * @throws IOException an undelying I/O error occured
+     */
+    public void flush()
+        throws IOException {
+
+        if (!committed) {
+
+            // Send the connector a request for commit. The connector should
+            // then validate the headers, send them (using sendHeader) and 
+            // set the filters accordingly.
+            response.action(ActionCode.ACTION_COMMIT, null);
+
+        }
+    }
+    
+    /**
+     * Reset current response.
+     * 
+     * @throws IllegalStateException if the response has already been committed
+     */
+    public void reset() {
+
+        if (committed)
+            throw new IllegalStateException(/*FIXME:Put an error message*/);
+
+        // Recycle Request object
+        response.recycle();
+
+    }
+    
+    /**
+     * Recycle the output buffer. This should be called when closing the 
+     * connection.
+     */
+    public void recycle() {
+        // Recycle filters
+        for (int i = 0; i <= lastActiveFilter; i++) {
+            activeFilters[i].recycle();
+        }
+        // Recycle Request object
+        response.recycle();
+        pos = 0;
+        lastActiveFilter = -1;
+        committed = false;
+        finished = false;
+
+    }
+    
+    /**
+     * End processing of current HTTP request.
+     * Note: All bytes of the current request should have been already 
+     * consumed. This method only resets all the pointers so that we are ready
+     * to parse the next HTTP request.
+     */
+    public void nextRequest() {
+
+        // Recycle Request object
+        response.recycle();
+        // Recycle filters
+        for (int i = 0; i <= lastActiveFilter; i++) {
+            activeFilters[i].recycle();
+        }
+
+        // Reset pointers
+        pos = 0;
+        lastActiveFilter = -1;
+        committed = false;
+        finished = false;
+
+    }
+    
+    /**
+     * End request.
+     * 
+     * @throws IOException an undelying I/O error occured
+     */
+    public void endRequest()
+        throws IOException {
+
+        if (!committed) {
+
+            // Send the connector a request for commit. The connector should
+            // then validate the headers, send them (using sendHeader) and 
+            // set the filters accordingly.
+            response.action(ActionCode.ACTION_COMMIT, null);
+
+        }
+
+        if (finished)
+            return;
+
+        if (lastActiveFilter != -1)
+            activeFilters[lastActiveFilter].end();
+        finished = true;
+
+    }
+    
+    public abstract void sendAck() throws IOException;
+    
+    protected abstract void commit() throws IOException;
+
+
+    /**
+     * Send the response status line.
+     */
+    public void sendStatus() {
+
+        // Write protocol name
+        write(Constants.HTTP_11_BYTES);
+        buf[pos++] = Constants.SP;
+
+        // Write status code
+        int status = response.getStatus();
+        switch (status) {
+        case 200:
+            write(Constants._200_BYTES);
+            break;
+        case 400:
+            write(Constants._400_BYTES);
+            break;
+        case 404:
+            write(Constants._404_BYTES);
+            break;
+        default:
+            write(status);
+        }
+
+        buf[pos++] = Constants.SP;
+
+        // Write message
+        String message = null;
+        if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER) {
+            message = response.getMessage();
+        }
+        if (message == null) {
+            write(HttpMessages.getMessage(status)); 
+        } else {
+            write(message.replace('\n', ' ').replace('\r', ' '));
+        }
+
+        // End the response status line
+        if (org.apache.coyote.Constants.IS_SECURITY_ENABLED){
+           AccessController.doPrivileged(
+                new PrivilegedAction<Void>(){
+                    public Void run(){
+                        buf[pos++] = Constants.CR;
+                        buf[pos++] = Constants.LF;
+                        return null;
+                    }
+                }
+           );
+        } else {
+            buf[pos++] = Constants.CR;
+            buf[pos++] = Constants.LF;
+        }
+
+    } 
+    
+
+
+    /**
+     * Send a header.
+     * 
+     * @param name Header name
+     * @param value Header value
+     */
+    public void sendHeader(MessageBytes name, MessageBytes value) {
+
+        write(name);
+        buf[pos++] = Constants.COLON;
+        buf[pos++] = Constants.SP;
+        write(value);
+        buf[pos++] = Constants.CR;
+        buf[pos++] = Constants.LF;
+
+    }
+
+
+    /**
+     * Send a header.
+     * 
+     * @param name Header name
+     * @param value Header value
+     */
+    public void sendHeader(ByteChunk name, ByteChunk value) {
+
+        write(name);
+        buf[pos++] = Constants.COLON;
+        buf[pos++] = Constants.SP;
+        write(value);
+        buf[pos++] = Constants.CR;
+        buf[pos++] = Constants.LF;
+
+    }
+
+
+    /**
+     * Send a header.
+     * 
+     * @param name Header name
+     * @param value Header value
+     */
+    public void sendHeader(String name, String value) {
+
+        write(name);
+        buf[pos++] = Constants.COLON;
+        buf[pos++] = Constants.SP;
+        write(value);
+        buf[pos++] = Constants.CR;
+        buf[pos++] = Constants.LF;
+
+    }
+
+
+    /**
+     * End the header block.
+     */
+    public void endHeaders() {
+
+        buf[pos++] = Constants.CR;
+        buf[pos++] = Constants.LF;
+
+    }
+    
+    
+    /**
+     * This method will write the contents of the specyfied message bytes 
+     * buffer to the output stream, without filtering. This method is meant to
+     * be used to write the response header.
+     * 
+     * @param mb data to be written
+     */
+    protected void write(MessageBytes mb) {
+
+        if (mb.getType() == MessageBytes.T_BYTES) {
+            ByteChunk bc = mb.getByteChunk();
+            write(bc);
+        } else if (mb.getType() == MessageBytes.T_CHARS) {
+            CharChunk cc = mb.getCharChunk();
+            write(cc);
+        } else {
+            write(mb.toString());
+        }
+
+    }
+
+
+    /**
+     * This method will write the contents of the specyfied message bytes 
+     * buffer to the output stream, without filtering. This method is meant to
+     * be used to write the response header.
+     * 
+     * @param bc data to be written
+     */
+    protected void write(ByteChunk bc) {
+
+        // Writing the byte chunk to the output buffer
+        int length = bc.getLength();
+        System.arraycopy(bc.getBytes(), bc.getStart(), buf, pos, length);
+        pos = pos + length;
+
+    }
+
+
+    /**
+     * This method will write the contents of the specyfied char 
+     * buffer to the output stream, without filtering. This method is meant to
+     * be used to write the response header.
+     * 
+     * @param cc data to be written
+     */
+    protected void write(CharChunk cc) {
+
+        int start = cc.getStart();
+        int end = cc.getEnd();
+        char[] cbuf = cc.getBuffer();
+        for (int i = start; i < end; i++) {
+            char c = cbuf[i];
+            // Note:  This is clearly incorrect for many strings,
+            // but is the only consistent approach within the current
+            // servlet framework.  It must suffice until servlet output
+            // streams properly encode their output.
+            if ((c <= 31) && (c != 9)) {
+                c = ' ';
+            } else if (c == 127) {
+                c = ' ';
+            }
+            buf[pos++] = (byte) c;
+        }
+
+    }
+
+
+    /**
+     * This method will write the contents of the specyfied byte 
+     * buffer to the output stream, without filtering. This method is meant to
+     * be used to write the response header.
+     * 
+     * @param b data to be written
+     */
+    public void write(byte[] b) {
+
+        // Writing the byte chunk to the output buffer
+        System.arraycopy(b, 0, buf, pos, b.length);
+        pos = pos + b.length;
+
+    }
+
+
+    /**
+     * This method will write the contents of the specyfied String to the 
+     * output stream, without filtering. This method is meant to be used to 
+     * write the response header.
+     * 
+     * @param s data to be written
+     */
+    protected void write(String s) {
+
+        if (s == null)
+            return;
+
+        // From the Tomcat 3.3 HTTP/1.0 connector
+        int len = s.length();
+        for (int i = 0; i < len; i++) {
+            char c = s.charAt (i);
+            // Note:  This is clearly incorrect for many strings,
+            // but is the only consistent approach within the current
+            // servlet framework.  It must suffice until servlet output
+            // streams properly encode their output.
+            if ((c <= 31) && (c != 9)) {
+                c = ' ';
+            } else if (c == 127) {
+                c = ' ';
+            }
+            buf[pos++] = (byte) c;
+        }
+
+    }
+
+
+    /**
+     * This method will print the specified integer to the output stream, 
+     * without filtering. This method is meant to be used to write the 
+     * response header.
+     * 
+     * @param i data to be written
+     */
+    protected void write(int i) {
+
+        write(String.valueOf(i));
+
+    }
+
+
+
+}

Propchange: tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=823608&r1=823607&r2=823608&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Fri Oct  
9 16:24:43 2009
@@ -66,18 +66,6 @@
 
 
     /**
-     * Logger.
-     */
-    protected static org.apache.juli.logging.Log log
-        = org.apache.juli.logging.LogFactory.getLog(Http11NioProcessor.class);
-
-    /**
-     * The string manager for this package.
-     */
-    protected static StringManager sm =
-        StringManager.getManager(Constants.Package);
-
-    /**
      * SSL information.
      */
     protected SSLSupport sslSupport;

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=823608&r1=823607&r2=823608&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Fri Oct  9 
16:24:43 2009
@@ -56,14 +56,7 @@
  */
 public class Http11Processor extends AbstractHttp11Processor implements 
ActionHook {
 
-
-    /**
-     * Logger.
-     */
-    protected static org.apache.juli.logging.Log log
-        = org.apache.juli.logging.LogFactory.getLog(Http11Processor.class);
-
-    // ------------------------------------------------------------ Constructor
+   // ------------------------------------------------------------ Constructor
 
 
     public Http11Processor(int headerBufferSize, JIoEndpoint endpoint) {

Modified: 
tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java?rev=823608&r1=823607&r2=823608&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java Fri 
Oct  9 16:24:43 2009
@@ -22,19 +22,14 @@
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 
-import org.apache.coyote.ActionCode;
 import org.apache.coyote.OutputBuffer;
 import org.apache.coyote.Response;
+import org.apache.tomcat.util.MutableInteger;
 import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.CharChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
 import org.apache.tomcat.util.http.HttpMessages;
-import org.apache.tomcat.util.http.MimeHeaders;
 import org.apache.tomcat.util.net.NioChannel;
 import org.apache.tomcat.util.net.NioEndpoint;
 import org.apache.tomcat.util.net.NioSelectorPool;
-import org.apache.tomcat.util.res.StringManager;
-import org.apache.tomcat.util.MutableInteger;
 
 /**
  * Output buffer.
@@ -42,8 +37,7 @@
  * @author <a href="mailto:r...@apache.org";>Remy Maucherat</a>
  * @author Filip Hanik
  */
-public class InternalNioOutputBuffer 
-    implements OutputBuffer {
+public class InternalNioOutputBuffer extends AbstractOutputBuffer {
 
 
     // -------------------------------------------------------------- Constants
@@ -93,54 +87,6 @@
     }
 
 
-    // -------------------------------------------------------------- Variables
-
-
-    /**
-     * The string manager for this package.
-     */
-    protected static StringManager sm =
-        StringManager.getManager(Constants.Package);
-
-
-    // ----------------------------------------------------- Instance Variables
-
-
-    /**
-     * Associated Coyote response.
-     */
-    protected Response response;
-
-
-    /**
-     * Headers of the associated request.
-     */
-    protected MimeHeaders headers;
-
-
-    /**
-     * Committed flag.
-     */
-    protected boolean committed;
-
-
-    /**
-     * Finished flag.
-     */
-    protected boolean finished;
-
-
-    /**
-     * Pointer to the current write buffer.
-     */
-    protected byte[] buf;
-
-
-    /**
-     * Position in the buffer.
-     */
-    protected int pos;
-
     /**
      * Number of bytes last written
      */
@@ -158,29 +104,6 @@
 
 
 
-    /**
-     * Underlying output buffer.
-     */
-    protected OutputBuffer outputStreamOutputBuffer;
-
-
-    /**
-     * Filter library.
-     * Note: Filter[0] is always the "chunked" filter.
-     */
-    protected OutputFilter[] filterLibrary;
-
-
-    /**
-     * Active filter (which is actually the top of the pipeline).
-     */
-    protected OutputFilter[] activeFilters;
-
-
-    /**
-     * Index of the last active filter.
-     */
-    protected int lastActiveFilter;
     
     // ------------------------------------------------------------- Properties
 
@@ -207,67 +130,6 @@
         return pool;
     }    
 
-    /**
-     * Add an output filter to the filter library.
-     */
-    public void addFilter(OutputFilter filter) {
-
-        OutputFilter[] newFilterLibrary = 
-            new OutputFilter[filterLibrary.length + 1];
-        for (int i = 0; i < filterLibrary.length; i++) {
-            newFilterLibrary[i] = filterLibrary[i];
-        }
-        newFilterLibrary[filterLibrary.length] = filter;
-        filterLibrary = newFilterLibrary;
-
-        activeFilters = new OutputFilter[filterLibrary.length];
-
-    }
-
-
-    /**
-     * Get filters.
-     */
-    public OutputFilter[] getFilters() {
-
-        return filterLibrary;
-
-    }
-
-
-    /**
-     * Clear filters.
-     */
-    public void clearFilters() {
-
-        filterLibrary = new OutputFilter[0];
-        lastActiveFilter = -1;
-
-    }
-
-
-    /**
-     * Add an output filter to the filter library.
-     */
-    public void addActiveFilter(OutputFilter filter) {
-
-        if (lastActiveFilter == -1) {
-            filter.setBuffer(outputStreamOutputBuffer);
-        } else {
-            for (int i = 0; i <= lastActiveFilter; i++) {
-                if (activeFilters[i] == filter)
-                    return;
-            }
-            filter.setBuffer(activeFilters[lastActiveFilter]);
-        }
-
-        activeFilters[++lastActiveFilter] = filter;
-
-        filter.setResponse(response);
-
-    }
-
-
     // --------------------------------------------------------- Public Methods
 
 
@@ -275,19 +137,12 @@
      * Flush the response.
      * 
      * @throws IOException an undelying I/O error occured
+     * 
      */
-    public void flush()
-        throws IOException {
-
-        if (!committed) {
-
-            // Send the connector a request for commit. The connector should
-            // then validate the headers, send them (using sendHeader) and 
-            // set the filters accordingly.
-            response.action(ActionCode.ACTION_COMMIT, null);
-
-        }
+    @Override
+    public void flush() throws IOException {
 
+        super.flush();
         // Flush the current buffer
         flushBuffer();
 
@@ -295,66 +150,15 @@
 
 
     /**
-     * Reset current response.
-     * 
-     * @throws IllegalStateException if the response has already been committed
-     */
-    public void reset() {
-
-        if (committed)
-            throw new IllegalStateException(/*FIXME:Put an error message*/);
-
-        // Recycle Request object
-        response.recycle();
-    }
-
-
-    /**
      * Recycle the output buffer. This should be called when closing the 
      * connection.
      */
+    @Override
     public void recycle() {
-        // Recycle filters
-        for (int i = 0; i <= lastActiveFilter; i++) {
-            activeFilters[i].recycle();
-        }
-
-        // Recycle Request object
-        response.recycle();
+        super.recycle();
         socket.getBufHandler().getWriteBuffer().clear();
-
         socket = null;
-        pos = 0;
-        lastActiveFilter = -1;
-        committed = false;
-        finished = false;
         lastWrite.set(1);
-
-    }
-
-
-    /**
-     * End processing of current HTTP request.
-     * Note: All bytes of the current request should have been already 
-     * consumed. This method only resets all the pointers so that we are ready
-     * to parse the next HTTP request.
-     */
-    public void nextRequest() {
-
-        // Recycle Request object
-        response.recycle();
-
-        // Recycle filters
-        for (int i = 0; i <= lastActiveFilter; i++) {
-            activeFilters[i].recycle();
-        }
-
-        // Reset pointers
-        pos = 0;
-        lastActiveFilter = -1;
-        committed = false;
-        finished = false;
-
     }
 
 
@@ -363,28 +167,10 @@
      * 
      * @throws IOException an undelying I/O error occured
      */
-    public void endRequest()
-        throws IOException {
-
-        if (!committed) {
-
-            // Send the connector a request for commit. The connector should
-            // then validate the headers, send them (using sendHeader) and 
-            // set the filters accordingly.
-            response.action(ActionCode.ACTION_COMMIT, null);
-
-        }
-
-        if (finished)
-            return;
-
-        if (lastActiveFilter != -1)
-            activeFilters[lastActiveFilter].end();
-
+    @Override
+    public void endRequest() throws IOException {
+        super.endRequest();
         flushBuffer();
-
-        finished = true;
-
     }
 
     public boolean isWritable() {
@@ -396,8 +182,7 @@
     /** 
      * Send an acknoledgement.
      */
-    public void sendAck()
-        throws IOException {
+    public void sendAck() throws IOException {
 
         if (!committed) {
             //Socket.send(socket, Constants.ACK_BYTES, 0, 
Constants.ACK_BYTES.length) < 0
@@ -443,145 +228,6 @@
     } 
 
 
-    /**
-     * Send the response status line.
-     */
-    public void sendStatus() {
-
-        // Write protocol name
-        write(Constants.HTTP_11_BYTES);
-        buf[pos++] = Constants.SP;
-
-        // Write status code
-        int status = response.getStatus();
-        switch (status) {
-        case 200:
-            write(Constants._200_BYTES);
-            break;
-        case 400:
-            write(Constants._400_BYTES);
-            break;
-        case 404:
-            write(Constants._404_BYTES);
-            break;
-        default:
-            write(status);
-        }
-
-        buf[pos++] = Constants.SP;
-
-        // Write message
-        String message = null;
-        if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER) {
-            message = response.getMessage();
-        }
-        if (message == null) {
-            write(HttpMessages.getMessage(status));
-        } else {
-            write(message.replace('\n', ' ').replace('\r', ' '));
-        }
-
-        // End the response status line
-        buf[pos++] = Constants.CR;
-        buf[pos++] = Constants.LF;
-
-    }
-
-
-    /**
-     * Send a header.
-     * 
-     * @param name Header name
-     * @param value Header value
-     */
-    public void sendHeader(MessageBytes name, MessageBytes value) {
-
-        write(name);
-        buf[pos++] = Constants.COLON;
-        buf[pos++] = Constants.SP;
-        write(value);
-        buf[pos++] = Constants.CR;
-        buf[pos++] = Constants.LF;
-
-    }
-
-
-    /**
-     * Send a header.
-     * 
-     * @param name Header name
-     * @param value Header value
-     */
-    public void sendHeader(ByteChunk name, ByteChunk value) {
-
-        write(name);
-        buf[pos++] = Constants.COLON;
-        buf[pos++] = Constants.SP;
-        write(value);
-        buf[pos++] = Constants.CR;
-        buf[pos++] = Constants.LF;
-
-    }
-
-
-    /**
-     * Send a header.
-     * 
-     * @param name Header name
-     * @param value Header value
-     */
-    public void sendHeader(String name, String value) {
-
-        write(name);
-        buf[pos++] = Constants.COLON;
-        buf[pos++] = Constants.SP;
-        write(value);
-        buf[pos++] = Constants.CR;
-        buf[pos++] = Constants.LF;
-
-    }
-
-
-    /**
-     * End the header block.
-     */
-    public void endHeaders() {
-
-        buf[pos++] = Constants.CR;
-        buf[pos++] = Constants.LF;
-
-    }
-
-
-    // --------------------------------------------------- OutputBuffer Methods
-
-
-    /**
-     * Write the contents of a byte chunk.
-     * 
-     * @param chunk byte chunk
-     * @return number of bytes written
-     * @throws IOException an undelying I/O error occured
-     */
-    public int doWrite(ByteChunk chunk, Response res) 
-        throws IOException {
-
-        if (!committed) {
-
-            // Send the connector a request for commit. The connector should
-            // then validate the headers, send them (using sendHeaders) and 
-            // set the filters accordingly.
-            response.action(ActionCode.ACTION_COMMIT, null);
-
-        }
-
-        if (lastActiveFilter == -1)
-            return outputStreamOutputBuffer.doWrite(chunk, res);
-        else
-            return activeFilters[lastActiveFilter].doWrite(chunk, res);
-
-    }
-
 
     // ------------------------------------------------------ Protected Methods
 
@@ -628,135 +274,6 @@
 
 
     /**
-     * This method will write the contents of the specyfied message bytes 
-     * buffer to the output stream, without filtering. This method is meant to
-     * be used to write the response header.
-     * 
-     * @param mb data to be written
-     */
-    protected void write(MessageBytes mb) {
-
-        if (mb.getType() == MessageBytes.T_BYTES) {
-            ByteChunk bc = mb.getByteChunk();
-            write(bc);
-        } else if (mb.getType() == MessageBytes.T_CHARS) {
-            CharChunk cc = mb.getCharChunk();
-            write(cc);
-        } else {
-            write(mb.toString());
-        }
-
-    }
-
-
-    /**
-     * This method will write the contents of the specyfied message bytes 
-     * buffer to the output stream, without filtering. This method is meant to
-     * be used to write the response header.
-     * 
-     * @param bc data to be written
-     */
-    protected void write(ByteChunk bc) {
-
-        // Writing the byte chunk to the output buffer
-        int length = bc.getLength();
-        System.arraycopy(bc.getBytes(), bc.getStart(), buf, pos, length);
-        pos = pos + length;
-
-    }
-
-
-    /**
-     * This method will write the contents of the specyfied char 
-     * buffer to the output stream, without filtering. This method is meant to
-     * be used to write the response header.
-     * 
-     * @param cc data to be written
-     */
-    protected void write(CharChunk cc) {
-
-        int start = cc.getStart();
-        int end = cc.getEnd();
-        char[] cbuf = cc.getBuffer();
-        for (int i = start; i < end; i++) {
-            char c = cbuf[i];
-            // Note:  This is clearly incorrect for many strings,
-            // but is the only consistent approach within the current
-            // servlet framework.  It must suffice until servlet output
-            // streams properly encode their output.
-            if ((c <= 31) && (c != 9)) {
-                c = ' ';
-            } else if (c == 127) {
-                c = ' ';
-            }
-            buf[pos++] = (byte) c;
-        }
-
-    }
-
-
-    /**
-     * This method will write the contents of the specyfied byte 
-     * buffer to the output stream, without filtering. This method is meant to
-     * be used to write the response header.
-     * 
-     * @param b data to be written
-     */
-    public void write(byte[] b) {
-
-        // Writing the byte chunk to the output buffer
-        System.arraycopy(b, 0, buf, pos, b.length);
-        pos = pos + b.length;
-
-    }
-
-
-    /**
-     * This method will write the contents of the specyfied String to the 
-     * output stream, without filtering. This method is meant to be used to 
-     * write the response header.
-     * 
-     * @param s data to be written
-     */
-    protected void write(String s) {
-
-        if (s == null)
-            return;
-
-        // From the Tomcat 3.3 HTTP/1.0 connector
-        int len = s.length();
-        for (int i = 0; i < len; i++) {
-            char c = s.charAt (i);
-            // Note:  This is clearly incorrect for many strings,
-            // but is the only consistent approach within the current
-            // servlet framework.  It must suffice until servlet output
-            // streams properly encode their output.
-            if ((c <= 31) && (c != 9)) {
-                c = ' ';
-            } else if (c == 127) {
-                c = ' ';
-            }
-            buf[pos++] = (byte) c;
-        }
-
-    }
-
-
-    /**
-     * This method will print the specified integer to the output stream, 
-     * without filtering. This method is meant to be used to write the 
-     * response header.
-     * 
-     * @param i data to be written
-     */
-    protected void write(int i) {
-
-        write(String.valueOf(i));
-
-    }
-
-
-    /**
      * Callback to write data from the buffer.
      */
     protected void flushBuffer()

Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java?rev=823608&r1=823607&r2=823608&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java Fri 
Oct  9 16:24:43 2009
@@ -19,27 +19,18 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.CharChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.HttpMessages;
-import org.apache.tomcat.util.http.MimeHeaders;
-import org.apache.tomcat.util.res.StringManager;
-
-import org.apache.coyote.ActionCode;
 import org.apache.coyote.OutputBuffer;
 import org.apache.coyote.Response;
+import org.apache.tomcat.util.buf.ByteChunk;
 
 /**
  * Output buffer.
  * 
  * @author <a href="mailto:r...@apache.org";>Remy Maucherat</a>
  */
-public class InternalOutputBuffer 
-    implements OutputBuffer, ByteChunk.ByteOutputChannel {
+public class InternalOutputBuffer extends AbstractOutputBuffer
+    implements ByteChunk.ByteOutputChannel {
 
     // -------------------------------------------------------------- Constants
 
@@ -80,56 +71,6 @@
 
     }
 
-
-    // -------------------------------------------------------------- Variables
-
-
-    /**
-     * The string manager for this package.
-     */
-    protected static StringManager sm =
-        StringManager.getManager(Constants.Package);
-
-
-    // ----------------------------------------------------- Instance Variables
-
-
-    /**
-     * Associated Coyote response.
-     */
-    protected Response response;
-
-
-    /**
-     * Headers of the associated request.
-     */
-    protected MimeHeaders headers;
-
-
-    /**
-     * Committed flag.
-     */
-    protected boolean committed;
-
-
-    /**
-     * Finished flag.
-     */
-    protected boolean finished;
-
-
-    /**
-     * The buffer used for header composition.
-     */
-    protected byte[] buf;
-
-
-    /**
-     * Position in the buffer.
-     */
-    protected int pos;
-
-
     /**
      * Underlying output stream.
      */
@@ -137,31 +78,6 @@
 
 
     /**
-     * Underlying output buffer.
-     */
-    protected OutputBuffer outputStreamOutputBuffer;
-
-
-    /**
-     * Filter library.
-     * Note: Filter[0] is always the "chunked" filter.
-     */
-    protected OutputFilter[] filterLibrary;
-
-
-    /**
-     * Active filter (which is actually the top of the pipeline).
-     */
-    protected OutputFilter[] activeFilters;
-
-
-    /**
-     * Index of the last active filter.
-     */
-    protected int lastActiveFilter;
-
-
-    /**
      * Socket buffer.
      */
     protected ByteChunk socketBuffer;
@@ -170,12 +86,8 @@
     /**
      * Socket buffer (extra buffering to reduce number of packets sent).
      */
-    protected boolean useSocketBuffer = false;
-
-
-    // ------------------------------------------------------------- Properties
-
-
+    protected boolean useSocketBuffer = false;    
+    
     /**
      * Set the underlying socket output stream.
      */
@@ -211,68 +123,9 @@
         }
 
     }
+    
 
 
-    /**
-     * Add an output filter to the filter library.
-     */
-    public void addFilter(OutputFilter filter) {
-
-        OutputFilter[] newFilterLibrary = 
-            new OutputFilter[filterLibrary.length + 1];
-        for (int i = 0; i < filterLibrary.length; i++) {
-            newFilterLibrary[i] = filterLibrary[i];
-        }
-        newFilterLibrary[filterLibrary.length] = filter;
-        filterLibrary = newFilterLibrary;
-
-        activeFilters = new OutputFilter[filterLibrary.length];
-
-    }
-
-
-    /**
-     * Get filters.
-     */
-    public OutputFilter[] getFilters() {
-
-        return filterLibrary;
-
-    }
-
-
-    /**
-     * Clear filters.
-     */
-    public void clearFilters() {
-
-        filterLibrary = new OutputFilter[0];
-        lastActiveFilter = -1;
-
-    }
-
-
-    /**
-     * Add an output filter to the filter library.
-     */
-    public void addActiveFilter(OutputFilter filter) {
-
-        if (lastActiveFilter == -1) {
-            filter.setBuffer(outputStreamOutputBuffer);
-        } else {
-            for (int i = 0; i <= lastActiveFilter; i++) {
-                if (activeFilters[i] == filter)
-                    return;
-            }
-            filter.setBuffer(activeFilters[lastActiveFilter]);
-        }
-
-        activeFilters[++lastActiveFilter] = filter;
-
-        filter.setResponse(response);
-
-    }
-
 
     // --------------------------------------------------------- Public Methods
 
@@ -280,20 +133,13 @@
     /**
      * Flush the response.
      * 
-     * @throws IOException an undelying I/O error occured
+     * @throws IOException an underlying I/O error occurred
      */
     public void flush()
         throws IOException {
 
-        if (!committed) {
-
-            // Send the connector a request for commit. The connector should
-            // then validate the headers, send them (using sendHeader) and 
-            // set the filters accordingly.
-            response.action(ActionCode.ACTION_COMMIT, null);
-
-        }
-
+        super.flush();
+        
         // Flush the current buffer
         if (useSocketBuffer) {
             socketBuffer.flushBuffer();
@@ -302,20 +148,7 @@
     }
 
 
-    /**
-     * Reset current response.
-     * 
-     * @throws IllegalStateException if the response has already been committed
-     */
-    public void reset() {
-
-        if (committed)
-            throw new IllegalStateException(/*FIXME:Put an error message*/);
-
-        // Recycle Request object
-        response.recycle();
-
-    }
+    
 
 
     /**
@@ -323,17 +156,9 @@
      * connection.
      */
     public void recycle() {
-
-        // Recycle Request object
-        response.recycle();
+        super.recycle();
         socketBuffer.recycle();
-
         outputStream = null;
-        pos = 0;
-        lastActiveFilter = -1;
-        committed = false;
-        finished = false;
-
     }
 
 
@@ -344,54 +169,22 @@
      * to parse the next HTTP request.
      */
     public void nextRequest() {
-
-        // Recycle Request object
-        response.recycle();
+        super.nextRequest();
         socketBuffer.recycle();
-
-        // Recycle filters
-        for (int i = 0; i <= lastActiveFilter; i++) {
-            activeFilters[i].recycle();
-        }
-
-        // Reset pointers
-        pos = 0;
-        lastActiveFilter = -1;
-        committed = false;
-        finished = false;
-
     }
 
 
     /**
      * End request.
      * 
-     * @throws IOException an undelying I/O error occured
+     * @throws IOException an underlying I/O error occurred
      */
     public void endRequest()
         throws IOException {
-
-        if (!committed) {
-
-            // Send the connector a request for commit. The connector should
-            // then validate the headers, send them (using sendHeader) and 
-            // set the filters accordingly.
-            response.action(ActionCode.ACTION_COMMIT, null);
-
-        }
-
-        if (finished)
-            return;
-
-        if (lastActiveFilter != -1)
-            activeFilters[lastActiveFilter].end();
-
+        super.endRequest();
         if (useSocketBuffer) {
             socketBuffer.flushBuffer();
         }
-
-        finished = true;
-
     }
 
 
@@ -410,156 +203,6 @@
     }
 
 
-    /**
-     * Send the response status line.
-     */
-    public void sendStatus() {
-
-        // Write protocol name
-        write(Constants.HTTP_11_BYTES);
-        buf[pos++] = Constants.SP;
-
-        // Write status code
-        int status = response.getStatus();
-        switch (status) {
-        case 200:
-            write(Constants._200_BYTES);
-            break;
-        case 400:
-            write(Constants._400_BYTES);
-            break;
-        case 404:
-            write(Constants._404_BYTES);
-            break;
-        default:
-            write(status);
-        }
-
-        buf[pos++] = Constants.SP;
-
-        // Write message
-        String message = null;
-        if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER) {
-            message = response.getMessage();
-        }
-        if (message == null) {
-            write(HttpMessages.getMessage(status)); 
-        } else {
-            write(message.replace('\n', ' ').replace('\r', ' '));
-        }
-
-        // End the response status line
-        if (org.apache.coyote.Constants.IS_SECURITY_ENABLED){
-           AccessController.doPrivileged(
-                new PrivilegedAction<Void>(){
-                    public Void run(){
-                        buf[pos++] = Constants.CR;
-                        buf[pos++] = Constants.LF;
-                        return null;
-                    }
-                }
-           );
-        } else {
-            buf[pos++] = Constants.CR;
-            buf[pos++] = Constants.LF;
-        }
-
-    }
-
-    /**
-     * Send a header.
-     * 
-     * @param name Header name
-     * @param value Header value
-     */
-    public void sendHeader(MessageBytes name, MessageBytes value) {
-
-        write(name);
-        buf[pos++] = Constants.COLON;
-        buf[pos++] = Constants.SP;
-        write(value);
-        buf[pos++] = Constants.CR;
-        buf[pos++] = Constants.LF;
-
-    }
-
-
-    /**
-     * Send a header.
-     * 
-     * @param name Header name
-     * @param value Header value
-     */
-    public void sendHeader(ByteChunk name, ByteChunk value) {
-
-        write(name);
-        buf[pos++] = Constants.COLON;
-        buf[pos++] = Constants.SP;
-        write(value);
-        buf[pos++] = Constants.CR;
-        buf[pos++] = Constants.LF;
-
-    }
-
-
-    /**
-     * Send a header.
-     * 
-     * @param name Header name
-     * @param value Header value
-     */
-    public void sendHeader(String name, String value) {
-
-        write(name);
-        buf[pos++] = Constants.COLON;
-        buf[pos++] = Constants.SP;
-        write(value);
-        buf[pos++] = Constants.CR;
-        buf[pos++] = Constants.LF;
-
-    }
-
-
-    /**
-     * End the header block.
-     */
-    public void endHeaders() {
-
-        buf[pos++] = Constants.CR;
-        buf[pos++] = Constants.LF;
-
-    }
-
-
-    // --------------------------------------------------- OutputBuffer Methods
-
-
-    /**
-     * Write the contents of a byte chunk.
-     * 
-     * @param chunk byte chunk
-     * @return number of bytes written
-     * @throws IOException an undelying I/O error occured
-     */
-    public int doWrite(ByteChunk chunk, Response res) 
-        throws IOException {
-
-        if (!committed) {
-
-            // Send the connector a request for commit. The connector should
-            // then validate the headers, send them (using sendHeaders) and 
-            // set the filters accordingly.
-            response.action(ActionCode.ACTION_COMMIT, null);
-
-        }
-
-        if (lastActiveFilter == -1)
-            return outputStreamOutputBuffer.doWrite(chunk, res);
-        else
-            return activeFilters[lastActiveFilter].doWrite(chunk, res);
-
-    }
-
 
     // ------------------------------------------------------ Protected Methods
 
@@ -588,134 +231,7 @@
     }
 
 
-    /**
-     * This method will write the contents of the specyfied message bytes 
-     * buffer to the output stream, without filtering. This method is meant to
-     * be used to write the response header.
-     * 
-     * @param mb data to be written
-     */
-    protected void write(MessageBytes mb) {
-
-        if (mb.getType() == MessageBytes.T_BYTES) {
-            ByteChunk bc = mb.getByteChunk();
-            write(bc);
-        } else if (mb.getType() == MessageBytes.T_CHARS) {
-            CharChunk cc = mb.getCharChunk();
-            write(cc);
-        } else {
-            write(mb.toString());
-        }
-
-    }
-
-
-    /**
-     * This method will write the contents of the specyfied message bytes 
-     * buffer to the output stream, without filtering. This method is meant to
-     * be used to write the response header.
-     * 
-     * @param bc data to be written
-     */
-    protected void write(ByteChunk bc) {
-
-        // Writing the byte chunk to the output buffer
-        int length = bc.getLength();
-        System.arraycopy(bc.getBytes(), bc.getStart(), buf, pos, length);
-        pos = pos + length;
-
-    }
-
-
-    /**
-     * This method will write the contents of the specyfied char 
-     * buffer to the output stream, without filtering. This method is meant to
-     * be used to write the response header.
-     * 
-     * @param cc data to be written
-     */
-    protected void write(CharChunk cc) {
-
-        int start = cc.getStart();
-        int end = cc.getEnd();
-        char[] cbuf = cc.getBuffer();
-        for (int i = start; i < end; i++) {
-            char c = cbuf[i];
-            // Note:  This is clearly incorrect for many strings,
-            // but is the only consistent approach within the current
-            // servlet framework.  It must suffice until servlet output
-            // streams properly encode their output.
-            if ((c <= 31) && (c != 9)) {
-                c = ' ';
-            } else if (c == 127) {
-                c = ' ';
-            }
-            buf[pos++] = (byte) c;
-        }
-
-    }
-
-
-    /**
-     * This method will write the contents of the specyfied byte 
-     * buffer to the output stream, without filtering. This method is meant to
-     * be used to write the response header.
-     * 
-     * @param b data to be written
-     */
-    public void write(byte[] b) {
-
-        // Writing the byte chunk to the output buffer
-        System.arraycopy(b, 0, buf, pos, b.length);
-        pos = pos + b.length;
-
-    }
-
-
-    /**
-     * This method will write the contents of the specyfied String to the 
-     * output stream, without filtering. This method is meant to be used to 
-     * write the response header.
-     * 
-     * @param s data to be written
-     */
-    protected void write(String s) {
-
-        if (s == null)
-            return;
-
-        // From the Tomcat 3.3 HTTP/1.0 connector
-        int len = s.length();
-        for (int i = 0; i < len; i++) {
-            char c = s.charAt (i);
-            // Note:  This is clearly incorrect for many strings,
-            // but is the only consistent approach within the current
-            // servlet framework.  It must suffice until servlet output
-            // streams properly encode their output.
-            if ((c <= 31) && (c != 9)) {
-                c = ' ';
-            } else if (c == 127) {
-                c = ' ';
-            }
-            buf[pos++] = (byte) c;
-        }
-
-    }
-
-
-    /**
-     * This method will print the specified integer to the output stream, 
-     * without filtering. This method is meant to be used to write the 
-     * response header.
-     * 
-     * @param i data to be written
-     */
-    protected void write(int i) {
-
-        write(String.valueOf(i));
-
-    }
-
+ 
 
     /**
      * Callback to write data from the buffer.



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to