Commit a4d965d6 authored by ycxiao@chromium.org's avatar ycxiao@chromium.org

Creat BrowsingDataCookieHelper and CannedBrowsingDataCookieHelper for logging cookies at UI thread.

BUG=XXX
TEST=XXX

Review URL: http://codereview.chromium.org/7355025

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95534 0039d316-1c4b-4281-b951-d872f2087c98
parent 199f0db1
// Copyright (c) 2011 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/browsing_data_cookie_helper.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/profiles/profile.h"
#include "content/browser/browser_thread.h"
#include "googleurl/src/gurl.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
BrowsingDataCookieHelper::BrowsingDataCookieHelper(Profile* profile)
: is_fetching_(false),
profile_(profile),
request_context_getter_(profile->GetRequestContext()) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
}
BrowsingDataCookieHelper::~BrowsingDataCookieHelper() {
}
void BrowsingDataCookieHelper::StartFetching(
const base::Callback<void(const net::CookieList& cookies)>& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(!is_fetching_);
DCHECK(!callback.is_null());
DCHECK(completion_callback_.is_null());
is_fetching_ = true;
completion_callback_ = callback;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&BrowsingDataCookieHelper::FetchCookiesOnIOThread, this));
}
void BrowsingDataCookieHelper::CancelNotification() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
completion_callback_.Reset();
}
void BrowsingDataCookieHelper::DeleteCookie(
const net::CookieMonster::CanonicalCookie& cookie) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&BrowsingDataCookieHelper::DeleteCookieOnIOThread,
this, cookie));
}
void BrowsingDataCookieHelper::FetchCookiesOnIOThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
scoped_refptr<net::CookieMonster> cookie_monster =
request_context_getter_->GetURLRequestContext()->
cookie_store()->GetCookieMonster();
if (cookie_monster) {
cookie_monster->GetAllCookiesAsync(
base::Bind(&BrowsingDataCookieHelper::OnFetchComplete, this));
} else {
OnFetchComplete(net::CookieList());
}
}
void BrowsingDataCookieHelper::OnFetchComplete(const net::CookieList& cookies) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&BrowsingDataCookieHelper::NotifyInUIThread, this, cookies));
}
void BrowsingDataCookieHelper::NotifyInUIThread(
const net::CookieList& cookies) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(is_fetching_);
is_fetching_ = false;
if (!completion_callback_.is_null()) {
completion_callback_.Run(cookies);
completion_callback_.Reset();
}
}
void BrowsingDataCookieHelper::DeleteCookieOnIOThread(
const net::CookieMonster::CanonicalCookie& cookie) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
scoped_refptr<net::CookieMonster> cookie_monster =
request_context_getter_->GetURLRequestContext()->
cookie_store()->GetCookieMonster();
if (cookie_monster) {
cookie_monster->DeleteCanonicalCookieAsync(
cookie, net::CookieMonster::DeleteCookieCallback());
}
}
CannedBrowsingDataCookieHelper::CannedBrowsingDataCookieHelper(
Profile* profile)
: BrowsingDataCookieHelper(profile),
profile_(profile) {
}
CannedBrowsingDataCookieHelper::~CannedBrowsingDataCookieHelper() {}
CannedBrowsingDataCookieHelper* CannedBrowsingDataCookieHelper::Clone() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
CannedBrowsingDataCookieHelper* clone =
new CannedBrowsingDataCookieHelper(profile_);
clone->cookie_list_ = cookie_list_;
return clone;
}
void CannedBrowsingDataCookieHelper::AddReadCookies(
const GURL& url,
const net::CookieList& cookie_list) {
typedef net::CookieList::const_iterator cookie_iterator;
for (cookie_iterator add_cookie = cookie_list.begin();
add_cookie != cookie_list.end(); ++add_cookie) {
DeleteMetchingCookie(*add_cookie);
cookie_list_.push_back(*add_cookie);
}
}
void CannedBrowsingDataCookieHelper::AddChangedCookie(
const GURL& url,
const std::string& cookie_line,
const net::CookieOptions& options) {
typedef net::CookieList::iterator cookie_iterator;
net::CookieMonster::ParsedCookie pc(cookie_line);
if (options.exclude_httponly() && pc.IsHttpOnly()) {
// Return if a Javascript cookie illegally specified the HTTP only flag.
return;
}
scoped_ptr<net::CookieMonster::CanonicalCookie> cc;
cc.reset(net::CookieMonster::CanonicalCookie::Create(url, pc));
// Fails creating canonical cookie, if the normalized cookie domain form
// cookie line and the url don't have the same domain+registry, or url host
// isn't cookie domain or one of its subdomains.
if (cc.get()) {
DeleteMetchingCookie(*cc);
cookie_list_.push_back(*cc);
}
}
void CannedBrowsingDataCookieHelper::Reset() {
cookie_list_.clear();
}
bool CannedBrowsingDataCookieHelper::empty() const {
return cookie_list_.empty();
}
void CannedBrowsingDataCookieHelper::StartFetching(
const net::CookieMonster::GetCookieListCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!callback.is_null())
callback.Run(cookie_list_);
}
void CannedBrowsingDataCookieHelper::CancelNotification() {}
bool CannedBrowsingDataCookieHelper::DeleteMetchingCookie(
const net::CookieMonster::CanonicalCookie& add_cookie) {
typedef net::CookieList::iterator cookie_iterator;
for (cookie_iterator cookie = cookie_list_.begin();
cookie != cookie_list_.end(); ++cookie) {
if (cookie->Name() == add_cookie.Name() &&
cookie->Domain() == add_cookie.Domain()&&
cookie->Path() == add_cookie.Path()) {
cookie_list_.erase(cookie);
return true;
}
}
return false;
}
// Copyright (c) 2011 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.
#ifndef CHROME_BROWSER_BROWSING_DATA_COOKIE_HELPER_H_
#define CHROME_BROWSER_BROWSING_DATA_COOKIE_HELPER_H_
#pragma once
#include <string>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "net/base/cookie_monster.h"
class GURL;
class Profile;
namespace net {
class URLRequestContextGetter;
}
// This class fetches cookie information on behalf of a caller
// on the UI thread.
// A client of this class need to call StartFetching from the UI thread to
// initiate the flow, and it'll be notified by the callback in its UI
// thread at some later point.
// The client must call CancelNotification() if it's destroyed before the
// callback is notified.
class BrowsingDataCookieHelper
: public base::RefCountedThreadSafe<BrowsingDataCookieHelper> {
public:
explicit BrowsingDataCookieHelper(Profile* profile);
// Starts the fetching process, which will notify its completion via
// callback.
// This must be called only in the UI thread.
virtual void StartFetching(
const base::Callback<void(const net::CookieList& cookies)>& callback);
// Cancels the notification callback (i.e., the window that created it no
// longer exists).
// This must be called only in the UI thread.
virtual void CancelNotification();
// Requests a single cookie to be deleted in the IO thread. This must be
// called in the UI thread.
virtual void DeleteCookie(const net::CookieMonster::CanonicalCookie& cookie);
protected:
friend class base::RefCountedThreadSafe<BrowsingDataCookieHelper>;
virtual ~BrowsingDataCookieHelper();
private:
// Fetch the cookies. This must be called in the IO thread.
void FetchCookiesOnIOThread();
// Callback function for get cookie. This must be called in the IO thread.
void OnFetchComplete(const net::CookieList& cookies);
// Notifies the completion callback. This must be called in the UI thread.
void NotifyInUIThread(const net::CookieList& cookies);
// Delete a single cookie. This must be called in IO thread.
void DeleteCookieOnIOThread(
const net::CookieMonster::CanonicalCookie& cookie);
// Indicates whether or not we're currently fetching information:
// it's true when StartFetching() is called in the UI thread, and it's reset
// after we notify the callback in the UI thread.
// This only mutates on the UI thread.
bool is_fetching_;
Profile* profile_;
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
// This only mutates on the UI thread.
base::Callback<void(const net::CookieList& cookies)> completion_callback_;
DISALLOW_COPY_AND_ASSIGN(BrowsingDataCookieHelper);
};
// This class is a thin wrapper around BrowsingDataCookieHelper that does not
// fetch its information from the persistent cookie store, but gets them passed
// as a parameter during construction.
class CannedBrowsingDataCookieHelper : public BrowsingDataCookieHelper {
public:
explicit CannedBrowsingDataCookieHelper(Profile* profile);
// Return a copy of the cookie helper. Only one consumer can use the
// StartFetching method at a time, so we need to create a copy of the helper
// everytime we instantiate a cookies tree model for it.
CannedBrowsingDataCookieHelper* Clone();
// Adds cookies and delete the current cookies with the same Name, Domain,
// and Path as the newly created ones.
void AddReadCookies(const GURL& url,
const net::CookieList& cookie_list);
// Adds cookies that will be stored by the CookieMonster. Designed to mirror
// the logic of SetCookieWithOptions.
void AddChangedCookie(const GURL& url,
const std::string& cookie_line,
const net::CookieOptions& options);
// Clears the list of canned cookies.
void Reset();
// True if no cookie are currently stored.
bool empty() const;
// BrowsingDataCookieHelper methods.
virtual void StartFetching(
const net::CookieMonster::GetCookieListCallback& callback);
virtual void CancelNotification();
private:
// Check if the cookie list contains a cookie with the same name,
// domain, and path as the newly created cookie. Delete the old cookie
// if does.
bool DeleteMetchingCookie(
const net::CookieMonster::CanonicalCookie& add_cookie);
virtual ~CannedBrowsingDataCookieHelper();
net::CookieList cookie_list_;
Profile* profile_;
DISALLOW_COPY_AND_ASSIGN(CannedBrowsingDataCookieHelper);
};
#endif // CHROME_BROWSER_BROWSING_DATA_COOKIE_HELPER_H_
// Copyright (c) 2011 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/browsing_data_cookie_helper.h"
#include "base/bind.h"
#include "base/message_loop.h"
#include "chrome/test/base/testing_profile.h"
#include "content/browser/browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
class BrowsingDataCookieHelperTest : public testing::Test {
public:
virtual void SetUp() {
ui_thread_.reset(new BrowserThread(BrowserThread::UI, &message_loop_));
// Note: we're starting a real IO thread because parts of the
// BrowsingDataCookieHelper expect to run on that thread.
io_thread_.reset(new BrowserThread(BrowserThread::IO));
ASSERT_TRUE(io_thread_->Start());
}
virtual void TearDown() {
message_loop_.RunAllPending();
io_thread_.reset();
ui_thread_.reset();
}
void CreateCookiesForTest() {
testing_profile_.CreateRequestContext();
scoped_refptr<net::CookieMonster> cookie_monster =
testing_profile_.GetCookieMonster();
cookie_monster->SetCookieWithOptionsAsync(
GURL("http://www.google.com"), "A=1", net::CookieOptions(),
net::CookieMonster::SetCookiesCallback());
cookie_monster->SetCookieWithOptionsAsync(
GURL("http://www.gmail.google.com"), "B=1", net::CookieOptions(),
net::CookieMonster::SetCookiesCallback());
}
void FetchCallback(const net::CookieList& cookies) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
ASSERT_EQ(2UL, cookies.size());
cookie_list_ = cookies;
net::CookieList::const_iterator it = cookies.begin();
// Correct because fetching cookies will get a sorted cookie list.
ASSERT_TRUE(it != cookies.end());
EXPECT_EQ("www.google.com", it->Domain());
EXPECT_EQ("A", it->Name());
ASSERT_TRUE(++it != cookies.end());
EXPECT_EQ("www.gmail.google.com", it->Domain());
EXPECT_EQ("B", it->Name());
ASSERT_TRUE(++it == cookies.end());
MessageLoop::current()->Quit();
}
void DeleteCallback(const net::CookieList& cookies) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
ASSERT_EQ(1UL, cookies.size());
net::CookieList::const_iterator it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
EXPECT_EQ("www.gmail.google.com", it->Domain());
EXPECT_EQ("B", it->Name());
ASSERT_TRUE(++it == cookies.end());
MessageLoop::current()->Quit();
}
void CannedUniqueCallback(const net::CookieList& cookies) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
ASSERT_EQ(1UL, cookies.size());
cookie_list_ = cookies;
net::CookieList::const_iterator it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
EXPECT_EQ("http://www.google.com/", it->Source());
EXPECT_EQ("A", it->Name());
ASSERT_TRUE(++it == cookies.end());
}
protected:
MessageLoop message_loop_;
scoped_ptr<BrowserThread> ui_thread_;
scoped_ptr<BrowserThread> io_thread_;
TestingProfile testing_profile_;
net::CookieList cookie_list_;
};
TEST_F(BrowsingDataCookieHelperTest, FetchData) {
CreateCookiesForTest();
scoped_refptr<BrowsingDataCookieHelper> cookie_helper(
new BrowsingDataCookieHelper(&testing_profile_));
cookie_helper->StartFetching(
base::Bind(&BrowsingDataCookieHelperTest::FetchCallback,
base::Unretained(this)));
// Blocks until BrowsingDataCookieHelperTest::FetchCallback is notified.
MessageLoop::current()->Run();
}
TEST_F(BrowsingDataCookieHelperTest, DeleteCookie) {
CreateCookiesForTest();
scoped_refptr<BrowsingDataCookieHelper> cookie_helper(
new BrowsingDataCookieHelper(&testing_profile_));
cookie_helper->StartFetching(
base::Bind(&BrowsingDataCookieHelperTest::FetchCallback,
base::Unretained(this)));
// Blocks until BrowsingDataCookieHelperTest::FetchCallback is notified.
MessageLoop::current()->Run();
net::CookieMonster::CanonicalCookie cookie = cookie_list_[0];
cookie_helper->DeleteCookie(cookie);
cookie_helper->StartFetching(
base::Bind(&BrowsingDataCookieHelperTest::DeleteCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
}
TEST_F(BrowsingDataCookieHelperTest, CannedUnique) {
const GURL origin("http://www.google.com");
net::CookieList cookie;
scoped_refptr<CannedBrowsingDataCookieHelper> helper(
new CannedBrowsingDataCookieHelper(&testing_profile_));
ASSERT_TRUE(helper->empty());
helper->AddChangedCookie(origin, "A=1", net::CookieOptions());
helper->AddChangedCookie(origin, "A=1", net::CookieOptions());
helper->StartFetching(
base::Bind(&BrowsingDataCookieHelperTest::CannedUniqueCallback,
base::Unretained(this)));
cookie = cookie_list_;
helper->Reset();
ASSERT_TRUE(helper->empty());
helper->AddReadCookies(origin, cookie);
helper->AddReadCookies(origin, cookie);
helper->StartFetching(
base::Bind(&BrowsingDataCookieHelperTest::CannedUniqueCallback,
base::Unretained(this)));
}
TEST_F(BrowsingDataCookieHelperTest, CannedEmpty) {
const GURL url_google("http://www.google.com");
scoped_refptr<CannedBrowsingDataCookieHelper> helper(
new CannedBrowsingDataCookieHelper(&testing_profile_));
ASSERT_TRUE(helper->empty());
helper->AddChangedCookie(url_google, "a=1",
net::CookieOptions());
ASSERT_FALSE(helper->empty());
helper->Reset();
ASSERT_TRUE(helper->empty());
net::CookieList cookies;
net::CookieMonster::ParsedCookie pc("a=1");
scoped_ptr<net::CookieMonster::CanonicalCookie> cookie(
new net::CookieMonster::CanonicalCookie(url_google, pc));
cookies.push_back(*cookie);
helper->AddReadCookies(url_google, cookies);
ASSERT_FALSE(helper->empty());
helper->Reset();
ASSERT_TRUE(helper->empty());
}
} // namespace
......@@ -9,6 +9,7 @@
#include "base/lazy_instance.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browsing_data_appcache_helper.h"
#include "chrome/browser/browsing_data_cookie_helper.h"
#include "chrome/browser/browsing_data_database_helper.h"
#include "chrome/browser/browsing_data_file_system_helper.h"
#include "chrome/browser/browsing_data_indexed_db_helper.h"
......@@ -26,7 +27,6 @@
#include "content/browser/tab_contents/tab_contents_delegate.h"
#include "content/common/notification_service.h"
#include "content/common/view_messages.h"
#include "net/base/cookie_monster.h"
#include "webkit/fileapi/file_system_types.h"
namespace {
......@@ -36,8 +36,8 @@ static base::LazyInstance<TabSpecificList> g_tab_specific(
}
bool TabSpecificContentSettings::LocalSharedObjectsContainer::empty() const {
return cookies_->GetAllCookies().empty() &&
appcaches_->empty() &&
return appcaches_->empty() &&
cookies_->empty() &&
databases_->empty() &&
file_systems_->empty() &&
indexed_dbs_->empty() &&
......@@ -239,24 +239,15 @@ void TabSpecificContentSettings::OnCookiesRead(
bool blocked_by_policy) {
if (cookie_list.empty())
return;
LocalSharedObjectsContainer& container = blocked_by_policy ?
blocked_local_shared_objects_ : allowed_local_shared_objects_;
typedef net::CookieList::const_iterator cookie_iterator;
for (cookie_iterator cookie = cookie_list.begin();
cookie != cookie_list.end(); ++cookie) {
container.cookies()->SetCookieWithDetails(url,
cookie->Name(),
cookie->Value(),
cookie->Domain(),
cookie->Path(),
cookie->ExpiryDate(),
cookie->IsSecure(),
cookie->IsHttpOnly());
}
if (blocked_by_policy)
if (blocked_by_policy) {
blocked_local_shared_objects_.cookies()->AddReadCookies(
url, cookie_list);
OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES, std::string());
else
} else {
allowed_local_shared_objects_.cookies()->AddReadCookies(
url, cookie_list);
OnContentAccessed(CONTENT_SETTINGS_TYPE_COOKIES);
}
}
void TabSpecificContentSettings::OnCookieChanged(
......@@ -265,11 +256,11 @@ void TabSpecificContentSettings::OnCookieChanged(
const net::CookieOptions& options,
bool blocked_by_policy) {
if (blocked_by_policy) {
blocked_local_shared_objects_.cookies()->SetCookieWithOptions(
blocked_local_shared_objects_.cookies()->AddChangedCookie(
url, cookie_line, options);
OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES, std::string());
} else {
allowed_local_shared_objects_.cookies()->SetCookieWithOptions(
allowed_local_shared_objects_.cookies()->AddChangedCookie(
url, cookie_line, options);
OnContentAccessed(CONTENT_SETTINGS_TYPE_COOKIES);
}
......@@ -486,17 +477,13 @@ void TabSpecificContentSettings::Observe(int type,
TabSpecificContentSettings::LocalSharedObjectsContainer::
LocalSharedObjectsContainer(Profile* profile)
: cookies_(new net::CookieMonster(NULL, NULL)),
appcaches_(new CannedBrowsingDataAppCacheHelper(profile)),
: appcaches_(new CannedBrowsingDataAppCacheHelper(profile)),
cookies_(new CannedBrowsingDataCookieHelper(profile)),
databases_(new CannedBrowsingDataDatabaseHelper(profile)),
file_systems_(new CannedBrowsingDataFileSystemHelper(profile)),
indexed_dbs_(new CannedBrowsingDataIndexedDBHelper(profile)),
local_storages_(new CannedBrowsingDataLocalStorageHelper(profile)),
session_storages_(new CannedBrowsingDataLocalStorageHelper(profile)) {
cookies_->SetCookieableSchemes(
net::CookieMonster::kDefaultCookieableSchemes,
net::CookieMonster::kDefaultCookieableSchemesCount);
cookies_->SetKeepExpiredCookies();
}
TabSpecificContentSettings::LocalSharedObjectsContainer::
......@@ -504,12 +491,8 @@ TabSpecificContentSettings::LocalSharedObjectsContainer::
}
void TabSpecificContentSettings::LocalSharedObjectsContainer::Reset() {
cookies_ = new net::CookieMonster(NULL, NULL);
cookies_->SetCookieableSchemes(
net::CookieMonster::kDefaultCookieableSchemes,
net::CookieMonster::kDefaultCookieableSchemesCount);
cookies_->SetKeepExpiredCookies();
appcaches_->Reset();
cookies_->Reset();
databases_->Reset();
file_systems_->Reset();
indexed_dbs_->Reset();
......@@ -519,7 +502,7 @@ void TabSpecificContentSettings::LocalSharedObjectsContainer::Reset() {
CookiesTreeModel*
TabSpecificContentSettings::LocalSharedObjectsContainer::GetCookiesTreeModel() {
return new CookiesTreeModel(cookies_,
return new CookiesTreeModel(cookies_->Clone(),
databases_->Clone(),
local_storages_->Clone(),
session_storages_->Clone(),
......
......@@ -6,6 +6,9 @@
#define CHROME_BROWSER_CONTENT_SETTINGS_TAB_SPECIFIC_CONTENT_SETTINGS_H_
#pragma once
#include <set>
#include <string>
#include "base/basictypes.h"
#include "chrome/browser/geolocation/geolocation_settings_state.h"
#include "chrome/common/content_settings.h"
......@@ -16,6 +19,7 @@
#include "content/common/notification_registrar.h"
class CannedBrowsingDataAppCacheHelper;
class CannedBrowsingDataCookieHelper;
class CannedBrowsingDataDatabaseHelper;
class CannedBrowsingDataFileSystemHelper;
class CannedBrowsingDataIndexedDBHelper;
......@@ -27,7 +31,6 @@ struct ContentSettings;
namespace net {
class CookieList;
class CookieMonster;
class CookieOptions;
}
......@@ -205,10 +208,12 @@ class TabSpecificContentSettings : public TabContentsObserver,
// Empties the container.
void Reset();
net::CookieMonster* cookies() const { return cookies_; }
CannedBrowsingDataAppCacheHelper* appcaches() const {
return appcaches_;
}
CannedBrowsingDataCookieHelper* cookies() const {
return cookies_;
}
CannedBrowsingDataDatabaseHelper* databases() const {
return databases_;
}
......@@ -230,15 +235,15 @@ class TabSpecificContentSettings : public TabContentsObserver,
bool empty() const;
private:
DISALLOW_COPY_AND_ASSIGN(LocalSharedObjectsContainer);
scoped_refptr<net::CookieMonster> cookies_;
scoped_refptr<CannedBrowsingDataAppCacheHelper> appcaches_;
scoped_refptr<CannedBrowsingDataCookieHelper> cookies_;
scoped_refptr<CannedBrowsingDataDatabaseHelper> databases_;
scoped_refptr<CannedBrowsingDataFileSystemHelper> file_systems_;
scoped_refptr<CannedBrowsingDataIndexedDBHelper> indexed_dbs_;
scoped_refptr<CannedBrowsingDataLocalStorageHelper> local_storages_;
scoped_refptr<CannedBrowsingDataLocalStorageHelper> session_storages_;
DISALLOW_COPY_AND_ASSIGN(LocalSharedObjectsContainer);
};
void AddBlockedResource(ContentSettingsType content_type,
......
......@@ -8,10 +8,12 @@
#include <functional>
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/linked_ptr.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browsing_data_cookie_helper.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/extensions/extension_service.h"
#include "content/browser/in_process_webkit/webkit_context.h"
......@@ -62,7 +64,7 @@ void CookieTreeCookieNode::DeleteStoredObjects() {
// vector storing the cookies in-tact and not delete from there (that would
// invalidate our pointers), and the fact that it contains semi out-of-date
// data is not problematic as we don't re-build the model based on that.
GetModel()->cookie_monster_->DeleteCanonicalCookie(*cookie_);
GetModel()->cookie_helper_->DeleteCookie(*cookie_);
}
CookieTreeNode::DetailedInfo CookieTreeCookieNode::GetDetailedInfo() const {
......@@ -551,7 +553,7 @@ void CookieTreeNode::AddChildSortedByTitle(CookieTreeNode* new_child) {
// CookiesTreeModel, public:
CookiesTreeModel::CookiesTreeModel(
net::CookieMonster* cookie_monster,
BrowsingDataCookieHelper* cookie_helper,
BrowsingDataDatabaseHelper* database_helper,
BrowsingDataLocalStorageHelper* local_storage_helper,
BrowsingDataLocalStorageHelper* session_storage_helper,
......@@ -561,8 +563,8 @@ CookiesTreeModel::CookiesTreeModel(
bool use_cookie_source)
: ALLOW_THIS_IN_INITIALIZER_LIST(ui::TreeNodeModel<CookieTreeNode>(
new CookieTreeRootNode(this))),
cookie_monster_(cookie_monster),
appcache_helper_(appcache_helper),
cookie_helper_(cookie_helper),
database_helper_(database_helper),
local_storage_helper_(local_storage_helper),
session_storage_helper_(session_storage_helper),
......@@ -570,7 +572,10 @@ CookiesTreeModel::CookiesTreeModel(
file_system_helper_(file_system_helper),
batch_update_(0),
use_cookie_source_(use_cookie_source) {
LoadCookies();
DCHECK(cookie_helper_);
cookie_helper_->StartFetching(
base::Bind(&CookiesTreeModel::OnCookiesModelInfoLoaded,
base::Unretained(this)));
DCHECK(database_helper_);
database_helper_->StartFetching(NewCallback(
this, &CookiesTreeModel::OnDatabaseModelInfoLoaded));
......@@ -601,6 +606,7 @@ CookiesTreeModel::CookiesTreeModel(
}
CookiesTreeModel::~CookiesTreeModel() {
cookie_helper_->CancelNotification();
database_helper_->CancelNotification();
local_storage_helper_->CancelNotification();
if (session_storage_helper_)
......@@ -656,42 +662,6 @@ int CookiesTreeModel::GetIconIndex(ui::TreeModelNode* node) {
return -1;
}
void CookiesTreeModel::LoadCookies() {
LoadCookiesWithFilter(std::wstring());
}
void CookiesTreeModel::LoadCookiesWithFilter(const std::wstring& filter) {
// mmargh mmargh mmargh! delicious!
all_cookies_ = cookie_monster_->GetAllCookies();
CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
for (CookieList::iterator it = all_cookies_.begin();
it != all_cookies_.end(); ++it) {
std::string source_string = it->Source();
if (source_string.empty() || !use_cookie_source_) {
std::string domain = it->Domain();
if (domain.length() > 1 && domain[0] == '.')
domain = domain.substr(1);
// We treat secure cookies just the same as normal ones.
source_string = std::string(chrome::kHttpScheme) +
chrome::kStandardSchemeSeparator + domain + "/";
}
GURL source(source_string);
if (!filter.size() ||
(CookieTreeOriginNode::TitleForUrl(source).find(filter) !=
std::string::npos)) {
CookieTreeOriginNode* origin_node =
root->GetOrCreateOriginNode(source);
CookieTreeCookiesNode* cookies_node =
origin_node->GetOrCreateCookiesNode();
CookieTreeCookieNode* new_cookie = new CookieTreeCookieNode(&*it);
cookies_node->AddCookieNode(new_cookie);
}
}
}
void CookiesTreeModel::DeleteAllStoredObjects() {
NotifyObserverBeginBatch();
CookieTreeNode* root = GetRoot();
......@@ -719,7 +689,7 @@ void CookiesTreeModel::UpdateSearchResults(const std::wstring& filter) {
NotifyObserverBeginBatch();
for (int i = num_children - 1; i >= 0; --i)
delete Remove(root, root->GetChild(i));
LoadCookiesWithFilter(filter);
PopulateCookieInfoWithFilter(filter);
PopulateDatabaseInfoWithFilter(filter);
PopulateLocalStorageInfoWithFilter(filter);
PopulateSessionStorageInfoWithFilter(filter);
......@@ -780,6 +750,44 @@ void CookiesTreeModel::PopulateAppCacheInfoWithFilter(
NotifyObserverEndBatch();
}
void CookiesTreeModel::OnCookiesModelInfoLoaded(
const CookieList& cookie_list) {
cookie_list_ = cookie_list;
PopulateCookieInfoWithFilter(std::wstring());
}
void CookiesTreeModel::PopulateCookieInfoWithFilter(
const std::wstring& filter) {
// mmargh mmargh mmargh! delicious!
CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
for (CookieList::iterator it = cookie_list_.begin();
it != cookie_list_.end(); ++it) {
std::string source_string = it->Source();
if (source_string.empty() || !use_cookie_source_) {
std::string domain = it->Domain();
if (domain.length() > 1 && domain[0] == '.')
domain = domain.substr(1);
// We treat secure cookies just the same as normal ones.
source_string = std::string(chrome::kHttpScheme) +
chrome::kStandardSchemeSeparator + domain + "/";
}
GURL source(source_string);
if (!filter.size() ||
(CookieTreeOriginNode::TitleForUrl(source).find(filter) !=
std::string::npos)) {
CookieTreeOriginNode* origin_node =
root->GetOrCreateOriginNode(source);
CookieTreeCookiesNode* cookies_node =
origin_node->GetOrCreateCookiesNode();
CookieTreeCookieNode* new_cookie = new CookieTreeCookieNode(&*it);
cookies_node->AddCookieNode(new_cookie);
}
}
}
void CookiesTreeModel::OnDatabaseModelInfoLoaded(
const DatabaseInfoList& database_info) {
database_info_list_ = database_info;
......
......@@ -25,6 +25,7 @@
#include "net/base/cookie_monster.h"
#include "ui/base/models/tree_node_model.h"
class BrowsingDataCookieHelper;
class CookiesTreeModel;
class CookieTreeAppCacheNode;
class CookieTreeAppCachesNode;
......@@ -69,8 +70,8 @@ class CookieTreeNode : public ui::TreeNode<CookieTreeNode> {
TYPE_APPCACHE, // This is used for CookieTreeAppCacheNode.
TYPE_INDEXED_DBS, // This is used for CookieTreeIndexedDBsNode.
TYPE_INDEXED_DB, // This is used for CookieTreeIndexedDBNode.
TYPE_FILE_SYSTEMS, // This is used for CookieTreeFileSystemsNode.
TYPE_FILE_SYSTEM, // This is used for CookieTreeFileSystemNode.
TYPE_FILE_SYSTEMS, // This is used for CookieTreeFileSystemsNode.
TYPE_FILE_SYSTEM, // This is used for CookieTreeFileSystemNode.
};
// TODO(viettrungluu): Figure out whether we want to store |origin| as a
......@@ -514,7 +515,7 @@ class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> {
};
CookiesTreeModel(
net::CookieMonster* cookie_monster_,
BrowsingDataCookieHelper* cookie_helper,
BrowsingDataDatabaseHelper* database_helper,
BrowsingDataLocalStorageHelper* local_storage_helper,
BrowsingDataLocalStorageHelper* session_storage_helper,
......@@ -566,10 +567,8 @@ class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> {
typedef std::vector<BrowsingDataFileSystemHelper::FileSystemInfo>
FileSystemInfoList;
void LoadCookies();
void LoadCookiesWithFilter(const std::wstring& filter);
void OnAppCacheModelInfoLoaded();
void OnCookiesModelInfoLoaded(const CookieList& cookie_list);
void OnDatabaseModelInfoLoaded(const DatabaseInfoList& database_info);
void OnLocalStorageModelInfoLoaded(
const LocalStorageInfoList& local_storage_info);
......@@ -581,6 +580,7 @@ class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> {
const FileSystemInfoList& file_system_info);
void PopulateAppCacheInfoWithFilter(const std::wstring& filter);
void PopulateCookieInfoWithFilter(const std::wstring& filter);
void PopulateDatabaseInfoWithFilter(const std::wstring& filter);
void PopulateLocalStorageInfoWithFilter(const std::wstring& filter);
void PopulateSessionStorageInfoWithFilter(const std::wstring& filter);
......@@ -590,18 +590,17 @@ class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> {
void NotifyObserverBeginBatch();
void NotifyObserverEndBatch();
scoped_refptr<net::CookieMonster> cookie_monster_;
CookieList all_cookies_;
scoped_refptr<BrowsingDataAppCacheHelper> appcache_helper_;
scoped_refptr<BrowsingDataCookieHelper> cookie_helper_;
scoped_refptr<BrowsingDataDatabaseHelper> database_helper_;
scoped_refptr<appcache::AppCacheInfoCollection> appcache_info_;
DatabaseInfoList database_info_list_;
scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper_;
scoped_refptr<BrowsingDataLocalStorageHelper> session_storage_helper_;
scoped_refptr<BrowsingDataIndexedDBHelper> indexed_db_helper_;
scoped_refptr<BrowsingDataFileSystemHelper> file_system_helper_;
scoped_refptr<appcache::AppCacheInfoCollection> appcache_info_;
CookieList cookie_list_;
DatabaseInfoList database_info_list_;
LocalStorageInfoList local_storage_info_list_;
LocalStorageInfoList session_storage_info_list_;
IndexedDBInfoList indexed_db_info_list_;
......
// Copyright (c) 2011 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/mock_browsing_data_cookie_helper.h"
MockBrowsingDataCookieHelper::MockBrowsingDataCookieHelper(Profile* profile)
: BrowsingDataCookieHelper(profile),
profile_(profile) {
}
MockBrowsingDataCookieHelper::~MockBrowsingDataCookieHelper() {
}
void MockBrowsingDataCookieHelper::StartFetching(
const net::CookieMonster::GetCookieListCallback &callback) {
callback_ = callback;
}
void MockBrowsingDataCookieHelper::CancelNotification() {
callback_.Reset();
}
void MockBrowsingDataCookieHelper::DeleteCookie(
const net::CookieMonster::CanonicalCookie& cookie) {
std::string key = cookie.Name() + "=" + cookie.Value();
CHECK(cookies_.find(key) != cookies_.end());
cookies_[key] = false;
}
void MockBrowsingDataCookieHelper::AddCookieSamples(
const GURL& url, const std::string& cookie_line) {
typedef net::CookieList::const_iterator cookie_iterator;
net::CookieMonster::ParsedCookie pc(cookie_line);
scoped_ptr<net::CookieMonster::CanonicalCookie> cc;
cc.reset(new net::CookieMonster::CanonicalCookie(url, pc));
if (cc.get()) {
for (cookie_iterator cookie = cookie_list_.begin();
cookie != cookie_list_.end(); ++cookie) {
if (cookie->Name() == cc->Name() &&
cookie->Domain() == cc->Domain()&&
cookie->Path() == cc->Path()) {
return;
}
}
cookie_list_.push_back(*cc);
cookies_[cookie_line] = true;
}
}
void MockBrowsingDataCookieHelper::Notify() {
if (!callback_.is_null())
callback_.Run(cookie_list_);
}
void MockBrowsingDataCookieHelper::Reset() {
for (std::map<const std::string, bool>::iterator i = cookies_.begin();
i != cookies_.end(); ++i)
i->second = true;
}
bool MockBrowsingDataCookieHelper::AllDeleted() {
for (std::map<const std::string, bool>::const_iterator i = cookies_.begin();
i != cookies_.end(); ++i)
if (i->second)
return false;
return true;
}
// Copyright (c) 2011 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.
#ifndef CHROME_BROWSER_MOCK_BROWSING_DATA_COOKIE_HELPER_H_
#define CHROME_BROWSER_MOCK_BROWSING_DATA_COOKIE_HELPER_H_
#pragma once
#include <map>
#include <string>
#include "chrome/browser/browsing_data_cookie_helper.h"
// Mock for BrowsingDataCookieHelper.
class MockBrowsingDataCookieHelper : public BrowsingDataCookieHelper {
public:
explicit MockBrowsingDataCookieHelper(Profile* profile);
// BrowsingDataCookieHelper methods.
virtual void StartFetching(
const net::CookieMonster::GetCookieListCallback &callback);
virtual void CancelNotification();
virtual void DeleteCookie(const net::CookieMonster::CanonicalCookie& cookie);
// Adds some cookie samples.
void AddCookieSamples(const GURL& url, const std::string& cookie_line);
// Notifies the callback.
void Notify();
// Marks all cookies as existing.
void Reset();
// Returns true if all cookies since the last Reset() invocation were
// deleted.
bool AllDeleted();
private:
virtual ~MockBrowsingDataCookieHelper();
Profile* profile_;
net::CookieMonster::GetCookieListCallback callback_;
net::CookieList cookie_list_;
// Stores which cookies exist.
std::map<const std::string, bool> cookies_;
};
#endif // CHROME_BROWSER_MOCK_BROWSING_DATA_COOKIE_HELPER_H_
......@@ -149,13 +149,14 @@ class ClientSideDetectionHostTest : public TabContentsWrapperTestHarness {
mock_profile_ = new NiceMock<MockTestingProfile>();
profile_.reset(mock_profile_);
TabContentsWrapperTestHarness::SetUp();
ui_thread_.reset(new BrowserThread(BrowserThread::UI, &message_loop_));
// Note: we're starting a real IO thread to make sure our DCHECKs that
// verify which thread is running are actually tested.
io_thread_.reset(new BrowserThread(BrowserThread::IO));
ASSERT_TRUE(io_thread_->Start());
TabContentsWrapperTestHarness::SetUp();
// Inject service classes.
csd_service_.reset(new StrictMock<MockClientSideDetectionService>());
sb_service_ = new StrictMock<MockSafeBrowsingService>();
......
......@@ -7,6 +7,7 @@
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browsing_data_appcache_helper.h"
#include "chrome/browser/browsing_data_cookie_helper.h"
#include "chrome/browser/browsing_data_database_helper.h"
#include "chrome/browser/browsing_data_file_system_helper.h"
#include "chrome/browser/browsing_data_indexed_db_helper.h"
......@@ -14,7 +15,6 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/cookies_tree_model_util.h"
#include "grit/generated_resources.h"
#include "net/url_request/url_request_context_getter.h"
#include "ui/base/l10n/l10n_util.h"
CookiesViewHandler::CookiesViewHandler() : batch_update_(false) {
......@@ -143,8 +143,7 @@ void CookiesViewHandler::EnsureCookiesTreeModelCreated() {
if (!cookies_tree_model_.get()) {
Profile* profile = web_ui_->GetProfile();
cookies_tree_model_.reset(new CookiesTreeModel(
profile->GetRequestContext()->DONTUSEME_GetCookieStore()->
GetCookieMonster(),
new BrowsingDataCookieHelper(profile),
new BrowsingDataDatabaseHelper(profile),
new BrowsingDataLocalStorageHelper(profile),
NULL,
......
......@@ -306,6 +306,8 @@
'browser/browser_util_win.h',
'browser/browsing_data_appcache_helper.cc',
'browser/browsing_data_appcache_helper.h',
'browser/browsing_data_cookie_helper.cc',
'browser/browsing_data_cookie_helper.h',
'browser/browsing_data_database_helper.cc',
'browser/browsing_data_database_helper.h',
'browser/browsing_data_file_system_helper.cc',
......
......@@ -79,6 +79,8 @@
'browser/extensions/test_extension_service.h',
'browser/mock_browsing_data_appcache_helper.cc',
'browser/mock_browsing_data_appcache_helper.h',
'browser/mock_browsing_data_cookie_helper.cc',
'browser/mock_browsing_data_cookie_helper.h',
'browser/mock_browsing_data_database_helper.cc',
'browser/mock_browsing_data_database_helper.h',
'browser/mock_browsing_data_file_system_helper.cc',
......@@ -1320,6 +1322,7 @@
'browser/browser_commands_unittest.cc',
'browser/browser_main_unittest.cc',
'browser/browsing_data_appcache_helper_unittest.cc',
'browser/browsing_data_cookie_helper_unittest.cc',
'browser/browsing_data_database_helper_unittest.cc',
'browser/browsing_data_file_system_helper_unittest.cc',
'browser/browsing_data_indexed_db_helper_unittest.cc',
......
......@@ -2151,6 +2151,28 @@ void CookieMonster::CanonicalCookie::SetSessionCookieExpiryTime() {
#endif
}
CookieMonster::CanonicalCookie* CookieMonster::CanonicalCookie::Create(
const GURL& url,
const ParsedCookie& pc) {
std::string domain_string;
if (pc.HasDomain())
domain_string = pc.Domain();
std::string path_string;
if (pc.HasPath())
path_string = pc.Path();
std::string mac_key = pc.HasMACKey() ? pc.MACKey() : std::string();
std::string mac_algorithm = pc.HasMACAlgorithm() ?
pc.MACAlgorithm() : std::string();
Time creation_time = Time::Now();
Time expiration_time;
if (pc.HasExpires())
expiration_time = net::CookieMonster::ParseCookieTime(pc.Expires());
return (Create(url, pc.Name(), pc.Value(), domain_string, path_string,
mac_key, mac_algorithm, creation_time, expiration_time,
pc.IsSecure(), pc.IsHttpOnly()));
}
CookieMonster::CanonicalCookie* CookieMonster::CanonicalCookie::Create(
const GURL& url,
const std::string& name,
......
......@@ -617,6 +617,12 @@ class NET_API CookieMonster::CanonicalCookie {
// Supports the default copy constructor.
// Creates a canonical cookie from parsed cookie.
// Canonicalizes and validates inputs. May return NULL if an attribute
// value is invalid.
static CanonicalCookie* Create(const GURL& url,
const ParsedCookie& pc);
// Creates a canonical cookie from unparsed attribute values.
// Canonicalizes and validates inputs. May return NULL if an attribute
// value is invalid.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment