Home | History | Annotate | Download | only in cookies
      1 // Copyright (c) 2012 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 #ifndef NET_COOKIES_PARSED_COOKIE_H_
      6 #define NET_COOKIES_PARSED_COOKIE_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "net/base/net_export.h"
     13 #include "net/cookies/cookie_constants.h"
     14 
     15 namespace net {
     16 
     17 class NET_EXPORT ParsedCookie {
     18  public:
     19   typedef std::pair<std::string, std::string> TokenValuePair;
     20   typedef std::vector<TokenValuePair> PairList;
     21 
     22   // The maximum length of a cookie string we will try to parse
     23   static const size_t kMaxCookieSize = 4096;
     24   // The maximum number of Token/Value pairs.  Shouldn't have more than 8.
     25   static const int kMaxPairs = 16;
     26 
     27   // Construct from a cookie string like "BLAH=1; path=/; domain=.google.com"
     28   // Format is according to RFC 6265. Cookies with both name and value empty
     29   // will be considered invalid.
     30   ParsedCookie(const std::string& cookie_line);
     31   ~ParsedCookie();
     32 
     33   // You should not call any other methods except for SetName/SetValue on the
     34   // class if !IsValid.
     35   bool IsValid() const;
     36 
     37   const std::string& Name() const { return pairs_[0].first; }
     38   const std::string& Token() const { return Name(); }
     39   const std::string& Value() const { return pairs_[0].second; }
     40 
     41   bool HasPath() const { return path_index_ != 0; }
     42   const std::string& Path() const { return pairs_[path_index_].second; }
     43   bool HasDomain() const { return domain_index_ != 0; }
     44   const std::string& Domain() const { return pairs_[domain_index_].second; }
     45   bool HasExpires() const { return expires_index_ != 0; }
     46   const std::string& Expires() const { return pairs_[expires_index_].second; }
     47   bool HasMaxAge() const { return maxage_index_ != 0; }
     48   const std::string& MaxAge() const { return pairs_[maxage_index_].second; }
     49   bool IsSecure() const { return secure_index_ != 0; }
     50   bool IsHttpOnly() const { return httponly_index_ != 0; }
     51   CookiePriority Priority() const;
     52 
     53   // Returns the number of attributes, for example, returning 2 for:
     54   //   "BLAH=hah; path=/; domain=.google.com"
     55   size_t NumberOfAttributes() const { return pairs_.size() - 1; }
     56 
     57   // These functions set the respective properties of the cookie. If the
     58   // parameters are empty, the respective properties are cleared.
     59   // The functions return false in case an error occurred.
     60   // The cookie needs to be assigned a name/value before setting the other
     61   // attributes.
     62   bool SetName(const std::string& name);
     63   bool SetValue(const std::string& value);
     64   bool SetPath(const std::string& path);
     65   bool SetDomain(const std::string& domain);
     66   bool SetExpires(const std::string& expires);
     67   bool SetMaxAge(const std::string& maxage);
     68   bool SetIsSecure(bool is_secure);
     69   bool SetIsHttpOnly(bool is_http_only);
     70   bool SetPriority(const std::string& priority);
     71 
     72   // Returns the cookie description as it appears in a HTML response header.
     73   std::string ToCookieLine() const;
     74 
     75   // Returns an iterator pointing to the first terminator character found in
     76   // the given string.
     77   static std::string::const_iterator FindFirstTerminator(const std::string& s);
     78 
     79   // Given iterators pointing to the beginning and end of a string segment,
     80   // returns as output arguments token_start and token_end to the start and end
     81   // positions of a cookie attribute token name parsed from the segment, and
     82   // updates the segment iterator to point to the next segment to be parsed.
     83   // If no token is found, the function returns false.
     84   static bool ParseToken(std::string::const_iterator* it,
     85                          const std::string::const_iterator& end,
     86                          std::string::const_iterator* token_start,
     87                          std::string::const_iterator* token_end);
     88 
     89   // Given iterators pointing to the beginning and end of a string segment,
     90   // returns as output arguments value_start and value_end to the start and end
     91   // positions of a cookie attribute value parsed from the segment, and updates
     92   // the segment iterator to point to the next segment to be parsed.
     93   static void ParseValue(std::string::const_iterator* it,
     94                          const std::string::const_iterator& end,
     95                          std::string::const_iterator* value_start,
     96                          std::string::const_iterator* value_end);
     97 
     98   // Same as the above functions, except the input is assumed to contain the
     99   // desired token/value and nothing else.
    100   static std::string ParseTokenString(const std::string& token);
    101   static std::string ParseValueString(const std::string& value);
    102 
    103  private:
    104   void ParseTokenValuePairs(const std::string& cookie_line);
    105   void SetupAttributes();
    106 
    107   // Sets a key/value pair for a cookie. |index| has to point to one of the
    108   // |*_index_| fields in ParsedCookie and is updated to the position where
    109   // the key/value pair is set in |pairs_|. Accordingly, |key| has to correspond
    110   // to the token matching |index|. If |value| contains invalid characters, the
    111   // cookie parameter is not changed and the function returns false.
    112   // If |value| is empty/false the key/value pair is removed.
    113   bool SetString(size_t* index,
    114                  const std::string& key,
    115                  const std::string& value);
    116   bool SetBool(size_t* index,
    117                const std::string& key,
    118                bool value);
    119 
    120   // Helper function for SetString and SetBool handling the case that the
    121   // key/value pair shall not be removed.
    122   bool SetAttributePair(size_t* index,
    123                         const std::string& key,
    124                         const std::string& value);
    125 
    126   // Removes the key/value pair from a cookie that is identified by |index|.
    127   // |index| refers to a position in |pairs_|.
    128   void ClearAttributePair(size_t index);
    129 
    130   PairList pairs_;
    131   bool is_valid_;
    132   // These will default to 0, but that should never be valid since the
    133   // 0th index is the user supplied token/value, not an attribute.
    134   // We're really never going to have more than like 8 attributes, so we
    135   // could fit these into 3 bits each if we're worried about size...
    136   size_t path_index_;
    137   size_t domain_index_;
    138   size_t expires_index_;
    139   size_t maxage_index_;
    140   size_t secure_index_;
    141   size_t httponly_index_;
    142   size_t priority_index_;
    143 
    144   DISALLOW_COPY_AND_ASSIGN(ParsedCookie);
    145 };
    146 
    147 }  // namespace net
    148 
    149 #endif  // NET_COOKIES_COOKIE_MONSTER_H_
    150