1 // Copyright 2015 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 "content/browser/net/quota_policy_cookie_store.h"
9 #include "base/basictypes.h"
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/profiler/scoped_tracker.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/cookie_store_factory.h"
19 #include "net/cookies/canonical_cookie.h"
20 #include "net/cookies/cookie_constants.h"
21 #include "net/cookies/cookie_util.h"
22 #include "net/extras/sqlite/cookie_crypto_delegate.h"
23 #include "storage/browser/quota/special_storage_policy.h"
28 QuotaPolicyCookieStore::QuotaPolicyCookieStore(
29 const scoped_refptr
<net::SQLitePersistentCookieStore
>& cookie_store
,
30 storage::SpecialStoragePolicy
* special_storage_policy
)
31 : special_storage_policy_(special_storage_policy
),
32 persistent_store_(cookie_store
) {
35 QuotaPolicyCookieStore::~QuotaPolicyCookieStore() {
36 if (!special_storage_policy_
.get() ||
37 !special_storage_policy_
->HasSessionOnlyOrigins()) {
41 std::list
<net::SQLitePersistentCookieStore::CookieOrigin
>
43 for (const auto& cookie
: cookies_per_origin_
) {
44 if (cookie
.second
== 0) {
47 const GURL
url(net::cookie_util::CookieOriginToURL(cookie
.first
.first
,
48 cookie
.first
.second
));
49 if (!url
.is_valid() || !special_storage_policy_
->IsStorageSessionOnly(url
))
52 session_only_cookies
.push_back(cookie
.first
);
55 persistent_store_
->DeleteAllInList(session_only_cookies
);
58 void QuotaPolicyCookieStore::Load(const LoadedCallback
& loaded_callback
) {
59 persistent_store_
->Load(
60 base::Bind(&QuotaPolicyCookieStore::OnLoad
, this, loaded_callback
));
63 void QuotaPolicyCookieStore::LoadCookiesForKey(
64 const std::string
& key
,
65 const LoadedCallback
& loaded_callback
) {
66 persistent_store_
->LoadCookiesForKey(
68 base::Bind(&QuotaPolicyCookieStore::OnLoad
, this, loaded_callback
));
71 void QuotaPolicyCookieStore::AddCookie(const net::CanonicalCookie
& cc
) {
72 net::SQLitePersistentCookieStore::CookieOrigin
origin(
73 cc
.Domain(), cc
.IsSecure());
74 ++cookies_per_origin_
[origin
];
75 persistent_store_
->AddCookie(cc
);
78 void QuotaPolicyCookieStore::UpdateCookieAccessTime(
79 const net::CanonicalCookie
& cc
) {
80 persistent_store_
->UpdateCookieAccessTime(cc
);
83 void QuotaPolicyCookieStore::DeleteCookie(const net::CanonicalCookie
& cc
) {
84 net::SQLitePersistentCookieStore::CookieOrigin
origin(
85 cc
.Domain(), cc
.IsSecure());
86 DCHECK_GE(cookies_per_origin_
[origin
], 1U);
87 --cookies_per_origin_
[origin
];
88 persistent_store_
->DeleteCookie(cc
);
91 void QuotaPolicyCookieStore::SetForceKeepSessionState() {
92 special_storage_policy_
= nullptr;
95 void QuotaPolicyCookieStore::Flush(const base::Closure
& callback
) {
96 persistent_store_
->Flush(callback
);
99 void QuotaPolicyCookieStore::OnLoad(
100 const LoadedCallback
& loaded_callback
,
101 const std::vector
<net::CanonicalCookie
*>& cookies
) {
102 for (const auto& cookie
: cookies
) {
103 net::SQLitePersistentCookieStore::CookieOrigin
origin(
104 cookie
->Domain(), cookie
->IsSecure());
105 ++cookies_per_origin_
[origin
];
108 loaded_callback
.Run(cookies
);
111 CookieStoreConfig::CookieStoreConfig()
112 : session_cookie_mode(EPHEMERAL_SESSION_COOKIES
),
113 crypto_delegate(nullptr) {
114 // Default to an in-memory cookie store.
117 CookieStoreConfig::CookieStoreConfig(
118 const base::FilePath
& path
,
119 SessionCookieMode session_cookie_mode
,
120 storage::SpecialStoragePolicy
* storage_policy
,
121 net::CookieMonsterDelegate
* cookie_delegate
)
123 session_cookie_mode(session_cookie_mode
),
124 storage_policy(storage_policy
),
125 cookie_delegate(cookie_delegate
),
126 crypto_delegate(nullptr) {
127 CHECK(!path
.empty() || session_cookie_mode
== EPHEMERAL_SESSION_COOKIES
);
130 CookieStoreConfig::~CookieStoreConfig() {
133 net::CookieStore
* CreateCookieStore(const CookieStoreConfig
& config
) {
134 // TODO(bcwhite): Remove ScopedTracker below once crbug.com/483686 is fixed.
135 tracked_objects::ScopedTracker
tracking_profile(
136 FROM_HERE_WITH_EXPLICIT_FUNCTION("483686 content::CreateCookieStore"));
138 net::CookieMonster
* cookie_monster
= nullptr;
140 if (config
.path
.empty()) {
141 // Empty path means in-memory store.
142 cookie_monster
= new net::CookieMonster(nullptr,
143 config
.cookie_delegate
.get());
145 scoped_refptr
<base::SequencedTaskRunner
> client_task_runner
=
146 config
.client_task_runner
;
147 scoped_refptr
<base::SequencedTaskRunner
> background_task_runner
=
148 config
.background_task_runner
;
150 if (!client_task_runner
.get()) {
152 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
);
155 if (!background_task_runner
.get()) {
156 background_task_runner
=
157 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(
158 BrowserThread::GetBlockingPool()->GetSequenceToken());
161 scoped_refptr
<net::SQLitePersistentCookieStore
> sqlite_store(
162 new net::SQLitePersistentCookieStore(
165 background_task_runner
,
166 (config
.session_cookie_mode
==
167 CookieStoreConfig::RESTORED_SESSION_COOKIES
),
168 config
.crypto_delegate
));
170 QuotaPolicyCookieStore
* persistent_store
=
171 new QuotaPolicyCookieStore(
173 config
.storage_policy
.get());
176 new net::CookieMonster(persistent_store
, config
.cookie_delegate
.get());
177 if ((config
.session_cookie_mode
==
178 CookieStoreConfig::PERSISTANT_SESSION_COOKIES
) ||
179 (config
.session_cookie_mode
==
180 CookieStoreConfig::RESTORED_SESSION_COOKIES
)) {
181 cookie_monster
->SetPersistSessionCookies(true);
185 return cookie_monster
;
188 } // namespace content