FileDocCategorySizeDatePackage
BasicLineParser.javaAPI DocAndroid 1.5 API16795Wed May 06 22:41:10 BST 2009org.apache.http.message

BasicLineParser

public class BasicLineParser extends Object implements LineParser
Basic parser for lines in the head section of an HTTP message. There are individual methods for parsing a request line, a status line, or a header line. The lines to parse are passed in memory, the parser does not depend on any specific IO mechanism. Instances of this class are stateless and thread-safe. Derived classes MUST maintain these properties.

Note: This class was created by refactoring parsing code located in various other classes. The author tags from those other classes have been replicated here, although the association with the parsing code taken from there has not been traced.

author
Jeff Dever
author
Mike Bowler
author
Oleg Kalnichevski
author
and others

Fields Summary
public static final BasicLineParser
DEFAULT
A default instance of this class, for use as default or fallback. Note that {@link BasicLineParser} is not a singleton, there can be many instances of the class itself and of derived classes. The instance here provides non-customized, default behavior.
protected final ProtocolVersion
protocol
A version of the protocol to parse. The version is typically not relevant, but the protocol name.
Constructors Summary
public BasicLineParser(ProtocolVersion proto)
Creates a new line parser for the given HTTP-like protocol.

param
proto a version of the protocol to parse, or null for HTTP. The actual version is not relevant, only the protocol name.



                                                                                
       
        if (proto == null) {
            proto = HttpVersion.HTTP_1_1;
        }
        this.protocol = proto;
    
public BasicLineParser()
Creates a new line parser for HTTP.

        this(null);
    
