Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
   *
   * The contents of this file are subject to the terms of either the GNU
   * General Public License Version 2 only ("GPL") or the Common Development
   * and Distribution License("CDDL") (collectively, the "License").  You
   * may not use this file except in compliance with the License. You can obtain
  * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
  * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
  * language governing permissions and limitations under the License.
  *
  * When distributing the software, include this License Header Notice in each
  * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
  * Sun designates this particular file as subject to the "Classpath" exception
  * as provided by Sun in the GPL Version 2 section of the License file that
  * accompanied this code.  If applicable, add the following below the License
  * Header, with the fields enclosed by brackets [] replaced by your own
  * identifying information: "Portions Copyrighted [year]
  * [name of copyright owner]"
  *
  * Contributor(s):
  *
  * If you wish your version of this file to be governed by only the CDDL or
  * only the GPL Version 2, indicate your decision by adding "[Contributor]
  * elects to include this software in this distribution under the [CDDL or GPL
  * Version 2] license."  If you don't indicate a single choice of license, a
  * recipient has the option to distribute your version of this file under
  * either the CDDL, the GPL Version 2 or to extend the choice of license to
  * its licensees as provided above.  However, if you add GPL Version 2 code
  * and therefore, elected the GPL Version 2 license, then the option applies
  * only if the new code is made subject to such option by the copyright
  * holder.
  *
  *
  * This file incorporates work covered by the following copyright and
  * permission notice:
  *
  * Copyright 2004 The Apache Software Foundation
  *
  * Licensed 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;
 
 
 
Implementation of InputBuffer which provides HTTP request header parsing as well as transfer decoding.

Author(s):
Remy Maucherat
 
 public class InternalInputBuffer implements InputBuffer {
 
 
     // -------------------------------------------------------------- Constants
 
 
     // ----------------------------------------------------------- Constructors
     
Void constructor.
 
     public InternalInputBuffer() {
        ;
     }

    
Default constructor.
 
     public InternalInputBuffer(Request request) {
         this(request.);
     }


    
Alternate constructor.
    public InternalInputBuffer(Request requestint headerBufferSize) {
        this. = request;
         = request.getMimeHeaders();
         = new byte[headerBufferSize];
         = new InputFilter[0];
         = new InputFilter[0];
         = -1;
         = true;
         = true;
    }
    // -------------------------------------------------------------- Variables


    
The string manager for this package.
    protected static final StringManager sm =
        StringManager.getManager(.);
    // ----------------------------------------------------- Instance Variables


    
Associated Coyote request.
    protected Request request;


    
Headers of the associated request.
    protected MimeHeaders headers;


    
State.
    protected boolean parsingHeader;


    
Swallow input ? (in the case of an expectation)
    protected boolean swallowInput;


    
Pointer to the current read buffer.
    protected byte[] buf;


    
Last valid byte.
    protected int lastValid;


    
Position in the buffer.
    protected int pos;
    
    /*
     * Pos of the end of the header in the buffer, which is also the
     * start of the body.
     **/
    protected int end;

    
Underlying input stream.
    protected InputStream inputStream;


    
Underlying input buffer.
    protected InputBuffer inputStreamInputBuffer;


    
Filter library. Note: Filter[0] is always the "chunked" filter.
    protected InputFilter[] filterLibrary;


    
Active filters (in order).
    protected InputFilter[] activeFilters;


    
Index of the last active filter.
    protected int lastActiveFilter;
    // START OF SJSAS 6231069
    
The stage we currently are during parsing the request line and the headers
 
    private int stage = 0;
    
    private MessageBytes headerValue = null;
    
    // END OF SJSAS 6231069
    
    // ------------------------------------------------------------- Properties


    
Set the underlying socket input stream.
    public void setInputStream(InputStream inputStream) {
        // FIXME: Check for null ?
        this. = inputStream;
    }


    
Get the underlying socket input stream.
    public InputStream getInputStream() {
        return ;
    }


    
Add an input filter to the filter library.
    public void addFilter(InputFilter filter) {
        // FIXME: Check for null ?
        InputFilter[] newFilterLibrary = 
            new InputFilter[. + 1];
        for (int i = 0; i < .i++) {
            newFilterLibrary[i] = [i];
        }
        newFilterLibrary[.] = filter;
         = newFilterLibrary;
    }


    
Get filters.
    public InputFilter[] getFilters() {
        return ;
    }


    
Clear filters.
    public void clearFilters() {
         = new InputFilter[0];
         = -1;
    }


    
Add an input filter to the filter library.
    public void addActiveFilter(InputFilter filter) {
        if ( == -1) {
            filter.setBuffer();
        } else {
            for (int i = 0; i <= i++) {
                if ([i] == filter)
                    return;
            }
            filter.setBuffer([]);
        }
        [++] = filter;
        filter.setRequest();
    }


    
Set the swallow input flag.
    public void setSwallowInput(boolean swallowInput) {
        this. = swallowInput;
    }
    // --------------------------------------------------------- Public Methods


    
Recycle the input buffer. This should be called when closing the connection.
    public void recycle() {
        // Recycle Request object
        .recycle();
         = null;
         = 0;
         = 0;
         = -1;
         = true;
         = true;
    }


    
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
        .recycle();
        // Determine the header buffer used for next request
        byte[] newHeaderBuf = null;
        // Copy leftover bytes to the beginning of the buffer
        if ( -  > 0) {
            int npos = 0;
            int opos = ;
            while ( - opos > opos - npos) {
                System.arraycopy(oposnposopos - npos);
                npos += ;
                opos += ;
            }
            System.arraycopy(oposnpos - opos);
        }
        // Recycle filters
        for (int i = 0; i <= i++) {
            [i].recycle();
        }
        // Reset pointers
         =  - ;
         = 0;
         = -1;
         = true;
         = true;
    }


    
End request (consumes leftover bytes).

Throws:
java.io.IOException an undelying I/O error occured
    public void endRequest()
        throws IOException {
        if ( && ( != -1)) {
            int extraBytes = (int[].end();
             =  - extraBytes;
        }
    }

    
    
Read the request line. This function is meant to be used during the HTTP request header parsing. Do NOT attempt to read the request body using it.

Throws:
java.io.IOException If an exception occurs during the underlying socket read operations, or if the given buffer is not big enough to accomodate the whole line.
    public void parseRequestLine()
        throws IOException {
        
        int start = 0;
        // END OF SJSAS 6231069
            
        byte chr = 0;
        do {
            // Read new bytes if needed
            if ( >= ) {
                if (!fill())
                    throw new EOFException(.getString("iib.eof.error"));
            }
            chr = [++];
        } while ((chr == .) || (chr == .));
        --;
        // Mark the current buffer position
        start = ;
        //
        // Reading the method name
        // Method name is always US-ASCII
        //
        boolean space = false;
        while (!space) {
            // Read new bytes if needed
            if ( >= ) {
                if (!fill())
                    throw new EOFException(.getString("iib.eof.error"));
            }
            if ([] == .) {
                space = true;
                .method().setBytes(start - start);
            }
            ++;
        }
       
        // Mark the current buffer position
        start = ;
        int end = 0;
        int questionPos = -1;
        //
        // Reading the URI
        //
        space = false;
        boolean eol = false;
        while (!space) {
            // Read new bytes if needed
            if ( >= ) {
                if (!fill())
                    throw new EOFException(.getString("iib.eof.error"));
            }
            if ([] == .) {
                space = true;
                end = ;
            } else if (([] == .
                       || ([] == .)) {
                // HTTP/0.9 style request
                eol = true;
                space = true;
                end = ;
            } else if (([] == .
                       && (questionPos == -1)) {
                questionPos = ;
            }
            ++;
        }
        
        .unparsedURI().setBytes(startend - start);
        if (questionPos >= 0) {
            .queryString().setBytes(questionPos + 1, 
                                           end - questionPos - 1);
            .requestURI().setBytes(startquestionPos - start);
        } else {
            .requestURI().setBytes(startend - start);
        }
        // Mark the current buffer position
        start = ;
        end = 0;
        //
        // Reading the protocol
        // Protocol is always US-ASCII
        //   
        while (!eol) {
            // Read new bytes if needed
            if ( >= ) {
                if (!fill())
                    throw new EOFException(.getString("iib.eof.error"));
            }
            if ([] == .) {
                end = ;
            } else if ([] == .) {
                if (end == 0)
                    end = ;
                eol = true;
            }
            ++;
        }
           
        if ((end - start) > 0) {
            .protocol().setBytes(startend - start);
        } else {
            .protocol().setString("");
        }
    }


    
Parse the HTTP headers.
    public void parseHeaders()
        throws IOException {
        while (parseHeader()) {
        }
         = false;
         = ;
    }


    
Parse an HTTP header.

Returns:
false after reading a blank line (which indicates that the HTTP header parsing is done
    public boolean parseHeader()
        throws IOException {
        //
        // Check for blank line
        //
        byte chr = 0;             
        while (true) {
            // Read new bytes if needed
            if ( >= ) {
                if (!fill())
                    throw new EOFException(.getString("iib.eof.error"));
            }
            chr = [];
            if ((chr == .) || (chr == .)) {
                if (chr == .) {
                    ++;        
                    return false;
                }
            } else {
                break;
            }
            ++;
        }
        
        // Mark the current buffer position
        int start = ;
        //
        // Reading the header name
        // Header name is always US-ASCII
        //
        boolean colon = false;
        //MessageBytes headerValue = null;
   
        while (!colon) {
            // Read new bytes if needed
            if ( >= ) {
                if (!fill())
                    throw new EOFException(.getString("iib.eof.error"));
            }
            if ([] == .) {
                colon = true;
                 = .addValue(start - start);
            }
            chr = [];
            if ((chr >= .) && (chr <= .)) {
                [] = (byte) (chr - .);
            }
            ++;
        } 
        
        // Mark the current buffer position
        start = ;
        int realPos = ;
        //
        // Reading the header value (which can be spanned over multiple lines)
        //
        boolean eol = false;
        boolean validLine = true;
        while (validLine) {
            boolean space = true;  
            // Skipping spaces
            while (space) {
                // Read new bytes if needed
                if ( >= ) {
                    if (!fill())
                        throw new EOFException(.getString("iib.eof.error"));
                }
                if (([] == .) || ([] == .)) {
                    ++;
                } else {
                    space = false;
                }
            }
            
            int lastSignificantChar = realPos;                 
            // Reading bytes until the end of the line
            while (!eol) {
                // Read new bytes if needed
                if ( >= ) {
                    if (!fill())
                        throw new EOFException(.getString("iib.eof.error"));
                }
                if ([] == .) {
                } else if ([] == .) {
                    eol = true;
                } else if ([] == .) {
                    [realPos] = [];
                    realPos++;
                } else {
                    [realPos] = [];
                    realPos++;
                    lastSignificantChar = realPos;
                }
                ++;
            }
            realPos = lastSignificantChar;        
            // Checking the first character of the new line. If the character
            // is a LWS, then it's a multiline header
            // Read new bytes if needed
            if ( >= ) {
                if (!fill())
                    throw new EOFException(.getString("iib.eof.error"));
            }
            chr = [];
            if ((chr != .) && (chr != .)) {
                validLine = false;
            } else {
                eol = false;
                // Copying one extra space in the buffer (since there must
                // be at least one space inserted between the lines)
                [realPos] = chr;
                realPos++;
            }
        }
        // Set the header value
        .setBytes(startrealPos - start);
        return true;
    }
    public int available() {
        return ;
    }
    // ---------------------------------------------------- InputBuffer Methods


    
Read some bytes.
    public int doRead(ByteChunk chunkRequest req
        throws IOException {
        if ( == -1)
            return .doRead(chunkreq);
        else
            return [].doRead(chunk,req);
    }
    // ------------------------------------------------------ Protected Methods


    
Fill the internal buffer using data from the undelying input stream.

Returns:
false if at end of stream
    protected boolean fill()
        throws IOException {
        int nRead = 0;
        if () {
            if ( == .) {
                throw new IllegalStateException
                    (.getString("iib.requestheadertoolarge.error"));
            }
            nRead = .read(. - );
            if (nRead > 0) {
                 =  + nRead;
            }
        } else {
            if (. -  < 4500) {
                // In this case, the request header was really large, so we allocate a 
                // brand new one; the old one will get GCed when subsequent requests
                // clear all references
                 = new byte[.];
                 = 0;
            }
             = ;
             = ;
            nRead = .read(. - );
            if (nRead > 0) {
                 =  + nRead;
            }
        }
        return (nRead > 0);
    }
    // ------------------------------------- InputStreamInputBuffer Inner Class


    
This class is an input buffer which will read its data from an input stream.
    protected class InputStreamInputBuffer 
        implements InputBuffer {


        
Read bytes into the specified chunk.
        public int doRead(ByteChunk chunkRequest req ) 
            throws IOException {
            if ( >= ) {
                if (!fill())
                    return -1;
            }
            int length =  - ;
            chunk.setBytes(length);
             = ;
            return (length);
        }
    }
New to GrepCode? Check out our FAQ X