Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 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.
      4 
      5 #include <time.h>
      6 
      7 #include <string>
      8 
      9 #include "base/basictypes.h"
     10 #include "base/memory/ref_counted.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/message_loop.h"
     13 #include "base/metrics/histogram.h"
     14 #include "base/string_util.h"
     15 #include "base/stringprintf.h"
     16 #include "base/threading/platform_thread.h"
     17 #include "base/time.h"
     18 #include "googleurl/src/gurl.h"
     19 #include "net/base/cookie_monster.h"
     20 #include "net/base/cookie_monster_store_test.h" // For CookieStore Mock
     21 #include "testing/gtest/include/gtest/gtest.h"
     22 
     23 namespace net {
     24 
     25 using base::Time;
     26 using base::TimeDelta;
     27 
     28 namespace {
     29 
     30 class ParsedCookieTest : public testing::Test { };
     31 class CookieMonsterTest : public testing::Test { };
     32 
     33 // Helper for DeleteAllForHost test; repopulates CM with same layout
     34 // each time.
     35 const char* kTopLevelDomainPlus1 = "http://www.harvard.edu";
     36 const char* kTopLevelDomainPlus2 = "http://www.math.harvard.edu";
     37 const char* kTopLevelDomainPlus2Secure = "https://www.math.harvard.edu";
     38 const char* kTopLevelDomainPlus3 =
     39     "http://www.bourbaki.math.harvard.edu";
     40 const char* kOtherDomain = "http://www.mit.edu";
     41 
     42 void PopulateCmForDeleteAllForHost(scoped_refptr<CookieMonster> cm) {
     43   GURL url_top_level_domain_plus_1(kTopLevelDomainPlus1);
     44   GURL url_top_level_domain_plus_2(kTopLevelDomainPlus2);
     45   GURL url_top_level_domain_plus_2_secure(kTopLevelDomainPlus2Secure);
     46   GURL url_top_level_domain_plus_3(kTopLevelDomainPlus3);
     47   GURL url_other(kOtherDomain);
     48 
     49   cm->DeleteAll(true);
     50 
     51   // Static population for probe:
     52   //    * Three levels of domain cookie (.b.a, .c.b.a, .d.c.b.a)
     53   //    * Three levels of host cookie (w.b.a, w.c.b.a, w.d.c.b.a)
     54   //    * http_only cookie (w.c.b.a)
     55   //    * Two secure cookies (.c.b.a, w.c.b.a)
     56   //    * Two domain path cookies (.c.b.a/dir1, .c.b.a/dir1/dir2)
     57   //    * Two host path cookies (w.c.b.a/dir1, w.c.b.a/dir1/dir2)
     58 
     59   // Domain cookies
     60   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_1,
     61                                        "dom_1", "X", ".harvard.edu", "/",
     62                                        base::Time(), false, false));
     63   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_2,
     64                                        "dom_2", "X", ".math.harvard.edu", "/",
     65                                        base::Time(), false, false));
     66   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_3,
     67                                        "dom_3", "X",
     68                                        ".bourbaki.math.harvard.edu", "/",
     69                                        base::Time(), false, false));
     70 
     71   // Host cookies
     72   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_1,
     73                                        "host_1", "X", "", "/",
     74                                        base::Time(), false, false));
     75   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_2,
     76                                        "host_2", "X", "", "/",
     77                                        base::Time(), false, false));
     78   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_3,
     79                                        "host_3", "X", "", "/",
     80                                        base::Time(), false, false));
     81 
     82   // Http_only cookie
     83   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_2,
     84                                        "httpo_check", "X", "", "/",
     85                                        base::Time(), false, true));
     86 
     87   // Secure cookies
     88   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_2_secure,
     89                                        "sec_dom", "X", ".math.harvard.edu",
     90                                        "/", base::Time(), true, false));
     91   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_2_secure,
     92                                        "sec_host", "X", "", "/",
     93                                        base::Time(), true, false));
     94 
     95   // Domain path cookies
     96   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_2,
     97                                        "dom_path_1", "X",
     98                                        ".math.harvard.edu", "/dir1",
     99                                        base::Time(), false, false));
    100   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_2,
    101                                        "dom_path_2", "X",
    102                                        ".math.harvard.edu", "/dir1/dir2",
    103                                        base::Time(), false, false));
    104 
    105   // Host path cookies
    106   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_2,
    107                                        "host_path_1", "X",
    108                                        "", "/dir1",
    109                                        base::Time(), false, false));
    110   EXPECT_TRUE(cm->SetCookieWithDetails(url_top_level_domain_plus_2,
    111                                        "host_path_2", "X",
    112                                        "", "/dir1/dir2",
    113                                        base::Time(), false, false));
    114 
    115   EXPECT_EQ(13U, cm->GetAllCookies().size());
    116 }
    117 
    118 }  // namespace
    119 
    120 TEST(ParsedCookieTest, TestBasic) {
    121   CookieMonster::ParsedCookie pc("a=b");
    122   EXPECT_TRUE(pc.IsValid());
    123   EXPECT_FALSE(pc.IsSecure());
    124   EXPECT_EQ("a", pc.Name());
    125   EXPECT_EQ("b", pc.Value());
    126 }
    127 
    128 TEST(ParsedCookieTest, TestQuoted) {
    129   // These are some quoting cases which the major browsers all
    130   // handle differently.  I've tested Internet Explorer 6, Opera 9.6,
    131   // Firefox 3, and Safari Windows 3.2.1.  We originally tried to match
    132   // Firefox closely, however we now match Internet Explorer and Safari.
    133   const char* values[] = {
    134     // Trailing whitespace after a quoted value.  The whitespace after
    135     // the quote is stripped in all browsers.
    136     "\"zzz \"  ",              "\"zzz \"",
    137     // Handling a quoted value with a ';', like FOO="zz;pp"  ;
    138     // IE and Safari: "zz;
    139     // Firefox and Opera: "zz;pp"
    140     "\"zz;pp\" ;",             "\"zz",
    141     // Handling a value with multiple quoted parts, like FOO="zzz "   "ppp" ;
    142     // IE and Safari: "zzz "   "ppp";
    143     // Firefox: "zzz ";
    144     // Opera: <rejects cookie>
    145     "\"zzz \"   \"ppp\" ",     "\"zzz \"   \"ppp\"",
    146     // A quote in a value that didn't start quoted.  like FOO=A"B ;
    147     // IE, Safari, and Firefox: A"B;
    148     // Opera: <rejects cookie>
    149     "A\"B",                    "A\"B",
    150   };
    151 
    152   for (size_t i = 0; i < arraysize(values); i += 2) {
    153     std::string input(values[i]);
    154     std::string expected(values[i + 1]);
    155 
    156     CookieMonster::ParsedCookie pc(
    157         "aBc=" + input + " ; path=\"/\"  ; httponly ");
    158     EXPECT_TRUE(pc.IsValid());
    159     EXPECT_FALSE(pc.IsSecure());
    160     EXPECT_TRUE(pc.IsHttpOnly());
    161     EXPECT_TRUE(pc.HasPath());
    162     EXPECT_EQ("aBc", pc.Name());
    163     EXPECT_EQ(expected, pc.Value());
    164 
    165     // If a path was quoted, the path attribute keeps the quotes.  This will
    166     // make the cookie effectively useless, but path parameters aren't supposed
    167     // to be quoted.  Bug 1261605.
    168     EXPECT_EQ("\"/\"", pc.Path());
    169   }
    170 }
    171 
    172 TEST(ParsedCookieTest, TestNameless) {
    173   CookieMonster::ParsedCookie pc("BLAHHH; path=/; secure;");
    174   EXPECT_TRUE(pc.IsValid());
    175   EXPECT_TRUE(pc.IsSecure());
    176   EXPECT_TRUE(pc.HasPath());
    177   EXPECT_EQ("/", pc.Path());
    178   EXPECT_EQ("", pc.Name());
    179   EXPECT_EQ("BLAHHH", pc.Value());
    180 }
    181 
    182 TEST(ParsedCookieTest, TestAttributeCase) {
    183   CookieMonster::ParsedCookie pc("BLAHHH; Path=/; sECuRe; httpONLY");
    184   EXPECT_TRUE(pc.IsValid());
    185   EXPECT_TRUE(pc.IsSecure());
    186   EXPECT_TRUE(pc.IsHttpOnly());
    187   EXPECT_TRUE(pc.HasPath());
    188   EXPECT_EQ("/", pc.Path());
    189   EXPECT_EQ("", pc.Name());
    190   EXPECT_EQ("BLAHHH", pc.Value());
    191   EXPECT_EQ(3U, pc.NumberOfAttributes());
    192 }
    193 
    194 TEST(ParsedCookieTest, TestDoubleQuotedNameless) {
    195   CookieMonster::ParsedCookie pc("\"BLA\\\"HHH\"; path=/; secure;");
    196   EXPECT_TRUE(pc.IsValid());
    197   EXPECT_TRUE(pc.IsSecure());
    198   EXPECT_TRUE(pc.HasPath());
    199   EXPECT_EQ("/", pc.Path());
    200   EXPECT_EQ("", pc.Name());
    201   EXPECT_EQ("\"BLA\\\"HHH\"", pc.Value());
    202   EXPECT_EQ(2U, pc.NumberOfAttributes());
    203 }
    204 
    205 TEST(ParsedCookieTest, QuoteOffTheEnd) {
    206   CookieMonster::ParsedCookie pc("a=\"B");
    207   EXPECT_TRUE(pc.IsValid());
    208   EXPECT_EQ("a", pc.Name());
    209   EXPECT_EQ("\"B", pc.Value());
    210   EXPECT_EQ(0U, pc.NumberOfAttributes());
    211 }
    212 
    213 TEST(ParsedCookieTest, MissingName) {
    214   CookieMonster::ParsedCookie pc("=ABC");
    215   EXPECT_TRUE(pc.IsValid());
    216   EXPECT_EQ("", pc.Name());
    217   EXPECT_EQ("ABC", pc.Value());
    218   EXPECT_EQ(0U, pc.NumberOfAttributes());
    219 }
    220 
    221 TEST(ParsedCookieTest, MissingValue) {
    222   CookieMonster::ParsedCookie pc("ABC=;  path = /wee");
    223   EXPECT_TRUE(pc.IsValid());
    224   EXPECT_EQ("ABC", pc.Name());
    225   EXPECT_EQ("", pc.Value());
    226   EXPECT_TRUE(pc.HasPath());
    227   EXPECT_EQ("/wee", pc.Path());
    228   EXPECT_EQ(1U, pc.NumberOfAttributes());
    229 }
    230 
    231 TEST(ParsedCookieTest, Whitespace) {
    232   CookieMonster::ParsedCookie pc("  A  = BC  ;secure;;;   httponly");
    233   EXPECT_TRUE(pc.IsValid());
    234   EXPECT_EQ("A", pc.Name());
    235   EXPECT_EQ("BC", pc.Value());
    236   EXPECT_FALSE(pc.HasPath());
    237   EXPECT_FALSE(pc.HasDomain());
    238   EXPECT_TRUE(pc.IsSecure());
    239   EXPECT_TRUE(pc.IsHttpOnly());
    240   // We parse anything between ; as attributes, so we end up with two
    241   // attributes with an empty string name and value.
    242   EXPECT_EQ(4U, pc.NumberOfAttributes());
    243 }
    244 TEST(ParsedCookieTest, MultipleEquals) {
    245   CookieMonster::ParsedCookie pc("  A=== BC  ;secure;;;   httponly");
    246   EXPECT_TRUE(pc.IsValid());
    247   EXPECT_EQ("A", pc.Name());
    248   EXPECT_EQ("== BC", pc.Value());
    249   EXPECT_FALSE(pc.HasPath());
    250   EXPECT_FALSE(pc.HasDomain());
    251   EXPECT_TRUE(pc.IsSecure());
    252   EXPECT_TRUE(pc.IsHttpOnly());
    253   EXPECT_EQ(4U, pc.NumberOfAttributes());
    254 }
    255 
    256 TEST(ParsedCookieTest, QuotedTrailingWhitespace) {
    257   CookieMonster::ParsedCookie pc("ANCUUID=\"zohNumRKgI0oxyhSsV3Z7D\"  ; "
    258                                       "expires=Sun, 18-Apr-2027 21:06:29 GMT ; "
    259                                       "path=/  ;  ");
    260   EXPECT_TRUE(pc.IsValid());
    261   EXPECT_EQ("ANCUUID", pc.Name());
    262   // Stripping whitespace after the quotes matches all other major browsers.
    263   EXPECT_EQ("\"zohNumRKgI0oxyhSsV3Z7D\"", pc.Value());
    264   EXPECT_TRUE(pc.HasExpires());
    265   EXPECT_TRUE(pc.HasPath());
    266   EXPECT_EQ("/", pc.Path());
    267   EXPECT_EQ(2U, pc.NumberOfAttributes());
    268 }
    269 
    270 TEST(ParsedCookieTest, TrailingWhitespace) {
    271   CookieMonster::ParsedCookie pc("ANCUUID=zohNumRKgI0oxyhSsV3Z7D  ; "
    272                                       "expires=Sun, 18-Apr-2027 21:06:29 GMT ; "
    273                                       "path=/  ;  ");
    274   EXPECT_TRUE(pc.IsValid());
    275   EXPECT_EQ("ANCUUID", pc.Name());
    276   EXPECT_EQ("zohNumRKgI0oxyhSsV3Z7D", pc.Value());
    277   EXPECT_TRUE(pc.HasExpires());
    278   EXPECT_TRUE(pc.HasPath());
    279   EXPECT_EQ("/", pc.Path());
    280   EXPECT_EQ(2U, pc.NumberOfAttributes());
    281 }
    282 
    283 TEST(ParsedCookieTest, TooManyPairs) {
    284   std::string blankpairs;
    285   blankpairs.resize(CookieMonster::ParsedCookie::kMaxPairs - 1, ';');
    286 
    287   CookieMonster::ParsedCookie pc1(blankpairs + "secure");
    288   EXPECT_TRUE(pc1.IsValid());
    289   EXPECT_TRUE(pc1.IsSecure());
    290 
    291   CookieMonster::ParsedCookie pc2(blankpairs + ";secure");
    292   EXPECT_TRUE(pc2.IsValid());
    293   EXPECT_FALSE(pc2.IsSecure());
    294 }
    295 
    296 // TODO some better test cases for invalid cookies.
    297 TEST(ParsedCookieTest, InvalidWhitespace) {
    298   CookieMonster::ParsedCookie pc("    ");
    299   EXPECT_FALSE(pc.IsValid());
    300 }
    301 
    302 TEST(ParsedCookieTest, InvalidTooLong) {
    303   std::string maxstr;
    304   maxstr.resize(CookieMonster::ParsedCookie::kMaxCookieSize, 'a');
    305 
    306   CookieMonster::ParsedCookie pc1(maxstr);
    307   EXPECT_TRUE(pc1.IsValid());
    308 
    309   CookieMonster::ParsedCookie pc2(maxstr + "A");
    310   EXPECT_FALSE(pc2.IsValid());
    311 }
    312 
    313 TEST(ParsedCookieTest, InvalidEmpty) {
    314   CookieMonster::ParsedCookie pc("");
    315   EXPECT_FALSE(pc.IsValid());
    316 }
    317 
    318 TEST(ParsedCookieTest, EmbeddedTerminator) {
    319   CookieMonster::ParsedCookie pc1("AAA=BB\0ZYX");
    320   CookieMonster::ParsedCookie pc2("AAA=BB\rZYX");
    321   CookieMonster::ParsedCookie pc3("AAA=BB\nZYX");
    322   EXPECT_TRUE(pc1.IsValid());
    323   EXPECT_EQ("AAA", pc1.Name());
    324   EXPECT_EQ("BB", pc1.Value());
    325   EXPECT_TRUE(pc2.IsValid());
    326   EXPECT_EQ("AAA", pc2.Name());
    327   EXPECT_EQ("BB", pc2.Value());
    328   EXPECT_TRUE(pc3.IsValid());
    329   EXPECT_EQ("AAA", pc3.Name());
    330   EXPECT_EQ("BB", pc3.Value());
    331 }
    332 
    333 TEST(ParsedCookieTest, ParseTokensAndValues) {
    334   EXPECT_EQ("hello",
    335             CookieMonster::ParsedCookie::ParseTokenString(
    336                 "hello\nworld"));
    337   EXPECT_EQ("fs!!@",
    338             CookieMonster::ParsedCookie::ParseTokenString(
    339                 "fs!!@;helloworld"));
    340   EXPECT_EQ("hello world\tgood",
    341             CookieMonster::ParsedCookie::ParseTokenString(
    342                 "hello world\tgood\rbye"));
    343   EXPECT_EQ("A",
    344             CookieMonster::ParsedCookie::ParseTokenString(
    345                 "A=B=C;D=E"));
    346   EXPECT_EQ("hello",
    347             CookieMonster::ParsedCookie::ParseValueString(
    348                 "hello\nworld"));
    349   EXPECT_EQ("fs!!@",
    350             CookieMonster::ParsedCookie::ParseValueString(
    351                 "fs!!@;helloworld"));
    352   EXPECT_EQ("hello world\tgood",
    353             CookieMonster::ParsedCookie::ParseValueString(
    354                 "hello world\tgood\rbye"));
    355   EXPECT_EQ("A=B=C",
    356             CookieMonster::ParsedCookie::ParseValueString(
    357                 "A=B=C;D=E"));
    358 }
    359 
    360 static const char kUrlGoogle[] = "http://www.google.izzle";
    361 static const char kUrlGoogleSpecific[] = "http://www.gmail.google.izzle";
    362 static const char kUrlGoogleSecure[] = "https://www.google.izzle";
    363 static const char kUrlFtp[] = "ftp://ftp.google.izzle/";
    364 static const char kValidCookieLine[] = "A=B; path=/";
    365 static const char kValidDomainCookieLine[] = "A=B; path=/; domain=google.izzle";
    366 
    367 TEST(CookieMonsterTest, DomainTest) {
    368   GURL url_google(kUrlGoogle);
    369 
    370   scoped_refptr<MockPersistentCookieStore> store(
    371       new MockPersistentCookieStore);
    372   scoped_refptr<CookieMonster> cm(new CookieMonster(store, NULL));
    373   EXPECT_TRUE(cm->SetCookie(url_google, "A=B"));
    374   EXPECT_EQ("A=B", cm->GetCookies(url_google));
    375   EXPECT_TRUE(cm->SetCookie(url_google, "C=D; domain=.google.izzle"));
    376   EXPECT_EQ("A=B; C=D", cm->GetCookies(url_google));
    377 
    378   // Verify that A=B was set as a host cookie rather than a domain
    379   // cookie -- should not be accessible from a sub sub-domain.
    380   EXPECT_EQ("C=D", cm->GetCookies(GURL("http://foo.www.google.izzle")));
    381 
    382   // Test and make sure we find domain cookies on the same domain.
    383   EXPECT_TRUE(cm->SetCookie(url_google, "E=F; domain=.www.google.izzle"));
    384   EXPECT_EQ("A=B; C=D; E=F", cm->GetCookies(url_google));
    385 
    386   // Test setting a domain= that doesn't start w/ a dot, should
    387   // treat it as a domain cookie, as if there was a pre-pended dot.
    388   EXPECT_TRUE(cm->SetCookie(url_google, "G=H; domain=www.google.izzle"));
    389   EXPECT_EQ("A=B; C=D; E=F; G=H", cm->GetCookies(url_google));
    390 
    391   // Test domain enforcement, should fail on a sub-domain or something too deep.
    392   EXPECT_FALSE(cm->SetCookie(url_google, "I=J; domain=.izzle"));
    393   EXPECT_EQ("", cm->GetCookies(GURL("http://a.izzle")));
    394   EXPECT_FALSE(cm->SetCookie(url_google, "K=L; domain=.bla.www.google.izzle"));
    395   EXPECT_EQ("C=D; E=F; G=H",
    396             cm->GetCookies(GURL("http://bla.www.google.izzle")));
    397   EXPECT_EQ("A=B; C=D; E=F; G=H", cm->GetCookies(url_google));
    398 
    399   // Nothing was persisted to the backing store.
    400   EXPECT_EQ(0u, store->commands().size());
    401 }
    402 
    403 // FireFox recognizes domains containing trailing periods as valid.
    404 // IE and Safari do not. Assert the expected policy here.
    405 TEST(CookieMonsterTest, DomainWithTrailingDotTest) {
    406   scoped_refptr<MockPersistentCookieStore> store(
    407       new MockPersistentCookieStore);
    408   scoped_refptr<CookieMonster> cm(new CookieMonster(store, NULL));
    409   GURL url_google("http://www.google.com");
    410 
    411   EXPECT_FALSE(cm->SetCookie(url_google, "a=1; domain=.www.google.com."));
    412   EXPECT_FALSE(cm->SetCookie(url_google, "b=2; domain=.www.google.com.."));
    413   EXPECT_EQ("", cm->GetCookies(url_google));
    414 
    415   // Nothing was persisted to the backing store.
    416   EXPECT_EQ(0u, store->commands().size());
    417 }
    418 
    419 // Test that cookies can bet set on higher level domains.
    420 // http://b/issue?id=896491
    421 TEST(CookieMonsterTest, ValidSubdomainTest) {
    422   scoped_refptr<MockPersistentCookieStore> store(
    423       new MockPersistentCookieStore);
    424   scoped_refptr<CookieMonster> cm(new CookieMonster(store, NULL));
    425   GURL url_abcd("http://a.b.c.d.com");
    426   GURL url_bcd("http://b.c.d.com");
    427   GURL url_cd("http://c.d.com");
    428   GURL url_d("http://d.com");
    429 
    430   EXPECT_TRUE(cm->SetCookie(url_abcd, "a=1; domain=.a.b.c.d.com"));
    431   EXPECT_TRUE(cm->SetCookie(url_abcd, "b=2; domain=.b.c.d.com"));
    432   EXPECT_TRUE(cm->SetCookie(url_abcd, "c=3; domain=.c.d.com"));
    433   EXPECT_TRUE(cm->SetCookie(url_abcd, "d=4; domain=.d.com"));
    434 
    435   EXPECT_EQ("a=1; b=2; c=3; d=4", cm->GetCookies(url_abcd));
    436   EXPECT_EQ("b=2; c=3; d=4", cm->GetCookies(url_bcd));
    437   EXPECT_EQ("c=3; d=4", cm->GetCookies(url_cd));
    438   EXPECT_EQ("d=4", cm->GetCookies(url_d));
    439 
    440   // Check that the same cookie can exist on different sub-domains.
    441   EXPECT_TRUE(cm->SetCookie(url_bcd, "X=bcd; domain=.b.c.d.com"));
    442   EXPECT_TRUE(cm->SetCookie(url_bcd, "X=cd; domain=.c.d.com"));
    443   EXPECT_EQ("b=2; c=3; d=4; X=bcd; X=cd", cm->GetCookies(url_bcd));
    444   EXPECT_EQ("c=3; d=4; X=cd", cm->GetCookies(url_cd));
    445 
    446   // Nothing was persisted to the backing store.
    447   EXPECT_EQ(0u, store->commands().size());
    448 }
    449 
    450 // Test that setting a cookie which specifies an invalid domain has
    451 // no side-effect. An invalid domain in this context is one which does
    452 // not match the originating domain.
    453 // http://b/issue?id=896472
    454 TEST(CookieMonsterTest, InvalidDomainTest) {
    455   {
    456     scoped_refptr<MockPersistentCookieStore> store(
    457         new MockPersistentCookieStore);
    458 
    459     scoped_refptr<CookieMonster> cm(new CookieMonster(store, NULL));
    460     GURL url_foobar("http://foo.bar.com");
    461 
    462     // More specific sub-domain than allowed.
    463     EXPECT_FALSE(cm->SetCookie(url_foobar, "a=1; domain=.yo.foo.bar.com"));
    464 
    465     EXPECT_FALSE(cm->SetCookie(url_foobar, "b=2; domain=.foo.com"));
    466     EXPECT_FALSE(cm->SetCookie(url_foobar, "c=3; domain=.bar.foo.com"));
    467 
    468     // Different TLD, but the rest is a substring.
    469     EXPECT_FALSE(cm->SetCookie(url_foobar, "d=4; domain=.foo.bar.com.net"));
    470 
    471     // A substring that isn't really a parent domain.
    472     EXPECT_FALSE(cm->SetCookie(url_foobar, "e=5; domain=ar.com"));
    473 
    474     // Completely invalid domains:
    475     EXPECT_FALSE(cm->SetCookie(url_foobar, "f=6; domain=."));
    476     EXPECT_FALSE(cm->SetCookie(url_foobar, "g=7; domain=/"));
    477     EXPECT_FALSE(cm->SetCookie(url_foobar, "h=8; domain=http://foo.bar.com"));
    478     EXPECT_FALSE(cm->SetCookie(url_foobar, "i=9; domain=..foo.bar.com"));
    479     EXPECT_FALSE(cm->SetCookie(url_foobar, "j=10; domain=..bar.com"));
    480 
    481     // Make sure there isn't something quirky in the domain canonicalization
    482     // that supports full URL semantics.
    483     EXPECT_FALSE(cm->SetCookie(url_foobar, "k=11; domain=.foo.bar.com?blah"));
    484     EXPECT_FALSE(cm->SetCookie(url_foobar, "l=12; domain=.foo.bar.com/blah"));
    485     EXPECT_FALSE(cm->SetCookie(url_foobar, "m=13; domain=.foo.bar.com:80"));
    486     EXPECT_FALSE(cm->SetCookie(url_foobar, "n=14; domain=.foo.bar.com:"));
    487     EXPECT_FALSE(cm->SetCookie(url_foobar, "o=15; domain=.foo.bar.com#sup"));
    488 
    489     EXPECT_EQ("", cm->GetCookies(url_foobar));
    490 
    491     // Nothing was persisted to the backing store.
    492     EXPECT_EQ(0u, store->commands().size());
    493   }
    494 
    495   {
    496     // Make sure the cookie code hasn't gotten its subdomain string handling
    497     // reversed, missed a suffix check, etc.  It's important here that the two
    498     // hosts below have the same domain + registry.
    499     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    500     GURL url_foocom("http://foo.com.com");
    501     EXPECT_FALSE(cm->SetCookie(url_foocom, "a=1; domain=.foo.com.com.com"));
    502     EXPECT_EQ("", cm->GetCookies(url_foocom));
    503   }
    504 }
    505 
    506 // Test the behavior of omitting dot prefix from domain, should
    507 // function the same as FireFox.
    508 // http://b/issue?id=889898
    509 TEST(CookieMonsterTest, DomainWithoutLeadingDotTest) {
    510   {  // The omission of dot results in setting a domain cookie.
    511     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    512     GURL url_hosted("http://manage.hosted.filefront.com");
    513     GURL url_filefront("http://www.filefront.com");
    514     EXPECT_TRUE(cm->SetCookie(url_hosted, "sawAd=1; domain=filefront.com"));
    515     EXPECT_EQ("sawAd=1", cm->GetCookies(url_hosted));
    516     EXPECT_EQ("sawAd=1", cm->GetCookies(url_filefront));
    517   }
    518 
    519   {  // Even when the domains match exactly, don't consider it host cookie.
    520     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    521     GURL url("http://www.google.com");
    522     EXPECT_TRUE(cm->SetCookie(url, "a=1; domain=www.google.com"));
    523     EXPECT_EQ("a=1", cm->GetCookies(url));
    524     EXPECT_EQ("a=1", cm->GetCookies(GURL("http://sub.www.google.com")));
    525     EXPECT_EQ("", cm->GetCookies(GURL("http://something-else.com")));
    526   }
    527 }
    528 
    529 // Test that the domain specified in cookie string is treated case-insensitive
    530 // http://b/issue?id=896475.
    531 TEST(CookieMonsterTest, CaseInsensitiveDomainTest) {
    532   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    533   GURL url_google("http://www.google.com");
    534   EXPECT_TRUE(cm->SetCookie(url_google, "a=1; domain=.GOOGLE.COM"));
    535   EXPECT_TRUE(cm->SetCookie(url_google, "b=2; domain=.wWw.gOOgLE.coM"));
    536   EXPECT_EQ("a=1; b=2", cm->GetCookies(url_google));
    537 }
    538 
    539 TEST(CookieMonsterTest, TestIpAddress) {
    540   GURL url_ip("http://1.2.3.4/weee");
    541   {
    542     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    543     EXPECT_TRUE(cm->SetCookie(url_ip, kValidCookieLine));
    544     EXPECT_EQ("A=B", cm->GetCookies(url_ip));
    545   }
    546 
    547   {  // IP addresses should not be able to set domain cookies.
    548     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    549     EXPECT_FALSE(cm->SetCookie(url_ip, "b=2; domain=.1.2.3.4"));
    550     EXPECT_FALSE(cm->SetCookie(url_ip, "c=3; domain=.3.4"));
    551     EXPECT_EQ("", cm->GetCookies(url_ip));
    552     // It should be allowed to set a cookie if domain= matches the IP address
    553     // exactly.  This matches IE/Firefox, even though it seems a bit wrong.
    554     EXPECT_FALSE(cm->SetCookie(url_ip, "b=2; domain=1.2.3.3"));
    555     EXPECT_EQ("", cm->GetCookies(url_ip));
    556     EXPECT_TRUE(cm->SetCookie(url_ip, "b=2; domain=1.2.3.4"));
    557     EXPECT_EQ("b=2", cm->GetCookies(url_ip));
    558   }
    559 }
    560 
    561 // Test host cookies, and setting of cookies on TLD.
    562 TEST(CookieMonsterTest, TestNonDottedAndTLD) {
    563   {
    564     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    565     GURL url("http://com/");
    566     // Allow setting on "com", (but only as a host cookie).
    567     EXPECT_TRUE(cm->SetCookie(url, "a=1"));
    568     EXPECT_FALSE(cm->SetCookie(url, "b=2; domain=.com"));
    569     EXPECT_FALSE(cm->SetCookie(url, "c=3; domain=com"));
    570     EXPECT_EQ("a=1", cm->GetCookies(url));
    571     // Make sure it doesn't show up for a normal .com, it should be a host
    572     // not a domain cookie.
    573     EXPECT_EQ("", cm->GetCookies(GURL("http://hopefully-no-cookies.com/")));
    574     EXPECT_EQ("", cm->GetCookies(GURL("http://.com/")));
    575   }
    576 
    577   {  // http://com. should be treated the same as http://com.
    578     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    579     GURL url("http://com./index.html");
    580     EXPECT_TRUE(cm->SetCookie(url, "a=1"));
    581     EXPECT_EQ("a=1", cm->GetCookies(url));
    582     EXPECT_EQ("", cm->GetCookies(GURL("http://hopefully-no-cookies.com./")));
    583   }
    584 
    585   {  // Should not be able to set host cookie from a subdomain.
    586     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    587     GURL url("http://a.b");
    588     EXPECT_FALSE(cm->SetCookie(url, "a=1; domain=.b"));
    589     EXPECT_FALSE(cm->SetCookie(url, "b=2; domain=b"));
    590     EXPECT_EQ("", cm->GetCookies(url));
    591   }
    592 
    593   {  // Same test as above, but explicitly on a known TLD (com).
    594     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    595     GURL url("http://google.com");
    596     EXPECT_FALSE(cm->SetCookie(url, "a=1; domain=.com"));
    597     EXPECT_FALSE(cm->SetCookie(url, "b=2; domain=com"));
    598     EXPECT_EQ("", cm->GetCookies(url));
    599   }
    600 
    601   {  // Make sure can't set cookie on TLD which is dotted.
    602     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    603     GURL url("http://google.co.uk");
    604     EXPECT_FALSE(cm->SetCookie(url, "a=1; domain=.co.uk"));
    605     EXPECT_FALSE(cm->SetCookie(url, "b=2; domain=.uk"));
    606     EXPECT_EQ("", cm->GetCookies(url));
    607     EXPECT_EQ("", cm->GetCookies(GURL("http://something-else.co.uk")));
    608     EXPECT_EQ("", cm->GetCookies(GURL("http://something-else.uk")));
    609   }
    610 
    611   {  // Intranet URLs should only be able to set host cookies.
    612     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    613     GURL url("http://b");
    614     EXPECT_TRUE(cm->SetCookie(url, "a=1"));
    615     EXPECT_FALSE(cm->SetCookie(url, "b=2; domain=.b"));
    616     EXPECT_FALSE(cm->SetCookie(url, "c=3; domain=b"));
    617     EXPECT_EQ("a=1", cm->GetCookies(url));
    618   }
    619 }
    620 
    621 // Test reading/writing cookies when the domain ends with a period,
    622 // as in "www.google.com."
    623 TEST(CookieMonsterTest, TestHostEndsWithDot) {
    624   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    625   GURL url("http://www.google.com");
    626   GURL url_with_dot("http://www.google.com.");
    627   EXPECT_TRUE(cm->SetCookie(url, "a=1"));
    628   EXPECT_EQ("a=1", cm->GetCookies(url));
    629 
    630   // Do not share cookie space with the dot version of domain.
    631   // Note: this is not what FireFox does, but it _is_ what IE+Safari do.
    632   EXPECT_FALSE(cm->SetCookie(url, "b=2; domain=.www.google.com."));
    633   EXPECT_EQ("a=1", cm->GetCookies(url));
    634 
    635   EXPECT_TRUE(cm->SetCookie(url_with_dot, "b=2; domain=.google.com."));
    636   EXPECT_EQ("b=2", cm->GetCookies(url_with_dot));
    637 
    638   // Make sure there weren't any side effects.
    639   EXPECT_EQ(cm->GetCookies(GURL("http://hopefully-no-cookies.com/")), "");
    640   EXPECT_EQ("", cm->GetCookies(GURL("http://.com/")));
    641 }
    642 
    643 TEST(CookieMonsterTest, InvalidScheme) {
    644   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    645   EXPECT_FALSE(cm->SetCookie(GURL(kUrlFtp), kValidCookieLine));
    646 }
    647 
    648 TEST(CookieMonsterTest, InvalidScheme_Read) {
    649   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    650   EXPECT_TRUE(cm->SetCookie(GURL(kUrlGoogle), kValidDomainCookieLine));
    651   EXPECT_EQ("", cm->GetCookies(GURL(kUrlFtp)));
    652 }
    653 
    654 TEST(CookieMonsterTest, PathTest) {
    655   std::string url("http://www.google.izzle");
    656   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    657   EXPECT_TRUE(cm->SetCookie(GURL(url), "A=B; path=/wee"));
    658   EXPECT_EQ("A=B", cm->GetCookies(GURL(url + "/wee")));
    659   EXPECT_EQ("A=B", cm->GetCookies(GURL(url + "/wee/")));
    660   EXPECT_EQ("A=B", cm->GetCookies(GURL(url + "/wee/war")));
    661   EXPECT_EQ("A=B", cm->GetCookies(GURL(url + "/wee/war/more/more")));
    662   EXPECT_EQ("", cm->GetCookies(GURL(url + "/weehee")));
    663   EXPECT_EQ("", cm->GetCookies(GURL(url + "/")));
    664 
    665   // If we add a 0 length path, it should default to /
    666   EXPECT_TRUE(cm->SetCookie(GURL(url), "A=C; path="));
    667   EXPECT_EQ("A=B; A=C", cm->GetCookies(GURL(url + "/wee")));
    668   EXPECT_EQ("A=C", cm->GetCookies(GURL(url + "/")));
    669 }
    670 
    671 TEST(CookieMonsterTest, HttpOnlyTest) {
    672   GURL url_google(kUrlGoogle);
    673   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    674   CookieOptions options;
    675   options.set_include_httponly();
    676 
    677   // Create a httponly cookie.
    678   EXPECT_TRUE(cm->SetCookieWithOptions(url_google, "A=B; httponly", options));
    679 
    680   // Check httponly read protection.
    681   EXPECT_EQ("", cm->GetCookies(url_google));
    682   EXPECT_EQ("A=B", cm->GetCookiesWithOptions(url_google, options));
    683 
    684   // Check httponly overwrite protection.
    685   EXPECT_FALSE(cm->SetCookie(url_google, "A=C"));
    686   EXPECT_EQ("", cm->GetCookies(url_google));
    687   EXPECT_EQ("A=B", cm->GetCookiesWithOptions(url_google, options));
    688   EXPECT_TRUE(cm->SetCookieWithOptions(url_google, "A=C", options));
    689   EXPECT_EQ("A=C", cm->GetCookies(url_google));
    690 
    691   // Check httponly create protection.
    692   EXPECT_FALSE(cm->SetCookie(url_google, "B=A; httponly"));
    693   EXPECT_EQ("A=C", cm->GetCookiesWithOptions(url_google, options));
    694   EXPECT_TRUE(cm->SetCookieWithOptions(url_google, "B=A; httponly", options));
    695   EXPECT_EQ("A=C; B=A", cm->GetCookiesWithOptions(url_google, options));
    696   EXPECT_EQ("A=C", cm->GetCookies(url_google));
    697 }
    698 
    699 namespace {
    700 
    701 struct CookieDateParsingCase {
    702   const char* str;
    703   const bool valid;
    704   const time_t epoch;
    705 };
    706 
    707 struct DomainIsHostOnlyCase {
    708   const char* str;
    709   const bool is_host_only;
    710 };
    711 
    712 }  // namespace
    713 
    714 TEST(CookieMonsterTest, TestCookieDateParsing) {
    715   const CookieDateParsingCase tests[] = {
    716     { "Sat, 15-Apr-17 21:01:22 GMT",           true, 1492290082 },
    717     { "Thu, 19-Apr-2007 16:00:00 GMT",         true, 1176998400 },
    718     { "Wed, 25 Apr 2007 21:02:13 GMT",         true, 1177534933 },
    719     { "Thu, 19/Apr\\2007 16:00:00 GMT",        true, 1176998400 },
    720     { "Fri, 1 Jan 2010 01:01:50 GMT",          true, 1262307710 },
    721     { "Wednesday, 1-Jan-2003 00:00:00 GMT",    true, 1041379200 },
    722     { ", 1-Jan-2003 00:00:00 GMT",             true, 1041379200 },
    723     { " 1-Jan-2003 00:00:00 GMT",              true, 1041379200 },
    724     { "1-Jan-2003 00:00:00 GMT",               true, 1041379200 },
    725     { "Wed,18-Apr-07 22:50:12 GMT",            true, 1176936612 },
    726     { "WillyWonka  , 18-Apr-07 22:50:12 GMT",  true, 1176936612 },
    727     { "WillyWonka  , 18-Apr-07 22:50:12",      true, 1176936612 },
    728     { "WillyWonka  ,  18-apr-07   22:50:12",   true, 1176936612 },
    729     { "Mon, 18-Apr-1977 22:50:13 GMT",         true, 230251813 },
    730     { "Mon, 18-Apr-77 22:50:13 GMT",           true, 230251813 },
    731     // If the cookie came in with the expiration quoted (which in terms of
    732     // the RFC you shouldn't do), we will get string quoted.  Bug 1261605.
    733     { "\"Sat, 15-Apr-17\\\"21:01:22\\\"GMT\"", true, 1492290082 },
    734     // Test with full month names and partial names.
    735     { "Partyday, 18- April-07 22:50:12",       true, 1176936612 },
    736     { "Partyday, 18 - Apri-07 22:50:12",       true, 1176936612 },
    737     { "Wednes, 1-Januar-2003 00:00:00 GMT",    true, 1041379200 },
    738     // Test that we always take GMT even with other time zones or bogus
    739     // values.  The RFC says everything should be GMT, and in the worst case
    740     // we are 24 hours off because of zone issues.
    741     { "Sat, 15-Apr-17 21:01:22",               true, 1492290082 },
    742     { "Sat, 15-Apr-17 21:01:22 GMT-2",         true, 1492290082 },
    743     { "Sat, 15-Apr-17 21:01:22 GMT BLAH",      true, 1492290082 },
    744     { "Sat, 15-Apr-17 21:01:22 GMT-0400",      true, 1492290082 },
    745     { "Sat, 15-Apr-17 21:01:22 GMT-0400 (EDT)",true, 1492290082 },
    746     { "Sat, 15-Apr-17 21:01:22 DST",           true, 1492290082 },
    747     { "Sat, 15-Apr-17 21:01:22 -0400",         true, 1492290082 },
    748     { "Sat, 15-Apr-17 21:01:22 (hello there)", true, 1492290082 },
    749     // Test that if we encounter multiple : fields, that we take the first
    750     // that correctly parses.
    751     { "Sat, 15-Apr-17 21:01:22 11:22:33",      true, 1492290082 },
    752     { "Sat, 15-Apr-17 ::00 21:01:22",          true, 1492290082 },
    753     { "Sat, 15-Apr-17 boink:z 21:01:22",       true, 1492290082 },
    754     // We take the first, which in this case is invalid.
    755     { "Sat, 15-Apr-17 91:22:33 21:01:22",      false, 0 },
    756     // amazon.com formats their cookie expiration like this.
    757     { "Thu Apr 18 22:50:12 2007 GMT",          true, 1176936612 },
    758     // Test that hh:mm:ss can occur anywhere.
    759     { "22:50:12 Thu Apr 18 2007 GMT",          true, 1176936612 },
    760     { "Thu 22:50:12 Apr 18 2007 GMT",          true, 1176936612 },
    761     { "Thu Apr 22:50:12 18 2007 GMT",          true, 1176936612 },
    762     { "Thu Apr 18 22:50:12 2007 GMT",          true, 1176936612 },
    763     { "Thu Apr 18 2007 22:50:12 GMT",          true, 1176936612 },
    764     { "Thu Apr 18 2007 GMT 22:50:12",          true, 1176936612 },
    765     // Test that the day and year can be anywhere if they are unambigious.
    766     { "Sat, 15-Apr-17 21:01:22 GMT",           true, 1492290082 },
    767     { "15-Sat, Apr-17 21:01:22 GMT",           true, 1492290082 },
    768     { "15-Sat, Apr 21:01:22 GMT 17",           true, 1492290082 },
    769     { "15-Sat, Apr 21:01:22 GMT 2017",         true, 1492290082 },
    770     { "15 Apr 21:01:22 2017",                  true, 1492290082 },
    771     { "15 17 Apr 21:01:22",                    true, 1492290082 },
    772     { "Apr 15 17 21:01:22",                    true, 1492290082 },
    773     { "Apr 15 21:01:22 17",                    true, 1492290082 },
    774     { "2017 April 15 21:01:22",                true, 1492290082 },
    775     { "15 April 2017 21:01:22",                true, 1492290082 },
    776     // Some invalid dates
    777     { "98 April 17 21:01:22",                    false, 0 },
    778     { "Thu, 012-Aug-2008 20:49:07 GMT",          false, 0 },
    779     { "Thu, 12-Aug-31841 20:49:07 GMT",          false, 0 },
    780     { "Thu, 12-Aug-9999999999 20:49:07 GMT",     false, 0 },
    781     { "Thu, 999999999999-Aug-2007 20:49:07 GMT", false, 0 },
    782     { "Thu, 12-Aug-2007 20:61:99999999999 GMT",  false, 0 },
    783     { "IAintNoDateFool",                         false, 0 },
    784   };
    785 
    786   Time parsed_time;
    787   for (size_t i = 0; i < arraysize(tests); ++i) {
    788     parsed_time = CookieMonster::ParseCookieTime(tests[i].str);
    789     if (!tests[i].valid) {
    790       EXPECT_FALSE(!parsed_time.is_null()) << tests[i].str;
    791       continue;
    792     }
    793     EXPECT_TRUE(!parsed_time.is_null()) << tests[i].str;
    794     EXPECT_EQ(tests[i].epoch, parsed_time.ToTimeT()) << tests[i].str;
    795   }
    796 }
    797 
    798 TEST(CookieMonsterTest, TestDomainIsHostOnly) {
    799   const DomainIsHostOnlyCase tests[] = {
    800     { "",               true },
    801     { "www.google.com", true },
    802     { ".google.com",    false }
    803   };
    804 
    805   for (size_t i = 0; i < arraysize(tests); ++i) {
    806     EXPECT_EQ(tests[i].is_host_only,
    807               CookieMonster::DomainIsHostOnly(tests[i].str));
    808   }
    809 }
    810 
    811 TEST(CookieMonsterTest, TestCookieDeletion) {
    812   GURL url_google(kUrlGoogle);
    813   scoped_refptr<MockPersistentCookieStore> store(
    814       new MockPersistentCookieStore);
    815   scoped_refptr<CookieMonster> cm(new CookieMonster(store, NULL));
    816 
    817   // Create a session cookie.
    818   EXPECT_TRUE(cm->SetCookie(url_google, kValidCookieLine));
    819   EXPECT_EQ("A=B", cm->GetCookies(url_google));
    820   // Delete it via Max-Age.
    821   EXPECT_TRUE(cm->SetCookie(url_google,
    822                            std::string(kValidCookieLine) + "; max-age=0"));
    823   EXPECT_EQ("", cm->GetCookies(url_google));
    824 
    825   // Create a session cookie.
    826   EXPECT_TRUE(cm->SetCookie(url_google, kValidCookieLine));
    827   EXPECT_EQ("A=B", cm->GetCookies(url_google));
    828   // Delete it via Expires.
    829   EXPECT_TRUE(cm->SetCookie(url_google,
    830                            std::string(kValidCookieLine) +
    831                            "; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
    832   EXPECT_EQ("", cm->GetCookies(url_google));
    833 
    834   // Create a persistent cookie.
    835   EXPECT_TRUE(cm->SetCookie(url_google,
    836                            std::string(kValidCookieLine) +
    837                            "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
    838   ASSERT_EQ(1u, store->commands().size());
    839   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
    840 
    841   EXPECT_EQ("A=B", cm->GetCookies(url_google));
    842   // Delete it via Max-Age.
    843   EXPECT_TRUE(cm->SetCookie(url_google,
    844                            std::string(kValidCookieLine) + "; max-age=0"));
    845   ASSERT_EQ(2u, store->commands().size());
    846   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
    847   EXPECT_EQ("", cm->GetCookies(url_google));
    848 
    849   // Create a persistent cookie.
    850   EXPECT_TRUE(cm->SetCookie(url_google,
    851                            std::string(kValidCookieLine) +
    852                            "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
    853   ASSERT_EQ(3u, store->commands().size());
    854   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[2].type);
    855   EXPECT_EQ("A=B", cm->GetCookies(url_google));
    856   // Delete it via Expires.
    857   EXPECT_TRUE(cm->SetCookie(url_google,
    858                            std::string(kValidCookieLine) +
    859                            "; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
    860   ASSERT_EQ(4u, store->commands().size());
    861   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[3].type);
    862   EXPECT_EQ("", cm->GetCookies(url_google));
    863 
    864   // Create a persistent cookie.
    865   EXPECT_TRUE(cm->SetCookie(url_google,
    866                            std::string(kValidCookieLine) +
    867                            "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
    868   ASSERT_EQ(5u, store->commands().size());
    869   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[4].type);
    870   EXPECT_EQ("A=B", cm->GetCookies(url_google));
    871   // Delete it via Expires, with a unix epoch of 0.
    872   EXPECT_TRUE(cm->SetCookie(url_google,
    873                            std::string(kValidCookieLine) +
    874                            "; expires=Thu, 1-Jan-1970 00:00:00 GMT"));
    875   ASSERT_EQ(6u, store->commands().size());
    876   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[5].type);
    877   EXPECT_EQ("", cm->GetCookies(url_google));
    878 }
    879 
    880 TEST(CookieMonsterTest, TestCookieDeleteAll) {
    881   GURL url_google(kUrlGoogle);
    882   scoped_refptr<MockPersistentCookieStore> store(
    883       new MockPersistentCookieStore);
    884   scoped_refptr<CookieMonster> cm(new CookieMonster(store, NULL));
    885   CookieOptions options;
    886   options.set_include_httponly();
    887 
    888   EXPECT_TRUE(cm->SetCookie(url_google, kValidCookieLine));
    889   EXPECT_EQ("A=B", cm->GetCookies(url_google));
    890 
    891   EXPECT_TRUE(cm->SetCookieWithOptions(url_google, "C=D; httponly", options));
    892   EXPECT_EQ("A=B; C=D", cm->GetCookiesWithOptions(url_google, options));
    893 
    894   EXPECT_EQ(2, cm->DeleteAll(false));
    895   EXPECT_EQ("", cm->GetCookiesWithOptions(url_google, options));
    896 
    897   EXPECT_EQ(0u, store->commands().size());
    898 
    899   // Create a persistent cookie.
    900   EXPECT_TRUE(cm->SetCookie(url_google,
    901                             std::string(kValidCookieLine) +
    902                             "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
    903   ASSERT_EQ(1u, store->commands().size());
    904   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
    905 
    906   EXPECT_EQ(1, cm->DeleteAll(true));  // sync_to_store = true.
    907   ASSERT_EQ(2u, store->commands().size());
    908   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
    909 
    910   EXPECT_EQ("", cm->GetCookiesWithOptions(url_google, options));
    911 }
    912 
    913 TEST(CookieMonsterTest, TestCookieDeleteAllCreatedAfterTimestamp) {
    914   GURL url_google(kUrlGoogle);
    915   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    916   Time now = Time::Now();
    917 
    918   // Nothing has been added so nothing should be deleted.
    919   EXPECT_EQ(0, cm->DeleteAllCreatedAfter(now - TimeDelta::FromDays(99), false));
    920 
    921   // Create 3 cookies with creation date of today, yesterday and the day before.
    922   EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google, "T-0=Now", now));
    923   EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google, "T-1=Yesterday",
    924                                            now - TimeDelta::FromDays(1)));
    925   EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google, "T-2=DayBefore",
    926                                            now - TimeDelta::FromDays(2)));
    927 
    928   // Try to delete everything from now onwards.
    929   EXPECT_EQ(1, cm->DeleteAllCreatedAfter(now, false));
    930   // Now delete the one cookie created in the last day.
    931   EXPECT_EQ(1, cm->DeleteAllCreatedAfter(now - TimeDelta::FromDays(1), false));
    932   // Now effectively delete all cookies just created (1 is remaining).
    933   EXPECT_EQ(1, cm->DeleteAllCreatedAfter(now - TimeDelta::FromDays(99), false));
    934 
    935   // Make sure everything is gone.
    936   EXPECT_EQ(0, cm->DeleteAllCreatedAfter(Time(), false));
    937   // Really make sure everything is gone.
    938   EXPECT_EQ(0, cm->DeleteAll(false));
    939 }
    940 
    941 TEST(CookieMonsterTest, TestCookieDeleteAllCreatedBetweenTimestamps) {
    942   GURL url_google(kUrlGoogle);
    943   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    944   Time now = Time::Now();
    945 
    946   // Nothing has been added so nothing should be deleted.
    947   EXPECT_EQ(0, cm->DeleteAllCreatedAfter(now - TimeDelta::FromDays(99), false));
    948 
    949   // Create 3 cookies with creation date of today, yesterday and the day before.
    950   EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google, "T-0=Now", now));
    951   EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google, "T-1=Yesterday",
    952                                            now - TimeDelta::FromDays(1)));
    953   EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google, "T-2=DayBefore",
    954                                            now - TimeDelta::FromDays(2)));
    955   EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google, "T-3=ThreeDays",
    956                                            now - TimeDelta::FromDays(3)));
    957   EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google, "T-7=LastWeek",
    958                                            now - TimeDelta::FromDays(7)));
    959 
    960   // Try to delete threedays and the daybefore.
    961   EXPECT_EQ(2, cm->DeleteAllCreatedBetween(now - TimeDelta::FromDays(3),
    962                                           now - TimeDelta::FromDays(1),
    963                                           false));
    964 
    965   // Try to delete yesterday, also make sure that delete_end is not
    966   // inclusive.
    967   EXPECT_EQ(1, cm->DeleteAllCreatedBetween(now - TimeDelta::FromDays(2),
    968                                           now,
    969                                           false));
    970 
    971   // Make sure the delete_begin is inclusive.
    972   EXPECT_EQ(1, cm->DeleteAllCreatedBetween(now - TimeDelta::FromDays(7),
    973                                           now,
    974                                           false));
    975 
    976   // Delete the last (now) item.
    977   EXPECT_EQ(1, cm->DeleteAllCreatedAfter(Time(), false));
    978 
    979   // Really make sure everything is gone.
    980   EXPECT_EQ(0, cm->DeleteAll(false));
    981 }
    982 
    983 TEST(CookieMonsterTest, TestSecure) {
    984   GURL url_google(kUrlGoogle);
    985   GURL url_google_secure(kUrlGoogleSecure);
    986   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
    987 
    988   EXPECT_TRUE(cm->SetCookie(url_google, "A=B"));
    989   EXPECT_EQ("A=B", cm->GetCookies(url_google));
    990   EXPECT_EQ("A=B", cm->GetCookies(url_google_secure));
    991 
    992   EXPECT_TRUE(cm->SetCookie(url_google_secure, "A=B; secure"));
    993   // The secure should overwrite the non-secure.
    994   EXPECT_EQ("", cm->GetCookies(url_google));
    995   EXPECT_EQ("A=B", cm->GetCookies(url_google_secure));
    996 
    997   EXPECT_TRUE(cm->SetCookie(url_google_secure, "D=E; secure"));
    998   EXPECT_EQ("", cm->GetCookies(url_google));
    999   EXPECT_EQ("A=B; D=E", cm->GetCookies(url_google_secure));
   1000 
   1001   EXPECT_TRUE(cm->SetCookie(url_google_secure, "A=B"));
   1002   // The non-secure should overwrite the secure.
   1003   EXPECT_EQ("A=B", cm->GetCookies(url_google));
   1004   EXPECT_EQ("D=E; A=B", cm->GetCookies(url_google_secure));
   1005 }
   1006 
   1007 static Time GetFirstCookieAccessDate(CookieMonster* cm) {
   1008   const CookieList all_cookies(cm->GetAllCookies());
   1009   return all_cookies.front().LastAccessDate();
   1010 }
   1011 
   1012 static const int kLastAccessThresholdMilliseconds = 200;
   1013 
   1014 TEST(CookieMonsterTest, TestLastAccess) {
   1015   GURL url_google(kUrlGoogle);
   1016   scoped_refptr<CookieMonster> cm(
   1017       new CookieMonster(NULL, NULL, kLastAccessThresholdMilliseconds));
   1018 
   1019   EXPECT_TRUE(cm->SetCookie(url_google, "A=B"));
   1020   const Time last_access_date(GetFirstCookieAccessDate(cm));
   1021 
   1022   // Reading the cookie again immediately shouldn't update the access date,
   1023   // since we're inside the threshold.
   1024   EXPECT_EQ("A=B", cm->GetCookies(url_google));
   1025   EXPECT_TRUE(last_access_date == GetFirstCookieAccessDate(cm));
   1026 
   1027   // Reading after a short wait should update the access date.
   1028   base::PlatformThread::Sleep(kLastAccessThresholdMilliseconds + 20);
   1029   EXPECT_EQ("A=B", cm->GetCookies(url_google));
   1030   EXPECT_FALSE(last_access_date == GetFirstCookieAccessDate(cm));
   1031 }
   1032 
   1033 static int CountInString(const std::string& str, char c) {
   1034   return std::count(str.begin(), str.end(), c);
   1035 }
   1036 
   1037 static void TestHostGarbageCollectHelper(
   1038     int domain_max_cookies,
   1039     int domain_purge_cookies,
   1040     CookieMonster::ExpiryAndKeyScheme key_scheme) {
   1041   GURL url_google(kUrlGoogle);
   1042   const int more_than_enough_cookies =
   1043       (domain_max_cookies + domain_purge_cookies) * 2;
   1044   // Add a bunch of cookies on a single host, should purge them.
   1045   {
   1046     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1047     cm->SetExpiryAndKeyScheme(key_scheme);
   1048     for (int i = 0; i < more_than_enough_cookies; ++i) {
   1049       std::string cookie = base::StringPrintf("a%03d=b", i);
   1050       EXPECT_TRUE(cm->SetCookie(url_google, cookie));
   1051       std::string cookies = cm->GetCookies(url_google);
   1052       // Make sure we find it in the cookies.
   1053       EXPECT_NE(cookies.find(cookie), std::string::npos);
   1054       // Count the number of cookies.
   1055       EXPECT_LE(CountInString(cookies, '='), domain_max_cookies);
   1056     }
   1057   }
   1058 
   1059   // Add a bunch of cookies on multiple hosts within a single eTLD.
   1060   // Should keep at least kDomainMaxCookies - kDomainPurgeCookies
   1061   // between them.  If we are using the effective domain keying system
   1062   // (EKS_KEEP_RECENT_AND_PURGE_ETLDP1) we shouldn't go above
   1063   // kDomainMaxCookies for both together.  If we're using the domain
   1064   // keying system (EKS_DISCARD_RECENT_AND_PURGE_DOMAIN), each
   1065   // individual domain shouldn't go above kDomainMaxCookies.
   1066   GURL url_google_specific(kUrlGoogleSpecific);
   1067   {
   1068     scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1069     cm->SetExpiryAndKeyScheme(key_scheme);
   1070     for (int i = 0; i < more_than_enough_cookies; ++i) {
   1071       std::string cookie_general = base::StringPrintf("a%03d=b", i);
   1072       EXPECT_TRUE(cm->SetCookie(url_google, cookie_general));
   1073       std::string cookie_specific = base::StringPrintf("c%03d=b", i);
   1074       EXPECT_TRUE(cm->SetCookie(url_google_specific, cookie_specific));
   1075       std::string cookies_general = cm->GetCookies(url_google);
   1076       EXPECT_NE(cookies_general.find(cookie_general), std::string::npos);
   1077       std::string cookies_specific = cm->GetCookies(url_google_specific);
   1078       EXPECT_NE(cookies_specific.find(cookie_specific), std::string::npos);
   1079       if (key_scheme == CookieMonster::EKS_KEEP_RECENT_AND_PURGE_ETLDP1) {
   1080         EXPECT_LE((CountInString(cookies_general, '=') +
   1081                    CountInString(cookies_specific, '=')),
   1082                   domain_max_cookies);
   1083       } else {
   1084         EXPECT_LE(CountInString(cookies_general, '='), domain_max_cookies);
   1085         EXPECT_LE(CountInString(cookies_specific, '='), domain_max_cookies);
   1086       }
   1087     }
   1088     // After all this, there should be at least
   1089     // kDomainMaxCookies - kDomainPurgeCookies for both URLs.
   1090     std::string cookies_general = cm->GetCookies(url_google);
   1091     std::string cookies_specific = cm->GetCookies(url_google_specific);
   1092     if (key_scheme == CookieMonster::EKS_KEEP_RECENT_AND_PURGE_ETLDP1) {
   1093       int total_cookies = (CountInString(cookies_general, '=') +
   1094                            CountInString(cookies_specific, '='));
   1095       EXPECT_GE(total_cookies,
   1096                 domain_max_cookies - domain_purge_cookies);
   1097       EXPECT_LE(total_cookies, domain_max_cookies);
   1098     } else {
   1099       int general_cookies = CountInString(cookies_general, '=');
   1100       int specific_cookies = CountInString(cookies_specific, '=');
   1101       EXPECT_GE(general_cookies,
   1102                 domain_max_cookies - domain_purge_cookies);
   1103       EXPECT_LE(general_cookies, domain_max_cookies);
   1104       EXPECT_GE(specific_cookies,
   1105                 domain_max_cookies - domain_purge_cookies);
   1106       EXPECT_LE(specific_cookies, domain_max_cookies);
   1107     }
   1108   }
   1109 }
   1110 
   1111 TEST(CookieMonsterTest, TestHostGarbageCollection) {
   1112   TestHostGarbageCollectHelper(
   1113       CookieMonster::kDomainMaxCookies, CookieMonster::kDomainPurgeCookies,
   1114       CookieMonster::EKS_KEEP_RECENT_AND_PURGE_ETLDP1);
   1115   TestHostGarbageCollectHelper(
   1116       CookieMonster::kDomainMaxCookies, CookieMonster::kDomainPurgeCookies,
   1117       CookieMonster::EKS_DISCARD_RECENT_AND_PURGE_DOMAIN);
   1118 }
   1119 
   1120 // Formerly NetUtilTest.CookieTest back when we used wininet's cookie handling.
   1121 TEST(CookieMonsterTest, NetUtilCookieTest) {
   1122   const GURL test_url("http://mojo.jojo.google.izzle/");
   1123 
   1124   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1125 
   1126   EXPECT_TRUE(cm->SetCookie(test_url, "foo=bar"));
   1127   std::string value = cm->GetCookies(test_url);
   1128   EXPECT_EQ("foo=bar", value);
   1129 
   1130   // test that we can retrieve all cookies:
   1131   EXPECT_TRUE(cm->SetCookie(test_url, "x=1"));
   1132   EXPECT_TRUE(cm->SetCookie(test_url, "y=2"));
   1133 
   1134   std::string result = cm->GetCookies(test_url);
   1135   EXPECT_FALSE(result.empty());
   1136   EXPECT_NE(result.find("x=1"), std::string::npos) << result;
   1137   EXPECT_NE(result.find("y=2"), std::string::npos) << result;
   1138 }
   1139 
   1140 static bool FindAndDeleteCookie(CookieMonster* cm,
   1141                                 const std::string& domain,
   1142                                 const std::string& name) {
   1143   CookieList cookies = cm->GetAllCookies();
   1144   for (CookieList::iterator it = cookies.begin();
   1145        it != cookies.end(); ++it)
   1146     if (it->Domain() == domain && it->Name() == name)
   1147       return cm->DeleteCanonicalCookie(*it);
   1148   return false;
   1149 }
   1150 
   1151 TEST(CookieMonsterTest, TestDeleteSingleCookie) {
   1152   GURL url_google(kUrlGoogle);
   1153 
   1154   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1155 
   1156   EXPECT_TRUE(cm->SetCookie(url_google, "A=B"));
   1157   EXPECT_TRUE(cm->SetCookie(url_google, "C=D"));
   1158   EXPECT_TRUE(cm->SetCookie(url_google, "E=F"));
   1159   EXPECT_EQ("A=B; C=D; E=F", cm->GetCookies(url_google));
   1160 
   1161   EXPECT_TRUE(FindAndDeleteCookie(cm, url_google.host(), "C"));
   1162   EXPECT_EQ("A=B; E=F", cm->GetCookies(url_google));
   1163 
   1164   EXPECT_FALSE(FindAndDeleteCookie(cm, "random.host", "E"));
   1165   EXPECT_EQ("A=B; E=F", cm->GetCookies(url_google));
   1166 }
   1167 
   1168 TEST(CookieMonsterTest, SetCookieableSchemes) {
   1169   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1170   scoped_refptr<CookieMonster> cm_foo(new CookieMonster(NULL, NULL));
   1171 
   1172   // Only cm_foo should allow foo:// cookies.
   1173   const char* kSchemes[] = {"foo"};
   1174   cm_foo->SetCookieableSchemes(kSchemes, 1);
   1175 
   1176   GURL foo_url("foo://host/path");
   1177   GURL http_url("http://host/path");
   1178 
   1179   EXPECT_TRUE(cm->SetCookie(http_url, "x=1"));
   1180   EXPECT_FALSE(cm->SetCookie(foo_url, "x=1"));
   1181   EXPECT_TRUE(cm_foo->SetCookie(foo_url, "x=1"));
   1182   EXPECT_FALSE(cm_foo->SetCookie(http_url, "x=1"));
   1183 }
   1184 
   1185 TEST(CookieMonsterTest, GetAllCookiesForURL) {
   1186   GURL url_google(kUrlGoogle);
   1187   GURL url_google_secure(kUrlGoogleSecure);
   1188 
   1189   scoped_refptr<CookieMonster> cm(
   1190       new CookieMonster(NULL, NULL, kLastAccessThresholdMilliseconds));
   1191 
   1192   // Create an httponly cookie.
   1193   CookieOptions options;
   1194   options.set_include_httponly();
   1195 
   1196   EXPECT_TRUE(cm->SetCookieWithOptions(url_google, "A=B; httponly", options));
   1197   EXPECT_TRUE(cm->SetCookieWithOptions(url_google,
   1198                                        "C=D; domain=.google.izzle",
   1199                                        options));
   1200   EXPECT_TRUE(cm->SetCookieWithOptions(url_google_secure,
   1201                                        "E=F; domain=.google.izzle; secure",
   1202                                        options));
   1203 
   1204   const Time last_access_date(GetFirstCookieAccessDate(cm));
   1205 
   1206   base::PlatformThread::Sleep(kLastAccessThresholdMilliseconds + 20);
   1207 
   1208   // Check cookies for url.
   1209   CookieList cookies = cm->GetAllCookiesForURL(url_google);
   1210   CookieList::iterator it = cookies.begin();
   1211 
   1212   ASSERT_TRUE(it != cookies.end());
   1213   EXPECT_EQ("www.google.izzle", it->Domain());
   1214   EXPECT_EQ("A", it->Name());
   1215 
   1216   ASSERT_TRUE(++it != cookies.end());
   1217   EXPECT_EQ(".google.izzle", it->Domain());
   1218   EXPECT_EQ("C", it->Name());
   1219 
   1220   ASSERT_TRUE(++it == cookies.end());
   1221 
   1222   // Check cookies for url excluding http-only cookies.
   1223   cookies =
   1224       cm->GetAllCookiesForURLWithOptions(url_google, CookieOptions());
   1225   it = cookies.begin();
   1226 
   1227   ASSERT_TRUE(it != cookies.end());
   1228   EXPECT_EQ(".google.izzle", it->Domain());
   1229   EXPECT_EQ("C", it->Name());
   1230 
   1231   ASSERT_TRUE(++it == cookies.end());
   1232 
   1233   // Test secure cookies.
   1234   cookies = cm->GetAllCookiesForURL(url_google_secure);
   1235   it = cookies.begin();
   1236 
   1237   ASSERT_TRUE(it != cookies.end());
   1238   EXPECT_EQ("www.google.izzle", it->Domain());
   1239   EXPECT_EQ("A", it->Name());
   1240 
   1241   ASSERT_TRUE(++it != cookies.end());
   1242   EXPECT_EQ(".google.izzle", it->Domain());
   1243   EXPECT_EQ("C", it->Name());
   1244 
   1245   ASSERT_TRUE(++it != cookies.end());
   1246   EXPECT_EQ(".google.izzle", it->Domain());
   1247   EXPECT_EQ("E", it->Name());
   1248 
   1249   ASSERT_TRUE(++it == cookies.end());
   1250 
   1251   // Reading after a short wait should not update the access date.
   1252   EXPECT_TRUE(last_access_date == GetFirstCookieAccessDate(cm));
   1253 }
   1254 
   1255 TEST(CookieMonsterTest, GetAllCookiesForURLPathMatching) {
   1256   GURL url_google(kUrlGoogle);
   1257   GURL url_google_foo("http://www.google.izzle/foo");
   1258   GURL url_google_bar("http://www.google.izzle/bar");
   1259 
   1260   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1261   CookieOptions options;
   1262 
   1263   EXPECT_TRUE(cm->SetCookieWithOptions(url_google_foo,
   1264                                        "A=B; path=/foo;",
   1265                                        options));
   1266   EXPECT_TRUE(cm->SetCookieWithOptions(url_google_bar,
   1267                                        "C=D; path=/bar;",
   1268                                        options));
   1269   EXPECT_TRUE(cm->SetCookieWithOptions(url_google,
   1270                                        "E=F;",
   1271                                        options));
   1272 
   1273   CookieList cookies = cm->GetAllCookiesForURL(url_google_foo);
   1274   CookieList::iterator it = cookies.begin();
   1275 
   1276   ASSERT_TRUE(it != cookies.end());
   1277   EXPECT_EQ("A", it->Name());
   1278   EXPECT_EQ("/foo", it->Path());
   1279 
   1280   ASSERT_TRUE(++it != cookies.end());
   1281   EXPECT_EQ("E", it->Name());
   1282   EXPECT_EQ("/", it->Path());
   1283 
   1284   ASSERT_TRUE(++it == cookies.end());
   1285 
   1286   cookies = cm->GetAllCookiesForURL(url_google_bar);
   1287   it = cookies.begin();
   1288 
   1289   ASSERT_TRUE(it != cookies.end());
   1290   EXPECT_EQ("C", it->Name());
   1291   EXPECT_EQ("/bar", it->Path());
   1292 
   1293   ASSERT_TRUE(++it != cookies.end());
   1294   EXPECT_EQ("E", it->Name());
   1295   EXPECT_EQ("/", it->Path());
   1296 
   1297   ASSERT_TRUE(++it == cookies.end());
   1298 }
   1299 
   1300 TEST(CookieMonsterTest, DeleteCookieByName) {
   1301   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1302   GURL url_google(kUrlGoogle);
   1303 
   1304   EXPECT_TRUE(cm->SetCookie(url_google, "A=A1; path=/"));
   1305   EXPECT_TRUE(cm->SetCookie(url_google, "A=A2; path=/foo"));
   1306   EXPECT_TRUE(cm->SetCookie(url_google, "A=A3; path=/bar"));
   1307   EXPECT_TRUE(cm->SetCookie(url_google, "B=B1; path=/"));
   1308   EXPECT_TRUE(cm->SetCookie(url_google, "B=B2; path=/foo"));
   1309   EXPECT_TRUE(cm->SetCookie(url_google, "B=B3; path=/bar"));
   1310 
   1311   cm->DeleteCookie(GURL(std::string(kUrlGoogle) + "/foo/bar"), "A");
   1312 
   1313   CookieList cookies = cm->GetAllCookies();
   1314   size_t expected_size = 4;
   1315   EXPECT_EQ(expected_size, cookies.size());
   1316   for (CookieList::iterator it = cookies.begin();
   1317        it != cookies.end(); ++it) {
   1318     EXPECT_NE("A1", it->Value());
   1319     EXPECT_NE("A2", it->Value());
   1320   }
   1321 }
   1322 
   1323 // Test that overwriting persistent cookies deletes the old one from the
   1324 // backing store.
   1325 TEST(CookieMonsterTest, OverwritePersistentCookie) {
   1326   GURL url_google("http://www.google.com/");
   1327   GURL url_chromium("http://chromium.org");
   1328   scoped_refptr<MockPersistentCookieStore> store(
   1329       new MockPersistentCookieStore);
   1330   scoped_refptr<CookieMonster> cm(new CookieMonster(store, NULL));
   1331 
   1332   // Insert a cookie "a" for path "/path1"
   1333   EXPECT_TRUE(
   1334       cm->SetCookie(url_google, "a=val1; path=/path1; "
   1335                                 "expires=Mon, 18-Apr-22 22:50:13 GMT"));
   1336   ASSERT_EQ(1u, store->commands().size());
   1337   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
   1338 
   1339   // Insert a cookie "b" for path "/path1"
   1340   EXPECT_TRUE(
   1341       cm->SetCookie(url_google, "b=val1; path=/path1; "
   1342                                 "expires=Mon, 18-Apr-22 22:50:14 GMT"));
   1343   ASSERT_EQ(2u, store->commands().size());
   1344   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[1].type);
   1345 
   1346   // Insert a cookie "b" for path "/path1", that is httponly. This should
   1347   // overwrite the non-http-only version.
   1348   CookieOptions allow_httponly;
   1349   allow_httponly.set_include_httponly();
   1350   EXPECT_TRUE(
   1351     cm->SetCookieWithOptions(url_google,
   1352                              "b=val2; path=/path1; httponly; "
   1353                              "expires=Mon, 18-Apr-22 22:50:14 GMT",
   1354                              allow_httponly));
   1355   ASSERT_EQ(4u, store->commands().size());
   1356   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[2].type);
   1357   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[3].type);
   1358 
   1359   // Insert a cookie "a" for path "/path1". This should overwrite.
   1360   EXPECT_TRUE(cm->SetCookie(url_google,
   1361                             "a=val33; path=/path1; "
   1362                             "expires=Mon, 18-Apr-22 22:50:14 GMT"));
   1363   ASSERT_EQ(6u, store->commands().size());
   1364   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[4].type);
   1365   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[5].type);
   1366 
   1367   // Insert a cookie "a" for path "/path2". This should NOT overwrite
   1368   // cookie "a", since the path is different.
   1369   EXPECT_TRUE(cm->SetCookie(url_google,
   1370                             "a=val9; path=/path2; "
   1371                             "expires=Mon, 18-Apr-22 22:50:14 GMT"));
   1372   ASSERT_EQ(7u, store->commands().size());
   1373   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[6].type);
   1374 
   1375   // Insert a cookie "a" for path "/path1", but this time for "chromium.org".
   1376   // Although the name and path match, the hostnames do not, so shouldn't
   1377   // overwrite.
   1378   EXPECT_TRUE(cm->SetCookie(url_chromium,
   1379                             "a=val99; path=/path1; "
   1380                             "expires=Mon, 18-Apr-22 22:50:14 GMT"));
   1381   ASSERT_EQ(8u, store->commands().size());
   1382   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[7].type);
   1383 
   1384   EXPECT_EQ("a=val33", cm->GetCookies(GURL("http://www.google.com/path1")));
   1385   EXPECT_EQ("a=val9", cm->GetCookies(GURL("http://www.google.com/path2")));
   1386   EXPECT_EQ("a=val99", cm->GetCookies(GURL("http://chromium.org/path1")));
   1387 }
   1388 
   1389 // Tests importing from a persistent cookie store that contains duplicate
   1390 // equivalent cookies. This situation should be handled by removing the
   1391 // duplicate cookie (both from the in-memory cache, and from the backing store).
   1392 //
   1393 // This is a regression test for: http://crbug.com/17855.
   1394 TEST(CookieMonsterTest, DontImportDuplicateCookies) {
   1395   GURL url_google("http://www.google.com/");
   1396 
   1397   scoped_refptr<MockPersistentCookieStore> store(
   1398       new MockPersistentCookieStore);
   1399 
   1400   // We will fill some initial cookies into the PersistentCookieStore,
   1401   // to simulate a database with 4 duplicates.  Note that we need to
   1402   // be careful not to have any duplicate creation times at all (as it's a
   1403   // violation of a CookieMonster invariant) even if Time::Now() doesn't
   1404   // move between calls.
   1405   std::vector<CookieMonster::CanonicalCookie*> initial_cookies;
   1406 
   1407   // Insert 4 cookies with name "X" on path "/", with varying creation
   1408   // dates. We expect only the most recent one to be preserved following
   1409   // the import.
   1410 
   1411   AddCookieToList("www.google.com",
   1412                   "X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
   1413                   Time::Now() + TimeDelta::FromDays(3),
   1414                   &initial_cookies);
   1415 
   1416   AddCookieToList("www.google.com",
   1417                   "X=2; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
   1418                   Time::Now() + TimeDelta::FromDays(1),
   1419                   &initial_cookies);
   1420 
   1421   // ===> This one is the WINNER (biggest creation time).  <====
   1422   AddCookieToList("www.google.com",
   1423                   "X=3; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
   1424                   Time::Now() + TimeDelta::FromDays(4),
   1425                   &initial_cookies);
   1426 
   1427   AddCookieToList("www.google.com",
   1428                   "X=4; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
   1429                   Time::Now(),
   1430                   &initial_cookies);
   1431 
   1432   // Insert 2 cookies with name "X" on path "/2", with varying creation
   1433   // dates. We expect only the most recent one to be preserved the import.
   1434 
   1435   // ===> This one is the WINNER (biggest creation time).  <====
   1436   AddCookieToList("www.google.com",
   1437                   "X=a1; path=/2; expires=Mon, 18-Apr-22 22:50:14 GMT",
   1438                   Time::Now() + TimeDelta::FromDays(9),
   1439                   &initial_cookies);
   1440 
   1441   AddCookieToList("www.google.com",
   1442                   "X=a2; path=/2; expires=Mon, 18-Apr-22 22:50:14 GMT",
   1443                   Time::Now() + TimeDelta::FromDays(2),
   1444                   &initial_cookies);
   1445 
   1446   // Insert 1 cookie with name "Y" on path "/".
   1447   AddCookieToList("www.google.com",
   1448                   "Y=a; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
   1449                   Time::Now() + TimeDelta::FromDays(10),
   1450                   &initial_cookies);
   1451 
   1452   // Inject our initial cookies into the mock PersistentCookieStore.
   1453   store->SetLoadExpectation(true, initial_cookies);
   1454 
   1455   scoped_refptr<CookieMonster> cm(new CookieMonster(store, NULL));
   1456 
   1457   // Verify that duplicates were not imported for path "/".
   1458   // (If this had failed, GetCookies() would have also returned X=1, X=2, X=4).
   1459   EXPECT_EQ("X=3; Y=a", cm->GetCookies(GURL("http://www.google.com/")));
   1460 
   1461   // Verify that same-named cookie on a different path ("/x2") didn't get
   1462   // messed up.
   1463   EXPECT_EQ("X=a1; X=3; Y=a",
   1464             cm->GetCookies(GURL("http://www.google.com/2/x")));
   1465 
   1466   // Verify that the PersistentCookieStore was told to kill its 4 duplicates.
   1467   ASSERT_EQ(4u, store->commands().size());
   1468   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[0].type);
   1469   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
   1470   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[2].type);
   1471   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[3].type);
   1472 }
   1473 
   1474 // Tests importing from a persistent cookie store that contains cookies
   1475 // with duplicate creation times.  This situation should be handled by
   1476 // dropping the cookies before insertion/visibility to user.
   1477 //
   1478 // This is a regression test for: http://crbug.com/43188.
   1479 TEST(CookieMonsterTest, DontImportDuplicateCreationTimes) {
   1480   GURL url_google("http://www.google.com/");
   1481 
   1482   scoped_refptr<MockPersistentCookieStore> store(
   1483       new MockPersistentCookieStore);
   1484 
   1485   Time now(Time::Now());
   1486   Time earlier(now - TimeDelta::FromDays(1));
   1487 
   1488   // Insert 8 cookies, four with the current time as creation times, and
   1489   // four with the earlier time as creation times.  We should only get
   1490   // two cookies remaining, but which two (other than that there should
   1491   // be one from each set) will be random.
   1492   std::vector<CookieMonster::CanonicalCookie*> initial_cookies;
   1493   AddCookieToList("www.google.com", "X=1; path=/", now, &initial_cookies);
   1494   AddCookieToList("www.google.com", "X=2; path=/", now, &initial_cookies);
   1495   AddCookieToList("www.google.com", "X=3; path=/", now, &initial_cookies);
   1496   AddCookieToList("www.google.com", "X=4; path=/", now, &initial_cookies);
   1497 
   1498   AddCookieToList("www.google.com", "Y=1; path=/", earlier, &initial_cookies);
   1499   AddCookieToList("www.google.com", "Y=2; path=/", earlier, &initial_cookies);
   1500   AddCookieToList("www.google.com", "Y=3; path=/", earlier, &initial_cookies);
   1501   AddCookieToList("www.google.com", "Y=4; path=/", earlier, &initial_cookies);
   1502 
   1503   // Inject our initial cookies into the mock PersistentCookieStore.
   1504   store->SetLoadExpectation(true, initial_cookies);
   1505 
   1506   scoped_refptr<CookieMonster> cm(new CookieMonster(store, NULL));
   1507 
   1508   CookieList list(cm->GetAllCookies());
   1509   EXPECT_EQ(2U, list.size());
   1510   // Confirm that we have one of each.
   1511   std::string name1(list[0].Name());
   1512   std::string name2(list[1].Name());
   1513   EXPECT_TRUE(name1 == "X" || name2 == "X");
   1514   EXPECT_TRUE(name1 == "Y" || name2 == "Y");
   1515   EXPECT_NE(name1, name2);
   1516 }
   1517 
   1518 TEST(CookieMonsterTest, Delegate) {
   1519   GURL url_google(kUrlGoogle);
   1520 
   1521   scoped_refptr<MockPersistentCookieStore> store(
   1522       new MockPersistentCookieStore);
   1523   scoped_refptr<MockCookieMonsterDelegate> delegate(
   1524       new MockCookieMonsterDelegate);
   1525   scoped_refptr<CookieMonster> cm(new CookieMonster(store, delegate));
   1526 
   1527   EXPECT_TRUE(cm->SetCookie(url_google, "A=B"));
   1528   EXPECT_TRUE(cm->SetCookie(url_google, "C=D"));
   1529   EXPECT_TRUE(cm->SetCookie(url_google, "E=F"));
   1530   EXPECT_EQ("A=B; C=D; E=F", cm->GetCookies(url_google));
   1531   ASSERT_EQ(3u, delegate->changes().size());
   1532   EXPECT_FALSE(delegate->changes()[0].second);
   1533   EXPECT_EQ(url_google.host(), delegate->changes()[0].first.Domain());
   1534   EXPECT_EQ("A", delegate->changes()[0].first.Name());
   1535   EXPECT_EQ("B", delegate->changes()[0].first.Value());
   1536   EXPECT_EQ(url_google.host(), delegate->changes()[1].first.Domain());
   1537   EXPECT_FALSE(delegate->changes()[1].second);
   1538   EXPECT_EQ("C", delegate->changes()[1].first.Name());
   1539   EXPECT_EQ("D", delegate->changes()[1].first.Value());
   1540   EXPECT_EQ(url_google.host(), delegate->changes()[2].first.Domain());
   1541   EXPECT_FALSE(delegate->changes()[2].second);
   1542   EXPECT_EQ("E", delegate->changes()[2].first.Name());
   1543   EXPECT_EQ("F", delegate->changes()[2].first.Value());
   1544   delegate->reset();
   1545 
   1546   EXPECT_TRUE(FindAndDeleteCookie(cm, url_google.host(), "C"));
   1547   EXPECT_EQ("A=B; E=F", cm->GetCookies(url_google));
   1548   ASSERT_EQ(1u, delegate->changes().size());
   1549   EXPECT_EQ(url_google.host(), delegate->changes()[0].first.Domain());
   1550   EXPECT_TRUE(delegate->changes()[0].second);
   1551   EXPECT_EQ("C", delegate->changes()[0].first.Name());
   1552   EXPECT_EQ("D", delegate->changes()[0].first.Value());
   1553   delegate->reset();
   1554 
   1555   EXPECT_FALSE(FindAndDeleteCookie(cm, "random.host", "E"));
   1556   EXPECT_EQ("A=B; E=F", cm->GetCookies(url_google));
   1557   EXPECT_EQ(0u, delegate->changes().size());
   1558 
   1559   // Insert a cookie "a" for path "/path1"
   1560   EXPECT_TRUE(
   1561       cm->SetCookie(url_google, "a=val1; path=/path1; "
   1562                                 "expires=Mon, 18-Apr-22 22:50:13 GMT"));
   1563   ASSERT_EQ(1u, store->commands().size());
   1564   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
   1565   ASSERT_EQ(1u, delegate->changes().size());
   1566   EXPECT_FALSE(delegate->changes()[0].second);
   1567   EXPECT_EQ(url_google.host(), delegate->changes()[0].first.Domain());
   1568   EXPECT_EQ("a", delegate->changes()[0].first.Name());
   1569   EXPECT_EQ("val1", delegate->changes()[0].first.Value());
   1570   delegate->reset();
   1571 
   1572   // Insert a cookie "a" for path "/path1", that is httponly. This should
   1573   // overwrite the non-http-only version.
   1574   CookieOptions allow_httponly;
   1575   allow_httponly.set_include_httponly();
   1576   EXPECT_TRUE(
   1577     cm->SetCookieWithOptions(url_google,
   1578                              "a=val2; path=/path1; httponly; "
   1579                              "expires=Mon, 18-Apr-22 22:50:14 GMT",
   1580                              allow_httponly));
   1581   ASSERT_EQ(3u, store->commands().size());
   1582   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
   1583   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[2].type);
   1584   ASSERT_EQ(2u, delegate->changes().size());
   1585   EXPECT_EQ(url_google.host(), delegate->changes()[0].first.Domain());
   1586   EXPECT_TRUE(delegate->changes()[0].second);
   1587   EXPECT_EQ("a", delegate->changes()[0].first.Name());
   1588   EXPECT_EQ("val1", delegate->changes()[0].first.Value());
   1589   EXPECT_EQ(url_google.host(), delegate->changes()[1].first.Domain());
   1590   EXPECT_FALSE(delegate->changes()[1].second);
   1591   EXPECT_EQ("a", delegate->changes()[1].first.Name());
   1592   EXPECT_EQ("val2", delegate->changes()[1].first.Value());
   1593   delegate->reset();
   1594 }
   1595 
   1596 TEST(CookieMonsterTest, SetCookieWithDetails) {
   1597   GURL url_google(kUrlGoogle);
   1598   GURL url_google_foo("http://www.google.izzle/foo");
   1599   GURL url_google_bar("http://www.google.izzle/bar");
   1600   GURL url_google_secure(kUrlGoogleSecure);
   1601 
   1602   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1603 
   1604   EXPECT_TRUE(cm->SetCookieWithDetails(
   1605       url_google_foo, "A", "B", std::string(), "/foo", base::Time(),
   1606       false, false));
   1607   EXPECT_TRUE(cm->SetCookieWithDetails(
   1608       url_google_bar, "C", "D", "google.izzle", "/bar", base::Time(),
   1609       false, true));
   1610   EXPECT_TRUE(cm->SetCookieWithDetails(
   1611       url_google, "E", "F", std::string(), std::string(), base::Time(),
   1612       true, false));
   1613 
   1614   // Test that malformed attributes fail to set the cookie.
   1615   EXPECT_FALSE(cm->SetCookieWithDetails(
   1616       url_google_foo, " A", "B", std::string(), "/foo", base::Time(),
   1617       false, false));
   1618   EXPECT_FALSE(cm->SetCookieWithDetails(
   1619       url_google_foo, "A;", "B", std::string(), "/foo", base::Time(),
   1620       false, false));
   1621   EXPECT_FALSE(cm->SetCookieWithDetails(
   1622       url_google_foo, "A=", "B", std::string(), "/foo", base::Time(),
   1623       false, false));
   1624   EXPECT_FALSE(cm->SetCookieWithDetails(
   1625       url_google_foo, "A", "B", "google.ozzzzzzle", "foo", base::Time(),
   1626       false, false));
   1627   EXPECT_FALSE(cm->SetCookieWithDetails(
   1628       url_google_foo, "A=", "B", std::string(), "foo", base::Time(),
   1629       false, false));
   1630 
   1631   CookieList cookies = cm->GetAllCookiesForURL(url_google_foo);
   1632   CookieList::iterator it = cookies.begin();
   1633 
   1634   ASSERT_TRUE(it != cookies.end());
   1635   EXPECT_EQ("A", it->Name());
   1636   EXPECT_EQ("B", it->Value());
   1637   EXPECT_EQ("www.google.izzle", it->Domain());
   1638   EXPECT_EQ("/foo", it->Path());
   1639   EXPECT_FALSE(it->DoesExpire());
   1640   EXPECT_FALSE(it->IsSecure());
   1641   EXPECT_FALSE(it->IsHttpOnly());
   1642 
   1643   ASSERT_TRUE(++it == cookies.end());
   1644 
   1645   cookies = cm->GetAllCookiesForURL(url_google_bar);
   1646   it = cookies.begin();
   1647 
   1648   ASSERT_TRUE(it != cookies.end());
   1649   EXPECT_EQ("C", it->Name());
   1650   EXPECT_EQ("D", it->Value());
   1651   EXPECT_EQ(".google.izzle", it->Domain());
   1652   EXPECT_EQ("/bar", it->Path());
   1653   EXPECT_FALSE(it->IsSecure());
   1654   EXPECT_TRUE(it->IsHttpOnly());
   1655 
   1656   ASSERT_TRUE(++it == cookies.end());
   1657 
   1658   cookies = cm->GetAllCookiesForURL(url_google_secure);
   1659   it = cookies.begin();
   1660 
   1661   ASSERT_TRUE(it != cookies.end());
   1662   EXPECT_EQ("E", it->Name());
   1663   EXPECT_EQ("F", it->Value());
   1664   EXPECT_EQ("/", it->Path());
   1665   EXPECT_EQ("www.google.izzle", it->Domain());
   1666   EXPECT_TRUE(it->IsSecure());
   1667   EXPECT_FALSE(it->IsHttpOnly());
   1668 
   1669   ASSERT_TRUE(++it == cookies.end());
   1670 }
   1671 
   1672 TEST(CookieMonsterTest, DeleteAllForHost) {
   1673   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1674 
   1675   // Test probes:
   1676   //    * Non-secure URL, mid-level (http://w.c.b.a)
   1677   //    * Secure URL, mid-level (https://w.c.b.a)
   1678   //    * URL with path, mid-level (https:/w.c.b.a/dir1/xx)
   1679   // All three tests should nuke only the midlevel host cookie,
   1680   // the http_only cookie, the host secure cookie, and the two host
   1681   // path cookies.  http_only, secure, and paths are ignored by
   1682   // this call, and domain cookies arent touched.
   1683   PopulateCmForDeleteAllForHost(cm);
   1684   EXPECT_EQ("dom_1=X; dom_2=X; dom_3=X; host_3=X",
   1685             cm->GetCookies(GURL(kTopLevelDomainPlus3)));
   1686   EXPECT_EQ("dom_1=X; dom_2=X; host_2=X; sec_dom=X; sec_host=X",
   1687             cm->GetCookies(GURL(kTopLevelDomainPlus2Secure)));
   1688   EXPECT_EQ("dom_1=X; host_1=X", cm->GetCookies(GURL(kTopLevelDomainPlus1)));
   1689   EXPECT_EQ("dom_path_2=X; host_path_2=X; dom_path_1=X; host_path_1=X; "
   1690             "dom_1=X; dom_2=X; host_2=X; sec_dom=X; sec_host=X",
   1691             cm->GetCookies(GURL(kTopLevelDomainPlus2Secure +
   1692                                 std::string("/dir1/dir2/xxx"))));
   1693 
   1694   EXPECT_EQ(5, cm->DeleteAllForHost(GURL(kTopLevelDomainPlus2)));
   1695   EXPECT_EQ(8U, cm->GetAllCookies().size());
   1696 
   1697   EXPECT_EQ("dom_1=X; dom_2=X; dom_3=X; host_3=X",
   1698             cm->GetCookies(GURL(kTopLevelDomainPlus3)));
   1699   EXPECT_EQ("dom_1=X; dom_2=X; sec_dom=X",
   1700             cm->GetCookies(GURL(kTopLevelDomainPlus2Secure)));
   1701   EXPECT_EQ("dom_1=X; host_1=X", cm->GetCookies(GURL(kTopLevelDomainPlus1)));
   1702   EXPECT_EQ("dom_path_2=X; dom_path_1=X; dom_1=X; dom_2=X; sec_dom=X",
   1703             cm->GetCookies(GURL(kTopLevelDomainPlus2Secure +
   1704                                 std::string("/dir1/dir2/xxx"))));
   1705 
   1706   PopulateCmForDeleteAllForHost(cm);
   1707   EXPECT_EQ(5, cm->DeleteAllForHost(GURL(kTopLevelDomainPlus2Secure)));
   1708   EXPECT_EQ(8U, cm->GetAllCookies().size());
   1709 
   1710   EXPECT_EQ("dom_1=X; dom_2=X; dom_3=X; host_3=X",
   1711             cm->GetCookies(GURL(kTopLevelDomainPlus3)));
   1712   EXPECT_EQ("dom_1=X; dom_2=X; sec_dom=X",
   1713             cm->GetCookies(GURL(kTopLevelDomainPlus2Secure)));
   1714   EXPECT_EQ("dom_1=X; host_1=X", cm->GetCookies(GURL(kTopLevelDomainPlus1)));
   1715   EXPECT_EQ("dom_path_2=X; dom_path_1=X; dom_1=X; dom_2=X; sec_dom=X",
   1716             cm->GetCookies(GURL(kTopLevelDomainPlus2Secure +
   1717                                 std::string("/dir1/dir2/xxx"))));
   1718 
   1719   PopulateCmForDeleteAllForHost(cm);
   1720   EXPECT_EQ(5, cm->DeleteAllForHost(GURL(kTopLevelDomainPlus2Secure +
   1721                                          std::string("/dir1/xxx"))));
   1722   EXPECT_EQ(8U, cm->GetAllCookies().size());
   1723 
   1724   EXPECT_EQ("dom_1=X; dom_2=X; dom_3=X; host_3=X",
   1725             cm->GetCookies(GURL(kTopLevelDomainPlus3)));
   1726   EXPECT_EQ("dom_1=X; dom_2=X; sec_dom=X",
   1727             cm->GetCookies(GURL(kTopLevelDomainPlus2Secure)));
   1728   EXPECT_EQ("dom_1=X; host_1=X", cm->GetCookies(GURL(kTopLevelDomainPlus1)));
   1729   EXPECT_EQ("dom_path_2=X; dom_path_1=X; dom_1=X; dom_2=X; sec_dom=X",
   1730             cm->GetCookies(GURL(kTopLevelDomainPlus2Secure +
   1731                                 std::string("/dir1/dir2/xxx"))));
   1732 
   1733 }
   1734 
   1735 TEST(CookieMonsterTest, UniqueCreationTime) {
   1736   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1737   GURL url_google(kUrlGoogle);
   1738   CookieOptions options;
   1739 
   1740   // Add in three cookies through every public interface to the
   1741   // CookieMonster and confirm that none of them have duplicate
   1742   // creation times.
   1743 
   1744   // SetCookieWithCreationTime and SetCookieWithCreationTimeAndOptions
   1745   // are not included as they aren't going to be public for very much
   1746   // longer.
   1747 
   1748   // SetCookie, SetCookies, SetCookiesWithOptions,
   1749   // SetCookieWithOptions, SetCookieWithDetails
   1750 
   1751   cm->SetCookie(url_google, "SetCookie1=A");
   1752   cm->SetCookie(url_google, "SetCookie2=A");
   1753   cm->SetCookie(url_google, "SetCookie3=A");
   1754 
   1755   {
   1756     std::vector<std::string> cookie_lines;
   1757     cookie_lines.push_back("setCookies1=A");
   1758     cookie_lines.push_back("setCookies2=A");
   1759     cookie_lines.push_back("setCookies4=A");
   1760     cm->SetCookies(url_google, cookie_lines);
   1761   }
   1762 
   1763   {
   1764     std::vector<std::string> cookie_lines;
   1765     cookie_lines.push_back("setCookiesWithOptions1=A");
   1766     cookie_lines.push_back("setCookiesWithOptions2=A");
   1767     cookie_lines.push_back("setCookiesWithOptions3=A");
   1768 
   1769     cm->SetCookiesWithOptions(url_google, cookie_lines, options);
   1770   }
   1771 
   1772   cm->SetCookieWithOptions(url_google, "setCookieWithOptions1=A", options);
   1773   cm->SetCookieWithOptions(url_google, "setCookieWithOptions2=A", options);
   1774   cm->SetCookieWithOptions(url_google, "setCookieWithOptions3=A", options);
   1775 
   1776   cm->SetCookieWithDetails(url_google, "setCookieWithDetails1", "A",
   1777                            ".google.com", "/", Time(), false, false);
   1778   cm->SetCookieWithDetails(url_google, "setCookieWithDetails2", "A",
   1779                            ".google.com", "/", Time(), false, false);
   1780   cm->SetCookieWithDetails(url_google, "setCookieWithDetails3", "A",
   1781                            ".google.com", "/", Time(), false, false);
   1782 
   1783   // Now we check
   1784   CookieList cookie_list(cm->GetAllCookies());
   1785   typedef std::map<int64, CookieMonster::CanonicalCookie> TimeCookieMap;
   1786   TimeCookieMap check_map;
   1787   for (CookieList::const_iterator it = cookie_list.begin();
   1788        it != cookie_list.end(); it++) {
   1789     const int64 creation_date = it->CreationDate().ToInternalValue();
   1790     TimeCookieMap::const_iterator
   1791         existing_cookie_it(check_map.find(creation_date));
   1792     EXPECT_TRUE(existing_cookie_it == check_map.end())
   1793         << "Cookie " << it->Name() << " has same creation date ("
   1794         << it->CreationDate().ToInternalValue()
   1795         << ") as previously entered cookie "
   1796         << existing_cookie_it->second.Name();
   1797 
   1798     if (existing_cookie_it == check_map.end()) {
   1799       check_map.insert(TimeCookieMap::value_type(
   1800           it->CreationDate().ToInternalValue(), *it));
   1801     }
   1802   }
   1803 }
   1804 
   1805 // Mainly a test of GetEffectiveDomain, or more specifically, of the
   1806 // expected behavior of GetEffectiveDomain within the CookieMonster.
   1807 TEST(CookieMonsterTest, GetKey) {
   1808   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1809 
   1810   // This test is really only interesting if GetKey() actually does something.
   1811   if (cm->expiry_and_key_scheme_ ==
   1812       CookieMonster::EKS_KEEP_RECENT_AND_PURGE_ETLDP1) {
   1813     EXPECT_EQ("google.com", cm->GetKey("www.google.com"));
   1814     EXPECT_EQ("google.izzie", cm->GetKey("www.google.izzie"));
   1815     EXPECT_EQ("google.izzie", cm->GetKey(".google.izzie"));
   1816     EXPECT_EQ("bbc.co.uk", cm->GetKey("bbc.co.uk"));
   1817     EXPECT_EQ("bbc.co.uk", cm->GetKey("a.b.c.d.bbc.co.uk"));
   1818     EXPECT_EQ("apple.com", cm->GetKey("a.b.c.d.apple.com"));
   1819     EXPECT_EQ("apple.izzie", cm->GetKey("a.b.c.d.apple.izzie"));
   1820 
   1821     // Cases where the effective domain is null, so we use the host
   1822     // as the key.
   1823     EXPECT_EQ("co.uk", cm->GetKey("co.uk"));
   1824     const std::string extension_name("iehocdgbbocmkdidlbnnfbmbinnahbae");
   1825     EXPECT_EQ(extension_name, cm->GetKey(extension_name));
   1826     EXPECT_EQ("com", cm->GetKey("com"));
   1827     EXPECT_EQ("hostalias", cm->GetKey("hostalias"));
   1828     EXPECT_EQ("localhost", cm->GetKey("localhost"));
   1829   }
   1830 }
   1831 
   1832 // Test that cookies transfer from/to the backing store correctly.
   1833 TEST(CookieMonsterTest, BackingStoreCommunication) {
   1834   // Store details for cookies transforming through the backing store interface.
   1835 
   1836   base::Time current(base::Time::Now());
   1837   scoped_refptr<MockSimplePersistentCookieStore> store(
   1838       new MockSimplePersistentCookieStore);
   1839   base::Time new_access_time;
   1840   base::Time expires(base::Time::Now() + base::TimeDelta::FromSeconds(100));
   1841 
   1842   struct CookiesInputInfo {
   1843     std::string gurl;
   1844     std::string name;
   1845     std::string value;
   1846     std::string domain;
   1847     std::string path;
   1848     base::Time expires;
   1849     bool secure;
   1850     bool http_only;
   1851   };
   1852   const CookiesInputInfo input_info[] = {
   1853     {"http://a.b.google.com", "a", "1", "", "/path/to/cookie", expires,
   1854      false, false},
   1855     {"https://www.google.com", "b", "2", ".google.com", "/path/from/cookie",
   1856      expires + TimeDelta::FromSeconds(10), true, true},
   1857     {"https://google.com", "c", "3", "", "/another/path/to/cookie",
   1858      base::Time::Now() + base::TimeDelta::FromSeconds(100),
   1859      true, false}
   1860   };
   1861   const int INPUT_DELETE = 1;
   1862 
   1863   // Create new cookies and flush them to the store.
   1864   {
   1865     scoped_refptr<CookieMonster> cmout(new CookieMonster(store, NULL));
   1866     for (const CookiesInputInfo* p = input_info;
   1867          p < &input_info[ARRAYSIZE_UNSAFE(input_info)]; p++) {
   1868       EXPECT_TRUE(cmout->SetCookieWithDetails(GURL(p->gurl), p->name, p->value,
   1869                                               p->domain, p->path, p->expires,
   1870                                               p->secure, p->http_only));
   1871     }
   1872     cmout->DeleteCookie(GURL(std::string(input_info[INPUT_DELETE].gurl) +
   1873                              input_info[INPUT_DELETE].path),
   1874                         input_info[INPUT_DELETE].name);
   1875   }
   1876 
   1877   // Create a new cookie monster and make sure that everything is correct
   1878   {
   1879     scoped_refptr<CookieMonster> cmin(new CookieMonster(store, NULL));
   1880     CookieList cookies(cmin->GetAllCookies());
   1881     ASSERT_EQ(2u, cookies.size());
   1882     // Ordering is path length, then creation time.  So second cookie
   1883     // will come first, and we need to swap them.
   1884     std::swap(cookies[0], cookies[1]);
   1885     for (int output_index = 0; output_index < 2; output_index++) {
   1886       int input_index = output_index * 2;
   1887       const CookiesInputInfo* input = &input_info[input_index];
   1888       const CookieMonster::CanonicalCookie* output = &cookies[output_index];
   1889 
   1890       EXPECT_EQ(input->name, output->Name());
   1891       EXPECT_EQ(input->value, output->Value());
   1892       EXPECT_EQ(GURL(input->gurl).host(), output->Domain());
   1893       EXPECT_EQ(input->path, output->Path());
   1894       EXPECT_LE(current.ToInternalValue(),
   1895                 output->CreationDate().ToInternalValue());
   1896       EXPECT_EQ(input->secure, output->IsSecure());
   1897       EXPECT_EQ(input->http_only, output->IsHttpOnly());
   1898       EXPECT_TRUE(output->IsPersistent());
   1899       EXPECT_EQ(input->expires.ToInternalValue(),
   1900                 output->ExpiryDate().ToInternalValue());
   1901     }
   1902   }
   1903 }
   1904 
   1905 TEST(CookieMonsterTest, CookieOrdering) {
   1906   // Put a random set of cookies into a monster and make sure
   1907   // they're returned in the right order.
   1908   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   1909   EXPECT_TRUE(cm->SetCookie(GURL("http://d.c.b.a.google.com/aa/x.html"),
   1910                             "c=1"));
   1911   EXPECT_TRUE(cm->SetCookie(GURL("http://b.a.google.com/aa/bb/cc/x.html"),
   1912                             "d=1; domain=b.a.google.com"));
   1913   EXPECT_TRUE(cm->SetCookie(GURL("http://b.a.google.com/aa/bb/cc/x.html"),
   1914                             "a=4; domain=b.a.google.com"));
   1915   EXPECT_TRUE(cm->SetCookie(GURL("http://c.b.a.google.com/aa/bb/cc/x.html"),
   1916                             "e=1; domain=c.b.a.google.com"));
   1917   EXPECT_TRUE(cm->SetCookie(GURL("http://d.c.b.a.google.com/aa/bb/x.html"),
   1918                             "b=1"));
   1919   EXPECT_TRUE(cm->SetCookie(GURL("http://news.bbc.co.uk/midpath/x.html"),
   1920                             "g=10"));
   1921   EXPECT_EQ("d=1; a=4; e=1; b=1; c=1",
   1922             cm->GetCookiesWithOptions(
   1923                 GURL("http://d.c.b.a.google.com/aa/bb/cc/dd"),
   1924                 CookieOptions()));
   1925   {
   1926     unsigned int i = 0;
   1927     CookieList cookies(cm->GetAllCookiesForURL(
   1928         GURL("http://d.c.b.a.google.com/aa/bb/cc/dd")));
   1929     ASSERT_EQ(5u, cookies.size());
   1930     EXPECT_EQ("d", cookies[i++].Name());
   1931     EXPECT_EQ("a", cookies[i++].Name());
   1932     EXPECT_EQ("e", cookies[i++].Name());
   1933     EXPECT_EQ("b", cookies[i++].Name());
   1934     EXPECT_EQ("c", cookies[i++].Name());
   1935   }
   1936 
   1937   {
   1938     unsigned int i = 0;
   1939     CookieList cookies(cm->GetAllCookies());
   1940     ASSERT_EQ(6u, cookies.size());
   1941     EXPECT_EQ("d", cookies[i++].Name());
   1942     EXPECT_EQ("a", cookies[i++].Name());
   1943     EXPECT_EQ("e", cookies[i++].Name());
   1944     EXPECT_EQ("g", cookies[i++].Name());
   1945     EXPECT_EQ("b", cookies[i++].Name());
   1946     EXPECT_EQ("c", cookies[i++].Name());
   1947   }
   1948 }
   1949 
   1950 
   1951 // Function for creating a CM with a number of cookies in it,
   1952 // no store (and hence no ability to affect access time).
   1953 static CookieMonster* CreateMonsterForGC(int num_cookies) {
   1954   CookieMonster* cm(new CookieMonster(NULL, NULL));
   1955   for (int i = 0; i < num_cookies; i++)
   1956     cm->SetCookie(GURL(StringPrintf("http://h%05d.izzle", i)), "a=1");
   1957   return cm;
   1958 }
   1959 
   1960 // This test and CookieMonstertest.TestGCTimes (in cookie_monster_perftest.cc)
   1961 // are somewhat complementary twins.  This test is probing for whether
   1962 // garbage collection always happens when it should (i.e. that we actually
   1963 // get rid of cookies when we should).  The perftest is probing for
   1964 // whether garbage collection happens when it shouldn't.  See comments
   1965 // before that test for more details.
   1966 TEST(CookieMonsterTest, GarbageCollectionTriggers) {
   1967   // First we check to make sure that a whole lot of recent cookies
   1968   // doesn't get rid of anything after garbage collection is checked for.
   1969   {
   1970     scoped_refptr<CookieMonster> cm(
   1971         CreateMonsterForGC(CookieMonster::kMaxCookies * 2));
   1972     EXPECT_EQ(CookieMonster::kMaxCookies * 2, cm->GetAllCookies().size());
   1973     cm->SetCookie(GURL("http://newdomain.com"), "b=2");
   1974     EXPECT_EQ(CookieMonster::kMaxCookies * 2 + 1, cm->GetAllCookies().size());
   1975   }
   1976 
   1977   // Now we explore a series of relationships between cookie last access
   1978   // time and size of store to make sure we only get rid of cookies when
   1979   // we really should.
   1980   const struct TestCase {
   1981     int num_cookies;
   1982     int num_old_cookies;
   1983     int expected_initial_cookies;
   1984     // Indexed by ExpiryAndKeyScheme
   1985     int expected_cookies_after_set[CookieMonster::EKS_LAST_ENTRY];
   1986   } test_cases[] = {
   1987     {
   1988       // A whole lot of recent cookies; gc shouldn't happen.
   1989       CookieMonster::kMaxCookies * 2,
   1990       0,
   1991       CookieMonster::kMaxCookies * 2,
   1992       { CookieMonster::kMaxCookies * 2 + 1,
   1993         CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies }
   1994     }, {
   1995       // Some old cookies, but still overflowing max.
   1996       CookieMonster::kMaxCookies * 2,
   1997       CookieMonster::kMaxCookies / 2,
   1998       CookieMonster::kMaxCookies * 2,
   1999       {CookieMonster::kMaxCookies * 2 - CookieMonster::kMaxCookies / 2 + 1,
   2000        CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies}
   2001     }, {
   2002       // Old cookies enough to bring us right down to our purge line.
   2003       CookieMonster::kMaxCookies * 2,
   2004       CookieMonster::kMaxCookies + CookieMonster::kPurgeCookies + 1,
   2005       CookieMonster::kMaxCookies * 2,
   2006       {CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies,
   2007        CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies}
   2008     }, {
   2009       // Old cookies enough to bring below our purge line (which we
   2010       // shouldn't do).
   2011       CookieMonster::kMaxCookies * 2,
   2012       CookieMonster::kMaxCookies * 3 / 2,
   2013       CookieMonster::kMaxCookies * 2,
   2014       {CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies,
   2015        CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies}
   2016     }
   2017   };
   2018   const CookieMonster::ExpiryAndKeyScheme schemes[] = {
   2019     CookieMonster::EKS_KEEP_RECENT_AND_PURGE_ETLDP1,
   2020     CookieMonster::EKS_DISCARD_RECENT_AND_PURGE_DOMAIN,
   2021   };
   2022 
   2023   for (int ci = 0; ci < static_cast<int>(ARRAYSIZE_UNSAFE(test_cases)); ++ci) {
   2024     // Test both old and new key and expiry schemes.
   2025     for (int recent_scheme = 0;
   2026          recent_scheme < static_cast<int>(ARRAYSIZE_UNSAFE(schemes));
   2027          recent_scheme++) {
   2028       const TestCase *test_case = &test_cases[ci];
   2029       scoped_refptr<CookieMonster> cm(
   2030           CreateMonsterFromStoreForGC(
   2031               test_case->num_cookies, test_case->num_old_cookies,
   2032               CookieMonster::kSafeFromGlobalPurgeDays * 2));
   2033       cm->SetExpiryAndKeyScheme(schemes[recent_scheme]);
   2034       EXPECT_EQ(test_case->expected_initial_cookies,
   2035                 static_cast<int>(cm->GetAllCookies().size()))
   2036           << "For test case " << ci;
   2037       // Will trigger GC
   2038       cm->SetCookie(GURL("http://newdomain.com"), "b=2");
   2039       EXPECT_EQ(test_case->expected_cookies_after_set[recent_scheme],
   2040                 static_cast<int>((cm->GetAllCookies().size())))
   2041           << "For test case (" << ci << ", " << recent_scheme << ")";
   2042     }
   2043   }
   2044 }
   2045 
   2046 // This test checks that setting a cookie forcing it to be a session only
   2047 // cookie works as expected.
   2048 TEST(CookieMonsterTest, ForceSessionOnly) {
   2049   GURL url_google(kUrlGoogle);
   2050   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   2051   CookieOptions options;
   2052 
   2053   // Set a persistent cookie, but force it to be a session cookie.
   2054   options.set_force_session();
   2055   ASSERT_TRUE(cm->SetCookieWithOptions(url_google,
   2056       std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT",
   2057       options));
   2058 
   2059   // Get the canonical cookie.
   2060   CookieList cookie_list = cm->GetAllCookies();
   2061   ASSERT_EQ(1U, cookie_list.size());
   2062   ASSERT_FALSE(cookie_list[0].IsPersistent());
   2063 
   2064   // Use a past expiry date to delete the cookie, but force it to session only.
   2065   ASSERT_TRUE(cm->SetCookieWithOptions(url_google,
   2066       std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-1977 22:50:13 GMT",
   2067       options));
   2068 
   2069   // Check that the cookie was deleted.
   2070   cookie_list = cm->GetAllCookies();
   2071   ASSERT_EQ(0U, cookie_list.size());
   2072 }
   2073 
   2074 // This test checks that keep expired cookies flag is working.
   2075 TEST(CookieMonsterTest, KeepExpiredCookies) {
   2076   GURL url_google(kUrlGoogle);
   2077   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   2078   cm->SetKeepExpiredCookies();
   2079   CookieOptions options;
   2080 
   2081   // Set a persistent cookie.
   2082   ASSERT_TRUE(cm->SetCookieWithOptions(url_google,
   2083       std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT",
   2084       options));
   2085 
   2086   // Get the canonical cookie.
   2087   CookieList cookie_list = cm->GetAllCookies();
   2088   ASSERT_EQ(1U, cookie_list.size());
   2089 
   2090   // Use a past expiry date to delete the cookie.
   2091   ASSERT_TRUE(cm->SetCookieWithOptions(url_google,
   2092       std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-1977 22:50:13 GMT",
   2093       options));
   2094 
   2095   // Check that the cookie with the past expiry date is still there.
   2096   // GetAllCookies() also triggers garbage collection.
   2097   cookie_list = cm->GetAllCookies();
   2098   ASSERT_EQ(1U, cookie_list.size());
   2099   ASSERT_TRUE(cookie_list[0].IsExpired(Time::Now()));
   2100 }
   2101 
   2102 namespace {
   2103 
   2104 // Mock PersistentCookieStore that keeps track of the number of Flush() calls.
   2105 class FlushablePersistentStore : public CookieMonster::PersistentCookieStore {
   2106  public:
   2107   FlushablePersistentStore() : flush_count_(0) {}
   2108 
   2109   bool Load(std::vector<CookieMonster::CanonicalCookie*>*) {
   2110     return false;
   2111   }
   2112 
   2113   void AddCookie(const CookieMonster::CanonicalCookie&) {}
   2114   void UpdateCookieAccessTime(const CookieMonster::CanonicalCookie&) {}
   2115   void DeleteCookie(const CookieMonster::CanonicalCookie&) {}
   2116   void SetClearLocalStateOnExit(bool clear_local_state) {}
   2117 
   2118   void Flush(Task* completion_callback) {
   2119     ++flush_count_;
   2120     if (completion_callback) {
   2121       completion_callback->Run();
   2122       delete completion_callback;
   2123     }
   2124   }
   2125 
   2126   int flush_count() {
   2127     return flush_count_;
   2128   }
   2129 
   2130  private:
   2131   volatile int flush_count_;
   2132 };
   2133 
   2134 // Counts the number of times Callback() has been run.
   2135 class CallbackCounter : public base::RefCountedThreadSafe<CallbackCounter> {
   2136  public:
   2137   CallbackCounter() : callback_count_(0) {}
   2138 
   2139   void Callback() {
   2140     ++callback_count_;
   2141   }
   2142 
   2143   int callback_count() {
   2144     return callback_count_;
   2145   }
   2146 
   2147  private:
   2148   friend class base::RefCountedThreadSafe<CallbackCounter>;
   2149   volatile int callback_count_;
   2150 };
   2151 
   2152 }  // namespace
   2153 
   2154 // Test that FlushStore() is forwarded to the store and callbacks are posted.
   2155 TEST(CookieMonsterTest, FlushStore) {
   2156   scoped_refptr<CallbackCounter> counter(new CallbackCounter());
   2157   scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
   2158   scoped_refptr<CookieMonster> cm(new CookieMonster(store, NULL));
   2159 
   2160   ASSERT_EQ(0, store->flush_count());
   2161   ASSERT_EQ(0, counter->callback_count());
   2162 
   2163   // Before initialization, FlushStore() should just run the callback.
   2164   cm->FlushStore(NewRunnableMethod(counter.get(), &CallbackCounter::Callback));
   2165   MessageLoop::current()->RunAllPending();
   2166 
   2167   ASSERT_EQ(0, store->flush_count());
   2168   ASSERT_EQ(1, counter->callback_count());
   2169 
   2170   // NULL callback is safe.
   2171   cm->FlushStore(NULL);
   2172   MessageLoop::current()->RunAllPending();
   2173 
   2174   ASSERT_EQ(0, store->flush_count());
   2175   ASSERT_EQ(1, counter->callback_count());
   2176 
   2177   // After initialization, FlushStore() should delegate to the store.
   2178   cm->GetAllCookies();  // Force init.
   2179   cm->FlushStore(NewRunnableMethod(counter.get(), &CallbackCounter::Callback));
   2180   MessageLoop::current()->RunAllPending();
   2181 
   2182   ASSERT_EQ(1, store->flush_count());
   2183   ASSERT_EQ(2, counter->callback_count());
   2184 
   2185   // NULL callback is still safe.
   2186   cm->FlushStore(NULL);
   2187   MessageLoop::current()->RunAllPending();
   2188 
   2189   ASSERT_EQ(2, store->flush_count());
   2190   ASSERT_EQ(2, counter->callback_count());
   2191 
   2192   // If there's no backing store, FlushStore() is always a safe no-op.
   2193   cm = new CookieMonster(NULL, NULL);
   2194   cm->GetAllCookies();  // Force init.
   2195   cm->FlushStore(NULL);
   2196   MessageLoop::current()->RunAllPending();
   2197 
   2198   ASSERT_EQ(2, counter->callback_count());
   2199 
   2200   cm->FlushStore(NewRunnableMethod(counter.get(), &CallbackCounter::Callback));
   2201   MessageLoop::current()->RunAllPending();
   2202 
   2203   ASSERT_EQ(3, counter->callback_count());
   2204 }
   2205 
   2206 TEST(CookieMonsterTest, GetCookieSourceFromURL) {
   2207   EXPECT_EQ("http://example.com/",
   2208             CookieMonster::CanonicalCookie::GetCookieSourceFromURL(
   2209                 GURL("http://example.com")));
   2210   EXPECT_EQ("http://example.com/",
   2211             CookieMonster::CanonicalCookie::GetCookieSourceFromURL(
   2212                 GURL("http://example.com/")));
   2213   EXPECT_EQ("http://example.com/",
   2214             CookieMonster::CanonicalCookie::GetCookieSourceFromURL(
   2215                 GURL("http://example.com/test")));
   2216   EXPECT_EQ("file:///tmp/test.html",
   2217             CookieMonster::CanonicalCookie::GetCookieSourceFromURL(
   2218                 GURL("file:///tmp/test.html")));
   2219   EXPECT_EQ("http://example.com/",
   2220             CookieMonster::CanonicalCookie::GetCookieSourceFromURL(
   2221                 GURL("http://example.com:1234/")));
   2222   EXPECT_EQ("http://example.com/",
   2223             CookieMonster::CanonicalCookie::GetCookieSourceFromURL(
   2224                 GURL("https://example.com/")));
   2225   EXPECT_EQ("http://example.com/",
   2226             CookieMonster::CanonicalCookie::GetCookieSourceFromURL(
   2227                 GURL("http://user:pwd@example.com/")));
   2228   EXPECT_EQ("http://example.com/",
   2229             CookieMonster::CanonicalCookie::GetCookieSourceFromURL(
   2230                 GURL("http://example.com/test?foo")));
   2231   EXPECT_EQ("http://example.com/",
   2232             CookieMonster::CanonicalCookie::GetCookieSourceFromURL(
   2233                 GURL("http://example.com/test#foo")));
   2234 }
   2235 
   2236 TEST(CookieMonsterTest, HistogramCheck) {
   2237   scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
   2238   // Should match call in InitializeHistograms, but doesn't really matter
   2239   // since the histogram should have been initialized by the CM construction
   2240   // above.
   2241   base::Histogram* expired_histogram =
   2242       base::Histogram::FactoryGet(
   2243           "Cookie.ExpirationDurationMinutes", 1, 10 * 365 * 24 * 60, 50,
   2244           base::Histogram::kUmaTargetedHistogramFlag);
   2245 
   2246   base::Histogram::SampleSet histogram_set_1;
   2247   expired_histogram->SnapshotSample(&histogram_set_1);
   2248   ASSERT_TRUE(cm->SetCookieWithDetails(
   2249       GURL("http://fake.a.url"), "a", "b", "a.url", "/",
   2250       base::Time::Now() + base::TimeDelta::FromMinutes(59),
   2251       false, false));
   2252 
   2253   base::Histogram::SampleSet histogram_set_2;
   2254   expired_histogram->SnapshotSample(&histogram_set_2);
   2255   EXPECT_EQ(histogram_set_1.TotalCount() + 1,
   2256             histogram_set_2.TotalCount());
   2257 
   2258   // kValidCookieLine creates a session cookie.
   2259   GURL url_google(kUrlGoogle);
   2260   ASSERT_TRUE(cm->SetCookie(url_google, kValidCookieLine));
   2261   expired_histogram->SnapshotSample(&histogram_set_1);
   2262   EXPECT_EQ(histogram_set_2.TotalCount(),
   2263             histogram_set_1.TotalCount());
   2264 }
   2265 
   2266 }  // namespace
   2267