Index: chrome/browser/prerender/prerender_cookie_store.cc |
=================================================================== |
--- chrome/browser/prerender/prerender_cookie_store.cc (revision 0) |
+++ chrome/browser/prerender/prerender_cookie_store.cc (revision 0) |
@@ -0,0 +1,241 @@ |
+// Copyright (c) 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/prerender/prerender_cookie_store.h" |
+ |
+#include "base/logging.h" |
+#include "base/stl_util.h" |
+#include "content/public/browser/browser_thread.h" |
+ |
+using content::BrowserThread; |
+ |
+namespace prerender { |
+ |
+PrerenderCookieStore::PrerenderCookieStore( |
+ scoped_refptr<net::CookieMonster> default_cookie_monster, |
+ const base::Closure& cookie_conflict_cb) |
+ : in_forwarding_mode_(false), |
+ default_cookie_monster_(default_cookie_monster), |
+ changes_cookie_monster_(new net::CookieMonster(NULL, NULL)), |
+ cookie_conflict_cb_(cookie_conflict_cb), |
+ cookie_conflict_(false) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DCHECK(default_cookie_monster_ != NULL); |
+ DCHECK(default_cookie_monster_->loaded()); |
+} |
+ |
+PrerenderCookieStore::~PrerenderCookieStore() { |
+} |
+ |
+void PrerenderCookieStore::SetCookieWithOptionsAsync( |
+ const GURL& url, |
+ const std::string& cookie_line, |
+ const net::CookieOptions& options, |
+ const SetCookiesCallback& callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ CookieOperation op; |
+ op.op = COOKIE_OP_SET_COOKIE_WITH_OPTIONS_ASYNC; |
+ op.url = url; |
+ op.cookie_line = cookie_line; |
+ op.options = options; |
+ |
+ GetCookieStoreForCookieOpAndLog(op)-> |
+ SetCookieWithOptionsAsync(url, cookie_line, options, callback); |
+} |
+ |
+void PrerenderCookieStore::GetCookiesWithOptionsAsync( |
+ const GURL& url, |
+ const net::CookieOptions& options, |
+ const GetCookiesCallback& callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ CookieOperation op; |
+ op.op = COOKIE_OP_GET_COOKIES_WITH_OPTIONS_ASYNC; |
+ op.url = url; |
+ op.options = options; |
+ |
+ GetCookieStoreForCookieOpAndLog(op)-> |
+ GetCookiesWithOptionsAsync(url, options, callback); |
+} |
+ |
+void PrerenderCookieStore::GetAllCookiesForURLAsync( |
+ const GURL& url, |
+ const GetCookieListCallback& callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ CookieOperation op; |
+ op.op = COOKIE_OP_GET_ALL_COOKIES_FOR_URL_ASYNC; |
+ op.url = url; |
+ |
+ GetCookieStoreForCookieOpAndLog(op)->GetAllCookiesForURLAsync(url, callback); |
+} |
+ |
+ |
+void PrerenderCookieStore::DeleteCookieAsync(const GURL& url, |
+ const std::string& cookie_name, |
+ const base::Closure& callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ CookieOperation op; |
+ op.op = COOKIE_OP_DELETE_COOKIE_ASYNC; |
+ op.url = url; |
+ op.cookie_name = cookie_name; |
+ |
+ GetCookieStoreForCookieOpAndLog(op)->DeleteCookieAsync(url, cookie_name, |
+ callback); |
+} |
+ |
+void PrerenderCookieStore::DeleteAllCreatedBetweenAsync( |
+ const base::Time& delete_begin, |
+ const base::Time& delete_end, |
+ const DeleteCallback& callback) { |
+ NOTREACHED(); |
+} |
+ |
+void PrerenderCookieStore::DeleteAllCreatedBetweenForHostAsync( |
+ const base::Time delete_begin, |
+ const base::Time delete_end, |
+ const GURL& url, |
+ const DeleteCallback& callback) { |
+ NOTREACHED(); |
+} |
+ |
+void PrerenderCookieStore::DeleteSessionCookiesAsync(const DeleteCallback&) { |
+ NOTREACHED(); |
+} |
+ |
+net::CookieMonster* PrerenderCookieStore::GetCookieMonster() { |
+ NOTREACHED(); |
+ return NULL; |
+} |
+ |
+net::CookieStore* PrerenderCookieStore::GetCookieStoreForCookieOpAndLog( |
+ const CookieOperation& op) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ std::string key = default_cookie_monster_->GetKey(op.url.host()); |
+ bool is_read_only = (op.op == COOKIE_OP_GET_COOKIES_WITH_OPTIONS_ASYNC || |
+ op.op == COOKIE_OP_GET_ALL_COOKIES_FOR_URL_ASYNC); |
+ |
+ if (in_forwarding_mode_) |
+ return default_cookie_monster_; |
+ |
+ DCHECK(changes_cookie_monster_ != NULL); |
+ |
+ cookie_ops_.push_back(op); |
+ |
+ bool key_copied = ContainsKey(copied_keys_, key); |
+ |
+ if (key_copied) |
+ return changes_cookie_monster_; |
+ |
+ if (is_read_only) { |
+ // Insert this key into the set of read keys, if it doesn't exist yet. |
+ if (!ContainsKey(read_keys_, key)) |
+ read_keys_.insert(key); |
+ return default_cookie_monster_; |
+ } |
+ |
+ // If this method hasn't returned yet, the key has not been copied yet, |
+ // and we must copy it due to the requested write operation. |
+ |
+ bool copy_success = default_cookie_monster_-> |
+ CopyCookiesForKeyToOtherCookieMonster(key, changes_cookie_monster_); |
+ |
+ // The copy must succeed. |
+ DCHECK(copy_success); |
+ |
+ copied_keys_.insert(key); |
+ |
+ return changes_cookie_monster_; |
+} |
+ |
+void PrerenderCookieStore::ApplyChanges(std::vector<GURL>* cookie_change_urls) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ if (in_forwarding_mode_) |
+ return; |
+ |
+ // Apply all changes to the underlying cookie store. |
+ for (std::vector<CookieOperation>::const_iterator it = cookie_ops_.begin(); |
+ it != cookie_ops_.end(); |
+ ++it) { |
+ switch (it->op) { |
+ case COOKIE_OP_SET_COOKIE_WITH_OPTIONS_ASYNC: |
+ cookie_change_urls->push_back(it->url); |
+ default_cookie_monster_->SetCookieWithOptionsAsync( |
+ it->url, it->cookie_line, it->options, SetCookiesCallback()); |
+ break; |
+ case COOKIE_OP_GET_COOKIES_WITH_OPTIONS_ASYNC: |
+ default_cookie_monster_->GetCookiesWithOptionsAsync( |
+ it->url, it->options, GetCookiesCallback()); |
+ break; |
+ case COOKIE_OP_GET_ALL_COOKIES_FOR_URL_ASYNC: |
+ default_cookie_monster_->GetAllCookiesForURLAsync( |
+ it->url, GetCookieListCallback()); |
+ break; |
+ case COOKIE_OP_DELETE_COOKIE_ASYNC: |
+ cookie_change_urls->push_back(it->url); |
+ default_cookie_monster_->DeleteCookieAsync( |
+ it->url, it->cookie_name, base::Closure()); |
+ break; |
+ case COOKIE_OP_MAX: |
+ NOTREACHED(); |
+ } |
+ } |
+ |
+ in_forwarding_mode_ = true; |
+ copied_keys_.clear(); |
+ cookie_ops_.clear(); |
+ changes_cookie_monster_ = NULL; |
+} |
+ |
+void PrerenderCookieStore::OnCookieChangedForURL( |
+ net::CookieMonster* cookie_monster, |
+ const GURL& url) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ // If the cookie was changed in a different cookie monster than the one |
+ // being decorated, there is nothing to do). |
+ if (cookie_monster != default_cookie_monster_) |
+ return; |
+ |
+ if (in_forwarding_mode_) |
+ return; |
+ |
+ // If we have encountered a conflict before, it has already been recorded |
+ // and the cb has been issued, so nothing to do. |
+ if (cookie_conflict_) |
+ return; |
+ |
+ std::string key = default_cookie_monster_->GetKey(url.host()); |
+ |
+ // If the key for the cookie which was modified was neither read nor written, |
+ // nothing to do. |
+ if ((!ContainsKey(read_keys_, key)) && (!ContainsKey(copied_keys_, key))) |
+ return; |
+ |
+ // There was a conflict in cookies. Call the conflict callback, which should |
+ // cancel the prerender if necessary (i.e. if it hasn't already been |
+ // cancelled for some other reason). |
+ // Notice that there is a race here with swapping in the prerender, but this |
+ // is the same issue that occurs when two tabs modify cookies for the |
+ // same domain concurrently. Therefore, there is no need to do anything |
+ // special to prevent this race condition. |
+ cookie_conflict_ = true; |
+ if (!cookie_conflict_cb_.is_null()) { |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ cookie_conflict_cb_); |
+ } |
+} |
+ |
+PrerenderCookieStore::CookieOperation::CookieOperation() { |
+} |
+ |
+PrerenderCookieStore::CookieOperation::~CookieOperation() { |
+} |
+ |
+} // namespace prerender |
Property changes on: chrome/browser/prerender/prerender_cookie_store.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |