OLD | NEW |
(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 |
OLD | NEW |