1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef mozilla_net_CookieStorage_h 7 #define mozilla_net_CookieStorage_h 8 9 #include "CookieKey.h" 10 11 #include "nsIObserver.h" 12 #include "nsTHashtable.h" 13 #include "nsWeakReference.h" 14 #include <functional> 15 16 class nsIArray; 17 class nsICookie; 18 class nsIPrefBranch; 19 20 namespace mozilla { 21 namespace net { 22 23 class Cookie; 24 25 // Inherit from CookieKey so this can be stored in nsTHashTable 26 // TODO: why aren't we using nsClassHashTable<CookieKey, ArrayType>? 27 class CookieEntry : public CookieKey { 28 public: 29 // Hash methods 30 typedef nsTArray<RefPtr<Cookie>> ArrayType; 31 typedef ArrayType::index_type IndexType; 32 CookieEntry(KeyTypePointer aKey)33 explicit CookieEntry(KeyTypePointer aKey) : CookieKey(aKey) {} 34 CookieEntry(const CookieEntry & toCopy)35 CookieEntry(const CookieEntry& toCopy) { 36 // if we end up here, things will break. nsTHashtable shouldn't 37 // allow this, since we set ALLOW_MEMMOVE to true. 38 MOZ_ASSERT_UNREACHABLE("CookieEntry copy constructor is forbidden!"); 39 } 40 41 ~CookieEntry() = default; 42 GetCookies()43 inline ArrayType& GetCookies() { return mCookies; } 44 45 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const; 46 47 private: 48 ArrayType mCookies; 49 }; 50 51 // stores the CookieEntry entryclass and an index into the cookie array within 52 // that entryclass, for purposes of storing an iteration state that points to a 53 // certain cookie. 54 struct CookieListIter { 55 // default (non-initializing) constructor. 56 CookieListIter() = default; 57 58 // explicit constructor to a given iterator state with entryclass 'aEntry' 59 // and index 'aIndex'. CookieListIterCookieListIter60 explicit CookieListIter(CookieEntry* aEntry, CookieEntry::IndexType aIndex) 61 : entry(aEntry), index(aIndex) {} 62 63 // get the Cookie * the iterator currently points to. CookieCookieListIter64 mozilla::net::Cookie* Cookie() const { return entry->GetCookies()[index]; } 65 66 CookieEntry* entry; 67 CookieEntry::IndexType index; 68 }; 69 70 class CookieStorage : public nsIObserver, public nsSupportsWeakReference { 71 public: 72 NS_DECL_THREADSAFE_ISUPPORTS 73 NS_DECL_NSIOBSERVER 74 75 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const; 76 77 void GetCookies(nsTArray<RefPtr<nsICookie>>& aCookies) const; 78 79 void GetSessionCookies(nsTArray<RefPtr<nsICookie>>& aCookies) const; 80 81 bool FindCookie(const nsACString& aBaseDomain, 82 const OriginAttributes& aOriginAttributes, 83 const nsACString& aHost, const nsACString& aName, 84 const nsACString& aPath, CookieListIter& aIter); 85 86 uint32_t CountCookiesFromHost(const nsACString& aBaseDomain, 87 uint32_t aPrivateBrowsingId); 88 89 void GetAll(nsTArray<RefPtr<nsICookie>>& aResult) const; 90 91 const nsTArray<RefPtr<Cookie>>* GetCookiesFromHost( 92 const nsACString& aBaseDomain, const OriginAttributes& aOriginAttributes); 93 94 void GetCookiesWithOriginAttributes(const OriginAttributesPattern& aPattern, 95 const nsACString& aBaseDomain, 96 nsTArray<RefPtr<nsICookie>>& aResult); 97 98 void RemoveCookie(const nsACString& aBaseDomain, 99 const OriginAttributes& aOriginAttributes, 100 const nsACString& aHost, const nsACString& aName, 101 const nsACString& aPath); 102 103 virtual void RemoveCookiesWithOriginAttributes( 104 const OriginAttributesPattern& aPattern, const nsACString& aBaseDomain); 105 106 virtual void RemoveCookiesFromExactHost( 107 const nsACString& aHost, const nsACString& aBaseDomain, 108 const OriginAttributesPattern& aPattern); 109 110 void RemoveAll(); 111 112 void NotifyChanged(nsISupports* aSubject, const char16_t* aData, 113 bool aOldCookieIsSession = false); 114 115 void AddCookie(const nsACString& aBaseDomain, 116 const OriginAttributes& aOriginAttributes, Cookie* aCookie, 117 int64_t aCurrentTimeInUsec, nsIURI* aHostURI, 118 const nsACString& aCookieHeader, bool aFromHttp); 119 120 static void CreateOrUpdatePurgeList(nsIArray** aPurgedList, 121 nsICookie* aCookie); 122 123 virtual void StaleCookies(const nsTArray<Cookie*>& aCookieList, 124 int64_t aCurrentTimeInUsec) = 0; 125 126 virtual void Close() = 0; 127 128 protected: 129 CookieStorage(); 130 virtual ~CookieStorage(); 131 132 void Init(); 133 134 void AddCookieToList(const nsACString& aBaseDomain, 135 const OriginAttributes& aOriginAttributes, 136 Cookie* aCookie); 137 138 virtual void StoreCookie(const nsACString& aBaseDomain, 139 const OriginAttributes& aOriginAttributes, 140 Cookie* aCookie) = 0; 141 142 virtual const char* NotificationTopic() const = 0; 143 144 virtual void NotifyChangedInternal(nsISupports* aSubject, 145 const char16_t* aData, 146 bool aOldCookieIsSession) = 0; 147 148 virtual void RemoveAllInternal() = 0; 149 150 // This method calls RemoveCookieFromDB + RemoveCookieFromListInternal. 151 void RemoveCookieFromList(const CookieListIter& aIter); 152 153 void RemoveCookieFromListInternal(const CookieListIter& aIter); 154 155 virtual void RemoveCookieFromDB(const CookieListIter& aIter) = 0; 156 157 already_AddRefed<nsIArray> PurgeCookiesWithCallbacks( 158 int64_t aCurrentTimeInUsec, uint16_t aMaxNumberOfCookies, 159 int64_t aCookiePurgeAge, 160 std::function<void(const CookieListIter&)>&& aRemoveCookieCallback, 161 std::function<void()>&& aFinalizeCallback); 162 163 nsTHashtable<CookieEntry> mHostTable; 164 165 uint32_t mCookieCount; 166 167 private: 168 void PrefChanged(nsIPrefBranch* aPrefBranch); 169 170 bool FindSecureCookie(const nsACString& aBaseDomain, 171 const OriginAttributes& aOriginAttributes, 172 Cookie* aCookie); 173 174 static void FindStaleCookies(CookieEntry* aEntry, int64_t aCurrentTime, 175 bool aIsSecure, 176 nsTArray<CookieListIter>& aOutput, 177 uint32_t aLimit); 178 179 void UpdateCookieOldestTime(Cookie* aCookie); 180 181 static already_AddRefed<nsIArray> CreatePurgeList(nsICookie* aCookie); 182 183 virtual already_AddRefed<nsIArray> PurgeCookies(int64_t aCurrentTimeInUsec, 184 uint16_t aMaxNumberOfCookies, 185 int64_t aCookiePurgeAge) = 0; 186 187 int64_t mCookieOldestTime; 188 189 uint16_t mMaxNumberOfCookies; 190 uint16_t mMaxCookiesPerHost; 191 uint16_t mCookieQuotaPerHost; 192 int64_t mCookiePurgeAge; 193 }; 194 195 } // namespace net 196 } // namespace mozilla 197 198 #endif // mozilla_net_CookieStorage_h 199