summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authordroger@google.com <droger@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-03 18:19:15 +0000
committerdroger@google.com <droger@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-03 18:19:15 +0000
commitb0d7aa366edee8b275be64678728c5add3515cdd (patch)
tree0b6f2371be42984e90f1f417b12dd4e4992009ed /net
parent0436978ca57f7acf9fcc26aa701906972bfe1aed (diff)
downloadchromium_src-b0d7aa366edee8b275be64678728c5add3515cdd.zip
chromium_src-b0d7aa366edee8b275be64678728c5add3515cdd.tar.gz
chromium_src-b0d7aa366edee8b275be64678728c5add3515cdd.tar.bz2
Move CookieStore unittests to a separate file.
This is a follow up from http://codereview.chromium.org/8953028/. This allows other CookieStore implementations to benefit from the tests. BUG=NONE TEST=NONE Review URL: http://codereview.chromium.org/9310051 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@120355 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/base/cookie_monster_unittest.cc1130
-rw-r--r--net/base/cookie_store_test_callbacks.cc65
-rw-r--r--net/base/cookie_store_test_callbacks.h137
-rw-r--r--net/base/cookie_store_unittest.h993
-rw-r--r--net/base/cookie_util_unittest.cc23
-rw-r--r--net/net.gyp8
6 files changed, 1234 insertions, 1122 deletions
diff --git a/net/base/cookie_monster_unittest.cc b/net/base/cookie_monster_unittest.cc
index a7477e3..c3a24f52 100644
--- a/net/base/cookie_monster_unittest.cc
+++ b/net/base/cookie_monster_unittest.cc
@@ -2,16 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <time.h>
+#include "net/base/cookie_store_unittest.h"
-#include <algorithm>
+#include <time.h>
#include <string>
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/stringprintf.h"
@@ -29,7 +28,6 @@ namespace net {
using base::Time;
using base::TimeDelta;
-using base::Thread;
namespace {
@@ -49,136 +47,13 @@ class NewMockPersistentCookieStore
MOCK_METHOD1(Flush, void(const base::Closure& callback));
};
-const int kTimeout = 1000;
-
const char* kTopLevelDomainPlus1 = "http://www.harvard.edu";
const char* kTopLevelDomainPlus2 = "http://www.math.harvard.edu";
const char* kTopLevelDomainPlus2Secure = "https://www.math.harvard.edu";
const char* kTopLevelDomainPlus3 =
"http://www.bourbaki.math.harvard.edu";
const char* kOtherDomain = "http://www.mit.edu";
-
-const char kUrlGoogle[] = "http://www.google.izzle";
-const char kUrlGoogleFoo[] = "http://www.google.izzle/foo";
-const char kUrlGoogleBar[] = "http://www.google.izzle/bar";
const char kUrlGoogleSpecific[] = "http://www.gmail.google.izzle";
-const char kUrlGoogleSecure[] = "https://www.google.izzle";
-const char kUrlFtp[] = "ftp://ftp.google.izzle/";
-const char kValidCookieLine[] = "A=B; path=/";
-const char kValidDomainCookieLine[] = "A=B; path=/; domain=google.izzle";
-
-// Defines common behaviour for the callbacks from GetCookies, SetCookies, etc.
-// Asserts that the current thread is the expected invocation thread, sends a
-// quit to the thread in which it was constructed.
-class CookieCallback {
- public:
- // Indicates whether the callback has been called.
- bool did_run() { return did_run_; }
-
- protected:
- // Constructs a callback that expects to be called in the given thread and
- // will, upon execution, send a QUIT to the constructing thread.
- explicit CookieCallback(Thread* run_in_thread)
- : did_run_(false),
- run_in_thread_(run_in_thread),
- run_in_loop_(NULL),
- parent_loop_(MessageLoop::current()),
- loop_to_quit_(MessageLoop::current()) {}
-
- // Constructs a callback that expects to be called in current thread and will
- // send a QUIT to the constructing thread.
- CookieCallback()
- : did_run_(false),
- run_in_thread_(NULL),
- run_in_loop_(MessageLoop::current()),
- parent_loop_(NULL),
- loop_to_quit_(MessageLoop::current()) {}
-
- // Tests whether the current thread was the caller's thread.
- // Sends a QUIT to the constructing thread.
- void CallbackEpilogue() {
- MessageLoop* expected_loop = NULL;
- if (run_in_thread_) {
- DCHECK(!run_in_loop_);
- expected_loop = run_in_thread_->message_loop();
- } else if (run_in_loop_) {
- expected_loop = run_in_loop_;
- }
- ASSERT_TRUE(expected_loop != NULL);
-
- did_run_ = true;
- EXPECT_EQ(expected_loop, MessageLoop::current());
- loop_to_quit_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
- }
-
- private:
- bool did_run_;
- Thread* run_in_thread_;
- MessageLoop* run_in_loop_;
- MessageLoop* parent_loop_;
- MessageLoop* loop_to_quit_;
-};
-
-// Callback implementations for the asynchronous CookieStore methods.
-
-class SetCookieCallback : public CookieCallback {
- public:
- SetCookieCallback() : result_(false) {}
- explicit SetCookieCallback(Thread* run_in_thread)
- : CookieCallback(run_in_thread),
- result_(false) {}
-
- void Run(bool result) {
- result_ = result;
- CallbackEpilogue();
- }
-
- bool result() { return result_; }
-
- private:
- bool result_;
-};
-
-class GetCookieStringCallback : public CookieCallback {
- public:
- GetCookieStringCallback() {}
- explicit GetCookieStringCallback(Thread* run_in_thread)
- : CookieCallback(run_in_thread) {}
-
- void Run(const std::string& cookie) {
- cookie_ = cookie;
- CallbackEpilogue();
- }
-
- const std::string& cookie() { return cookie_; }
-
- private:
- std::string cookie_;
-};
-
-class GetCookiesWithInfoCallback : public CookieCallback {
- public:
- GetCookiesWithInfoCallback() {}
- explicit GetCookiesWithInfoCallback(Thread* run_in_thread)
- : CookieCallback(run_in_thread) {}
-
- void Run(
- const std::string& cookie_line,
- const std::vector<CookieStore::CookieInfo>& cookie_info) {
- cookie_line_ = cookie_line;
- cookie_info_ = cookie_info;
- CallbackEpilogue();
- }
-
- const std::string& cookie_line() { return cookie_line_; }
- const std::vector<CookieStore::CookieInfo>& cookie_info() {
- return cookie_info_;
- }
-
- private:
- std::string cookie_line_;
- std::vector<CookieStore::CookieInfo> cookie_info_;
-};
class GetCookieListCallback : public CookieCallback {
public:
@@ -197,35 +72,6 @@ class GetCookieListCallback : public CookieCallback {
CookieList cookies_;
};
-class DeleteCallback : public CookieCallback {
- public:
- DeleteCallback() : num_deleted_(0) {}
- explicit DeleteCallback(Thread* run_in_thread)
- : CookieCallback(run_in_thread),
- num_deleted_(0) {}
-
- void Run(int num_deleted) {
- num_deleted_ = num_deleted;
- CallbackEpilogue();
- }
-
- int num_deleted() { return num_deleted_; }
-
- private:
- int num_deleted_;
-};
-
-class DeleteCookieCallback : public CookieCallback {
- public:
- DeleteCookieCallback() {}
- explicit DeleteCookieCallback(Thread* run_in_thread)
- : CookieCallback(run_in_thread) {}
-
- void Run() {
- CallbackEpilogue();
- }
-};
-
class ParsedCookieTest : public testing::Test { };
} // namespace
@@ -501,42 +347,12 @@ TEST(ParsedCookieTest, ParseTokensAndValues) {
namespace {
-// The CookieStoreTestTraits must have the following members:
-// struct CookieStoreTestTraits {
-// // Factory function.
-// static scoped_refptr<CookieStore> Create();
-//
-// // The cookie store supports cookies with the exclude_httponly() option.
-// static const bool supports_http_only;
-//
-// // The cookie store supports the GetCookiesWithInfoAsync() method.
-// static const bool supports_cookies_with_info;
-//
-// // The cookie store is able to make the difference between the ".com"
-// // and the "com" domains.
-// static const bool supports_non_dotted_domains;
-//
-// // The cookie store handles the domains with trailing dots (such as "com.")
-// // correctly.
-// static const bool supports_trailing_dots;
-//
-// // The cookie store rejects cookies for invalid schemes such as ftp.
-// static const bool filters_schemes;
-//
-// // The cookie store has a bug happening when a path is a substring of
-// // another.
-// static const bool has_path_prefix_bug;
-//
-// // Time to wait between two cookie insertions to ensure that cookies have
-// // different creation times.
-// static const int creation_time_granularity_in_ms;
-// };
-
struct CookieMonsterTestTraits {
static scoped_refptr<CookieStore> Create() {
return new CookieMonster(NULL, NULL);
}
+ static const bool is_cookie_monster = true;
static const bool supports_http_only = true;
static const bool supports_cookies_with_info = true;
static const bool supports_non_dotted_domains = true;
@@ -546,157 +362,13 @@ struct CookieMonsterTestTraits {
static const int creation_time_granularity_in_ms = 0;
};
-template <class CookieStoreTestTraits>
-class CookieStoreTest : public testing::Test {
- protected:
- CookieStoreTest()
- : url_google_(kUrlGoogle),
- url_google_secure_(kUrlGoogleSecure),
- url_google_foo_(kUrlGoogleFoo),
- url_google_bar_(kUrlGoogleBar),
- weak_factory_(MessageLoop::current()) {}
-
- // Helper methods for the asynchronous Cookie Store API that call the
- // asynchronous method and then pump the loop until the callback is invoked,
- // finally returning the value.
-
- std::string GetCookies(CookieStore* cs, const GURL& url) {
- DCHECK(cs);
- CookieOptions options;
- if (!CookieStoreTestTraits::supports_http_only)
- options.set_include_httponly();
- GetCookieStringCallback callback;
- cs->GetCookiesWithOptionsAsync(
- url, options,
- base::Bind(&GetCookieStringCallback::Run, base::Unretained(&callback)));
- RunFor(kTimeout);
- EXPECT_TRUE(callback.did_run());
- return callback.cookie();
- }
-
- std::string GetCookiesWithOptions(CookieStore* cs,
- const GURL& url,
- const CookieOptions& options) {
- DCHECK(cs);
- GetCookieStringCallback callback;
- cs->GetCookiesWithOptionsAsync(
- url, options, base::Bind(&GetCookieStringCallback::Run,
- base::Unretained(&callback)));
- RunFor(kTimeout);
- EXPECT_TRUE(callback.did_run());
- return callback.cookie();
- }
-
- void GetCookiesWithInfo(CookieStore* cs,
- const GURL& url,
- const CookieOptions& options,
- std::string* cookie_line,
- std::vector<CookieStore::CookieInfo>* cookie_info) {
- DCHECK(cs);
- DCHECK(cookie_line);
- DCHECK(cookie_info);
- GetCookiesWithInfoCallback callback;
- cs->GetCookiesWithInfoAsync(
- url, options, base::Bind(&GetCookiesWithInfoCallback::Run,
- base::Unretained(&callback)));
- RunFor(kTimeout);
- EXPECT_TRUE(callback.did_run());
- *cookie_line = callback.cookie_line();
- *cookie_info = callback.cookie_info();
- }
-
- bool SetCookieWithOptions(CookieStore* cs,
- const GURL& url,
- const std::string& cookie_line,
- const CookieOptions& options) {
- DCHECK(cs);
- SetCookieCallback callback;
- cs->SetCookieWithOptionsAsync(
- url, cookie_line, options,
- base::Bind(&SetCookieCallback::Run, base::Unretained(&callback)));
- RunFor(kTimeout);
- EXPECT_TRUE(callback.did_run());
- return callback.result();
- }
-
- bool SetCookie(CookieStore* cs,
- const GURL& url,
- const std::string& cookie_line) {
- CookieOptions options;
- if (!CookieStoreTestTraits::supports_http_only)
- options.set_include_httponly();
- return SetCookieWithOptions(cs, url, cookie_line, options);
- }
-
- void DeleteCookie(CookieStore* cs,
- const GURL& url,
- const std::string& cookie_name) {
- DCHECK(cs);
- DeleteCookieCallback callback;
- cs->DeleteCookieAsync(
- url, cookie_name,
- base::Bind(&DeleteCookieCallback::Run, base::Unretained(&callback)));
- RunFor(kTimeout);
- EXPECT_TRUE(callback.did_run());
- }
-
- void RunFor(int ms) {
- // Runs the test thread message loop for up to |ms| milliseconds.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, base::Bind(&MessageLoop::Quit, weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(ms));
- MessageLoop::current()->Run();
- weak_factory_.InvalidateWeakPtrs();
- }
-
- scoped_refptr<CookieStore> GetCookieStore() {
- return CookieStoreTestTraits::Create();
- }
-
- // Compares two cookie lines.
- void MatchCookieLines(const std::string& line1, const std::string& line2) {
- EXPECT_EQ(TokenizeCookieLine(line1), TokenizeCookieLine(line2));
- }
-
- // Check the cookie line by polling until equality or a timeout is reached.
- void MatchCookieLineWithTimeout(CookieStore* cs,
- const GURL& url,
- const std::string& line) {
- std::string cookies = GetCookies(cs, url);
- bool matched = (TokenizeCookieLine(line) == TokenizeCookieLine(cookies));
- base::Time polling_end_date = base::Time::Now() +
- base::TimeDelta::FromMilliseconds(
- CookieStoreTestTraits::creation_time_granularity_in_ms);
-
- while (!matched && base::Time::Now() <= polling_end_date) {
- base::PlatformThread::Sleep(10);
- cookies = GetCookies(cs, url);
- matched = (TokenizeCookieLine(line) == TokenizeCookieLine(cookies));
- }
-
- EXPECT_TRUE(matched) << "\"" << cookies
- << "\" does not match \"" << line << "\"";
- }
-
- GURL url_google_;
- GURL url_google_secure_;
- GURL url_google_foo_;
- GURL url_google_bar_;
-
- base::WeakPtrFactory<MessageLoop> weak_factory_;
-
- private:
- // Returns a set of strings of type "name=value". Fails in case of duplicate.
- std::set<std::string> TokenizeCookieLine(const std::string& line) {
- std::set<std::string> tokens;
- StringTokenizer tokenizer(line, " ;");
- while (tokenizer.GetNext())
- EXPECT_TRUE(tokens.insert(tokenizer.token()).second);
- return tokens;
- }
-};
+INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
+ CookieStoreTest,
+ CookieMonsterTestTraits);
-TYPED_TEST_CASE_P(CookieStoreTest);
+INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
+ MultiThreadedCookieStoreTest,
+ CookieMonsterTestTraits);
class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
protected:
@@ -1107,6 +779,7 @@ ACTION_P3(GetAllCookiesForUrlAction, cookie_monster, url, callback) {
ACTION_P(PushCallbackAction, callback_vector) {
callback_vector->push(arg1);
}
+
} // namespace
// This test suite verifies the task deferral behaviour of the CookieMonster.
@@ -1482,404 +1155,6 @@ TEST_F(DeferredCookieTaskTest, DeferredTaskOrder) {
CompleteLoadingAndWait();
}
-TYPED_TEST_P(CookieStoreTest, DomainTest) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B"));
- this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
- "C=D; domain=.google.izzle"));
- this->MatchCookieLines("A=B; C=D", this->GetCookies(cs, this->url_google_));
-
- // Verify that A=B was set as a host cookie rather than a domain
- // cookie -- should not be accessible from a sub sub-domain.
- this->MatchCookieLines("C=D",
- this->GetCookies(cs, GURL("http://foo.www.google.izzle")));
-
- // Test and make sure we find domain cookies on the same domain.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
- "E=F; domain=.www.google.izzle"));
- this->MatchCookieLines("A=B; C=D; E=F",
- this->GetCookies(cs, this->url_google_));
-
- // Test setting a domain= that doesn't start w/ a dot, should
- // treat it as a domain cookie, as if there was a pre-pended dot.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
- "G=H; domain=www.google.izzle"));
- this->MatchCookieLines("A=B; C=D; E=F; G=H",
- this->GetCookies(cs, this->url_google_));
-
- // Test domain enforcement, should fail on a sub-domain or something too deep.
- EXPECT_FALSE(this->SetCookie(cs, this->url_google_, "I=J; domain=.izzle"));
- this->MatchCookieLines("", this->GetCookies(cs, GURL("http://a.izzle")));
- EXPECT_FALSE(this->SetCookie(cs, this->url_google_,
- "K=L; domain=.bla.www.google.izzle"));
- this->MatchCookieLines("C=D; E=F; G=H",
- this->GetCookies(cs, GURL("http://bla.www.google.izzle")));
- this->MatchCookieLines("A=B; C=D; E=F; G=H",
- this->GetCookies(cs, this->url_google_));
-}
-
-// FireFox recognizes domains containing trailing periods as valid.
-// IE and Safari do not. Assert the expected policy here.
-TYPED_TEST_P(CookieStoreTest, DomainWithTrailingDotTest) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_FALSE(this->SetCookie(cs, this->url_google_,
- "a=1; domain=.www.google.com."));
- EXPECT_FALSE(this->SetCookie(cs, this->url_google_,
- "b=2; domain=.www.google.com.."));
- this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
-}
-
-// Test that cookies can bet set on higher level domains.
-// http://b/issue?id=896491
-TYPED_TEST_P(CookieStoreTest, ValidSubdomainTest) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url_abcd("http://a.b.c.d.com");
- GURL url_bcd("http://b.c.d.com");
- GURL url_cd("http://c.d.com");
- GURL url_d("http://d.com");
-
- EXPECT_TRUE(this->SetCookie(cs, url_abcd, "a=1; domain=.a.b.c.d.com"));
- EXPECT_TRUE(this->SetCookie(cs, url_abcd, "b=2; domain=.b.c.d.com"));
- EXPECT_TRUE(this->SetCookie(cs, url_abcd, "c=3; domain=.c.d.com"));
- EXPECT_TRUE(this->SetCookie(cs, url_abcd, "d=4; domain=.d.com"));
-
- this->MatchCookieLines("a=1; b=2; c=3; d=4", this->GetCookies(cs, url_abcd));
- this->MatchCookieLines("b=2; c=3; d=4", this->GetCookies(cs, url_bcd));
- this->MatchCookieLines("c=3; d=4", this->GetCookies(cs, url_cd));
- this->MatchCookieLines("d=4", this->GetCookies(cs, url_d));
-
- // Check that the same cookie can exist on different sub-domains.
- EXPECT_TRUE(this->SetCookie(cs, url_bcd, "X=bcd; domain=.b.c.d.com"));
- EXPECT_TRUE(this->SetCookie(cs, url_bcd, "X=cd; domain=.c.d.com"));
- this->MatchCookieLines("b=2; c=3; d=4; X=bcd; X=cd",
- this->GetCookies(cs, url_bcd));
- this->MatchCookieLines("c=3; d=4; X=cd", this->GetCookies(cs, url_cd));
-}
-
-// Test that setting a cookie which specifies an invalid domain has
-// no side-effect. An invalid domain in this context is one which does
-// not match the originating domain.
-// http://b/issue?id=896472
-TYPED_TEST_P(CookieStoreTest, InvalidDomainTest) {
- {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url_foobar("http://foo.bar.com");
-
- // More specific sub-domain than allowed.
- EXPECT_FALSE(this->SetCookie(cs, url_foobar,
- "a=1; domain=.yo.foo.bar.com"));
-
- EXPECT_FALSE(this->SetCookie(cs, url_foobar, "b=2; domain=.foo.com"));
- EXPECT_FALSE(this->SetCookie(cs, url_foobar, "c=3; domain=.bar.foo.com"));
-
- // Different TLD, but the rest is a substring.
- EXPECT_FALSE(this->SetCookie(cs, url_foobar,
- "d=4; domain=.foo.bar.com.net"));
-
- // A substring that isn't really a parent domain.
- EXPECT_FALSE(this->SetCookie(cs, url_foobar, "e=5; domain=ar.com"));
-
- // Completely invalid domains:
- EXPECT_FALSE(this->SetCookie(cs, url_foobar, "f=6; domain=."));
- EXPECT_FALSE(this->SetCookie(cs, url_foobar, "g=7; domain=/"));
- EXPECT_FALSE(this->SetCookie(cs, url_foobar,
- "h=8; domain=http://foo.bar.com"));
- EXPECT_FALSE(this->SetCookie(cs, url_foobar, "i=9; domain=..foo.bar.com"));
- EXPECT_FALSE(this->SetCookie(cs, url_foobar, "j=10; domain=..bar.com"));
-
- // Make sure there isn't something quirky in the domain canonicalization
- // that supports full URL semantics.
- EXPECT_FALSE(this->SetCookie(cs, url_foobar,
- "k=11; domain=.foo.bar.com?blah"));
- EXPECT_FALSE(this->SetCookie(cs, url_foobar,
- "l=12; domain=.foo.bar.com/blah"));
- EXPECT_FALSE(this->SetCookie(cs, url_foobar,
- "m=13; domain=.foo.bar.com:80"));
- EXPECT_FALSE(this->SetCookie(cs, url_foobar,
- "n=14; domain=.foo.bar.com:"));
- EXPECT_FALSE(this->SetCookie(cs, url_foobar,
- "o=15; domain=.foo.bar.com#sup"));
-
- this->MatchCookieLines("", this->GetCookies(cs, url_foobar));
- }
-
- {
- // Make sure the cookie code hasn't gotten its subdomain string handling
- // reversed, missed a suffix check, etc. It's important here that the two
- // hosts below have the same domain + registry.
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url_foocom("http://foo.com.com");
- EXPECT_FALSE(this->SetCookie(cs, url_foocom,
- "a=1; domain=.foo.com.com.com"));
- this->MatchCookieLines("", this->GetCookies(cs, url_foocom));
- }
-}
-
-// Test the behavior of omitting dot prefix from domain, should
-// function the same as FireFox.
-// http://b/issue?id=889898
-TYPED_TEST_P(CookieStoreTest, DomainWithoutLeadingDotTest) {
- { // The omission of dot results in setting a domain cookie.
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url_hosted("http://manage.hosted.filefront.com");
- GURL url_filefront("http://www.filefront.com");
- EXPECT_TRUE(this->SetCookie(cs, url_hosted,
- "sawAd=1; domain=filefront.com"));
- this->MatchCookieLines("sawAd=1", this->GetCookies(cs, url_hosted));
- this->MatchCookieLines("sawAd=1", this->GetCookies(cs, url_filefront));
- }
-
- { // Even when the domains match exactly, don't consider it host cookie.
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url("http://www.google.com");
- EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=www.google.com"));
- this->MatchCookieLines("a=1", this->GetCookies(cs, url));
- this->MatchCookieLines("a=1",
- this->GetCookies(cs, GURL("http://sub.www.google.com")));
- this->MatchCookieLines("",
- this->GetCookies(cs, GURL("http://something-else.com")));
- }
-}
-
-// Test that the domain specified in cookie string is treated case-insensitive
-// http://b/issue?id=896475.
-TYPED_TEST_P(CookieStoreTest, CaseInsensitiveDomainTest) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url("http://www.google.com");
- EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=.GOOGLE.COM"));
- EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.wWw.gOOgLE.coM"));
- this->MatchCookieLines("a=1; b=2", this->GetCookies(cs, url));
-}
-
-TYPED_TEST_P(CookieStoreTest, TestIpAddress) {
- GURL url_ip("http://1.2.3.4/weee");
- {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_TRUE(this->SetCookie(cs, url_ip, kValidCookieLine));
- this->MatchCookieLines("A=B", this->GetCookies(cs, url_ip));
- }
-
- { // IP addresses should not be able to set domain cookies.
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_FALSE(this->SetCookie(cs, url_ip, "b=2; domain=.1.2.3.4"));
- EXPECT_FALSE(this->SetCookie(cs, url_ip, "c=3; domain=.3.4"));
- this->MatchCookieLines("", this->GetCookies(cs, url_ip));
- // It should be allowed to set a cookie if domain= matches the IP address
- // exactly. This matches IE/Firefox, even though it seems a bit wrong.
- EXPECT_FALSE(this->SetCookie(cs, url_ip, "b=2; domain=1.2.3.3"));
- this->MatchCookieLines("", this->GetCookies(cs, url_ip));
- EXPECT_TRUE(this->SetCookie(cs, url_ip, "b=2; domain=1.2.3.4"));
- this->MatchCookieLines("b=2", this->GetCookies(cs, url_ip));
- }
-}
-
-// Test host cookies, and setting of cookies on TLD.
-TYPED_TEST_P(CookieStoreTest, TestNonDottedAndTLD) {
- {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url("http://com/");
- // Allow setting on "com", (but only as a host cookie).
- EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
- EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.com"));
- EXPECT_FALSE(this->SetCookie(cs, url, "c=3; domain=com"));
- this->MatchCookieLines("a=1", this->GetCookies(cs, url));
- // Make sure it doesn't show up for a normal .com, it should be a host
- // not a domain cookie.
- this->MatchCookieLines("",
- this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/")));
- if (TypeParam::supports_non_dotted_domains) {
- this->MatchCookieLines("", this->GetCookies(cs, GURL("http://.com/")));
- }
- }
-
- {
- // http://com. should be treated the same as http://com.
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url("http://com./index.html");
- if (TypeParam::supports_trailing_dots) {
- EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
- this->MatchCookieLines("a=1", this->GetCookies(cs, url));
- this->MatchCookieLines("",
- this->GetCookies(cs, GURL("http://hopefully-no-cookies.com./")));
- } else {
- EXPECT_FALSE(this->SetCookie(cs, url, "a=1"));
- }
- }
-
- { // Should not be able to set host cookie from a subdomain.
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url("http://a.b");
- EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.b"));
- EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=b"));
- this->MatchCookieLines("", this->GetCookies(cs, url));
- }
-
- { // Same test as above, but explicitly on a known TLD (com).
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url("http://google.com");
- EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.com"));
- EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=com"));
- this->MatchCookieLines("", this->GetCookies(cs, url));
- }
-
- { // Make sure can't set cookie on TLD which is dotted.
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url("http://google.co.uk");
- EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.co.uk"));
- EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.uk"));
- this->MatchCookieLines("", this->GetCookies(cs, url));
- this->MatchCookieLines("",
- this->GetCookies(cs, GURL("http://something-else.co.uk")));
- this->MatchCookieLines("",
- this->GetCookies(cs, GURL("http://something-else.uk")));
- }
-
- { // Intranet URLs should only be able to set host cookies.
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url("http://b");
- EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
- EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.b"));
- EXPECT_FALSE(this->SetCookie(cs, url, "c=3; domain=b"));
- this->MatchCookieLines("a=1", this->GetCookies(cs, url));
- }
-}
-
-// Test reading/writing cookies when the domain ends with a period,
-// as in "www.google.com."
-TYPED_TEST_P(CookieStoreTest, TestHostEndsWithDot) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- GURL url("http://www.google.com");
- GURL url_with_dot("http://www.google.com.");
- EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
- this->MatchCookieLines("a=1", this->GetCookies(cs, url));
-
- if (TypeParam::supports_trailing_dots) {
- // Do not share cookie space with the dot version of domain.
- // Note: this is not what FireFox does, but it _is_ what IE+Safari do.
- EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.www.google.com."));
- this->MatchCookieLines("a=1", this->GetCookies(cs, url));
-
- EXPECT_TRUE(this->SetCookie(cs, url_with_dot, "b=2; domain=.google.com."));
- this->MatchCookieLines("b=2", this->GetCookies(cs, url_with_dot));
- } else {
- EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.www.google.com."));
- EXPECT_FALSE(this->SetCookie(cs, url_with_dot, "b=2; domain=.google.com."));
- }
-
- // Make sure there weren't any side effects.
- this->MatchCookieLines("",
- this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/")));
- this->MatchCookieLines("", this->GetCookies(cs, GURL("http://.com/")));
-}
-
-TYPED_TEST_P(CookieStoreTest, InvalidScheme) {
- if (!TypeParam::filters_schemes)
- return;
-
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_FALSE(this->SetCookie(cs, GURL(kUrlFtp), kValidCookieLine));
-}
-
-TYPED_TEST_P(CookieStoreTest, InvalidScheme_Read) {
- if (!TypeParam::filters_schemes)
- return;
-
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_TRUE(this->SetCookie(cs, GURL(kUrlGoogle), kValidDomainCookieLine));
- this->MatchCookieLines("", this->GetCookies(cs, GURL(kUrlFtp)));
-}
-
-TYPED_TEST_P(CookieStoreTest, PathTest) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- std::string url("http://www.google.izzle");
- EXPECT_TRUE(this->SetCookie(cs, GURL(url), "A=B; path=/wee"));
- this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee")));
- this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee/")));
- this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee/war")));
- this->MatchCookieLines("A=B",
- this->GetCookies(cs, GURL(url + "/wee/war/more/more")));
- if (!TypeParam::has_path_prefix_bug)
- this->MatchCookieLines("", this->GetCookies(cs, GURL(url + "/weehee")));
- this->MatchCookieLines("", this->GetCookies(cs, GURL(url + "/")));
-
- // If we add a 0 length path, it should default to /
- EXPECT_TRUE(this->SetCookie(cs, GURL(url), "A=C; path="));
- this->MatchCookieLines("A=B; A=C", this->GetCookies(cs, GURL(url + "/wee")));
- this->MatchCookieLines("A=C", this->GetCookies(cs, GURL(url + "/")));
-}
-
-TYPED_TEST_P(CookieStoreTest, HttpOnlyTest) {
- if (!TypeParam::supports_http_only)
- return;
-
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- CookieOptions options;
- options.set_include_httponly();
-
- // Create a httponly cookie.
- EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B; httponly",
- options));
-
- // Check httponly read protection.
- this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
- this->MatchCookieLines("A=B",
- this->GetCookiesWithOptions(cs, this->url_google_, options));
-
- // Check httponly overwrite protection.
- EXPECT_FALSE(this->SetCookie(cs, this->url_google_, "A=C"));
- this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
- this->MatchCookieLines("A=B",
- this->GetCookiesWithOptions(cs, this->url_google_, options));
- EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=C",
- options));
- this->MatchCookieLines("A=C", this->GetCookies(cs, this->url_google_));
-
- // Check httponly create protection.
- EXPECT_FALSE(this->SetCookie(cs, this->url_google_, "B=A; httponly"));
- this->MatchCookieLines("A=C",
- this->GetCookiesWithOptions(cs, this->url_google_, options));
- EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "B=A; httponly",
- options));
- this->MatchCookieLines("A=C; B=A",
- this->GetCookiesWithOptions(cs, this->url_google_, options));
- this->MatchCookieLines("A=C", this->GetCookies(cs, this->url_google_));
-}
-
-TYPED_TEST_P(CookieStoreTest, TestGetCookiesWithInfo) {
- if (!TypeParam::supports_cookies_with_info)
- return;
-
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- CookieOptions options;
-
- EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B",
- options));
- EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_,
- "C=D; Mac-Key=390jfn0awf3; Mac-Algorithm=hmac-sha-1", options));
-
- this->MatchCookieLines("A=B; C=D",
- this->GetCookiesWithOptions(cs, this->url_google_, options));
-
- std::string cookie_line;
- std::vector<CookieStore::CookieInfo> cookie_infos;
-
- this->GetCookiesWithInfo(cs, this->url_google_, options, &cookie_line,
- &cookie_infos);
-
- EXPECT_EQ("A=B; C=D", cookie_line);
-
- EXPECT_EQ(2U, cookie_infos.size());
-
- EXPECT_EQ("A", cookie_infos[0].name);
- EXPECT_EQ("", cookie_infos[0].mac_key);
- EXPECT_EQ("", cookie_infos[0].mac_algorithm);
-
- EXPECT_EQ("C", cookie_infos[1].name);
- EXPECT_EQ("390jfn0awf3", cookie_infos[1].mac_key);
- EXPECT_EQ("hmac-sha-1", cookie_infos[1].mac_algorithm);
-}
-
TEST_F(CookieMonsterTest, TestCookieDateParsing) {
const struct {
const char* str;
@@ -1968,76 +1243,6 @@ TEST_F(CookieMonsterTest, TestCookieDateParsing) {
}
}
-TEST_F(CookieMonsterTest, TestDomainIsHostOnly) {
- const struct {
- const char* str;
- const bool is_host_only;
- } tests[] = {
- { "", true },
- { "www.google.com", true },
- { ".google.com", false }
- };
-
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
- EXPECT_EQ(tests[i].is_host_only,
- cookie_util::DomainIsHostOnly(tests[i].str));
- }
-}
-
-TYPED_TEST_P(CookieStoreTest, TestCookieDeletion) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
-
- // Create a session cookie.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_, kValidCookieLine));
- this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
- // Delete it via Max-Age.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
- std::string(kValidCookieLine) + "; max-age=0"));
- this->MatchCookieLineWithTimeout(cs, this->url_google_, "");
-
- // Create a session cookie.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_, kValidCookieLine));
- this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
- // Delete it via Expires.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
- std::string(kValidCookieLine) +
- "; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
- this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
-
- // Create a persistent cookie.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
- std::string(kValidCookieLine) +
- "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
-
- this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
- // Delete it via Max-Age.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
- std::string(kValidCookieLine) + "; max-age=0"));
- this->MatchCookieLineWithTimeout(cs, this->url_google_, "");
-
- // Create a persistent cookie.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
- std::string(kValidCookieLine) +
- "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
- this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
- // Delete it via Expires.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
- std::string(kValidCookieLine) +
- "; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
- this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
-
- // Create a persistent cookie.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
- std::string(kValidCookieLine) +
- "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
- this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
- // Delete it via Expires, with a unix epoch of 0.
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
- std::string(kValidCookieLine) +
- "; expires=Thu, 1-Jan-1970 00:00:00 GMT"));
- this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
-}
-
TEST_F(CookieMonsterTest, TestCookieDeleteAll) {
scoped_refptr<MockPersistentCookieStore> store(
new MockPersistentCookieStore);
@@ -2109,31 +1314,6 @@ TEST_F(CookieMonsterTest, TestCookieDeleteAllCreatedBetweenTimestamps) {
EXPECT_EQ(0, DeleteAll(cm));
}
-TYPED_TEST_P(CookieStoreTest, TestSecure) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
-
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B"));
- this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
- this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_secure_));
-
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_secure_, "A=B; secure"));
- // The secure should overwrite the non-secure.
- this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
- this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_secure_));
-
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_secure_, "D=E; secure"));
- this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
- this->MatchCookieLines("A=B; D=E",
- this->GetCookies(cs, this->url_google_secure_));
-
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_secure_, "A=B"));
- // The non-secure should overwrite the secure.
- this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
- this->MatchCookieLines("D=E; A=B",
- this->GetCookies(cs, this->url_google_secure_));
-}
-
-static const int kLastAccessThresholdMilliseconds = 200;
static const int kAccessDelayMs = kLastAccessThresholdMilliseconds + 20;
TEST_F(CookieMonsterTest, TestLastAccess) {
@@ -2164,26 +1344,6 @@ TEST_F(CookieMonsterTest, TestHostGarbageCollection) {
CookieMonster::EKS_DISCARD_RECENT_AND_PURGE_DOMAIN);
}
-// Formerly NetUtilTest.CookieTest back when we used wininet's cookie handling.
-TYPED_TEST_P(CookieStoreTest, NetUtilCookieTest) {
- const GURL test_url("http://mojo.jojo.google.izzle/");
-
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
-
- EXPECT_TRUE(this->SetCookie(cs, test_url, "foo=bar"));
- std::string value = this->GetCookies(cs, test_url);
- this->MatchCookieLines("foo=bar", value);
-
- // test that we can retrieve all cookies:
- EXPECT_TRUE(this->SetCookie(cs, test_url, "x=1"));
- EXPECT_TRUE(this->SetCookie(cs, test_url, "y=2"));
-
- std::string result = this->GetCookies(cs, test_url);
- EXPECT_FALSE(result.empty());
- EXPECT_NE(result.find("x=1"), std::string::npos) << result;
- EXPECT_NE(result.find("y=2"), std::string::npos) << result;
-}
-
TEST_F(CookieMonsterTest, TestDeleteSingleCookie) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
@@ -2381,62 +1541,6 @@ TEST_F(CookieMonsterTest, InitializeFromCookieMonster) {
EXPECT_EQ("/", it->Path());
}
-TYPED_TEST_P(CookieStoreTest, OverwritePersistentCookie) {
- GURL url_google("http://www.google.com/");
- GURL url_chromium("http://chromium.org");
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
-
- // Insert a cookie "a" for path "/path1"
- EXPECT_TRUE(
- this->SetCookie(cs, url_google, "a=val1; path=/path1; "
- "expires=Mon, 18-Apr-22 22:50:13 GMT"));
-
- // Insert a cookie "b" for path "/path1"
- EXPECT_TRUE(
- this->SetCookie(cs, url_google, "b=val1; path=/path1; "
- "expires=Mon, 18-Apr-22 22:50:14 GMT"));
-
- // Insert a cookie "b" for path "/path1", that is httponly. This should
- // overwrite the non-http-only version.
- CookieOptions allow_httponly;
- allow_httponly.set_include_httponly();
- EXPECT_TRUE(
- this->SetCookieWithOptions(cs, url_google,
- "b=val2; path=/path1; httponly; "
- "expires=Mon, 18-Apr-22 22:50:14 GMT",
- allow_httponly));
-
- // Insert a cookie "a" for path "/path1". This should overwrite.
- EXPECT_TRUE(this->SetCookie(cs, url_google,
- "a=val33; path=/path1; "
- "expires=Mon, 18-Apr-22 22:50:14 GMT"));
-
- // Insert a cookie "a" for path "/path2". This should NOT overwrite
- // cookie "a", since the path is different.
- EXPECT_TRUE(this->SetCookie(cs, url_google,
- "a=val9; path=/path2; "
- "expires=Mon, 18-Apr-22 22:50:14 GMT"));
-
- // Insert a cookie "a" for path "/path1", but this time for "chromium.org".
- // Although the name and path match, the hostnames do not, so shouldn't
- // overwrite.
- EXPECT_TRUE(this->SetCookie(cs, url_chromium,
- "a=val99; path=/path1; "
- "expires=Mon, 18-Apr-22 22:50:14 GMT"));
-
- if (TypeParam::supports_http_only) {
- this->MatchCookieLines("a=val33",
- this->GetCookies(cs, GURL("http://www.google.com/path1")));
- } else {
- this->MatchCookieLines("a=val33; b=val2",
- this->GetCookies(cs, GURL("http://www.google.com/path1")));
- }
- this->MatchCookieLines("a=val9",
- this->GetCookies(cs, GURL("http://www.google.com/path2")));
- this->MatchCookieLines("a=val99",
- this->GetCookies(cs, GURL("http://chromium.org/path1")));
-}
-
// Tests importing from a persistent cookie store that contains duplicate
// equivalent cookies. This situation should be handled by removing the
// duplicate cookie (both from the in-memory cache, and from the backing store).
@@ -2922,31 +2026,6 @@ TEST_F(CookieMonsterTest, BackingStoreCommunication) {
}
}
-TYPED_TEST_P(CookieStoreTest, CookieOrdering) {
- // Put a random set of cookies into a store and make sure they're returned in
- // the right order.
- // Cookies should be sorted by path length and creation time, as per RFC6265.
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_TRUE(this->SetCookie(cs, GURL("http://d.c.b.a.google.com/aa/x.html"),
- "c=1"));
- EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.google.com/aa/bb/cc/x.html"),
- "d=1; domain=b.a.google.com"));
- base::PlatformThread::Sleep(TypeParam::creation_time_granularity_in_ms);
- EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.google.com/aa/bb/cc/x.html"),
- "a=4; domain=b.a.google.com"));
- base::PlatformThread::Sleep(TypeParam::creation_time_granularity_in_ms);
- EXPECT_TRUE(this->SetCookie(cs,
- GURL("http://c.b.a.google.com/aa/bb/cc/x.html"),
- "e=1; domain=c.b.a.google.com"));
- EXPECT_TRUE(this->SetCookie(cs,
- GURL("http://d.c.b.a.google.com/aa/bb/x.html"),
- "b=1"));
- EXPECT_TRUE(this->SetCookie(cs, GURL("http://news.bbc.co.uk/midpath/x.html"),
- "g=10"));
- EXPECT_EQ("d=1; a=4; e=1; b=1; c=1",
- this->GetCookies(cs, GURL("http://d.c.b.a.google.com/aa/bb/cc/dd")));
-}
-
TEST_F(CookieMonsterTest, CookieListOrdering) {
// Put a random set of cookies into a monster and make sure
// they're returned in the right order.
@@ -3132,17 +2211,6 @@ TEST_F(CookieMonsterTest, KeepExpiredCookies) {
ASSERT_TRUE(cookie_list[0].IsExpired(Time::Now()));
}
-REGISTER_TYPED_TEST_CASE_P(CookieStoreTest,
- DomainTest, DomainWithTrailingDotTest, ValidSubdomainTest, InvalidDomainTest,
- DomainWithoutLeadingDotTest, CaseInsensitiveDomainTest, TestIpAddress,
- TestNonDottedAndTLD, TestHostEndsWithDot, InvalidScheme, InvalidScheme_Read,
- PathTest, HttpOnlyTest, TestGetCookiesWithInfo, TestCookieDeletion,
- TestSecure, NetUtilCookieTest, OverwritePersistentCookie, CookieOrdering);
-
-INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
- CookieStoreTest,
- CookieMonsterTestTraits);
-
namespace {
// Mock PersistentCookieStore that keeps track of the number of Flush() calls.
@@ -3314,77 +2382,6 @@ TEST_F(CookieMonsterTest, HistogramCheck) {
namespace {
-template<class CookieStoreTestTraits>
-class MultiThreadedCookieStoreTest :
- public CookieStoreTest<CookieStoreTestTraits> {
- public:
- MultiThreadedCookieStoreTest() : other_thread_("CMTthread") {}
-
- // Helper methods for calling the asynchronous CookieStore methods
- // from a different thread.
-
- void GetCookiesTask(CookieStore* cs,
- const GURL& url,
- GetCookieStringCallback* callback) {
- CookieOptions options;
- if (!CookieStoreTestTraits::supports_http_only)
- options.set_include_httponly();
- cs->GetCookiesWithOptionsAsync(
- url, options,
- base::Bind(&GetCookieStringCallback::Run, base::Unretained(callback)));
- }
-
- void GetCookiesWithOptionsTask(CookieStore* cs,
- const GURL& url,
- const CookieOptions& options,
- GetCookieStringCallback* callback) {
- cs->GetCookiesWithOptionsAsync(
- url, options,
- base::Bind(&GetCookieStringCallback::Run, base::Unretained(callback)));
- }
-
- void GetCookiesWithInfoTask(CookieStore* cs,
- const GURL& url,
- const CookieOptions& options,
- GetCookiesWithInfoCallback* callback) {
- cs->GetCookiesWithInfoAsync(
- url, options,
- base::Bind(&GetCookiesWithInfoCallback::Run,
- base::Unretained(callback)));
- }
-
- void SetCookieWithOptionsTask(CookieStore* cs,
- const GURL& url,
- const std::string& cookie_line,
- const CookieOptions& options,
- SetCookieCallback* callback) {
- cs->SetCookieWithOptionsAsync(
- url, cookie_line, options,
- base::Bind(&SetCookieCallback::Run, base::Unretained(callback)));
- }
-
- void DeleteCookieTask(CookieStore* cs,
- const GURL& url,
- const std::string& cookie_name,
- DeleteCookieCallback* callback) {
- cs->DeleteCookieAsync(
- url, cookie_name,
- base::Bind(&DeleteCookieCallback::Run, base::Unretained(callback)));
- }
-
- protected:
- void RunOnOtherThread(const base::Closure& task) {
- other_thread_.Start();
- other_thread_.message_loop()->PostTask(FROM_HERE, task);
- CookieStoreTest<CookieStoreTestTraits>::RunFor(kTimeout);
- other_thread_.Stop();
- }
-
- Thread other_thread_;
-};
-
-TYPED_TEST_CASE_P(MultiThreadedCookieStoreTest);
-
class MultiThreadedCookieMonsterTest : public CookieMonsterTest {
public:
MultiThreadedCookieMonsterTest() : other_thread_("CMTthread") {}
@@ -3470,69 +2467,6 @@ class MultiThreadedCookieMonsterTest : public CookieMonsterTest {
} // namespace
-// TODO(ycxiao): Eventually, we will need to create a separate thread, create
-// the cookie store on that thread (or at least its store, i.e., the DB
-// thread).
-TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckGetCookies) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B"));
- this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
- GetCookieStringCallback callback(&this->other_thread_);
- base::Closure task = base::Bind(
- &net::MultiThreadedCookieStoreTest<TypeParam>::GetCookiesTask,
- base::Unretained(this),
- cs, this->url_google_, &callback);
- this->RunOnOtherThread(task);
- EXPECT_TRUE(callback.did_run());
- EXPECT_EQ("A=B", callback.cookie());
-}
-
-TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckGetCookiesWithOptions) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- CookieOptions options;
- if (!TypeParam::supports_http_only)
- options.set_include_httponly();
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B"));
- this->MatchCookieLines("A=B",
- this->GetCookiesWithOptions(cs, this->url_google_, options));
- GetCookieStringCallback callback(&this->other_thread_);
- base::Closure task = base::Bind(
- &net::MultiThreadedCookieStoreTest<TypeParam>::GetCookiesWithOptionsTask,
- base::Unretained(this),
- cs, this->url_google_, options, &callback);
- this->RunOnOtherThread(task);
- EXPECT_TRUE(callback.did_run());
- EXPECT_EQ("A=B", callback.cookie());
-}
-
-TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckGetCookiesWithInfo) {
- if (!TypeParam::supports_cookies_with_info)
- return;
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- CookieOptions options;
- std::string cookie_line;
- std::vector<CookieStore::CookieInfo> cookie_infos;
- EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B"));
- this->GetCookiesWithInfo(cs, this->url_google_, options, &cookie_line,
- &cookie_infos);
- this->MatchCookieLines("A=B", cookie_line);
- EXPECT_EQ(1U, cookie_infos.size());
- EXPECT_EQ("A", cookie_infos[0].name);
- EXPECT_EQ("", cookie_infos[0].mac_key);
- EXPECT_EQ("", cookie_infos[0].mac_algorithm);
- GetCookiesWithInfoCallback callback(&this->other_thread_);
- base::Closure task = base::Bind(
- &net::MultiThreadedCookieStoreTest<TypeParam>::GetCookiesWithInfoTask,
- base::Unretained(this), cs, this->url_google_, options, &callback);
- this->RunOnOtherThread(task);
- EXPECT_TRUE(callback.did_run());
- this->MatchCookieLines("A=B", callback.cookie_line());
- EXPECT_EQ(1U, callback.cookie_info().size());
- EXPECT_EQ("A", callback.cookie_info()[0].name);
- EXPECT_EQ("", callback.cookie_info()[0].mac_key);
- EXPECT_EQ("", callback.cookie_info()[0].mac_algorithm);
-}
-
TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckGetAllCookies) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
EXPECT_TRUE(SetCookie(cm, url_google_, "A=B"));
@@ -3604,23 +2538,6 @@ TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckGetAllCookiesForURLWithOpt) {
ASSERT_TRUE(++it == callback.cookies().end());
}
-TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckSetCookieWithOptions) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- CookieOptions options;
- if (!TypeParam::supports_http_only)
- options.set_include_httponly();
- EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B",
- options));
- SetCookieCallback callback(&this->other_thread_);
- base::Closure task = base::Bind(
- &net::MultiThreadedCookieStoreTest<TypeParam>::SetCookieWithOptionsTask,
- base::Unretained(this),
- cs, this->url_google_, "A=B", options, &callback);
- this->RunOnOtherThread(task);
- EXPECT_TRUE(callback.did_run());
- EXPECT_TRUE(callback.result());
-}
-
TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckSetCookieWithDetails) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
EXPECT_TRUE(SetCookieWithDetails(
@@ -3637,24 +2554,6 @@ TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckSetCookieWithDetails) {
EXPECT_TRUE(callback.result());
}
-TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckDeleteCookie) {
- scoped_refptr<CookieStore> cs(this->GetCookieStore());
- CookieOptions options;
- if (!TypeParam::supports_http_only)
- options.set_include_httponly();
- EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B",
- options));
- this->DeleteCookie(cs, this->url_google_, "A");
- EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B",
- options));
- DeleteCookieCallback callback(&this->other_thread_);
- base::Closure task = base::Bind(
- &net::MultiThreadedCookieStoreTest<TypeParam>::DeleteCookieTask,
- base::Unretained(this),
- cs, this->url_google_, "A", &callback);
- this->RunOnOtherThread(task);
- EXPECT_TRUE(callback.did_run());
-}
TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteAllCreatedBetween) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
@@ -3712,15 +2611,6 @@ TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteCanonicalCookie) {
EXPECT_TRUE(callback.result());
}
-REGISTER_TYPED_TEST_CASE_P(MultiThreadedCookieStoreTest,
- ThreadCheckGetCookies, ThreadCheckGetCookiesWithOptions,
- ThreadCheckGetCookiesWithInfo, ThreadCheckSetCookieWithOptions,
- ThreadCheckDeleteCookie);
-
-INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
- MultiThreadedCookieStoreTest,
- CookieMonsterTestTraits);
-
TEST_F(CookieMonsterTest, ShortLivedSessionCookies) {
scoped_refptr<MockPersistentCookieStore> store(
new MockPersistentCookieStore);
diff --git a/net/base/cookie_store_test_callbacks.cc b/net/base/cookie_store_test_callbacks.cc
new file mode 100644
index 0000000..e16df06
--- /dev/null
+++ b/net/base/cookie_store_test_callbacks.cc
@@ -0,0 +1,65 @@
+// 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/base/cookie_store_test_callbacks.h"
+
+#include "base/message_loop.h"
+#include "base/threading/thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+CookieCallback::CookieCallback(base::Thread* run_in_thread)
+ : did_run_(false),
+ run_in_thread_(run_in_thread),
+ run_in_loop_(NULL),
+ parent_loop_(MessageLoop::current()),
+ loop_to_quit_(MessageLoop::current()) {}
+
+CookieCallback::CookieCallback()
+ : did_run_(false),
+ run_in_thread_(NULL),
+ run_in_loop_(MessageLoop::current()),
+ parent_loop_(NULL),
+ loop_to_quit_(MessageLoop::current()) {}
+
+void CookieCallback::CallbackEpilogue() {
+ MessageLoop* expected_loop = NULL;
+ if (run_in_thread_) {
+ DCHECK(!run_in_loop_);
+ expected_loop = run_in_thread_->message_loop();
+ } else if (run_in_loop_) {
+ expected_loop = run_in_loop_;
+ }
+ ASSERT_TRUE(expected_loop != NULL);
+
+ did_run_ = true;
+ EXPECT_EQ(expected_loop, MessageLoop::current());
+ loop_to_quit_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+}
+
+SetCookieCallback::SetCookieCallback() : result_(false) {}
+SetCookieCallback::SetCookieCallback(base::Thread* run_in_thread)
+ : CookieCallback(run_in_thread),
+ result_(false) {}
+
+GetCookieStringCallback::GetCookieStringCallback() {}
+GetCookieStringCallback::GetCookieStringCallback(base::Thread* run_in_thread)
+ : CookieCallback(run_in_thread) {}
+
+GetCookiesWithInfoCallback::GetCookiesWithInfoCallback() {}
+GetCookiesWithInfoCallback::GetCookiesWithInfoCallback(
+ base::Thread* run_in_thread) : CookieCallback(run_in_thread) {}
+GetCookiesWithInfoCallback::~GetCookiesWithInfoCallback() {}
+
+DeleteCallback::DeleteCallback() : num_deleted_(0) {}
+DeleteCallback::DeleteCallback(base::Thread* run_in_thread)
+ : CookieCallback(run_in_thread),
+ num_deleted_(0) {}
+
+DeleteCookieCallback::DeleteCookieCallback() {}
+DeleteCookieCallback::DeleteCookieCallback(base::Thread* run_in_thread)
+ : CookieCallback(run_in_thread) {}
+
+} // namespace net
diff --git a/net/base/cookie_store_test_callbacks.h b/net/base/cookie_store_test_callbacks.h
new file mode 100644
index 0000000..0957839
--- /dev/null
+++ b/net/base/cookie_store_test_callbacks.h
@@ -0,0 +1,137 @@
+// 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.
+
+#ifndef NET_BASE_COOKIE_STORE_TEST_CALLBACKS_H_
+#define NET_BASE_COOKIE_STORE_TEST_CALLBACKS_H_
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "net/base/cookie_store.h"
+
+class MessageLoop;
+
+namespace base {
+class Thread;
+}
+
+namespace net {
+
+// Defines common behaviour for the callbacks from GetCookies, SetCookies, etc.
+// Asserts that the current thread is the expected invocation thread, sends a
+// quit to the thread in which it was constructed.
+class CookieCallback {
+ public:
+ // Indicates whether the callback has been called.
+ bool did_run() { return did_run_; }
+
+ protected:
+ // Constructs a callback that expects to be called in the given thread and
+ // will, upon execution, send a QUIT to the constructing thread.
+ explicit CookieCallback(base::Thread* run_in_thread);
+
+ // Constructs a callback that expects to be called in current thread and will
+ // send a QUIT to the constructing thread.
+ CookieCallback();
+
+ // Tests whether the current thread was the caller's thread.
+ // Sends a QUIT to the constructing thread.
+ void CallbackEpilogue();
+
+ private:
+ bool did_run_;
+ base::Thread* run_in_thread_;
+ MessageLoop* run_in_loop_;
+ MessageLoop* parent_loop_;
+ MessageLoop* loop_to_quit_;
+};
+
+// Callback implementations for the asynchronous CookieStore methods.
+
+class SetCookieCallback : public CookieCallback {
+ public:
+ SetCookieCallback();
+ explicit SetCookieCallback(base::Thread* run_in_thread);
+
+ void Run(bool result) {
+ result_ = result;
+ CallbackEpilogue();
+ }
+
+ bool result() { return result_; }
+
+ private:
+ bool result_;
+};
+
+class GetCookieStringCallback : public CookieCallback {
+ public:
+ GetCookieStringCallback();
+ explicit GetCookieStringCallback(base::Thread* run_in_thread);
+
+ void Run(const std::string& cookie) {
+ cookie_ = cookie;
+ CallbackEpilogue();
+ }
+
+ const std::string& cookie() { return cookie_; }
+
+ private:
+ std::string cookie_;
+};
+
+class GetCookiesWithInfoCallback : public CookieCallback {
+ public:
+ GetCookiesWithInfoCallback();
+ explicit GetCookiesWithInfoCallback(base::Thread* run_in_thread);
+ ~GetCookiesWithInfoCallback();
+
+ void Run(
+ const std::string& cookie_line,
+ const std::vector<CookieStore::CookieInfo>& cookie_info) {
+ cookie_line_ = cookie_line;
+ cookie_info_ = cookie_info;
+ CallbackEpilogue();
+ }
+
+ const std::string& cookie_line() { return cookie_line_; }
+ const std::vector<CookieStore::CookieInfo>& cookie_info() {
+ return cookie_info_;
+ }
+
+ private:
+ std::string cookie_line_;
+ std::vector<CookieStore::CookieInfo> cookie_info_;
+};
+
+class DeleteCallback : public CookieCallback {
+ public:
+ DeleteCallback();
+ explicit DeleteCallback(base::Thread* run_in_thread);
+
+ void Run(int num_deleted) {
+ num_deleted_ = num_deleted;
+ CallbackEpilogue();
+ }
+
+ int num_deleted() { return num_deleted_; }
+
+ private:
+ int num_deleted_;
+};
+
+class DeleteCookieCallback : public CookieCallback {
+ public:
+ DeleteCookieCallback();
+ explicit DeleteCookieCallback(base::Thread* run_in_thread);
+
+ void Run() {
+ CallbackEpilogue();
+ }
+};
+
+} // namespace net
+
+#endif // NET_BASE_COOKIE_STORE_TEST_CALLBACKS_H_
diff --git a/net/base/cookie_store_unittest.h b/net/base/cookie_store_unittest.h
new file mode 100644
index 0000000..a537c9a
--- /dev/null
+++ b/net/base/cookie_store_unittest.h
@@ -0,0 +1,993 @@
+// 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.
+
+#ifndef NET_BASE_COOKIE_STORE_UNITTEST_H_
+#define NET_BASE_COOKIE_STORE_UNITTEST_H_
+#pragma once
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "base/string_tokenizer.h"
+#include "base/threading/thread.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/cookie_store.h"
+#include "net/base/cookie_store_test_callbacks.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// This file declares unittest templates that can be used to test common
+// behavior of any CookieStore implementation.
+// See cookie_monster_unittest.cc for an example of an implementation.
+
+namespace net {
+
+using base::Thread;
+
+const int kTimeout = 1000;
+
+const char kUrlFtp[] = "ftp://ftp.google.izzle/";
+const char kUrlGoogle[] = "http://www.google.izzle";
+const char kUrlGoogleFoo[] = "http://www.google.izzle/foo";
+const char kUrlGoogleBar[] = "http://www.google.izzle/bar";
+const char kUrlGoogleSecure[] = "https://www.google.izzle";
+const char kValidCookieLine[] = "A=B; path=/";
+const char kValidDomainCookieLine[] = "A=B; path=/; domain=google.izzle";
+
+// The CookieStoreTestTraits must have the following members:
+// struct CookieStoreTestTraits {
+// // Factory function.
+// static scoped_refptr<CookieStore> Create();
+//
+// // The cookie store is a CookieMonster. Only used to test
+// // GetCookieMonster().
+// static const bool is_cookie_monster;
+//
+// // The cookie store supports cookies with the exclude_httponly() option.
+// static const bool supports_http_only;
+//
+// // The cookie store supports the GetCookiesWithInfoAsync() method.
+// static const bool supports_cookies_with_info;
+//
+// // The cookie store is able to make the difference between the ".com"
+// // and the "com" domains.
+// static const bool supports_non_dotted_domains;
+//
+// // The cookie store handles the domains with trailing dots (such as "com.")
+// // correctly.
+// static const bool supports_trailing_dots;
+//
+// // The cookie store rejects cookies for invalid schemes such as ftp.
+// static const bool filters_schemes;
+//
+// // The cookie store has a bug happening when a path is a substring of
+// // another.
+// static const bool has_path_prefix_bug;
+//
+// // Time to wait between two cookie insertions to ensure that cookies have
+// // different creation times.
+// static const int creation_time_granularity_in_ms;
+// };
+
+template <class CookieStoreTestTraits>
+class CookieStoreTest : public testing::Test {
+ protected:
+ CookieStoreTest()
+ : url_google_(kUrlGoogle),
+ url_google_secure_(kUrlGoogleSecure),
+ url_google_foo_(kUrlGoogleFoo),
+ url_google_bar_(kUrlGoogleBar),
+ weak_factory_(MessageLoop::current()) {}
+
+ // Helper methods for the asynchronous Cookie Store API that call the
+ // asynchronous method and then pump the loop until the callback is invoked,
+ // finally returning the value.
+
+ std::string GetCookies(CookieStore* cs, const GURL& url) {
+ DCHECK(cs);
+ CookieOptions options;
+ if (!CookieStoreTestTraits::supports_http_only)
+ options.set_include_httponly();
+ GetCookieStringCallback callback;
+ cs->GetCookiesWithOptionsAsync(
+ url, options,
+ base::Bind(&GetCookieStringCallback::Run, base::Unretained(&callback)));
+ RunFor(kTimeout);
+ EXPECT_TRUE(callback.did_run());
+ return callback.cookie();
+ }
+
+ std::string GetCookiesWithOptions(CookieStore* cs,
+ const GURL& url,
+ const CookieOptions& options) {
+ DCHECK(cs);
+ GetCookieStringCallback callback;
+ cs->GetCookiesWithOptionsAsync(
+ url, options, base::Bind(&GetCookieStringCallback::Run,
+ base::Unretained(&callback)));
+ RunFor(kTimeout);
+ EXPECT_TRUE(callback.did_run());
+ return callback.cookie();
+ }
+
+ void GetCookiesWithInfo(CookieStore* cs,
+ const GURL& url,
+ const CookieOptions& options,
+ std::string* cookie_line,
+ std::vector<CookieStore::CookieInfo>* cookie_info) {
+ DCHECK(cs);
+ DCHECK(cookie_line);
+ DCHECK(cookie_info);
+ GetCookiesWithInfoCallback callback;
+ cs->GetCookiesWithInfoAsync(
+ url, options, base::Bind(&GetCookiesWithInfoCallback::Run,
+ base::Unretained(&callback)));
+ RunFor(kTimeout);
+ EXPECT_TRUE(callback.did_run());
+ *cookie_line = callback.cookie_line();
+ *cookie_info = callback.cookie_info();
+ }
+
+ bool SetCookieWithOptions(CookieStore* cs,
+ const GURL& url,
+ const std::string& cookie_line,
+ const CookieOptions& options) {
+ DCHECK(cs);
+ SetCookieCallback callback;
+ cs->SetCookieWithOptionsAsync(
+ url, cookie_line, options,
+ base::Bind(&SetCookieCallback::Run, base::Unretained(&callback)));
+ RunFor(kTimeout);
+ EXPECT_TRUE(callback.did_run());
+ return callback.result();
+ }
+
+ bool SetCookie(CookieStore* cs,
+ const GURL& url,
+ const std::string& cookie_line) {
+ CookieOptions options;
+ if (!CookieStoreTestTraits::supports_http_only)
+ options.set_include_httponly();
+ return SetCookieWithOptions(cs, url, cookie_line, options);
+ }
+
+ void DeleteCookie(CookieStore* cs,
+ const GURL& url,
+ const std::string& cookie_name) {
+ DCHECK(cs);
+ DeleteCookieCallback callback;
+ cs->DeleteCookieAsync(
+ url, cookie_name,
+ base::Bind(&DeleteCookieCallback::Run, base::Unretained(&callback)));
+ RunFor(kTimeout);
+ EXPECT_TRUE(callback.did_run());
+ }
+
+ void RunFor(int ms) {
+ // Runs the test thread message loop for up to |ms| milliseconds.
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, base::Bind(&MessageLoop::Quit, weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(ms));
+ MessageLoop::current()->Run();
+ weak_factory_.InvalidateWeakPtrs();
+ }
+
+ scoped_refptr<CookieStore> GetCookieStore() {
+ return CookieStoreTestTraits::Create();
+ }
+
+ // Compares two cookie lines.
+ void MatchCookieLines(const std::string& line1, const std::string& line2) {
+ EXPECT_EQ(TokenizeCookieLine(line1), TokenizeCookieLine(line2));
+ }
+
+ // Check the cookie line by polling until equality or a timeout is reached.
+ void MatchCookieLineWithTimeout(CookieStore* cs,
+ const GURL& url,
+ const std::string& line) {
+ std::string cookies = GetCookies(cs, url);
+ bool matched = (TokenizeCookieLine(line) == TokenizeCookieLine(cookies));
+ base::Time polling_end_date = base::Time::Now() +
+ base::TimeDelta::FromMilliseconds(
+ CookieStoreTestTraits::creation_time_granularity_in_ms);
+
+ while (!matched && base::Time::Now() <= polling_end_date) {
+ base::PlatformThread::Sleep(10);
+ cookies = GetCookies(cs, url);
+ matched = (TokenizeCookieLine(line) == TokenizeCookieLine(cookies));
+ }
+
+ EXPECT_TRUE(matched) << "\"" << cookies
+ << "\" does not match \"" << line << "\"";
+ }
+
+ GURL url_google_;
+ GURL url_google_secure_;
+ GURL url_google_foo_;
+ GURL url_google_bar_;
+
+ base::WeakPtrFactory<MessageLoop> weak_factory_;
+
+ private:
+ // Returns a set of strings of type "name=value". Fails in case of duplicate.
+ std::set<std::string> TokenizeCookieLine(const std::string& line) {
+ std::set<std::string> tokens;
+ StringTokenizer tokenizer(line, " ;");
+ while (tokenizer.GetNext())
+ EXPECT_TRUE(tokens.insert(tokenizer.token()).second);
+ return tokens;
+ }
+};
+
+TYPED_TEST_CASE_P(CookieStoreTest);
+
+TYPED_TEST_P(CookieStoreTest, TypeTest) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ EXPECT_EQ(cs->GetCookieMonster(),
+ (TypeParam::is_cookie_monster) ? cs.get() : NULL);
+}
+
+TYPED_TEST_P(CookieStoreTest, DomainTest) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B"));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
+ "C=D; domain=.google.izzle"));
+ this->MatchCookieLines("A=B; C=D", this->GetCookies(cs, this->url_google_));
+
+ // Verify that A=B was set as a host cookie rather than a domain
+ // cookie -- should not be accessible from a sub sub-domain.
+ this->MatchCookieLines("C=D",
+ this->GetCookies(cs, GURL("http://foo.www.google.izzle")));
+
+ // Test and make sure we find domain cookies on the same domain.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
+ "E=F; domain=.www.google.izzle"));
+ this->MatchCookieLines("A=B; C=D; E=F",
+ this->GetCookies(cs, this->url_google_));
+
+ // Test setting a domain= that doesn't start w/ a dot, should
+ // treat it as a domain cookie, as if there was a pre-pended dot.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
+ "G=H; domain=www.google.izzle"));
+ this->MatchCookieLines("A=B; C=D; E=F; G=H",
+ this->GetCookies(cs, this->url_google_));
+
+ // Test domain enforcement, should fail on a sub-domain or something too deep.
+ EXPECT_FALSE(this->SetCookie(cs, this->url_google_, "I=J; domain=.izzle"));
+ this->MatchCookieLines("", this->GetCookies(cs, GURL("http://a.izzle")));
+ EXPECT_FALSE(this->SetCookie(cs, this->url_google_,
+ "K=L; domain=.bla.www.google.izzle"));
+ this->MatchCookieLines("C=D; E=F; G=H",
+ this->GetCookies(cs, GURL("http://bla.www.google.izzle")));
+ this->MatchCookieLines("A=B; C=D; E=F; G=H",
+ this->GetCookies(cs, this->url_google_));
+}
+
+// FireFox recognizes domains containing trailing periods as valid.
+// IE and Safari do not. Assert the expected policy here.
+TYPED_TEST_P(CookieStoreTest, DomainWithTrailingDotTest) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ EXPECT_FALSE(this->SetCookie(cs, this->url_google_,
+ "a=1; domain=.www.google.com."));
+ EXPECT_FALSE(this->SetCookie(cs, this->url_google_,
+ "b=2; domain=.www.google.com.."));
+ this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
+}
+
+// Test that cookies can bet set on higher level domains.
+// http://b/issue?id=896491
+TYPED_TEST_P(CookieStoreTest, ValidSubdomainTest) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url_abcd("http://a.b.c.d.com");
+ GURL url_bcd("http://b.c.d.com");
+ GURL url_cd("http://c.d.com");
+ GURL url_d("http://d.com");
+
+ EXPECT_TRUE(this->SetCookie(cs, url_abcd, "a=1; domain=.a.b.c.d.com"));
+ EXPECT_TRUE(this->SetCookie(cs, url_abcd, "b=2; domain=.b.c.d.com"));
+ EXPECT_TRUE(this->SetCookie(cs, url_abcd, "c=3; domain=.c.d.com"));
+ EXPECT_TRUE(this->SetCookie(cs, url_abcd, "d=4; domain=.d.com"));
+
+ this->MatchCookieLines("a=1; b=2; c=3; d=4", this->GetCookies(cs, url_abcd));
+ this->MatchCookieLines("b=2; c=3; d=4", this->GetCookies(cs, url_bcd));
+ this->MatchCookieLines("c=3; d=4", this->GetCookies(cs, url_cd));
+ this->MatchCookieLines("d=4", this->GetCookies(cs, url_d));
+
+ // Check that the same cookie can exist on different sub-domains.
+ EXPECT_TRUE(this->SetCookie(cs, url_bcd, "X=bcd; domain=.b.c.d.com"));
+ EXPECT_TRUE(this->SetCookie(cs, url_bcd, "X=cd; domain=.c.d.com"));
+ this->MatchCookieLines("b=2; c=3; d=4; X=bcd; X=cd",
+ this->GetCookies(cs, url_bcd));
+ this->MatchCookieLines("c=3; d=4; X=cd", this->GetCookies(cs, url_cd));
+}
+
+// Test that setting a cookie which specifies an invalid domain has
+// no side-effect. An invalid domain in this context is one which does
+// not match the originating domain.
+// http://b/issue?id=896472
+TYPED_TEST_P(CookieStoreTest, InvalidDomainTest) {
+ {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url_foobar("http://foo.bar.com");
+
+ // More specific sub-domain than allowed.
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar,
+ "a=1; domain=.yo.foo.bar.com"));
+
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar, "b=2; domain=.foo.com"));
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar, "c=3; domain=.bar.foo.com"));
+
+ // Different TLD, but the rest is a substring.
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar,
+ "d=4; domain=.foo.bar.com.net"));
+
+ // A substring that isn't really a parent domain.
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar, "e=5; domain=ar.com"));
+
+ // Completely invalid domains:
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar, "f=6; domain=."));
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar, "g=7; domain=/"));
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar,
+ "h=8; domain=http://foo.bar.com"));
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar, "i=9; domain=..foo.bar.com"));
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar, "j=10; domain=..bar.com"));
+
+ // Make sure there isn't something quirky in the domain canonicalization
+ // that supports full URL semantics.
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar,
+ "k=11; domain=.foo.bar.com?blah"));
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar,
+ "l=12; domain=.foo.bar.com/blah"));
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar,
+ "m=13; domain=.foo.bar.com:80"));
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar,
+ "n=14; domain=.foo.bar.com:"));
+ EXPECT_FALSE(this->SetCookie(cs, url_foobar,
+ "o=15; domain=.foo.bar.com#sup"));
+
+ this->MatchCookieLines("", this->GetCookies(cs, url_foobar));
+ }
+
+ {
+ // Make sure the cookie code hasn't gotten its subdomain string handling
+ // reversed, missed a suffix check, etc. It's important here that the two
+ // hosts below have the same domain + registry.
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url_foocom("http://foo.com.com");
+ EXPECT_FALSE(this->SetCookie(cs, url_foocom,
+ "a=1; domain=.foo.com.com.com"));
+ this->MatchCookieLines("", this->GetCookies(cs, url_foocom));
+ }
+}
+
+// Test the behavior of omitting dot prefix from domain, should
+// function the same as FireFox.
+// http://b/issue?id=889898
+TYPED_TEST_P(CookieStoreTest, DomainWithoutLeadingDotTest) {
+ { // The omission of dot results in setting a domain cookie.
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url_hosted("http://manage.hosted.filefront.com");
+ GURL url_filefront("http://www.filefront.com");
+ EXPECT_TRUE(this->SetCookie(cs, url_hosted,
+ "sawAd=1; domain=filefront.com"));
+ this->MatchCookieLines("sawAd=1", this->GetCookies(cs, url_hosted));
+ this->MatchCookieLines("sawAd=1", this->GetCookies(cs, url_filefront));
+ }
+
+ { // Even when the domains match exactly, don't consider it host cookie.
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url("http://www.google.com");
+ EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=www.google.com"));
+ this->MatchCookieLines("a=1", this->GetCookies(cs, url));
+ this->MatchCookieLines("a=1",
+ this->GetCookies(cs, GURL("http://sub.www.google.com")));
+ this->MatchCookieLines("",
+ this->GetCookies(cs, GURL("http://something-else.com")));
+ }
+}
+
+// Test that the domain specified in cookie string is treated case-insensitive
+// http://b/issue?id=896475.
+TYPED_TEST_P(CookieStoreTest, CaseInsensitiveDomainTest) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url("http://www.google.com");
+ EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=.GOOGLE.COM"));
+ EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.wWw.gOOgLE.coM"));
+ this->MatchCookieLines("a=1; b=2", this->GetCookies(cs, url));
+}
+
+TYPED_TEST_P(CookieStoreTest, TestIpAddress) {
+ GURL url_ip("http://1.2.3.4/weee");
+ {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ EXPECT_TRUE(this->SetCookie(cs, url_ip, kValidCookieLine));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, url_ip));
+ }
+
+ { // IP addresses should not be able to set domain cookies.
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ EXPECT_FALSE(this->SetCookie(cs, url_ip, "b=2; domain=.1.2.3.4"));
+ EXPECT_FALSE(this->SetCookie(cs, url_ip, "c=3; domain=.3.4"));
+ this->MatchCookieLines("", this->GetCookies(cs, url_ip));
+ // It should be allowed to set a cookie if domain= matches the IP address
+ // exactly. This matches IE/Firefox, even though it seems a bit wrong.
+ EXPECT_FALSE(this->SetCookie(cs, url_ip, "b=2; domain=1.2.3.3"));
+ this->MatchCookieLines("", this->GetCookies(cs, url_ip));
+ EXPECT_TRUE(this->SetCookie(cs, url_ip, "b=2; domain=1.2.3.4"));
+ this->MatchCookieLines("b=2", this->GetCookies(cs, url_ip));
+ }
+}
+
+// Test host cookies, and setting of cookies on TLD.
+TYPED_TEST_P(CookieStoreTest, TestNonDottedAndTLD) {
+ {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url("http://com/");
+ // Allow setting on "com", (but only as a host cookie).
+ EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
+ EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.com"));
+ EXPECT_FALSE(this->SetCookie(cs, url, "c=3; domain=com"));
+ this->MatchCookieLines("a=1", this->GetCookies(cs, url));
+ // Make sure it doesn't show up for a normal .com, it should be a host
+ // not a domain cookie.
+ this->MatchCookieLines("",
+ this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/")));
+ if (TypeParam::supports_non_dotted_domains) {
+ this->MatchCookieLines("", this->GetCookies(cs, GURL("http://.com/")));
+ }
+ }
+
+ {
+ // http://com. should be treated the same as http://com.
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url("http://com./index.html");
+ if (TypeParam::supports_trailing_dots) {
+ EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
+ this->MatchCookieLines("a=1", this->GetCookies(cs, url));
+ this->MatchCookieLines("",
+ this->GetCookies(cs, GURL("http://hopefully-no-cookies.com./")));
+ } else {
+ EXPECT_FALSE(this->SetCookie(cs, url, "a=1"));
+ }
+ }
+
+ { // Should not be able to set host cookie from a subdomain.
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url("http://a.b");
+ EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.b"));
+ EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=b"));
+ this->MatchCookieLines("", this->GetCookies(cs, url));
+ }
+
+ { // Same test as above, but explicitly on a known TLD (com).
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url("http://google.com");
+ EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.com"));
+ EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=com"));
+ this->MatchCookieLines("", this->GetCookies(cs, url));
+ }
+
+ { // Make sure can't set cookie on TLD which is dotted.
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url("http://google.co.uk");
+ EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.co.uk"));
+ EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.uk"));
+ this->MatchCookieLines("", this->GetCookies(cs, url));
+ this->MatchCookieLines("",
+ this->GetCookies(cs, GURL("http://something-else.co.uk")));
+ this->MatchCookieLines("",
+ this->GetCookies(cs, GURL("http://something-else.uk")));
+ }
+
+ { // Intranet URLs should only be able to set host cookies.
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url("http://b");
+ EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
+ EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.b"));
+ EXPECT_FALSE(this->SetCookie(cs, url, "c=3; domain=b"));
+ this->MatchCookieLines("a=1", this->GetCookies(cs, url));
+ }
+}
+
+// Test reading/writing cookies when the domain ends with a period,
+// as in "www.google.com."
+TYPED_TEST_P(CookieStoreTest, TestHostEndsWithDot) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url("http://www.google.com");
+ GURL url_with_dot("http://www.google.com.");
+ EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
+ this->MatchCookieLines("a=1", this->GetCookies(cs, url));
+
+ if (TypeParam::supports_trailing_dots) {
+ // Do not share cookie space with the dot version of domain.
+ // Note: this is not what FireFox does, but it _is_ what IE+Safari do.
+ EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.www.google.com."));
+ this->MatchCookieLines("a=1", this->GetCookies(cs, url));
+
+ EXPECT_TRUE(this->SetCookie(cs, url_with_dot, "b=2; domain=.google.com."));
+ this->MatchCookieLines("b=2", this->GetCookies(cs, url_with_dot));
+ } else {
+ EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.www.google.com."));
+ EXPECT_FALSE(this->SetCookie(cs, url_with_dot, "b=2; domain=.google.com."));
+ }
+
+ // Make sure there weren't any side effects.
+ this->MatchCookieLines("",
+ this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/")));
+ this->MatchCookieLines("", this->GetCookies(cs, GURL("http://.com/")));
+}
+
+TYPED_TEST_P(CookieStoreTest, InvalidScheme) {
+ if (!TypeParam::filters_schemes)
+ return;
+
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ EXPECT_FALSE(this->SetCookie(cs, GURL(kUrlFtp), kValidCookieLine));
+}
+
+TYPED_TEST_P(CookieStoreTest, InvalidScheme_Read) {
+ if (!TypeParam::filters_schemes)
+ return;
+
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ EXPECT_TRUE(this->SetCookie(cs, GURL(kUrlGoogle), kValidDomainCookieLine));
+ this->MatchCookieLines("", this->GetCookies(cs, GURL(kUrlFtp)));
+}
+
+TYPED_TEST_P(CookieStoreTest, PathTest) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ std::string url("http://www.google.izzle");
+ EXPECT_TRUE(this->SetCookie(cs, GURL(url), "A=B; path=/wee"));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee")));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee/")));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee/war")));
+ this->MatchCookieLines("A=B",
+ this->GetCookies(cs, GURL(url + "/wee/war/more/more")));
+ if (!TypeParam::has_path_prefix_bug)
+ this->MatchCookieLines("", this->GetCookies(cs, GURL(url + "/weehee")));
+ this->MatchCookieLines("", this->GetCookies(cs, GURL(url + "/")));
+
+ // If we add a 0 length path, it should default to /
+ EXPECT_TRUE(this->SetCookie(cs, GURL(url), "A=C; path="));
+ this->MatchCookieLines("A=B; A=C", this->GetCookies(cs, GURL(url + "/wee")));
+ this->MatchCookieLines("A=C", this->GetCookies(cs, GURL(url + "/")));
+}
+
+TYPED_TEST_P(CookieStoreTest, HttpOnlyTest) {
+ if (!TypeParam::supports_http_only)
+ return;
+
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ CookieOptions options;
+ options.set_include_httponly();
+
+ // Create a httponly cookie.
+ EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B; httponly",
+ options));
+
+ // Check httponly read protection.
+ this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
+ this->MatchCookieLines("A=B",
+ this->GetCookiesWithOptions(cs, this->url_google_, options));
+
+ // Check httponly overwrite protection.
+ EXPECT_FALSE(this->SetCookie(cs, this->url_google_, "A=C"));
+ this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
+ this->MatchCookieLines("A=B",
+ this->GetCookiesWithOptions(cs, this->url_google_, options));
+ EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=C",
+ options));
+ this->MatchCookieLines("A=C", this->GetCookies(cs, this->url_google_));
+
+ // Check httponly create protection.
+ EXPECT_FALSE(this->SetCookie(cs, this->url_google_, "B=A; httponly"));
+ this->MatchCookieLines("A=C",
+ this->GetCookiesWithOptions(cs, this->url_google_, options));
+ EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "B=A; httponly",
+ options));
+ this->MatchCookieLines("A=C; B=A",
+ this->GetCookiesWithOptions(cs, this->url_google_, options));
+ this->MatchCookieLines("A=C", this->GetCookies(cs, this->url_google_));
+}
+
+TYPED_TEST_P(CookieStoreTest, TestGetCookiesWithInfo) {
+ if (!TypeParam::supports_cookies_with_info)
+ return;
+
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ CookieOptions options;
+
+ EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B",
+ options));
+ EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_,
+ "C=D; Mac-Key=390jfn0awf3; Mac-Algorithm=hmac-sha-1", options));
+
+ this->MatchCookieLines("A=B; C=D",
+ this->GetCookiesWithOptions(cs, this->url_google_, options));
+
+ std::string cookie_line;
+ std::vector<CookieStore::CookieInfo> cookie_infos;
+
+ this->GetCookiesWithInfo(cs, this->url_google_, options, &cookie_line,
+ &cookie_infos);
+
+ EXPECT_EQ("A=B; C=D", cookie_line);
+
+ EXPECT_EQ(2U, cookie_infos.size());
+
+ EXPECT_EQ("A", cookie_infos[0].name);
+ EXPECT_EQ("", cookie_infos[0].mac_key);
+ EXPECT_EQ("", cookie_infos[0].mac_algorithm);
+
+ EXPECT_EQ("C", cookie_infos[1].name);
+ EXPECT_EQ("390jfn0awf3", cookie_infos[1].mac_key);
+ EXPECT_EQ("hmac-sha-1", cookie_infos[1].mac_algorithm);
+}
+
+TYPED_TEST_P(CookieStoreTest, TestCookieDeletion) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+
+ // Create a session cookie.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_, kValidCookieLine));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
+ // Delete it via Max-Age.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
+ std::string(kValidCookieLine) + "; max-age=0"));
+ this->MatchCookieLineWithTimeout(cs, this->url_google_, "");
+
+ // Create a session cookie.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_, kValidCookieLine));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
+ // Delete it via Expires.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
+ std::string(kValidCookieLine) +
+ "; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
+ this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
+
+ // Create a persistent cookie.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
+ std::string(kValidCookieLine) +
+ "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
+
+ this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
+ // Delete it via Max-Age.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
+ std::string(kValidCookieLine) + "; max-age=0"));
+ this->MatchCookieLineWithTimeout(cs, this->url_google_, "");
+
+ // Create a persistent cookie.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
+ std::string(kValidCookieLine) +
+ "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
+ // Delete it via Expires.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
+ std::string(kValidCookieLine) +
+ "; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
+ this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
+
+ // Create a persistent cookie.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
+ std::string(kValidCookieLine) +
+ "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
+ // Delete it via Expires, with a unix epoch of 0.
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_,
+ std::string(kValidCookieLine) +
+ "; expires=Thu, 1-Jan-1970 00:00:00 GMT"));
+ this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
+}
+
+TYPED_TEST_P(CookieStoreTest, TestSecure) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B"));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_secure_));
+
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_secure_, "A=B; secure"));
+ // The secure should overwrite the non-secure.
+ this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_secure_));
+
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_secure_, "D=E; secure"));
+ this->MatchCookieLines("", this->GetCookies(cs, this->url_google_));
+ this->MatchCookieLines("A=B; D=E",
+ this->GetCookies(cs, this->url_google_secure_));
+
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_secure_, "A=B"));
+ // The non-secure should overwrite the secure.
+ this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
+ this->MatchCookieLines("D=E; A=B",
+ this->GetCookies(cs, this->url_google_secure_));
+}
+
+static const int kLastAccessThresholdMilliseconds = 200;
+
+// Formerly NetUtilTest.CookieTest back when we used wininet's cookie handling.
+TYPED_TEST_P(CookieStoreTest, NetUtilCookieTest) {
+ const GURL test_url("http://mojo.jojo.google.izzle/");
+
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+
+ EXPECT_TRUE(this->SetCookie(cs, test_url, "foo=bar"));
+ std::string value = this->GetCookies(cs, test_url);
+ this->MatchCookieLines("foo=bar", value);
+
+ // test that we can retrieve all cookies:
+ EXPECT_TRUE(this->SetCookie(cs, test_url, "x=1"));
+ EXPECT_TRUE(this->SetCookie(cs, test_url, "y=2"));
+
+ std::string result = this->GetCookies(cs, test_url);
+ EXPECT_FALSE(result.empty());
+ EXPECT_NE(result.find("x=1"), std::string::npos) << result;
+ EXPECT_NE(result.find("y=2"), std::string::npos) << result;
+}
+
+TYPED_TEST_P(CookieStoreTest, OverwritePersistentCookie) {
+ GURL url_google("http://www.google.com/");
+ GURL url_chromium("http://chromium.org");
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+
+ // Insert a cookie "a" for path "/path1"
+ EXPECT_TRUE(
+ this->SetCookie(cs, url_google, "a=val1; path=/path1; "
+ "expires=Mon, 18-Apr-22 22:50:13 GMT"));
+
+ // Insert a cookie "b" for path "/path1"
+ EXPECT_TRUE(
+ this->SetCookie(cs, url_google, "b=val1; path=/path1; "
+ "expires=Mon, 18-Apr-22 22:50:14 GMT"));
+
+ // Insert a cookie "b" for path "/path1", that is httponly. This should
+ // overwrite the non-http-only version.
+ CookieOptions allow_httponly;
+ allow_httponly.set_include_httponly();
+ EXPECT_TRUE(
+ this->SetCookieWithOptions(cs, url_google,
+ "b=val2; path=/path1; httponly; "
+ "expires=Mon, 18-Apr-22 22:50:14 GMT",
+ allow_httponly));
+
+ // Insert a cookie "a" for path "/path1". This should overwrite.
+ EXPECT_TRUE(this->SetCookie(cs, url_google,
+ "a=val33; path=/path1; "
+ "expires=Mon, 18-Apr-22 22:50:14 GMT"));
+
+ // Insert a cookie "a" for path "/path2". This should NOT overwrite
+ // cookie "a", since the path is different.
+ EXPECT_TRUE(this->SetCookie(cs, url_google,
+ "a=val9; path=/path2; "
+ "expires=Mon, 18-Apr-22 22:50:14 GMT"));
+
+ // Insert a cookie "a" for path "/path1", but this time for "chromium.org".
+ // Although the name and path match, the hostnames do not, so shouldn't
+ // overwrite.
+ EXPECT_TRUE(this->SetCookie(cs, url_chromium,
+ "a=val99; path=/path1; "
+ "expires=Mon, 18-Apr-22 22:50:14 GMT"));
+
+ if (TypeParam::supports_http_only) {
+ this->MatchCookieLines("a=val33",
+ this->GetCookies(cs, GURL("http://www.google.com/path1")));
+ } else {
+ this->MatchCookieLines("a=val33; b=val2",
+ this->GetCookies(cs, GURL("http://www.google.com/path1")));
+ }
+ this->MatchCookieLines("a=val9",
+ this->GetCookies(cs, GURL("http://www.google.com/path2")));
+ this->MatchCookieLines("a=val99",
+ this->GetCookies(cs, GURL("http://chromium.org/path1")));
+}
+
+TYPED_TEST_P(CookieStoreTest, CookieOrdering) {
+ // Put a random set of cookies into a store and make sure they're returned in
+ // the right order.
+ // Cookies should be sorted by path length and creation time, as per RFC6265.
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ EXPECT_TRUE(this->SetCookie(cs, GURL("http://d.c.b.a.google.com/aa/x.html"),
+ "c=1"));
+ EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.google.com/aa/bb/cc/x.html"),
+ "d=1; domain=b.a.google.com"));
+ base::PlatformThread::Sleep(TypeParam::creation_time_granularity_in_ms);
+ EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.google.com/aa/bb/cc/x.html"),
+ "a=4; domain=b.a.google.com"));
+ base::PlatformThread::Sleep(TypeParam::creation_time_granularity_in_ms);
+ EXPECT_TRUE(this->SetCookie(cs,
+ GURL("http://c.b.a.google.com/aa/bb/cc/x.html"),
+ "e=1; domain=c.b.a.google.com"));
+ EXPECT_TRUE(this->SetCookie(cs,
+ GURL("http://d.c.b.a.google.com/aa/bb/x.html"),
+ "b=1"));
+ EXPECT_TRUE(this->SetCookie(cs, GURL("http://news.bbc.co.uk/midpath/x.html"),
+ "g=10"));
+ EXPECT_EQ("d=1; a=4; e=1; b=1; c=1",
+ this->GetCookies(cs, GURL("http://d.c.b.a.google.com/aa/bb/cc/dd")));
+}
+
+REGISTER_TYPED_TEST_CASE_P(CookieStoreTest,
+ TypeTest, DomainTest, DomainWithTrailingDotTest, ValidSubdomainTest,
+ InvalidDomainTest, DomainWithoutLeadingDotTest, CaseInsensitiveDomainTest,
+ TestIpAddress, TestNonDottedAndTLD, TestHostEndsWithDot, InvalidScheme,
+ InvalidScheme_Read, PathTest, HttpOnlyTest, TestGetCookiesWithInfo,
+ TestCookieDeletion, TestSecure, NetUtilCookieTest,
+ OverwritePersistentCookie, CookieOrdering);
+
+template<class CookieStoreTestTraits>
+class MultiThreadedCookieStoreTest :
+ public CookieStoreTest<CookieStoreTestTraits> {
+ public:
+ MultiThreadedCookieStoreTest() : other_thread_("CMTthread") {}
+
+ // Helper methods for calling the asynchronous CookieStore methods
+ // from a different thread.
+
+ void GetCookiesTask(CookieStore* cs,
+ const GURL& url,
+ GetCookieStringCallback* callback) {
+ CookieOptions options;
+ if (!CookieStoreTestTraits::supports_http_only)
+ options.set_include_httponly();
+ cs->GetCookiesWithOptionsAsync(
+ url, options,
+ base::Bind(&GetCookieStringCallback::Run, base::Unretained(callback)));
+ }
+
+ void GetCookiesWithOptionsTask(CookieStore* cs,
+ const GURL& url,
+ const CookieOptions& options,
+ GetCookieStringCallback* callback) {
+ cs->GetCookiesWithOptionsAsync(
+ url, options,
+ base::Bind(&GetCookieStringCallback::Run, base::Unretained(callback)));
+ }
+
+ void GetCookiesWithInfoTask(CookieStore* cs,
+ const GURL& url,
+ const CookieOptions& options,
+ GetCookiesWithInfoCallback* callback) {
+ cs->GetCookiesWithInfoAsync(
+ url, options,
+ base::Bind(&GetCookiesWithInfoCallback::Run,
+ base::Unretained(callback)));
+ }
+
+ void SetCookieWithOptionsTask(CookieStore* cs,
+ const GURL& url,
+ const std::string& cookie_line,
+ const CookieOptions& options,
+ SetCookieCallback* callback) {
+ cs->SetCookieWithOptionsAsync(
+ url, cookie_line, options,
+ base::Bind(&SetCookieCallback::Run, base::Unretained(callback)));
+ }
+
+ void DeleteCookieTask(CookieStore* cs,
+ const GURL& url,
+ const std::string& cookie_name,
+ DeleteCookieCallback* callback) {
+ cs->DeleteCookieAsync(
+ url, cookie_name,
+ base::Bind(&DeleteCookieCallback::Run, base::Unretained(callback)));
+ }
+
+ protected:
+ void RunOnOtherThread(const base::Closure& task) {
+ other_thread_.Start();
+ other_thread_.message_loop()->PostTask(FROM_HERE, task);
+ CookieStoreTest<CookieStoreTestTraits>::RunFor(kTimeout);
+ other_thread_.Stop();
+ }
+
+ Thread other_thread_;
+};
+
+TYPED_TEST_CASE_P(MultiThreadedCookieStoreTest);
+
+// TODO(ycxiao): Eventually, we will need to create a separate thread, create
+// the cookie store on that thread (or at least its store, i.e., the DB
+// thread).
+TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckGetCookies) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B"));
+ this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_));
+ GetCookieStringCallback callback(&this->other_thread_);
+ base::Closure task = base::Bind(
+ &net::MultiThreadedCookieStoreTest<TypeParam>::GetCookiesTask,
+ base::Unretained(this),
+ cs, this->url_google_, &callback);
+ this->RunOnOtherThread(task);
+ EXPECT_TRUE(callback.did_run());
+ EXPECT_EQ("A=B", callback.cookie());
+}
+
+TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckGetCookiesWithOptions) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ CookieOptions options;
+ if (!TypeParam::supports_http_only)
+ options.set_include_httponly();
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B"));
+ this->MatchCookieLines("A=B",
+ this->GetCookiesWithOptions(cs, this->url_google_, options));
+ GetCookieStringCallback callback(&this->other_thread_);
+ base::Closure task = base::Bind(
+ &net::MultiThreadedCookieStoreTest<TypeParam>::GetCookiesWithOptionsTask,
+ base::Unretained(this),
+ cs, this->url_google_, options, &callback);
+ this->RunOnOtherThread(task);
+ EXPECT_TRUE(callback.did_run());
+ EXPECT_EQ("A=B", callback.cookie());
+}
+
+TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckGetCookiesWithInfo) {
+ if (!TypeParam::supports_cookies_with_info)
+ return;
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ CookieOptions options;
+ std::string cookie_line;
+ std::vector<CookieStore::CookieInfo> cookie_infos;
+ EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B"));
+ this->GetCookiesWithInfo(cs, this->url_google_, options, &cookie_line,
+ &cookie_infos);
+ this->MatchCookieLines("A=B", cookie_line);
+ EXPECT_EQ(1U, cookie_infos.size());
+ EXPECT_EQ("A", cookie_infos[0].name);
+ EXPECT_EQ("", cookie_infos[0].mac_key);
+ EXPECT_EQ("", cookie_infos[0].mac_algorithm);
+ GetCookiesWithInfoCallback callback(&this->other_thread_);
+ base::Closure task = base::Bind(
+ &net::MultiThreadedCookieStoreTest<TypeParam>::GetCookiesWithInfoTask,
+ base::Unretained(this), cs, this->url_google_, options, &callback);
+ this->RunOnOtherThread(task);
+ EXPECT_TRUE(callback.did_run());
+ this->MatchCookieLines("A=B", callback.cookie_line());
+ EXPECT_EQ(1U, callback.cookie_info().size());
+ EXPECT_EQ("A", callback.cookie_info()[0].name);
+ EXPECT_EQ("", callback.cookie_info()[0].mac_key);
+ EXPECT_EQ("", callback.cookie_info()[0].mac_algorithm);
+}
+
+TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckSetCookieWithOptions) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ CookieOptions options;
+ if (!TypeParam::supports_http_only)
+ options.set_include_httponly();
+ EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B",
+ options));
+ SetCookieCallback callback(&this->other_thread_);
+ base::Closure task = base::Bind(
+ &net::MultiThreadedCookieStoreTest<TypeParam>::SetCookieWithOptionsTask,
+ base::Unretained(this),
+ cs, this->url_google_, "A=B", options, &callback);
+ this->RunOnOtherThread(task);
+ EXPECT_TRUE(callback.did_run());
+ EXPECT_TRUE(callback.result());
+}
+
+TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckDeleteCookie) {
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ CookieOptions options;
+ if (!TypeParam::supports_http_only)
+ options.set_include_httponly();
+ EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B",
+ options));
+ this->DeleteCookie(cs, this->url_google_, "A");
+ EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B",
+ options));
+ DeleteCookieCallback callback(&this->other_thread_);
+ base::Closure task = base::Bind(
+ &net::MultiThreadedCookieStoreTest<TypeParam>::DeleteCookieTask,
+ base::Unretained(this),
+ cs, this->url_google_, "A", &callback);
+ this->RunOnOtherThread(task);
+ EXPECT_TRUE(callback.did_run());
+}
+
+REGISTER_TYPED_TEST_CASE_P(MultiThreadedCookieStoreTest,
+ ThreadCheckGetCookies, ThreadCheckGetCookiesWithOptions,
+ ThreadCheckGetCookiesWithInfo, ThreadCheckSetCookieWithOptions,
+ ThreadCheckDeleteCookie);
+
+} // namespace net
+
+#endif // NET_BASE_COOKIE_STORE_UNITTEST_H_
diff --git a/net/base/cookie_util_unittest.cc b/net/base/cookie_util_unittest.cc
new file mode 100644
index 0000000..4c3db80
--- /dev/null
+++ b/net/base/cookie_util_unittest.cc
@@ -0,0 +1,23 @@
+// 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 "base/basictypes.h"
+#include "net/base/cookie_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(CookieUtilTest, TestDomainIsHostOnly) {
+ const struct {
+ const char* str;
+ const bool is_host_only;
+ } tests[] = {
+ { "", true },
+ { "www.google.com", true },
+ { ".google.com", false }
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ EXPECT_EQ(tests[i].is_host_only,
+ net::cookie_util::DomainIsHostOnly(tests[i].str));
+ }
+}
diff --git a/net/net.gyp b/net/net.gyp
index 46327a1..f991318 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -1008,6 +1008,8 @@
'base/cert_database_nss_unittest.cc',
'base/cert_verifier_unittest.cc',
'base/cookie_monster_unittest.cc',
+ 'base/cookie_store_unittest.h',
+ 'base/cookie_util_unittest.cc',
'base/crl_set_unittest.cc',
'base/data_url_unittest.cc',
'base/default_origin_bound_cert_store_unittest.cc',
@@ -1088,7 +1090,7 @@
'ftp/ftp_network_transaction_unittest.cc',
'ftp/ftp_util_unittest.cc',
'http/des_unittest.cc',
- 'http/disk_cache_based_ssl_host_info_unittest.cc',
+ 'http/disk_cache_based_ssl_host_info_unittest.cc',
'http/http_auth_cache_unittest.cc',
'http/http_auth_controller_unittest.cc',
'http/http_auth_filter_unittest.cc',
@@ -1129,7 +1131,7 @@
'http/mock_gssapi_library_posix.cc',
'http/mock_gssapi_library_posix.h',
'http/mock_http_cache.cc',
- 'http/mock_http_cache.h',
+ 'http/mock_http_cache.h',
'http/mock_sspi_library_win.h',
'http/mock_sspi_library_win.cc',
'http/url_security_manager_unittest.cc',
@@ -1393,6 +1395,8 @@
'base/cert_test_util.h',
'base/cookie_monster_store_test.cc',
'base/cookie_monster_store_test.h',
+ 'base/cookie_store_test_callbacks.cc',
+ 'base/cookie_store_test_callbacks.h',
'base/cookie_store_test_helpers.cc',
'base/cookie_store_test_helpers.h',
'base/mock_file_stream.cc',