Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@apache.org Received: (qmail 23563 invoked from network); 11 Feb 2003 05:04:14 -0000 Received: from exchange.sun.com (192.18.33.10) by daedalus.apache.org with SMTP; 11 Feb 2003 05:04:14 -0000 Received: (qmail 19926 invoked by uid 97); 11 Feb 2003 05:05:54 -0000 Delivered-To: qmlist-jakarta-archive-commons-dev@nagoya.betaversion.org Received: (qmail 19919 invoked from network); 11 Feb 2003 05:05:53 -0000 Received: from daedalus.apache.org (HELO apache.org) (208.185.179.12) by nagoya.betaversion.org with SMTP; 11 Feb 2003 05:05:53 -0000 Received: (qmail 23370 invoked by uid 500); 11 Feb 2003 05:04:12 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 23359 invoked by uid 500); 11 Feb 2003 05:04:12 -0000 Received: (qmail 23356 invoked from network); 11 Feb 2003 05:04:12 -0000 Received: from icarus.apache.org (208.185.179.13) by daedalus.apache.org with SMTP; 11 Feb 2003 05:04:12 -0000 Received: (qmail 19092 invoked by uid 1536); 11 Feb 2003 05:04:11 -0000 Date: 11 Feb 2003 05:04:11 -0000 Message-ID: <20030211050411.19091.qmail@icarus.apache.org> From: jsdever@apache.org To: jakarta-commons-cvs@apache.org Subject: cvs commit: jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util HeaderParser.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N jsdever 2003/02/10 21:04:10 Added: httpclient/src/java/org/apache/commons/httpclient HeaderGroup.java httpclient/src/java/org/apache/commons/httpclient/util HeaderParser.java Log: Multivalued headers. Bug: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=11218 Contributed by: Mike Becke changeLog: - HeaderGroup, a new class for storing headers. This class supports multiple headers with the same name and it remembers header order. I'm not a huge fan of the name, but it was the best I could come up with. - HeaderParser, a new class for parsing headers. Header parsing code was duplicated in HttpMethodBase and ChunkedInputStream and was placed here. - HttpMethod has 3 new methods. getRequestHeaderGroup(), getResponseHeaderGroup(), and getResponseFooterGroup(). This will break an existing extension of HttpMethod. - Some of the methods for accessing headers in HttpMethod have been deprecated. - Classes in the general codebase that use the newly deprecated methods have been fixed. Some of the test cases are still using deprecated methods. - SimpleHttpConnection and SimpleHttpMethod have been changed to work correctly with the new header storage method. Revision Changes Path 1.1 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HeaderGroup.java Index: HeaderGroup.java =================================================================== package org.apache.commons.httpclient; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * A class for combining a set of headers. This class allows for multiple * headers with the same name and keeps track of the order in which headers were * added. * * @author Michael Becke * * @since 2.0beta1 */ public class HeaderGroup { private List headers; /** * Constructor for HeaderGroup. */ public HeaderGroup() { this.headers = new ArrayList(); } /** * Removes any contained headers. */ public void clear() { headers.clear(); } /** * Adds the given header to the group. The order in which this header was * added is preserved. * * @param header the header to add */ public void addHeader(Header header) { headers.add(header); } /** * Removes the given header. * * @param header the header to remove */ public void removeHeader(Header header) { headers.remove(header); } /** * Sets all of the headers contained within this group overriding any * existing headers. The headers are added in the order in which they appear * in the array. * * @param headers the headers to set */ public void setHeaders(Header[] headers) { clear(); for (int i = 0; i < headers.length; i++) { addHeader(headers[i]); } } /** * Gets a header representing all of the header values with the given name. * If more that one header with the given name exists the values will be * combined with a "," as per RFC 1945. * *

