| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/files/file_util.h" | 6 #include "base/files/file_util.h" |
| 7 #include "base/files/scoped_temp_dir.h" | 7 #include "base/files/scoped_temp_dir.h" |
| 8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "base/stl_util.h" | |
| 11 #include "base/synchronization/waitable_event.h" | 10 #include "base/synchronization/waitable_event.h" |
| 12 #include "base/test/sequenced_worker_pool_owner.h" | 11 #include "base/test/sequenced_worker_pool_owner.h" |
| 13 #include "base/threading/sequenced_worker_pool.h" | 12 #include "base/threading/sequenced_worker_pool.h" |
| 14 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 15 #include "content/browser/net/quota_policy_cookie_store.h" | 14 #include "content/browser/net/quota_policy_cookie_store.h" |
| 16 #include "content/public/test/mock_special_storage_policy.h" | 15 #include "content/public/test/mock_special_storage_policy.h" |
| 17 #include "content/public/test/test_browser_thread_bundle.h" | 16 #include "content/public/test/test_browser_thread_bundle.h" |
| 18 #include "net/cookies/cookie_util.h" | 17 #include "net/cookies/cookie_util.h" |
| 19 #include "net/ssl/ssl_client_cert_type.h" | 18 #include "net/ssl/ssl_client_cert_type.h" |
| 20 #include "net/test/cert_test_util.h" | 19 #include "net/test/cert_test_util.h" |
| 21 #include "net/test/test_data_directory.h" | 20 #include "net/test/test_data_directory.h" |
| 22 #include "sql/statement.h" | 21 #include "sql/statement.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 24 #include "url/gurl.h" | 23 #include "url/gurl.h" |
| 25 | 24 |
| 26 namespace { | 25 namespace { |
| 27 const base::FilePath::CharType kTestCookiesFilename[] = | 26 const base::FilePath::CharType kTestCookiesFilename[] = |
| 28 FILE_PATH_LITERAL("Cookies"); | 27 FILE_PATH_LITERAL("Cookies"); |
| 29 } | 28 } |
| 30 | 29 |
| 31 namespace content { | 30 namespace content { |
| 32 namespace { | 31 namespace { |
| 33 | 32 |
| 34 typedef std::vector<net::CanonicalCookie*> CanonicalCookieVector; | 33 using CanonicalCookieVector = |
| 34 std::vector<std::unique_ptr<net::CanonicalCookie>>; |
| 35 | 35 |
| 36 class QuotaPolicyCookieStoreTest : public testing::Test { | 36 class QuotaPolicyCookieStoreTest : public testing::Test { |
| 37 public: | 37 public: |
| 38 QuotaPolicyCookieStoreTest() | 38 QuotaPolicyCookieStoreTest() |
| 39 : pool_owner_(new base::SequencedWorkerPoolOwner(3, "Background Pool")), | 39 : pool_owner_(new base::SequencedWorkerPoolOwner(3, "Background Pool")), |
| 40 loaded_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 40 loaded_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 41 base::WaitableEvent::InitialState::NOT_SIGNALED), | 41 base::WaitableEvent::InitialState::NOT_SIGNALED), |
| 42 destroy_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 42 destroy_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 43 base::WaitableEvent::InitialState::NOT_SIGNALED) {} | 43 base::WaitableEvent::InitialState::NOT_SIGNALED) {} |
| 44 | 44 |
| 45 void OnLoaded(const CanonicalCookieVector& cookies) { | 45 void OnLoaded(CanonicalCookieVector cookies) { |
| 46 cookies_ = cookies; | 46 cookies_.swap(cookies); |
| 47 loaded_event_.Signal(); | 47 loaded_event_.Signal(); |
| 48 } | 48 } |
| 49 | 49 |
| 50 void Load(CanonicalCookieVector* cookies) { | 50 void Load(CanonicalCookieVector* cookies) { |
| 51 EXPECT_FALSE(loaded_event_.IsSignaled()); | 51 EXPECT_FALSE(loaded_event_.IsSignaled()); |
| 52 store_->Load(base::Bind(&QuotaPolicyCookieStoreTest::OnLoaded, | 52 store_->Load(base::Bind(&QuotaPolicyCookieStoreTest::OnLoaded, |
| 53 base::Unretained(this))); | 53 base::Unretained(this))); |
| 54 loaded_event_.Wait(); | 54 loaded_event_.Wait(); |
| 55 *cookies = cookies_; | 55 cookies->swap(cookies_); |
| 56 } | 56 } |
| 57 | 57 |
| 58 void ReleaseStore() { | 58 void ReleaseStore() { |
| 59 EXPECT_TRUE(background_task_runner()->RunsTasksOnCurrentThread()); | 59 EXPECT_TRUE(background_task_runner()->RunsTasksOnCurrentThread()); |
| 60 store_ = nullptr; | 60 store_ = nullptr; |
| 61 destroy_event_.Signal(); | 61 destroy_event_.Signal(); |
| 62 } | 62 } |
| 63 | 63 |
| 64 void DestroyStoreOnBackgroundThread() { | 64 void DestroyStoreOnBackgroundThread() { |
| 65 background_task_runner()->PostTask( | 65 background_task_runner()->PostTask( |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 t += base::TimeDelta::FromInternalValue(10); | 141 t += base::TimeDelta::FromInternalValue(10); |
| 142 AddCookie(GURL("http://persistent.com"), "A", "B", std::string(), "/", t); | 142 AddCookie(GURL("http://persistent.com"), "A", "B", std::string(), "/", t); |
| 143 | 143 |
| 144 // Replace the store, which forces the current store to flush data to | 144 // Replace the store, which forces the current store to flush data to |
| 145 // disk. Then, after reloading the store, confirm that the data was flushed by | 145 // disk. Then, after reloading the store, confirm that the data was flushed by |
| 146 // making sure it loads successfully. This ensures that all pending commits | 146 // making sure it loads successfully. This ensures that all pending commits |
| 147 // are made to the store before allowing it to be closed. | 147 // are made to the store before allowing it to be closed. |
| 148 DestroyStore(); | 148 DestroyStore(); |
| 149 | 149 |
| 150 // Reload and test for persistence. | 150 // Reload and test for persistence. |
| 151 base::STLDeleteElements(&cookies); | 151 cookies.clear(); |
| 152 CreateAndLoad(nullptr, &cookies); | 152 CreateAndLoad(nullptr, &cookies); |
| 153 EXPECT_EQ(2U, cookies.size()); | 153 EXPECT_EQ(2U, cookies.size()); |
| 154 bool found_foo_cookie = false; | 154 bool found_foo_cookie = false; |
| 155 bool found_persistent_cookie = false; | 155 bool found_persistent_cookie = false; |
| 156 for (auto* cookie : cookies) { | 156 for (const auto& cookie : cookies) { |
| 157 if (cookie->Domain() == "foo.com") | 157 if (cookie->Domain() == "foo.com") |
| 158 found_foo_cookie = true; | 158 found_foo_cookie = true; |
| 159 else if (cookie->Domain() == "persistent.com") | 159 else if (cookie->Domain() == "persistent.com") |
| 160 found_persistent_cookie = true; | 160 found_persistent_cookie = true; |
| 161 } | 161 } |
| 162 EXPECT_TRUE(found_foo_cookie); | 162 EXPECT_TRUE(found_foo_cookie); |
| 163 EXPECT_TRUE(found_persistent_cookie); | 163 EXPECT_TRUE(found_persistent_cookie); |
| 164 | 164 |
| 165 // Now delete the cookies and check persistence again. | 165 // Now delete the cookies and check persistence again. |
| 166 store_->DeleteCookie(*cookies[0]); | 166 store_->DeleteCookie(*cookies[0]); |
| 167 store_->DeleteCookie(*cookies[1]); | 167 store_->DeleteCookie(*cookies[1]); |
| 168 DestroyStore(); | 168 DestroyStore(); |
| 169 | 169 |
| 170 // Reload and check if the cookies have been removed. | 170 // Reload and check if the cookies have been removed. |
| 171 base::STLDeleteElements(&cookies); | 171 cookies.clear(); |
| 172 CreateAndLoad(nullptr, &cookies); | 172 CreateAndLoad(nullptr, &cookies); |
| 173 EXPECT_EQ(0U, cookies.size()); | 173 EXPECT_EQ(0U, cookies.size()); |
| 174 base::STLDeleteElements(&cookies); | 174 cookies.clear(); |
| 175 } | 175 } |
| 176 | 176 |
| 177 // Test if data is stored as expected in the QuotaPolicy database. | 177 // Test if data is stored as expected in the QuotaPolicy database. |
| 178 TEST_F(QuotaPolicyCookieStoreTest, TestPolicy) { | 178 TEST_F(QuotaPolicyCookieStoreTest, TestPolicy) { |
| 179 CanonicalCookieVector cookies; | 179 CanonicalCookieVector cookies; |
| 180 CreateAndLoad(nullptr, &cookies); | 180 CreateAndLoad(nullptr, &cookies); |
| 181 ASSERT_EQ(0U, cookies.size()); | 181 ASSERT_EQ(0U, cookies.size()); |
| 182 | 182 |
| 183 base::Time t = base::Time::Now(); | 183 base::Time t = base::Time::Now(); |
| 184 AddCookie(GURL("http://foo.com"), "A", "B", std::string(), "/", t); | 184 AddCookie(GURL("http://foo.com"), "A", "B", std::string(), "/", t); |
| 185 t += base::TimeDelta::FromInternalValue(10); | 185 t += base::TimeDelta::FromInternalValue(10); |
| 186 AddCookie(GURL("http://persistent.com"), "A", "B", std::string(), "/", t); | 186 AddCookie(GURL("http://persistent.com"), "A", "B", std::string(), "/", t); |
| 187 t += base::TimeDelta::FromInternalValue(10); | 187 t += base::TimeDelta::FromInternalValue(10); |
| 188 AddCookie(GURL("http://nonpersistent.com"), "A", "B", std::string(), "/", t); | 188 AddCookie(GURL("http://nonpersistent.com"), "A", "B", std::string(), "/", t); |
| 189 | 189 |
| 190 // Replace the store, which forces the current store to flush data to | 190 // Replace the store, which forces the current store to flush data to |
| 191 // disk. Then, after reloading the store, confirm that the data was flushed by | 191 // disk. Then, after reloading the store, confirm that the data was flushed by |
| 192 // making sure it loads successfully. This ensures that all pending commits | 192 // making sure it loads successfully. This ensures that all pending commits |
| 193 // are made to the store before allowing it to be closed. | 193 // are made to the store before allowing it to be closed. |
| 194 DestroyStore(); | 194 DestroyStore(); |
| 195 // Specify storage policy that makes "nonpersistent.com" session only. | 195 // Specify storage policy that makes "nonpersistent.com" session only. |
| 196 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy = | 196 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy = |
| 197 new content::MockSpecialStoragePolicy(); | 197 new content::MockSpecialStoragePolicy(); |
| 198 storage_policy->AddSessionOnly( | 198 storage_policy->AddSessionOnly( |
| 199 net::cookie_util::CookieOriginToURL("nonpersistent.com", false)); | 199 net::cookie_util::CookieOriginToURL("nonpersistent.com", false)); |
| 200 | 200 |
| 201 // Reload and test for persistence. | 201 // Reload and test for persistence. |
| 202 base::STLDeleteElements(&cookies); | 202 cookies.clear(); |
| 203 CreateAndLoad(storage_policy.get(), &cookies); | 203 CreateAndLoad(storage_policy.get(), &cookies); |
| 204 EXPECT_EQ(3U, cookies.size()); | 204 EXPECT_EQ(3U, cookies.size()); |
| 205 | 205 |
| 206 t += base::TimeDelta::FromInternalValue(10); | 206 t += base::TimeDelta::FromInternalValue(10); |
| 207 AddCookie(GURL("http://nonpersistent.com"), "A", "B", std::string(), | 207 AddCookie(GURL("http://nonpersistent.com"), "A", "B", std::string(), |
| 208 "/second", t); | 208 "/second", t); |
| 209 | 209 |
| 210 // Now close the store, and "nonpersistent.com" should be deleted according to | 210 // Now close the store, and "nonpersistent.com" should be deleted according to |
| 211 // policy. | 211 // policy. |
| 212 DestroyStore(); | 212 DestroyStore(); |
| 213 base::STLDeleteElements(&cookies); | 213 cookies.clear(); |
| 214 CreateAndLoad(nullptr, &cookies); | 214 CreateAndLoad(nullptr, &cookies); |
| 215 | 215 |
| 216 EXPECT_EQ(2U, cookies.size()); | 216 EXPECT_EQ(2U, cookies.size()); |
| 217 for (auto* cookie : cookies) { | 217 for (const auto& cookie : cookies) { |
| 218 EXPECT_NE("nonpersistent.com", cookie->Domain()); | 218 EXPECT_NE("nonpersistent.com", cookie->Domain()); |
| 219 } | 219 } |
| 220 base::STLDeleteElements(&cookies); | 220 cookies.clear(); |
| 221 } | 221 } |
| 222 | 222 |
| 223 TEST_F(QuotaPolicyCookieStoreTest, ForceKeepSessionState) { | 223 TEST_F(QuotaPolicyCookieStoreTest, ForceKeepSessionState) { |
| 224 CanonicalCookieVector cookies; | 224 CanonicalCookieVector cookies; |
| 225 CreateAndLoad(nullptr, &cookies); | 225 CreateAndLoad(nullptr, &cookies); |
| 226 ASSERT_EQ(0U, cookies.size()); | 226 ASSERT_EQ(0U, cookies.size()); |
| 227 | 227 |
| 228 base::Time t = base::Time::Now(); | 228 base::Time t = base::Time::Now(); |
| 229 AddCookie(GURL("http://foo.com"), "A", "B", std::string(), "/", t); | 229 AddCookie(GURL("http://foo.com"), "A", "B", std::string(), "/", t); |
| 230 | 230 |
| 231 // Recreate |store_| with a storage policy that makes "nonpersistent.com" | 231 // Recreate |store_| with a storage policy that makes "nonpersistent.com" |
| 232 // session only, but then instruct the store to forcibly keep all cookies. | 232 // session only, but then instruct the store to forcibly keep all cookies. |
| 233 DestroyStore(); | 233 DestroyStore(); |
| 234 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy = | 234 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy = |
| 235 new content::MockSpecialStoragePolicy(); | 235 new content::MockSpecialStoragePolicy(); |
| 236 storage_policy->AddSessionOnly( | 236 storage_policy->AddSessionOnly( |
| 237 net::cookie_util::CookieOriginToURL("nonpersistent.com", false)); | 237 net::cookie_util::CookieOriginToURL("nonpersistent.com", false)); |
| 238 | 238 |
| 239 // Reload and test for persistence | 239 // Reload and test for persistence |
| 240 base::STLDeleteElements(&cookies); | 240 cookies.clear(); |
| 241 CreateAndLoad(storage_policy.get(), &cookies); | 241 CreateAndLoad(storage_policy.get(), &cookies); |
| 242 EXPECT_EQ(1U, cookies.size()); | 242 EXPECT_EQ(1U, cookies.size()); |
| 243 | 243 |
| 244 t += base::TimeDelta::FromInternalValue(10); | 244 t += base::TimeDelta::FromInternalValue(10); |
| 245 AddCookie(GURL("http://persistent.com"), "A", "B", std::string(), "/", t); | 245 AddCookie(GURL("http://persistent.com"), "A", "B", std::string(), "/", t); |
| 246 t += base::TimeDelta::FromInternalValue(10); | 246 t += base::TimeDelta::FromInternalValue(10); |
| 247 AddCookie(GURL("http://nonpersistent.com"), "A", "B", std::string(), "/", t); | 247 AddCookie(GURL("http://nonpersistent.com"), "A", "B", std::string(), "/", t); |
| 248 | 248 |
| 249 // Now close the store, but the "nonpersistent.com" cookie should not be | 249 // Now close the store, but the "nonpersistent.com" cookie should not be |
| 250 // deleted. | 250 // deleted. |
| 251 store_->SetForceKeepSessionState(); | 251 store_->SetForceKeepSessionState(); |
| 252 DestroyStore(); | 252 DestroyStore(); |
| 253 base::STLDeleteElements(&cookies); | 253 cookies.clear(); |
| 254 CreateAndLoad(nullptr, &cookies); | 254 CreateAndLoad(nullptr, &cookies); |
| 255 | 255 |
| 256 EXPECT_EQ(3U, cookies.size()); | 256 EXPECT_EQ(3U, cookies.size()); |
| 257 base::STLDeleteElements(&cookies); | 257 cookies.clear(); |
| 258 } | 258 } |
| 259 | 259 |
| 260 // Tests that the special storage policy is properly applied even when the store | 260 // Tests that the special storage policy is properly applied even when the store |
| 261 // is destroyed on a background thread. | 261 // is destroyed on a background thread. |
| 262 TEST_F(QuotaPolicyCookieStoreTest, TestDestroyOnBackgroundThread) { | 262 TEST_F(QuotaPolicyCookieStoreTest, TestDestroyOnBackgroundThread) { |
| 263 // Specify storage policy that makes "nonpersistent.com" session only. | 263 // Specify storage policy that makes "nonpersistent.com" session only. |
| 264 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy = | 264 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy = |
| 265 new content::MockSpecialStoragePolicy(); | 265 new content::MockSpecialStoragePolicy(); |
| 266 storage_policy->AddSessionOnly( | 266 storage_policy->AddSessionOnly( |
| 267 net::cookie_util::CookieOriginToURL("nonpersistent.com", false)); | 267 net::cookie_util::CookieOriginToURL("nonpersistent.com", false)); |
| 268 | 268 |
| 269 CanonicalCookieVector cookies; | 269 CanonicalCookieVector cookies; |
| 270 CreateAndLoad(storage_policy.get(), &cookies); | 270 CreateAndLoad(storage_policy.get(), &cookies); |
| 271 ASSERT_EQ(0U, cookies.size()); | 271 ASSERT_EQ(0U, cookies.size()); |
| 272 | 272 |
| 273 base::Time t = base::Time::Now(); | 273 base::Time t = base::Time::Now(); |
| 274 AddCookie(GURL("http://nonpersistent.com"), "A", "B", std::string(), "/", t); | 274 AddCookie(GURL("http://nonpersistent.com"), "A", "B", std::string(), "/", t); |
| 275 | 275 |
| 276 // Replace the store, which forces the current store to flush data to | 276 // Replace the store, which forces the current store to flush data to |
| 277 // disk. Then, after reloading the store, confirm that the data was flushed by | 277 // disk. Then, after reloading the store, confirm that the data was flushed by |
| 278 // making sure it loads successfully. This ensures that all pending commits | 278 // making sure it loads successfully. This ensures that all pending commits |
| 279 // are made to the store before allowing it to be closed. | 279 // are made to the store before allowing it to be closed. |
| 280 DestroyStoreOnBackgroundThread(); | 280 DestroyStoreOnBackgroundThread(); |
| 281 | 281 |
| 282 // Reload and test for persistence. | 282 // Reload and test for persistence. |
| 283 base::STLDeleteElements(&cookies); | 283 cookies.clear(); |
| 284 CreateAndLoad(storage_policy.get(), &cookies); | 284 CreateAndLoad(storage_policy.get(), &cookies); |
| 285 EXPECT_EQ(0U, cookies.size()); | 285 EXPECT_EQ(0U, cookies.size()); |
| 286 | 286 |
| 287 base::STLDeleteElements(&cookies); | 287 cookies.clear(); |
| 288 } | 288 } |
| 289 | 289 |
| 290 } // namespace | 290 } // namespace |
| 291 } // namespace content | 291 } // namespace content |
| OLD | NEW |