Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: chrome/browser/prerender/prerender_cookie_store.cc

Issue 233353003: Only commit cookie changes in prerenders after a prerender is shown (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Add browser tests, fix a bug in what was changed yesterday. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 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.
4
5 #include "chrome/browser/prerender/prerender_cookie_store.h"
6
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "content/public/browser/browser_thread.h"
10
11 using content::BrowserThread;
12
13 namespace prerender {
14
15 PrerenderCookieStore::PrerenderCookieStore(
16 scoped_refptr<net::CookieMonster> default_cookie_monster,
17 const base::Closure& cookie_conflict_cb)
18 : in_forwarding_mode_(false),
19 default_cookie_monster_(default_cookie_monster),
20 changes_cookie_monster_(new net::CookieMonster(NULL, NULL)),
21 cookie_conflict_cb_(cookie_conflict_cb),
22 cookie_conflict_(false) {
23 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
24 DCHECK(default_cookie_monster_ != NULL);
25 DCHECK(default_cookie_monster_->loaded());
26 }
27
28 PrerenderCookieStore::~PrerenderCookieStore() {
29 }
30
31 void PrerenderCookieStore::SetCookieWithOptionsAsync(
32 const GURL& url,
33 const std::string& cookie_line,
34 const net::CookieOptions& options,
35 const SetCookiesCallback& callback) {
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
37
38 CookieOperation op;
39 op.op = COOKIE_OP_SET_COOKIE_WITH_OPTIONS_ASYNC;
40 op.url = url;
41 op.cookie_line = cookie_line;
42 op.options = options;
43
44 GetCookieStoreForCookieOpAndLog(op)->
45 SetCookieWithOptionsAsync(url, cookie_line, options, callback);
46 }
47
48 void PrerenderCookieStore::GetCookiesWithOptionsAsync(
49 const GURL& url,
50 const net::CookieOptions& options,
51 const GetCookiesCallback& callback) {
52 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
53 CookieOperation op;
54 op.op = COOKIE_OP_GET_COOKIES_WITH_OPTIONS_ASYNC;
55 op.url = url;
56 op.options = options;
57
58 GetCookieStoreForCookieOpAndLog(op)->
59 GetCookiesWithOptionsAsync(url, options, callback);
60 }
61
62 void PrerenderCookieStore::GetAllCookiesForURLAsync(
63 const GURL& url,
64 const GetCookieListCallback& callback) {
65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
66
67 CookieOperation op;
68 op.op = COOKIE_OP_GET_ALL_COOKIES_FOR_URL_ASYNC;
69 op.url = url;
70
71 GetCookieStoreForCookieOpAndLog(op)->GetAllCookiesForURLAsync(url, callback);
72 }
73
74
75 void PrerenderCookieStore::DeleteCookieAsync(const GURL& url,
76 const std::string& cookie_name,
77 const base::Closure& callback) {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
79
80 CookieOperation op;
81 op.op = COOKIE_OP_DELETE_COOKIE_ASYNC;
82 op.url = url;
83 op.cookie_name = cookie_name;
84
85 GetCookieStoreForCookieOpAndLog(op)->DeleteCookieAsync(url, cookie_name,
86 callback);
87 }
88
89 void PrerenderCookieStore::DeleteAllCreatedBetweenAsync(
90 const base::Time& delete_begin,
91 const base::Time& delete_end,
92 const DeleteCallback& callback) {
93 NOTREACHED();
94 }
95
96 void PrerenderCookieStore::DeleteAllCreatedBetweenForHostAsync(
97 const base::Time delete_begin,
98 const base::Time delete_end,
99 const GURL& url,
100 const DeleteCallback& callback) {
101 NOTREACHED();
102 }
103
104 void PrerenderCookieStore::DeleteSessionCookiesAsync(const DeleteCallback&) {
105 NOTREACHED();
106 }
107
108 net::CookieMonster* PrerenderCookieStore::GetCookieMonster() {
109 NOTREACHED();
110 return NULL;
111 }
112
113 net::CookieStore* PrerenderCookieStore::GetCookieStoreForCookieOpAndLog(
114 const CookieOperation& op) {
115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
116
117 std::string key = default_cookie_monster_->GetKey(op.url.host());
118 bool is_read_only = (op.op == COOKIE_OP_GET_COOKIES_WITH_OPTIONS_ASYNC ||
119 op.op == COOKIE_OP_GET_ALL_COOKIES_FOR_URL_ASYNC);
120
121 if (in_forwarding_mode_)
122 return default_cookie_monster_;
123
124 DCHECK(changes_cookie_monster_ != NULL);
125
126 cookie_ops_.push_back(op);
127
128 bool key_copied = ContainsKey(copied_keys_, key);
129
130 if (key_copied)
131 return changes_cookie_monster_;
132
133 if (is_read_only) {
134 // Insert this key into the set of read keys, if it doesn't exist yet.
135 if (!ContainsKey(read_keys_, key))
136 read_keys_.insert(key);
137 return default_cookie_monster_;
138 }
139
140 // If this method hasn't returned yet, the key has not been copied yet,
141 // and we must copy it due to the requested write operation.
142
143 bool copy_success = default_cookie_monster_->
144 CopyCookiesForKeyToOtherCookieMonster(key, changes_cookie_monster_);
145
146 // The copy must succeed.
147 DCHECK(copy_success);
148
149 copied_keys_.insert(key);
150
151 return changes_cookie_monster_;
152 }
153
154 void PrerenderCookieStore::ApplyChanges() {
155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
156
157 if (in_forwarding_mode_)
158 return;
159
160 // Apply all changes to the underlying cookie store.
161 for (std::vector<CookieOperation>::const_iterator it = cookie_ops_.begin();
162 it != cookie_ops_.end();
163 ++it) {
164 switch (it->op) {
165 case COOKIE_OP_SET_COOKIE_WITH_OPTIONS_ASYNC:
166 default_cookie_monster_->SetCookieWithOptionsAsync(
167 it->url, it->cookie_line, it->options, SetCookiesCallback());
168 break;
169 case COOKIE_OP_GET_COOKIES_WITH_OPTIONS_ASYNC:
170 default_cookie_monster_->GetCookiesWithOptionsAsync(
171 it->url, it->options, GetCookiesCallback());
172 break;
173 case COOKIE_OP_GET_ALL_COOKIES_FOR_URL_ASYNC:
174 default_cookie_monster_->GetAllCookiesForURLAsync(
175 it->url, GetCookieListCallback());
176 break;
177 case COOKIE_OP_DELETE_COOKIE_ASYNC:
178 default_cookie_monster_->DeleteCookieAsync(
179 it->url, it->cookie_name, base::Closure());
180 break;
181 case COOKIE_OP_MAX:
182 NOTREACHED();
183 }
184 }
185
186 in_forwarding_mode_ = true;
187 copied_keys_.clear();
188 cookie_ops_.clear();
189 changes_cookie_monster_ = NULL;
190 }
191
192 void PrerenderCookieStore::OnCookieChangedForURL(const GURL& url) {
193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
194
195 if (in_forwarding_mode_)
196 return;
197
198 // If we have encountered a conflict before, it has already been recorded
199 // and the cb has been issued, so nothing to do.
200 if (cookie_conflict_)
201 return;
202
203 std::string key = default_cookie_monster_->GetKey(url.host());
204
205 // If the key for the cookie which was modified was neither read nor written,
206 // nothing to do.
207 if ((!ContainsKey(read_keys_, key)) && (!ContainsKey(copied_keys_, key)))
208 return;
209
210 // There was a conflict in cookies. Call the conflict callback, which should
211 // cancel the prerender if necessary (i.e. if it hasn't already been
212 // cancelled for some other reason).
213 // Notice that there is a race here with swapping in the prerender, but this
214 // is the same issue that occurs when two tabs modify cookies for the
215 // same domain concurrently. Therefore, there is no need to do anything
216 // special to prevent this race condition.
217 cookie_conflict_ = true;
218 if (!cookie_conflict_cb_.is_null()) {
219 BrowserThread::PostTask(
220 BrowserThread::UI,
221 FROM_HERE,
222 cookie_conflict_cb_);
223 }
224 }
225
226 PrerenderCookieStore::CookieOperation::CookieOperation() {
227 }
228
229 PrerenderCookieStore::CookieOperation::~CookieOperation() {
230 }
231
232 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698