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