Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ios / net / cookies / cookie_store_ios.h
blobad56bb511a34a27687e19274414726082a23189a
1 // Copyright 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.
5 #ifndef IOS_NET_COOKIES_COOKIE_STORE_IOS_H_
6 #define IOS_NET_COOKIES_COOKIE_STORE_IOS_H_
8 #include <map>
9 #include <string>
10 #include <utility>
11 #include <vector>
13 #include "base/callback.h"
14 #include "base/cancelable_callback.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/threading/thread_checker.h"
17 #include "base/time/time.h"
18 #include "ios/net/cookies/cookie_cache.h"
19 #include "net/cookies/cookie_monster.h"
20 #include "net/cookies/cookie_store.h"
21 #include "url/gurl.h"
23 #if defined(__OBJC__)
24 @class NSHTTPCookie;
25 @class NSArray;
26 #else
27 class NSHTTPCookie;
28 class NSArray;
29 #endif
31 namespace net {
33 class CookieCreationTimeManager;
35 // Observer for system cookie notifications.
36 class CookieNotificationObserver {
37 public:
38 // Called when any cookie is added, deleted or changed in the system store.
39 virtual void OnSystemCookiesChanged() = 0;
40 // Called when the cookie policy changes.
41 virtual void OnSystemCookiePolicyChanged() = 0;
44 // The CookieStoreIOS is an implementation of CookieStore relying on
45 // NSHTTPCookieStorage, ensuring that the cookies are consistent between the
46 // network stack and the UIWebViews.
47 // On iOS, the Chrome CookieMonster is not used in conjunction with UIWebView,
48 // because UIWebView expects the cookies to be in the shared
49 // NSHTTPCookieStorage. In particular, javascript may read and write cookies
50 // there.
51 // CookieStoreIOS is not thread safe.
53 // At any given time, a CookieStoreIOS can either be synchronized with the
54 // system cookie store or not. If a CookieStoreIOS is not synchronized with the
55 // system store, changes are written back to the backing CookieStore. If a
56 // CookieStoreIOS is synchronized with the system store, changes are written
57 // directly to the system cookie store, then propagated to the backing store by
58 // OnSystemCookiesChanged, which is called by the system store once the change
59 // to the system store is written back.
61 // To unsynchronize, CookieStoreIOS copies the system cookie store into its
62 // backing CookieStore. To synchronize, CookieStoreIOS clears the system cookie
63 // store, copies its backing CookieStore into the system cookie store.
64 class CookieStoreIOS : public net::CookieStore,
65 public CookieNotificationObserver {
66 public:
67 explicit CookieStoreIOS(
68 net::CookieMonster::PersistentCookieStore* persistent_store);
70 enum CookiePolicy { ALLOW, BLOCK };
72 // Must be called on the thread where CookieStoreIOS instances live.
73 static void SetCookiePolicy(CookiePolicy setting);
75 // Create an instance of CookieStoreIOS that is generated from the cookies
76 // stored in the system NSHTTPCookieStorage. The caller is responsible for
77 // deleting the cookie store.
78 // Apple does not persist the cookies' creation dates in the system store,
79 // so callers should not expect these values to be populated.
80 static CookieStoreIOS* CreateCookieStoreFromNSHTTPCookieStorage();
82 // As there is only one system store, only one CookieStoreIOS at a time may
83 // be synchronized with it.
84 static void SwitchSynchronizedStore(CookieStoreIOS* old_store,
85 CookieStoreIOS* new_store);
87 // Must be called when the state of the system cookie store changes.
88 static void NotifySystemCookiesChanged();
90 // Saves the cookies to the cookie monster.
91 // Note: ignores the write cookie operation if |write_on_flush_| is false.
92 void Flush(const base::Closure& callback);
94 // Unsynchronizes the cookie store if it is currently synchronized.
95 void UnSynchronize();
97 // Only one cookie store may enable metrics.
98 void SetMetricsEnabled();
100 // Sets the delay between flushes. Only used in tests.
101 void set_flush_delay_for_testing(base::TimeDelta delay) {
102 flush_delay_ = delay;
105 // Inherited CookieStore methods.
106 void SetCookieWithOptionsAsync(const GURL& url,
107 const std::string& cookie_line,
108 const net::CookieOptions& options,
109 const SetCookiesCallback& callback) override;
110 void GetCookiesWithOptionsAsync(const GURL& url,
111 const net::CookieOptions& options,
112 const GetCookiesCallback& callback) override;
113 void GetAllCookiesForURLAsync(const GURL& url,
114 const GetCookieListCallback& callback) override;
115 void DeleteCookieAsync(const GURL& url,
116 const std::string& cookie_name,
117 const base::Closure& callback) override;
118 net::CookieMonster* GetCookieMonster() override;
119 void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin,
120 const base::Time& delete_end,
121 const DeleteCallback& callback) override;
122 void DeleteAllCreatedBetweenForHostAsync(
123 const base::Time delete_begin,
124 const base::Time delete_end,
125 const GURL& url,
126 const DeleteCallback& callback) override;
127 void DeleteSessionCookiesAsync(const DeleteCallback& callback) override;
129 scoped_ptr<CookieChangedSubscription> AddCallbackForCookie(
130 const GURL& url,
131 const std::string& name,
132 const CookieChangedCallback& callback) override;
134 protected:
135 ~CookieStoreIOS() override;
137 private:
138 // For tests.
139 friend struct CookieStoreIOSTestTraits;
141 enum SynchronizationState {
142 NOT_SYNCHRONIZED, // Uses CookieMonster as backend.
143 SYNCHRONIZING, // Moves from NSHTTPCookieStorage to CookieMonster.
144 SYNCHRONIZED // Uses NSHTTPCookieStorage as backend.
147 // Cookie fliter for DeleteCookiesWithFilter().
148 // Takes a cookie and a creation time and returns true if the cookie must be
149 // deleted.
150 typedef base::Callback<bool(NSHTTPCookie*, base::Time)> CookieFilterFunction;
152 // Clears the system cookie store.
153 void ClearSystemStore();
154 // Changes the synchronization of the store.
155 // If |synchronized| is true, then the system cookie store is used as a
156 // backend, else |cookie_monster_| is used. Cookies are moved from one to
157 // the other accordingly.
158 void SetSynchronizedWithSystemStore(bool synchronized);
159 // Returns true if the system cookie store policy is
160 // |NSHTTPCookieAcceptPolicyAlways|.
161 bool SystemCookiesAllowed();
162 // Converts |cookies| to NSHTTPCookie and add them to the system store.
163 void AddCookiesToSystemStore(const net::CookieList& cookies);
164 // Copies the cookies to the backing CookieMonster. If the cookie store is not
165 // synchronized with the system store, this is a no-op.
166 void WriteToCookieMonster(NSArray* system_cookies);
167 // Runs all the pending tasks.
168 void RunAllPendingTasks();
170 // Inherited CookieNotificationObserver methods.
171 void OnSystemCookiesChanged() override;
172 void OnSystemCookiePolicyChanged() override;
174 void DeleteCookiesWithFilter(const CookieFilterFunction& filter,
175 const DeleteCallback& callback);
177 scoped_refptr<net::CookieMonster> cookie_monster_;
178 scoped_ptr<CookieCreationTimeManager> creation_time_manager_;
179 bool metrics_enabled_;
180 base::TimeDelta flush_delay_;
181 base::CancelableClosure flush_closure_;
183 SynchronizationState synchronization_state_;
184 // Tasks received when SYNCHRONIZING are queued and run when SYNCHRONIZED.
185 std::vector<base::Closure> tasks_pending_synchronization_;
187 base::ThreadChecker thread_checker_;
189 // Cookie notification methods.
190 // The cookie cache is updated from both the system store and the
191 // CookieStoreIOS' own mutators. Changes when the CookieStoreIOS is
192 // synchronized are signalled by the system store; changes when the
193 // CookieStoreIOS is not synchronized are signalled by the appropriate
194 // mutators on CookieStoreIOS. The cookie cache tracks the system store when
195 // the CookieStoreIOS is synchronized and the CookieStore when the
196 // CookieStoreIOS is not synchronized.
198 // Fetches any cookies named |name| that would be sent with a request for
199 // |url| from the system cookie store and pushes them onto the back of the
200 // vector pointed to by |cookies|. Returns true if any cookies were pushed
201 // onto the vector, and false otherwise.
202 bool GetSystemCookies(const GURL& url,
203 const std::string& name,
204 std::vector<net::CanonicalCookie>* cookies);
206 // Updates the cookie cache with the current set of system cookies named
207 // |name| that would be sent with a request for |url|. Returns whether the
208 // cache changed.
209 // |out_removed_cookies|, if not null, will be populated with the cookies that
210 // were removed.
211 // |out_changed_cookies|, if not null, will be populated with the cookies that
212 // were added.
213 bool UpdateCacheForCookieFromSystem(
214 const GURL& gurl,
215 const std::string& name,
216 std::vector<net::CanonicalCookie>* out_removed_cookies,
217 std::vector<net::CanonicalCookie>* out_added_cookies);
219 // Runs all callbacks registered for cookies named |name| that would be sent
220 // with a request for |url|.
221 // All cookies in |cookies| must have the name equal to |name|.
222 void RunCallbacksForCookies(const GURL& url,
223 const std::string& name,
224 const std::vector<net::CanonicalCookie>& cookies,
225 bool removed);
227 // Called by this CookieStoreIOS' internal CookieMonster instance when
228 // GetAllCookiesForURLAsync() completes. Updates the cookie cache and runs
229 // callbacks if the cache changed.
230 void GotCookieListFor(const std::pair<GURL, std::string> key,
231 const net::CookieList& cookies);
233 // Fetches new values for all (url, name) pairs that have hooks registered,
234 // asynchronously invoking callbacks if necessary.
235 void UpdateCachesFromCookieMonster();
237 // Called after cookies are cleared from NSHTTPCookieStorage so that cookies
238 // can be cleared from .binarycookies file. |callback| is called after all the
239 // cookies are deleted (with the total number of cookies deleted).
240 // |num_deleted| contains the number of cookies deleted from
241 // NSHTTPCookieStorage.
242 void DidClearNSHTTPCookieStorageCookies(const DeleteCallback& callback,
243 int num_deleted);
244 // Called after cookies are cleared from .binarycookies files. |callback| is
245 // called after all the cookies are deleted with the total number of cookies
246 // deleted.
247 // |num_deleted_from_nshttp_cookie_storage| contains the number of cookies
248 // deleted from NSHTTPCookieStorage.
249 void DidClearBinaryCookiesFileCookies(
250 const DeleteCallback& callback,
251 int num_deleted_from_nshttp_cookie_storage);
253 // Callback-wrapping:
254 // When this CookieStoreIOS object is synchronized with the system store,
255 // OnSystemCookiesChanged is responsible for updating the cookie cache (and
256 // hence running callbacks).
258 // When this CookieStoreIOS object is not synchronized (or is synchronizing),
259 // the various mutator methods (SetCookieWithOptionsAsync &c) instead store
260 // their state in a CookieMonster object to be written back when the system
261 // store synchronizes. To deliver notifications in a timely manner, the
262 // mutators have to ensure that hooks get run, but only after the changes have
263 // been written back to CookieMonster. To do this, the mutators wrap the
264 // user-supplied callback in a callback which schedules an asynchronous task
265 // to synchronize the cache and run callbacks, then calls through to the
266 // user-specified callback.
268 // These three UpdateCachesAfter functions are responsible for scheduling an
269 // asynchronous cache update (using UpdateCachesFromCookieMonster()) and
270 // calling the provided callback.
272 void UpdateCachesAfterSet(const SetCookiesCallback& callback, bool success);
273 void UpdateCachesAfterDelete(const DeleteCallback& callback, int num_deleted);
274 void UpdateCachesAfterClosure(const base::Closure& callback);
276 // These three functions are used for wrapping user-supplied callbacks given
277 // to CookieStoreIOS mutator methods. Given a callback, they return a new
278 // callback that invokes UpdateCachesFromCookieMonster() to schedule an
279 // asynchronous synchronization of the cookie cache and then calls the
280 // original callback.
282 SetCookiesCallback WrapSetCallback(const SetCookiesCallback& callback);
283 DeleteCallback WrapDeleteCallback(const DeleteCallback& callback);
284 base::Closure WrapClosure(const base::Closure& callback);
286 // Cached values of system cookies. Only cookies which have an observer added
287 // with AddCallbackForCookie are kept in this cache.
288 scoped_ptr<CookieCache> cookie_cache_;
290 // Callbacks for cookie changes installed by AddCallbackForCookie.
291 typedef std::map<std::pair<GURL, std::string>, CookieChangedCallbackList*>
292 CookieChangedHookMap;
293 CookieChangedHookMap hook_map_;
295 DISALLOW_COPY_AND_ASSIGN(CookieStoreIOS);
298 } // namespace net
300 #endif // IOS_NET_COOKIES_COOKIE_STORE_IOS_H_