OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Brought to you by the letter D and the number 2. | 5 // Brought to you by the letter D and the number 2. |
6 | 6 |
7 #ifndef NET_COOKIES_COOKIE_MONSTER_H_ | 7 #ifndef NET_COOKIES_COOKIE_MONSTER_H_ |
8 #define NET_COOKIES_COOKIE_MONSTER_H_ | 8 #define NET_COOKIES_COOKIE_MONSTER_H_ |
9 | 9 |
10 #include <deque> | 10 #include <deque> |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 class GURL; | 28 class GURL; |
29 | 29 |
30 namespace base { | 30 namespace base { |
31 class Histogram; | 31 class Histogram; |
32 class TimeTicks; | 32 class TimeTicks; |
33 } // namespace base | 33 } // namespace base |
34 | 34 |
35 namespace net { | 35 namespace net { |
36 | 36 |
| 37 class CanonicalCookie; |
37 class CookieList; | 38 class CookieList; |
38 class ParsedCookie; | 39 class ParsedCookie; |
39 | 40 |
40 // The cookie monster is the system for storing and retrieving cookies. It has | 41 // The cookie monster is the system for storing and retrieving cookies. It has |
41 // an in-memory list of all cookies, and synchronizes non-session cookies to an | 42 // an in-memory list of all cookies, and synchronizes non-session cookies to an |
42 // optional permanent storage that implements the PersistentCookieStore | 43 // optional permanent storage that implements the PersistentCookieStore |
43 // interface. | 44 // interface. |
44 // | 45 // |
45 // This class IS thread-safe. Normally, it is only used on the I/O thread, but | 46 // This class IS thread-safe. Normally, it is only used on the I/O thread, but |
46 // is also accessed directly through Automation for UI testing. | 47 // is also accessed directly through Automation for UI testing. |
47 // | 48 // |
48 // All cookie tasks are handled asynchronously. Tasks may be deferred if | 49 // All cookie tasks are handled asynchronously. Tasks may be deferred if |
49 // all affected cookies are not yet loaded from the backing store. Otherwise, | 50 // all affected cookies are not yet loaded from the backing store. Otherwise, |
50 // the callback may be invoked immediately (prior to return of the asynchronous | 51 // the callback may be invoked immediately (prior to return of the asynchronous |
51 // function). | 52 // function). |
52 // | 53 // |
53 // A cookie task is either pending loading of the entire cookie store, or | 54 // A cookie task is either pending loading of the entire cookie store, or |
54 // loading of cookies for a specfic domain key(eTLD+1). In the former case, the | 55 // loading of cookies for a specfic domain key(eTLD+1). In the former case, the |
55 // cookie task will be queued in queue_ while PersistentCookieStore chain loads | 56 // cookie task will be queued in queue_ while PersistentCookieStore chain loads |
56 // the cookie store on DB thread. In the latter case, the cookie task will be | 57 // the cookie store on DB thread. In the latter case, the cookie task will be |
57 // queued in tasks_queued_ while PermanentCookieStore loads cookies for the | 58 // queued in tasks_queued_ while PermanentCookieStore loads cookies for the |
58 // specified domain key(eTLD+1) on DB thread. | 59 // specified domain key(eTLD+1) on DB thread. |
59 // | 60 // |
60 // Callbacks are guaranteed to be invoked on the calling thread. | 61 // Callbacks are guaranteed to be invoked on the calling thread. |
61 // | 62 // |
62 // TODO(deanm) Implement CookieMonster, the cookie database. | 63 // TODO(deanm) Implement CookieMonster, the cookie database. |
63 // - Verify that our domain enforcement and non-dotted handling is correct | 64 // - Verify that our domain enforcement and non-dotted handling is correct |
64 class NET_EXPORT CookieMonster : public CookieStore { | 65 class NET_EXPORT CookieMonster : public CookieStore { |
65 public: | 66 public: |
66 class CanonicalCookie; | |
67 class Delegate; | 67 class Delegate; |
68 class PersistentCookieStore; | 68 class PersistentCookieStore; |
69 | 69 |
70 // Terminology: | 70 // Terminology: |
71 // * The 'top level domain' (TLD) of an internet domain name is | 71 // * The 'top level domain' (TLD) of an internet domain name is |
72 // the terminal "." free substring (e.g. "com" for google.com | 72 // the terminal "." free substring (e.g. "com" for google.com |
73 // or world.std.com). | 73 // or world.std.com). |
74 // * The 'effective top level domain' (eTLD) is the longest | 74 // * The 'effective top level domain' (eTLD) is the longest |
75 // "." initiated terminal substring of an internet domain name | 75 // "." initiated terminal substring of an internet domain name |
76 // that is controlled by a general domain registrar. | 76 // that is controlled by a general domain registrar. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 // monster's existence. If |store| is NULL, then no backing store will be | 112 // monster's existence. If |store| is NULL, then no backing store will be |
113 // updated. If |delegate| is non-NULL, it will be notified on | 113 // updated. If |delegate| is non-NULL, it will be notified on |
114 // creation/deletion of cookies. | 114 // creation/deletion of cookies. |
115 CookieMonster(PersistentCookieStore* store, Delegate* delegate); | 115 CookieMonster(PersistentCookieStore* store, Delegate* delegate); |
116 | 116 |
117 // Only used during unit testing. | 117 // Only used during unit testing. |
118 CookieMonster(PersistentCookieStore* store, | 118 CookieMonster(PersistentCookieStore* store, |
119 Delegate* delegate, | 119 Delegate* delegate, |
120 int last_access_threshold_milliseconds); | 120 int last_access_threshold_milliseconds); |
121 | 121 |
122 // Parses the string with the cookie time (very forgivingly). | |
123 static base::Time ParseCookieTime(const std::string& time_string); | |
124 | |
125 // Helper function that adds all cookies from |list| into this instance. | 122 // Helper function that adds all cookies from |list| into this instance. |
126 bool InitializeFrom(const CookieList& list); | 123 bool InitializeFrom(const CookieList& list); |
127 | 124 |
128 typedef base::Callback<void(const CookieList& cookies)> GetCookieListCallback; | 125 typedef base::Callback<void(const CookieList& cookies)> GetCookieListCallback; |
129 typedef base::Callback<void(bool success)> DeleteCookieCallback; | 126 typedef base::Callback<void(bool success)> DeleteCookieCallback; |
130 | 127 |
131 // Sets a cookie given explicit user-provided cookie attributes. The cookie | 128 // Sets a cookie given explicit user-provided cookie attributes. The cookie |
132 // name, value, domain, etc. are each provided as separate strings. This | 129 // name, value, domain, etc. are each provided as separate strings. This |
133 // function expects each attribute to be well-formed. It will check for | 130 // function expects each attribute to be well-formed. It will check for |
134 // disallowed characters (e.g. the ';' character is disallowed within the | 131 // disallowed characters (e.g. the ';' character is disallowed within the |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 bool persist_session_cookies_; | 650 bool persist_session_cookies_; |
654 | 651 |
655 // Static setting for whether or not file scheme cookies are allows when | 652 // Static setting for whether or not file scheme cookies are allows when |
656 // a new CookieMonster is created, or the accepted schemes on a CookieMonster | 653 // a new CookieMonster is created, or the accepted schemes on a CookieMonster |
657 // instance are reset back to defaults. | 654 // instance are reset back to defaults. |
658 static bool default_enable_file_scheme_; | 655 static bool default_enable_file_scheme_; |
659 | 656 |
660 DISALLOW_COPY_AND_ASSIGN(CookieMonster); | 657 DISALLOW_COPY_AND_ASSIGN(CookieMonster); |
661 }; | 658 }; |
662 | 659 |
663 class NET_EXPORT CookieMonster::CanonicalCookie { | |
664 public: | |
665 | |
666 // These constructors do no validation or canonicalization of their inputs; | |
667 // the resulting CanonicalCookies should not be relied on to be canonical | |
668 // unless the caller has done appropriate validation and canonicalization | |
669 // themselves. | |
670 CanonicalCookie(); | |
671 CanonicalCookie(const GURL& url, | |
672 const std::string& name, | |
673 const std::string& value, | |
674 const std::string& domain, | |
675 const std::string& path, | |
676 const std::string& mac_key, | |
677 const std::string& mac_algorithm, | |
678 const base::Time& creation, | |
679 const base::Time& expiration, | |
680 const base::Time& last_access, | |
681 bool secure, | |
682 bool httponly); | |
683 | |
684 // This constructor does canonicalization but not validation. | |
685 // The result of this constructor should not be relied on in contexts | |
686 // in which pre-validation of the ParsedCookie has not been done. | |
687 CanonicalCookie(const GURL& url, const ParsedCookie& pc); | |
688 | |
689 ~CanonicalCookie(); | |
690 | |
691 // Supports the default copy constructor. | |
692 | |
693 // Creates a canonical cookie from parsed cookie. | |
694 // Canonicalizes and validates inputs. May return NULL if an attribute | |
695 // value is invalid. | |
696 static CanonicalCookie* Create(const GURL& url, | |
697 const ParsedCookie& pc); | |
698 | |
699 // Creates a canonical cookie from unparsed attribute values. | |
700 // Canonicalizes and validates inputs. May return NULL if an attribute | |
701 // value is invalid. | |
702 static CanonicalCookie* Create(const GURL& url, | |
703 const std::string& name, | |
704 const std::string& value, | |
705 const std::string& domain, | |
706 const std::string& path, | |
707 const std::string& mac_key, | |
708 const std::string& mac_algorithm, | |
709 const base::Time& creation, | |
710 const base::Time& expiration, | |
711 bool secure, | |
712 bool http_only); | |
713 | |
714 const std::string& Source() const { return source_; } | |
715 const std::string& Name() const { return name_; } | |
716 const std::string& Value() const { return value_; } | |
717 const std::string& Domain() const { return domain_; } | |
718 const std::string& Path() const { return path_; } | |
719 const std::string& MACKey() const { return mac_key_; } | |
720 const std::string& MACAlgorithm() const { return mac_algorithm_; } | |
721 const base::Time& CreationDate() const { return creation_date_; } | |
722 const base::Time& LastAccessDate() const { return last_access_date_; } | |
723 bool IsPersistent() const { return !expiry_date_.is_null(); } | |
724 const base::Time& ExpiryDate() const { return expiry_date_; } | |
725 bool IsSecure() const { return secure_; } | |
726 bool IsHttpOnly() const { return httponly_; } | |
727 bool IsDomainCookie() const { | |
728 return !domain_.empty() && domain_[0] == '.'; } | |
729 bool IsHostCookie() const { return !IsDomainCookie(); } | |
730 | |
731 bool IsExpired(const base::Time& current) { | |
732 return !expiry_date_.is_null() && current >= expiry_date_; | |
733 } | |
734 | |
735 // Are the cookies considered equivalent in the eyes of RFC 2965. | |
736 // The RFC says that name must match (case-sensitive), domain must | |
737 // match (case insensitive), and path must match (case sensitive). | |
738 // For the case insensitive domain compare, we rely on the domain | |
739 // having been canonicalized (in | |
740 // GetCookieDomainWithString->CanonicalizeHost). | |
741 bool IsEquivalent(const CanonicalCookie& ecc) const { | |
742 // It seems like it would make sense to take secure and httponly into | |
743 // account, but the RFC doesn't specify this. | |
744 // NOTE: Keep this logic in-sync with TrimDuplicateCookiesForHost(). | |
745 return (name_ == ecc.Name() && domain_ == ecc.Domain() | |
746 && path_ == ecc.Path()); | |
747 } | |
748 | |
749 void SetLastAccessDate(const base::Time& date) { | |
750 last_access_date_ = date; | |
751 } | |
752 | |
753 bool IsOnPath(const std::string& url_path) const; | |
754 bool IsDomainMatch(const std::string& scheme, const std::string& host) const; | |
755 | |
756 std::string DebugString() const; | |
757 | |
758 // Returns the cookie source when cookies are set for |url|. This function | |
759 // is public for unit test purposes only. | |
760 static std::string GetCookieSourceFromURL(const GURL& url); | |
761 | |
762 private: | |
763 // Gives the session cookie an expiration time if needed | |
764 void SetSessionCookieExpiryTime(); | |
765 | |
766 // The source member of a canonical cookie is the origin of the URL that tried | |
767 // to set this cookie, minus the port number if any. This field is not | |
768 // persistent though; its only used in the in-tab cookies dialog to show the | |
769 // user the source URL. This is used for both allowed and blocked cookies. | |
770 // When a CanonicalCookie is constructed from the backing store (common case) | |
771 // this field will be null. CanonicalCookie consumers should not rely on | |
772 // this field unless they guarantee that the creator of those | |
773 // CanonicalCookies properly initialized the field. | |
774 // TODO(abarth): We might need to make this field persistent for MAC cookies. | |
775 std::string source_; | |
776 std::string name_; | |
777 std::string value_; | |
778 std::string domain_; | |
779 std::string path_; | |
780 std::string mac_key_; // TODO(abarth): Persist to disk. | |
781 std::string mac_algorithm_; // TODO(abarth): Persist to disk. | |
782 base::Time creation_date_; | |
783 base::Time expiry_date_; | |
784 base::Time last_access_date_; | |
785 bool secure_; | |
786 bool httponly_; | |
787 }; | |
788 | |
789 class CookieMonster::Delegate | 660 class CookieMonster::Delegate |
790 : public base::RefCountedThreadSafe<CookieMonster::Delegate> { | 661 : public base::RefCountedThreadSafe<CookieMonster::Delegate> { |
791 public: | 662 public: |
792 // The publicly relevant reasons a cookie might be changed. | 663 // The publicly relevant reasons a cookie might be changed. |
793 enum ChangeCause { | 664 enum ChangeCause { |
794 // The cookie was changed directly by a consumer's action. | 665 // The cookie was changed directly by a consumer's action. |
795 CHANGE_COOKIE_EXPLICIT, | 666 CHANGE_COOKIE_EXPLICIT, |
796 // The cookie was automatically removed due to an insert operation that | 667 // The cookie was automatically removed due to an insert operation that |
797 // overwrote it. | 668 // overwrote it. |
798 CHANGE_COOKIE_OVERWRITE, | 669 CHANGE_COOKIE_OVERWRITE, |
799 // The cookie was automatically removed as it expired. | 670 // The cookie was automatically removed as it expired. |
800 CHANGE_COOKIE_EXPIRED, | 671 CHANGE_COOKIE_EXPIRED, |
801 // The cookie was automatically evicted during garbage collection. | 672 // The cookie was automatically evicted during garbage collection. |
802 CHANGE_COOKIE_EVICTED, | 673 CHANGE_COOKIE_EVICTED, |
803 // The cookie was overwritten with an already-expired expiration date. | 674 // The cookie was overwritten with an already-expired expiration date. |
804 CHANGE_COOKIE_EXPIRED_OVERWRITE | 675 CHANGE_COOKIE_EXPIRED_OVERWRITE |
805 }; | 676 }; |
806 | 677 |
807 // Will be called when a cookie is added or removed. The function is passed | 678 // Will be called when a cookie is added or removed. The function is passed |
808 // the respective |cookie| which was added to or removed from the cookies. | 679 // the respective |cookie| which was added to or removed from the cookies. |
809 // If |removed| is true, the cookie was deleted, and |cause| will be set | 680 // If |removed| is true, the cookie was deleted, and |cause| will be set |
810 // to the reason for its removal. If |removed| is false, the cookie was | 681 // to the reason for its removal. If |removed| is false, the cookie was |
811 // added, and |cause| will be set to CHANGE_COOKIE_EXPLICIT. | 682 // added, and |cause| will be set to CHANGE_COOKIE_EXPLICIT. |
812 // | 683 // |
813 // As a special case, note that updating a cookie's properties is implemented | 684 // As a special case, note that updating a cookie's properties is implemented |
814 // as a two step process: the cookie to be updated is first removed entirely, | 685 // as a two step process: the cookie to be updated is first removed entirely, |
815 // generating a notification with cause CHANGE_COOKIE_OVERWRITE. Afterwards, | 686 // generating a notification with cause CHANGE_COOKIE_OVERWRITE. Afterwards, |
816 // a new cookie is written with the updated values, generating a notification | 687 // a new cookie is written with the updated values, generating a notification |
817 // with cause CHANGE_COOKIE_EXPLICIT. | 688 // with cause CHANGE_COOKIE_EXPLICIT. |
818 virtual void OnCookieChanged(const CookieMonster::CanonicalCookie& cookie, | 689 virtual void OnCookieChanged(const CanonicalCookie& cookie, |
819 bool removed, | 690 bool removed, |
820 ChangeCause cause) = 0; | 691 ChangeCause cause) = 0; |
821 protected: | 692 protected: |
822 friend class base::RefCountedThreadSafe<CookieMonster::Delegate>; | 693 friend class base::RefCountedThreadSafe<CookieMonster::Delegate>; |
823 virtual ~Delegate() {} | 694 virtual ~Delegate() {} |
824 }; | 695 }; |
825 | 696 |
826 typedef base::RefCountedThreadSafe<CookieMonster::PersistentCookieStore> | 697 typedef base::RefCountedThreadSafe<CookieMonster::PersistentCookieStore> |
827 RefcountedPersistentCookieStore; | 698 RefcountedPersistentCookieStore; |
828 | 699 |
829 class CookieMonster::PersistentCookieStore | 700 class CookieMonster::PersistentCookieStore |
830 : public RefcountedPersistentCookieStore { | 701 : public RefcountedPersistentCookieStore { |
831 public: | 702 public: |
832 typedef base::Callback<void(const std::vector< | 703 typedef base::Callback<void(const std::vector<CanonicalCookie*>&)> |
833 CookieMonster::CanonicalCookie*>&)> LoadedCallback; | 704 LoadedCallback; |
834 | 705 |
835 // Initializes the store and retrieves the existing cookies. This will be | 706 // Initializes the store and retrieves the existing cookies. This will be |
836 // called only once at startup. The callback will return all the cookies | 707 // called only once at startup. The callback will return all the cookies |
837 // that are not yet returned to CookieMonster by previous priority loads. | 708 // that are not yet returned to CookieMonster by previous priority loads. |
838 virtual void Load(const LoadedCallback& loaded_callback) = 0; | 709 virtual void Load(const LoadedCallback& loaded_callback) = 0; |
839 | 710 |
840 // Does a priority load of all cookies for the domain key (eTLD+1). The | 711 // Does a priority load of all cookies for the domain key (eTLD+1). The |
841 // callback will return all the cookies that are not yet returned by previous | 712 // callback will return all the cookies that are not yet returned by previous |
842 // loads, which includes cookies for the requested domain key if they are not | 713 // loads, which includes cookies for the requested domain key if they are not |
843 // already returned, plus all cookies that are chain-loaded and not yet | 714 // already returned, plus all cookies that are chain-loaded and not yet |
(...skipping 13 matching lines...) Expand all Loading... |
857 | 728 |
858 protected: | 729 protected: |
859 PersistentCookieStore() {} | 730 PersistentCookieStore() {} |
860 virtual ~PersistentCookieStore() {} | 731 virtual ~PersistentCookieStore() {} |
861 | 732 |
862 private: | 733 private: |
863 friend class base::RefCountedThreadSafe<PersistentCookieStore>; | 734 friend class base::RefCountedThreadSafe<PersistentCookieStore>; |
864 DISALLOW_COPY_AND_ASSIGN(PersistentCookieStore); | 735 DISALLOW_COPY_AND_ASSIGN(PersistentCookieStore); |
865 }; | 736 }; |
866 | 737 |
867 class CookieList : public std::vector<CookieMonster::CanonicalCookie> { | |
868 }; | |
869 | |
870 } // namespace net | 738 } // namespace net |
871 | 739 |
872 #endif // NET_COOKIES_COOKIE_MONSTER_H_ | 740 #endif // NET_COOKIES_COOKIE_MONSTER_H_ |
OLD | NEW |