From 8b400331c736101fd414113a0d0d7ade0e65cb5d Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Thu, 2 May 2019 18:23:57 -0400 Subject: [PATCH] Support disabling of cookie load/save via SetSupportedSchemes (see issue #2622). With this change the CefCookieManager::SetSupportedSchemes method can be used to disable all loading and saving of cookies for the associated request context. This matches functionality that was previously available via GetBlockingManager. This change also fixes a bug where Set-Cookie headers returned for a request handled via CefSchemeHandlerFactory would be ignored if there was not also a CefResourceRequestHandler returned for the request. To test: All CookieTest.* tests pass. --- include/capi/cef_cookie_capi.h | 14 +- include/cef_api_hash.h | 10 +- include/cef_cookie.h | 12 +- libcef/browser/browser_context.h | 7 +- libcef/browser/net/cookie_manager_old_impl.cc | 26 +- libcef/browser/net/cookie_manager_old_impl.h | 9 +- .../browser/net/url_request_context_getter.cc | 15 +- .../browser/net/url_request_context_getter.h | 4 +- .../net_service/cookie_manager_impl.cc | 19 +- .../browser/net_service/cookie_manager_impl.h | 1 + .../resource_request_handler_wrapper.cc | 8 +- libcef_dll/cpptoc/cookie_manager_cpptoc.cc | 6 +- libcef_dll/ctocpp/cookie_manager_ctocpp.cc | 5 +- libcef_dll/ctocpp/cookie_manager_ctocpp.h | 3 +- patch/patches/services_network_2622.patch | 16 +- tests/ceftests/cookie_unittest.cc | 324 ++++++++++++------ tests/ceftests/urlrequest_unittest.cc | 2 +- tests/shared/browser/client_app_browser.cc | 2 +- 18 files changed, 322 insertions(+), 161 deletions(-) diff --git a/include/capi/cef_cookie_capi.h b/include/capi/cef_cookie_capi.h index ef4cd7c18..f931f422c 100644 --- a/include/capi/cef_cookie_capi.h +++ b/include/capi/cef_cookie_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=7ec5f39057b2a75576fe732fc7bff7b953956fe6$ +// $hash=ef1fc4ab41a3fc6046a8754ce1a64bc2732332e6$ // #ifndef CEF_INCLUDE_CAPI_CEF_COOKIE_CAPI_H_ @@ -62,14 +62,18 @@ typedef struct _cef_cookie_manager_t { cef_base_ref_counted_t base; /// - // Set the schemes supported by this manager. The default schemes ("http", - // "https", "ws" and "wss") will always be supported. If |callback| is non- - // NULL it will be executed asnychronously on the UI thread after the change - // has been applied. Must be called before any cookies are accessed. + // Set the schemes supported by this manager. If |include_defaults| is true + // (1) the default schemes ("http", "https", "ws" and "wss") will also be + // supported. Calling this function with an NULL |schemes| value and + // |include_defaults| set to false (0) will disable all loading and saving of + // cookies for this manager. If |callback| is non-NULL it will be executed + // asnychronously on the UI thread after the change has been applied. Must be + // called before any cookies are accessed. /// void(CEF_CALLBACK* set_supported_schemes)( struct _cef_cookie_manager_t* self, cef_string_list_t schemes, + int include_defaults, struct _cef_completion_callback_t* callback); /// diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h index 74f23eadd..1d0be326f 100644 --- a/include/cef_api_hash.h +++ b/include/cef_api_hash.h @@ -34,7 +34,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=9d23feaba9aac41aff230ff51bb08a5f18ddda48$ +// $hash=dd6129d832b33b4da283d86722ba5a7b743a15a5$ // #ifndef CEF_INCLUDE_API_HASH_H_ @@ -47,13 +47,13 @@ // way that may cause binary incompatibility with other builds. The universal // hash value will change if any platform is affected whereas the platform hash // values will change only if that particular platform is affected. -#define CEF_API_HASH_UNIVERSAL "02918155c74c1f12406114bce5f668fba5fb8b8a" +#define CEF_API_HASH_UNIVERSAL "91bb58af264779076e95dfd1a63033bc7da296cd" #if defined(OS_WIN) -#define CEF_API_HASH_PLATFORM "d331dc982255599b7a6929cc38fdf133e58c16e6" +#define CEF_API_HASH_PLATFORM "7cacaf3f958d22f84e4ee6b5216dc5ccc4c18e31" #elif defined(OS_MACOSX) -#define CEF_API_HASH_PLATFORM "8ab0117e584d529145dee6aac2409a0d523fae95" +#define CEF_API_HASH_PLATFORM "b471cf826966f5917fd3855996c8998898df2334" #elif defined(OS_LINUX) -#define CEF_API_HASH_PLATFORM "6663ec2c35cbc01eec7a1bd939fcb7bf45203a42" +#define CEF_API_HASH_PLATFORM "1b0a73214b4f50b23e2dab96d7a1d6def2c195dc" #endif #ifdef __cplusplus diff --git a/include/cef_cookie.h b/include/cef_cookie.h index e833829f1..f48c7df40 100644 --- a/include/cef_cookie.h +++ b/include/cef_cookie.h @@ -65,14 +65,18 @@ class CefCookieManager : public virtual CefBaseRefCounted { CefRefPtr callback); /// - // Set the schemes supported by this manager. The default schemes ("http", - // "https", "ws" and "wss") will always be supported. If |callback| is non- - // NULL it will be executed asnychronously on the UI thread after the change - // has been applied. Must be called before any cookies are accessed. + // Set the schemes supported by this manager. If |include_defaults| is true + // the default schemes ("http", "https", "ws" and "wss") will also be + // supported. Calling this method with an empty |schemes| value and + // |include_defaults| set to false will disable all loading and saving of + // cookies for this manager. If |callback| is non-NULL it will be executed + // asnychronously on the UI thread after the change has been applied. Must be + // called before any cookies are accessed. /// /*--cef(optional_param=callback)--*/ virtual void SetSupportedSchemes( const std::vector& schemes, + bool include_defaults, CefRefPtr callback) = 0; /// diff --git a/libcef/browser/browser_context.h b/libcef/browser/browser_context.h index 956053b12..28b80d899 100644 --- a/libcef/browser/browser_context.h +++ b/libcef/browser/browser_context.h @@ -186,7 +186,7 @@ class CefBrowserContext : public ChromeProfileStub, bool ShouldPersistSessionCookies() override { return should_persist_session_cookies_; } - std::vector GetCookieableSchemes() override { + base::Optional> GetCookieableSchemes() override { return cookieable_schemes_; } @@ -233,7 +233,8 @@ class CefBrowserContext : public ChromeProfileStub, void set_should_persist_session_cookies(bool value) { should_persist_session_cookies_ = value; } - void set_cookieable_schemes(const std::vector& schemes) { + void set_cookieable_schemes( + base::Optional> schemes) { cookieable_schemes_ = schemes; } @@ -273,7 +274,7 @@ class CefBrowserContext : public ChromeProfileStub, // |visitedlink_listener_| is owned by visitedlink_master_. CefVisitedLinkListener* visitedlink_listener_; bool should_persist_session_cookies_ = false; - std::vector cookieable_schemes_; + base::Optional> cookieable_schemes_; std::unique_ptr resource_context_; diff --git a/libcef/browser/net/cookie_manager_old_impl.cc b/libcef/browser/net/cookie_manager_old_impl.cc index 6fc634c88..1b2489095 100644 --- a/libcef/browser/net/cookie_manager_old_impl.cc +++ b/libcef/browser/net/cookie_manager_old_impl.cc @@ -165,11 +165,12 @@ net::CookieStore* CefCookieManagerOldImpl::GetExistingCookieStore() { void CefCookieManagerOldImpl::SetSupportedSchemes( const std::vector& schemes, + bool include_defaults, CefRefPtr callback) { if (!CEF_CURRENTLY_ON_IOT()) { CEF_POST_TASK( CEF_IOT, base::Bind(&CefCookieManagerOldImpl::SetSupportedSchemes, this, - schemes, callback)); + schemes, include_defaults, callback)); return; } @@ -178,7 +179,7 @@ void CefCookieManagerOldImpl::SetSupportedSchemes( for (; it != schemes.end(); ++it) scheme_set.push_back(*it); - SetSupportedSchemesInternal(scheme_set, callback); + SetSupportedSchemesInternal(scheme_set, include_defaults, callback); } bool CefCookieManagerOldImpl::VisitAllCookies( @@ -243,16 +244,19 @@ bool CefCookieManagerOldImpl::FlushStore( // static void CefCookieManagerOldImpl::SetCookieMonsterSchemes( net::CookieMonster* cookie_monster, - const std::vector& schemes) { + const std::vector& schemes, + bool include_defaults) { CEF_REQUIRE_IOT(); std::vector all_schemes = schemes; - // Add default schemes that should always support cookies. - all_schemes.push_back("http"); - all_schemes.push_back("https"); - all_schemes.push_back("ws"); - all_schemes.push_back("wss"); + if (include_defaults) { + // Add default schemes that should always support cookies. + all_schemes.push_back("http"); + all_schemes.push_back("https"); + all_schemes.push_back("ws"); + all_schemes.push_back("wss"); + } cookie_monster->SetCookieableSchemes( all_schemes, net::CookieStore::SetCookieableSchemesCallback()); @@ -292,11 +296,12 @@ void CefCookieManagerOldImpl::InitWithContext( void CefCookieManagerOldImpl::SetSupportedSchemesWithContext( const std::vector& schemes, + bool include_defaults, CefRefPtr callback, scoped_refptr request_context) { CEF_REQUIRE_IOT(); - request_context->SetCookieSupportedSchemes(schemes); + request_context->SetCookieSupportedSchemes(schemes, include_defaults); RunAsyncCompletionOnUIThread(callback); } @@ -322,12 +327,13 @@ void CefCookieManagerOldImpl::GetCookieStoreWithContext( void CefCookieManagerOldImpl::SetSupportedSchemesInternal( const std::vector& schemes, + bool include_defaults, CefRefPtr callback) { CEF_REQUIRE_IOT(); RunMethodWithContext( base::Bind(&CefCookieManagerOldImpl::SetSupportedSchemesWithContext, this, - schemes, callback)); + schemes, include_defaults, callback)); } void CefCookieManagerOldImpl::VisitAllCookiesInternal( diff --git a/libcef/browser/net/cookie_manager_old_impl.h b/libcef/browser/net/cookie_manager_old_impl.h index e58a3b784..ec0fa9f93 100644 --- a/libcef/browser/net/cookie_manager_old_impl.h +++ b/libcef/browser/net/cookie_manager_old_impl.h @@ -43,6 +43,7 @@ class CefCookieManagerOldImpl : public CefCookieManager { // CefCookieManager methods. void SetSupportedSchemes(const std::vector& schemes, + bool include_defaults, CefRefPtr callback) override; bool VisitAllCookies(CefRefPtr visitor) override; bool VisitUrlCookies(const CefString& url, @@ -56,10 +57,10 @@ class CefCookieManagerOldImpl : public CefCookieManager { CefRefPtr callback) override; bool FlushStore(CefRefPtr callback) override; - // Set the schemes supported by |cookie_monster|. Default schemes will always - // be supported. + // Set the schemes supported by |cookie_monster|. static void SetCookieMonsterSchemes(net::CookieMonster* cookie_monster, - const std::vector& schemes); + const std::vector& schemes, + bool include_defaults); private: // Execute |method| on the IO thread once the request context is available. @@ -71,6 +72,7 @@ class CefCookieManagerOldImpl : public CefCookieManager { scoped_refptr request_context); void SetSupportedSchemesWithContext( const std::vector& schemes, + bool include_defaults, CefRefPtr callback, scoped_refptr request_context); void GetCookieStoreWithContext( @@ -79,6 +81,7 @@ class CefCookieManagerOldImpl : public CefCookieManager { scoped_refptr request_context); void SetSupportedSchemesInternal(const std::vector& schemes, + bool include_defaults, CefRefPtr callback); void VisitAllCookiesInternal(CefRefPtr visitor, const CookieStoreGetter& cookie_store_getter); diff --git a/libcef/browser/net/url_request_context_getter.cc b/libcef/browser/net/url_request_context_getter.cc index 8947ae0a4..16b9480cb 100644 --- a/libcef/browser/net/url_request_context_getter.cc +++ b/libcef/browser/net/url_request_context_getter.cc @@ -480,13 +480,15 @@ net::HostResolver* CefURLRequestContextGetter::GetHostResolver() const { } void CefURLRequestContextGetter::SetCookieSupportedSchemes( - const std::vector& schemes) { + const std::vector& schemes, + bool include_defaults) { CEF_REQUIRE_IOT(); io_state_->cookie_supported_schemes_ = schemes; + io_state_->include_defaults_ = include_defaults; CefCookieManagerOldImpl::SetCookieMonsterSchemes( - static_cast(GetExistingCookieStore()), - io_state_->cookie_supported_schemes_); + static_cast(GetExistingCookieStore()), schemes, + include_defaults); } void CefURLRequestContextGetter::AddHandler( @@ -541,15 +543,16 @@ void CefURLRequestContextGetter::SetCookieStoragePath( // Set the new cookie store that will be used for all new requests. The old // cookie store, if any, will be automatically flushed and closed when no // longer referenced. - std::unique_ptr cookie_monster(new net::CookieMonster( - persistent_store.get(), io_state_->net_log_)); + std::unique_ptr cookie_monster( + new net::CookieMonster(persistent_store.get(), io_state_->net_log_)); if (persistent_store.get() && persist_session_cookies) cookie_monster->SetPersistSessionCookies(true); io_state_->cookie_store_path_ = path; // Restore the previously supported schemes. CefCookieManagerOldImpl::SetCookieMonsterSchemes( - cookie_monster.get(), io_state_->cookie_supported_schemes_); + cookie_monster.get(), io_state_->cookie_supported_schemes_, + io_state_->include_defaults_); io_state_->storage_->set_cookie_store(std::move(cookie_monster)); } diff --git a/libcef/browser/net/url_request_context_getter.h b/libcef/browser/net/url_request_context_getter.h index 7f6673aea..e6915ee18 100644 --- a/libcef/browser/net/url_request_context_getter.h +++ b/libcef/browser/net/url_request_context_getter.h @@ -68,7 +68,8 @@ class CefURLRequestContextGetter : public net::URLRequestContextGetter { // CefURLRequestContextGetter implementation. net::HostResolver* GetHostResolver() const; - void SetCookieSupportedSchemes(const std::vector& schemes); + void SetCookieSupportedSchemes(const std::vector& schemes, + bool include_defaults); // Keep a reference to all handlers sharing this context so that they'll be // kept alive until the context is destroyed. @@ -116,6 +117,7 @@ class CefURLRequestContextGetter : public net::URLRequestContextGetter { base::FilePath cookie_store_path_; std::vector cookie_supported_schemes_; + bool include_defaults_ = true; std::vector> handler_list_; diff --git a/libcef/browser/net_service/cookie_manager_impl.cc b/libcef/browser/net_service/cookie_manager_impl.cc index cb0cc692a..a80b87f07 100644 --- a/libcef/browser/net_service/cookie_manager_impl.cc +++ b/libcef/browser/net_service/cookie_manager_impl.cc @@ -98,11 +98,12 @@ void CefCookieManagerImpl::Initialize( void CefCookieManagerImpl::SetSupportedSchemes( const std::vector& schemes, + bool include_defaults, CefRefPtr callback) { if (!CEF_CURRENTLY_ON_UIT()) { CEF_POST_TASK(CEF_UIT, base::Bind(&CefCookieManagerImpl::SetSupportedSchemes, this, - schemes, callback)); + schemes, include_defaults, callback)); return; } @@ -110,16 +111,20 @@ void CefCookieManagerImpl::SetSupportedSchemes( for (const auto& scheme : schemes) all_schemes.push_back(scheme); - // This list should match CookieMonster::kDefaultCookieableSchemes. - all_schemes.push_back("http"); - all_schemes.push_back("https"); - all_schemes.push_back("ws"); - all_schemes.push_back("wss"); + if (include_defaults) { + // Add default schemes that should always support cookies. + // This list should match CookieMonster::kDefaultCookieableSchemes. + all_schemes.push_back("http"); + all_schemes.push_back("https"); + all_schemes.push_back("ws"); + all_schemes.push_back("wss"); + } // This will be forwarded to the CookieMonster that lives in the // NetworkService process when the NetworkContext is created via // CefContentBrowserClient::CreateNetworkContext. - request_context_->GetBrowserContext()->set_cookieable_schemes(all_schemes); + request_context_->GetBrowserContext()->set_cookieable_schemes( + base::make_optional(all_schemes)); RunAsyncCompletionOnUIThread(callback); } diff --git a/libcef/browser/net_service/cookie_manager_impl.h b/libcef/browser/net_service/cookie_manager_impl.h index 68ecc24b6..baa4ccbcc 100644 --- a/libcef/browser/net_service/cookie_manager_impl.h +++ b/libcef/browser/net_service/cookie_manager_impl.h @@ -23,6 +23,7 @@ class CefCookieManagerImpl : public CefCookieManager { // CefCookieManager methods. void SetSupportedSchemes(const std::vector& schemes, + bool include_defaults, CefRefPtr callback) override; bool VisitAllCookies(CefRefPtr visitor) override; bool VisitUrlCookies(const CefString& url, diff --git a/libcef/browser/net_service/resource_request_handler_wrapper.cc b/libcef/browser/net_service/resource_request_handler_wrapper.cc index 2577cb1fd..eb580c097 100644 --- a/libcef/browser/net_service/resource_request_handler_wrapper.cc +++ b/libcef/browser/net_service/resource_request_handler_wrapper.cc @@ -453,8 +453,12 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler { RequestState* state = GetState(id); DCHECK(state); if (!state->handler_) { - InterceptedRequestHandler::OnRequestResponse( - id, request, head, redirect_info, std::move(callback)); + // Cookies may come from a scheme handler. + MaybeSaveCookies( + state, request, head, + base::BindOnce( + std::move(callback), ResponseMode::CONTINUE, nullptr, + redirect_info.has_value() ? redirect_info->new_url : GURL())); return; } diff --git a/libcef_dll/cpptoc/cookie_manager_cpptoc.cc b/libcef_dll/cpptoc/cookie_manager_cpptoc.cc index a66999003..aa7f0efac 100644 --- a/libcef_dll/cpptoc/cookie_manager_cpptoc.cc +++ b/libcef_dll/cpptoc/cookie_manager_cpptoc.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=a672fab541f9c28f77a06c31d89f5a9d66c78751$ +// $hash=887754026eb62e631a0279fbba8fb1c370f0bcf7$ // #include "libcef_dll/cpptoc/cookie_manager_cpptoc.h" @@ -42,6 +42,7 @@ namespace { void CEF_CALLBACK cookie_manager_set_supported_schemes(struct _cef_cookie_manager_t* self, cef_string_list_t schemes, + int include_defaults, cef_completion_callback_t* callback) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -60,7 +61,8 @@ cookie_manager_set_supported_schemes(struct _cef_cookie_manager_t* self, // Execute CefCookieManagerCppToC::Get(self)->SetSupportedSchemes( - schemesList, CefCompletionCallbackCToCpp::Wrap(callback)); + schemesList, include_defaults ? true : false, + CefCompletionCallbackCToCpp::Wrap(callback)); } int CEF_CALLBACK diff --git a/libcef_dll/ctocpp/cookie_manager_ctocpp.cc b/libcef_dll/ctocpp/cookie_manager_ctocpp.cc index b303f2fc9..e371cd5dd 100644 --- a/libcef_dll/ctocpp/cookie_manager_ctocpp.cc +++ b/libcef_dll/ctocpp/cookie_manager_ctocpp.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=fdbb50cba70b9638aaaadc2e4040b18390ae3a6d$ +// $hash=87369bed5916a070a4f1a7f4bb9fcff5885cd31f$ // #include "libcef_dll/ctocpp/cookie_manager_ctocpp.h" @@ -41,6 +41,7 @@ CefRefPtr CefCookieManager::GetGlobalManager( NO_SANITIZE("cfi-icall") void CefCookieManagerCToCpp::SetSupportedSchemes( const std::vector& schemes, + bool include_defaults, CefRefPtr callback) { cef_cookie_manager_t* _struct = GetStruct(); if (CEF_MEMBER_MISSING(_struct, set_supported_schemes)) @@ -57,7 +58,7 @@ void CefCookieManagerCToCpp::SetSupportedSchemes( transfer_string_list_contents(schemes, schemesList); // Execute - _struct->set_supported_schemes(_struct, schemesList, + _struct->set_supported_schemes(_struct, schemesList, include_defaults, CefCompletionCallbackCppToC::Wrap(callback)); // Restore param:schemes; type: string_vec_byref_const diff --git a/libcef_dll/ctocpp/cookie_manager_ctocpp.h b/libcef_dll/ctocpp/cookie_manager_ctocpp.h index f36a7868f..b56331820 100644 --- a/libcef_dll/ctocpp/cookie_manager_ctocpp.h +++ b/libcef_dll/ctocpp/cookie_manager_ctocpp.h @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=99bb8be3c19be11e4abf2cf904d75667723ae643$ +// $hash=c08c701ad13790067983a7b5eb964975bc1f186b$ // #ifndef CEF_LIBCEF_DLL_CTOCPP_COOKIE_MANAGER_CTOCPP_H_ @@ -37,6 +37,7 @@ class CefCookieManagerCToCpp // CefCookieManager methods. void SetSupportedSchemes(const std::vector& schemes, + bool include_defaults, CefRefPtr callback) OVERRIDE; bool VisitAllCookies(CefRefPtr visitor) OVERRIDE; bool VisitUrlCookies(const CefString& url, diff --git a/patch/patches/services_network_2622.patch b/patch/patches/services_network_2622.patch index d06857ce3..a867f46fe 100644 --- a/patch/patches/services_network_2622.patch +++ b/patch/patches/services_network_2622.patch @@ -35,7 +35,7 @@ index 2b24d1ac1b5b..6577495d87a9 100644 base_cache_path.Append(chrome::kCacheDirname); network_context_params->http_cache_max_size = diff --git chrome/browser/profiles/profile.h chrome/browser/profiles/profile.h -index c70a4c0f48ac..8aaadf324a0e 100644 +index c70a4c0f48ac..f76776fb39bf 100644 --- chrome/browser/profiles/profile.h +++ chrome/browser/profiles/profile.h @@ -310,6 +310,11 @@ class Profile : public content::BrowserContext { @@ -43,15 +43,15 @@ index c70a4c0f48ac..8aaadf324a0e 100644 virtual bool ShouldPersistSessionCookies(); + // Returns schemes that should be cookieable, if other than the defaults. -+ virtual std::vector GetCookieableSchemes() { -+ return std::vector(); ++ virtual base::Optional> GetCookieableSchemes() { ++ return base::nullopt; + } + // Creates NetworkContext for the specified isolated app (or for the profile // itself, if |relative_path| is empty). virtual network::mojom::NetworkContextPtr CreateNetworkContext( diff --git services/network/network_context.cc services/network/network_context.cc -index b882aa825923..f1921814e1d8 100644 +index b882aa825923..eedf167ee32b 100644 --- services/network/network_context.cc +++ services/network/network_context.cc @@ -1733,6 +1733,7 @@ URLRequestContextOwner NetworkContext::ApplyContextParamsToBuilder( @@ -82,9 +82,9 @@ index b882aa825923..f1921814e1d8 100644 + std::make_unique(nullptr /* store */, net_log); } -+ if (!params_->cookieable_schemes.empty()) { ++ if (params_->cookieable_schemes.has_value()) { + cookie_store->SetCookieableSchemes( -+ params_->cookieable_schemes, ++ *params_->cookieable_schemes, + net::CookieStore::SetCookieableSchemesCallback()); + } + @@ -94,7 +94,7 @@ index b882aa825923..f1921814e1d8 100644 std::make_unique( params_->accept_language, params_->user_agent); diff --git services/network/public/mojom/network_context.mojom services/network/public/mojom/network_context.mojom -index 864e55731cdf..9fea7361d730 100644 +index 864e55731cdf..ef70c6f30168 100644 --- services/network/public/mojom/network_context.mojom +++ services/network/public/mojom/network_context.mojom @@ -189,6 +189,9 @@ struct NetworkContextParams { @@ -102,7 +102,7 @@ index 864e55731cdf..9fea7361d730 100644 bool persist_session_cookies = false; + // Schemes that will be passed to CookieMonster::SetCookieableSchemes. -+ array cookieable_schemes; ++ array? cookieable_schemes; + // True if an HTTP cache should be used. bool http_cache_enabled = true; diff --git a/tests/ceftests/cookie_unittest.cc b/tests/ceftests/cookie_unittest.cc index ca4c129e9..f8956fcd1 100644 --- a/tests/ceftests/cookie_unittest.cc +++ b/tests/ceftests/cookie_unittest.cc @@ -658,6 +658,21 @@ namespace { const char kCustomCookieScheme[] = "ccustom"; +class CompletionCallback : public CefCompletionCallback { + public: + explicit CompletionCallback(const base::Closure& callback) + : callback_(callback) {} + + void OnComplete() override { + callback_.Run(); + callback_.Reset(); + } + + private: + base::Closure callback_; + IMPLEMENT_REFCOUNTING(CompletionCallback); +}; + class CookieTestSchemeHandler : public TestHandler { public: class SchemeHandler : public CefResourceHandler { @@ -768,23 +783,12 @@ class CookieTestSchemeHandler : public TestHandler { IMPLEMENT_REFCOUNTING(SchemeHandlerFactory); }; - class CompletionCallback : public CefCompletionCallback { - public: - explicit CompletionCallback(const base::Closure& callback) - : callback_(callback) {} - - void OnComplete() override { - callback_.Run(); - callback_.Reset(); - } - - private: - base::Closure callback_; - IMPLEMENT_REFCOUNTING(CompletionCallback); - }; - - CookieTestSchemeHandler(const std::string& scheme, bool use_global) - : scheme_(scheme), use_global_(use_global) { + CookieTestSchemeHandler(const std::string& scheme, + bool use_global, + bool block_cookies = false) + : scheme_(scheme), + use_global_(use_global), + block_cookies_(block_cookies) { url1_ = scheme + "://cookie-tests/cookie1.html"; url2_ = scheme + "://cookie-tests/cookie2.html"; url3_ = scheme + "://cookie-tests/cookie3.html"; @@ -803,14 +807,16 @@ class CookieTestSchemeHandler : public TestHandler { request_context_->RegisterSchemeHandlerFactory( scheme_, "cookie-tests", new SchemeHandlerFactory(this)); manager_ = request_context_->GetCookieManager(NULL); - if (!use_global_) { + if (!use_global_ && (scheme_ == kCustomCookieScheme || block_cookies_)) { std::vector schemes; - schemes.push_back(kCustomCookieScheme); + if (!block_cookies_) + schemes.push_back(kCustomCookieScheme); // Need to wait for completion before creating the browser. manager_->SetSupportedSchemes( - schemes, new CompletionCallback(base::Bind( - &CookieTestSchemeHandler::CreateBrowserContinue, this))); + schemes, !block_cookies_ /* include_defaults */, + new CompletionCallback(base::Bind( + &CookieTestSchemeHandler::CreateBrowserContinue, this))); } else { CreateBrowserContinue(); } @@ -875,17 +881,26 @@ class CookieTestSchemeHandler : public TestHandler { EXPECT_TRUE(got_process_request1_); EXPECT_TRUE(got_process_request2_); EXPECT_TRUE(got_process_request3_); - if (IsNetworkServiceEnabled()) - EXPECT_TRUE(got_create_cookie_); - else - EXPECT_FALSE(got_create_cookie_); - EXPECT_TRUE(got_process_request_cookie_); EXPECT_TRUE(got_load_end1_); EXPECT_TRUE(got_load_end2_); EXPECT_TRUE(got_load_end3_); - EXPECT_TRUE(got_cookie1_); - EXPECT_TRUE(got_cookie2_); - EXPECT_TRUE(got_cookie3_); + + if (block_cookies_) { + EXPECT_FALSE(got_create_cookie_); + EXPECT_FALSE(got_process_request_cookie_); + EXPECT_FALSE(got_cookie1_); + EXPECT_FALSE(got_cookie2_); + EXPECT_FALSE(got_cookie3_); + } else { + if (IsNetworkServiceEnabled()) + EXPECT_TRUE(got_create_cookie_); + else + EXPECT_FALSE(got_create_cookie_); + EXPECT_TRUE(got_process_request_cookie_); + EXPECT_TRUE(got_cookie1_); + EXPECT_TRUE(got_cookie2_); + EXPECT_TRUE(got_cookie3_); + } // Unregister the scheme handler. request_context_->RegisterSchemeHandlerFactory(scheme_, "cookie-tests", @@ -925,6 +940,7 @@ class CookieTestSchemeHandler : public TestHandler { const std::string scheme_; const bool use_global_; + const bool block_cookies_; std::string url1_; std::string url2_; std::string url3_; @@ -967,6 +983,14 @@ TEST(CookieTest, GetCookieManagerHttpInMemory) { ReleaseAndWaitForDestructor(handler); } +// Verify use of an in-memory cookie manager with HTTP to block all cookies. +TEST(CookieTest, GetCookieManagerHttpInMemoryBlocked) { + CefRefPtr handler = + new CookieTestSchemeHandler("http", false, true); + handler->ExecuteTest(); + ReleaseAndWaitForDestructor(handler); +} + // Verify use of the global cookie manager with a custom scheme. TEST(CookieTest, GetCookieManagerCustomGlobal) { CefRefPtr handler = @@ -990,24 +1014,27 @@ const char kCookieAccessDomain[] = "test-cookies.com"; const char kCookieAccessServerIP[] = "127.0.0.1"; const uint16 kCookieAccessServerPort = 8099; -std::string GetCookieAccessOrigin(bool server_backend) { +std::string GetCookieAccessOrigin(const std::string& scheme, + bool server_backend) { std::stringstream ss; if (server_backend) { - ss << kCookieAccessScheme << "://" << kCookieAccessServerIP << ":" + ss << scheme << "://" << kCookieAccessServerIP << ":" << kCookieAccessServerPort; } else { - ss << kCookieAccessScheme << "://" << kCookieAccessDomain; + ss << scheme << "://" << kCookieAccessDomain; } ss << "/"; return ss.str(); } -std::string GetCookieAccessUrl1(bool server_backend) { - return GetCookieAccessOrigin(server_backend) + "cookie1.html"; +std::string GetCookieAccessUrl1(const std::string& scheme, + bool server_backend) { + return GetCookieAccessOrigin(scheme, server_backend) + "cookie1.html"; } -std::string GetCookieAccessUrl2(bool server_backend) { - return GetCookieAccessOrigin(server_backend) + "cookie2.html"; +std::string GetCookieAccessUrl2(const std::string& scheme, + bool server_backend) { + return GetCookieAccessOrigin(scheme, server_backend) + "cookie2.html"; } void TestCookieString(const std::string& cookie_str, @@ -1459,8 +1486,15 @@ class CookieAccessTestHandler : public RoutingTestHandler, BLOCK_READ_WRITE = BLOCK_READ | BLOCK_WRITE, ALLOW_NO_FILTER = 1 << 2, - // Can only be used in combination with the SERVER backend. - ALLOW_NO_HANDLER = 1 << 3, + // Block all cookies using SetSupportedSchemes. Can only be used with a + // non-global request context because it's too late (during test execution) + // to call this method on the global context. + BLOCK_ALL_COOKIES = 1 << 3, + + // Return nullptr from GetResourceRequestHandler. Can only be used in + // combination with the SERVER or SCHEME_HANDLER backend (the + // RESOURCE_HANDLER backend would not be called). + ALLOW_NO_HANDLER = 1 << 4, }; enum TestBackend { @@ -1474,17 +1508,49 @@ class CookieAccessTestHandler : public RoutingTestHandler, RESOURCE_HANDLER, }; - CookieAccessTestHandler(TestMode test_mode, TestBackend test_backend) - : test_mode_(test_mode), test_backend_(test_backend) {} + CookieAccessTestHandler(TestMode test_mode, + TestBackend test_backend, + bool custom_scheme, + bool use_global) + : test_mode_(test_mode), + test_backend_(test_backend), + scheme_(custom_scheme ? kCustomCookieScheme : kCookieAccessScheme), + use_global_(use_global) { + if (test_mode_ == BLOCK_ALL_COOKIES) + CHECK(!use_global_); + else if (test_mode_ == ALLOW_NO_HANDLER) + CHECK_NE(RESOURCE_HANDLER, test_backend_); + if (test_backend_ == SERVER) + CHECK(!custom_scheme); + } void RunTest() override { - cookie_manager_ = CefCookieManager::GetGlobalManager(nullptr); + if (use_global_) { + context_ = CefRequestContext::GetGlobalContext(); + } else { + // Create the request context that will use an in-memory cache. + CefRequestContextSettings settings; + context_ = CefRequestContext::CreateContext(settings, NULL); + } + + cookie_manager_ = context_->GetCookieManager(nullptr); + SetTestTimeout(); - CefPostTask(TID_UI, - base::Bind(&CookieAccessTestHandler::StartBackend, this, - base::Bind(&CookieAccessTestHandler::RunTestContinue, - this))); + const bool block_cookies = (test_mode_ == BLOCK_ALL_COOKIES); + if (!use_global_ && (scheme_ == kCustomCookieScheme || block_cookies)) { + std::vector schemes; + if (!block_cookies) + schemes.push_back(kCustomCookieScheme); + + // Need to wait for completion before creating the browser. + cookie_manager_->SetSupportedSchemes( + schemes, !block_cookies /* include_defaults */, + new CompletionCallback(base::Bind( + &CookieAccessTestHandler::RunTestSetupContinue, this))); + } else { + RunTestSetupContinue(); + } } void DestroyTest() override { @@ -1495,8 +1561,7 @@ class CookieAccessTestHandler : public RoutingTestHandler, } cookie_manager_ = NULL; - if (context_) - context_ = NULL; + context_ = NULL; // Got both network requests. EXPECT_TRUE(data1_.got_request_); @@ -1511,7 +1576,10 @@ class CookieAccessTestHandler : public RoutingTestHandler, // Get 1 call to CanSaveCookie for the 1st network request due to the // network cookie. EXPECT_EQ(1, can_save_cookie1_ct_); - if (test_mode_ & BLOCK_WRITE) { + if (test_mode_ == BLOCK_ALL_COOKIES) { + // Never send any cookies. + EXPECT_EQ(0, can_send_cookie2_ct_); + } else if (test_mode_ & BLOCK_WRITE) { // Get 1 calls to CanSendCookie for the 2nd network request due to the // JS cookie (network cookie is blocked). EXPECT_EQ(1, can_send_cookie2_ct_); @@ -1522,13 +1590,20 @@ class CookieAccessTestHandler : public RoutingTestHandler, } } - // Always get the JS cookie via JS. - EXPECT_TRUE(got_cookie_js1_); - EXPECT_TRUE(got_cookie_js2_); - EXPECT_TRUE(got_cookie_js3_); + if (test_mode_ == BLOCK_ALL_COOKIES) { + // Never get the JS cookie via JS. + EXPECT_FALSE(got_cookie_js1_); + EXPECT_FALSE(got_cookie_js2_); + EXPECT_FALSE(got_cookie_js3_); + } else { + // Always get the JS cookie via JS. + EXPECT_TRUE(got_cookie_js1_); + EXPECT_TRUE(got_cookie_js2_); + EXPECT_TRUE(got_cookie_js3_); + } // Only get the net cookie via JS if cookie write was allowed. - if (test_mode_ & BLOCK_WRITE) { + if ((test_mode_ & BLOCK_WRITE) || test_mode_ == BLOCK_ALL_COOKIES) { EXPECT_FALSE(got_cookie_net1_); EXPECT_FALSE(got_cookie_net2_); EXPECT_FALSE(got_cookie_net3_); @@ -1543,7 +1618,7 @@ class CookieAccessTestHandler : public RoutingTestHandler, EXPECT_FALSE(data1_.got_cookie_net_); // 2nd network request... - if (test_mode_ & BLOCK_READ) { + if ((test_mode_ & BLOCK_READ) || test_mode_ == BLOCK_ALL_COOKIES) { // No cookies sent if reading was blocked. EXPECT_FALSE(data2_.got_cookie_js_); EXPECT_FALSE(data2_.got_cookie_net_); @@ -1580,10 +1655,8 @@ class CookieAccessTestHandler : public RoutingTestHandler, bool is_download, const CefString& request_initiator, bool& disable_default_handling) override { - if (test_mode_ == ALLOW_NO_HANDLER) { - DCHECK_EQ(SERVER, test_backend_); + if (test_mode_ == ALLOW_NO_HANDLER) return nullptr; - } return this; } @@ -1593,8 +1666,7 @@ class CookieAccessTestHandler : public RoutingTestHandler, CefRefPtr frame, CefRefPtr request) override { if (test_backend_ == RESOURCE_HANDLER) { - return scheme_factory_->Create(browser, frame, kCookieAccessScheme, - request); + return scheme_factory_->Create(browser, frame, scheme_, request); } return nullptr; @@ -1607,7 +1679,7 @@ class CookieAccessTestHandler : public RoutingTestHandler, EXPECT_IO_THREAD(); const std::string& url = request->GetURL(); - if (url == GetCookieAccessUrl2(test_backend_ == SERVER)) { + if (url == GetCookieAccessUrl2(scheme_, test_backend_ == SERVER)) { can_send_cookie2_ct_++; } else { ADD_FAILURE() << "Unexpected url: " << url; @@ -1628,7 +1700,7 @@ class CookieAccessTestHandler : public RoutingTestHandler, EXPECT_STREQ("value_net", CefString(&cookie.value).ToString().c_str()); const std::string& url = request->GetURL(); - if (url == GetCookieAccessUrl1(test_backend_ == SERVER)) { + if (url == GetCookieAccessUrl1(scheme_, test_backend_ == SERVER)) { can_save_cookie1_ct_++; } else { ADD_FAILURE() << "Unexpected url: " << url; @@ -1645,11 +1717,11 @@ class CookieAccessTestHandler : public RoutingTestHandler, CefRefPtr callback) override { const std::string& url = frame->GetURL(); const std::string& cookie_str = request.ToString(); - if (url == GetCookieAccessUrl1(test_backend_ == SERVER)) { + if (url == GetCookieAccessUrl1(scheme_, test_backend_ == SERVER)) { TestCookieString(cookie_str, got_cookie_js1_, got_cookie_net1_); browser->GetMainFrame()->LoadURL( - GetCookieAccessUrl2(test_backend_ == SERVER)); - } else if (url == GetCookieAccessUrl2(test_backend_ == SERVER)) { + GetCookieAccessUrl2(scheme_, test_backend_ == SERVER)); + } else if (url == GetCookieAccessUrl2(scheme_, test_backend_ == SERVER)) { TestCookieString(cookie_str, got_cookie_js2_, got_cookie_net2_); FinishTest(); } else { @@ -1681,8 +1753,8 @@ class CookieAccessTestHandler : public RoutingTestHandler, "" "COOKIE ACCESS TEST 1"; - handler->AddResponse(GetCookieAccessUrl1(test_backend_ == SERVER), - &data1_); + handler->AddResponse( + GetCookieAccessUrl1(scheme_, test_backend_ == SERVER), &data1_); } // 2nd request retrieves the cookies via JS. @@ -1699,11 +1771,18 @@ class CookieAccessTestHandler : public RoutingTestHandler, "" "COOKIE ACCESS TEST 2"; - handler->AddResponse(GetCookieAccessUrl2(test_backend_ == SERVER), - &data2_); + handler->AddResponse( + GetCookieAccessUrl2(scheme_, test_backend_ == SERVER), &data2_); } } + void RunTestSetupContinue() { + CefPostTask(TID_UI, + base::Bind(&CookieAccessTestHandler::StartBackend, this, + base::Bind(&CookieAccessTestHandler::RunTestContinue, + this))); + } + void StartBackend(const base::Closure& complete_callback) { if (test_backend_ == SERVER) { StartServer(complete_callback); @@ -1725,13 +1804,8 @@ class CookieAccessTestHandler : public RoutingTestHandler, scheme_factory_ = new CookieAccessSchemeHandlerFactory(); AddResponses(scheme_factory_.get()); if (test_backend_ == SCHEME_HANDLER) { - if (context_) { - context_->RegisterSchemeHandlerFactory( - kCookieAccessScheme, kCookieAccessDomain, scheme_factory_.get()); - } else { - CefRegisterSchemeHandlerFactory( - kCookieAccessScheme, kCookieAccessDomain, scheme_factory_.get()); - } + context_->RegisterSchemeHandlerFactory(scheme_, kCookieAccessDomain, + scheme_factory_.get()); } complete_callback.Run(); @@ -1744,7 +1818,8 @@ class CookieAccessTestHandler : public RoutingTestHandler, return; } - CreateBrowser(GetCookieAccessUrl1(test_backend_ == SERVER), context_); + CreateBrowser(GetCookieAccessUrl1(scheme_, test_backend_ == SERVER), + context_); } void FinishTest() { @@ -1806,13 +1881,8 @@ class CookieAccessTestHandler : public RoutingTestHandler, EXPECT_TRUE(scheme_factory_); if (test_backend_ == SCHEME_HANDLER) { - if (context_) { - context_->RegisterSchemeHandlerFactory(kCookieAccessScheme, - kCookieAccessDomain, nullptr); - } else { - CefRegisterSchemeHandlerFactory(kCookieAccessScheme, - kCookieAccessDomain, nullptr); - } + context_->RegisterSchemeHandlerFactory(scheme_, kCookieAccessDomain, + nullptr); } scheme_factory_->Shutdown(complete_callback); scheme_factory_ = nullptr; @@ -1820,6 +1890,8 @@ class CookieAccessTestHandler : public RoutingTestHandler, const TestMode test_mode_; const TestBackend test_backend_; + const std::string scheme_; + const bool use_global_; CefRefPtr context_; CefRefPtr cookie_manager_; @@ -1849,29 +1921,81 @@ class CookieAccessTestHandler : public RoutingTestHandler, IMPLEMENT_REFCOUNTING(CookieAccessTestHandler); }; +bool IsTestSupported(CookieAccessTestHandler::TestMode test_mode, + CookieAccessTestHandler::TestBackend backend_mode, + bool custom_scheme, + bool use_global) { + if (!IsNetworkServiceEnabled() && + backend_mode == CookieAccessTestHandler::RESOURCE_HANDLER && + custom_scheme) { + // The old network implementation does not support the same functionality + // for intercepting custom scheme requests via GetResourceHandler(). + return false; + } + return true; +} + } // namespace -#define ACCESS_TEST(name, test_mode, backend_mode) \ - TEST(CookieTest, Access##name) { \ - CefRefPtr handler = \ - new CookieAccessTestHandler(CookieAccessTestHandler::test_mode, \ - CookieAccessTestHandler::backend_mode); \ - handler->ExecuteTest(); \ - ReleaseAndWaitForDestructor(handler); \ +#define ACCESS_TEST(name, test_mode, backend_mode, custom_scheme, use_global) \ + TEST(CookieTest, Access##name) { \ + if (!IsTestSupported(CookieAccessTestHandler::test_mode, \ + CookieAccessTestHandler::backend_mode, custom_scheme, \ + use_global)) { \ + return; \ + } \ + CefRefPtr handler = new CookieAccessTestHandler( \ + CookieAccessTestHandler::test_mode, \ + CookieAccessTestHandler::backend_mode, custom_scheme, use_global); \ + handler->ExecuteTest(); \ + ReleaseAndWaitForDestructor(handler); \ } -#define ACCESS_TEST_ALL_MODES(name, backend_mode) \ - ACCESS_TEST(name##Allow, ALLOW, backend_mode) \ - ACCESS_TEST(name##AllowNoFilter, ALLOW_NO_FILTER, backend_mode) \ - ACCESS_TEST(name##BlockRead, BLOCK_READ, backend_mode) \ - ACCESS_TEST(name##BlockWrite, BLOCK_WRITE, backend_mode) \ - ACCESS_TEST(name##BlockReadWrite, BLOCK_READ_WRITE, backend_mode) +#define ACCESS_TEST_ALL_MODES(name, backend_mode, custom_scheme, use_global) \ + ACCESS_TEST(name##Allow, ALLOW, backend_mode, custom_scheme, use_global) \ + ACCESS_TEST(name##AllowNoFilter, ALLOW_NO_FILTER, backend_mode, \ + custom_scheme, use_global) \ + ACCESS_TEST(name##BlockRead, BLOCK_READ, backend_mode, custom_scheme, \ + use_global) \ + ACCESS_TEST(name##BlockWrite, BLOCK_WRITE, backend_mode, custom_scheme, \ + use_global) \ + ACCESS_TEST(name##BlockReadWrite, BLOCK_READ_WRITE, backend_mode, \ + custom_scheme, use_global) -ACCESS_TEST(ServerAllowNoHandler, ALLOW_NO_HANDLER, SERVER) +// These tests only work with a non-global context. +#define ACCESS_TEST_BLOCKALLCOOKIES_MODES(name, backend_mode, custom_scheme) \ + ACCESS_TEST(name##BlockAllCookies, BLOCK_ALL_COOKIES, backend_mode, \ + custom_scheme, false) -ACCESS_TEST_ALL_MODES(Server, SERVER) -ACCESS_TEST_ALL_MODES(Scheme, SCHEME_HANDLER) -ACCESS_TEST_ALL_MODES(Resource, RESOURCE_HANDLER) +// These tests only work with SERVER and SCHEME_HANDLER backends. +#define ACCESS_TEST_ALLOWNOHANDLER_MODES(name, backend_mode, custom_scheme) \ + ACCESS_TEST(name##GlobalAllowNoHandler, ALLOW_NO_HANDLER, backend_mode, \ + custom_scheme, false) \ + ACCESS_TEST(name##InMemoryAllowNoHandler, ALLOW_NO_HANDLER, backend_mode, \ + custom_scheme, true) + +#define ACCESS_TEST_CUSTOM(name, backend_mode) \ + ACCESS_TEST_ALL_MODES(name##CustomGlobal, backend_mode, true, true) \ + ACCESS_TEST_ALL_MODES(name##CustomInMemory, backend_mode, true, false) \ + ACCESS_TEST_BLOCKALLCOOKIES_MODES(name##CustomInMemory, backend_mode, true) + +#define ACCESS_TEST_STANDARD(name, backend_mode) \ + ACCESS_TEST_ALL_MODES(name##StandardGlobal, backend_mode, false, true) \ + ACCESS_TEST_ALL_MODES(name##StandardInMemory, backend_mode, false, false) \ + ACCESS_TEST_BLOCKALLCOOKIES_MODES(name##StandardInMemory, backend_mode, false) + +// Server backend only works with standard schemes. +ACCESS_TEST_STANDARD(Server, SERVER) +ACCESS_TEST_ALLOWNOHANDLER_MODES(ServerStandard, SERVER, false) + +// Other backends work with all schemes. +ACCESS_TEST_CUSTOM(Scheme, SCHEME_HANDLER) +ACCESS_TEST_ALLOWNOHANDLER_MODES(SchemeCustom, SCHEME_HANDLER, true) +ACCESS_TEST_STANDARD(Scheme, SCHEME_HANDLER) +ACCESS_TEST_ALLOWNOHANDLER_MODES(SchemeStandard, SCHEME_HANDLER, false) + +ACCESS_TEST_CUSTOM(Resource, RESOURCE_HANDLER) +ACCESS_TEST_STANDARD(Resource, RESOURCE_HANDLER) // Entry point for registering custom schemes. // Called from client_app_delegates.cc. diff --git a/tests/ceftests/urlrequest_unittest.cc b/tests/ceftests/urlrequest_unittest.cc index 364aa1f1f..472480132 100644 --- a/tests/ceftests/urlrequest_unittest.cc +++ b/tests/ceftests/urlrequest_unittest.cc @@ -2185,7 +2185,7 @@ class RequestTestHandler : public TestHandler { // Continue the test once supported schemes has been set. request_context->GetCookieManager(NULL)->SetSupportedSchemes( - supported_schemes, + supported_schemes, true, new SupportedSchemesCompletionCallback( base::Bind(&RequestTestHandler::PreSetupComplete, this))); } else { diff --git a/tests/shared/browser/client_app_browser.cc b/tests/shared/browser/client_app_browser.cc index 6832ca9ec..afed49c93 100644 --- a/tests/shared/browser/client_app_browser.cc +++ b/tests/shared/browser/client_app_browser.cc @@ -59,7 +59,7 @@ void ClientAppBrowser::OnContextInitialized() { CefRefPtr manager = CefCookieManager::GetGlobalManager(NULL); DCHECK(manager.get()); - manager->SetSupportedSchemes(cookieable_schemes_, NULL); + manager->SetSupportedSchemes(cookieable_schemes_, true, NULL); } print_handler_ = CreatePrintHandler();