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