Methods Summary
protected org.apache.http.ProtocolVersioncreateProtocolVersion(int major, int minor)
Creates a protocol version. Called from {@link #parseProtocolVersion}.

param
major the major version number, for example 1 in HTTP/1.0
param
minor the minor version number, for example 0 in HTTP/1.0
return
the protocol version

        return protocol.forVersion(major, minor);
    
protected org.apache.http.RequestLinecreateRequestLine(java.lang.String method, java.lang.String uri, org.apache.http.ProtocolVersion ver)
Instantiates a new request line. Called from {@link #parseRequestLine}.

param
method the request method
param
uri the requested URI
param
ver the protocol version
return
a new status line with the given data

        return new BasicRequestLine(method, uri, ver);
    
protected org.apache.http.StatusLinecreateStatusLine(org.apache.http.ProtocolVersion ver, int status, java.lang.String reason)
Instantiates a new status line. Called from {@link #parseStatusLine}.

param
ver the protocol version
param
status the status code
param
reason the reason phrase
return
a new status line with the given data

        return new BasicStatusLine(ver, status, reason);
    
public booleanhasProtocolVersion(org.apache.http.util.CharArrayBuffer buffer, org.apache.http.message.ParserCursor cursor)


        if (buffer == null) {
            throw new IllegalArgumentException("Char array buffer may not be null");
        }
        if (cursor == null) {
            throw new IllegalArgumentException("Parser cursor may not be null");
        }
        int index = cursor.getPos();

        final String protoname = this.protocol.getProtocol();
        final int  protolength = protoname.length();

        if (buffer.length() < protolength+4)
            return false; // not long enough for "HTTP/1.1"

        if (index < 0) {
            // end of line, no tolerance for trailing whitespace
            // this works only for single-digit major and minor version
            index = buffer.length() -4 -protolength;
        } else if (index == 0) {
            // beginning of line, tolerate leading whitespace
            while ((index < buffer.length()) &&
                    HTTP.isWhitespace(buffer.charAt(index))) {
                 index++;
             }
        } // else within line, don't tolerate whitespace


        if (index + protolength + 4 > buffer.length())
            return false;


        // just check protocol name and slash, no need to analyse the version
        boolean ok = true;
        for (int j=0; ok && (j<protolength); j++) {
            ok = (buffer.charAt(index+j) == protoname.charAt(j));
        }
        if (ok) {
            ok = (buffer.charAt(index+protolength) == '/");
        }

        return ok;
    
public static final org.apache.http.HeaderparseHeader(java.lang.String value, org.apache.http.message.LineParser parser)


        if (value == null) {
            throw new IllegalArgumentException
                ("Value to parse may not be null");
        }

        if (parser == null)
            parser = BasicLineParser.DEFAULT;

        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
        buffer.append(value);
        return parser.parseHeader(buffer);
    
public org.apache.http.HeaderparseHeader(org.apache.http.util.CharArrayBuffer buffer)


        // the actual parser code is in the constructor of BufferedHeader
        return new BufferedHeader(buffer);
    
public static final org.apache.http.ProtocolVersionparseProtocolVersion(java.lang.String value, org.apache.http.message.LineParser parser)


        if (value == null) {
            throw new IllegalArgumentException
                ("Value to parse may not be null.");
        }

        if (parser == null)
            parser = BasicLineParser.DEFAULT;

        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
        buffer.append(value);
        ParserCursor cursor = new ParserCursor(0, value.length());
        return parser.parseProtocolVersion(buffer, cursor);
    
public org.apache.http.ProtocolVersionparseProtocolVersion(org.apache.http.util.CharArrayBuffer buffer, org.apache.http.message.ParserCursor cursor)


        if (buffer == null) {
            throw new IllegalArgumentException("Char array buffer may not be null");
        }
        if (cursor == null) {
            throw new IllegalArgumentException("Parser cursor may not be null");
        }

        final String protoname = this.protocol.getProtocol();
        final int protolength  = protoname.length();

        int indexFrom = cursor.getPos();
        int indexTo = cursor.getUpperBound();
        
        skipWhitespace(buffer, cursor);

        int i = cursor.getPos();
        
        // long enough for "HTTP/1.1"?
        if (i + protolength + 4 > indexTo) {
            throw new ParseException
                ("Not a valid protocol version: " +
                 buffer.substring(indexFrom, indexTo));
        }

        // check the protocol name and slash
        boolean ok = true;
        for (int j=0; ok && (j<protolength); j++) {
            ok = (buffer.charAt(i+j) == protoname.charAt(j));
        }
        if (ok) {
            ok = (buffer.charAt(i+protolength) == '/");
        }
        if (!ok) {
            throw new ParseException
                ("Not a valid protocol version: " +
                 buffer.substring(indexFrom, indexTo));
        }

        i += protolength+1;

        int period = buffer.indexOf('.", i, indexTo);
        if (period == -1) {
            throw new ParseException
                ("Invalid protocol version number: " + 
                 buffer.substring(indexFrom, indexTo));
        }
        int major;
        try {
            major = Integer.parseInt(buffer.substringTrimmed(i, period)); 
        } catch (NumberFormatException e) {
            throw new ParseException
                ("Invalid protocol major version number: " + 
                 buffer.substring(indexFrom, indexTo));
        }
        i = period + 1;
        
        int blank = buffer.indexOf(' ", i, indexTo);
        if (blank == -1) {
            blank = indexTo;
        }
        int minor;
        try {
            minor = Integer.parseInt(buffer.substringTrimmed(i, blank)); 
        } catch (NumberFormatException e) {
            throw new ParseException(
                "Invalid protocol minor version number: " + 
                buffer.substring(indexFrom, indexTo));
        }
        
        cursor.updatePos(blank);

        return createProtocolVersion(major, minor);

    
public static final org.apache.http.RequestLineparseRequestLine(java.lang.String value, org.apache.http.message.LineParser parser)


        if (value == null) {
            throw new IllegalArgumentException
                ("Value to parse may not be null.");
        }

        if (parser == null)
            parser = BasicLineParser.DEFAULT;

        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
        buffer.append(value);
        ParserCursor cursor = new ParserCursor(0, value.length());
        return parser.parseRequestLine(buffer, cursor);
    
public org.apache.http.RequestLineparseRequestLine(org.apache.http.util.CharArrayBuffer buffer, org.apache.http.message.ParserCursor cursor)
Parses a request line.

param
buffer a buffer holding the line to parse
return
the parsed request line
throws
ParseException in case of a parse error


        if (buffer == null) {
            throw new IllegalArgumentException("Char array buffer may not be null");
        }
        if (cursor == null) {
            throw new IllegalArgumentException("Parser cursor may not be null");
        }

        int indexFrom = cursor.getPos();
        int indexTo = cursor.getUpperBound();
        
        try {
            skipWhitespace(buffer, cursor);
            int i = cursor.getPos();
            
            int blank = buffer.indexOf(' ", i, indexTo);
            if (blank < 0) {
                throw new ParseException("Invalid request line: " + 
                        buffer.substring(indexFrom, indexTo));
            }
            String method = buffer.substringTrimmed(i, blank);
            cursor.updatePos(blank);

            skipWhitespace(buffer, cursor);
            i = cursor.getPos();

            blank = buffer.indexOf(' ", i, indexTo);
            if (blank < 0) {
                throw new ParseException("Invalid request line: " + 
                        buffer.substring(indexFrom, indexTo));
            }
            String uri = buffer.substringTrimmed(i, blank);
            cursor.updatePos(blank);

            ProtocolVersion ver = parseProtocolVersion(buffer, cursor);
            
            skipWhitespace(buffer, cursor);
            if (!cursor.atEnd()) {
                throw new ParseException("Invalid request line: " + 
                        buffer.substring(indexFrom, indexTo));
            }
            
            return createRequestLine(method, uri, ver);
        } catch (IndexOutOfBoundsException e) {
            throw new ParseException("Invalid request line: " + 
                                     buffer.substring(indexFrom, indexTo)); 
        }
    
public static final org.apache.http.StatusLineparseStatusLine(java.lang.String value, org.apache.http.message.LineParser parser)


        if (value == null) {
            throw new IllegalArgumentException
                ("Value to parse may not be null.");
        }

        if (parser == null)
            parser = BasicLineParser.DEFAULT;

        CharArrayBuffer buffer = new CharArrayBuffer(value.length());
        buffer.append(value);
        ParserCursor cursor = new ParserCursor(0, value.length());
        return parser.parseStatusLine(buffer, cursor);
    
public org.apache.http.StatusLineparseStatusLine(org.apache.http.util.CharArrayBuffer buffer, org.apache.http.message.ParserCursor cursor)


        if (buffer == null) {
            throw new IllegalArgumentException("Char array buffer may not be null");
        }
        if (cursor == null) {
            throw new IllegalArgumentException("Parser cursor may not be null");
        }

        int indexFrom = cursor.getPos();
        int indexTo = cursor.getUpperBound();
        
        try {
            // handle the HTTP-Version
            ProtocolVersion ver = parseProtocolVersion(buffer, cursor);

            // handle the Status-Code
            skipWhitespace(buffer, cursor);
            int i = cursor.getPos();
            
            int blank = buffer.indexOf(' ", i, indexTo);
            if (blank < 0) {
                blank = indexTo;
            }
            int statusCode = 0;
            try {
                statusCode =
                    Integer.parseInt(buffer.substringTrimmed(i, blank));
            } catch (NumberFormatException e) {
                throw new ParseException(
                    "Unable to parse status code from status line: " 
                    + buffer.substring(indexFrom, indexTo));
            }
            //handle the Reason-Phrase
            i = blank;
            String reasonPhrase = null;
            if (i < indexTo) {
                reasonPhrase = buffer.substringTrimmed(i, indexTo);
            } else {
                reasonPhrase = "";
            }
            return createStatusLine(ver, statusCode, reasonPhrase);

        } catch (IndexOutOfBoundsException e) {
            throw new ParseException("Invalid status line: " + 
                                     buffer.substring(indexFrom, indexTo)); 
        }
    
protected voidskipWhitespace(org.apache.http.util.CharArrayBuffer buffer, org.apache.http.message.ParserCursor cursor)
Helper to skip whitespace.

        int pos = cursor.getPos();
        int indexTo = cursor.getUpperBound();
        while ((pos < indexTo) &&
               HTTP.isWhitespace(buffer.charAt(pos))) {
            pos++;
        }
        cursor.updatePos(pos);