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_CANONICAL_COOKIE_H_
6#define NET_COOKIES_CANONICAL_COOKIE_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/time/time.h"
13#include "net/base/net_export.h"
14#include "net/cookies/cookie_constants.h"
15#include "net/cookies/cookie_options.h"
16
17class GURL;
18
19namespace net {
20
21class ParsedCookie;
22
23class NET_EXPORT CanonicalCookie {
24 public:
25  // These constructors do no validation or canonicalization of their inputs;
26  // the resulting CanonicalCookies should not be relied on to be canonical
27  // unless the caller has done appropriate validation and canonicalization
28  // themselves.
29  CanonicalCookie();
30  CanonicalCookie(const GURL& url,
31                  const std::string& name,
32                  const std::string& value,
33                  const std::string& domain,
34                  const std::string& path,
35                  const base::Time& creation,
36                  const base::Time& expiration,
37                  const base::Time& last_access,
38                  bool secure,
39                  bool httponly,
40                  CookiePriority priority);
41
42  // This constructor does canonicalization but not validation.
43  // The result of this constructor should not be relied on in contexts
44  // in which pre-validation of the ParsedCookie has not been done.
45  CanonicalCookie(const GURL& url, const ParsedCookie& pc);
46
47  ~CanonicalCookie();
48
49  // Supports the default copy constructor.
50
51  // Creates a new |CanonicalCookie| from the |cookie_line| and the
52  // |creation_time|. Canonicalizes and validates inputs. May return NULL if
53  // an attribut value is invalid.
54  static CanonicalCookie* Create(const GURL& url,
55                                 const std::string& cookie_line,
56                                 const base::Time& creation_time,
57                                 const CookieOptions& options);
58
59  // Creates a canonical cookie from unparsed attribute values.
60  // Canonicalizes and validates inputs.  May return NULL if an attribute
61  // value is invalid.
62  static CanonicalCookie* Create(const GURL& url,
63                                 const std::string& name,
64                                 const std::string& value,
65                                 const std::string& domain,
66                                 const std::string& path,
67                                 const base::Time& creation,
68                                 const base::Time& expiration,
69                                 bool secure,
70                                 bool http_only,
71                                 CookiePriority priority);
72
73  const std::string& Source() const { return source_; }
74  const std::string& Name() const { return name_; }
75  const std::string& Value() const { return value_; }
76  const std::string& Domain() const { return domain_; }
77  const std::string& Path() const { return path_; }
78  const base::Time& CreationDate() const { return creation_date_; }
79  const base::Time& LastAccessDate() const { return last_access_date_; }
80  bool IsPersistent() const { return !expiry_date_.is_null(); }
81  const base::Time& ExpiryDate() const { return expiry_date_; }
82  bool IsSecure() const { return secure_; }
83  bool IsHttpOnly() const { return httponly_; }
84  CookiePriority Priority() const { return priority_; }
85  bool IsDomainCookie() const {
86    return !domain_.empty() && domain_[0] == '.'; }
87  bool IsHostCookie() const { return !IsDomainCookie(); }
88
89  bool IsExpired(const base::Time& current) const {
90    return !expiry_date_.is_null() && current >= expiry_date_;
91  }
92
93  // Are the cookies considered equivalent in the eyes of RFC 2965.
94  // The RFC says that name must match (case-sensitive), domain must
95  // match (case insensitive), and path must match (case sensitive).
96  // For the case insensitive domain compare, we rely on the domain
97  // having been canonicalized (in
98  // GetCookieDomainWithString->CanonicalizeHost).
99  bool IsEquivalent(const CanonicalCookie& ecc) const {
100    // It seems like it would make sense to take secure and httponly into
101    // account, but the RFC doesn't specify this.
102    // NOTE: Keep this logic in-sync with TrimDuplicateCookiesForHost().
103    return (name_ == ecc.Name() && domain_ == ecc.Domain()
104            && path_ == ecc.Path());
105  }
106
107  void SetLastAccessDate(const base::Time& date) {
108    last_access_date_ = date;
109  }
110
111  // Returns true if the given |url_path| path-matches the cookie-path as
112  // described in section 5.1.4 in RFC 6265.
113  bool IsOnPath(const std::string& url_path) const;
114
115  // Returns true if the cookie domain matches the given |host| as described in
116  // section 5.1.3 of RFC 6265.
117  bool IsDomainMatch(const std::string& host) const;
118
119  // Returns true if the cookie should be included for the given request |url|.
120  // HTTP only cookies can be filter by using appropriate cookie |options|.
121  // PLEASE NOTE that this method does not check whether a cookie is expired or
122  // not!
123  bool IncludeForRequestURL(const GURL& url,
124                            const CookieOptions& options) const;
125
126  std::string DebugString() const;
127
128  // Returns a duplicate of this cookie.
129  CanonicalCookie* Duplicate();
130
131  // Returns the cookie source when cookies are set for |url|. This function
132  // is public for unit test purposes only.
133  static std::string GetCookieSourceFromURL(const GURL& url);
134  static std::string CanonPath(const GURL& url, const ParsedCookie& pc);
135  static base::Time CanonExpiration(const ParsedCookie& pc,
136                                    const base::Time& current,
137                                    const base::Time& server_time);
138
139 private:
140  // NOTE: When any new members are added below, the implementation of
141  // Duplicate() must be updated to copy the new member accordingly.
142
143  // The source member of a canonical cookie is the origin of the URL that tried
144  // to set this cookie, minus the port number if any.  This field is not
145  // persistent though; its only used in the in-tab cookies dialog to show the
146  // user the source URL. This is used for both allowed and blocked cookies.
147  // When a CanonicalCookie is constructed from the backing store (common case)
148  // this field will be null.  CanonicalCookie consumers should not rely on
149  // this field unless they guarantee that the creator of those
150  // CanonicalCookies properly initialized the field.
151  std::string source_;
152  std::string name_;
153  std::string value_;
154  std::string domain_;
155  std::string path_;
156  base::Time creation_date_;
157  base::Time expiry_date_;
158  base::Time last_access_date_;
159  bool secure_;
160  bool httponly_;
161  CookiePriority priority_;
162  // NOTE: When any new members are added above this comment, the
163  // implementation of Duplicate() must be updated to copy the new member
164  // accordingly.
165};
166
167typedef std::vector<CanonicalCookie> CookieList;
168
169}  // namespace net
170
171#endif  // NET_COOKIES_CANONICAL_COOKIE_H_
172