mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-28 16:26:10 +03:00
1849 lines
77 KiB
C++
1849 lines
77 KiB
C++
// 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_COOKIES_COOKIE_STORE_UNITTEST_H_
|
|
#define NET_COOKIES_COOKIE_STORE_UNITTEST_H_
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <memory>
|
|
#include <set>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "base/bind.h"
|
|
#include "base/location.h"
|
|
#include "base/message_loop/message_loop_current.h"
|
|
#include "base/single_thread_task_runner.h"
|
|
#include "base/strings/string_tokenizer.h"
|
|
#include "base/test/task_environment.h"
|
|
#include "base/threading/thread.h"
|
|
#include "base/threading/thread_task_runner_handle.h"
|
|
#include "net/cookies/canonical_cookie.h"
|
|
#include "net/cookies/cookie_store.h"
|
|
#include "net/cookies/cookie_store_test_callbacks.h"
|
|
#include "net/cookies/cookie_store_test_helpers.h"
|
|
#include "net/cookies/test_cookie_access_delegate.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "url/gurl.h"
|
|
|
|
#if defined(OS_IOS)
|
|
#include "base/ios/ios_util.h"
|
|
#endif
|
|
|
|
// 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;
|
|
using TimeRange = CookieDeletionInfo::TimeRange;
|
|
|
|
const int kTimeout = 1000;
|
|
|
|
const char kValidCookieLine[] = "A=B; path=/";
|
|
|
|
// The CookieStoreTestTraits must have the following members:
|
|
// struct CookieStoreTestTraits {
|
|
// // Factory function. Will be called at most once per test.
|
|
// static std::unique_ptr<CookieStore> Create();
|
|
//
|
|
// // Drains the run loop(s) used to deliver cookie change notifications.
|
|
// static void DeliverChangeNotifications();
|
|
//
|
|
// // The cookie store supports cookies with the exclude_httponly() option.
|
|
// static const bool supports_http_only;
|
|
//
|
|
// // 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 does not fold domains with trailing dots (so "com." and
|
|
// "com" are different domains).
|
|
// static const bool preserves_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;
|
|
//
|
|
// // The cookie store forbids setting a cookie with an empty name.
|
|
// static const bool forbids_setting_empty_name;
|
|
//
|
|
// // The cookie store supports global tracking of cookie changes (i.e.
|
|
// // calls to CookieStore::AddCallbackForAllChanges()).
|
|
// static const bool supports_global_cookie_tracking;
|
|
//
|
|
// // The cookie store supports tracking of cookie changes for an URL (i.e.
|
|
// // calls to CookieStore::AddCallbackForUrl()).
|
|
// static const bool supports_url_cookie_tracking;
|
|
//
|
|
// // The cookie store supports tracking of named cookie changes (i.e.
|
|
// // calls to CookieStore::AddCallbackForCookie()).
|
|
// static const bool supports_named_cookie_tracking;
|
|
//
|
|
// // The cookie store supports more than one callback per cookie change type.
|
|
// static const bool supports_multiple_tracking_callbacks;
|
|
//
|
|
// // The cookie store correctly distinguishes between OVERWRITE and EXPLICIT
|
|
// // (deletion) change causes.
|
|
// static const bool has_exact_change_cause;
|
|
//
|
|
// // The cookie store is guaranteed to deliver cookie changes in the order
|
|
// // in which calls were issued. This only applies to changes coming from
|
|
// // _different_ calls. If a call results in a cookie overwrite, the deletion
|
|
// // change must still be issued before the insertion change.
|
|
// static const bool has_exact_change_ordering;
|
|
//
|
|
// // Time to wait between two cookie insertions to ensure that cookies have
|
|
// // different creation times.
|
|
// static const int creation_time_granularity_in_ms;
|
|
//
|
|
// // The cookie store supports setting a CookieAccessDelegate and using it to
|
|
// // get the access semantics for each cookie via
|
|
// // CookieStore::GetAllCookiesWithAccessSemanticsAsync().
|
|
// // If this is not supported, all access semantics will show up as UNKNOWN.
|
|
// static const bool supports_cookie_access_semantics;
|
|
// };
|
|
|
|
template <class CookieStoreTestTraits>
|
|
class CookieStoreTest : public testing::Test {
|
|
protected:
|
|
CookieStoreTest()
|
|
: http_www_foo_("http://www.foo.com"),
|
|
http_bar_foo_("http://bar.foo.com"),
|
|
http_www_bar_("http://www.bar.com"),
|
|
https_www_foo_("https://www.foo.com"),
|
|
ftp_foo_("ftp://ftp.foo.com/"),
|
|
ws_www_foo_("ws://www.foo.com"),
|
|
wss_www_foo_("wss://www.foo.com"),
|
|
www_foo_foo_("http://www.foo.com/foo"),
|
|
www_foo_bar_("http://www.foo.com/bar"),
|
|
http_baz_com_("http://baz.com"),
|
|
http_bar_com_("http://bar.com") {
|
|
// This test may be used outside of the net test suite, and thus may not
|
|
// have a task environment.
|
|
if (!base::MessageLoopCurrent::Get()) {
|
|
task_environment_ =
|
|
std::make_unique<base::test::SingleThreadTaskEnvironment>();
|
|
}
|
|
}
|
|
|
|
// 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.
|
|
// TODO(chlily): Consolidate some of these.
|
|
|
|
std::string GetCookies(CookieStore* cs, const GURL& url) {
|
|
DCHECK(cs);
|
|
CookieOptions options;
|
|
if (!CookieStoreTestTraits::supports_http_only)
|
|
options.set_include_httponly();
|
|
options.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
return GetCookiesWithOptions(cs, url, options);
|
|
}
|
|
|
|
std::string GetCookiesWithOptions(CookieStore* cs,
|
|
const GURL& url,
|
|
const CookieOptions& options) {
|
|
return CanonicalCookie::BuildCookieLine(
|
|
GetCookieListWithOptions(cs, url, options));
|
|
}
|
|
|
|
CookieList GetCookieListWithOptions(CookieStore* cs,
|
|
const GURL& url,
|
|
const CookieOptions& options) {
|
|
DCHECK(cs);
|
|
GetCookieListCallback callback;
|
|
cs->GetCookieListWithOptionsAsync(url, options, callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.cookies();
|
|
}
|
|
|
|
// This does not update the access time on the cookies.
|
|
CookieList GetAllCookiesForURL(CookieStore* cs, const GURL& url) {
|
|
return GetCookieListWithOptions(cs, url, CookieOptions::MakeAllInclusive());
|
|
}
|
|
|
|
// This does not update the access time on the cookies.
|
|
CookieStatusList GetExcludedCookiesForURL(CookieStore* cs, const GURL& url) {
|
|
DCHECK(cs);
|
|
GetCookieListCallback callback;
|
|
CookieOptions options = CookieOptions::MakeAllInclusive();
|
|
options.set_return_excluded_cookies();
|
|
cs->GetCookieListWithOptionsAsync(url, options, callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.excluded_cookies();
|
|
}
|
|
|
|
CookieList GetAllCookies(CookieStore* cs) {
|
|
DCHECK(cs);
|
|
GetAllCookiesCallback callback;
|
|
cs->GetAllCookiesAsync(callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.cookies();
|
|
}
|
|
|
|
bool CreateAndSetCookie(
|
|
CookieStore* cs,
|
|
const GURL& url,
|
|
const std::string& cookie_line,
|
|
const CookieOptions& options,
|
|
base::Optional<base::Time> server_time = base::nullopt) {
|
|
auto cookie = CanonicalCookie::Create(url, cookie_line, base::Time::Now(),
|
|
server_time);
|
|
if (!cookie)
|
|
return false;
|
|
DCHECK(cs);
|
|
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
|
|
cs->SetCanonicalCookieAsync(std::move(cookie), url.scheme(), options,
|
|
callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.result().IsInclude();
|
|
}
|
|
|
|
bool SetCanonicalCookie(CookieStore* cs,
|
|
std::unique_ptr<CanonicalCookie> cookie,
|
|
std::string source_scheme,
|
|
bool can_modify_httponly) {
|
|
DCHECK(cs);
|
|
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
|
|
CookieOptions options;
|
|
if (can_modify_httponly)
|
|
options.set_include_httponly();
|
|
options.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
cs->SetCanonicalCookieAsync(std::move(cookie), std::move(source_scheme),
|
|
options, callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.result().IsInclude();
|
|
}
|
|
|
|
bool SetCookieWithServerTime(CookieStore* cs,
|
|
const GURL& url,
|
|
const std::string& cookie_line,
|
|
const base::Time& server_time) {
|
|
CookieOptions options;
|
|
if (!CookieStoreTestTraits::supports_http_only)
|
|
options.set_include_httponly();
|
|
options.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
return CreateAndSetCookie(cs, url, cookie_line, options,
|
|
base::make_optional(server_time));
|
|
}
|
|
|
|
bool SetCookie(CookieStore* cs,
|
|
const GURL& url,
|
|
const std::string& cookie_line) {
|
|
CookieOptions options;
|
|
if (!CookieStoreTestTraits::supports_http_only)
|
|
options.set_include_httponly();
|
|
options.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
return CreateAndSetCookie(cs, url, cookie_line, options);
|
|
}
|
|
|
|
CanonicalCookie::CookieInclusionStatus CreateAndSetCookieReturnStatus(
|
|
CookieStore* cs,
|
|
const GURL& url,
|
|
const std::string& cookie_line) {
|
|
CanonicalCookie::CookieInclusionStatus create_status;
|
|
auto cookie = CanonicalCookie::Create(url, cookie_line, base::Time::Now(),
|
|
base::nullopt /* server_time */,
|
|
&create_status);
|
|
if (!cookie)
|
|
return create_status;
|
|
|
|
CookieOptions options;
|
|
if (!CookieStoreTestTraits::supports_http_only)
|
|
options.set_include_httponly();
|
|
// Allow setting SameSite cookies.
|
|
options.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
|
|
DCHECK(cs);
|
|
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
|
|
cs->SetCanonicalCookieAsync(std::move(cookie), url.scheme(), options,
|
|
callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.result();
|
|
}
|
|
|
|
CanonicalCookie::CookieInclusionStatus SetCanonicalCookieReturnStatus(
|
|
CookieStore* cs,
|
|
std::unique_ptr<CanonicalCookie> cookie,
|
|
std::string source_scheme,
|
|
bool can_modify_httponly) {
|
|
DCHECK(cs);
|
|
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
|
|
CookieOptions options;
|
|
if (can_modify_httponly)
|
|
options.set_include_httponly();
|
|
options.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
cs->SetCanonicalCookieAsync(std::move(cookie), std::move(source_scheme),
|
|
options, callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.result();
|
|
}
|
|
|
|
uint32_t DeleteCanonicalCookie(CookieStore* cs,
|
|
const CanonicalCookie& cookie) {
|
|
DCHECK(cs);
|
|
ResultSavingCookieCallback<uint32_t> callback;
|
|
cs->DeleteCanonicalCookieAsync(cookie, callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.result();
|
|
}
|
|
|
|
uint32_t DeleteCreatedInTimeRange(CookieStore* cs,
|
|
const TimeRange& creation_range) {
|
|
DCHECK(cs);
|
|
ResultSavingCookieCallback<uint32_t> callback;
|
|
cs->DeleteAllCreatedInTimeRangeAsync(creation_range,
|
|
callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.result();
|
|
}
|
|
|
|
uint32_t DeleteAllCreatedInTimeRange(CookieStore* cs,
|
|
CookieDeletionInfo delete_info) {
|
|
DCHECK(cs);
|
|
ResultSavingCookieCallback<uint32_t> callback;
|
|
cs->DeleteAllMatchingInfoAsync(std::move(delete_info),
|
|
callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.result();
|
|
}
|
|
|
|
uint32_t DeleteSessionCookies(CookieStore* cs) {
|
|
DCHECK(cs);
|
|
ResultSavingCookieCallback<uint32_t> callback;
|
|
cs->DeleteSessionCookiesAsync(callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.result();
|
|
}
|
|
|
|
uint32_t DeleteAll(CookieStore* cs) {
|
|
DCHECK(cs);
|
|
ResultSavingCookieCallback<uint32_t> callback;
|
|
cs->DeleteAllAsync(callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
return callback.result();
|
|
}
|
|
|
|
bool FindAndDeleteCookie(CookieStore* cs,
|
|
const std::string& domain,
|
|
const std::string& name) {
|
|
for (auto& cookie : this->GetAllCookies(cs)) {
|
|
if (cookie.Domain() == domain && cookie.Name() == name)
|
|
return this->DeleteCanonicalCookie(cs, cookie);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Returns the CookieStore for the test - each test only uses one CookieStore.
|
|
CookieStore* GetCookieStore() {
|
|
if (!cookie_store_)
|
|
cookie_store_ = CookieStoreTestTraits::Create();
|
|
return cookie_store_.get();
|
|
}
|
|
|
|
// Resets CookieStore.
|
|
void ResetCookieStore() { cookie_store_.reset(); }
|
|
|
|
// 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(base::TimeDelta::FromMilliseconds(10));
|
|
cookies = GetCookies(cs, url);
|
|
matched = (TokenizeCookieLine(line) == TokenizeCookieLine(cookies));
|
|
}
|
|
|
|
EXPECT_TRUE(matched) << "\"" << cookies
|
|
<< "\" does not match \"" << line << "\"";
|
|
}
|
|
|
|
const CookieURLHelper http_www_foo_;
|
|
const CookieURLHelper http_bar_foo_;
|
|
const CookieURLHelper http_www_bar_;
|
|
const CookieURLHelper https_www_foo_;
|
|
const CookieURLHelper ftp_foo_;
|
|
const CookieURLHelper ws_www_foo_;
|
|
const CookieURLHelper wss_www_foo_;
|
|
const CookieURLHelper www_foo_foo_;
|
|
const CookieURLHelper www_foo_bar_;
|
|
const CookieURLHelper http_baz_com_;
|
|
const CookieURLHelper http_bar_com_;
|
|
|
|
std::unique_ptr<base::test::SingleThreadTaskEnvironment> task_environment_;
|
|
|
|
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;
|
|
base::StringTokenizer tokenizer(line, " ;");
|
|
while (tokenizer.GetNext())
|
|
EXPECT_TRUE(tokens.insert(tokenizer.token()).second);
|
|
return tokens;
|
|
}
|
|
|
|
std::unique_ptr<CookieStore> cookie_store_;
|
|
};
|
|
TYPED_TEST_SUITE_P(CookieStoreTest);
|
|
|
|
TYPED_TEST_P(CookieStoreTest, FilterTest) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
|
|
base::Time two_hours_ago = base::Time::Now() - base::TimeDelta::FromHours(2);
|
|
base::Time one_hour_ago = base::Time::Now() - base::TimeDelta::FromHours(1);
|
|
base::Time one_hour_from_now =
|
|
base::Time::Now() + base::TimeDelta::FromHours(1);
|
|
|
|
std::unique_ptr<CanonicalCookie> cc(CanonicalCookie::CreateSanitizedCookie(
|
|
this->www_foo_foo_.url(), "A", "B", std::string(), "/foo", one_hour_ago,
|
|
one_hour_from_now, base::Time(), false, false,
|
|
CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT));
|
|
ASSERT_TRUE(cc);
|
|
EXPECT_TRUE(this->SetCanonicalCookie(cs, std::move(cc), "https",
|
|
true /*modify_httponly*/));
|
|
|
|
// Note that for the creation time to be set exactly, without modification,
|
|
// it must be different from the one set by the line above.
|
|
cc = CanonicalCookie::CreateSanitizedCookie(
|
|
this->www_foo_bar_.url(), "C", "D", this->www_foo_bar_.domain(), "/bar",
|
|
two_hours_ago, base::Time(), one_hour_ago, false, true,
|
|
CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT);
|
|
ASSERT_TRUE(cc);
|
|
EXPECT_TRUE(this->SetCanonicalCookie(cs, std::move(cc), "https",
|
|
true /*modify_httponly*/));
|
|
|
|
// Because of strict secure cookies, it should not be possible to create
|
|
// a secure cookie with an HTTP URL.
|
|
|
|
cc = CanonicalCookie::CreateSanitizedCookie(
|
|
this->http_www_foo_.url(), "E", "F", std::string(), std::string(),
|
|
base::Time(), base::Time(), base::Time(), true, false,
|
|
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
|
|
ASSERT_FALSE(cc);
|
|
|
|
cc = CanonicalCookie::CreateSanitizedCookie(
|
|
this->https_www_foo_.url(), "E", "F", std::string(), std::string(),
|
|
base::Time(), base::Time(), base::Time(), true, false,
|
|
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
|
|
ASSERT_TRUE(cc);
|
|
EXPECT_TRUE(this->SetCanonicalCookie(cs, std::move(cc), "https",
|
|
true /*modify_httponly*/));
|
|
|
|
// Get all the cookies for a given URL, regardless of properties. This 'get()'
|
|
// operation shouldn't update the access time, as the test checks that the
|
|
// access time is set properly upon creation. Updating the access time would
|
|
// make that difficult.
|
|
CookieList cookies = this->GetAllCookiesForURL(cs, this->www_foo_foo_.url());
|
|
CookieList::iterator it = cookies.begin();
|
|
|
|
ASSERT_TRUE(it != cookies.end());
|
|
EXPECT_EQ("A", it->Name());
|
|
EXPECT_EQ("B", it->Value());
|
|
EXPECT_EQ(this->www_foo_foo_.host(), it->Domain());
|
|
EXPECT_EQ("/foo", it->Path());
|
|
EXPECT_EQ(one_hour_ago, it->CreationDate());
|
|
EXPECT_TRUE(it->IsPersistent());
|
|
// Expect expiration date is in the right range. Some cookie implementations
|
|
// may not record it with millisecond accuracy.
|
|
EXPECT_LE((one_hour_from_now - it->ExpiryDate()).magnitude().InSeconds(), 5);
|
|
// Some CookieStores don't store last access date.
|
|
if (!it->LastAccessDate().is_null())
|
|
EXPECT_EQ(one_hour_ago, it->LastAccessDate());
|
|
EXPECT_FALSE(it->IsSecure());
|
|
EXPECT_FALSE(it->IsHttpOnly());
|
|
|
|
ASSERT_TRUE(++it == cookies.end());
|
|
|
|
// Verify that the cookie was set as 'httponly' by passing in a CookieOptions
|
|
// that excludes them and getting an empty result.
|
|
if (TypeParam::supports_http_only) {
|
|
net::CookieOptions options;
|
|
options.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
cookies =
|
|
this->GetCookieListWithOptions(cs, this->www_foo_bar_.url(), options);
|
|
it = cookies.begin();
|
|
ASSERT_TRUE(it == cookies.end());
|
|
}
|
|
|
|
// Get the cookie using the wide open |options|:
|
|
cookies = this->GetAllCookiesForURL(cs, this->www_foo_bar_.url());
|
|
it = cookies.begin();
|
|
|
|
ASSERT_TRUE(it != cookies.end());
|
|
EXPECT_EQ("C", it->Name());
|
|
EXPECT_EQ("D", it->Value());
|
|
EXPECT_EQ(this->www_foo_bar_.Format(".%D"), it->Domain());
|
|
EXPECT_EQ("/bar", it->Path());
|
|
EXPECT_EQ(two_hours_ago, it->CreationDate());
|
|
EXPECT_FALSE(it->IsPersistent());
|
|
// Some CookieStores don't store last access date.
|
|
if (!it->LastAccessDate().is_null())
|
|
EXPECT_EQ(one_hour_ago, it->LastAccessDate());
|
|
EXPECT_FALSE(it->IsSecure());
|
|
EXPECT_TRUE(it->IsHttpOnly());
|
|
|
|
EXPECT_TRUE(++it == cookies.end());
|
|
|
|
cookies = this->GetAllCookiesForURL(cs, this->https_www_foo_.url());
|
|
it = cookies.begin();
|
|
|
|
ASSERT_TRUE(it != cookies.end());
|
|
EXPECT_EQ("E", it->Name());
|
|
EXPECT_EQ("F", it->Value());
|
|
EXPECT_EQ("/", it->Path());
|
|
EXPECT_EQ(this->https_www_foo_.host(), it->Domain());
|
|
// Cookie should have its creation time set, and be in a reasonable range.
|
|
EXPECT_LE((base::Time::Now() - it->CreationDate()).magnitude().InMinutes(),
|
|
2);
|
|
EXPECT_FALSE(it->IsPersistent());
|
|
// Some CookieStores don't store last access date.
|
|
if (!it->LastAccessDate().is_null())
|
|
EXPECT_EQ(it->CreationDate(), it->LastAccessDate());
|
|
EXPECT_TRUE(it->IsSecure());
|
|
EXPECT_FALSE(it->IsHttpOnly());
|
|
|
|
EXPECT_TRUE(++it == cookies.end());
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
|
|
base::Time two_hours_ago = base::Time::Now() - base::TimeDelta::FromHours(2);
|
|
base::Time one_hour_ago = base::Time::Now() - base::TimeDelta::FromHours(1);
|
|
base::Time one_hour_from_now =
|
|
base::Time::Now() + base::TimeDelta::FromHours(1);
|
|
|
|
std::string foo_foo_host(this->www_foo_foo_.url().host());
|
|
std::string foo_bar_domain(this->www_foo_bar_.domain());
|
|
std::string http_foo_host(this->http_www_foo_.url().host());
|
|
std::string https_foo_host(this->https_www_foo_.url().host());
|
|
|
|
EXPECT_TRUE(this->SetCanonicalCookie(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"A", "B", foo_foo_host, "/foo", one_hour_ago, one_hour_from_now,
|
|
base::Time(), false /* secure */, false /* httponly */,
|
|
CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
|
|
"http", true));
|
|
// Note that for the creation time to be set exactly, without modification,
|
|
// it must be different from the one set by the line above.
|
|
EXPECT_TRUE(this->SetCanonicalCookie(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"C", "D", "." + foo_bar_domain, "/bar", two_hours_ago, base::Time(),
|
|
one_hour_ago, false, true, CookieSameSite::LAX_MODE,
|
|
COOKIE_PRIORITY_DEFAULT),
|
|
"http", true));
|
|
|
|
// A secure source is required for setting secure cookies.
|
|
EXPECT_TRUE(
|
|
this->SetCanonicalCookieReturnStatus(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"E", "F", http_foo_host, "/", base::Time(), base::Time(),
|
|
base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
|
|
COOKIE_PRIORITY_DEFAULT),
|
|
"http", true)
|
|
.HasExclusionReason(
|
|
CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
|
|
|
|
// A Secure cookie can be created from an insecure URL, but is rejected upon
|
|
// setting.
|
|
CanonicalCookie::CookieInclusionStatus status;
|
|
auto cookie = CanonicalCookie::Create(
|
|
this->http_www_foo_.url(), "foo=1; Secure", base::Time::Now(),
|
|
base::nullopt /* server_time */, &status);
|
|
EXPECT_TRUE(cookie->IsSecure());
|
|
EXPECT_TRUE(status.IsInclude());
|
|
EXPECT_TRUE(
|
|
this->SetCanonicalCookieReturnStatus(cs, std::move(cookie), "http", true)
|
|
.HasExclusionReason(
|
|
CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
|
|
|
|
// A secure source is also required for overwriting secure cookies. Writing
|
|
// a secure cookie then overwriting it from a non-secure source should fail.
|
|
EXPECT_TRUE(this->SetCanonicalCookie(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"E", "F", http_foo_host, "/", base::Time(), base::Time(),
|
|
base::Time(), true /* secure */, false /* httponly */,
|
|
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
|
|
"https", true /* modify_http_only */));
|
|
|
|
EXPECT_TRUE(
|
|
this->SetCanonicalCookieReturnStatus(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"E", "F", http_foo_host, "/", base::Time(), base::Time(),
|
|
base::Time(), true /* secure */, false /* httponly */,
|
|
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
|
|
"http", true /* modify_http_only */)
|
|
.HasExclusionReason(
|
|
CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
|
|
|
|
if (TypeParam::supports_http_only) {
|
|
// Permission to modify http only cookies is required to set an
|
|
// httponly cookie.
|
|
EXPECT_TRUE(
|
|
this->SetCanonicalCookieReturnStatus(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"G", "H", http_foo_host, "/unique", base::Time(),
|
|
base::Time(), base::Time(), false /* secure */,
|
|
true /* httponly */, CookieSameSite::LAX_MODE,
|
|
COOKIE_PRIORITY_DEFAULT),
|
|
"http", false /* modify_http_only */)
|
|
.HasExclusionReason(
|
|
CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
|
|
|
|
// A HttpOnly cookie can be created, but is rejected
|
|
// upon setting if the options do not specify include_httponly.
|
|
CanonicalCookie::CookieInclusionStatus create_status;
|
|
auto c = CanonicalCookie::Create(
|
|
this->http_www_foo_.url(), "bar=1; HttpOnly", base::Time::Now(),
|
|
base::nullopt /* server_time */, &create_status);
|
|
EXPECT_TRUE(c->IsHttpOnly());
|
|
EXPECT_TRUE(create_status.IsInclude());
|
|
EXPECT_TRUE(
|
|
this->SetCanonicalCookieReturnStatus(cs, std::move(c), "http",
|
|
false /* can_modify_httponly */)
|
|
.HasExclusionReason(
|
|
CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
|
|
|
|
// Permission to modify httponly cookies is also required to overwrite
|
|
// an httponly cookie.
|
|
EXPECT_TRUE(this->SetCanonicalCookie(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"G", "H", http_foo_host, "/unique", base::Time(), base::Time(),
|
|
base::Time(), false /* secure */, true /* httponly */,
|
|
CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
|
|
"http", true /* modify_http_only */));
|
|
|
|
EXPECT_TRUE(
|
|
this->SetCanonicalCookieReturnStatus(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"G", "H", http_foo_host, "/unique", base::Time(),
|
|
base::Time(), base::Time(), false /* secure */,
|
|
true /* httponly */, CookieSameSite::LAX_MODE,
|
|
COOKIE_PRIORITY_DEFAULT),
|
|
"http", false /* modify_http_only */)
|
|
.HasExclusionReason(
|
|
CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
|
|
} else {
|
|
// Leave store in same state as if the above tests had been run.
|
|
EXPECT_TRUE(this->SetCanonicalCookie(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"G", "H", http_foo_host, "/unique", base::Time(), base::Time(),
|
|
base::Time(), false /* secure */, true /* httponly */,
|
|
CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
|
|
"http", true /* modify_http_only */));
|
|
}
|
|
|
|
// Get all the cookies for a given URL, regardless of properties. This 'get()'
|
|
// operation shouldn't update the access time, as the test checks that the
|
|
// access time is set properly upon creation. Updating the access time would
|
|
// make that difficult.
|
|
CookieList cookies = this->GetAllCookiesForURL(cs, this->www_foo_foo_.url());
|
|
CookieList::iterator it = cookies.begin();
|
|
|
|
ASSERT_EQ(1u, cookies.size());
|
|
EXPECT_EQ("A", it->Name());
|
|
EXPECT_EQ("B", it->Value());
|
|
EXPECT_EQ(this->www_foo_foo_.host(), it->Domain());
|
|
EXPECT_EQ("/foo", it->Path());
|
|
EXPECT_EQ(one_hour_ago, it->CreationDate());
|
|
EXPECT_TRUE(it->IsPersistent());
|
|
// Expect expiration date is in the right range. Some cookie implementations
|
|
// may not record it with millisecond accuracy.
|
|
EXPECT_LE((one_hour_from_now - it->ExpiryDate()).magnitude().InSeconds(), 5);
|
|
// Some CookieStores don't store last access date.
|
|
if (!it->LastAccessDate().is_null())
|
|
EXPECT_EQ(one_hour_ago, it->LastAccessDate());
|
|
EXPECT_FALSE(it->IsSecure());
|
|
EXPECT_FALSE(it->IsHttpOnly());
|
|
|
|
// Get the cookie using the wide open |options|:
|
|
cookies = this->GetAllCookiesForURL(cs, this->www_foo_bar_.url());
|
|
ASSERT_EQ(1u, cookies.size());
|
|
it = cookies.begin();
|
|
|
|
EXPECT_EQ("C", it->Name());
|
|
EXPECT_EQ("D", it->Value());
|
|
EXPECT_EQ(this->www_foo_bar_.Format(".%D"), it->Domain());
|
|
EXPECT_EQ("/bar", it->Path());
|
|
EXPECT_EQ(two_hours_ago, it->CreationDate());
|
|
EXPECT_FALSE(it->IsPersistent());
|
|
// Some CookieStores don't store last access date.
|
|
if (!it->LastAccessDate().is_null())
|
|
EXPECT_EQ(one_hour_ago, it->LastAccessDate());
|
|
EXPECT_FALSE(it->IsSecure());
|
|
EXPECT_TRUE(it->IsHttpOnly());
|
|
|
|
cookies = this->GetAllCookiesForURL(cs, this->https_www_foo_.url());
|
|
ASSERT_EQ(1u, cookies.size());
|
|
it = cookies.begin();
|
|
|
|
EXPECT_EQ("E", it->Name());
|
|
EXPECT_EQ("F", it->Value());
|
|
EXPECT_EQ("/", it->Path());
|
|
EXPECT_EQ(this->https_www_foo_.host(), it->Domain());
|
|
// Cookie should have its creation time set, and be in a reasonable range.
|
|
EXPECT_LE((base::Time::Now() - it->CreationDate()).magnitude().InMinutes(),
|
|
2);
|
|
EXPECT_FALSE(it->IsPersistent());
|
|
// Some CookieStores don't store last access date.
|
|
if (!it->LastAccessDate().is_null())
|
|
EXPECT_EQ(it->CreationDate(), it->LastAccessDate());
|
|
EXPECT_TRUE(it->IsSecure());
|
|
EXPECT_FALSE(it->IsHttpOnly());
|
|
}
|
|
|
|
// Test enforcement around setting secure cookies.
|
|
TYPED_TEST_P(CookieStoreTest, SecureEnforcement) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
GURL http_url(this->http_www_foo_.url());
|
|
std::string http_domain(http_url.host());
|
|
GURL https_url(this->https_www_foo_.url());
|
|
std::string https_domain(https_url.host());
|
|
|
|
// Confirm that setting the secure attribute from an insecure source fails,
|
|
// but the other combinations work.
|
|
EXPECT_FALSE(this->SetCanonicalCookie(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
|
|
base::Time(), true, false, CookieSameSite::STRICT_MODE,
|
|
COOKIE_PRIORITY_DEFAULT),
|
|
"http", true /*modify_httponly*/));
|
|
EXPECT_TRUE(this->SetCanonicalCookie(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
|
|
base::Time(), true, false, CookieSameSite::STRICT_MODE,
|
|
COOKIE_PRIORITY_DEFAULT),
|
|
"https", true /*modify_httponly*/));
|
|
EXPECT_TRUE(this->SetCanonicalCookie(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
|
|
base::Time(), false, false, CookieSameSite::STRICT_MODE,
|
|
COOKIE_PRIORITY_DEFAULT),
|
|
"https", true /*modify_httponly*/));
|
|
EXPECT_TRUE(this->SetCanonicalCookie(
|
|
cs,
|
|
std::make_unique<CanonicalCookie>(
|
|
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
|
|
base::Time(), false, false, CookieSameSite::STRICT_MODE,
|
|
COOKIE_PRIORITY_DEFAULT),
|
|
"http", true /*modify_httponly*/));
|
|
}
|
|
|
|
// The iOS networking stack uses the iOS cookie parser, which we do not
|
|
// control. While it is spec-compliant, that does not match the practical
|
|
// behavior of most UAs in some cases, which we try to replicate. See
|
|
// https://crbug.com/638389 for more information.
|
|
TYPED_TEST_P(CookieStoreTest, EmptyKeyTest) {
|
|
#if !defined(OS_IOS)
|
|
CookieStore* cs = this->GetCookieStore();
|
|
|
|
GURL url1("http://foo1.bar.com");
|
|
EXPECT_TRUE(this->SetCookie(cs, url1, "foo"));
|
|
EXPECT_EQ("foo", this->GetCookies(cs, url1));
|
|
|
|
// Regression tests for https://crbug.com/601786
|
|
GURL url2("http://foo2.bar.com");
|
|
EXPECT_TRUE(this->SetCookie(cs, url2, "foo"));
|
|
EXPECT_TRUE(this->SetCookie(cs, url2, "\t"));
|
|
EXPECT_EQ("", this->GetCookies(cs, url2));
|
|
|
|
GURL url3("http://foo3.bar.com");
|
|
EXPECT_TRUE(this->SetCookie(cs, url3, "foo"));
|
|
EXPECT_TRUE(this->SetCookie(cs, url3, "="));
|
|
EXPECT_EQ("", this->GetCookies(cs, url3));
|
|
|
|
GURL url4("http://foo4.bar.com");
|
|
EXPECT_TRUE(this->SetCookie(cs, url4, "foo"));
|
|
EXPECT_TRUE(this->SetCookie(cs, url4, ""));
|
|
EXPECT_EQ("", this->GetCookies(cs, url4));
|
|
|
|
GURL url5("http://foo5.bar.com");
|
|
EXPECT_TRUE(this->SetCookie(cs, url5, "foo"));
|
|
EXPECT_TRUE(this->SetCookie(cs, url5, "; bar"));
|
|
EXPECT_EQ("", this->GetCookies(cs, url5));
|
|
|
|
GURL url6("http://foo6.bar.com");
|
|
EXPECT_TRUE(this->SetCookie(cs, url6, "foo"));
|
|
EXPECT_TRUE(this->SetCookie(cs, url6, " "));
|
|
EXPECT_EQ("", this->GetCookies(cs, url6));
|
|
#endif
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, DomainTest) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
|
|
this->http_www_foo_.Format("C=D; domain=.%D")));
|
|
this->MatchCookieLines("A=B; C=D",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// 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(this->http_www_foo_.Format("http://foo.www.%D"))));
|
|
|
|
// Test and make sure we find domain cookies on the same domain.
|
|
EXPECT_TRUE(
|
|
this->SetCookie(cs, this->http_www_foo_.url(),
|
|
this->http_www_foo_.Format("E=F; domain=.www.%D")));
|
|
this->MatchCookieLines("A=B; C=D; E=F",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// 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->http_www_foo_.url(),
|
|
this->http_www_foo_.Format("G=H; domain=www.%D")));
|
|
this->MatchCookieLines("A=B; C=D; E=F; G=H",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// Test domain enforcement, should fail on a sub-domain or something too deep.
|
|
EXPECT_FALSE(this->SetCookie(cs, this->http_www_foo_.url(),
|
|
this->http_www_foo_.Format("I=J; domain=.%R")));
|
|
this->MatchCookieLines(
|
|
std::string(),
|
|
this->GetCookies(cs, GURL(this->http_www_foo_.Format("http://a.%R"))));
|
|
EXPECT_FALSE(
|
|
this->SetCookie(cs, this->http_www_foo_.url(),
|
|
this->http_www_foo_.Format("K=L; domain=.bla.www.%D")));
|
|
this->MatchCookieLines(
|
|
"C=D; E=F; G=H",
|
|
this->GetCookies(cs,
|
|
GURL(this->http_www_foo_.Format("http://bla.www.%D"))));
|
|
this->MatchCookieLines("A=B; C=D; E=F; G=H",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
}
|
|
|
|
// FireFox recognizes domains containing trailing periods as valid.
|
|
// IE and Safari do not. Assert the expected policy here.
|
|
TYPED_TEST_P(CookieStoreTest, DomainWithTrailingDotTest) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
// These two cases fail because the url, http://www.foo.com, does not match
|
|
// the domain given in the cookie line (due to the trailing dots), so the
|
|
// cookie is not created.
|
|
EXPECT_FALSE(this->SetCookie(cs, this->http_www_foo_.url(),
|
|
"a=1; domain=.www.foo.com."));
|
|
EXPECT_FALSE(this->SetCookie(cs, this->http_www_foo_.url(),
|
|
"b=2; domain=.www.foo.com.."));
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
GURL url_with_dot("http://www.foo.com.");
|
|
GURL url_with_double_dot("http://www.foo.com..");
|
|
|
|
// This succeeds because the urls match.
|
|
EXPECT_TRUE(this->SetCookie(cs, url_with_dot, "a=1; domain=.www.foo.com."));
|
|
// This fails because two trailing dots are not allowed, so the cookie is not
|
|
// created.
|
|
EXPECT_FALSE(
|
|
this->SetCookie(cs, url_with_double_dot, "b=2; domain=.www.foo.com.."));
|
|
|
|
if (TypeParam::preserves_trailing_dots) {
|
|
// If the CookieStore preserves trailing dots, then .www.foo.com is not
|
|
// considered the same as .www.foo.com.
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
this->MatchCookieLines("a=1", this->GetCookies(cs, url_with_dot));
|
|
} else {
|
|
// If the CookieStore does not preserve trailing dots, the domains will both
|
|
// be folded into one.
|
|
this->MatchCookieLines("a=1",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
this->MatchCookieLines("a=1", this->GetCookies(cs, url_with_dot));
|
|
}
|
|
}
|
|
|
|
// Test that cookies can bet set on higher level domains.
|
|
TYPED_TEST_P(CookieStoreTest, ValidSubdomainTest) {
|
|
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.
|
|
TYPED_TEST_P(CookieStoreTest, InvalidDomainTest) {
|
|
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"));
|
|
|
|
// The iOS networking stack uses the iOS cookie parser, which we do not
|
|
// control. Its handling of multiple domain= values in cookie string varies
|
|
// depending on iOS version. See https://crbug.com/639167
|
|
#if !defined(OS_IOS)
|
|
// Regression test for https://crbug.com/601786
|
|
EXPECT_FALSE(
|
|
this->SetCookie(cs, url_foobar, "a=1; domain=.yo.foo.bar.com; domain="));
|
|
#endif // !defined(OS_IOS)
|
|
|
|
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(std::string(), 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.
|
|
TYPED_TEST_P(CookieStoreTest, InvalidDomainSameDomainAndRegistry) {
|
|
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(std::string(), this->GetCookies(cs, url_foocom));
|
|
}
|
|
|
|
// Setting the domain without a dot on a parent domain should add a domain
|
|
// cookie.
|
|
TYPED_TEST_P(CookieStoreTest, DomainWithoutLeadingDotParentDomain) {
|
|
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 specified domain matches the domain of the URL exactly, treat
|
|
// it as setting a domain cookie.
|
|
TYPED_TEST_P(CookieStoreTest, DomainWithoutLeadingDotSameDomain) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
GURL url("http://www.foo.com");
|
|
EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=www.foo.com"));
|
|
this->MatchCookieLines("a=1", this->GetCookies(cs, url));
|
|
this->MatchCookieLines("a=1",
|
|
this->GetCookies(cs, GURL("http://sub.www.foo.com")));
|
|
this->MatchCookieLines(
|
|
std::string(), this->GetCookies(cs, GURL("http://something-else.com")));
|
|
}
|
|
|
|
// Test that the domain specified in cookie string is treated case-insensitive
|
|
TYPED_TEST_P(CookieStoreTest, CaseInsensitiveDomainTest) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
GURL url("http://www.foo.com");
|
|
EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=.FOO.COM"));
|
|
EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.wWw.fOO.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");
|
|
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.
|
|
TYPED_TEST_P(CookieStoreTest, TestIpAddressNoDomainCookies) {
|
|
GURL url_ip("http://1.2.3.4/weee");
|
|
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(std::string(), 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(std::string(), 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 a TLD setting cookies on itself.
|
|
TYPED_TEST_P(CookieStoreTest, TestTLD) {
|
|
if (!TypeParam::supports_non_dotted_domains)
|
|
return;
|
|
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"));
|
|
// Domain cookies can't be set.
|
|
EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.com"));
|
|
// Exact matches between the domain attribute and the host are treated as
|
|
// host cookies, not domain cookies.
|
|
EXPECT_TRUE(this->SetCookie(cs, url, "c=3; domain=com"));
|
|
|
|
this->MatchCookieLines("a=1; c=3", this->GetCookies(cs, url));
|
|
|
|
// Make sure they don't show up for a normal .com, they should be host,
|
|
// domain, cookies.
|
|
this->MatchCookieLines(
|
|
std::string(),
|
|
this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/")));
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, GURL("http://.com/")));
|
|
}
|
|
|
|
// http://com. should be treated the same as http://com.
|
|
TYPED_TEST_P(CookieStoreTest, TestTLDWithTerminalDot) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
GURL url("http://com./index.html");
|
|
EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
|
|
EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.com."));
|
|
this->MatchCookieLines("a=1", this->GetCookies(cs, url));
|
|
this->MatchCookieLines(
|
|
std::string(),
|
|
this->GetCookies(cs, GURL("http://hopefully-no-cookies.com./")));
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, TestSubdomainSettingCookiesOnUnknownTLD) {
|
|
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(std::string(), this->GetCookies(cs, url));
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, TestSubdomainSettingCookiesOnKnownTLD) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
GURL url("http://foo.com");
|
|
EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.com"));
|
|
EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=com"));
|
|
this->MatchCookieLines(std::string(), this->GetCookies(cs, url));
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, TestSubdomainSettingCookiesOnKnownDottedTLD) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
GURL url("http://foo.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(std::string(), this->GetCookies(cs, url));
|
|
this->MatchCookieLines(
|
|
std::string(), this->GetCookies(cs, GURL("http://something-else.co.uk")));
|
|
this->MatchCookieLines(
|
|
std::string(), this->GetCookies(cs, GURL("http://something-else.uk")));
|
|
}
|
|
|
|
// Intranet URLs should only be able to set host cookies.
|
|
TYPED_TEST_P(CookieStoreTest, TestSettingCookiesOnUnknownTLD) {
|
|
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"));
|
|
this->MatchCookieLines("a=1", this->GetCookies(cs, url));
|
|
}
|
|
|
|
// Exact matches between the domain attribute and an intranet host are
|
|
// treated as host cookies, not domain cookies.
|
|
TYPED_TEST_P(CookieStoreTest, TestSettingCookiesWithHostDomainOnUnknownTLD) {
|
|
if (!TypeParam::supports_non_dotted_domains)
|
|
return;
|
|
CookieStore* cs = this->GetCookieStore();
|
|
GURL url("http://b");
|
|
EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=b"));
|
|
|
|
this->MatchCookieLines("a=1", this->GetCookies(cs, url));
|
|
|
|
// Make sure it doesn't show up for an intranet subdomain, it should be
|
|
// a host, not domain, cookie.
|
|
this->MatchCookieLines(
|
|
std::string(),
|
|
this->GetCookies(cs, GURL("http://hopefully-no-cookies.b/")));
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, GURL("http://.b/")));
|
|
}
|
|
|
|
// Test reading/writing cookies when the domain ends with a period,
|
|
// as in "www.foo.com."
|
|
TYPED_TEST_P(CookieStoreTest, TestHostEndsWithDot) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
GURL url("http://www.foo.com");
|
|
GURL url_with_dot("http://www.foo.com.");
|
|
EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
|
|
this->MatchCookieLines("a=1", this->GetCookies(cs, url));
|
|
// This fails because the url does not match the domain, so the cookie cannot
|
|
// be created.
|
|
EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.www.foo.com."));
|
|
this->MatchCookieLines("a=1", this->GetCookies(cs, url));
|
|
// This cookie can be created because the url matches the domain, and it can
|
|
// be set, but the get-cookie result differs depending on whether the
|
|
// CookieStore preserves trailing dots.
|
|
EXPECT_TRUE(this->SetCookie(cs, url_with_dot, "b=2; domain=.foo.com."));
|
|
|
|
// 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.
|
|
if (TypeParam::preserves_trailing_dots) {
|
|
this->MatchCookieLines("a=1", this->GetCookies(cs, url));
|
|
this->MatchCookieLines("b=2", this->GetCookies(cs, url_with_dot));
|
|
} else {
|
|
this->MatchCookieLines("a=1 b=2", this->GetCookies(cs, url));
|
|
this->MatchCookieLines("a=1 b=2", this->GetCookies(cs, url_with_dot));
|
|
}
|
|
|
|
// Make sure there weren't any side effects.
|
|
this->MatchCookieLines(
|
|
std::string(),
|
|
this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/")));
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, GURL("http://.com/")));
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, InvalidScheme) {
|
|
if (!TypeParam::filters_schemes)
|
|
return;
|
|
|
|
CookieStore* cs = this->GetCookieStore();
|
|
EXPECT_FALSE(this->SetCookie(cs, this->ftp_foo_.url(), kValidCookieLine));
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, InvalidScheme_Read) {
|
|
if (!TypeParam::filters_schemes)
|
|
return;
|
|
|
|
const std::string kValidDomainCookieLine =
|
|
this->http_www_foo_.Format("A=B; path=/; domain=%D");
|
|
|
|
CookieStore* cs = this->GetCookieStore();
|
|
EXPECT_TRUE(
|
|
this->SetCookie(cs, this->http_www_foo_.url(), kValidDomainCookieLine));
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->ftp_foo_.url()));
|
|
EXPECT_EQ(0U,
|
|
this->GetCookieListWithOptions(cs, this->ftp_foo_.url(),
|
|
CookieOptions::MakeAllInclusive())
|
|
.size());
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, PathTest) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
std::string url("http://www.foo.com");
|
|
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(std::string(),
|
|
this->GetCookies(cs, GURL(url + "/weehee")));
|
|
this->MatchCookieLines(std::string(), 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, EmptyExpires) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
CookieOptions options;
|
|
if (!TypeParam::supports_http_only)
|
|
options.set_include_httponly();
|
|
options.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
GURL url("http://www7.ipdl.inpit.go.jp/Tokujitu/tjkta.ipdl?N0000=108");
|
|
std::string set_cookie_line =
|
|
"ACSTM=20130308043820420042; path=/; domain=ipdl.inpit.go.jp; Expires=";
|
|
std::string cookie_line = "ACSTM=20130308043820420042";
|
|
|
|
this->CreateAndSetCookie(cs, url, set_cookie_line, options);
|
|
this->MatchCookieLines(cookie_line,
|
|
this->GetCookiesWithOptions(cs, url, options));
|
|
|
|
base::Optional<base::Time> server_time =
|
|
base::make_optional(base::Time::Now() - base::TimeDelta::FromHours(1));
|
|
this->CreateAndSetCookie(cs, url, set_cookie_line, options, server_time);
|
|
this->MatchCookieLines(cookie_line,
|
|
this->GetCookiesWithOptions(cs, url, options));
|
|
|
|
server_time = base::Time::Now() + base::TimeDelta::FromHours(1);
|
|
this->CreateAndSetCookie(cs, url, set_cookie_line, options, server_time);
|
|
this->MatchCookieLines(cookie_line,
|
|
this->GetCookiesWithOptions(cs, url, options));
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, HttpOnlyTest) {
|
|
if (!TypeParam::supports_http_only)
|
|
return;
|
|
|
|
CookieStore* cs = this->GetCookieStore();
|
|
CookieOptions options;
|
|
options.set_include_httponly();
|
|
options.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
|
|
// Create a httponly cookie.
|
|
EXPECT_TRUE(this->CreateAndSetCookie(cs, this->http_www_foo_.url(),
|
|
"A=B; httponly", options));
|
|
|
|
// Check httponly read protection.
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
this->MatchCookieLines("A=B", this->GetCookiesWithOptions(
|
|
cs, this->http_www_foo_.url(), options));
|
|
|
|
// Check httponly overwrite protection.
|
|
EXPECT_FALSE(this->SetCookie(cs, this->http_www_foo_.url(), "A=C"));
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
this->MatchCookieLines("A=B", this->GetCookiesWithOptions(
|
|
cs, this->http_www_foo_.url(), options));
|
|
EXPECT_TRUE(
|
|
this->CreateAndSetCookie(cs, this->http_www_foo_.url(), "A=C", options));
|
|
this->MatchCookieLines("A=C",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// Check httponly create protection.
|
|
EXPECT_FALSE(this->SetCookie(cs, this->http_www_foo_.url(), "B=A; httponly"));
|
|
this->MatchCookieLines("A=C", this->GetCookiesWithOptions(
|
|
cs, this->http_www_foo_.url(), options));
|
|
EXPECT_TRUE(this->CreateAndSetCookie(cs, this->http_www_foo_.url(),
|
|
"B=A; httponly", options));
|
|
this->MatchCookieLines(
|
|
"A=C; B=A",
|
|
this->GetCookiesWithOptions(cs, this->http_www_foo_.url(), options));
|
|
this->MatchCookieLines("A=C",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, TestCookieDeletion) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
|
|
// Create a session cookie.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), kValidCookieLine));
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
// Delete it via Max-Age.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
|
|
std::string(kValidCookieLine) + "; max-age=0"));
|
|
this->MatchCookieLineWithTimeout(cs, this->http_www_foo_.url(),
|
|
std::string());
|
|
|
|
// Create a session cookie.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), kValidCookieLine));
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
// Delete it via Expires.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
|
|
std::string(kValidCookieLine) +
|
|
"; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// Create a persistent cookie.
|
|
EXPECT_TRUE(this->SetCookie(
|
|
cs, this->http_www_foo_.url(),
|
|
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
|
|
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
// Delete it via Max-Age.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
|
|
std::string(kValidCookieLine) + "; max-age=0"));
|
|
this->MatchCookieLineWithTimeout(cs, this->http_www_foo_.url(),
|
|
std::string());
|
|
|
|
// Create a persistent cookie.
|
|
EXPECT_TRUE(this->SetCookie(
|
|
cs, this->http_www_foo_.url(),
|
|
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
// Delete it via Expires.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
|
|
std::string(kValidCookieLine) +
|
|
"; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// Create a persistent cookie.
|
|
EXPECT_TRUE(this->SetCookie(
|
|
cs, this->http_www_foo_.url(),
|
|
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
// Check that it is not deleted with significant enough clock skew.
|
|
base::Time server_time;
|
|
EXPECT_TRUE(base::Time::FromString("Sun, 17-Apr-1977 22:50:13 GMT",
|
|
&server_time));
|
|
EXPECT_TRUE(this->SetCookieWithServerTime(
|
|
cs, this->http_www_foo_.url(),
|
|
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-1977 22:50:13 GMT",
|
|
server_time));
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// Create a persistent cookie.
|
|
EXPECT_TRUE(this->SetCookie(
|
|
cs, this->http_www_foo_.url(),
|
|
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
// Delete it via Expires, with a unix epoch of 0.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
|
|
std::string(kValidCookieLine) +
|
|
"; expires=Thu, 1-Jan-1970 00:00:00 GMT"));
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, TestDeleteAll) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
|
|
// Set a session cookie.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), kValidCookieLine));
|
|
EXPECT_EQ("A=B", this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// Set a persistent cookie.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
|
|
"C=D; expires=Mon, 18-Apr-22 22:50:13 GMT"));
|
|
|
|
EXPECT_EQ(2u, this->GetAllCookies(cs).size());
|
|
|
|
// Delete both, and make sure it works
|
|
EXPECT_EQ(2u, this->DeleteAll(cs));
|
|
EXPECT_EQ(0u, this->GetAllCookies(cs).size());
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, TestDeleteAllCreatedInTimeRange) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
const base::Time last_month = base::Time::Now() -
|
|
base::TimeDelta::FromDays(30);
|
|
const base::Time last_minute = base::Time::Now() -
|
|
base::TimeDelta::FromMinutes(1);
|
|
const base::Time next_minute = base::Time::Now() +
|
|
base::TimeDelta::FromMinutes(1);
|
|
const base::Time next_month = base::Time::Now() +
|
|
base::TimeDelta::FromDays(30);
|
|
|
|
// Add a cookie.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
|
|
// Check that the cookie is in the store.
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// Remove cookies in empty intervals.
|
|
EXPECT_EQ(0u, this->DeleteCreatedInTimeRange(
|
|
cs, TimeRange(last_month, last_minute)));
|
|
EXPECT_EQ(0u, this->DeleteCreatedInTimeRange(
|
|
cs, TimeRange(next_minute, next_month)));
|
|
// Check that the cookie is still there.
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// Remove the cookie with an interval defined by two dates.
|
|
EXPECT_EQ(1u, this->DeleteCreatedInTimeRange(
|
|
cs, TimeRange(last_minute, next_minute)));
|
|
// Check that the cookie disappeared.
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// Add another cookie.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
|
|
// Check that the cookie is in the store.
|
|
this->MatchCookieLines("C=D",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
|
|
// Remove the cookie with a null ending time.
|
|
EXPECT_EQ(1u, this->DeleteCreatedInTimeRange(
|
|
cs, TimeRange(last_minute, base::Time())));
|
|
// Check that the cookie disappeared.
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, TestDeleteAllWithInfo) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
base::Time now = base::Time::Now();
|
|
base::Time last_month = base::Time::Now() - base::TimeDelta::FromDays(30);
|
|
base::Time last_minute = base::Time::Now() - base::TimeDelta::FromMinutes(1);
|
|
|
|
// These 3 cookies match the time range and host.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "Y=Z"));
|
|
EXPECT_TRUE(this->SetCookie(cs, this->https_www_foo_.url(), "E=B"));
|
|
|
|
// Delete cookies.
|
|
CookieDeletionInfo delete_info(now, base::Time::Max());
|
|
delete_info.value_for_testing = "B";
|
|
EXPECT_EQ(2u, // Deletes A=B, E=B
|
|
this->DeleteAllCreatedInTimeRange(cs, std::move(delete_info)));
|
|
|
|
// Check that we deleted the right ones.
|
|
this->MatchCookieLines("C=D;Y=Z",
|
|
this->GetCookies(cs, this->https_www_foo_.url()));
|
|
|
|
// Finally, check that we don't delete cookies when our time range is off.
|
|
delete_info = CookieDeletionInfo(last_month, last_minute);
|
|
delete_info.value_for_testing = "D";
|
|
EXPECT_EQ(0u, this->DeleteAllCreatedInTimeRange(cs, std::move(delete_info)));
|
|
this->MatchCookieLines("C=D;Y=Z",
|
|
this->GetCookies(cs, this->https_www_foo_.url()));
|
|
// Same thing, but with a good time range.
|
|
delete_info = CookieDeletionInfo(now, base::Time::Max());
|
|
delete_info.value_for_testing = "D";
|
|
EXPECT_EQ(1u, this->DeleteAllCreatedInTimeRange(cs, std::move(delete_info)));
|
|
this->MatchCookieLines("Y=Z",
|
|
this->GetCookies(cs, this->https_www_foo_.url()));
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, TestSecure) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->https_www_foo_.url()));
|
|
|
|
EXPECT_TRUE(this->SetCookie(cs, this->https_www_foo_.url(), "A=B; secure"));
|
|
// The secure should overwrite the non-secure.
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->https_www_foo_.url()));
|
|
|
|
EXPECT_TRUE(this->SetCookie(cs, this->https_www_foo_.url(), "D=E; secure"));
|
|
this->MatchCookieLines(std::string(),
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
this->MatchCookieLines("A=B; D=E",
|
|
this->GetCookies(cs, this->https_www_foo_.url()));
|
|
|
|
EXPECT_TRUE(this->SetCookie(cs, this->https_www_foo_.url(), "A=B"));
|
|
// The non-secure should overwrite the secure.
|
|
this->MatchCookieLines("A=B",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
this->MatchCookieLines("D=E; A=B",
|
|
this->GetCookies(cs, this->https_www_foo_.url()));
|
|
}
|
|
|
|
// Formerly NetUtilTest.CookieTest back when we used wininet's cookie handling.
|
|
TYPED_TEST_P(CookieStoreTest, NetUtilCookieTest) {
|
|
const GURL test_url("http://mojo.jojo.foo.com/");
|
|
|
|
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_foo("http://www.foo.com/");
|
|
GURL url_chromium("http://chromium.org");
|
|
CookieStore* cs = this->GetCookieStore();
|
|
|
|
// Insert a cookie "a" for path "/path1"
|
|
EXPECT_TRUE(this->SetCookie(cs, url_foo,
|
|
"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_foo,
|
|
"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();
|
|
allow_httponly.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
EXPECT_TRUE(this->CreateAndSetCookie(cs, url_foo,
|
|
"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_foo,
|
|
"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_foo,
|
|
"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.foo.com/path1")));
|
|
} else {
|
|
this->MatchCookieLines(
|
|
"a=val33; b=val2",
|
|
this->GetCookies(cs, GURL("http://www.foo.com/path1")));
|
|
}
|
|
this->MatchCookieLines(
|
|
"a=val9", this->GetCookies(cs, GURL("http://www.foo.com/path2")));
|
|
this->MatchCookieLines(
|
|
"a=val99", this->GetCookies(cs, GURL("http://chromium.org/path1")));
|
|
}
|
|
|
|
// Note that accepting an empty name is contrary to spec; see
|
|
// https://tools.ietf.org/html/rfc6265#section-4.1.1. However, we do it
|
|
// for web compatibility; see http://inikulin.github.io/cookie-compat/
|
|
// (specifically the "foo" and "=a" tests). This test is present in Chromium
|
|
// so that a flag is raised if this behavior is changed.
|
|
// On IOS we use the system cookie store which has Safari's behavior, so
|
|
// the test is skipped.
|
|
TYPED_TEST_P(CookieStoreTest, EmptyName) {
|
|
if (TypeParam::forbids_setting_empty_name)
|
|
return;
|
|
|
|
GURL url_foo("http://www.foo.com/");
|
|
CookieStore* cs = this->GetCookieStore();
|
|
|
|
CookieOptions options;
|
|
if (!TypeParam::supports_http_only)
|
|
options.set_include_httponly();
|
|
options.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
|
|
EXPECT_TRUE(this->CreateAndSetCookie(cs, url_foo, "a", options));
|
|
CookieList list = this->GetAllCookiesForURL(cs, url_foo);
|
|
EXPECT_EQ(1u, list.size());
|
|
EXPECT_EQ("", list[0].Name());
|
|
EXPECT_EQ("a", list[0].Value());
|
|
EXPECT_EQ(1u, this->DeleteAll(cs));
|
|
|
|
EXPECT_TRUE(this->CreateAndSetCookie(cs, url_foo, "=b", options));
|
|
list = this->GetAllCookiesForURL(cs, url_foo);
|
|
EXPECT_EQ(1u, list.size());
|
|
EXPECT_EQ("", list[0].Name());
|
|
EXPECT_EQ("b", list[0].Value());
|
|
EXPECT_EQ(1u, this->DeleteAll(cs));
|
|
}
|
|
|
|
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.
|
|
CookieStore* cs = this->GetCookieStore();
|
|
EXPECT_TRUE(
|
|
this->SetCookie(cs, GURL("http://d.c.b.a.foo.com/aa/x.html"), "c=1"));
|
|
EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.foo.com/aa/bb/cc/x.html"),
|
|
"d=1; domain=b.a.foo.com"));
|
|
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
|
|
TypeParam::creation_time_granularity_in_ms));
|
|
EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.foo.com/aa/bb/cc/x.html"),
|
|
"a=4; domain=b.a.foo.com"));
|
|
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
|
|
TypeParam::creation_time_granularity_in_ms));
|
|
EXPECT_TRUE(this->SetCookie(cs, GURL("http://c.b.a.foo.com/aa/bb/cc/x.html"),
|
|
"e=1; domain=c.b.a.foo.com"));
|
|
EXPECT_TRUE(
|
|
this->SetCookie(cs, GURL("http://d.c.b.a.foo.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.foo.com/aa/bb/cc/dd")));
|
|
|
|
CookieOptions options;
|
|
options.set_same_site_cookie_context(
|
|
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
|
|
|
|
CookieList cookies = this->GetCookieListWithOptions(
|
|
cs, GURL("http://d.c.b.a.foo.com/aa/bb/cc/dd"), options);
|
|
CookieList::const_iterator it = cookies.begin();
|
|
|
|
ASSERT_TRUE(it != cookies.end());
|
|
EXPECT_EQ("d", it->Name());
|
|
|
|
ASSERT_TRUE(++it != cookies.end());
|
|
EXPECT_EQ("a", it->Name());
|
|
|
|
ASSERT_TRUE(++it != cookies.end());
|
|
EXPECT_EQ("e", it->Name());
|
|
|
|
ASSERT_TRUE(++it != cookies.end());
|
|
EXPECT_EQ("b", it->Name());
|
|
|
|
ASSERT_TRUE(++it != cookies.end());
|
|
EXPECT_EQ("c", it->Name());
|
|
|
|
EXPECT_TRUE(++it == cookies.end());
|
|
}
|
|
|
|
// Check that GetAllCookiesAsync returns cookies from multiple domains, in the
|
|
// correct order.
|
|
TYPED_TEST_P(CookieStoreTest, GetAllCookiesAsync) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/a"));
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_baz_com_.url(), "C=D;/"));
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "E=F; path=/bar"));
|
|
|
|
// Check cookies for url.
|
|
CookieList cookies = this->GetAllCookies(cs);
|
|
CookieList::const_iterator it = cookies.begin();
|
|
|
|
ASSERT_TRUE(it != cookies.end());
|
|
EXPECT_EQ(this->http_bar_com_.host(), it->Domain());
|
|
EXPECT_EQ("/bar", it->Path());
|
|
EXPECT_EQ("E", it->Name());
|
|
EXPECT_EQ("F", it->Value());
|
|
|
|
ASSERT_TRUE(++it != cookies.end());
|
|
EXPECT_EQ(this->http_www_foo_.host(), it->Domain());
|
|
EXPECT_EQ("/a", it->Path());
|
|
EXPECT_EQ("A", it->Name());
|
|
EXPECT_EQ("B", it->Value());
|
|
|
|
ASSERT_TRUE(++it != cookies.end());
|
|
EXPECT_EQ(this->http_baz_com_.host(), it->Domain());
|
|
EXPECT_EQ("/", it->Path());
|
|
EXPECT_EQ("C", it->Name());
|
|
EXPECT_EQ("D", it->Value());
|
|
|
|
ASSERT_TRUE(++it == cookies.end());
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, GetAllCookiesWithAccessSemanticsAsync) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
auto access_delegate = std::make_unique<TestCookieAccessDelegate>();
|
|
TestCookieAccessDelegate* test_delegate = access_delegate.get();
|
|
// if !supports_cookie_access_semantics, the delegate will be stored but will
|
|
// not be used.
|
|
cs->SetCookieAccessDelegate(std::move(access_delegate));
|
|
|
|
test_delegate->SetExpectationForCookieDomain("domain1.test",
|
|
CookieAccessSemantics::LEGACY);
|
|
test_delegate->SetExpectationForCookieDomain(
|
|
"domain2.test", CookieAccessSemantics::NONLEGACY);
|
|
test_delegate->SetExpectationForCookieDomain("domain3.test",
|
|
CookieAccessSemantics::UNKNOWN);
|
|
|
|
this->CreateAndSetCookie(cs, GURL("http://domain1.test"), "cookie=1",
|
|
CookieOptions::MakeAllInclusive());
|
|
this->CreateAndSetCookie(cs, GURL("http://domain2.test"), "cookie=1",
|
|
CookieOptions::MakeAllInclusive());
|
|
this->CreateAndSetCookie(cs, GURL("http://domain3.test"), "cookie=1",
|
|
CookieOptions::MakeAllInclusive());
|
|
this->CreateAndSetCookie(cs, GURL("http://domain4.test"), "cookie=1",
|
|
CookieOptions::MakeAllInclusive());
|
|
|
|
GetAllCookiesWithAccessSemanticsCallback callback;
|
|
cs->GetAllCookiesWithAccessSemanticsAsync(callback.MakeCallback());
|
|
callback.WaitUntilDone();
|
|
EXPECT_TRUE(callback.was_run());
|
|
|
|
EXPECT_EQ(callback.cookies().size(), callback.access_semantics_list().size());
|
|
EXPECT_EQ(4u, callback.access_semantics_list().size());
|
|
EXPECT_EQ("domain1.test", callback.cookies()[0].Domain());
|
|
EXPECT_EQ("domain2.test", callback.cookies()[1].Domain());
|
|
EXPECT_EQ("domain3.test", callback.cookies()[2].Domain());
|
|
EXPECT_EQ("domain4.test", callback.cookies()[3].Domain());
|
|
|
|
if (!TypeParam::supports_cookie_access_semantics) {
|
|
for (CookieAccessSemantics semantics : callback.access_semantics_list()) {
|
|
EXPECT_EQ(CookieAccessSemantics::UNKNOWN, semantics);
|
|
}
|
|
} else {
|
|
EXPECT_EQ(CookieAccessSemantics::LEGACY,
|
|
callback.access_semantics_list()[0]);
|
|
EXPECT_EQ(CookieAccessSemantics::NONLEGACY,
|
|
callback.access_semantics_list()[1]);
|
|
EXPECT_EQ(CookieAccessSemantics::UNKNOWN,
|
|
callback.access_semantics_list()[2]);
|
|
EXPECT_EQ(CookieAccessSemantics::UNKNOWN,
|
|
callback.access_semantics_list()[3]);
|
|
}
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, DeleteCanonicalCookieAsync) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
|
|
// Set two cookies with the same name, and make sure both are set.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B;Path=/foo"));
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=C;Path=/bar"));
|
|
EXPECT_EQ(2u, this->GetAllCookies(cs).size());
|
|
EXPECT_EQ("A=B", this->GetCookies(cs, this->www_foo_foo_.url()));
|
|
EXPECT_EQ("A=C", this->GetCookies(cs, this->www_foo_bar_.url()));
|
|
|
|
// Delete the "/foo" cookie, and make sure only it was deleted.
|
|
CookieList cookies = this->GetCookieListWithOptions(
|
|
cs, this->www_foo_foo_.url(), CookieOptions::MakeAllInclusive());
|
|
ASSERT_EQ(1u, cookies.size());
|
|
EXPECT_EQ(1u, this->DeleteCanonicalCookie(cs, cookies[0]));
|
|
EXPECT_EQ(1u, this->GetAllCookies(cs).size());
|
|
EXPECT_EQ("", this->GetCookies(cs, this->www_foo_foo_.url()));
|
|
EXPECT_EQ("A=C", this->GetCookies(cs, this->www_foo_bar_.url()));
|
|
|
|
// Deleting the "/foo" cookie again should fail.
|
|
EXPECT_EQ(0u, this->DeleteCanonicalCookie(cs, cookies[0]));
|
|
|
|
// Try to delete the "/bar" cookie after overwriting it with a new cookie.
|
|
cookies = this->GetCookieListWithOptions(cs, this->www_foo_bar_.url(),
|
|
CookieOptions::MakeAllInclusive());
|
|
ASSERT_EQ(1u, cookies.size());
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=D;Path=/bar"));
|
|
EXPECT_EQ(0u, this->DeleteCanonicalCookie(cs, cookies[0]));
|
|
EXPECT_EQ(1u, this->GetAllCookies(cs).size());
|
|
EXPECT_EQ("A=D", this->GetCookies(cs, this->www_foo_bar_.url()));
|
|
|
|
// Delete the new "/bar" cookie.
|
|
cookies = this->GetCookieListWithOptions(cs, this->www_foo_bar_.url(),
|
|
CookieOptions::MakeAllInclusive());
|
|
ASSERT_EQ(1u, cookies.size());
|
|
EXPECT_EQ(1u, this->DeleteCanonicalCookie(cs, cookies[0]));
|
|
EXPECT_EQ(0u, this->GetAllCookies(cs).size());
|
|
EXPECT_EQ("", this->GetCookies(cs, this->www_foo_bar_.url()));
|
|
}
|
|
|
|
TYPED_TEST_P(CookieStoreTest, DeleteSessionCookie) {
|
|
CookieStore* cs = this->GetCookieStore();
|
|
// Create a session cookie and a persistent cookie.
|
|
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
|
|
std::string(kValidCookieLine)));
|
|
EXPECT_TRUE(this->SetCookie(
|
|
cs, this->http_www_foo_.url(),
|
|
this->http_www_foo_.Format("C=D; path=/; domain=%D;"
|
|
"expires=Mon, 18-Apr-22 22:50:13 GMT")));
|
|
this->MatchCookieLines("A=B; C=D",
|
|
this->GetCookies(cs, this->http_www_foo_.url()));
|
|
// Delete the session cookie.
|
|
this->DeleteSessionCookies(cs);
|
|
// Check that the session cookie has been deleted but not the persistent one.
|
|
EXPECT_EQ("C=D", this->GetCookies(cs, this->http_www_foo_.url()));
|
|
}
|
|
|
|
REGISTER_TYPED_TEST_SUITE_P(CookieStoreTest,
|
|
FilterTest,
|
|
SetCanonicalCookieTest,
|
|
SecureEnforcement,
|
|
EmptyKeyTest,
|
|
DomainTest,
|
|
DomainWithTrailingDotTest,
|
|
ValidSubdomainTest,
|
|
InvalidDomainTest,
|
|
InvalidDomainSameDomainAndRegistry,
|
|
DomainWithoutLeadingDotParentDomain,
|
|
DomainWithoutLeadingDotSameDomain,
|
|
CaseInsensitiveDomainTest,
|
|
TestIpAddress,
|
|
TestIpAddressNoDomainCookies,
|
|
TestTLD,
|
|
TestTLDWithTerminalDot,
|
|
TestSubdomainSettingCookiesOnUnknownTLD,
|
|
TestSubdomainSettingCookiesOnKnownTLD,
|
|
TestSubdomainSettingCookiesOnKnownDottedTLD,
|
|
TestSettingCookiesOnUnknownTLD,
|
|
TestSettingCookiesWithHostDomainOnUnknownTLD,
|
|
TestHostEndsWithDot,
|
|
InvalidScheme,
|
|
InvalidScheme_Read,
|
|
PathTest,
|
|
EmptyExpires,
|
|
HttpOnlyTest,
|
|
TestCookieDeletion,
|
|
TestDeleteAll,
|
|
TestDeleteAllCreatedInTimeRange,
|
|
TestDeleteAllWithInfo,
|
|
TestSecure,
|
|
NetUtilCookieTest,
|
|
OverwritePersistentCookie,
|
|
EmptyName,
|
|
CookieOrdering,
|
|
GetAllCookiesAsync,
|
|
GetAllCookiesWithAccessSemanticsAsync,
|
|
DeleteCanonicalCookieAsync,
|
|
DeleteSessionCookie);
|
|
|
|
} // namespace net
|
|
|
|
#endif // NET_COOKIES_COOKIE_STORE_UNITTEST_H_
|