remm        01/09/30 18:20:42

  Modified:    http11   .cvsignore
               http11/src/java/org/apache/coyote/http11 Constants.java
                        Http11Connector.java InternalOutputBuffer.java
  Log:
  - Implement the output.
  - The last parts to be written are the request processing itself, as well as some
    utility components (like the chunking filters).
  
  Revision  Changes    Path
  1.2       +2 -3      jakarta-tomcat-connectors/http11/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/http11/.cvsignore,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- .cvsignore        2001/09/17 06:04:00     1.1
  +++ .cvsignore        2001/10/01 01:20:42     1.2
  @@ -1,3 +1,2 @@
  -dist
  -build.properties
  -target
  \ No newline at end of file
  +build
  +build.properties
  \ No newline at end of file
  
  
  
  1.2       +6 -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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Constants.java    2001/09/17 06:04:00     1.1
  +++ Constants.java    2001/10/01 01:20:42     1.2
  @@ -137,4 +137,10 @@
       public static final int DEFAULT_HTTP_HEADER_BUFFER_SIZE = 128 * 1024;
   
   
  +    /**
  +     * CRLF.
  +     */
  +    public static final String CRLF = "\r\n";
  +
  +
   }
  
  
  
  1.2       +157 -1    
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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Http11Connector.java      2001/09/17 06:04:00     1.1
  +++ Http11Connector.java      2001/10/01 01:20:42     1.2
  @@ -84,6 +84,93 @@
   public class Http11Connector implements Connector, ActionHook {
   
   
  +    // ----------------------------------------------------------- Constructors
  +
  +
  +    /**
  +     * Default constructor.
  +     */
  +    public Http11Connector() {
  +
  +        request = new Request();
  +        inputBuffer = new InternalInputBuffer(request);
  +        request.setInputBuffer(inputBuffer);
  +
  +        response = new Response();
  +        response.setHook(this);
  +        outputBuffer = new InternalOutputBuffer(response);
  +        response.setOutputBuffer(outputBuffer);
  +
  +    }
  +
  +
  +    // ----------------------------------------------------- Instance Variables
  +
  +
  +    /**
  +     * Associated adapter.
  +     */
  +    protected Adapter adapter = null;
  +
  +
  +    /**
  +     * Request object.
  +     */
  +    protected Request request = null;
  +
  +
  +    /**
  +     * Response object.
  +     */
  +    protected Response response = null;
  +
  +
  +    /**
  +     * Input.
  +     */
  +    protected InternalInputBuffer inputBuffer = null;
  +
  +
  +    /**
  +     * Output.
  +     */
  +    protected InternalOutputBuffer outputBuffer = null;
  +
  +
  +    // --------------------------------------------------------- Public Methods
  +
  +
  +    /**
  +     * Process pipelined HTTP requests using the specified input and output
  +     * streams.
  +     * 
  +     * @param inputStream stream from which the HTTP requests will be read
  +     * @param outputStream stream which will be used to output the HTTP 
  +     * responses
  +     * @throws IOException error during an I/O operation
  +     */
  +    public void process(InputStream input, OutputStream output)
  +        throws IOException {
  +
  +        // Setting up the I/O
  +        inputBuffer.setInputStream(input);
  +        outputBuffer.setOutputStream(output);
  +
  +
  +
  +
  +        try {
  +            adapter.service(request, response);
  +        } catch (Exception e) {
  +            ;
  +        }
  +
  +
  +
  +
  +    }
  +
  +
       // ----------------------------------------------------- ActionHook Methods
   
   
  @@ -94,18 +181,87 @@
        * @param param Action parameter
        */
       public void action(ActionCode actionCode, Object param) {
  +
  +        if (actionCode == ActionCode.ACTION_COMMIT) {
  +
  +            // Commit current response
  +
  +            // Validate and write response headers
  +            prepareResponse();
  +
  +        } else if (actionCode == ActionCode.ACTION_ACK) {
  +
  +            // Acknowlege request
  +
  +            // Send a 100 status back if it makes sense (response not committed
  +            // yet, and client specified an expectation for 100-continue)
  +
  +        } else if (actionCode == ActionCode.ACTION_CLOSE) {
  +
  +            // Close
  +
  +            // End the processing of the current request, and stop any further
  +            // transactions with the client
  +
  +        } else if (actionCode == ActionCode.ACTION_RESET) {
  +
  +            // Reset response
  +
  +            // Note: This must be called before the response is committed
  +
  +        } else if (actionCode == ActionCode.ACTION_CUSTOM) {
  +
  +            // Do nothing
  +
  +        }
  +
       }
   
   
       // ------------------------------------------------------ Connector Methods
   
   
  +    /**
  +     * Set the associated adapter.
  +     * 
  +     * @param adapter the new adapter
  +     */
       public void setAdapter(Adapter adapter) {
  +        this.adapter = adapter;
       }
   
   
  +    /**
  +     * Get the associated adapter.
  +     * 
  +     * @return the associated adapter
  +     */
       public Adapter getAdapter() {
  -        return null;
  +        return adapter;
  +    }
  +
  +
  +    // ------------------------------------------------------ Protected Methods
  +
  +
  +    /**
  +     * After reading the request headers, we have to setup the request filters.
  +     */
  +    protected void prepareRequest() {
  +
  +
  +
  +    }
  +
  +
  +    /**
  +     * When committing the response, we have to validate the set of headers, as
  +     * well as setup the response filters.
  +     */
  +    protected void prepareResponse() {
  +
  +
  +
       }
   
   
  
  
  
  1.2       +233 -24   
jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/InternalOutputBuffer.java
  
  Index: InternalOutputBuffer.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/InternalOutputBuffer.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- InternalOutputBuffer.java 2001/09/17 06:04:00     1.1
  +++ InternalOutputBuffer.java 2001/10/01 01:20:42     1.2
  @@ -64,9 +64,11 @@
   
   import org.apache.tomcat.util.buf.ByteChunk;
   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;
   
  @@ -149,12 +151,6 @@
   
   
       /**
  -     * Last valid byte.
  -     */
  -    protected int lastValid;
  -
  -
  -    /**
        * Position in the buffer.
        */
       protected int pos;
  @@ -289,7 +285,6 @@
   
           outputStream = null;
           buf = headerBuffer;
  -        lastValid = 0;
           pos = 0;
           lastActiveFilter = 0;
           committed = false;
  @@ -304,8 +299,7 @@
        * consumed. This method only resets all the pointers so that we are ready
        * to parse the next HTTP request.
        */
  -    public void nextRequest()
  -        throws IOException {
  +    public void nextRequest() {
   
           // FIXME: Recycle Response object (or do it elsewhere) ?
   
  @@ -320,7 +314,6 @@
           }
   
           // Reset pointers
  -        lastValid = 0;
           pos = 0;
           lastActiveFilter = 0;
           committed = false;
  @@ -330,23 +323,23 @@
   
   
       /**
  -     * Send response header.
  +     * End request.
  +     * 
  +     * @throws IOException an undelying I/O error occured
        */
  -    public void sendHeader()
  +    public void endRequest()
           throws IOException {
   
  -        // FIXME
  +        if (!committed) {
   
  -        committed = true;
  -
  -    }
  +            // 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);
   
  +            commit();
   
  -    /**
  -     * End request.
  -     */
  -    public void endRequest()
  -        throws IOException {
  +        }
   
           if (lastActiveFilter > 0) {
               // Parsing through the filter list
  @@ -355,22 +348,133 @@
               }
           }
   
  -        if (closeChunk.getLength() > 0)
  +        if (closeChunk.getLength() > 0) {
               outputStream.write(closeChunk.getBytes(), closeChunk.getStart(), 
                                  closeChunk.getLength());
  +            outputStream.flush();
  +        }
  +
  +    }
  +
  +
  +    // ------------------------------------------------ HTTP/1.1 Output Methods
  +
  +
  +    /**
  +     * Send the response status line.
  +     */
  +    public void sendStatus() {
  +
  +        // Write protocol name
  +        write("HTTP/1.1 ");
   
  +        // Write status code
  +        int status = response.getStatus();
  +     switch (status) {
  +     case 200:
  +            write("200");
  +         break;
  +     case 400:
  +            write("400");
  +         break;
  +     case 404:
  +            write("404");
  +         break;
  +        default:
  +         write(status);
  +     }
  +
  +        // Write message
  +        write(HttpMessages.getMessage(status));
  +
  +        // End the response status line
  +        write(Constants.CRLF);
  +
  +    }
  +
  +
  +    /**
  +     * Send a header.
  +     * 
  +     * @param name Header name
  +     * @param value Header value
  +     */
  +    public void sendHeader(MessageBytes name, MessageBytes value) {
  +
  +        write(name);
  +        write(": ");
  +        write(value);
  +        write(Constants.CRLF);
  +
  +    }
  +
  +
  +    /**
  +     * Send a header.
  +     * 
  +     * @param name Header name
  +     * @param value Header value
  +     */
  +    public void sendHeader(ByteChunk name, ByteChunk value) {
  +
  +        write(name);
  +        write(": ");
  +        write(value);
  +        write(Constants.CRLF);
  +
       }
   
   
  +    /**
  +     * Send a header.
  +     * 
  +     * @param name Header name
  +     * @param value Header value
  +     */
  +    public void sendHeader(String name, String value) {
  +
  +        write(name);
  +        write(": ");
  +        write(value);
  +        write(Constants.CRLF);
  +
  +    }
  +
  +
  +    /**
  +     * End the header block.
  +     */
  +    public void endHeaders() {
  +
  +        write(Constants.CRLF);
  +
  +    }
  +
  +
       // --------------------------------------------------- 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) 
           throws IOException {
   
  -        if (!committed)
  -            sendHeader();
  +        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);
  +
  +            commit();
  +
  +        }
  +
           int n = -1;
   
           if (lastActiveFilter > 0) {
  @@ -384,6 +488,111 @@
                              chunk.getLength());
   
           return n;
  +
  +    }
  +
  +
  +    // ------------------------------------------------------ Protected Methods
  +
  +
  +    /**
  +     * Commit the response.
  +     * 
  +     * @throws IOException an undelying I/O error occured
  +     */
  +    protected void commit()
  +        throws IOException {
  +
  +        if (pos > 0) {
  +            // Sending the response header buffer
  +            outputStream.write(buf, 0, pos);
  +            outputStream.flush(); // Is it really necessary ?
  +        }
  +
  +        // The response is now committed
  +        committed = true;
  +        response.setCommitted(true);
  +
  +    }
  +
  +
  +    /**
  +     * 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) {
  +
  +        mb.toBytes();
  +        ByteChunk bc = mb.getByteChunk();
  +        if (!bc.isNull()) {
  +            // Writing the byte chunk to the output buffer
  +            write(bc);
  +        } else {
  +            // Using toString
  +            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
  +        System.arraycopy(bc.getBytes(), bc.getStart(), buf, pos,
  +                         bc.getLength());
  +        pos = pos + bc.getLength();
  +
  +    }
  +
  +
  +    /**
  +     * 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) {
  +
  +        // 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 & 0xff00) != 0) {
  +                // High order byte must be zero
  +                //log("Header character is not iso8859_1, " +
  +                //"not supported yet: " + c, Log.ERROR ) ;
  +            }
  +            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));
   
       }
   
  
  
  


Reply via email to