// 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 handler) : parent_(parent), handler_(handler) { DCHECK(parent_); DCHECK(handler_); } net::CookieStore* CefCookieStoreHandlerSource::GetCookieStore() { CEF_REQUIRE_IOT(); CefRefPtr 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(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, net::NetLog* net_log) { 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 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, base::CreateSingleThreadTaskRunnerWithTraits( {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 cookie_monster( new net::CookieMonster(persistent_store.get(), nullptr, net_log)); 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& schemes) { CEF_REQUIRE_IOT(); supported_schemes_ = schemes; CefCookieManagerImpl::SetCookieMonsterSchemes( static_cast(cookie_store_.get()), supported_schemes_); } net::CookieStore* CefCookieStoreOwnerSource::GetCookieStore() { CEF_REQUIRE_IOT(); return cookie_store_.get(); }