Return-Path: Delivered-To: apmail-jakarta-httpcomponents-commits-archive@www.apache.org Received: (qmail 76907 invoked from network); 21 Aug 2007 07:47:08 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 21 Aug 2007 07:47:08 -0000 Received: (qmail 52289 invoked by uid 500); 21 Aug 2007 07:47:06 -0000 Delivered-To: apmail-jakarta-httpcomponents-commits-archive@jakarta.apache.org Received: (qmail 52273 invoked by uid 500); 21 Aug 2007 07:47:06 -0000 Mailing-List: contact httpcomponents-commits-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: httpcomponents-dev@jakarta.apache.org Delivered-To: mailing list httpcomponents-commits@jakarta.apache.org Received: (qmail 52264 invoked by uid 99); 21 Aug 2007 07:47:05 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Aug 2007 00:47:05 -0700 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Aug 2007 07:47:03 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 7EF471A981A; Tue, 21 Aug 2007 00:46:43 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r567997 - in /jakarta/httpcomponents/httpcore/trunk: module-main/src/main/java/org/apache/http/ module-main/src/main/java/org/apache/http/impl/ module-main/src/main/java/org/apache/http/impl/io/ module-main/src/main/java/org/apache/http/mes... Date: Tue, 21 Aug 2007 07:46:31 -0000 To: httpcomponents-commits@jakarta.apache.org From: rolandw@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20070821074643.7EF471A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: rolandw Date: Tue Aug 21 00:46:29 2007 New Revision: 567997 URL: http://svn.apache.org/viewvc?rev=567997&view=rev Log: HTTPCORE-110, patch 1 with additional cleanup Added: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ParseException.java (with props) jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderValueParser.java (with props) jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicLineParser.java (with props) jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/HeaderValueParser.java (with props) jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/LineParser.java (with props) Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ProtocolException.java jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/AbstractHttpClientConnection.java jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/AbstractMessageParser.java jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/HttpRequestParser.java jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/HttpResponseParser.java jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElement.java jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BufferedHeader.java jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/impl/io/TestMessageParser.java jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageParser.java jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpRequestParser.java jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpResponseParser.java jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestHttpMessageParser.java Added: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ParseException.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ParseException.java?rev=567997&view=auto ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ParseException.java (added) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ParseException.java Tue Aug 21 00:46:29 2007 @@ -0,0 +1,74 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * Indicates a parse error. + * Parse errors when receiving a message will typically trigger + * {@link ProtocolException}. Parse errors that do not occur during + * protocol execution may be handled differently. + * This is an unchecked exceptions, since there are cases where + * the data to be parsed has been generated and is therefore + * known to be parseable. + * + * @since 4.0 + */ +public class ParseException extends RuntimeException { + + private static final long serialVersionUID = -1714832601648789035L; + + /** + * Creates a {@link ParseException} without details. + */ + public ParseException() { + super(); + } + + /** + * Creates a {@link ParseException} with a detail message. + * + * @param message the exception detail message, or null + */ + public ParseException(String message) { + super(message); + } + + /** + * Creates a {@link ParseException} with a detail message and root cause. + * + * @param message the exception detail message, or null + * @param cause the root cause of this exception, or null + */ + public ParseException(String message, Throwable cause) { + super(message, cause); + } +} Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ParseException.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ParseException.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ParseException.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ProtocolException.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ProtocolException.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ProtocolException.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ProtocolException.java Tue Aug 21 00:46:29 2007 @@ -41,7 +41,7 @@ */ public class ProtocolException extends HttpException { - static final long serialVersionUID = -2143571074341228994L; + private static final long serialVersionUID = -2143571074341228994L; /** * Creates a new ProtocolException with a null detail message. Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/AbstractHttpClientConnection.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/AbstractHttpClientConnection.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/AbstractHttpClientConnection.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/AbstractHttpClientConnection.java Tue Aug 21 00:46:29 2007 @@ -98,7 +98,8 @@ final SessionInputBuffer buffer, final HttpResponseFactory responseFactory, final HttpParams params) { - return new HttpResponseParser(buffer, responseFactory, params); + //@@@ how to configure the parser? + return new HttpResponseParser(buffer, null, responseFactory, params); } protected HttpMessageWriter createRequestWriter( Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java Tue Aug 21 00:46:29 2007 @@ -98,7 +98,8 @@ final SessionInputBuffer buffer, final HttpRequestFactory requestFactory, final HttpParams params) { - return new HttpRequestParser(buffer, requestFactory, params); + //@@@ how to configure the parser? + return new HttpRequestParser(buffer, null, requestFactory, params); } protected HttpMessageWriter createResponseWriter( Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/AbstractMessageParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/AbstractMessageParser.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/AbstractMessageParser.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/AbstractMessageParser.java Tue Aug 21 00:46:29 2007 @@ -40,7 +40,8 @@ import org.apache.http.ProtocolException; import org.apache.http.io.HttpMessageParser; import org.apache.http.io.SessionInputBuffer; -import org.apache.http.message.BufferedHeader; +import org.apache.http.message.LineParser; +import org.apache.http.message.BasicLineParser; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.CharArrayBuffer; @@ -56,9 +57,12 @@ private final SessionInputBuffer sessionBuffer; private final int maxHeaderCount; private final int maxLineLen; + protected final LineParser lineParser; + public AbstractMessageParser( final SessionInputBuffer buffer, + final LineParser parser, final HttpParams params) { super(); if (buffer == null) { @@ -72,6 +76,7 @@ HttpConnectionParams.MAX_HEADER_COUNT, -1); this.maxLineLen = params.getIntParameter( HttpConnectionParams.MAX_LINE_LENGTH, -1); + this.lineParser = (parser != null) ? parser : BasicLineParser.DEFAULT; } /** @@ -93,10 +98,16 @@ public static Header[] parseHeaders( final SessionInputBuffer inbuffer, int maxHeaderCount, - int maxLineLen) throws HttpException, IOException { + int maxLineLen, + LineParser parser) + throws HttpException, IOException { + if (inbuffer == null) { throw new IllegalArgumentException("Session input buffer may not be null"); } + if (parser == null) + parser = BasicLineParser.DEFAULT; + ArrayList headerLines = new ArrayList(); CharArrayBuffer current = null; @@ -145,7 +156,7 @@ for (int i = 0; i < headerLines.size(); i++) { CharArrayBuffer buffer = (CharArrayBuffer) headerLines.get(i); try { - headers[i] = new BufferedHeader(buffer); + headers[i] = parser.parseHeader(buffer); } catch (IllegalArgumentException ex) { throw new ProtocolException(ex.getMessage()); } @@ -153,9 +164,16 @@ return headers; } + public static Header[] parseHeaders( + final SessionInputBuffer inbuffer, + int maxHeaderCount, + int maxLineLen) throws HttpException, IOException { + return parseHeaders(inbuffer, maxHeaderCount, maxLineLen, null); + } + public static Header[] parseHeaders(final SessionInputBuffer inbuffer) throws HttpException, IOException { - return parseHeaders(inbuffer, -1, -1); + return parseHeaders(inbuffer, -1, -1, null); } protected abstract HttpMessage parseHead(SessionInputBuffer sessionBuffer) @@ -166,7 +184,8 @@ Header[] headers = AbstractMessageParser.parseHeaders( this.sessionBuffer, this.maxHeaderCount, - this.maxLineLen); + this.maxLineLen, + this.lineParser); message.setHeaders(headers); return message; } Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/HttpRequestParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/HttpRequestParser.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/HttpRequestParser.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/HttpRequestParser.java Tue Aug 21 00:46:29 2007 @@ -39,7 +39,7 @@ import org.apache.http.HttpRequestFactory; import org.apache.http.RequestLine; import org.apache.http.io.SessionInputBuffer; -import org.apache.http.message.BasicRequestLine; +import org.apache.http.message.LineParser; import org.apache.http.params.HttpParams; import org.apache.http.util.CharArrayBuffer; @@ -50,9 +50,10 @@ public HttpRequestParser( final SessionInputBuffer buffer, + final LineParser parser, final HttpRequestFactory requestFactory, final HttpParams params) { - super(buffer, params); + super(buffer, parser, params); if (requestFactory == null) { throw new IllegalArgumentException("Request factory may not be null"); } @@ -67,7 +68,7 @@ if (i == -1) { throw new ConnectionClosedException("Client closed connection"); } - RequestLine requestline = BasicRequestLine.parse(this.lineBuf, 0, this.lineBuf.length()); + RequestLine requestline = lineParser.parseRequestLine(this.lineBuf, 0, this.lineBuf.length()); return this.requestFactory.newHttpRequest(requestline); } Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/HttpResponseParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/HttpResponseParser.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/HttpResponseParser.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/HttpResponseParser.java Tue Aug 21 00:46:29 2007 @@ -39,7 +39,7 @@ import org.apache.http.NoHttpResponseException; import org.apache.http.StatusLine; import org.apache.http.io.SessionInputBuffer; -import org.apache.http.message.BasicStatusLine; +import org.apache.http.message.LineParser; import org.apache.http.params.HttpParams; import org.apache.http.util.CharArrayBuffer; @@ -50,9 +50,10 @@ public HttpResponseParser( final SessionInputBuffer buffer, + final LineParser parser, final HttpResponseFactory responseFactory, final HttpParams params) { - super(buffer, params); + super(buffer, parser, params); if (responseFactory == null) { throw new IllegalArgumentException("Response factory may not be null"); } @@ -68,7 +69,7 @@ throw new NoHttpResponseException("The target server failed to respond"); } //create the status line from the status string - StatusLine statusline = BasicStatusLine.parse(this.lineBuf, 0, this.lineBuf.length()); + StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, 0, this.lineBuf.length()); return this.responseFactory.newHttpResponse(statusline, null); } Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElement.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElement.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElement.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElement.java Tue Aug 21 00:46:29 2007 @@ -93,7 +93,7 @@ private final String value; private final NameValuePair[] parameters; - private BasicHeaderElement(final NameValuePair[] nvps) { + public BasicHeaderElement(final NameValuePair[] nvps) { super(); if (nvps.length > 0) { NameValuePair nvp = nvps[0]; Added: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderValueParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderValueParser.java?rev=567997&view=auto ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderValueParser.java (added) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderValueParser.java Tue Aug 21 00:46:29 2007 @@ -0,0 +1,290 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + + +import java.util.List; +import java.util.ArrayList; + +import org.apache.http.HeaderElement; +import org.apache.http.NameValuePair; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.CharArrayBuffer; + + + +/** + * Basic implementation for parsing header values into elements. + * Instances of this class are stateless and thread-safe. + * Derived classes are expected to maintain these properties. + * + * @author B.C. Holmes + * @author Park, Sung-Gu + * @author Mike Bowler + * @author Oleg Kalnichevski + * @author and others + * + * + * + * @version $Revision$ $Date$ + * + * @since 4.0 + */ +public class BasicHeaderValueParser implements HeaderValueParser { + + /** + * 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. + */ + public final static + BasicHeaderValueParser DEFAULT = new BasicHeaderValueParser(); + + + // public default constructor + + + // non-javadoc, see interface HeaderValueParser + public HeaderElement[] parseElements(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) { + + if (buffer == null) { + throw new IllegalArgumentException + ("Char array buffer may not be null"); + } + if (indexFrom < 0) { + throw new IndexOutOfBoundsException(); + } + if (indexTo > buffer.length()) { + throw new IndexOutOfBoundsException(); + } + if (indexFrom > indexTo) { + throw new IndexOutOfBoundsException(); + } + List elements = new ArrayList(); + int cur = indexFrom; + int from = indexFrom; + boolean qouted = false; + boolean escaped = false; + while (cur < indexTo) { + char ch = buffer.charAt(cur); + if (ch == '"' && !escaped) { + qouted = !qouted; + } + HeaderElement element = null; + if ((!qouted) && (ch == ',')) { + element = parseHeaderElement(buffer, from, cur); + from = cur + 1; + } else if (cur == indexTo - 1) { + element = parseHeaderElement(buffer, from, indexTo); + } + if (element != null && !(element.getName().length() == 0 && + element.getValue() == null) + ) { + elements.add(element); + } + if (escaped) { + escaped = false; + } else { + escaped = qouted && ch == '\\'; + } + cur++; + } + return (HeaderElement[]) + elements.toArray(new HeaderElement[elements.size()]); + } + + + /** + * Parses a single header element. + * A header element consist of a semicolon-separate list + * of name=value definitions. + */ + protected HeaderElement parseHeaderElement(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) { + + if (buffer == null) { + throw new IllegalArgumentException + ("Char array buffer may not be null"); + } + if (indexFrom < 0) { + throw new IndexOutOfBoundsException(); + } + if (indexTo > buffer.length()) { + throw new IndexOutOfBoundsException(); + } + if (indexFrom > indexTo) { + throw new IndexOutOfBoundsException(); + } + NameValuePair[] nvps = parseParameters(buffer, indexFrom, indexTo); + return createHeaderElement(nvps); + } + + + /** + * Craetes a header element. + * Called from {@link #parseHeaderElement}. + * + * @param nvps the name-value pairs + * + * @return a header element representing the argument + */ + protected HeaderElement createHeaderElement(NameValuePair[] nvps) { + return new BasicHeaderElement(nvps); + } + + + + // non-javadoc, see interface HeaderValueParser + public NameValuePair[] parseParameters(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) { + + if (buffer == null) { + throw new IllegalArgumentException + ("Char array buffer may not be null"); + } + if (indexFrom < 0) { + throw new IndexOutOfBoundsException(); + } + if (indexTo > buffer.length()) { + throw new IndexOutOfBoundsException(); + } + if (indexFrom > indexTo) { + throw new IndexOutOfBoundsException(); + } + List params = new ArrayList(); + int cur = indexFrom; + int from = indexFrom; + boolean qouted = false; + boolean escaped = false; + while (cur < indexTo) { + char ch = buffer.charAt(cur); + if (ch == '"' && !escaped) { + qouted = !qouted; + } + NameValuePair param = null; + if (!qouted && ch == ';') { + param = parseNameValuePair(buffer, from, cur); + from = cur + 1; + } else if (cur == indexTo - 1) { + param = parseNameValuePair(buffer, from, indexTo); + } + if (param != null && !(param.getName().length() == 0 && + param.getValue() == null) + ) { + params.add(param); + } + if (escaped) { + escaped = false; + } else { + escaped = qouted && ch == '\\'; + } + cur++; + } + return (NameValuePair[]) + params.toArray(new NameValuePair[params.size()]); + } + + + /** + * Parses a name=value specification, where the = and value are optional. + * + * @param buffer the buffer holding the name-value pair to parse + * + * @return the name-value pair, where the value is null + * if no value is specified + */ + protected NameValuePair parseNameValuePair(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) { + + if (buffer == null) { + throw new IllegalArgumentException + ("Char array buffer may not be null"); + } + if (indexFrom < 0) { + throw new IndexOutOfBoundsException(); + } + if (indexTo > buffer.length()) { + throw new IndexOutOfBoundsException(); + } + if (indexFrom > indexTo) { + throw new IndexOutOfBoundsException(); + } + + int eq = buffer.indexOf('=', indexFrom, indexTo); + if (eq < 0) { + return createNameValuePair(buffer.substringTrimmed(indexFrom, indexTo), null); + } + String name = buffer.substringTrimmed(indexFrom, eq); + int i1 = eq + 1; + int i2 = indexTo; + // Trim leading white spaces + while (i1 < i2 && (HTTP.isWhitespace(buffer.charAt(i1)))) { + i1++; + } + // Trim trailing white spaces + while ((i2 > i1) && (HTTP.isWhitespace(buffer.charAt(i2 - 1)))) { + i2--; + } + // Strip away quotes if necessary + if (((i2 - i1) >= 2) + && (buffer.charAt(i1) == '"') + && (buffer.charAt(i2 - 1) == '"')) { + i1++; + i2--; + } + String value = buffer.substring(i1, i2); + return createNameValuePair(name, value); + } + + + /** + * Creates a name-value pair. + * Called from {@link #parseNameValuePair}. + * + * @param name the name + * @param value the value, or null + * + * @return a name-value pair representing the arguments + */ + protected NameValuePair createNameValuePair(String name, String value) { + return new BasicNameValuePair(name, value); + } + + +} + Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderValueParser.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderValueParser.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderValueParser.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicLineParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicLineParser.java?rev=567997&view=auto ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicLineParser.java (added) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicLineParser.java Tue Aug 21 00:46:29 2007 @@ -0,0 +1,347 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + + +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.ParseException; +import org.apache.http.ProtocolException; +import org.apache.http.RequestLine; +import org.apache.http.StatusLine; +import org.apache.http.Header; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.CharArrayBuffer; + + + +/** + * 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 + */ +public class BasicLineParser implements LineParser { + + /** + * 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. + */ + public final static BasicLineParser DEFAULT = new BasicLineParser(); + + + + // public default constructor + + + // non-javadoc, see interface LineParser + public HttpVersion parseProtocolVersion(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) + throws ProtocolException { + + if (buffer == null) { + throw new IllegalArgumentException + ("Char array buffer may not be null"); + } + if (indexFrom < 0) { + throw new IndexOutOfBoundsException(); + } + if (indexTo > buffer.length()) { + throw new IndexOutOfBoundsException(); + } + if (indexFrom > indexTo) { + throw new IndexOutOfBoundsException(); + } + try { + int major, minor; + + int i = indexFrom; + while (HTTP.isWhitespace(buffer.charAt(i))) { + i++; + } + if (buffer.charAt(i ) != 'H' + || buffer.charAt(i + 1) != 'T' + || buffer.charAt(i + 2) != 'T' + || buffer.charAt(i + 3) != 'P' + || buffer.charAt(i + 4) != '/') { + throw new ProtocolException("Not a valid HTTP version string: " + + buffer.substring(indexFrom, indexTo)); + } + i += 5; + int period = buffer.indexOf('.', i, indexTo); + if (period == -1) { + throw new ProtocolException("Invalid HTTP version number: " + + buffer.substring(indexFrom, indexTo)); + } + try { + major = Integer.parseInt(buffer.substringTrimmed(i, period)); + } catch (NumberFormatException e) { + throw new ProtocolException("Invalid HTTP major version number: " + + buffer.substring(indexFrom, indexTo)); + } + try { + minor = Integer.parseInt(buffer.substringTrimmed(period + 1, indexTo)); + } catch (NumberFormatException e) { + throw new ProtocolException("Invalid HTTP minor version number: " + + buffer.substring(indexFrom, indexTo)); + } + return createProtocolVersion(major, minor); + + } catch (IndexOutOfBoundsException e) { + throw new ProtocolException("Invalid HTTP version string: " + + buffer.substring(indexFrom, indexTo)); + } + } // parseProtocolVersion + + + /** + * 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 + */ + protected HttpVersion createProtocolVersion(int major, int minor) { + return new HttpVersion(major, minor); + } + + + /** + * Parses a request line. + * + * @param buffer a buffer holding the line to parse + * + * @return the parsed request line + * + * @throws ProtocolException in case of a parse error + */ + public RequestLine parseRequestLine(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) + throws ProtocolException { + + if (buffer == null) { + throw new IllegalArgumentException + ("Char array buffer may not be null"); + } + if (indexFrom < 0) { + throw new IndexOutOfBoundsException(); + } + if (indexTo > buffer.length()) { + throw new IndexOutOfBoundsException(); + } + if (indexFrom > indexTo) { + throw new IndexOutOfBoundsException(); + } + + try { + int i = indexFrom; + while (HTTP.isWhitespace(buffer.charAt(i))) { + i++; + } + int blank = buffer.indexOf(' ', i, indexTo); + if (blank < 0) { + throw new ProtocolException("Invalid request line: " + + buffer.substring(indexFrom, indexTo)); + } + String method = buffer.substringTrimmed(i, blank); + i = blank; + while (HTTP.isWhitespace(buffer.charAt(i))) { + i++; + } + blank = buffer.indexOf(' ', i, indexTo); + if (blank < 0) { + throw new ProtocolException("Invalid request line: " + + buffer.substring(indexFrom, indexTo)); + } + String uri = buffer.substringTrimmed(i, blank); + HttpVersion ver = parseProtocolVersion(buffer, blank, indexTo); + return createRequestLine(method, uri, ver); + } catch (IndexOutOfBoundsException e) { + throw new ProtocolException("Invalid request line: " + + buffer.substring(indexFrom, indexTo)); + } + } // parseRequestLine + + + /** + * 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 + */ + protected RequestLine createRequestLine(String method, + String uri, + HttpVersion ver) { + return new BasicRequestLine(method, uri, ver); + } + + + // non-javadoc, see interface LineParser + public StatusLine parseStatusLine(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) + throws ProtocolException { + + if (buffer == null) { + throw new IllegalArgumentException + ("Char array buffer may not be null"); + } + if (indexFrom < 0) { + throw new IndexOutOfBoundsException(); + } + if (indexTo > buffer.length()) { + throw new IndexOutOfBoundsException(); + } + if (indexFrom > indexTo) { + throw new IndexOutOfBoundsException(); + } + + try { + int i = indexFrom; + //handle the HTTP-Version + while (HTTP.isWhitespace(buffer.charAt(i))) { + i++; + } + int blank = buffer.indexOf(' ', i, indexTo); + if (blank <= 0) { + throw new ProtocolException( + "Unable to parse HTTP-Version from the status line: " + + buffer.substring(indexFrom, indexTo)); + } + HttpVersion ver = parseProtocolVersion(buffer, i, blank); + + i = blank; + //advance through spaces + while (HTTP.isWhitespace(buffer.charAt(i))) { + i++; + } + + //handle the Status-Code + 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 ProtocolException( + "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 ProtocolException("Invalid status line: " + + buffer.substring(indexFrom, indexTo)); + } + } // parseStatusLine + + + /** + * 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 + */ + protected StatusLine createStatusLine(HttpVersion ver, + int status, String reason) { + return new BasicStatusLine(ver, status, reason); + } + + + // non-javadoc, see interface LineParser + public Header parseHeader(CharArrayBuffer buffer) + throws ProtocolException { + + Header result = null; + try { + // the actual parser code is in the constructor of BufferedHeader + result = new BufferedHeader(buffer, getHeaderValueParser()); + } catch (ParseException px) { + throw new ProtocolException(px.getMessage(), px); + } + return result; + } + + + /** + * Obtains the header value parser to use. + * Called by {@link #parseHeader}. + * + * @return the header value parser, or + * null for the default + */ + protected HeaderValueParser getHeaderValueParser() { + return null; + } + + +} // class BasicLineParser Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicLineParser.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicLineParser.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicLineParser.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BufferedHeader.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BufferedHeader.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BufferedHeader.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BufferedHeader.java Tue Aug 21 00:46:29 2007 @@ -33,6 +33,7 @@ import org.apache.http.Header; import org.apache.http.HeaderElement; +import org.apache.http.ParseException; import org.apache.http.util.CharArrayBuffer; /** @@ -62,6 +63,11 @@ */ private final int valuePos; + /** + * The parser for the header value, or null. + */ + private HeaderValueParser parser; + /** * Creates a new header from a buffer. @@ -69,25 +75,41 @@ * the value only if it is accessed. * * @param buffer the buffer containing the header to represent + * @param parser the header value parser, or null + * + * @throws ParseException in case of a parse error */ - public BufferedHeader(final CharArrayBuffer buffer) { + public BufferedHeader(final CharArrayBuffer buffer, + final HeaderValueParser parser) + throws ParseException { + super(); if (buffer == null) { - throw new IllegalArgumentException("Char array buffer may not be null"); + throw new IllegalArgumentException + ("Char array buffer may not be null"); } int colon = buffer.indexOf(':'); if (colon == -1) { - throw new IllegalArgumentException("Invalid header: " + buffer.toString()); + throw new ParseException + ("Invalid header: " + buffer.toString()); } String s = buffer.substringTrimmed(0, colon); if (s.length() == 0) { - throw new IllegalArgumentException("Invalid header: " + buffer.toString()); + throw new ParseException + ("Invalid header: " + buffer.toString()); } this.buffer = buffer; this.name = s; this.valuePos = colon + 1; + this.parser = parser; + } + + public BufferedHeader(final CharArrayBuffer buffer) + throws ParseException { + this(buffer, null); } + public String getName() { return this.name; } @@ -95,15 +117,27 @@ public String getValue() { return this.buffer.substringTrimmed(this.valuePos, this.buffer.length()); } - + + public HeaderValueParser getParser() { + return this.parser; + } + + public void setParser(HeaderValueParser parser) { + this.parser = parser; + } + public HeaderElement[] getElements() { - return BasicHeaderElement.parseAll(this.buffer, this.valuePos, this.buffer.length()); + HeaderValueParser hvp = this.parser; + if (hvp == null) + hvp = BasicHeaderValueParser.DEFAULT; + return hvp.parseElements(this.buffer, + this.valuePos, this.buffer.length()); } public int getValuePos() { return this.valuePos; } - + public CharArrayBuffer getBuffer() { return this.buffer; } Added: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/HeaderValueParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/HeaderValueParser.java?rev=567997&view=auto ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/HeaderValueParser.java (added) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/HeaderValueParser.java Tue Aug 21 00:46:29 2007 @@ -0,0 +1,183 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + + +import org.apache.http.HeaderElement; +import org.apache.http.NameValuePair; +import org.apache.http.ParseException; +import org.apache.http.util.CharArrayBuffer; + + + +/** + * Interface for parsing header values into elements. + * Instances of this interface are expected to be stateless and thread-safe. + * + * + * + * @version $Revision$ $Date$ + * + * @since 4.0 + */ +public interface HeaderValueParser { + + /** + * Parses a header value into elements. + * Parse errors are indicated as RuntimeException. + *