Header name comparison is case insensitive. * * @param name the name of the header(s) to get * @return a header with a condensed value or null if no * headers by the given name are present */ public Header getCondensedHeader(String name) { Header[] headers = getHeaders(name); if (headers.length == 0) { return null; } else if (headers.length == 1) { return new Header(headers[0].getName(), headers[0].getValue()); } else { StringBuffer valueBuffer = new StringBuffer(headers[0].getValue()); for (int i = 1; i < headers.length; i++) { valueBuffer.append(", "); valueBuffer.append(headers[i].getValue()); } return new Header(name.toLowerCase(), valueBuffer.toString()); } } /** * Gets all of the headers with the given name. The returned array * maintains the relative order in which the headers were added. * *

Header name comparison is case insensitive. * * @param name the name of the header(s) to get * * @return an array of length >= 0 */ public Header[] getHeaders(String name) { ArrayList headersFound = new ArrayList(); for (Iterator headerIter = headers.iterator(); headerIter.hasNext();) { Header header = (Header) headerIter.next(); if (header.getName().equalsIgnoreCase(name)) { headersFound.add(header); } } return (Header[]) headersFound.toArray(new Header[headersFound.size()]); } /** * Gets the first header with the given name. * *

Header name comparison is case insensitive. * * @param name the name of the header to get * @return the first header or null */ public Header getFirstHeader(String name) { for (Iterator headerIter = headers.iterator(); headerIter.hasNext();) { Header header = (Header) headerIter.next(); if (header.getName().equalsIgnoreCase(name)) { return header; } } return null; } /** * Gets the last header with the given name. * *

Header name comparison is case insensitive. * * @param name the name of the header to get * @return the last header or null */ public Header getLastHeader(String name) { // start at the end of the list and work backwards for (int i = headers.size() - 1; i >= 0; i--) { Header header = (Header) headers.get(i); if (header.getName().equalsIgnoreCase(name)) { return header; } } return null; } /** * Gets all of the headers contained within this group. * * @return an array of length >= 0 */ public Header[] getAllHeaders() { return (Header[]) headers.toArray(new Header[headers.size()]); } /** * Tests if headers with the given name are contained within this group. * *

Header name comparison is case insensitive. * * @param name the header name to test for * @return true if at least one header with the name is * contained, false otherwise */ public boolean containsHeader(String name) { for (Iterator headerIter = headers.iterator(); headerIter.hasNext();) { Header header = (Header) headerIter.next(); if (header.getName().equalsIgnoreCase(name)) { return true; } } return false; } } 1.1 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/HeaderParser.java Index: HeaderParser.java =================================================================== package org.apache.commons.httpclient.util; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpConnection; import org.apache.commons.httpclient.HttpException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * A utility class for parsing http header values. * * @author Michael Becke * * @since 2.0beta1 */ public class HeaderParser { /** Log object for this class. */ private static final Log LOG = LogFactory.getLog(HeaderParser.class); /** * Constructor for HeaderParser. */ private HeaderParser() {} /** * Parses headers from the given stream. Headers with the same name are not * combined. * * @param is the stream to read headers from * * @return an array of headers in the order in which they were parsed * * @throws IOException if an IO error occurs while reading from the stream * @throws HttpException if there is an error parsing a header value */ public static Header[] parseHeaders(InputStream is) throws IOException, HttpException { LOG.trace("enter HeaderParser.parseHeaders(HttpConnection, HeaderGroup)"); ArrayList headers = new ArrayList(); String name = null; StringBuffer value = null; for (; ;) { String line = HttpConnection.readLine(is); if ((line == null) || (line.length() < 1)) { break; } // Parse the header name and value // Check for folded headers first // Detect LWS-char see HTTP/1.0 or HTTP/1.1 Section 2.2 // discussion on folded headers if ((line.charAt(0) == ' ') || (line.charAt(0) == '\t')) { // we have continuation folded header // so append value value.append(' '); value.append(line.trim()); } else { // make sure we save the previous name,value pair if present if (name != null) { headers.add(new Header(name, value.toString())); } // Otherwise we should have normal HTTP header line // Parse the header name and value int colon = line.indexOf(":"); if (colon < 0) { throw new HttpException("Unable to parse header: " + line); } name = line.substring(0, colon).trim(); value = new StringBuffer(line.substring(colon + 1).trim()); } } // make sure we save the last name,value pair if present if (name != null) { headers.add(new Header(name, value.toString())); } return (Header[]) headers.toArray(new Header[headers.size()]); } } --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org