Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / browsing_data / browsing_data_cookie_helper.cc
blob25355209ffca4547c240a5ca40816eb5695d70d4
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
7 #include "utility"
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/stl_util.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
16 #include "net/cookies/canonical_cookie.h"
17 #include "net/cookies/cookie_util.h"
18 #include "net/cookies/parsed_cookie.h"
19 #include "net/url_request/url_request_context.h"
20 #include "net/url_request/url_request_context_getter.h"
21 #include "url/gurl.h"
23 using content::BrowserThread;
25 namespace {
26 const char kGlobalCookieSetURL[] = "chrome://cookieset";
29 BrowsingDataCookieHelper::BrowsingDataCookieHelper(
30 net::URLRequestContextGetter* request_context_getter)
31 : is_fetching_(false),
32 request_context_getter_(request_context_getter) {
33 DCHECK_CURRENTLY_ON(BrowserThread::UI);
36 BrowsingDataCookieHelper::~BrowsingDataCookieHelper() {
39 void BrowsingDataCookieHelper::StartFetching(
40 const base::Callback<void(const net::CookieList& cookies)>& callback) {
41 DCHECK_CURRENTLY_ON(BrowserThread::UI);
42 DCHECK(!is_fetching_);
43 DCHECK(!callback.is_null());
44 DCHECK(completion_callback_.is_null());
45 is_fetching_ = true;
46 completion_callback_ = callback;
47 BrowserThread::PostTask(
48 BrowserThread::IO, FROM_HERE,
49 base::Bind(&BrowsingDataCookieHelper::FetchCookiesOnIOThread, this));
52 void BrowsingDataCookieHelper::DeleteCookie(
53 const net::CanonicalCookie& cookie) {
54 DCHECK_CURRENTLY_ON(BrowserThread::UI);
55 BrowserThread::PostTask(
56 BrowserThread::IO, FROM_HERE,
57 base::Bind(&BrowsingDataCookieHelper::DeleteCookieOnIOThread,
58 this, cookie));
61 void BrowsingDataCookieHelper::FetchCookiesOnIOThread() {
62 DCHECK_CURRENTLY_ON(BrowserThread::IO);
63 scoped_refptr<net::CookieMonster> cookie_monster =
64 request_context_getter_->GetURLRequestContext()->
65 cookie_store()->GetCookieMonster();
66 if (cookie_monster.get()) {
67 cookie_monster->GetAllCookiesAsync(
68 base::Bind(&BrowsingDataCookieHelper::OnFetchComplete, this));
69 } else {
70 OnFetchComplete(net::CookieList());
74 void BrowsingDataCookieHelper::OnFetchComplete(const net::CookieList& cookies) {
75 DCHECK_CURRENTLY_ON(BrowserThread::IO);
76 BrowserThread::PostTask(
77 BrowserThread::UI, FROM_HERE,
78 base::Bind(&BrowsingDataCookieHelper::NotifyInUIThread, this, cookies));
81 void BrowsingDataCookieHelper::NotifyInUIThread(
82 const net::CookieList& cookies) {
83 DCHECK_CURRENTLY_ON(BrowserThread::UI);
84 DCHECK(is_fetching_);
85 is_fetching_ = false;
86 completion_callback_.Run(cookies);
87 completion_callback_.Reset();
90 void BrowsingDataCookieHelper::DeleteCookieOnIOThread(
91 const net::CanonicalCookie& cookie) {
92 DCHECK_CURRENTLY_ON(BrowserThread::IO);
93 scoped_refptr<net::CookieMonster> cookie_monster =
94 request_context_getter_->GetURLRequestContext()->
95 cookie_store()->GetCookieMonster();
96 if (cookie_monster.get()) {
97 cookie_monster->DeleteCanonicalCookieAsync(
98 cookie, net::CookieMonster::DeleteCookieCallback());
102 CannedBrowsingDataCookieHelper::CannedBrowsingDataCookieHelper(
103 net::URLRequestContextGetter* request_context_getter)
104 : BrowsingDataCookieHelper(request_context_getter) {
107 CannedBrowsingDataCookieHelper::~CannedBrowsingDataCookieHelper() {
108 Reset();
111 void CannedBrowsingDataCookieHelper::AddReadCookies(
112 const GURL& frame_url,
113 const GURL& url,
114 const net::CookieList& cookie_list) {
115 typedef net::CookieList::const_iterator cookie_iterator;
116 for (cookie_iterator add_cookie = cookie_list.begin();
117 add_cookie != cookie_list.end(); ++add_cookie) {
118 AddCookie(frame_url, *add_cookie);
122 void CannedBrowsingDataCookieHelper::AddChangedCookie(
123 const GURL& frame_url,
124 const GURL& url,
125 const std::string& cookie_line,
126 const net::CookieOptions& options) {
127 scoped_ptr<net::CanonicalCookie> cookie(net::CanonicalCookie::Create(
128 url, cookie_line, base::Time::Now(), options));
129 if (cookie.get())
130 AddCookie(frame_url, *cookie);
133 void CannedBrowsingDataCookieHelper::Reset() {
134 STLDeleteContainerPairSecondPointers(origin_cookie_set_map_.begin(),
135 origin_cookie_set_map_.end());
136 origin_cookie_set_map_.clear();
139 bool CannedBrowsingDataCookieHelper::empty() const {
140 for (OriginCookieSetMap::const_iterator it = origin_cookie_set_map_.begin();
141 it != origin_cookie_set_map_.end();
142 ++it) {
143 if (!it->second->empty())
144 return false;
146 return true;
150 size_t CannedBrowsingDataCookieHelper::GetCookieCount() const {
151 size_t count = 0;
152 for (OriginCookieSetMap::const_iterator it = origin_cookie_set_map_.begin();
153 it != origin_cookie_set_map_.end();
154 ++it) {
155 count += it->second->size();
157 return count;
161 void CannedBrowsingDataCookieHelper::StartFetching(
162 const net::CookieMonster::GetCookieListCallback& callback) {
163 DCHECK_CURRENTLY_ON(BrowserThread::UI);
164 net::CookieList cookie_list;
165 for (OriginCookieSetMap::iterator it = origin_cookie_set_map_.begin();
166 it != origin_cookie_set_map_.end();
167 ++it) {
168 cookie_list.insert(cookie_list.begin(),
169 it->second->begin(),
170 it->second->end());
172 callback.Run(cookie_list);
175 void CannedBrowsingDataCookieHelper::DeleteCookie(
176 const net::CanonicalCookie& cookie) {
177 for (OriginCookieSetMap::iterator it = origin_cookie_set_map_.begin();
178 it != origin_cookie_set_map_.end();
179 ++it) {
180 DeleteMatchingCookie(cookie, it->second);
182 BrowsingDataCookieHelper::DeleteCookie(cookie);
185 bool CannedBrowsingDataCookieHelper::DeleteMatchingCookie(
186 const net::CanonicalCookie& add_cookie,
187 canonical_cookie::CookieHashSet* cookie_set) {
188 return cookie_set->erase(add_cookie) > 0;
191 canonical_cookie::CookieHashSet* CannedBrowsingDataCookieHelper::GetCookiesFor(
192 const GURL& first_party_origin) {
193 OriginCookieSetMap::iterator it =
194 origin_cookie_set_map_.find(first_party_origin);
195 if (it == origin_cookie_set_map_.end()) {
196 canonical_cookie::CookieHashSet* cookies =
197 new canonical_cookie::CookieHashSet;
198 origin_cookie_set_map_.insert(
199 std::pair<GURL, canonical_cookie::CookieHashSet*>(first_party_origin,
200 cookies));
201 return cookies;
203 return it->second;
206 void CannedBrowsingDataCookieHelper::AddCookie(
207 const GURL& frame_url,
208 const net::CanonicalCookie& cookie) {
209 // Storing cookies in separate cookie sets per frame origin makes the
210 // GetCookieCount method count a cookie multiple times if it is stored in
211 // multiple sets.
212 // E.g. let "example.com" be redirected to "www.example.com". A cookie set
213 // with the cookie string "A=B; Domain=.example.com" would be sent to both
214 // hosts. This means it would be stored in the separate cookie sets for both
215 // hosts ("example.com", "www.example.com"). The method GetCookieCount would
216 // count this cookie twice. To prevent this, we us a single global cookie
217 // set as a work-around to store all added cookies. Per frame URL cookie
218 // sets are currently not used. In the future they will be used for
219 // collecting cookies per origin in redirect chains.
220 // TODO(markusheintz): A) Change the GetCookiesCount method to prevent
221 // counting cookies multiple times if they are stored in multiple cookie
222 // sets. B) Replace the GetCookieFor method call below with:
223 // "GetCookiesFor(frame_url.GetOrigin());"
224 CR_DEFINE_STATIC_LOCAL(const GURL, origin_cookie_url, (kGlobalCookieSetURL));
225 canonical_cookie::CookieHashSet* cookie_set =
226 GetCookiesFor(origin_cookie_url);
227 DeleteMatchingCookie(cookie, cookie_set);
228 cookie_set->insert(cookie);