Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044).

- CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext.
- Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods.
- Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method.
- CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only).
- The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed.
- When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk.
- Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk.
- Add asynchronous callbacks for all CefCookieManager methods.
- Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath.
- cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2015-03-02 20:25:14 +00:00
parent 031f192e5a
commit ca0e381681
91 changed files with 3816 additions and 1347 deletions

View File

@ -6,30 +6,129 @@
#include <map>
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/thread_util.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/net/proxy_service_factory.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "net/proxy/proxy_config_service.h"
using content::BrowserThread;
CefBrowserContextImpl::CefBrowserContextImpl() {
namespace {
// Manages the global mapping of cache path to Impl instance.
class ImplManager {
public:
ImplManager() {}
~ImplManager() {
DCHECK(map_.empty());
}
CefBrowserContextImpl* GetImpl(const base::FilePath& path) {
CEF_REQUIRE_UIT();
DCHECK(!path.empty());
PathMap::const_iterator it = map_.find(path);
if (it != map_.end())
return it->second;
return NULL;
}
void AddImpl(const base::FilePath& path, CefBrowserContextImpl* impl) {
CEF_REQUIRE_UIT();
DCHECK(!path.empty());
DCHECK(GetImpl(path) == NULL);
map_.insert(std::make_pair(path, impl));
}
void RemoveImpl(const base::FilePath& path) {
CEF_REQUIRE_UIT();
DCHECK(!path.empty());
PathMap::iterator it = map_.find(path);
DCHECK(it != map_.end());
if (it != map_.end())
map_.erase(it);
}
private:
typedef std::map<base::FilePath, CefBrowserContextImpl*> PathMap;
PathMap map_;
DISALLOW_COPY_AND_ASSIGN(ImplManager);
};
base::LazyInstance<ImplManager> g_manager = LAZY_INSTANCE_INITIALIZER;
} // namespace
CefBrowserContextImpl::CefBrowserContextImpl(
const CefRequestContextSettings& settings)
: settings_(settings) {
}
CefBrowserContextImpl::~CefBrowserContextImpl() {
pref_proxy_config_tracker_->DetachFromPrefService();
// Delete the download manager delegate here because otherwise we'll crash
// when it's accessed from the content::BrowserContext destructor.
if (download_manager_delegate_.get())
download_manager_delegate_.reset(NULL);
if (!cache_path_.empty())
g_manager.Get().RemoveImpl(cache_path_);
}
void CefBrowserContextImpl::Initialize() {
cache_path_ = base::FilePath(CefString(&settings_.cache_path));
if (!cache_path_.empty()) {
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (!base::DirectoryExists(cache_path_) &&
!base::CreateDirectory(cache_path_)) {
LOG(ERROR) << "The cache_path directory could not be created: " <<
cache_path_.value();
cache_path_ = base::FilePath();
CefString(&settings_.cache_path).clear();
}
}
if (!cache_path_.empty())
g_manager.Get().AddImpl(cache_path_, this);
if (settings_.accept_language_list.length == 0) {
// Use the global language list setting.
CefString(&settings_.accept_language_list) =
CefString(&CefContext::Get()->settings().accept_language_list);
}
// Initialize proxy configuration tracker.
pref_proxy_config_tracker_.reset(
ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
CefContentBrowserClient::Get()->pref_service()));
// Create the CefURLRequestContextGetterImpl via an indirect call to
// CreateRequestContext. Triggers a call to CefURLRequestContextGetterImpl::
// GetURLRequestContext() on the IO thread which creates the
// CefURLRequestContextImpl.
GetRequestContext();
DCHECK(url_request_getter_.get());
}
// static
scoped_refptr<CefBrowserContextImpl> CefBrowserContextImpl::GetForCachePath(
const base::FilePath& cache_path) {
return g_manager.Get().GetImpl(cache_path);
}
base::FilePath CefBrowserContextImpl::GetPath() const {
return CefContext::Get()->cache_path();
return cache_path_;
}
scoped_ptr<content::ZoomLevelDelegate>
@ -38,7 +137,7 @@ scoped_ptr<content::ZoomLevelDelegate>
}
bool CefBrowserContextImpl::IsOffTheRecord() const {
return false;
return cache_path_.empty();
}
content::DownloadManagerDelegate*
@ -98,14 +197,36 @@ content::SSLHostStateDelegate*
return NULL;
}
bool CefBrowserContextImpl::IsProxy() const {
return false;
}
const CefRequestContextSettings& CefBrowserContextImpl::GetSettings() const {
return settings_;
}
CefRefPtr<CefRequestContextHandler> CefBrowserContextImpl::GetHandler() const {
return NULL;
}
net::URLRequestContextGetter* CefBrowserContextImpl::CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
CEF_REQUIRE_UIT();
DCHECK(!url_request_getter_.get());
// Initialize the proxy configuration service.
scoped_ptr<net::ProxyConfigService> proxy_config_service;
proxy_config_service.reset(
ProxyServiceFactory::CreateProxyConfigService(
pref_proxy_config_tracker_.get()));
url_request_getter_ = new CefURLRequestContextGetterImpl(
settings_,
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
protocol_handlers,
proxy_config_service.Pass(),
request_interceptors.Pass());
resource_context()->set_url_request_context_getter(url_request_getter_.get());
return url_request_getter_.get();