mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	Fix crash using CefCookieManager::SetStoragePath (issue #2522)
This commit is contained in:
		
							
								
								
									
										2
									
								
								BUILD.gn
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								BUILD.gn
									
									
									
									
									
								
							| @@ -403,6 +403,8 @@ static_library("libcef_static") { | ||||
|     "libcef/browser/net/chrome_scheme_handler.h", | ||||
|     "libcef/browser/net/cookie_store_proxy.cc", | ||||
|     "libcef/browser/net/cookie_store_proxy.h", | ||||
|     "libcef/browser/net/cookie_store_source.cc", | ||||
|     "libcef/browser/net/cookie_store_source.h", | ||||
|     "libcef/browser/net/crlset_file_util_impl.cc", | ||||
|     "libcef/browser/net/devtools_scheme_handler.cc", | ||||
|     "libcef/browser/net/devtools_scheme_handler.h", | ||||
|   | ||||
| @@ -10,19 +10,18 @@ | ||||
|  | ||||
| #include "libcef/browser/content_browser_client.h" | ||||
| #include "libcef/browser/context.h" | ||||
| #include "libcef/browser/net/cookie_store_source.h" | ||||
| #include "libcef/browser/net/network_delegate.h" | ||||
| #include "libcef/common/task_runner_impl.h" | ||||
| #include "libcef/common/time_util.h" | ||||
|  | ||||
| #include "base/bind.h" | ||||
| #include "base/files/file_util.h" | ||||
| #include "base/format_macros.h" | ||||
| #include "base/logging.h" | ||||
| #include "base/threading/thread_restrictions.h" | ||||
| #include "content/browser/storage_partition_impl.h" | ||||
| #include "net/cookies/cookie_util.h" | ||||
| #include "net/cookies/parsed_cookie.h" | ||||
| #include "net/extras/sqlite/sqlite_persistent_cookie_store.h" | ||||
| #include "net/url_request/url_request_context.h" | ||||
| #include "url/gurl.h" | ||||
|  | ||||
| @@ -162,7 +161,7 @@ void CefCookieManagerImpl::GetCookieStore( | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   DCHECK(is_blocking_ || cookie_store_.get()); | ||||
|   DCHECK(is_blocking_ || cookie_source_); | ||||
|  | ||||
|   // Binding ref-counted |this| to CookieStoreGetter may result in | ||||
|   // heap-use-after-free if (a) the CookieStoreGetter contains the last | ||||
| @@ -185,8 +184,8 @@ void CefCookieManagerImpl::GetCookieStore( | ||||
|  | ||||
| net::CookieStore* CefCookieManagerImpl::GetExistingCookieStore() { | ||||
|   CEF_REQUIRE_IOT(); | ||||
|   if (cookie_store_.get()) { | ||||
|     return cookie_store_.get(); | ||||
|   if (cookie_source_) { | ||||
|     return cookie_source_->GetCookieStore(); | ||||
|   } else if (request_context_impl_.get()) { | ||||
|     net::CookieStore* cookie_store = | ||||
|         request_context_impl_->GetExistingCookieStore(); | ||||
| @@ -287,44 +286,13 @@ bool CefCookieManagerImpl::SetStoragePath( | ||||
|   if (!path.empty()) | ||||
|     new_path = base::FilePath(path); | ||||
|  | ||||
|   if (cookie_store_.get() && | ||||
|       ((storage_path_.empty() && path.empty()) || storage_path_ == new_path)) { | ||||
|     // The path has not changed so don't do anything. | ||||
|     RunAsyncCompletionOnIOThread(callback); | ||||
|     return true; | ||||
|   if (!cookie_source_) { | ||||
|     cookie_source_.reset(new CefCookieStoreOwnerSource()); | ||||
|   } | ||||
|  | ||||
|   scoped_refptr<net::SQLitePersistentCookieStore> persistent_store; | ||||
|   if (!new_path.empty()) { | ||||
|     // TODO(cef): Move directory creation to the blocking pool instead of | ||||
|     // allowing file IO on this thread. | ||||
|     base::ThreadRestrictions::ScopedAllowIO allow_io; | ||||
|     if (base::DirectoryExists(new_path) || base::CreateDirectory(new_path)) { | ||||
|       const base::FilePath& cookie_path = new_path.AppendASCII("Cookies"); | ||||
|       persistent_store = new net::SQLitePersistentCookieStore( | ||||
|           cookie_path, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), | ||||
|           // Intentionally using the background task runner exposed by CEF to | ||||
|           // facilitate unit test expectations. This task runner MUST be | ||||
|           // configured with BLOCK_SHUTDOWN. | ||||
|           CefContentBrowserClient::Get()->background_task_runner(), | ||||
|           persist_session_cookies, NULL); | ||||
|     } else { | ||||
|       NOTREACHED() << "The cookie storage directory could not be created"; | ||||
|       storage_path_.clear(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // 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. | ||||
|   cookie_store_.reset(new net::CookieMonster(persistent_store.get(), NULL)); | ||||
|   if (persistent_store.get() && persist_session_cookies) | ||||
|     cookie_store_->SetPersistSessionCookies(true); | ||||
|   storage_path_ = new_path; | ||||
|  | ||||
|   // Restore the previously supported schemes. | ||||
|   SetSupportedSchemesInternal(supported_schemes_, callback); | ||||
|   cookie_source_->SetCookieStoragePath(new_path, persist_session_cookies); | ||||
|  | ||||
|   RunAsyncCompletionOnIOThread(callback); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| @@ -502,10 +470,9 @@ void CefCookieManagerImpl::SetSupportedSchemesInternal( | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   DCHECK(is_blocking_ || cookie_store_.get()); | ||||
|   if (cookie_store_) { | ||||
|     supported_schemes_ = schemes; | ||||
|     SetCookieMonsterSchemes(cookie_store_.get(), supported_schemes_); | ||||
|   DCHECK(is_blocking_ || cookie_source_); | ||||
|   if (cookie_source_) { | ||||
|     cookie_source_->SetCookieSupportedSchemes(schemes); | ||||
|   } | ||||
|  | ||||
|   RunAsyncCompletionOnIOThread(callback); | ||||
|   | ||||
| @@ -15,6 +15,8 @@ | ||||
| #include "base/memory/weak_ptr.h" | ||||
| #include "net/cookies/cookie_monster.h" | ||||
|  | ||||
| class CefCookieStoreOwnerSource; | ||||
|  | ||||
| // Implementation of the CefCookieManager interface. | ||||
| class CefCookieManagerImpl : public CefCookieManager { | ||||
|  public: | ||||
| @@ -122,9 +124,7 @@ class CefCookieManagerImpl : public CefCookieManager { | ||||
|   scoped_refptr<CefURLRequestContextGetterImpl> request_context_impl_; | ||||
|  | ||||
|   // Used for cookie monsters owned by this object. | ||||
|   base::FilePath storage_path_; | ||||
|   std::vector<std::string> supported_schemes_; | ||||
|   std::unique_ptr<net::CookieMonster> cookie_store_; | ||||
|   std::unique_ptr<CefCookieStoreOwnerSource> cookie_source_; | ||||
|  | ||||
|   // Must be the last member. | ||||
|   base::WeakPtrFactory<CefCookieManagerImpl> weak_ptr_factory_; | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #include "libcef/browser/net/cookie_store_proxy.h" | ||||
|  | ||||
| #include "libcef/browser/cookie_manager_impl.h" | ||||
| #include "libcef/browser/net/url_request_context_impl.h" | ||||
| #include "include/cef_request_context.h" | ||||
| #include "libcef/browser/net/cookie_store_source.h" | ||||
| #include "libcef/browser/thread_util.h" | ||||
|  | ||||
| #include "base/logging.h" | ||||
| #include "net/url_request/url_request_context.h" | ||||
| #include "net/cookies/cookie_change_dispatcher.h" | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| @@ -44,12 +44,10 @@ class NullCookieChangeDispatcher : public net::CookieChangeDispatcher { | ||||
| }  // namespace | ||||
|  | ||||
| CefCookieStoreProxy::CefCookieStoreProxy( | ||||
|     CefURLRequestContextImpl* parent, | ||||
|     CefRefPtr<CefRequestContextHandler> handler) | ||||
|     : parent_(parent), handler_(handler) { | ||||
|     std::unique_ptr<CefCookieStoreSource> source) | ||||
|     : source_(std::move(source)) { | ||||
|   CEF_REQUIRE_IOT(); | ||||
|   DCHECK(parent_); | ||||
|   DCHECK(handler_.get()); | ||||
|   DCHECK(source_); | ||||
| } | ||||
|  | ||||
| CefCookieStoreProxy::~CefCookieStoreProxy() { | ||||
| @@ -189,24 +187,5 @@ bool CefCookieStoreProxy::IsEphemeral() { | ||||
|  | ||||
| net::CookieStore* CefCookieStoreProxy::GetCookieStore() { | ||||
|   CEF_REQUIRE_IOT(); | ||||
|  | ||||
|   CefRefPtr<CefCookieManager> manager = handler_->GetCookieManager(); | ||||
|   if (manager.get()) { | ||||
|     // Use the cookie store provided by the manager. May be nullptr if the | ||||
|     // cookie manager is blocking. | ||||
|     return reinterpret_cast<CefCookieManagerImpl*>(manager.get()) | ||||
|         ->GetExistingCookieStore(); | ||||
|   } | ||||
|  | ||||
|   DCHECK(parent_); | ||||
|   if (parent_) { | ||||
|     // Use the cookie store from the parent. | ||||
|     net::CookieStore* cookie_store = parent_->cookie_store(); | ||||
|     DCHECK(cookie_store); | ||||
|     if (!cookie_store) | ||||
|       LOG(ERROR) << "Cookie store does not exist"; | ||||
|     return cookie_store; | ||||
|   } | ||||
|  | ||||
|   return nullptr; | ||||
|   return source_->GetCookieStore(); | ||||
| } | ||||
|   | ||||
| @@ -6,19 +6,15 @@ | ||||
| #define CEF_LIBCEF_BROWSER_COOKIE_STORE_PROXY_H_ | ||||
| #pragma once | ||||
|  | ||||
| #include "include/cef_request_context_handler.h" | ||||
|  | ||||
| #include "net/cookies/cookie_store.h" | ||||
|  | ||||
| class CefURLRequestContextImpl; | ||||
| class CefCookieStoreSource; | ||||
|  | ||||
| // Proxies cookie requests to the CefRequestContextHandler or global cookie | ||||
| // store. Life span is controlled by CefURLRequestContextProxy. Only accessed on | ||||
| // the IO thread. See browser_context.h for an object relationship diagram. | ||||
| // Proxies cookie requests to a CefCookieStoreSource (see comments on the | ||||
| // implementation classes for details). Only accessed on the IO thread. | ||||
| class CefCookieStoreProxy : public net::CookieStore { | ||||
|  public: | ||||
|   CefCookieStoreProxy(CefURLRequestContextImpl* parent, | ||||
|                       CefRefPtr<CefRequestContextHandler> handler); | ||||
|   explicit CefCookieStoreProxy(std::unique_ptr<CefCookieStoreSource> source); | ||||
|   ~CefCookieStoreProxy() override; | ||||
|  | ||||
|   // net::CookieStore methods. | ||||
| @@ -52,11 +48,7 @@ class CefCookieStoreProxy : public net::CookieStore { | ||||
|  private: | ||||
|   net::CookieStore* GetCookieStore(); | ||||
|  | ||||
|   // The |parent_| pointer is kept alive by CefURLRequestContextGetterProxy | ||||
|   // which has a ref to the owning CefURLRequestContextGetterImpl. | ||||
|   CefURLRequestContextImpl* parent_; | ||||
|   CefRefPtr<CefRequestContextHandler> handler_; | ||||
|  | ||||
|   std::unique_ptr<CefCookieStoreSource> const source_; | ||||
|   std::unique_ptr<net::CookieChangeDispatcher> null_dispatcher_; | ||||
|  | ||||
|   DISALLOW_COPY_AND_ASSIGN(CefCookieStoreProxy); | ||||
|   | ||||
							
								
								
									
										110
									
								
								libcef/browser/net/cookie_store_source.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								libcef/browser/net/cookie_store_source.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| // Copyright (c) 2018 The Chromium Embedded Framework Authors. All rights | ||||
| // reserved. Use of this source code is governed by a BSD-style license that can | ||||
| // be found in the LICENSE file. | ||||
|  | ||||
| #include "libcef/browser/net/cookie_store_source.h" | ||||
|  | ||||
| #include "libcef/browser/content_browser_client.h" | ||||
| #include "libcef/browser/cookie_manager_impl.h" | ||||
| #include "libcef/browser/net/url_request_context_impl.h" | ||||
| #include "libcef/browser/thread_util.h" | ||||
|  | ||||
| #include "base/files/file_util.h" | ||||
| #include "base/logging.h" | ||||
| #include "net/extras/sqlite/sqlite_persistent_cookie_store.h" | ||||
|  | ||||
| CefCookieStoreHandlerSource::CefCookieStoreHandlerSource( | ||||
|     CefURLRequestContextImpl* parent, | ||||
|     CefRefPtr<CefRequestContextHandler> handler) | ||||
|     : parent_(parent), handler_(handler) { | ||||
|   DCHECK(parent_); | ||||
|   DCHECK(handler_); | ||||
| } | ||||
|  | ||||
| net::CookieStore* CefCookieStoreHandlerSource::GetCookieStore() { | ||||
|   CEF_REQUIRE_IOT(); | ||||
|  | ||||
|   CefRefPtr<CefCookieManager> manager = handler_->GetCookieManager(); | ||||
|   if (manager) { | ||||
|     // Use the cookie store provided by the manager. May be nullptr if the | ||||
|     // cookie manager is blocking. | ||||
|     return reinterpret_cast<CefCookieManagerImpl*>(manager.get()) | ||||
|         ->GetExistingCookieStore(); | ||||
|   } | ||||
|  | ||||
|   DCHECK(parent_); | ||||
|   if (parent_) { | ||||
|     // Use the cookie store from the parent. | ||||
|     net::CookieStore* cookie_store = parent_->cookie_store(); | ||||
|     DCHECK(cookie_store); | ||||
|     if (!cookie_store) | ||||
|       LOG(ERROR) << "Cookie store does not exist"; | ||||
|     return cookie_store; | ||||
|   } | ||||
|  | ||||
|   return nullptr; | ||||
| } | ||||
|  | ||||
| CefCookieStoreOwnerSource::CefCookieStoreOwnerSource() {} | ||||
|  | ||||
| void CefCookieStoreOwnerSource::SetCookieStoragePath( | ||||
|     const base::FilePath& path, | ||||
|     bool persist_session_cookies) { | ||||
|   CEF_REQUIRE_IOT(); | ||||
|  | ||||
|   if (cookie_store_ && ((path_.empty() && path.empty()) || path_ == path)) { | ||||
|     // The path has not changed so don't do anything. | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   scoped_refptr<net::SQLitePersistentCookieStore> persistent_store; | ||||
|   if (!path.empty()) { | ||||
|     // TODO(cef): Move directory creation to the blocking pool instead of | ||||
|     // allowing file IO on this thread. | ||||
|     base::ThreadRestrictions::ScopedAllowIO allow_io; | ||||
|     if (base::DirectoryExists(path) || base::CreateDirectory(path)) { | ||||
|       const base::FilePath& cookie_path = path.AppendASCII("Cookies"); | ||||
|       persistent_store = new net::SQLitePersistentCookieStore( | ||||
|           cookie_path, | ||||
|           content::BrowserThread::GetTaskRunnerForThread( | ||||
|               content::BrowserThread::IO), | ||||
|           // Intentionally using the background task runner exposed by CEF to | ||||
|           // facilitate unit test expectations. This task runner MUST be | ||||
|           // configured with BLOCK_SHUTDOWN. | ||||
|           CefContentBrowserClient::Get()->background_task_runner(), | ||||
|           persist_session_cookies, NULL); | ||||
|     } else { | ||||
|       NOTREACHED() << "The cookie storage directory could not be created"; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // 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<net::CookieMonster> cookie_monster( | ||||
|       new net::CookieMonster(persistent_store.get(), nullptr)); | ||||
|   if (persistent_store.get() && persist_session_cookies) | ||||
|     cookie_monster->SetPersistSessionCookies(true); | ||||
|   path_ = path; | ||||
|  | ||||
|   // Restore the previously supported schemes. | ||||
|   CefCookieManagerImpl::SetCookieMonsterSchemes(cookie_monster.get(), | ||||
|                                                 supported_schemes_); | ||||
|  | ||||
|   cookie_store_ = std::move(cookie_monster); | ||||
| } | ||||
|  | ||||
| void CefCookieStoreOwnerSource::SetCookieSupportedSchemes( | ||||
|     const std::vector<std::string>& schemes) { | ||||
|   CEF_REQUIRE_IOT(); | ||||
|  | ||||
|   supported_schemes_ = schemes; | ||||
|   CefCookieManagerImpl::SetCookieMonsterSchemes( | ||||
|       static_cast<net::CookieMonster*>(cookie_store_.get()), | ||||
|       supported_schemes_); | ||||
| } | ||||
|  | ||||
| net::CookieStore* CefCookieStoreOwnerSource::GetCookieStore() { | ||||
|   CEF_REQUIRE_IOT(); | ||||
|   return cookie_store_.get(); | ||||
| } | ||||
							
								
								
									
										73
									
								
								libcef/browser/net/cookie_store_source.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								libcef/browser/net/cookie_store_source.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| // Copyright (c) 2018 The Chromium Embedded Framework 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 CEF_LIBCEF_BROWSER_COOKIE_STORE_SOURCE_H_ | ||||
| #define CEF_LIBCEF_BROWSER_COOKIE_STORE_SOURCE_H_ | ||||
| #pragma once | ||||
|  | ||||
| #include <memory> | ||||
| #include <string> | ||||
| #include <vector> | ||||
|  | ||||
| #include "include/cef_request_context_handler.h" | ||||
|  | ||||
| #include "base/macros.h" | ||||
|  | ||||
| namespace base { | ||||
| class FilePath; | ||||
| } | ||||
|  | ||||
| namespace net { | ||||
| class CookieStore; | ||||
| } | ||||
|  | ||||
| class CefURLRequestContextImpl; | ||||
|  | ||||
| // Abstract base class for CookieStore sources. Only accessed on the IO thread. | ||||
| class CefCookieStoreSource { | ||||
|  public: | ||||
|   virtual net::CookieStore* GetCookieStore() = 0; | ||||
|   virtual ~CefCookieStoreSource() {} | ||||
| }; | ||||
|  | ||||
| // Sources a cookie store that is created/owned by a CefCookieManager or the | ||||
| // parent context. Life span is controlled by CefURLRequestContextProxy. See | ||||
| // browser_context.h for an object relationship diagram. | ||||
| class CefCookieStoreHandlerSource : public CefCookieStoreSource { | ||||
|  public: | ||||
|   CefCookieStoreHandlerSource(CefURLRequestContextImpl* parent, | ||||
|                               CefRefPtr<CefRequestContextHandler> handler); | ||||
|  | ||||
|   net::CookieStore* GetCookieStore() override; | ||||
|  | ||||
|  private: | ||||
|   // The |parent_| pointer is kept alive by CefURLRequestContextGetterProxy | ||||
|   // which has a ref to the owning CefURLRequestContextGetterImpl. | ||||
|   CefURLRequestContextImpl* parent_; | ||||
|   CefRefPtr<CefRequestContextHandler> handler_; | ||||
|  | ||||
|   DISALLOW_COPY_AND_ASSIGN(CefCookieStoreHandlerSource); | ||||
| }; | ||||
|  | ||||
| // Sources a cookie store that is created/owned by this object. Life span is | ||||
| // controlled by the owning URLRequestContext. | ||||
| class CefCookieStoreOwnerSource : public CefCookieStoreSource { | ||||
|  public: | ||||
|   CefCookieStoreOwnerSource(); | ||||
|  | ||||
|   void SetCookieStoragePath(const base::FilePath& path, | ||||
|                             bool persist_session_cookies); | ||||
|   void SetCookieSupportedSchemes(const std::vector<std::string>& schemes); | ||||
|  | ||||
|   net::CookieStore* GetCookieStore() override; | ||||
|  | ||||
|  private: | ||||
|   std::unique_ptr<net::CookieStore> cookie_store_; | ||||
|   base::FilePath path_; | ||||
|   std::vector<std::string> supported_schemes_; | ||||
|  | ||||
|   DISALLOW_COPY_AND_ASSIGN(CefCookieStoreOwnerSource); | ||||
| }; | ||||
|  | ||||
| #endif  // CEF_LIBCEF_BROWSER_COOKIE_STORE_SOURCE_H_ | ||||
| @@ -10,6 +10,8 @@ | ||||
|  | ||||
| #include "libcef/browser/content_browser_client.h" | ||||
| #include "libcef/browser/cookie_manager_impl.h" | ||||
| #include "libcef/browser/net/cookie_store_proxy.h" | ||||
| #include "libcef/browser/net/cookie_store_source.h" | ||||
| #include "libcef/browser/net/network_delegate.h" | ||||
| #include "libcef/browser/net/scheme_handler.h" | ||||
| #include "libcef/browser/net/url_request_interceptor.h" | ||||
| @@ -18,7 +20,6 @@ | ||||
| #include "libcef/common/content_client.h" | ||||
|  | ||||
| #include "base/command_line.h" | ||||
| #include "base/files/file_util.h" | ||||
| #include "base/logging.h" | ||||
| #include "base/memory/ptr_util.h" | ||||
| #include "base/stl_util.h" | ||||
| @@ -43,7 +44,6 @@ | ||||
| #include "net/cert/multi_log_ct_verifier.h" | ||||
| #include "net/cookies/cookie_monster.h" | ||||
| #include "net/dns/host_resolver.h" | ||||
| #include "net/extras/sqlite/sqlite_persistent_cookie_store.h" | ||||
| #include "net/ftp/ftp_network_layer.h" | ||||
| #include "net/http/http_auth_handler_factory.h" | ||||
| #include "net/http/http_auth_preferences.h" | ||||
| @@ -473,57 +473,21 @@ void CefURLRequestContextGetterImpl::SetCookieStoragePath( | ||||
|     const base::FilePath& path, | ||||
|     bool persist_session_cookies) { | ||||
|   CEF_REQUIRE_IOT(); | ||||
|  | ||||
|   if (io_state_->url_request_context_->cookie_store() && | ||||
|       ((io_state_->cookie_store_path_.empty() && path.empty()) || | ||||
|        io_state_->cookie_store_path_ == path)) { | ||||
|     // The path has not changed so don't do anything. | ||||
|     return; | ||||
|   if (!io_state_->cookie_source_) { | ||||
|     // Use a proxy because we can't change the URLRequestContext's CookieStore | ||||
|     // during runtime. | ||||
|     io_state_->cookie_source_ = new CefCookieStoreOwnerSource(); | ||||
|     io_state_->storage_->set_cookie_store(std::make_unique<CefCookieStoreProxy>( | ||||
|         base::WrapUnique(io_state_->cookie_source_))); | ||||
|   } | ||||
|  | ||||
|   scoped_refptr<net::SQLitePersistentCookieStore> persistent_store; | ||||
|   if (!path.empty()) { | ||||
|     // TODO(cef): Move directory creation to the blocking pool instead of | ||||
|     // allowing file IO on this thread. | ||||
|     base::ThreadRestrictions::ScopedAllowIO allow_io; | ||||
|     if (base::DirectoryExists(path) || base::CreateDirectory(path)) { | ||||
|       const base::FilePath& cookie_path = path.AppendASCII("Cookies"); | ||||
|       persistent_store = new net::SQLitePersistentCookieStore( | ||||
|           cookie_path, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), | ||||
|           // Intentionally using the background task runner exposed by CEF to | ||||
|           // facilitate unit test expectations. This task runner MUST be | ||||
|           // configured with BLOCK_SHUTDOWN. | ||||
|           CefContentBrowserClient::Get()->background_task_runner(), | ||||
|           persist_session_cookies, NULL); | ||||
|     } else { | ||||
|       NOTREACHED() << "The cookie storage directory could not be created"; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // 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<net::CookieMonster> cookie_monster( | ||||
|       new net::CookieMonster(persistent_store.get(), NULL)); | ||||
|   if (persistent_store.get() && persist_session_cookies) | ||||
|     cookie_monster->SetPersistSessionCookies(true); | ||||
|   io_state_->cookie_store_path_ = path; | ||||
|  | ||||
|   // Restore the previously supported schemes. | ||||
|   CefCookieManagerImpl::SetCookieMonsterSchemes( | ||||
|       cookie_monster.get(), io_state_->cookie_supported_schemes_); | ||||
|  | ||||
|   io_state_->storage_->set_cookie_store(std::move(cookie_monster)); | ||||
|   io_state_->cookie_source_->SetCookieStoragePath(path, | ||||
|                                                   persist_session_cookies); | ||||
| } | ||||
|  | ||||
| void CefURLRequestContextGetterImpl::SetCookieSupportedSchemes( | ||||
|     const std::vector<std::string>& schemes) { | ||||
|   CEF_REQUIRE_IOT(); | ||||
|  | ||||
|   io_state_->cookie_supported_schemes_ = schemes; | ||||
|   CefCookieManagerImpl::SetCookieMonsterSchemes( | ||||
|       static_cast<net::CookieMonster*>(GetExistingCookieStore()), | ||||
|       io_state_->cookie_supported_schemes_); | ||||
|   io_state_->cookie_source_->SetCookieSupportedSchemes(schemes); | ||||
| } | ||||
|  | ||||
| void CefURLRequestContextGetterImpl::AddHandler( | ||||
| @@ -540,9 +504,8 @@ void CefURLRequestContextGetterImpl::AddHandler( | ||||
| net::CookieStore* CefURLRequestContextGetterImpl::GetExistingCookieStore() | ||||
|     const { | ||||
|   CEF_REQUIRE_IOT(); | ||||
|   if (io_state_->url_request_context_ && | ||||
|       io_state_->url_request_context_->cookie_store()) { | ||||
|     return io_state_->url_request_context_->cookie_store(); | ||||
|   if (io_state_->cookie_source_) { | ||||
|     return io_state_->cookie_source_->GetCookieStore(); | ||||
|   } | ||||
|  | ||||
|   LOG(ERROR) << "Cookie store does not exist"; | ||||
|   | ||||
| @@ -22,6 +22,7 @@ | ||||
| #include "content/public/browser/browser_context.h" | ||||
| #include "net/url_request/url_request_job_factory.h" | ||||
|  | ||||
| class CefCookieStoreOwnerSource; | ||||
| class PrefRegistrySimple; | ||||
| class PrefService; | ||||
|  | ||||
| @@ -113,8 +114,8 @@ class CefURLRequestContextGetterImpl : public CefURLRequestContextGetter { | ||||
|     content::ProtocolHandlerMap protocol_handlers_; | ||||
|     content::URLRequestInterceptorScopedVector request_interceptors_; | ||||
|  | ||||
|     base::FilePath cookie_store_path_; | ||||
|     std::vector<std::string> cookie_supported_schemes_; | ||||
|     // Owned by the URLRequestContextStorage. | ||||
|     CefCookieStoreOwnerSource* cookie_source_ = nullptr; | ||||
|  | ||||
|     std::vector<CefRefPtr<CefRequestContextHandler>> handler_list_; | ||||
|  | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include "libcef/browser/net/url_request_context_proxy.h" | ||||
|  | ||||
| #include "libcef/browser/net/cookie_store_proxy.h" | ||||
| #include "libcef/browser/net/cookie_store_source.h" | ||||
| #include "libcef/browser/net/url_request_context_impl.h" | ||||
| #include "libcef/browser/thread_util.h" | ||||
|  | ||||
| @@ -16,7 +17,8 @@ CefURLRequestContextProxy::CefURLRequestContextProxy( | ||||
|   DCHECK(handler.get()); | ||||
|  | ||||
|   // Cookie store that proxies to the browser implementation. | ||||
|   cookie_store_proxy_.reset(new CefCookieStoreProxy(parent, handler)); | ||||
|   cookie_store_proxy_.reset(new CefCookieStoreProxy( | ||||
|       std::make_unique<CefCookieStoreHandlerSource>(parent, handler))); | ||||
|   set_cookie_store(cookie_store_proxy_.get()); | ||||
|  | ||||
|   // All other values refer to the parent request context. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user