| 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
|
|
|
|
|