From 3f3daac24caec2913641fe2fc2685feb738676ad Mon Sep 17 00:00:00 2001 From: mkwst Date: Thu, 26 Feb 2015 12:15:26 -0800 Subject: [PATCH] First-Party Cookies: Wire it up as an experimental web platform feature This patch adds a flag to the NetworkDelegate to control the first-party cookies experiment, and implements the flag in the ChromeNetworkDelegate and ShellNetworkDelegate by checking the value of the experimental web platform features command-line flag. Once we decide whether or not to ship this feature, we can revert everything in this patch other than the tests and the change to URLRequestHttpJob::DoLoadCookies. BUG=459154 Review URL: https://codereview.chromium.org/940373002 Cr-Commit-Position: refs/heads/master@{#318295} --- chrome/browser/net/chrome_network_delegate.cc | 10 +- chrome/browser/net/chrome_network_delegate.h | 5 +- .../net/chrome_network_delegate_unittest.cc | 46 ++++++- .../shell/browser/shell_network_delegate.cc | 7 + .../shell/browser/shell_network_delegate.h | 1 + net/base/layered_network_delegate.cc | 9 ++ net/base/layered_network_delegate.h | 3 + net/base/network_delegate.cc | 4 + net/base/network_delegate.h | 11 ++ net/base/network_delegate_impl.cc | 4 + net/base/network_delegate_impl.h | 7 + net/url_request/url_request_http_job.cc | 11 +- net/url_request/url_request_test_util.cc | 5 + net/url_request/url_request_test_util.h | 6 + net/url_request/url_request_unittest.cc | 120 ++++++++++++++++++ 15 files changed, 236 insertions(+), 13 deletions(-) diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc index 34f78aad9b66c5..68a4a74f3444dd 100644 --- a/chrome/browser/net/chrome_network_delegate.cc +++ b/chrome/browser/net/chrome_network_delegate.cc @@ -9,6 +9,7 @@ #include #include "base/base_paths.h" +#include "base/command_line.h" #include "base/debug/alias.h" #include "base/debug/dump_without_crashing.h" #include "base/debug/stack_trace.h" @@ -39,6 +40,7 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/resource_request_info.h" +#include "content/public/common/content_switches.h" #include "content/public/common/process_type.h" #include "net/base/host_port_pair.h" #include "net/base/load_flags.h" @@ -59,7 +61,6 @@ #endif #if defined(OS_CHROMEOS) -#include "base/command_line.h" #include "base/sys_info.h" #include "chrome/common/chrome_switches.h" #endif @@ -293,6 +294,9 @@ ChromeNetworkDelegate::ChromeNetworkDelegate( url_blacklist_manager_(NULL), #endif domain_reliability_monitor_(NULL), + experimental_web_platform_features_enabled_( + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableExperimentalWebPlatformFeatures)), first_request_(true), prerender_tracker_(NULL) { DCHECK(enable_referrers); @@ -724,6 +728,10 @@ bool ChromeNetworkDelegate::OnCanEnablePrivacyMode( return privacy_mode; } +bool ChromeNetworkDelegate::OnFirstPartyOnlyCookieExperimentEnabled() const { + return experimental_web_platform_features_enabled_; +} + bool ChromeNetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader( const net::URLRequest& request, const GURL& target_url, diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h index 0d7053950d5921..034e79f7ddf18f 100644 --- a/chrome/browser/net/chrome_network_delegate.h +++ b/chrome/browser/net/chrome_network_delegate.h @@ -144,7 +144,7 @@ class ChromeNetworkDelegate : public net::NetworkDelegateImpl { static void AllowAccessToAllFiles(); private: - friend class ChromeNetworkDelegateTest; + friend class ChromeNetworkDelegateThrottlingTest; // NetworkDelegate implementation. int OnBeforeURLRequest(net::URLRequest* request, @@ -184,6 +184,7 @@ class ChromeNetworkDelegate : public net::NetworkDelegateImpl { bool OnCanEnablePrivacyMode( const GURL& url, const GURL& first_party_for_cookies) const override; + bool OnFirstPartyOnlyCookieExperimentEnabled() const override; bool OnCancelURLRequestWithPolicyViolatingReferrerHeader( const net::URLRequest& request, const GURL& target_url, @@ -225,6 +226,8 @@ class ChromeNetworkDelegate : public net::NetworkDelegateImpl { // static anyway since it is based on a command-line flag. static bool g_never_throttle_requests_; + bool experimental_web_platform_features_enabled_; + bool first_request_; prerender::PrerenderTracker* prerender_tracker_; diff --git a/chrome/browser/net/chrome_network_delegate_unittest.cc b/chrome/browser/net/chrome_network_delegate_unittest.cc index 4b722dd325fab7..0550cde311fb83 100644 --- a/chrome/browser/net/chrome_network_delegate_unittest.cc +++ b/chrome/browser/net/chrome_network_delegate_unittest.cc @@ -4,6 +4,7 @@ #include "chrome/browser/net/chrome_network_delegate.h" +#include "base/command_line.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" @@ -13,6 +14,7 @@ #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_pref_service_syncable.h" #include "chrome/test/base/testing_profile.h" +#include "content/public/common/content_switches.h" #include "content/public/test/test_browser_thread_bundle.h" #include "net/base/request_priority.h" #include "net/url_request/url_request.h" @@ -23,12 +25,41 @@ #include "chrome/browser/extensions/event_router_forwarder.h" #endif +TEST(ChromeNetworkDelegateTest, DisableFirstPartyOnlyCookiesIffFlagDisabled) { + BooleanPrefMember pref_member_; + scoped_ptr delegate; + +#if defined(ENABLE_EXTENSIONS) + scoped_refptr forwarder = + new extensions::EventRouterForwarder(); + delegate.reset(new ChromeNetworkDelegate(forwarder.get(), &pref_member_)); +#else + delegate.reset(new ChromeNetworkDelegate(nullptr, &pref_member_)); +#endif + EXPECT_FALSE(delegate->FirstPartyOnlyCookieExperimentEnabled()); +} + +TEST(ChromeNetworkDelegateTest, EnableFirstPartyOnlyCookiesIffFlagEnabled) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableExperimentalWebPlatformFeatures); + BooleanPrefMember pref_member_; + scoped_ptr delegate; + #if defined(ENABLE_EXTENSIONS) -class ChromeNetworkDelegateTest : public testing::Test { + scoped_refptr forwarder = + new extensions::EventRouterForwarder(); + delegate.reset(new ChromeNetworkDelegate(forwarder.get(), &pref_member_)); +#else + delegate.reset(new ChromeNetworkDelegate(nullptr, &pref_member_)); +#endif + EXPECT_TRUE(delegate->FirstPartyOnlyCookieExperimentEnabled()); +} + +#if defined(ENABLE_EXTENSIONS) +class ChromeNetworkDelegateThrottlingTest : public testing::Test { protected: - ChromeNetworkDelegateTest() - : forwarder_(new extensions::EventRouterForwarder()) { - } + ChromeNetworkDelegateThrottlingTest() + : forwarder_(new extensions::EventRouterForwarder()) {} void SetUp() override { never_throttle_requests_original_value_ = @@ -43,7 +74,7 @@ class ChromeNetworkDelegateTest : public testing::Test { scoped_ptr CreateNetworkDelegate() { return make_scoped_ptr( - new ChromeNetworkDelegate(forwarder_.get(), &pref_member_)); + new ChromeNetworkDelegate(forwarder(), &pref_member_)); } // Implementation moved here for access to private bits. @@ -81,6 +112,8 @@ class ChromeNetworkDelegateTest : public testing::Test { } private: + extensions::EventRouterForwarder* forwarder() { return forwarder_.get(); } + bool never_throttle_requests_original_value_; base::MessageLoopForIO message_loop_; @@ -88,7 +121,7 @@ class ChromeNetworkDelegateTest : public testing::Test { BooleanPrefMember pref_member_; }; -TEST_F(ChromeNetworkDelegateTest, NeverThrottleLogic) { +TEST_F(ChromeNetworkDelegateThrottlingTest, NeverThrottleLogic) { NeverThrottleLogicImpl(); } #endif // defined(ENABLE_EXTENSIONS) @@ -313,4 +346,3 @@ TEST_F(ChromeNetworkDelegatePrivacyModeTest, EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, kBlockedFirstPartySite)); } - diff --git a/content/shell/browser/shell_network_delegate.cc b/content/shell/browser/shell_network_delegate.cc index 633fb46890556d..135bba36d0e302 100644 --- a/content/shell/browser/shell_network_delegate.cc +++ b/content/shell/browser/shell_network_delegate.cc @@ -4,6 +4,8 @@ #include "content/shell/browser/shell_network_delegate.h" +#include "base/command_line.h" +#include "content/public/common/content_switches.h" #include "net/base/net_errors.h" #include "net/base/static_cookie_policy.h" #include "net/url_request/url_request.h" @@ -114,4 +116,9 @@ bool ShellNetworkDelegate::OnCanThrottleRequest( return false; } +bool ShellNetworkDelegate::OnFirstPartyOnlyCookieExperimentEnabled() const { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableExperimentalWebPlatformFeatures); +} + } // namespace content diff --git a/content/shell/browser/shell_network_delegate.h b/content/shell/browser/shell_network_delegate.h index 75faa9a4ad9f5c..a23f5ffc56367e 100644 --- a/content/shell/browser/shell_network_delegate.h +++ b/content/shell/browser/shell_network_delegate.h @@ -54,6 +54,7 @@ class ShellNetworkDelegate : public net::NetworkDelegateImpl { bool OnCanAccessFile(const net::URLRequest& request, const base::FilePath& path) const override; bool OnCanThrottleRequest(const net::URLRequest& request) const override; + bool OnFirstPartyOnlyCookieExperimentEnabled() const override; DISALLOW_COPY_AND_ASSIGN(ShellNetworkDelegate); }; diff --git a/net/base/layered_network_delegate.cc b/net/base/layered_network_delegate.cc index 95e423623453af..9fd497397617bc 100644 --- a/net/base/layered_network_delegate.cc +++ b/net/base/layered_network_delegate.cc @@ -252,6 +252,15 @@ void LayeredNetworkDelegate::OnCanEnablePrivacyModeInternal( const GURL& first_party_for_cookies) const { } +bool LayeredNetworkDelegate::OnFirstPartyOnlyCookieExperimentEnabled() const { + OnFirstPartyOnlyCookieExperimentEnabledInternal(); + return nested_network_delegate_->FirstPartyOnlyCookieExperimentEnabled(); +} + +void LayeredNetworkDelegate::OnFirstPartyOnlyCookieExperimentEnabledInternal() + const { +} + bool LayeredNetworkDelegate:: OnCancelURLRequestWithPolicyViolatingReferrerHeader( const URLRequest& request, diff --git a/net/base/layered_network_delegate.h b/net/base/layered_network_delegate.h index e4b6411395f1e8..87c1d86cff597f 100644 --- a/net/base/layered_network_delegate.h +++ b/net/base/layered_network_delegate.h @@ -80,6 +80,7 @@ class NET_EXPORT LayeredNetworkDelegate : public NetworkDelegate { bool OnCanThrottleRequest(const URLRequest& request) const final; bool OnCanEnablePrivacyMode(const GURL& url, const GURL& first_party_for_cookies) const final; + bool OnFirstPartyOnlyCookieExperimentEnabled() const final; bool OnCancelURLRequestWithPolicyViolatingReferrerHeader( const URLRequest& request, const GURL& target_url, @@ -152,6 +153,8 @@ class NET_EXPORT LayeredNetworkDelegate : public NetworkDelegate { const GURL& url, const GURL& first_party_for_cookies) const; + virtual void OnFirstPartyOnlyCookieExperimentEnabledInternal() const; + virtual void OnCancelURLRequestWithPolicyViolatingReferrerHeaderInternal( const URLRequest& request, const GURL& target_url, diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc index b6858da65bdccb..1f59d03a6411e0 100644 --- a/net/base/network_delegate.cc +++ b/net/base/network_delegate.cc @@ -229,6 +229,10 @@ bool NetworkDelegate::CanEnablePrivacyMode( return OnCanEnablePrivacyMode(url, first_party_for_cookies); } +bool NetworkDelegate::FirstPartyOnlyCookieExperimentEnabled() const { + return OnFirstPartyOnlyCookieExperimentEnabled(); +} + bool NetworkDelegate::CancelURLRequestWithPolicyViolatingReferrerHeader( const URLRequest& request, const GURL& target_url, diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h index 5af2ac140efa5b..9ea82028b11fc8 100644 --- a/net/base/network_delegate.h +++ b/net/base/network_delegate.h @@ -104,6 +104,10 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe { bool CanEnablePrivacyMode(const GURL& url, const GURL& first_party_for_cookies) const; + // TODO(mkwst): Remove this once we decide whether or not we wish to ship + // first-party cookies. https://crbug.com/459154 + bool FirstPartyOnlyCookieExperimentEnabled() const; + bool CancelURLRequestWithPolicyViolatingReferrerHeader( const URLRequest& request, const GURL& target_url, @@ -266,6 +270,13 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe { const GURL& url, const GURL& first_party_for_cookies) const = 0; + // Returns true if the embedder has enabled the "first-party" cookie + // experiment, and false otherwise. + // + // TODO(mkwst): Remove this once we decide whether or not we wish to ship + // first-party cookies. https://crbug.com/459154 + virtual bool OnFirstPartyOnlyCookieExperimentEnabled() const = 0; + // Called when the |referrer_url| for requesting |target_url| during handling // of the |request| is does not comply with the referrer policy (e.g. a // secure referrer for an insecure initial target). diff --git a/net/base/network_delegate_impl.cc b/net/base/network_delegate_impl.cc index f10bee300ee452..c4bdd04e4c31f9 100644 --- a/net/base/network_delegate_impl.cc +++ b/net/base/network_delegate_impl.cc @@ -105,6 +105,10 @@ bool NetworkDelegateImpl::OnCanEnablePrivacyMode( return false; } +bool NetworkDelegateImpl::OnFirstPartyOnlyCookieExperimentEnabled() const { + return false; +} + bool NetworkDelegateImpl::OnCancelURLRequestWithPolicyViolatingReferrerHeader( const URLRequest& request, const GURL& target_url, diff --git a/net/base/network_delegate_impl.h b/net/base/network_delegate_impl.h index aa87bd46f03445..8ad483ecd1edf3 100644 --- a/net/base/network_delegate_impl.h +++ b/net/base/network_delegate_impl.h @@ -184,6 +184,13 @@ class NET_EXPORT NetworkDelegateImpl : public NetworkDelegate { const GURL& url, const GURL& first_party_for_cookies) const override; + // Returns true if the embedder has enabled the "first-party" cookie + // experiment, and false otherwise. + // + // TODO(mkwst): Remove this once we decide whether or not we wish to ship + // first-party cookies. https://crbug.com/459154 + bool OnFirstPartyOnlyCookieExperimentEnabled() const override; + // Called when the |referrer_url| for requesting |target_url| during handling // of the |request| is does not comply with the referrer policy (e.g. a // secure referrer for an insecure initial target). diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 958ef821d5d875..0520c0cc1b71c6 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -629,11 +629,14 @@ void URLRequestHttpJob::AddCookieHeaderAndStart() { void URLRequestHttpJob::DoLoadCookies() { CookieOptions options; options.set_include_httponly(); - options.set_include_first_party_only(); - // TODO(mkwst): Pipe a switch down here to allow us to decide whether we - // should enforce "first-party only" cookies or not (by setting |options|'s - // first-party-url to the first-party-for-cookies value. crbug.com/459154 + // TODO(mkwst): Drop this `if` once we decide whether or not to ship + // first-party cookies: https://crbug.com/459154 + if (network_delegate() && + network_delegate()->FirstPartyOnlyCookieExperimentEnabled()) + options.set_first_party_url(request_->first_party_for_cookies()); + else + options.set_include_first_party_only(); GetCookieStore()->GetCookiesWithOptionsAsync( request_->url(), options, diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index 107da7858a33b3..ebccd876de7cdb 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc @@ -322,6 +322,7 @@ TestNetworkDelegate::TestNetworkDelegate() has_load_timing_info_before_auth_(false), can_access_files_(true), can_throttle_requests_(true), + first_party_only_cookies_enabled_(false), cancel_request_with_policy_violating_referrer_(false), will_be_intercepted_on_next_error_(false) { } @@ -603,6 +604,10 @@ bool TestNetworkDelegate::OnCanThrottleRequest( return can_throttle_requests_; } +bool TestNetworkDelegate::OnFirstPartyOnlyCookieExperimentEnabled() const { + return first_party_only_cookies_enabled_; +} + bool TestNetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader( const URLRequest& request, const GURL& target_url, diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h index 9ad66a14aa1727..0208b4392fcf3f 100644 --- a/net/url_request/url_request_test_util.h +++ b/net/url_request/url_request_test_util.h @@ -265,6 +265,10 @@ class TestNetworkDelegate : public NetworkDelegateImpl { void set_can_access_files(bool val) { can_access_files_ = val; } bool can_access_files() const { return can_access_files_; } + void set_first_party_only_cookies_enabled(bool val) { + first_party_only_cookies_enabled_ = val; + } + void set_can_throttle_requests(bool val) { can_throttle_requests_ = val; } bool can_throttle_requests() const { return can_throttle_requests_; } @@ -325,6 +329,7 @@ class TestNetworkDelegate : public NetworkDelegateImpl { bool OnCanAccessFile(const URLRequest& request, const base::FilePath& path) const override; bool OnCanThrottleRequest(const URLRequest& request) const override; + bool OnFirstPartyOnlyCookieExperimentEnabled() const override; bool OnCancelURLRequestWithPolicyViolatingReferrerHeader( const URLRequest& request, const GURL& target_url, @@ -370,6 +375,7 @@ class TestNetworkDelegate : public NetworkDelegateImpl { bool can_access_files_; // true by default bool can_throttle_requests_; // true by default + bool first_party_only_cookies_enabled_; // false by default bool cancel_request_with_policy_violating_referrer_; // false by default bool will_be_intercepted_on_next_error_; }; diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index cfe3b7184b4cf2..ba4d52a5699403 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc @@ -2543,6 +2543,126 @@ TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy_Async) { } } +TEST_F(URLRequestTest, FirstPartyOnlyCookiesEnabled) { + LocalHttpTestServer test_server; + ASSERT_TRUE(test_server.Start()); + + // Set up a 'First-Party-Only' cookie (on '127.0.0.1', as that's where + // LocalHttpTestServer points). + { + TestNetworkDelegate network_delegate; + network_delegate.set_first_party_only_cookies_enabled(true); + default_context_.set_network_delegate(&network_delegate); + + TestDelegate d; + scoped_ptr req(default_context_.CreateRequest( + test_server.GetURL( + "set-cookie?FirstPartyCookieToSet=1;First-Party-Only"), + DEFAULT_PRIORITY, &d, NULL)); + req->Start(); + base::RunLoop().Run(); + EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); + EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); + EXPECT_EQ(1, network_delegate.set_cookie_count()); + } + + // Verify that the cookie is sent for first-party requests. + { + TestNetworkDelegate network_delegate; + network_delegate.set_first_party_only_cookies_enabled(true); + default_context_.set_network_delegate(&network_delegate); + TestDelegate d; + scoped_ptr req(default_context_.CreateRequest( + test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); + req->set_first_party_for_cookies(test_server.GetURL("")); + req->Start(); + base::RunLoop().Run(); + + EXPECT_TRUE(d.data_received().find("FirstPartyCookieToSet=1") != + std::string::npos); + EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); + EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); + } + + // Verify that the cookie is not-sent for non-first-party requests. + { + TestNetworkDelegate network_delegate; + network_delegate.set_first_party_only_cookies_enabled(true); + default_context_.set_network_delegate(&network_delegate); + TestDelegate d; + scoped_ptr req(default_context_.CreateRequest( + test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); + req->set_first_party_for_cookies(GURL("http://third-party.test/")); + req->Start(); + base::RunLoop().Run(); + + EXPECT_TRUE(d.data_received().find("FirstPartyCookieToSet=1") == + std::string::npos); + EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); + EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); + } +} + +TEST_F(URLRequestTest, FirstPartyOnlyCookiesDisabled) { + LocalHttpTestServer test_server; + ASSERT_TRUE(test_server.Start()); + + // Set up a 'First-Party-Only' cookie (on '127.0.0.1', as that's where + // LocalHttpTestServer points). + { + TestNetworkDelegate network_delegate; + network_delegate.set_first_party_only_cookies_enabled(false); + default_context_.set_network_delegate(&network_delegate); + + TestDelegate d; + scoped_ptr req(default_context_.CreateRequest( + test_server.GetURL( + "set-cookie?FirstPartyCookieToSet=1;First-Party-Only"), + DEFAULT_PRIORITY, &d, NULL)); + req->Start(); + base::RunLoop().Run(); + EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); + EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); + EXPECT_EQ(1, network_delegate.set_cookie_count()); + } + + // Verify that the cookie is sent for first-party requests. + { + TestNetworkDelegate network_delegate; + network_delegate.set_first_party_only_cookies_enabled(false); + default_context_.set_network_delegate(&network_delegate); + TestDelegate d; + scoped_ptr req(default_context_.CreateRequest( + test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); + req->set_first_party_for_cookies(test_server.GetURL("")); + req->Start(); + base::RunLoop().Run(); + + EXPECT_TRUE(d.data_received().find("FirstPartyCookieToSet=1") != + std::string::npos); + EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); + EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); + } + + // Verify that the cookie is also sent for non-first-party requests. + { + TestNetworkDelegate network_delegate; + network_delegate.set_first_party_only_cookies_enabled(false); + default_context_.set_network_delegate(&network_delegate); + TestDelegate d; + scoped_ptr req(default_context_.CreateRequest( + test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); + req->set_first_party_for_cookies(GURL("http://third-party.test/")); + req->Start(); + base::RunLoop().Run(); + + EXPECT_TRUE(d.data_received().find("FirstPartyCookieToSet=1") != + std::string::npos); + EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); + EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); + } +} + // FixedDateNetworkDelegate swaps out the server's HTTP Date response header // value for the |fixed_date| argument given to the constructor. class FixedDateNetworkDelegate : public TestNetworkDelegate {