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

Unified 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: sync @269781 + 'autlock'->'autolock' from erik's comment that was not included before 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 side-by-side diff with in-line comments
Download patch
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
« no previous file with comments | « chrome/browser/prerender/prerender_cookie_store.h ('k') | chrome/browser/prerender/prerender_final_status.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698