| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "net/cookies/cookie_monster.h" | 5 #include "net/cookies/cookie_monster.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 case 'H': | 367 case 'H': |
| 368 return COOKIE_PRIORITY_HIGH; | 368 return COOKIE_PRIORITY_HIGH; |
| 369 } | 369 } |
| 370 NOTREACHED(); | 370 NOTREACHED(); |
| 371 return COOKIE_PRIORITY_DEFAULT; | 371 return COOKIE_PRIORITY_DEFAULT; |
| 372 } | 372 } |
| 373 | 373 |
| 374 // Instantiates a CookieMonster, adds multiple cookies (to http_www_google_) | 374 // Instantiates a CookieMonster, adds multiple cookies (to http_www_google_) |
| 375 // with priorities specified by |coded_priority_str|, and tests priority-aware | 375 // with priorities specified by |coded_priority_str|, and tests priority-aware |
| 376 // domain cookie eviction. | 376 // domain cookie eviction. |
| 377 // |coded_priority_str| specifies a run-length-encoded string of priorities. | 377 // |
| 378 // Example: "2M 3L M 4H" means "MMLLLMHHHH", and speicifies sequential (i.e., | 378 // Example: |coded_priority_string| of "2MN 3LS MN 4HN" specifies sequential |
| 379 // from least- to most-recently accessed) insertion of 2 medium-priority | 379 // (i.e., from least- to most-recently accessed) insertion of 2 |
| 380 // cookies, 3 low-priority cookies, 1 medium-priority cookie, and 4 | 380 // medium-priority non-secure cookies, 3 low-priority secure cookies, 1 |
| 381 // high-priority cookies. | 381 // medium-priority non-secure cookie, and 4 high-priority non-secure cookies. |
| 382 // |
| 382 // Within each priority, only the least-accessed cookies should be evicted. | 383 // Within each priority, only the least-accessed cookies should be evicted. |
| 383 // Thus, to describe expected suriving cookies, it suffices to specify the | 384 // Thus, to describe expected suriving cookies, it suffices to specify the |
| 384 // expected population of surviving cookies per priority, i.e., | 385 // expected population of surviving cookies per priority, i.e., |
| 385 // |expected_low_count|, |expected_medium_count|, and |expected_high_count|. | 386 // |expected_low_count|, |expected_medium_count|, and |expected_high_count|. |
| 386 void TestPriorityCookieCase(CookieMonster* cm, | 387 void TestPriorityCookieCase(CookieMonster* cm, |
| 387 const std::string& coded_priority_str, | 388 const std::string& coded_priority_str, |
| 388 size_t expected_low_count, | 389 size_t expected_low_count, |
| 389 size_t expected_medium_count, | 390 size_t expected_medium_count, |
| 390 size_t expected_high_count) { | 391 size_t expected_high_count, |
| 392 size_t expected_nonsecure, |
| 393 size_t expected_secure) { |
| 391 SCOPED_TRACE(coded_priority_str); | 394 SCOPED_TRACE(coded_priority_str); |
| 392 this->DeleteAll(cm); | 395 this->DeleteAll(cm); |
| 393 int next_cookie_id = 0; | 396 int next_cookie_id = 0; |
| 394 std::vector<CookiePriority> priority_list; | 397 // A list of cookie IDs, indexed by secure status, then by priority. |
| 395 std::vector<int> id_list[3]; // Indexed by CookiePriority. | 398 std::vector<int> id_list[2][3]; |
| 399 // A list of all the cookies stored, along with their properties. |
| 400 std::vector<std::pair<bool, CookiePriority>> cookie_data; |
| 396 | 401 |
| 397 // Parse |coded_priority_str| and add cookies. | 402 // Parse |coded_priority_str| and add cookies. |
| 398 for (const std::string& token : | 403 for (const std::string& token : |
| 399 base::SplitString(coded_priority_str, " ", base::TRIM_WHITESPACE, | 404 base::SplitString(coded_priority_str, " ", base::TRIM_WHITESPACE, |
| 400 base::SPLIT_WANT_ALL)) { | 405 base::SPLIT_WANT_ALL)) { |
| 401 DCHECK(!token.empty()); | 406 DCHECK(!token.empty()); |
| 402 // Take last character as priority. | 407 |
| 403 CookiePriority priority = CharToPriority(token.back()); | 408 bool is_secure = token[token.size() - 1] == 'S'; |
| 404 std::string priority_str = CookiePriorityToString(priority); | 409 |
| 405 // The rest of the string (possibly empty) specifies repetition. | 410 // The second-to-last character is the priority. Grab and discard it. |
| 411 CookiePriority priority = CharToPriority(token[token.size() - 2]); |
| 412 |
| 413 // Discard the security status and priority tokens. The rest of the string |
| 414 // (possibly empty) specifies repetition. |
| 406 int rep = 1; | 415 int rep = 1; |
| 407 if (!token.empty()) { | 416 if (!token.empty()) { |
| 408 bool result = base::StringToInt( | 417 bool result = base::StringToInt( |
| 409 base::StringPiece(token.begin(), token.end() - 1), &rep); | 418 base::StringPiece(token.begin(), token.end() - 2), &rep); |
| 410 DCHECK(result); | 419 DCHECK(result); |
| 411 } | 420 } |
| 412 for (; rep > 0; --rep, ++next_cookie_id) { | 421 for (; rep > 0; --rep, ++next_cookie_id) { |
| 413 std::string cookie = base::StringPrintf( | 422 std::string cookie = |
| 414 "a%d=b;priority=%s", next_cookie_id, priority_str.c_str()); | 423 base::StringPrintf("a%d=b;priority=%s;%s", next_cookie_id, |
| 415 EXPECT_TRUE(SetCookie(cm, http_www_google_.url(), cookie)); | 424 CookiePriorityToString(priority).c_str(), |
| 416 priority_list.push_back(priority); | 425 is_secure ? "secure" : ""); |
| 417 id_list[priority].push_back(next_cookie_id); | 426 EXPECT_TRUE(SetCookie(cm, https_www_google_.url(), cookie)); |
| 427 cookie_data.push_back(std::make_pair(is_secure, priority)); |
| 428 id_list[is_secure][priority].push_back(next_cookie_id); |
| 418 } | 429 } |
| 419 } | 430 } |
| 420 | 431 |
| 421 int num_cookies = static_cast<int>(priority_list.size()); | 432 int num_cookies = static_cast<int>(cookie_data.size()); |
| 422 std::vector<int> surviving_id_list[3]; // Indexed by CookiePriority. | 433 // A list of cookie IDs, indexed by secure status, then by priority. |
| 434 std::vector<int> surviving_id_list[2][3]; |
| 423 | 435 |
| 424 // Parse the list of cookies | 436 // Parse the list of cookies |
| 425 std::string cookie_str = this->GetCookies(cm, http_www_google_.url()); | 437 std::string cookie_str = this->GetCookies(cm, https_www_google_.url()); |
| 438 size_t num_nonsecure = 0; |
| 439 size_t num_secure = 0; |
| 426 for (const std::string& token : base::SplitString( | 440 for (const std::string& token : base::SplitString( |
| 427 cookie_str, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { | 441 cookie_str, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { |
| 428 // Assuming *it is "a#=b", so extract and parse "#" portion. | 442 // Assuming *it is "a#=b", so extract and parse "#" portion. |
| 429 int id = -1; | 443 int id = -1; |
| 430 bool result = base::StringToInt( | 444 bool result = base::StringToInt( |
| 431 base::StringPiece(token.begin() + 1, token.end() - 2), &id); | 445 base::StringPiece(token.begin() + 1, token.end() - 2), &id); |
| 432 DCHECK(result); | 446 DCHECK(result); |
| 433 DCHECK_GE(id, 0); | 447 DCHECK_GE(id, 0); |
| 434 DCHECK_LT(id, num_cookies); | 448 DCHECK_LT(id, num_cookies); |
| 435 surviving_id_list[priority_list[id]].push_back(id); | 449 surviving_id_list[cookie_data[id].first][cookie_data[id].second] |
| 450 .push_back(id); |
| 451 if (cookie_data[id].first) |
| 452 num_secure += 1; |
| 453 else |
| 454 num_nonsecure += 1; |
| 436 } | 455 } |
| 437 | 456 |
| 457 EXPECT_EQ(expected_nonsecure, num_nonsecure); |
| 458 EXPECT_EQ(expected_secure, num_secure); |
| 459 |
| 438 // Validate each priority. | 460 // Validate each priority. |
| 439 size_t expected_count[3] = { | 461 size_t expected_count[3] = { |
| 440 expected_low_count, expected_medium_count, expected_high_count}; | 462 expected_low_count, expected_medium_count, expected_high_count}; |
| 441 for (int i = 0; i < 3; ++i) { | 463 for (int i = 0; i < 3; ++i) { |
| 442 DCHECK_LE(surviving_id_list[i].size(), id_list[i].size()); | 464 size_t num_for_priority = |
| 443 EXPECT_EQ(expected_count[i], surviving_id_list[i].size()); | 465 surviving_id_list[0][i].size() + surviving_id_list[1][i].size(); |
| 466 EXPECT_EQ(expected_count[i], num_for_priority); |
| 444 // Verify that the remaining cookies are the most recent among those | 467 // Verify that the remaining cookies are the most recent among those |
| 445 // with the same priorities. | 468 // with the same priorities. |
| 446 if (expected_count[i] == surviving_id_list[i].size()) { | 469 if (expected_count[i] == num_for_priority) { |
| 447 std::sort(surviving_id_list[i].begin(), surviving_id_list[i].end()); | 470 // Non-secure: |
| 448 EXPECT_TRUE(std::equal(surviving_id_list[i].begin(), | 471 std::sort(surviving_id_list[0][i].begin(), |
| 449 surviving_id_list[i].end(), | 472 surviving_id_list[0][i].end()); |
| 450 id_list[i].end() - expected_count[i])); | 473 EXPECT_TRUE(std::equal( |
| 474 surviving_id_list[0][i].begin(), surviving_id_list[0][i].end(), |
| 475 id_list[0][i].end() - surviving_id_list[0][i].size())); |
| 476 |
| 477 // Secure: |
| 478 std::sort(surviving_id_list[1][i].begin(), |
| 479 surviving_id_list[1][i].end()); |
| 480 EXPECT_TRUE(std::equal( |
| 481 surviving_id_list[1][i].begin(), surviving_id_list[1][i].end(), |
| 482 id_list[1][i].end() - surviving_id_list[1][i].size())); |
| 451 } | 483 } |
| 452 } | 484 } |
| 453 } | 485 } |
| 454 | 486 |
| 455 // Represents a number of cookies to create, if they are Secure cookies, and | 487 // Represents a number of cookies to create, if they are Secure cookies, and |
| 456 // a url to add them to. | 488 // a url to add them to. |
| 457 struct CookiesEntry { | 489 struct CookiesEntry { |
| 458 size_t num_cookies; | 490 size_t num_cookies; |
| 459 bool is_secure; | 491 bool is_secure; |
| 460 }; | 492 }; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 if (cookie.IsSecure()) | 539 if (cookie.IsSecure()) |
| 508 ++total_secure_cookies; | 540 ++total_secure_cookies; |
| 509 else | 541 else |
| 510 ++total_non_secure_cookies; | 542 ++total_non_secure_cookies; |
| 511 } | 543 } |
| 512 | 544 |
| 513 EXPECT_EQ(expected_secure_cookies, total_secure_cookies); | 545 EXPECT_EQ(expected_secure_cookies, total_secure_cookies); |
| 514 EXPECT_EQ(expected_non_secure_cookies, total_non_secure_cookies); | 546 EXPECT_EQ(expected_non_secure_cookies, total_non_secure_cookies); |
| 515 } | 547 } |
| 516 | 548 |
| 517 void TestPriorityAwareGarbageCollectHelper() { | 549 void TestPriorityAwareGarbageCollectHelperNonSecure() { |
| 518 // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint. | 550 // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint. |
| 519 DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies); | 551 DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies); |
| 520 DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies - | 552 DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies - |
| 521 CookieMonster::kDomainPurgeCookies); | 553 CookieMonster::kDomainPurgeCookies); |
| 522 DCHECK_EQ(30U, CookieMonster::kDomainCookiesQuotaLow); | 554 |
| 523 DCHECK_EQ(50U, CookieMonster::kDomainCookiesQuotaMedium); | 555 std::unique_ptr<CookieMonster> cm(new CookieMonster(NULL, NULL)); |
| 524 DCHECK_EQ(70U, CookieMonster::kDomainCookiesQuotaHigh); | 556 |
| 557 // Each test case adds 181 cookies, so 31 cookies are evicted. |
| 558 // Cookie same priority, repeated for each priority. |
| 559 TestPriorityCookieCase(cm.get(), "181LN", 150U, 0U, 0U, 150U, 0U); |
| 560 TestPriorityCookieCase(cm.get(), "181MN", 0U, 150U, 0U, 150U, 0U); |
| 561 TestPriorityCookieCase(cm.get(), "181HN", 0U, 0U, 150U, 150U, 0U); |
| 562 |
| 563 // Pairwise scenarios. |
| 564 // Round 1 => none; round2 => 31M; round 3 => none. |
| 565 TestPriorityCookieCase(cm.get(), "10HN 171MN", 0U, 140U, 10U, 150U, 0U); |
| 566 // Round 1 => 10L; round2 => 21M; round 3 => none. |
| 567 TestPriorityCookieCase(cm.get(), "141MN 40LN", 30U, 120U, 0U, 150U, 0U); |
| 568 // Round 1 => none; round2 => none; round 3 => 31H. |
| 569 TestPriorityCookieCase(cm.get(), "101HN 80MN", 0U, 80U, 70U, 150U, 0U); |
| 570 |
| 571 // For {low, medium} priorities right on quota, different orders. |
| 572 // Round 1 => 1L; round 2 => none, round3 => 30L. |
| 573 TestPriorityCookieCase(cm.get(), "31LN 50MN 100HN", 0U, 50U, 100U, 150U, |
| 574 0U); |
| 575 // Round 1 => none; round 2 => 1M, round3 => 30M. |
| 576 TestPriorityCookieCase(cm.get(), "51MN 100HN 30LN", 30U, 20U, 100U, 150U, |
| 577 0U); |
| 578 // Round 1 => none; round 2 => none; round3 => 31H. |
| 579 TestPriorityCookieCase(cm.get(), "101HN 50MN 30LN", 30U, 50U, 70U, 150U, |
| 580 0U); |
| 581 |
| 582 // Round 1 => 10L; round 2 => 10M; round3 => 11H. |
| 583 TestPriorityCookieCase(cm.get(), "81HN 60MN 40LN", 30U, 50U, 70U, 150U, 0U); |
| 584 |
| 585 // More complex scenarios. |
| 586 // Round 1 => 10L; round 2 => 10M; round 3 => 11H. |
| 587 TestPriorityCookieCase(cm.get(), "21HN 60MN 40LN 60HN", 30U, 50U, 70U, 150U, |
| 588 0U); |
| 589 // Round 1 => 10L; round 2 => 11M, 10L; round 3 => none. |
| 590 TestPriorityCookieCase(cm.get(), "11HN 10MN 20LN 110MN 20LN 10HN", 20U, |
| 591 109U, 21U, 150U, 0U); |
| 592 // Round 1 => none; round 2 => none; round 3 => 11L, 10M, 10H. |
| 593 TestPriorityCookieCase(cm.get(), "11LN 10MN 140HN 10MN 10LN", 10U, 10U, |
| 594 130U, 150U, 0U); |
| 595 // Round 1 => none; round 2 => 1M; round 3 => 10L, 10M, 10H. |
| 596 TestPriorityCookieCase(cm.get(), "11MN 10HN 10LN 60MN 90HN", 0U, 60U, 90U, |
| 597 150U, 0U); |
| 598 // Round 1 => none; round 2 => 10L, 21M; round 3 => none. |
| 599 TestPriorityCookieCase(cm.get(), "11MN 10HN 10LN 90MN 60HN", 0U, 80U, 70U, |
| 600 150U, 0U); |
| 601 |
| 602 // TODO(jww): According to |
| 603 // https://tools.ietf.org/html/draft-west-cookie-priority#section-3, it |
| 604 // seems that quotas are a mechanism for preventing another application on |
| 605 // the same doman from DoS'ing an application by constantly evicting *all* |
| 606 // lower priority cookies. |
| 607 // |
| 608 // Unfortunately, this has never strictly worked in our implementation. Take |
| 609 // the following test as an example: |
| 610 // TestPriorityCookieCase(cm.get(), "50LN 131HN", 30U, 0U, 120U, 150U, 0U); |
| 611 // |
| 612 // According to this theory, we would expect eviction to proceed as: |
| 613 // Round 1 => 20L; round 2 => 0; round 3 => 11H |
| 614 // thus resulting in 30L and 120H at the end. |
| 615 // |
| 616 // However, what happens in practice is that the cookies left are 19L and |
| 617 // 131H. This is because the quotas are accumulated over the rounds and what |
| 618 // priority they apply to is lost information. Since in the last round all |
| 619 // that is known is a total quota, and the low-priority cookies are least |
| 620 // recently accessed, they are evicted first to get down to 150 cookies. |
| 621 // |
| 622 // We should address this and uncomment the test below when it is fixed. |
| 623 // |
| 624 // See https://crbug.com/609550 |
| 625 // |
| 626 // Round 1 => 20L; round 2 => 0; round 3 => 11H |
| 627 // TestPriorityCookieCase(cm.get(), "50LN 131HN", 30U, 0U, 120U, 150U, 0U); |
| 628 // Round 1 => 20L; round 2 => 0; round 3 => 11H |
| 629 TestPriorityCookieCase(cm.get(), "131HN 50LN", 30U, 0U, 120U, 150U, 0U); |
| 630 // Round 1 => 20L; round 2 => none; round 3 => 11H. |
| 631 TestPriorityCookieCase(cm.get(), "50HN 50LN 81HN", 30U, 0U, 120U, 150U, 0U); |
| 632 // Round 1 => 20L; round 2 => none; round 3 => 11H. |
| 633 TestPriorityCookieCase(cm.get(), "81HN 50LN 50HN", 30U, 0U, 120U, 150U, 0U); |
| 634 } |
| 635 |
| 636 void TestPriorityAwareGarbageCollectHelperSecure() { |
| 637 // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint. |
| 638 DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies); |
| 639 DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies - |
| 640 CookieMonster::kDomainPurgeCookies); |
| 525 | 641 |
| 526 std::unique_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr)); | 642 std::unique_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr)); |
| 527 | 643 |
| 528 // Each test case adds 181 cookies, so 31 cookies are evicted. | 644 // Each test case adds 181 cookies, so 31 cookies are evicted. |
| 529 // Cookie same priority, repeated for each priority. | 645 // Cookie same priority, repeated for each priority. |
| 530 TestPriorityCookieCase(cm.get(), "181L", 150U, 0U, 0U); | 646 TestPriorityCookieCase(cm.get(), "181LS", 150U, 0U, 0U, 0U, 150U); |
| 531 TestPriorityCookieCase(cm.get(), "181M", 0U, 150U, 0U); | 647 TestPriorityCookieCase(cm.get(), "181MS", 0U, 150U, 0U, 0U, 150U); |
| 532 TestPriorityCookieCase(cm.get(), "181H", 0U, 0U, 150U); | 648 TestPriorityCookieCase(cm.get(), "181HS", 0U, 0U, 150U, 0U, 150U); |
| 533 | 649 |
| 534 // Pairwise scenarios. | 650 // Pairwise scenarios. |
| 535 // Round 1 => none; round2 => 31M; round 3 => none. | 651 // Round 1 => none; round2 => 31M; round 3 => none. |
| 536 TestPriorityCookieCase(cm.get(), "10H 171M", 0U, 140U, 10U); | 652 TestPriorityCookieCase(cm.get(), "10HS 171MS", 0U, 140U, 10U, 0U, 150U); |
| 537 // Round 1 => 10L; round2 => 21M; round 3 => none. | 653 // Round 1 => 10L; round2 => 21M; round 3 => none. |
| 538 TestPriorityCookieCase(cm.get(), "141M 40L", 30U, 120U, 0U); | 654 TestPriorityCookieCase(cm.get(), "141MS 40LS", 30U, 120U, 0U, 0U, 150U); |
| 539 // Round 1 => none; round2 => none; round 3 => 31H. | 655 // Round 1 => none; round2 => none; round 3 => 31H. |
| 540 TestPriorityCookieCase(cm.get(), "101H 80M", 0U, 80U, 70U); | 656 TestPriorityCookieCase(cm.get(), "101HS 80MS", 0U, 80U, 70U, 0U, 150U); |
| 541 | 657 |
| 542 // For {low, medium} priorities right on quota, different orders. | 658 // For {low, medium} priorities right on quota, different orders. |
| 543 // Round 1 => 1L; round 2 => none, round3 => 30L. | 659 // Round 1 => 1L; round 2 => none, round3 => 30L. |
| 544 TestPriorityCookieCase(cm.get(), "31L 50M 100H", 0U, 50U, 100U); | 660 TestPriorityCookieCase(cm.get(), "31LS 50MS 100HS", 0U, 50U, 100U, 0U, |
| 661 150U); |
| 545 // Round 1 => none; round 2 => 1M, round3 => 30M. | 662 // Round 1 => none; round 2 => 1M, round3 => 30M. |
| 546 TestPriorityCookieCase(cm.get(), "51M 100H 30L", 30U, 20U, 100U); | 663 TestPriorityCookieCase(cm.get(), "51MS 100HS 30LS", 30U, 20U, 100U, 0U, |
| 664 150U); |
| 547 // Round 1 => none; round 2 => none; round3 => 31H. | 665 // Round 1 => none; round 2 => none; round3 => 31H. |
| 548 TestPriorityCookieCase(cm.get(), "101H 50M 30L", 30U, 50U, 70U); | 666 TestPriorityCookieCase(cm.get(), "101HS 50MS 30LS", 30U, 50U, 70U, 0U, |
| 667 150U); |
| 549 | 668 |
| 550 // Round 1 => 10L; round 2 => 10M; round3 => 11H. | 669 // Round 1 => 10L; round 2 => 10M; round3 => 11H. |
| 551 TestPriorityCookieCase(cm.get(), "81H 60M 40L", 30U, 50U, 70U); | 670 TestPriorityCookieCase(cm.get(), "81HS 60MS 40LS", 30U, 50U, 70U, 0U, 150U); |
| 552 | 671 |
| 553 // More complex scenarios. | 672 // More complex scenarios. |
| 554 // Round 1 => 10L; round 2 => 10M; round 3 => 11H. | 673 // Round 1 => 10L; round 2 => 10M; round 3 => 11H. |
| 555 TestPriorityCookieCase(cm.get(), "21H 60M 40L 60H", 30U, 50U, 70U); | 674 TestPriorityCookieCase(cm.get(), "21HS 60MS 40LS 60HS", 30U, 50U, 70U, 0U, |
| 675 150U); |
| 556 // Round 1 => 10L; round 2 => 11M, 10L; round 3 => none. | 676 // Round 1 => 10L; round 2 => 11M, 10L; round 3 => none. |
| 557 TestPriorityCookieCase(cm.get(), "11H 10M 20L 110M 20L 10H", 20U, 109U, | 677 TestPriorityCookieCase(cm.get(), "11HS 10MS 20LS 110MS 20LS 10HS", 20U, |
| 558 21U); | 678 109U, 21U, 0U, 150U); |
| 559 // Round 1 => none; round 2 => none; round 3 => 11L, 10M, 10H. | 679 // Round 1 => none; round 2 => none; round 3 => 11L, 10M, 10H. |
| 560 TestPriorityCookieCase(cm.get(), "11L 10M 140H 10M 10L", 10U, 10U, 130U); | 680 TestPriorityCookieCase(cm.get(), "11LS 10MS 140HS 10MS 10LS", 10U, 10U, |
| 681 130U, 0U, 150U); |
| 561 // Round 1 => none; round 2 => 1M; round 3 => 10L, 10M, 10H. | 682 // Round 1 => none; round 2 => 1M; round 3 => 10L, 10M, 10H. |
| 562 TestPriorityCookieCase(cm.get(), "11M 10H 10L 60M 90H", 0U, 60U, 90U); | 683 TestPriorityCookieCase(cm.get(), "11MS 10HS 10LS 60MS 90HS", 0U, 60U, 90U, |
| 684 0U, 150U); |
| 563 // Round 1 => none; round 2 => 10L, 21M; round 3 => none. | 685 // Round 1 => none; round 2 => 10L, 21M; round 3 => none. |
| 564 TestPriorityCookieCase(cm.get(), "11M 10H 10L 90M 60H", 0U, 80U, 70U); | 686 TestPriorityCookieCase(cm.get(), "11MS 10HS 10LS 90MS 60HS", 0U, 80U, 70U, |
| 687 0U, 150U); |
| 688 } |
| 689 |
| 690 void TestPriorityAwareGarbageCollectHelperMixed() { |
| 691 // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint. |
| 692 DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies); |
| 693 DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies - |
| 694 CookieMonster::kDomainPurgeCookies); |
| 695 |
| 696 std::unique_ptr<CookieMonster> cm(new CookieMonster(NULL, NULL)); |
| 697 |
| 698 // Each test case adds 180 secure cookies, and some non-secure cookie. The |
| 699 // secure cookies take priority, so the non-secure cookie is removed, along |
| 700 // with 30 secure cookies. Repeated for each priority, and with the |
| 701 // non-secure cookie as older and newer. |
| 702 TestPriorityCookieCase(cm.get(), "1LN 180LS", 150U, 0U, 0U, 0U, 150U); |
| 703 TestPriorityCookieCase(cm.get(), "1MN 180MS", 0U, 150U, 0U, 0U, 150U); |
| 704 TestPriorityCookieCase(cm.get(), "1HN 180HS", 0U, 0U, 150U, 0U, 150U); |
| 705 TestPriorityCookieCase(cm.get(), "180LS 1LN", 150U, 0U, 0U, 0U, 150U); |
| 706 TestPriorityCookieCase(cm.get(), "180MS 1MN", 0U, 150U, 0U, 0U, 150U); |
| 707 TestPriorityCookieCase(cm.get(), "180HS 1HN", 0U, 0U, 150U, 0U, 150U); |
| 708 |
| 709 // Low-priority secure cookies are removed before higher priority non-secure |
| 710 // cookies. |
| 711 TestPriorityCookieCase(cm.get(), "180LS 1MN", 149U, 1U, 0U, 1U, 149U); |
| 712 TestPriorityCookieCase(cm.get(), "180LS 1HN", 149U, 0U, 1U, 1U, 149U); |
| 713 TestPriorityCookieCase(cm.get(), "1MN 180LS", 149U, 1U, 0U, 1U, 149U); |
| 714 TestPriorityCookieCase(cm.get(), "1HN 180LS", 149U, 0U, 1U, 1U, 149U); |
| 715 |
| 716 // Higher-priority non-secure cookies are removed before any secure cookie |
| 717 // with greater than low-priority. |
| 718 TestPriorityCookieCase(cm.get(), "180MS 1HN", 0U, 150U, 0U, 0U, 150U); |
| 719 TestPriorityCookieCase(cm.get(), "1HN 180MS", 0U, 150U, 0U, 0U, 150U); |
| 720 |
| 721 // Pairwise: |
| 722 TestPriorityCookieCase(cm.get(), "1LS 180LN", 150U, 0U, 0U, 149U, 1U); |
| 723 TestPriorityCookieCase(cm.get(), "100LS 81LN", 150U, 0U, 0U, 50U, 100U); |
| 724 TestPriorityCookieCase(cm.get(), "150LS 31LN", 150U, 0U, 0U, 0U, 150U); |
| 725 TestPriorityCookieCase(cm.get(), "1LS 180HN", 0U, 0U, 150U, 150U, 0U); |
| 726 TestPriorityCookieCase(cm.get(), "100LS 81HN", 69U, 0U, 81U, 81U, 69U); |
| 727 TestPriorityCookieCase(cm.get(), "150LS 31HN", 119U, 0U, 31U, 31U, 119U); |
| 728 |
| 729 // Quota calculations inside non-secure/secure blocks remain in place: |
| 730 // Round 1 => 20LS; round 2 => none; round 3 => 11HN. |
| 731 TestPriorityCookieCase(cm.get(), "50HN 50LS 81HS", 30U, 0U, 120U, 39U, |
| 732 111U); |
| 733 // Round 1 => none; round 2 => 10LS, 21MN; round 3 => none. |
| 734 TestPriorityCookieCase(cm.get(), "11MS 10HN 10LS 90MN 60HN", 0U, 80U, 70U, |
| 735 139U, 11U); |
| 736 |
| 737 // Multiple GC rounds end up with consistent behavior: |
| 738 TestPriorityCookieCase(cm.get(), "100HS 100LN 100MN", 0, 76U, 100U, 76U, |
| 739 100U); |
| 565 } | 740 } |
| 566 | 741 |
| 567 // Function for creating a CM with a number of cookies in it, | 742 // Function for creating a CM with a number of cookies in it, |
| 568 // no store (and hence no ability to affect access time). | 743 // no store (and hence no ability to affect access time). |
| 569 CookieMonster* CreateMonsterForGC(int num_cookies) { | 744 CookieMonster* CreateMonsterForGC(int num_cookies) { |
| 570 CookieMonster* cm(new CookieMonster(NULL, NULL)); | 745 CookieMonster* cm(new CookieMonster(NULL, NULL)); |
| 571 for (int i = 0; i < num_cookies; i++) { | 746 for (int i = 0; i < num_cookies; i++) { |
| 572 SetCookie(cm, GURL(base::StringPrintf("http://h%05d.izzle", i)), "a=1"); | 747 SetCookie(cm, GURL(base::StringPrintf("http://h%05d.izzle", i)), "a=1"); |
| 573 } | 748 } |
| 574 return cm; | 749 return cm; |
| (...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1370 options = CookieOptions(); | 1545 options = CookieOptions(); |
| 1371 EXPECT_EQ("A=B", | 1546 EXPECT_EQ("A=B", |
| 1372 GetCookiesWithOptions(cm.get(), http_www_google_.url(), options)); | 1547 GetCookiesWithOptions(cm.get(), http_www_google_.url(), options)); |
| 1373 EXPECT_FALSE(last_access_date == GetFirstCookieAccessDate(cm.get())); | 1548 EXPECT_FALSE(last_access_date == GetFirstCookieAccessDate(cm.get())); |
| 1374 } | 1549 } |
| 1375 | 1550 |
| 1376 TEST_F(CookieMonsterTest, TestHostGarbageCollection) { | 1551 TEST_F(CookieMonsterTest, TestHostGarbageCollection) { |
| 1377 TestHostGarbageCollectHelper(); | 1552 TestHostGarbageCollectHelper(); |
| 1378 } | 1553 } |
| 1379 | 1554 |
| 1380 TEST_F(CookieMonsterTest, TestPriorityAwareGarbageCollection) { | 1555 TEST_F(CookieMonsterTest, TestPriorityAwareGarbageCollectionNonSecure) { |
| 1381 TestPriorityAwareGarbageCollectHelper(); | 1556 TestPriorityAwareGarbageCollectHelperNonSecure(); |
| 1557 } |
| 1558 |
| 1559 TEST_F(CookieMonsterTest, TestPriorityAwareGarbageCollectionSecure) { |
| 1560 TestPriorityAwareGarbageCollectHelperSecure(); |
| 1561 } |
| 1562 |
| 1563 TEST_F(CookieMonsterStrictSecureTest, TestPriorityAwareGarbageCollectionMixed) { |
| 1564 TestPriorityAwareGarbageCollectHelperMixed(); |
| 1382 } | 1565 } |
| 1383 | 1566 |
| 1384 TEST_F(CookieMonsterTest, SetCookieableSchemes) { | 1567 TEST_F(CookieMonsterTest, SetCookieableSchemes) { |
| 1385 std::unique_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr)); | 1568 std::unique_ptr<CookieMonster> cm(new CookieMonster(nullptr, nullptr)); |
| 1386 std::unique_ptr<CookieMonster> cm_foo(new CookieMonster(nullptr, nullptr)); | 1569 std::unique_ptr<CookieMonster> cm_foo(new CookieMonster(nullptr, nullptr)); |
| 1387 | 1570 |
| 1388 // Only cm_foo should allow foo:// cookies. | 1571 // Only cm_foo should allow foo:// cookies. |
| 1389 std::vector<std::string> schemes; | 1572 std::vector<std::string> schemes; |
| 1390 schemes.push_back("foo"); | 1573 schemes.push_back("foo"); |
| 1391 cm_foo->SetCookieableSchemes(schemes); | 1574 cm_foo->SetCookieableSchemes(schemes); |
| (...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2894 DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies); | 3077 DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies); |
| 2895 DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies - | 3078 DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies - |
| 2896 CookieMonster::kDomainPurgeCookies); | 3079 CookieMonster::kDomainPurgeCookies); |
| 2897 DCHECK_EQ(3300U, CookieMonster::kMaxCookies); | 3080 DCHECK_EQ(3300U, CookieMonster::kMaxCookies); |
| 2898 DCHECK_EQ(30, CookieMonster::kSafeFromGlobalPurgeDays); | 3081 DCHECK_EQ(30, CookieMonster::kSafeFromGlobalPurgeDays); |
| 2899 | 3082 |
| 2900 // If secure cookies for one domain hit the per domain limit (180), a | 3083 // If secure cookies for one domain hit the per domain limit (180), a |
| 2901 // non-secure cookie will not evict them (and, in fact, the non-secure cookie | 3084 // non-secure cookie will not evict them (and, in fact, the non-secure cookie |
| 2902 // will be removed right after creation). | 3085 // will be removed right after creation). |
| 2903 const CookiesEntry test1[] = {{180U, true}, {1U, false}}; | 3086 const CookiesEntry test1[] = {{180U, true}, {1U, false}}; |
| 2904 TestSecureCookieEviction(test1, arraysize(test1), 180U, 0U, nullptr); | 3087 TestSecureCookieEviction(test1, arraysize(test1), 150U, 0U, nullptr); |
| 2905 | 3088 |
| 2906 // If non-secure cookies for one domain hit the per domain limit (180), the | 3089 // If non-secure cookies for one domain hit the per domain limit (180), the |
| 2907 // creation of secure cookies will evict all of the non-secure cookies, and | 3090 // creation of secure cookies will evict the non-secure cookies first, making |
| 2908 // the secure cookies will still be created. | 3091 // room for the secure cookies. |
| 2909 const CookiesEntry test2[] = {{180U, false}, {20U, true}}; | 3092 const CookiesEntry test2[] = {{180U, false}, {20U, true}}; |
| 2910 TestSecureCookieEviction(test2, arraysize(test2), 20U, 0U, nullptr); | 3093 TestSecureCookieEviction(test2, arraysize(test2), 20U, 149U, nullptr); |
| 2911 | 3094 |
| 2912 // If secure cookies for one domain go past the per domain limit (180), they | 3095 // If secure cookies for one domain go past the per domain limit (180), they |
| 2913 // will be evicted as normal by the per domain purge amount (30) down to a | 3096 // will be evicted as normal by the per domain purge amount (30) down to a |
| 2914 // lower amount (150), and then will continue to create the remaining cookies | 3097 // lower amount (150), and then will continue to create the remaining cookies |
| 2915 // (19 more to 169). | 3098 // (19 more to 169). |
| 2916 const CookiesEntry test3[] = {{200U, true}}; | 3099 const CookiesEntry test3[] = {{200U, true}}; |
| 2917 TestSecureCookieEviction(test3, arraysize(test3), 169U, 0U, nullptr); | 3100 TestSecureCookieEviction(test3, arraysize(test3), 169U, 0U, nullptr); |
| 2918 | 3101 |
| 2919 // If a non-secure cookie is created, and a number of secure cookies exceeds | 3102 // If a non-secure cookie is created, and a number of secure cookies exceeds |
| 2920 // the per domain limit (18), the total cookies will be evicted down to a | 3103 // the per domain limit (18), the total cookies will be evicted down to a |
| 2921 // lower amount (150), enforcing the eviction of the non-secure cookie, and | 3104 // lower amount (150), enforcing the eviction of the non-secure cookie, and |
| 2922 // the remaining secure cookies will be created (another 18 to 168). | 3105 // the remaining secure cookies will be created (another 19 to 169). |
| 2923 const CookiesEntry test4[] = {{1U, false}, {199U, true}}; | 3106 const CookiesEntry test4[] = {{1U, false}, {199U, true}}; |
| 2924 TestSecureCookieEviction(test4, arraysize(test4), 168U, 0U, nullptr); | 3107 TestSecureCookieEviction(test4, arraysize(test4), 169U, 0U, nullptr); |
| 2925 | 3108 |
| 2926 // If an even number of non-secure and secure cookies are created below the | 3109 // If an even number of non-secure and secure cookies are created below the |
| 2927 // per-domain limit (180), all will be created and none evicted. | 3110 // per-domain limit (180), all will be created and none evicted. |
| 2928 const CookiesEntry test5[] = {{75U, false}, {75U, true}}; | 3111 const CookiesEntry test5[] = {{75U, false}, {75U, true}}; |
| 2929 TestSecureCookieEviction(test5, arraysize(test5), 75U, 75U, nullptr); | 3112 TestSecureCookieEviction(test5, arraysize(test5), 75U, 75U, nullptr); |
| 2930 | 3113 |
| 2931 // If the same number of secure and non-secure cookies are created (50 each) | 3114 // If the same number of secure and non-secure cookies are created (50 each) |
| 2932 // below the per domain limit (180), and then another set of secure cookies | 3115 // below the per domain limit (180), and then another set of secure cookies |
| 2933 // are created to bring the total above the per-domain limit, all of the | 3116 // are created to bring the total above the per-domain limit, all secure |
| 2934 // non-secure cookies will be evicted but none of the secure ones will be | 3117 // cookies will be retained, and the non-secure cookies will be culled down |
| 2935 // evicted. | 3118 // to the limit. |
| 2936 const CookiesEntry test6[] = {{50U, true}, {50U, false}, {81U, true}}; | 3119 const CookiesEntry test6[] = {{50U, true}, {50U, false}, {81U, true}}; |
| 2937 TestSecureCookieEviction(test6, arraysize(test6), 131U, 0U, nullptr); | 3120 TestSecureCookieEviction(test6, arraysize(test6), 131U, 19U, nullptr); |
| 2938 | 3121 |
| 2939 // If the same number of non-secure and secure cookies are created (50 each) | 3122 // If the same number of non-secure and secure cookies are created (50 each) |
| 2940 // below the per domain limit (180), and then another set of non-secure | 3123 // below the per domain limit (180), and then another set of non-secure |
| 2941 // cookies are created to bring the total above the per-domain limit, all of | 3124 // cookies are created to bring the total above the per-domain limit, all |
| 2942 // the non-secure cookies will be evicted but none of the secure ones will be | 3125 // secure cookies will be retained, and the non-secure cookies will be culled |
| 2943 // evicted. | 3126 // down to the limit. |
| 2944 const CookiesEntry test7[] = {{50U, false}, {50U, true}, {81U, false}}; | 3127 const CookiesEntry test7[] = {{50U, false}, {50U, true}, {81U, false}}; |
| 2945 TestSecureCookieEviction(test7, arraysize(test7), 50U, 0U, nullptr); | 3128 TestSecureCookieEviction(test7, arraysize(test7), 50U, 100U, nullptr); |
| 2946 | 3129 |
| 2947 // If the same number of non-secure and secure cookies are created (50 each) | 3130 // If the same number of non-secure and secure cookies are created (50 each) |
| 2948 // below the per domain limit (180), and then another set of non-secure | 3131 // below the per domain limit (180), and then another set of non-secure |
| 2949 // cookies are created to bring the total above the per-domain limit, all of | 3132 // cookies are created to bring the total above the per-domain limit, all |
| 2950 // the non-secure cookies will be evicted but none of the secure ones will be | 3133 // secure cookies will be retained, and the non-secure cookies will be culled |
| 2951 // evicted, and then the remaining non-secure cookies will be created (9). | 3134 // down to the limit, then the remaining non-secure cookies will be created |
| 3135 // (9). |
| 2952 const CookiesEntry test8[] = {{50U, false}, {50U, true}, {90U, false}}; | 3136 const CookiesEntry test8[] = {{50U, false}, {50U, true}, {90U, false}}; |
| 2953 TestSecureCookieEviction(test8, arraysize(test8), 50U, 9U, nullptr); | 3137 TestSecureCookieEviction(test8, arraysize(test8), 50U, 109U, nullptr); |
| 2954 | 3138 |
| 2955 // If a number of non-secure cookies are created on other hosts (20) and are | 3139 // If a number of non-secure cookies are created on other hosts (20) and are |
| 2956 // past the global 'safe' date, and then the number of non-secure cookies for | 3140 // past the global 'safe' date, and then the number of non-secure cookies for |
| 2957 // a single domain are brought to the per-domain limit (180), followed by | 3141 // a single domain are brought to the per-domain limit (180), followed by |
| 2958 // another set of secure cookies on that same domain (20), all of the | 3142 // another set of secure cookies on that same domain (20), all the secure |
| 2959 // non-secure cookies for that domain should be evicted, but the non-secure | 3143 // cookies for that domain should be retained, while the non-secure should be |
| 2960 // cookies for other domains should remain, as should the secure cookies for | 3144 // culled down to the per-domain limit. The non-secure cookies for other |
| 2961 // that domain. | 3145 // domains should remain untouched. |
| 2962 const CookiesEntry test9[] = {{180U, false}, {20U, true}}; | 3146 const CookiesEntry test9[] = {{180U, false}, {20U, true}}; |
| 2963 const AltHosts test9_alt_hosts(0, 20); | 3147 const AltHosts test9_alt_hosts(0, 20); |
| 2964 TestSecureCookieEviction(test9, arraysize(test9), 20U, 20U, &test9_alt_hosts); | 3148 TestSecureCookieEviction(test9, arraysize(test9), 20U, 169U, |
| 3149 &test9_alt_hosts); |
| 2965 | 3150 |
| 2966 // If a number of secure cookies are created on other hosts and hit the global | 3151 // If a number of secure cookies are created on other hosts and hit the global |
| 2967 // cookie limit (3300) and are past the global 'safe' date, and then a single | 3152 // cookie limit (3300) and are past the global 'safe' date, and then a single |
| 2968 // non-secure cookie is created now, the secure cookies are removed so that | 3153 // non-secure cookie is created now, the secure cookies are removed so that |
| 2969 // the global total number of cookies is at the global purge goal (3000), but | 3154 // the global total number of cookies is at the global purge goal (3000), but |
| 2970 // the non-secure cookie is not evicted since it is too young. | 3155 // the non-secure cookie is not evicted since it is too young. |
| 2971 const CookiesEntry test10[] = {{1U, false}}; | 3156 const CookiesEntry test10[] = {{1U, false}}; |
| 2972 const AltHosts test10_alt_hosts(3300, 0); | 3157 const AltHosts test10_alt_hosts(3300, 0); |
| 2973 TestSecureCookieEviction(test10, arraysize(test10), 2999U, 1U, | 3158 TestSecureCookieEviction(test10, arraysize(test10), 2999U, 1U, |
| 2974 &test10_alt_hosts); | 3159 &test10_alt_hosts); |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3262 monster()->AddCallbackForCookie( | 3447 monster()->AddCallbackForCookie( |
| 3263 test_url_, "abc", | 3448 test_url_, "abc", |
| 3264 base::Bind(&RecordCookieChanges, &cookies1, nullptr))); | 3449 base::Bind(&RecordCookieChanges, &cookies1, nullptr))); |
| 3265 SetCookie(monster(), test_url_, "abc=def"); | 3450 SetCookie(monster(), test_url_, "abc=def"); |
| 3266 base::MessageLoop::current()->RunUntilIdle(); | 3451 base::MessageLoop::current()->RunUntilIdle(); |
| 3267 EXPECT_EQ(1U, cookies0.size()); | 3452 EXPECT_EQ(1U, cookies0.size()); |
| 3268 EXPECT_EQ(1U, cookies0.size()); | 3453 EXPECT_EQ(1U, cookies0.size()); |
| 3269 } | 3454 } |
| 3270 | 3455 |
| 3271 } // namespace net | 3456 } // namespace net |
| OLD | NEW |