Home | History | Annotate | Download | only in http
      1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 //
      5 // HttpRequestHeaders manages the request headers.
      6 // It maintains these in a vector of header key/value pairs, thereby maintaining
      7 // the order of the headers.  This means that any lookups are linear time
      8 // operations.
      9 
     10 #ifndef NET_HTTP_HTTP_REQUEST_HEADERS_H_
     11 #define NET_HTTP_HTTP_REQUEST_HEADERS_H_
     12 #pragma once
     13 
     14 #include <string>
     15 #include <vector>
     16 #include "base/basictypes.h"
     17 #include "base/string_piece.h"
     18 #include "net/base/net_export.h"
     19 
     20 namespace net {
     21 
     22 class NET_EXPORT HttpRequestHeaders {
     23  public:
     24   struct HeaderKeyValuePair {
     25     HeaderKeyValuePair();
     26     HeaderKeyValuePair(const base::StringPiece& key,
     27                        const base::StringPiece& value);
     28 
     29     std::string key;
     30     std::string value;
     31   };
     32 
     33   typedef std::vector<HeaderKeyValuePair> HeaderVector;
     34 
     35   class Iterator {
     36    public:
     37     explicit Iterator(const HttpRequestHeaders& headers);
     38     ~Iterator();
     39 
     40     // Advances the iterator to the next header, if any.  Returns true if there
     41     // is a next header.  Use name() and value() methods to access the resultant
     42     // header name and value.
     43     bool GetNext();
     44 
     45     // These two accessors are only valid if GetNext() returned true.
     46     const std::string& name() const { return curr_->key; }
     47     const std::string& value() const { return curr_->value; }
     48 
     49    private:
     50     bool started_;
     51     HttpRequestHeaders::HeaderVector::const_iterator curr_;
     52     const HttpRequestHeaders::HeaderVector::const_iterator end_;
     53 
     54     DISALLOW_COPY_AND_ASSIGN(Iterator);
     55   };
     56 
     57   static const char kGetMethod[];
     58 
     59   static const char kAcceptCharset[];
     60   static const char kAcceptEncoding[];
     61   static const char kAcceptLanguage[];
     62   static const char kCacheControl[];
     63   static const char kConnection[];
     64   static const char kContentType[];
     65   static const char kCookie[];
     66   static const char kContentLength[];
     67   static const char kHost[];
     68   static const char kIfModifiedSince[];
     69   static const char kIfNoneMatch[];
     70   static const char kIfRange[];
     71   static const char kOrigin[];
     72   static const char kPragma[];
     73   static const char kProxyConnection[];
     74   static const char kRange[];
     75   static const char kReferer[];
     76   static const char kUserAgent[];
     77   static const char kTransferEncoding[];
     78 
     79   HttpRequestHeaders();
     80   ~HttpRequestHeaders();
     81 
     82   bool IsEmpty() const { return headers_.empty(); }
     83 
     84   bool HasHeader(const base::StringPiece& key) const {
     85     return FindHeader(key) != headers_.end();
     86   }
     87 
     88   // Gets the first header that matches |key|.  If found, returns true and
     89   // writes the value to |out|.
     90   bool GetHeader(const base::StringPiece& key, std::string* out) const;
     91 
     92   // Clears all the headers.
     93   void Clear();
     94 
     95   // Sets the header value pair for |key| and |value|.  If |key| already exists,
     96   // then the header value is modified, but the key is untouched, and the order
     97   // in the vector remains the same.  When comparing |key|, case is ignored.
     98   void SetHeader(const base::StringPiece& key, const base::StringPiece& value);
     99 
    100   // Sets the header value pair for |key| and |value|, if |key| does not exist.
    101   // If |key| already exists, the call is a no-op.
    102   // When comparing |key|, case is ignored.
    103   void SetHeaderIfMissing(const base::StringPiece& key,
    104                           const base::StringPiece& value);
    105 
    106   // Removes the first header that matches (case insensitive) |key|.
    107   void RemoveHeader(const base::StringPiece& key);
    108 
    109   // Parses the header from a string and calls SetHeader() with it.  This string
    110   // should not contain any CRLF.  As per RFC2616, the format is:
    111   //
    112   // message-header = field-name ":" [ field-value ]
    113   // field-name     = token
    114   // field-value    = *( field-content | LWS )
    115   // field-content  = <the OCTETs making up the field-value
    116   //                  and consisting of either *TEXT or combinations
    117   //                  of token, separators, and quoted-string>
    118   //
    119   // AddHeaderFromString() will trim any LWS surrounding the
    120   // field-content.
    121   void AddHeaderFromString(const base::StringPiece& header_line);
    122 
    123   // Same thing as AddHeaderFromString() except that |headers| is a "\r\n"
    124   // delimited string of header lines.  It will split up the string by "\r\n"
    125   // and call AddHeaderFromString() on each.
    126   void AddHeadersFromString(const base::StringPiece& headers);
    127 
    128   // Calls SetHeader() on each header from |other|, maintaining order.
    129   void MergeFrom(const HttpRequestHeaders& other);
    130 
    131   // Copies from |other| to |this|.
    132   void CopyFrom(const HttpRequestHeaders& other) {
    133     *this = other;
    134   }
    135 
    136   // Serializes HttpRequestHeaders to a string representation.  Joins all the
    137   // header keys and values with ": ", and inserts "\r\n" between each header
    138   // line, and adds the trailing "\r\n".
    139   std::string ToString() const;
    140 
    141  private:
    142   HeaderVector::iterator FindHeader(const base::StringPiece& key);
    143   HeaderVector::const_iterator FindHeader(const base::StringPiece& key) const;
    144 
    145   HeaderVector headers_;
    146 
    147   // Allow the copy construction and operator= to facilitate copying in
    148   // HttpRequestInfo.
    149   // TODO(willchan): Investigate to see if we can remove the need to copy
    150   // HttpRequestInfo.
    151   // DISALLOW_COPY_AND_ASSIGN(HttpRequestHeaders);
    152 };
    153 
    154 }  // namespace net
    155 
    156 #endif  // NET_HTTP_HTTP_REQUEST_HEADERS_H_
    157