| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/safe_browsing_db/database_manager.h" | 5 #include "components/safe_browsing_db/database_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 negative_cache_expire_), | 54 negative_cache_expire_), |
| 55 base::TimeDelta::FromSeconds(delay_seconds_)); | 55 base::TimeDelta::FromSeconds(delay_seconds_)); |
| 56 } | 56 } |
| 57 | 57 |
| 58 void SetDelaySeconds(int delay) { | 58 void SetDelaySeconds(int delay) { |
| 59 delay_seconds_ = delay; | 59 delay_seconds_ = delay; |
| 60 } | 60 } |
| 61 | 61 |
| 62 void SetNegativeCacheDurationMins(base::Time now, | 62 void SetNegativeCacheDurationMins(base::Time now, |
| 63 int negative_cache_duration_mins) { | 63 int negative_cache_duration_mins) { |
| 64 negative_cache_expire_ = now + | 64 negative_cache_expire_ = negative_cache_duration_mins ? now + |
| 65 base::TimeDelta::FromMinutes(negative_cache_duration_mins); | 65 base::TimeDelta::FromMinutes(negative_cache_duration_mins) : now; |
| 66 } | 66 } |
| 67 | 67 |
| 68 // Prepare the GetFullHash results for the next request. | 68 // Prepare the GetFullHash results for the next request. |
| 69 void AddGetFullHashResponse(const SBFullHashResult& full_hash_result) { | 69 void AddGetFullHashResponse(const SBFullHashResult& full_hash_result) { |
| 70 full_hashes_.push_back(full_hash_result); | 70 full_hashes_.push_back(full_hash_result); |
| 71 } | 71 } |
| 72 | 72 |
| 73 // Clear the GetFullHash results for the next request. |
| 74 void ClearFullHashResponse() { |
| 75 full_hashes_.clear(); |
| 76 } |
| 77 |
| 73 // Returns the prefixes that were sent in the last request. | 78 // Returns the prefixes that were sent in the last request. |
| 74 const std::vector<SBPrefix>& GetRequestPrefixes() { return prefixes_; } | 79 const std::vector<SBPrefix>& GetRequestPrefixes() { return prefixes_; } |
| 75 | 80 |
| 76 private: | 81 private: |
| 77 std::vector<SBPrefix> prefixes_; | 82 std::vector<SBPrefix> prefixes_; |
| 78 std::vector<SBFullHashResult> full_hashes_; | 83 std::vector<SBFullHashResult> full_hashes_; |
| 79 base::Time negative_cache_expire_; | 84 base::Time negative_cache_expire_; |
| 80 int delay_seconds_; | 85 int delay_seconds_; |
| 81 }; | 86 }; |
| 82 | 87 |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 pm->AddGetFullHashResponse(full_hash_result); | 325 pm->AddGetFullHashResponse(full_hash_result); |
| 321 | 326 |
| 322 EXPECT_TRUE(db_manager_->api_cache_.empty()); | 327 EXPECT_TRUE(db_manager_->api_cache_.empty()); |
| 323 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url, &client)); | 328 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url, &client)); |
| 324 base::RunLoop().RunUntilIdle(); | 329 base::RunLoop().RunUntilIdle(); |
| 325 | 330 |
| 326 EXPECT_TRUE(client.callback_invoked()); | 331 EXPECT_TRUE(client.callback_invoked()); |
| 327 EXPECT_TRUE(db_manager_->api_cache_.empty()); | 332 EXPECT_TRUE(db_manager_->api_cache_.empty()); |
| 328 } | 333 } |
| 329 | 334 |
| 335 // Checks that results are looked up correctly in the cache. |
| 336 TEST_F(SafeBrowsingDatabaseManagerTest, GetCachedResults) { |
| 337 base::Time now = base::Time::UnixEpoch(); |
| 338 std::vector<SBFullHash> full_hashes; |
| 339 SBFullHash full_hash = SBFullHashForString("example.com/"); |
| 340 full_hashes.push_back(full_hash); |
| 341 std::vector<SBFullHashResult> cached_results; |
| 342 std::vector<SBPrefix> prefixes; |
| 343 db_manager_->GetCachedResults(full_hashes, now, &prefixes, &cached_results); |
| 344 |
| 345 // The cache is empty. |
| 346 EXPECT_TRUE(cached_results.empty()); |
| 347 EXPECT_EQ(1ul, prefixes.size()); |
| 348 EXPECT_EQ(full_hash.prefix, prefixes[0]); |
| 349 |
| 350 // Prefix has a cache entry but full hash is not there. |
| 351 SBCachedFullHashResult& entry = db_manager_->api_cache_[full_hash.prefix] = |
| 352 SBCachedFullHashResult(now + base::TimeDelta::FromMinutes(5)); |
| 353 db_manager_->GetCachedResults(full_hashes, now, &prefixes, &cached_results); |
| 354 |
| 355 EXPECT_TRUE(prefixes.empty()); |
| 356 EXPECT_TRUE(cached_results.empty()); |
| 357 |
| 358 // Expired negative cache entry. |
| 359 entry.expire_after = now - base::TimeDelta::FromMinutes(5); |
| 360 db_manager_->GetCachedResults(full_hashes, now, &prefixes, &cached_results); |
| 361 |
| 362 EXPECT_TRUE(cached_results.empty()); |
| 363 EXPECT_EQ(1ul, prefixes.size()); |
| 364 EXPECT_EQ(full_hash.prefix, prefixes[0]); |
| 365 |
| 366 // Now put the full hash in the cache. |
| 367 SBFullHashResult full_hash_result; |
| 368 full_hash_result.hash = full_hash; |
| 369 full_hash_result.cache_expire_after = now + base::TimeDelta::FromMinutes(3); |
| 370 entry.full_hashes.push_back(full_hash_result); |
| 371 db_manager_->GetCachedResults(full_hashes, now, &prefixes, &cached_results); |
| 372 |
| 373 EXPECT_TRUE(prefixes.empty()); |
| 374 EXPECT_EQ(1ul, cached_results.size()); |
| 375 EXPECT_TRUE(SBFullHashEqual(full_hash, cached_results[0].hash)); |
| 376 |
| 377 // Expired full hash in cache. |
| 378 entry.full_hashes.clear(); |
| 379 full_hash_result.cache_expire_after = now - base::TimeDelta::FromMinutes(3); |
| 380 entry.full_hashes.push_back(full_hash_result); |
| 381 db_manager_->GetCachedResults(full_hashes, now, &prefixes, &cached_results); |
| 382 |
| 383 EXPECT_TRUE(cached_results.empty()); |
| 384 EXPECT_EQ(1ul, prefixes.size()); |
| 385 EXPECT_EQ(full_hash.prefix, prefixes[0]); |
| 386 } |
| 387 |
| 388 // Checks that the cached results and request results are merged. |
| 389 TEST_F(SafeBrowsingDatabaseManagerTest, CachedResultsMerged) { |
| 390 TestClient client; |
| 391 const GURL url("https://www.example.com/more"); |
| 392 TestV4GetHashProtocolManager* pm = static_cast<TestV4GetHashProtocolManager*>( |
| 393 db_manager_->v4_get_hash_protocol_manager_); |
| 394 // Set now to max time so the cache expire times are in the future. |
| 395 SBFullHashResult full_hash_result; |
| 396 full_hash_result.hash = SBFullHashForString("example.com/"); |
| 397 full_hash_result.metadata.api_permissions.push_back("GEOLOCATION"); |
| 398 full_hash_result.cache_expire_after = base::Time::Max(); |
| 399 pm->AddGetFullHashResponse(full_hash_result); |
| 400 pm->SetNegativeCacheDurationMins(base::Time::Max(), 0); |
| 401 |
| 402 EXPECT_TRUE(db_manager_->api_cache_.empty()); |
| 403 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url, &client)); |
| 404 base::RunLoop().RunUntilIdle(); |
| 405 |
| 406 EXPECT_TRUE(client.callback_invoked()); |
| 407 const std::vector<std::string>& permissions = client.GetBlockedPermissions(); |
| 408 EXPECT_EQ(1ul, permissions.size()); |
| 409 EXPECT_EQ("GEOLOCATION", permissions[0]); |
| 410 |
| 411 // The results should be cached, so remove them from the protocol manager |
| 412 // response. |
| 413 TestClient client2; |
| 414 pm->ClearFullHashResponse(); |
| 415 pm->SetNegativeCacheDurationMins(base::Time(), 0); |
| 416 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url, &client2)); |
| 417 base::RunLoop().RunUntilIdle(); |
| 418 |
| 419 EXPECT_TRUE(client2.callback_invoked()); |
| 420 const std::vector<std::string>& permissions2 = |
| 421 client2.GetBlockedPermissions(); |
| 422 EXPECT_EQ(1ul, permissions2.size()); |
| 423 EXPECT_EQ("GEOLOCATION", permissions2[0]); |
| 424 |
| 425 // Add a different result to the protocol manager response and ensure it is |
| 426 // merged with the cached result in the metadata. |
| 427 TestClient client3; |
| 428 const GURL url2("https://m.example.com/more"); |
| 429 full_hash_result.hash = SBFullHashForString("m.example.com/"); |
| 430 full_hash_result.metadata.api_permissions.push_back("NOTIFICATIONS"); |
| 431 pm->AddGetFullHashResponse(full_hash_result); |
| 432 pm->SetNegativeCacheDurationMins(base::Time::Max(), 0); |
| 433 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url2, &client3)); |
| 434 base::RunLoop().RunUntilIdle(); |
| 435 |
| 436 EXPECT_TRUE(client3.callback_invoked()); |
| 437 const std::vector<std::string>& permissions3 = |
| 438 client3.GetBlockedPermissions(); |
| 439 EXPECT_EQ(3ul, permissions3.size()); |
| 440 // TODO(kcarattini): Fix the metadata storage of permissions to avoid |
| 441 // duplicates. |
| 442 EXPECT_EQ("GEOLOCATION", permissions3[0]); |
| 443 EXPECT_EQ("NOTIFICATIONS", permissions3[1]); |
| 444 EXPECT_EQ("GEOLOCATION", permissions3[2]); |
| 445 } |
| 446 |
| 330 } // namespace safe_browsing | 447 } // namespace safe_browsing |
| OLD | NEW |