+ * Some HTTP headers (such as the set-cookie header) have values that + * can be decomposed into multiple elements. In order to be processed + * by this parser, such headers must be in the following form: + *

+ *
+     * header  = [ element ] *( "," [ element ] )
+     * element = name [ "=" [ value ] ] *( ";" [ param ] )
+     * param   = name [ "=" [ value ] ]
+     *
+     * name    = token
+     * value   = ( token | quoted-string )
+     *
+     * token         = 1*<any char except "=", ",", ";", <"> and
+     *                       white space>
+     * quoted-string = <"> *( text | quoted-char ) <">
+     * text          = any char except <">
+     * quoted-char   = "\" char
+     * 
+ *

+ * Any amount of white space is allowed between any part of the + * header, element or param and is ignored. A missing value in any + * element or param will be stored as the empty {@link String}; + * if the "=" is also missing null will be stored instead. + *

+ * + * @param buffer buffer holding the header value to parse + * + * @return an array holding all elements of the header value + * + * @throws ParseException in case of a parse error + */ + public HeaderElement[] parseElements(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) + throws ParseException + ; + + + /** + * Parses a list of name-value pairs. + * These lists are used to specify parameters to a header element. + * Parse errors are indicated as RuntimeException. + *

+ * This method comforms to the generic grammar and formatting rules + * outlined in the + * Section 2.2 + * and + * Section 3.6 + * of + * RFC 2616. + *

+ * 2.2 Basic Rules + *

+ * The following rules are used throughout this specification to + * describe basic parsing constructs. + * The US-ASCII coded character set is defined by ANSI X3.4-1986. + *

+ *
+     *     OCTET          = 
+     *     CHAR           = 
+     *     UPALPHA        = 
+     *     LOALPHA        = 
+     *     ALPHA          = UPALPHA | LOALPHA
+     *     DIGIT          = 
+     *     CTL            = 
+     *     CR             = 
+     *     LF             = 
+     *     SP             = 
+     *     HT             = 
+     *     <">            = 
+     * 
+ *

+ * Many HTTP/1.1 header field values consist of words separated + * by LWS or special characters. These special characters MUST be + * in a quoted string to be used within + * a parameter value (as defined in section 3.6). + *

+ *

+     * token          = 1*
+     * separators     = "(" | ")" | "<" | ">" | "@"
+     *                | "," | ";" | ":" | "\" | <">
+     *                | "/" | "[" | "]" | "?" | "="
+     *                | "{" | "}" | SP | HT
+     * 
+ *

+ * A string of text is parsed as a single word if it is quoted using + * double-quote marks. + *

+ *
+     * quoted-string  = ( <"> *(qdtext | quoted-pair ) <"> )
+     * qdtext         = >
+     * 
+ *

+ * The backslash character ("\") MAY be used as a single-character + * quoting mechanism only within quoted-string and comment constructs. + *

+ *
+     * quoted-pair    = "\" CHAR
+     * 
+ * 3.6 Transfer Codings + *

+ * Parameters are in the form of attribute/value pairs. + *

+ *
+     * parameter               = attribute "=" value
+     * attribute               = token
+     * value                   = token | quoted-string
+     * 
+ * + * @param buffer buffer holding the name-value list to parse + * + * @return an array holding all items of the name-value list + * + * @throws ParseException in case of a parse error + */ + public NameValuePair[] parseParameters(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) + throws ParseException + ; + +} + Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/HeaderValueParser.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/HeaderValueParser.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/HeaderValueParser.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/LineParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/LineParser.java?rev=567997&view=auto ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/LineParser.java (added) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/LineParser.java Tue Aug 21 00:46:29 2007 @@ -0,0 +1,130 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + + +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolException; +import org.apache.http.RequestLine; +import org.apache.http.StatusLine; +import org.apache.http.Header; +import org.apache.http.util.CharArrayBuffer; + + +/** + * Interface for parsing 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 interface are expected to be stateless and thread-safe. + * + * + * + * @version $Revision$ $Date$ + * + * @since 4.0 + */ +public interface LineParser { + + + /** + * Parses the textual representation of a protocol version. + * This is needed for parsing request lines (last element) + * as well as status lines (first element). + * + * @param buffer a buffer holding the protocol version to parse + * + * @return the parsed protocol version + * + * @throws ProtocolException in case of a parse error + */ + public HttpVersion parseProtocolVersion(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) + throws ProtocolException + ; + + + /** + * Parses a request line. + * + * @param buffer a buffer holding the line to parse + * + * @return the parsed request line + * + * @throws ProtocolException in case of a parse error + */ + public RequestLine parseRequestLine(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) + throws ProtocolException + ; + + + /** + * Parses a status line. + * + * @param buffer a buffer holding the line to parse + * + * @return the parsed status line + * + * @throws ProtocolException in case of a parse error + */ + public StatusLine parseStatusLine(final CharArrayBuffer buffer, + final int indexFrom, + final int indexTo) + throws ProtocolException + ; + + + /** + * Creates a header from a line. + * The full header line is expected here. Header continuation lines + * must be joined by the caller before invoking this method. + * + * @param buffer a buffer holding the full header line. + * This buffer MUST NOT be re-used afterwards, since + * the returned object may reference the contents later. + * + * @return the header in the argument buffer. + * The returned object MAY be a wrapper for the argument buffer. + * The argument buffer MUST NOT be re-used or changed afterwards. + * + * @throws ProtocolException in case of a parse error + */ + public Header parseHeader(CharArrayBuffer buffer) + throws ProtocolException + ; + + +} Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/LineParser.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/LineParser.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/LineParser.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/impl/io/TestMessageParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/impl/io/TestMessageParser.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/impl/io/TestMessageParser.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/impl/io/TestMessageParser.java Tue Aug 21 00:46:29 2007 @@ -73,7 +73,7 @@ // expected } try { - new BufferedHeader(null); + new BufferedHeader(null, null); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java Tue Aug 21 00:46:29 2007 @@ -78,7 +78,8 @@ final SessionInputBuffer buffer, final HttpResponseFactory responseFactory, final HttpParams params) { - return new HttpResponseParser(buffer, responseFactory, params); + //@@@ how to configure the parser? + return new HttpResponseParser(buffer, null, responseFactory, params); } protected NHttpMessageWriter createRequestWriter( Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java Tue Aug 21 00:46:29 2007 @@ -75,7 +75,8 @@ final SessionInputBuffer buffer, final HttpRequestFactory requestFactory, final HttpParams params) { - return new HttpRequestParser(buffer, requestFactory, params); + //@@@ how to configure the parser? + return new HttpRequestParser(buffer, null, requestFactory, params); } protected NHttpMessageWriter createResponseWriter( Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageParser.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageParser.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/AbstractMessageParser.java Tue Aug 21 00:46:29 2007 @@ -39,7 +39,8 @@ import org.apache.http.HttpException; import org.apache.http.HttpMessage; import org.apache.http.ProtocolException; -import org.apache.http.message.BufferedHeader; +import org.apache.http.message.LineParser; +import org.apache.http.message.BasicLineParser; import org.apache.http.nio.NHttpMessageParser; import org.apache.http.nio.reactor.SessionInputBuffer; import org.apache.http.params.HttpConnectionParams; @@ -63,8 +64,9 @@ private int maxLineLen = -1; private int maxHeaderCount = -1; + protected final LineParser lineParser; - public AbstractMessageParser(final SessionInputBuffer buffer, final HttpParams params) { + public AbstractMessageParser(final SessionInputBuffer buffer, final LineParser parser, final HttpParams params) { super(); if (buffer == null) { throw new IllegalArgumentException("Session input buffer may not be null"); @@ -80,6 +82,7 @@ HttpConnectionParams.MAX_LINE_LENGTH, -1); this.maxHeaderCount = params.getIntParameter( HttpConnectionParams.MAX_HEADER_COUNT, -1); + this.lineParser = (parser != null) ? parser : BasicLineParser.DEFAULT; } public void reset() { @@ -172,7 +175,7 @@ for (int i = 0; i < this.headerBufs.size(); i++) { CharArrayBuffer buffer = (CharArrayBuffer) this.headerBufs.get(i); try { - this.message.addHeader(new BufferedHeader(buffer)); + this.message.addHeader(lineParser.parseHeader(buffer)); } catch (IllegalArgumentException ex) { throw new ProtocolException(ex.getMessage()); } Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java Tue Aug 21 00:46:29 2007 @@ -42,6 +42,7 @@ import org.apache.http.message.BufferedHeader; import org.apache.http.nio.reactor.SessionInputBuffer; import org.apache.http.impl.io.HttpTransportMetricsImpl; +import org.apache.http.ParseException; import org.apache.http.protocol.HTTP; import org.apache.http.util.CharArrayBuffer; @@ -137,8 +138,8 @@ for (int i = 0; i < this.trailerBufs.size(); i++) { CharArrayBuffer buffer = (CharArrayBuffer) this.trailerBufs.get(i); try { - this.footers[i] = new BufferedHeader(buffer); - } catch (IllegalArgumentException ex) { + this.footers[i] = new BufferedHeader(buffer, null); + } catch (ParseException ex) { throw new IOException(ex.getMessage()); } } Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpRequestParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpRequestParser.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpRequestParser.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpRequestParser.java Tue Aug 21 00:46:29 2007 @@ -35,7 +35,7 @@ import org.apache.http.HttpMessage; import org.apache.http.HttpRequestFactory; import org.apache.http.RequestLine; -import org.apache.http.message.BasicRequestLine; +import org.apache.http.message.LineParser; import org.apache.http.nio.reactor.SessionInputBuffer; import org.apache.http.params.HttpParams; import org.apache.http.util.CharArrayBuffer; @@ -46,9 +46,10 @@ public HttpRequestParser( final SessionInputBuffer buffer, + final LineParser parser, final HttpRequestFactory requestFactory, final HttpParams params) { - super(buffer, params); + super(buffer, parser, params); if (requestFactory == null) { throw new IllegalArgumentException("Request factory may not be null"); } @@ -57,7 +58,7 @@ protected HttpMessage createMessage(final CharArrayBuffer buffer) throws HttpException { - RequestLine requestLine = BasicRequestLine.parse(buffer, 0, buffer.length()); + RequestLine requestLine = lineParser.parseRequestLine(buffer, 0, buffer.length()); return this.requestFactory.newHttpRequest(requestLine); } Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpResponseParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpResponseParser.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpResponseParser.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/HttpResponseParser.java Tue Aug 21 00:46:29 2007 @@ -35,7 +35,7 @@ import org.apache.http.HttpMessage; import org.apache.http.HttpResponseFactory; import org.apache.http.StatusLine; -import org.apache.http.message.BasicStatusLine; +import org.apache.http.message.LineParser; import org.apache.http.nio.reactor.SessionInputBuffer; import org.apache.http.params.HttpParams; import org.apache.http.util.CharArrayBuffer; @@ -46,9 +46,10 @@ public HttpResponseParser( final SessionInputBuffer buffer, + final LineParser parser, final HttpResponseFactory responseFactory, final HttpParams params) { - super(buffer, params); + super(buffer, parser, params); if (responseFactory == null) { throw new IllegalArgumentException("Response factory may not be null"); } @@ -57,7 +58,7 @@ protected HttpMessage createMessage(final CharArrayBuffer buffer) throws HttpException { - StatusLine statusline = BasicStatusLine.parse(buffer, 0, buffer.length()); + StatusLine statusline = lineParser.parseStatusLine(buffer, 0, buffer.length()); return this.responseFactory.newHttpResponse(statusline, null); } Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestHttpMessageParser.java URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestHttpMessageParser.java?rev=567997&r1=567996&r2=567997&view=diff ============================================================================== --- jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestHttpMessageParser.java (original) +++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestHttpMessageParser.java Tue Aug 21 00:46:29 2007 @@ -93,7 +93,7 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); requestParser.fillBuffer(newChannel("GET /whatever HTTP/1.1\r\nSome header: stuff\r\n\r\n")); HttpRequest request = (HttpRequest) requestParser.parse(); assertNotNull(request); @@ -105,7 +105,7 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); requestParser.fillBuffer(newChannel("GET /whatev")); HttpRequest request = (HttpRequest) requestParser.parse(); @@ -126,7 +126,7 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); requestParser.fillBuffer(newChannel("GET /whatev")); HttpRequest request = (HttpRequest) requestParser.parse(); @@ -156,7 +156,7 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); requestParser.fillBuffer(newChannel("GET /whatev")); HttpRequest request = (HttpRequest) requestParser.parse(); @@ -183,7 +183,7 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); requestParser.fillBuffer(newChannel("GET /whatev")); HttpRequest request = (HttpRequest) requestParser.parse(); @@ -213,7 +213,7 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); ReadableByteChannel channel = newChannel("GET /whatever HTTP/1.0"); requestParser.fillBuffer(channel); @@ -227,7 +227,7 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); ReadableByteChannel channel = newChannel("GET /whatever HTTP/1.0\r\nHeader: whatever"); requestParser.fillBuffer(channel); @@ -242,7 +242,7 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); ReadableByteChannel channel = newChannel("GET garbage\r\n"); requestParser.fillBuffer(channel); @@ -258,7 +258,7 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); HttpResponseFactory responseFactory = new DefaultHttpResponseFactory(); - HttpResponseParser responseParser = new HttpResponseParser(inbuf, responseFactory, params); + HttpResponseParser responseParser = new HttpResponseParser(inbuf, null, responseFactory, params); ReadableByteChannel channel = newChannel("HTTP 200 OK\r\n"); responseParser.fillBuffer(channel); @@ -274,7 +274,7 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); HttpResponseFactory responseFactory = new DefaultHttpResponseFactory(); - HttpResponseParser responseParser = new HttpResponseParser(inbuf, responseFactory, params); + HttpResponseParser responseParser = new HttpResponseParser(inbuf, null, responseFactory, params); ReadableByteChannel channel = newChannel("HTTP/1.0 200 OK\r\nstuff\r\n\r\n"); responseParser.fillBuffer(channel); @@ -290,7 +290,7 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); ReadableByteChannel channel = newChannel("GET /whatever HTTP/1.0\r\nHeader: one\r\n\r\n"); requestParser.fillBuffer(channel); @@ -313,25 +313,25 @@ HttpParams params = new BasicHttpParams(); SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 128, params); try { - new HttpRequestParser(null, null, params); + new HttpRequestParser(null, null, null, params); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // ignore } try { - new HttpRequestParser(inbuf, null, params); + new HttpRequestParser(inbuf, null, null, params); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // ignore } try { - new HttpResponseParser(null, null, params); + new HttpResponseParser(null, null, null, params); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // ignore } try { - new HttpResponseParser(inbuf, null, params); + new HttpResponseParser(inbuf, null, null, params); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // ignore @@ -344,13 +344,13 @@ HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); params.setIntParameter(HttpConnectionParams.MAX_LINE_LENGTH, 0); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); requestParser.fillBuffer(newChannel("GET /whatever HTTP/1.0\r\nHeader: one\r\n\r\n")); requestParser.parse(); requestParser.reset(); params.setIntParameter(HttpConnectionParams.MAX_LINE_LENGTH, 15); - requestParser = new HttpRequestParser(inbuf, requestFactory, params); + requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); try { requestParser.fillBuffer(newChannel("GET /loooooooooooooooong HTTP/1.0\r\nHeader: one\r\n\r\n")); requestParser.parse(); @@ -365,13 +365,13 @@ HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); params.setIntParameter(HttpConnectionParams.MAX_LINE_LENGTH, 0); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); requestParser.fillBuffer(newChannel("GET /whatever HTTP/1.0\r\nHeader: one\r\n\r\n")); requestParser.parse(); requestParser.reset(); params.setIntParameter(HttpConnectionParams.MAX_LINE_LENGTH, 15); - requestParser = new HttpRequestParser(inbuf, requestFactory, params); + requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); requestParser.fillBuffer(newChannel("GET / HTTP/1.0\r\nHeader: 9012345\r\n\r\n")); requestParser.parse(); requestParser.reset(); @@ -390,7 +390,7 @@ params.setIntParameter(HttpConnectionParams.MAX_HEADER_COUNT, 2); params.setIntParameter(HttpConnectionParams.MAX_LINE_LENGTH, 15); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); try { requestParser.fillBuffer(newChannel("GET / HTTP/1.0\r\nHeader: 9012345\r\n 23456789012345\r\n 23456789012345\r\n 23456789012345\r\n\r\n")); requestParser.parse(); @@ -405,7 +405,7 @@ HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); params.setIntParameter(HttpConnectionParams.MAX_HEADER_COUNT, 2); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); requestParser.fillBuffer(newChannel("GET /whatever HTTP/1.0\r\nHeader: one\r\nHeader: two\r\n\r\n")); requestParser.parse(); requestParser.reset(); @@ -424,7 +424,7 @@ HttpRequestFactory requestFactory = new DefaultHttpRequestFactory(); params.setIntParameter(HttpConnectionParams.MAX_LINE_LENGTH, 2); - HttpRequestParser requestParser = new HttpRequestParser(inbuf, requestFactory, params); + HttpRequestParser requestParser = new HttpRequestParser(inbuf, null, requestFactory, params); ReadableByteChannel channel = newChannel("GET / HTTP/1.0\r\nHeader: one\r\n\r\n"); assertEquals(2, requestParser.fillBuffer(channel)); assertNull(requestParser.parse());