|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "net/cookies/canonical_cookie.h" | 
|  |  | 
|  | #include "base/memory/scoped_ptr.h" | 
|  | #include "googleurl/src/gurl.h" | 
|  | #include "net/cookies/cookie_options.h" | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  |  | 
|  | namespace net { | 
|  |  | 
|  | TEST(CanonicalCookieTest, GetCookieSourceFromURL) { | 
|  | EXPECT_EQ("http://example.com/", | 
|  | CanonicalCookie::GetCookieSourceFromURL( | 
|  | GURL("http://example.com"))); | 
|  | EXPECT_EQ("http://example.com/", | 
|  | CanonicalCookie::GetCookieSourceFromURL( | 
|  | GURL("http://example.com/"))); | 
|  | EXPECT_EQ("http://example.com/", | 
|  | CanonicalCookie::GetCookieSourceFromURL( | 
|  | GURL("http://example.com/test"))); | 
|  | EXPECT_EQ("file:///tmp/test.html", | 
|  | CanonicalCookie::GetCookieSourceFromURL( | 
|  | GURL("file:///tmp/test.html"))); | 
|  | EXPECT_EQ("http://example.com/", | 
|  | CanonicalCookie::GetCookieSourceFromURL( | 
|  | GURL("http://example.com:1234/"))); | 
|  | EXPECT_EQ("http://example.com/", | 
|  | CanonicalCookie::GetCookieSourceFromURL( | 
|  | GURL("https://example.com/"))); | 
|  | EXPECT_EQ("http://example.com/", | 
|  | CanonicalCookie::GetCookieSourceFromURL( | 
|  | GURL("http://user:pwd@example.com/"))); | 
|  | EXPECT_EQ("http://example.com/", | 
|  | CanonicalCookie::GetCookieSourceFromURL( | 
|  | GURL("http://example.com/test?foo"))); | 
|  | EXPECT_EQ("http://example.com/", | 
|  | CanonicalCookie::GetCookieSourceFromURL( | 
|  | GURL("http://example.com/test#foo"))); | 
|  | } | 
|  |  | 
|  | TEST(CanonicalCookieTest, Constructor) { | 
|  | GURL url("http://www.example.com/test"); | 
|  | base::Time current_time = base::Time::Now(); | 
|  |  | 
|  | CanonicalCookie cookie(url, "A", "2", "www.example.com", "/test", "", "", | 
|  | current_time, base::Time(), current_time, false, | 
|  | false); | 
|  | EXPECT_EQ(url.GetOrigin().spec(), cookie.Source()); | 
|  | EXPECT_EQ("A", cookie.Name()); | 
|  | EXPECT_EQ("2", cookie.Value()); | 
|  | EXPECT_EQ("www.example.com", cookie.Domain()); | 
|  | EXPECT_EQ("/test", cookie.Path()); | 
|  | EXPECT_FALSE(cookie.IsSecure()); | 
|  |  | 
|  | CanonicalCookie cookie2(url, "A", "2", "", "", "", "", current_time, | 
|  | base::Time(), current_time, false, false); | 
|  | EXPECT_EQ(url.GetOrigin().spec(), cookie.Source()); | 
|  | EXPECT_EQ("A", cookie2.Name()); | 
|  | EXPECT_EQ("2", cookie2.Value()); | 
|  | EXPECT_EQ("", cookie2.Domain()); | 
|  | EXPECT_EQ("", cookie2.Path()); | 
|  | EXPECT_FALSE(cookie2.IsSecure()); | 
|  |  | 
|  | } | 
|  |  | 
|  | TEST(CanonicalCookieTest, Create) { | 
|  | // Test creating cookies from a cookie string. | 
|  | GURL url("http://www.example.com/test/foo.html"); | 
|  | base::Time creation_time = base::Time::Now(); | 
|  | CookieOptions options; | 
|  |  | 
|  | scoped_ptr<CanonicalCookie> cookie( | 
|  | CanonicalCookie::Create(url, "A=2", creation_time, options)); | 
|  | EXPECT_EQ(url.GetOrigin().spec(), cookie->Source()); | 
|  | EXPECT_EQ("A", cookie->Name()); | 
|  | EXPECT_EQ("2", cookie->Value()); | 
|  | EXPECT_EQ("www.example.com", cookie->Domain()); | 
|  | EXPECT_EQ("/test", cookie->Path()); | 
|  | EXPECT_FALSE(cookie->IsSecure()); | 
|  |  | 
|  | GURL url2("http://www.foo.com"); | 
|  | cookie.reset(CanonicalCookie::Create(url2, "B=1", creation_time, options)); | 
|  | EXPECT_EQ(url2.GetOrigin().spec(), cookie->Source()); | 
|  | EXPECT_EQ("B", cookie->Name()); | 
|  | EXPECT_EQ("1", cookie->Value()); | 
|  | EXPECT_EQ("www.foo.com", cookie->Domain()); | 
|  | EXPECT_EQ("/", cookie->Path()); | 
|  | EXPECT_FALSE(cookie->IsSecure()); | 
|  |  | 
|  | // Test creating secure cookies. RFC 6265 allows insecure urls to set secure | 
|  | // cookies. | 
|  | cookie.reset( | 
|  | CanonicalCookie::Create(url, "A=2; Secure", creation_time, options)); | 
|  | EXPECT_TRUE(cookie.get()); | 
|  | EXPECT_TRUE(cookie->IsSecure()); | 
|  |  | 
|  | // Test creating http only cookies. | 
|  | cookie.reset( | 
|  | CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, options)); | 
|  | EXPECT_FALSE(cookie.get()); | 
|  | CookieOptions httponly_options; | 
|  | httponly_options.set_include_httponly(); | 
|  | cookie.reset( | 
|  | CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, | 
|  | httponly_options)); | 
|  | EXPECT_TRUE(cookie->IsHttpOnly()); | 
|  |  | 
|  | // Test the creating cookies using specific parameter instead of a cookie | 
|  | // string. | 
|  | cookie.reset(CanonicalCookie::Create( | 
|  | url, "A", "2", "www.example.com", "/test", "", "", creation_time, | 
|  | base::Time(), false, false)); | 
|  | EXPECT_EQ(url.GetOrigin().spec(), cookie->Source()); | 
|  | EXPECT_EQ("A", cookie->Name()); | 
|  | EXPECT_EQ("2", cookie->Value()); | 
|  | EXPECT_EQ(".www.example.com", cookie->Domain()); | 
|  | EXPECT_EQ("/test", cookie->Path()); | 
|  | EXPECT_FALSE(cookie->IsSecure()); | 
|  |  | 
|  | cookie.reset(CanonicalCookie::Create( | 
|  | url, "A", "2", ".www.example.com", "/test", "", "", creation_time, | 
|  | base::Time(), false, false)); | 
|  | EXPECT_EQ(url.GetOrigin().spec(), cookie->Source()); | 
|  | EXPECT_EQ("A", cookie->Name()); | 
|  | EXPECT_EQ("2", cookie->Value()); | 
|  | EXPECT_EQ(".www.example.com", cookie->Domain()); | 
|  | EXPECT_EQ("/test", cookie->Path()); | 
|  | EXPECT_FALSE(cookie->IsSecure()); | 
|  | } | 
|  |  | 
|  | TEST(CanonicalCookieTest, IsEquivalent) { | 
|  | GURL url("http://www.example.com/"); | 
|  | std::string cookie_name = "A"; | 
|  | std::string cookie_value = "2EDA-EF"; | 
|  | std::string cookie_domain = ".www.example.com"; | 
|  | std::string cookie_path = "/"; | 
|  | std::string mac_key; | 
|  | std::string mac_algorithm; | 
|  | base::Time creation_time = base::Time::Now(); | 
|  | base::Time last_access_time = creation_time; | 
|  | base::Time expiration_time = creation_time + base::TimeDelta::FromDays(2); | 
|  | bool secure(false); | 
|  | bool httponly(false); | 
|  |  | 
|  | // Test that a cookie is equivalent to itself. | 
|  | scoped_ptr<CanonicalCookie> cookie( | 
|  | new CanonicalCookie(url, cookie_name, cookie_value, cookie_domain, | 
|  | cookie_path, mac_key, mac_algorithm, creation_time, | 
|  | expiration_time, last_access_time, secure, httponly)); | 
|  | EXPECT_TRUE(cookie->IsEquivalent(*cookie)); | 
|  |  | 
|  | // Test that two identical cookies are equivalent. | 
|  | scoped_ptr<CanonicalCookie> other_cookie( | 
|  | new CanonicalCookie(url, cookie_name, cookie_value, cookie_domain, | 
|  | cookie_path, mac_key, mac_algorithm, creation_time, | 
|  | expiration_time, last_access_time, secure, httponly)); | 
|  | EXPECT_TRUE(cookie->IsEquivalent(*other_cookie)); | 
|  |  | 
|  | // Tests that use different variations of attribute values that | 
|  | // DON'T affect cookie equivalence. | 
|  | other_cookie.reset(new CanonicalCookie(url, cookie_name, "2", cookie_domain, | 
|  | cookie_path, mac_key, mac_algorithm, | 
|  | creation_time, expiration_time, | 
|  | last_access_time, secure, httponly)); | 
|  | EXPECT_TRUE(cookie->IsEquivalent(*other_cookie)); | 
|  |  | 
|  | base::Time other_creation_time = | 
|  | creation_time + base::TimeDelta::FromMinutes(2); | 
|  | other_cookie.reset(new CanonicalCookie(url, cookie_name, "2", cookie_domain, | 
|  | cookie_path, mac_key, mac_algorithm, | 
|  | other_creation_time, expiration_time, | 
|  | last_access_time, secure, httponly)); | 
|  | EXPECT_TRUE(cookie->IsEquivalent(*other_cookie)); | 
|  |  | 
|  | other_cookie.reset(new CanonicalCookie(url, cookie_name, cookie_name, | 
|  | cookie_domain, cookie_path, mac_key, | 
|  | mac_algorithm, creation_time, | 
|  | expiration_time, last_access_time, | 
|  | true, httponly)); | 
|  | EXPECT_TRUE(cookie->IsEquivalent(*other_cookie)); | 
|  |  | 
|  | // Tests that use different variations of attribute values that | 
|  | // DO affect cookie equivalence. | 
|  | other_cookie.reset(new CanonicalCookie(url, "B", cookie_value, cookie_domain, | 
|  | cookie_path, mac_key, mac_algorithm, | 
|  | creation_time, expiration_time, | 
|  | last_access_time, secure, httponly)); | 
|  | EXPECT_FALSE(cookie->IsEquivalent(*other_cookie)); | 
|  |  | 
|  | other_cookie.reset(new CanonicalCookie(url, cookie_name, cookie_value, | 
|  | "www.example.com", cookie_path, | 
|  | mac_key, mac_algorithm, creation_time, | 
|  | expiration_time, last_access_time, | 
|  | secure, httponly)); | 
|  | EXPECT_TRUE(cookie->IsDomainCookie()); | 
|  | EXPECT_FALSE(other_cookie->IsDomainCookie()); | 
|  | EXPECT_FALSE(cookie->IsEquivalent(*other_cookie)); | 
|  |  | 
|  | other_cookie.reset(new CanonicalCookie(url, cookie_name, cookie_value, | 
|  | ".example.com", cookie_path, mac_key, | 
|  | mac_algorithm, creation_time, | 
|  | expiration_time, last_access_time, | 
|  | secure, httponly)); | 
|  | EXPECT_FALSE(cookie->IsEquivalent(*other_cookie)); | 
|  |  | 
|  | other_cookie.reset(new CanonicalCookie(url, cookie_name, cookie_value, | 
|  | cookie_domain, "/test/0", mac_key, | 
|  | mac_algorithm, creation_time, | 
|  | expiration_time, last_access_time, | 
|  | secure, httponly)); | 
|  | EXPECT_FALSE(cookie->IsEquivalent(*other_cookie)); | 
|  | } | 
|  |  | 
|  | TEST(CanonicalCookieTest, IsDomainMatch) { | 
|  | GURL url("http://www.example.com/test/foo.html"); | 
|  | base::Time creation_time = base::Time::Now(); | 
|  | CookieOptions options; | 
|  |  | 
|  | scoped_ptr<CanonicalCookie> cookie( | 
|  | CanonicalCookie::Create(url, "A=2", creation_time, options)); | 
|  | EXPECT_TRUE(cookie->IsHostCookie()); | 
|  | EXPECT_TRUE(cookie->IsDomainMatch("www.example.com")); | 
|  | EXPECT_TRUE(cookie->IsDomainMatch("www.example.com")); | 
|  | EXPECT_FALSE(cookie->IsDomainMatch("foo.www.example.com")); | 
|  | EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com")); | 
|  | EXPECT_FALSE(cookie->IsDomainMatch("example.com")); | 
|  |  | 
|  | cookie.reset( | 
|  | CanonicalCookie::Create(url, "A=2; Domain=www.example.com", creation_time, | 
|  | options)); | 
|  | EXPECT_TRUE(cookie->IsDomainCookie()); | 
|  | EXPECT_TRUE(cookie->IsDomainMatch("www.example.com")); | 
|  | EXPECT_TRUE(cookie->IsDomainMatch("www.example.com")); | 
|  | EXPECT_TRUE(cookie->IsDomainMatch("foo.www.example.com")); | 
|  | EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com")); | 
|  | EXPECT_FALSE(cookie->IsDomainMatch("example.com")); | 
|  |  | 
|  | cookie.reset( | 
|  | CanonicalCookie::Create(url, "A=2; Domain=.www.example.com", | 
|  | creation_time, options)); | 
|  | EXPECT_TRUE(cookie->IsDomainMatch("www.example.com")); | 
|  | EXPECT_TRUE(cookie->IsDomainMatch("www.example.com")); | 
|  | EXPECT_TRUE(cookie->IsDomainMatch("foo.www.example.com")); | 
|  | EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com")); | 
|  | EXPECT_FALSE(cookie->IsDomainMatch("example.com")); | 
|  | } | 
|  |  | 
|  | TEST(CanonicalCookieTest, IsOnPath) { | 
|  | base::Time creation_time = base::Time::Now(); | 
|  | CookieOptions options; | 
|  |  | 
|  | scoped_ptr<CanonicalCookie> cookie( | 
|  | CanonicalCookie::Create(GURL("http://www.example.com"), | 
|  | "A=2", creation_time, options)); | 
|  | EXPECT_TRUE(cookie->IsOnPath("/")); | 
|  | EXPECT_TRUE(cookie->IsOnPath("/test")); | 
|  | EXPECT_TRUE(cookie->IsOnPath("/test/bar.html")); | 
|  |  | 
|  | // Test the empty string edge case. | 
|  | EXPECT_FALSE(cookie->IsOnPath("")); | 
|  |  | 
|  | cookie.reset( | 
|  | CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"), | 
|  | "A=2", creation_time, options)); | 
|  | EXPECT_FALSE(cookie->IsOnPath("/")); | 
|  | EXPECT_TRUE(cookie->IsOnPath("/test")); | 
|  | EXPECT_TRUE(cookie->IsOnPath("/test/bar.html")); | 
|  | EXPECT_TRUE(cookie->IsOnPath("/test/sample/bar.html")); | 
|  | } | 
|  |  | 
|  | TEST(CanonicalCookieTest, IncludeForRequestURL) { | 
|  | GURL url("http://www.example.com"); | 
|  | base::Time creation_time = base::Time::Now(); | 
|  | CookieOptions options; | 
|  |  | 
|  | scoped_ptr<CanonicalCookie> cookie( | 
|  | CanonicalCookie::Create(url, "A=2", creation_time, options)); | 
|  | EXPECT_TRUE(cookie->IncludeForRequestURL(url, options)); | 
|  | EXPECT_TRUE(cookie->IncludeForRequestURL( | 
|  | GURL("http://www.example.com/foo/bar"), options)); | 
|  | EXPECT_TRUE(cookie->IncludeForRequestURL( | 
|  | GURL("https://www.example.com/foo/bar"), options)); | 
|  | EXPECT_FALSE(cookie->IncludeForRequestURL(GURL("https://sub.example.com"), | 
|  | options)); | 
|  | EXPECT_FALSE(cookie->IncludeForRequestURL(GURL("https://sub.www.example.com"), | 
|  | options)); | 
|  |  | 
|  | // Test that cookie with a cookie path that does not match the url path are | 
|  | // not included. | 
|  | cookie.reset(CanonicalCookie::Create(url, "A=2; Path=/foo/bar", creation_time, | 
|  | options)); | 
|  | EXPECT_FALSE(cookie->IncludeForRequestURL(url, options)); | 
|  | EXPECT_TRUE(cookie->IncludeForRequestURL( | 
|  | GURL("http://www.example.com/foo/bar/index.html"), options)); | 
|  |  | 
|  | // Test that a secure cookie is not included for a non secure URL. | 
|  | GURL secure_url("https://www.example.com"); | 
|  | cookie.reset(CanonicalCookie::Create(secure_url, "A=2; Secure", creation_time, | 
|  | options)); | 
|  | EXPECT_TRUE(cookie->IsSecure()); | 
|  | EXPECT_TRUE(cookie->IncludeForRequestURL(secure_url, options)); | 
|  | EXPECT_FALSE(cookie->IncludeForRequestURL(url, options)); | 
|  |  | 
|  | // Test that http only cookies are only included if the include httponly flag | 
|  | // is set on the cookie options. | 
|  | options.set_include_httponly(); | 
|  | cookie.reset( | 
|  | CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, options)); | 
|  | EXPECT_TRUE(cookie->IsHttpOnly()); | 
|  | EXPECT_TRUE(cookie->IncludeForRequestURL(url, options)); | 
|  | options.set_exclude_httponly(); | 
|  | EXPECT_FALSE(cookie->IncludeForRequestURL(url, options)); | 
|  | } | 
|  |  | 
|  | }  // namespace net |