1 // Copyright 2014 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 CHROME_BROWSER_PRERENDER_PRERENDER_COOKIE_STORE_H_
6 #define CHROME_BROWSER_PRERENDER_PRERENDER_COOKIE_STORE_H_
12 #include "base/callback.h"
13 #include "base/compiler_specific.h"
14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h"
16 #include "net/cookies/cookie_monster.h"
17 #include "net/cookies/cookie_store.h"
22 // A cookie store which keeps track of provisional changes to the cookie monster
23 // of an underlying request context (called the default cookie monster).
24 // Initially, it will proxy read requests to the default cookie monster, and
25 // copy on write keys that are being modified into a private cookie monster.
26 // Reads for these will then happen from the private cookie monster.
27 // Should keys be modified in the default cookie store, the corresponding
28 // prerender should be aborted.
29 // This class also keeps a log of all cookie transactions. Once ApplyChanges
30 // is called, the changes will be applied to the default cookie monster,
31 // and any future requests to this object will simply be forwarded to the
32 // default cookie monster. After ApplyChanges is called, the prerender tracker,
33 // which "owns" the PrerenderCookieStore reference, will remove its entry for
34 // the PrerenderCookieStore. Therefore, after ApplyChanges is called, the
35 // object will only stick around (and exhibit forwarding mode) as long as
36 // eg pending requests hold on to its reference.
37 class PrerenderCookieStore
: public net::CookieStore
{
39 // Creates a PrerenderCookieStore using the default cookie monster provided
40 // by the URLRequestContext. The underlying cookie store must be loaded,
41 // ie it's call to loaded() must return true.
42 // Otherwise, copying cookie data between the prerender cookie store
43 // (used to only commit cookie changes once a prerender is shown) would
44 // not work synchronously, which would complicate the code.
45 // |cookie_conflict_cb| will be called when a cookie conflict is detected.
46 // The callback will be run on the UI thread.
47 PrerenderCookieStore(scoped_refptr
<net::CookieMonster
> default_cookie_store_
,
48 const base::Closure
& cookie_conflict_cb
);
50 // CookieStore implementation
51 void SetCookieWithOptionsAsync(const GURL
& url
,
52 const std::string
& cookie_line
,
53 const net::CookieOptions
& options
,
54 const SetCookiesCallback
& callback
) override
;
56 void GetCookiesWithOptionsAsync(const GURL
& url
,
57 const net::CookieOptions
& options
,
58 const GetCookiesCallback
& callback
) override
;
60 void GetAllCookiesForURLAsync(const GURL
& url
,
61 const GetCookieListCallback
& callback
) override
;
63 void DeleteCookieAsync(const GURL
& url
,
64 const std::string
& cookie_name
,
65 const base::Closure
& callback
) override
;
67 // All the following methods should not be used in the scenarios where
68 // a PrerenderCookieStore is used. This will be checked via NOTREACHED().
69 // Should PrerenderCookieStore used in contexts requiring these, they will
70 // need to be implemented first. They are only intended to be called on the
73 void DeleteAllCreatedBetweenAsync(const base::Time
& delete_begin
,
74 const base::Time
& delete_end
,
75 const DeleteCallback
& callback
) override
;
77 void DeleteAllCreatedBetweenForHostAsync(
78 const base::Time delete_begin
,
79 const base::Time delete_end
,
81 const DeleteCallback
& callback
) override
;
83 void DeleteSessionCookiesAsync(const DeleteCallback
&) override
;
85 net::CookieMonster
* GetCookieMonster() override
;
87 scoped_ptr
<net::CookieStore::CookieChangedSubscription
> AddCallbackForCookie(
89 const std::string
& name
,
90 const CookieChangedCallback
& callback
) override
;
92 // Commits the changes made to the underlying cookie store, and switches
93 // into forwarding mode. To be called on the IO thread.
94 // |cookie_change_urls| will be populated with all URLs for which cookies
96 void ApplyChanges(std::vector
<GURL
>* cookie_change_urls
);
98 // Called when a cookie for a URL is changed in the underlying default cookie
99 // store. To be called on the IO thread. If the key corresponding to the URL
100 // was copied or read, the prerender will be cancelled.
101 void OnCookieChangedForURL(net::CookieMonster
* cookie_monster
,
104 net::CookieMonster
* default_cookie_monster() {
105 return default_cookie_monster_
.get();
109 enum CookieOperationType
{
110 COOKIE_OP_SET_COOKIE_WITH_OPTIONS_ASYNC
,
111 COOKIE_OP_GET_COOKIES_WITH_OPTIONS_ASYNC
,
112 COOKIE_OP_GET_ALL_COOKIES_FOR_URL_ASYNC
,
113 COOKIE_OP_DELETE_COOKIE_ASYNC
,
117 struct CookieOperation
{
118 CookieOperationType op
;
120 net::CookieOptions options
;
121 std::string cookie_line
;
122 std::string cookie_name
;
127 ~PrerenderCookieStore() override
;
129 // Gets the appropriate cookie store for the operation provided, and pushes
130 // it back on the log of cookie operations performed.
131 net::CookieStore
* GetCookieStoreForCookieOpAndLog(const CookieOperation
& op
);
133 // Indicates whether the changes have already been applied (ie the prerender
134 // has been shown), and we are merely in forwarding mode;
135 bool in_forwarding_mode_
;
137 // The default cookie monster.
138 scoped_refptr
<net::CookieMonster
> default_cookie_monster_
;
140 // A cookie monster storing changes made by the prerender.
141 // Entire keys are copied from default_cookie_monster_ on change, and then
143 scoped_refptr
<net::CookieMonster
> changes_cookie_monster_
;
145 // Log of cookie operations performed
146 std::vector
<CookieOperation
> cookie_ops_
;
148 // The keys which have been copied on write to |changes_cookie_monster_|.
149 std::set
<std::string
> copied_keys_
;
151 // Keys which have been read (but not necessarily been modified).
152 std::set
<std::string
> read_keys_
;
154 // Callback when a cookie conflict was detected
155 base::Closure cookie_conflict_cb_
;
157 // Indicates whether a cookie conflict has been detected yet.
158 bool cookie_conflict_
;
160 DISALLOW_COPY_AND_ASSIGN(PrerenderCookieStore
);
163 } // namespace prerender
165 #endif // CHROME_BROWSER_PRERENDER_PRERENDER_COOKIE_STORE_H_