You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by js...@apache.org on 2003/02/11 06:04:11 UTC

cvs commit: jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util HeaderParser.java

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.
       * 
       * <p>Header name comparison is case insensitive.
       * 
       * @param name the name of the header(s) to get
       * @return a header with a condensed value or <code>null</code> 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.  
       * 
       * <p>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.
       * 
       * <p>Header name comparison is case insensitive.
       * 
       * @param name the name of the header to get
       * @return the first header or <code>null</code>
       */
      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.
       *
       * <p>Header name comparison is case insensitive.
       *
       * @param name the name of the header to get
       * @return the last header or <code>null</code>
       */
      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.
       * 
       * <p>Header name comparison is case insensitive.
       * 
       * @param name the header name to test for
       * @return <code>true</code> if at least one header with the name is
       * contained, <code>false</code> 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