Fix issues related to request and context object lifespan (issue #1037, issue #1044).

- Simplify and document the relationship between the various context object types. See browser_context.h for a description of the new relationships.
- cefclient: Add `request-context-per-browser` command-line flag for testing multiple CefRequestContext instances.
- cefclient: Add a CefURLRequest example.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2032 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2015-02-13 23:17:08 +00:00
parent 559ca19bbe
commit 7a2ce64096
66 changed files with 1233 additions and 773 deletions

11
cef.gyp
View File

@ -904,6 +904,7 @@
],
'sources': [
'<@(includes_common)',
'libcef/browser/browser_context.cc',
'libcef/browser/browser_context.h',
'libcef/browser/browser_context_impl.cc',
'libcef/browser/browser_context_impl.h',
@ -937,6 +938,8 @@
'libcef/browser/context_menu_params_impl.h',
'libcef/browser/cookie_manager_impl.cc',
'libcef/browser/cookie_manager_impl.h',
'libcef/browser/cookie_store_proxy.cc',
'libcef/browser/cookie_store_proxy.h',
'libcef/browser/devtools_delegate.cc',
'libcef/browser/devtools_delegate.h',
'libcef/browser/devtools_frontend.cc',
@ -980,6 +983,8 @@
'libcef/browser/proxy_stubs.cc',
'libcef/browser/render_widget_host_view_osr.cc',
'libcef/browser/render_widget_host_view_osr.h',
'libcef/browser/resource_context.cc',
'libcef/browser/resource_context.h',
'libcef/browser/resource_dispatcher_host_delegate.cc',
'libcef/browser/resource_dispatcher_host_delegate.h',
'libcef/browser/resource_request_job.cc',
@ -1006,10 +1011,14 @@
'libcef/browser/thread_util.h',
'libcef/browser/url_network_delegate.cc',
'libcef/browser/url_network_delegate.h',
'libcef/browser/url_request_context_getter.cc',
'libcef/browser/url_request_context.cc',
'libcef/browser/url_request_context.h',
'libcef/browser/url_request_context_getter.h',
'libcef/browser/url_request_context_getter_impl.cc',
'libcef/browser/url_request_context_getter_impl.h',
'libcef/browser/url_request_context_getter_proxy.cc',
'libcef/browser/url_request_context_getter_proxy.h',
'libcef/browser/url_request_context_impl.h',
'libcef/browser/url_request_context_proxy.cc',
'libcef/browser/url_request_context_proxy.h',
'libcef/browser/url_request_interceptor.cc',

View File

@ -174,6 +174,8 @@
'tests/cefclient/browser/temp_window.h',
'tests/cefclient/browser/test_runner.cc',
'tests/cefclient/browser/test_runner.h',
'tests/cefclient/browser/urlrequest_test.cc',
'tests/cefclient/browser/urlrequest_test.h',
'tests/cefclient/browser/window_test.cc',
'tests/cefclient/browser/window_test.h',
],
@ -209,6 +211,7 @@
'tests/cefclient/resources/performance.html',
'tests/cefclient/resources/performance2.html',
'tests/cefclient/resources/transparency.html',
'tests/cefclient/resources/urlrequest.html',
'tests/cefclient/resources/window.html',
'tests/cefclient/resources/xmlhttprequest.html',
],

View File

@ -0,0 +1,52 @@
// Copyright (c) 2015 The Chromium 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/browser_context.h"
#include "libcef/browser/content_browser_client.h"
#include "base/logging.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_thread.h"
#ifndef NDEBUG
base::AtomicRefCount CefBrowserContext::DebugObjCt = 0;
#endif
CefBrowserContext::CefBrowserContext()
: resource_context_(new CefResourceContext) {
BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
this);
// Spell checking support and possibly other subsystems retrieve the
// PrefService associated with a BrowserContext via UserPrefs::Get().
PrefService* pref_service = CefContentBrowserClient::Get()->pref_service();
DCHECK(pref_service);
user_prefs::UserPrefs::Set(this, pref_service);
#ifndef NDEBUG
base::AtomicRefCountInc(&DebugObjCt);
#endif
}
CefBrowserContext::~CefBrowserContext() {
if (resource_context_.get()) {
// Destruction of the ResourceContext will trigger destruction of all
// associated URLRequests.
content::BrowserThread::DeleteSoon(
content::BrowserThread::IO, FROM_HERE, resource_context_.release());
}
// Remove any BrowserContextKeyedServiceFactory associations.
BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
this);
#ifndef NDEBUG
base::AtomicRefCountDec(&DebugObjCt);
#endif
}
content::ResourceContext* CefBrowserContext::GetResourceContext() {
return resource_context_.get();
}

View File

@ -6,11 +6,115 @@
#define CEF_LIBCEF_BROWSER_BROWSER_CONTEXT_H_
#pragma once
#include "libcef/browser/resource_context.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
class CefBrowserContext : public content::BrowserContext {
/*
// Classes used in request processing (network, storage, service, etc.):
//
// WC = WebContents
// Content API representation of a browser. Created by BHI or the system (for
// popups) and owned by BHI. Keeps a pointer to BCI/BCP.
//
// BHI = CefBrowserHostImpl
// Implements the CefBrowser and CefBrowserHost interfaces which are exposed
// to clients. References an RCI instance. Owns a WC. Life span is controlled
// by client references and CefContentBrowserClient.
//
// RCI = CefRequestContextImpl
// Implements the CefRequestContext interface which is exposed to clients.
// References the global BCI or creates a new BCP.
//
// BCI = CefBrowserContextImpl
// Entry point from WC when using the global RCI. Owns the RC and creates the
// URCGI. Life span controlled by RCI and CefBrowserMainParts.
//
// BCP = CefBrowserContextProxy
// Entry point from WC when using a custom RCI. Owns the RC and creates the
// URCGP. Life span controlled by RCI.
//
// RC = CefResourceContext
// Acts as a bridge for resource loading. URLRequest life span is tied to this
// object. Must be destroyed before the associated URCGI/URCGP. Life span is
// controlled by BCI/BCP.
//
// URCGI = CefURLRequestContextGetterImpl
// Creates and owns the URCI. Life span is controlled by RC and
// CefBrowserMainParts.
//
// URCGP = CefURLRequestContextGetterProxy
// Creates and owns the URCP. Life span is controlled by RC.
//
// URCI = CefURLRequestContextImpl
// Owns various network-related objects including the global cookie manager.
// Owns URLRequest objects which must be destroyed first. Life span is
// controlled by URCGI.
//
// URCP = CefURLRequestContextProxy
// Creates the CSP and forwards requests to the objects owned by URCI. Owns
// URLRequest objects which must be destroyed first. Life span is controlled
// by URCGP.
//
// CSP = CefCookieStoreProxy
// Gives the CefCookieManager instance retrieved via CefRequestContextHandler
// an opportunity to handle cookie requests. Otherwise forwards requests via
// URCI to the global cookie manager. Life span is controlled by URCP.
//
//
// Relationship diagram:
// ref = reference (CefRefPtr/scoped_refptr)
// own = ownership (scoped_ptr)
// ptr = raw pointer
//
// CefBrowserMainParts global cookie manager, etc...
// | | ^
// ref ref ref/own
// v v |
// /---> BCI -ref-> URCGI --own-> URCI <-ptr-- CSP
// / ^ ^ ^
// ptr ref ref /
// / | | /
// BHI -own-> WC -ptr-> BCP -ref-> URCGP -own-> URCP --ref-/
//
// BHI -ref-> RCI -ref-> BCI/BCP -own-> RC -ref-> URCGI/URCGP
//
//
// How shutdown works:
// 1. CefBrowserHostImpl is destroyed on any thread due to browser close,
// ref release, etc.
// 2. CefRequestContextImpl is destroyed on any thread due to
// CefBrowserHostImpl destruction, ref release, etc.
// 3. CefBrowserContext* is destroyed on the UI thread due to
// CefRequestContextImpl destruction (*Impl, *Proxy) or ref release in
// CefBrowserMainParts::PostMainMessageLoopRun() (*Impl).
// 4. CefResourceContext is destroyed asynchronously on the IO thread due to
// CefBrowserContext* destruction. This cancels/destroys any pending
// URLRequests.
// 5. CefURLRequestContextGetter* is destroyed asynchronously on the IO thread
// due to CefResourceContext destruction (*Impl, *Proxy) or ref release in
// CefBrowserMainParts::PostMainMessageLoopRun() (*Impl). This may be delayed
// if other network-related objects still have a reference to it.
// 6. CefURLRequestContext* is destroyed on the IO thread due to
// CefURLRequestContextGetter* destruction.
*/
// Main entry point for configuring behavior on a per-browser basis. An instance
// of this class is passed to WebContents::Create in CefBrowserHostImpl::
// CreateInternal. Only accessed on the UI thread.
class CefBrowserContext
: public content::BrowserContext,
public base::RefCountedThreadSafe<
CefBrowserContext, content::BrowserThread::DeleteOnUIThread> {
public:
CefBrowserContext();
// BrowserContext methods.
content::ResourceContext* GetResourceContext() override;
// Called from CefContentBrowserClient to create the URLRequestContextGetter.
virtual net::URLRequestContextGetter* CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) = 0;
@ -19,6 +123,28 @@ class CefBrowserContext : public content::BrowserContext {
bool in_memory,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) = 0;
CefResourceContext* resource_context() const {
return resource_context_.get();
}
#ifndef NDEBUG
// Simple tracking of allocated objects.
static base::AtomicRefCount DebugObjCt; // NOLINT(runtime/int)
#endif
protected:
~CefBrowserContext() override;
private:
// Only allow deletion via scoped_refptr().
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>;
friend class base::DeleteHelper<CefBrowserContext>;
scoped_ptr<CefResourceContext> resource_context_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserContext);
};
#endif // CEF_LIBCEF_BROWSER_BROWSER_CONTEXT_H_

View File

@ -10,47 +10,15 @@
#include "libcef/browser/context.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_getter.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/threading/thread.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/storage_partition.h"
using content::BrowserThread;
class CefBrowserContextImpl::CefResourceContext : public content::ResourceContext {
public:
CefResourceContext() : getter_(NULL) {}
// ResourceContext implementation:
net::HostResolver* GetHostResolver() override {
CHECK(getter_);
return getter_->host_resolver();
}
net::URLRequestContext* GetRequestContext() override {
CHECK(getter_);
return getter_->GetURLRequestContext();
}
void set_url_request_context_getter(CefURLRequestContextGetter* getter) {
getter_ = getter;
}
private:
CefURLRequestContextGetter* getter_;
DISALLOW_COPY_AND_ASSIGN(CefResourceContext);
};
CefBrowserContextImpl::CefBrowserContextImpl()
: resource_context_(new CefResourceContext) {
BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
this);
CefBrowserContextImpl::CefBrowserContextImpl() {
}
CefBrowserContextImpl::~CefBrowserContextImpl() {
@ -58,15 +26,6 @@ CefBrowserContextImpl::~CefBrowserContextImpl() {
// when it's accessed from the content::BrowserContext destructor.
if (download_manager_delegate_.get())
download_manager_delegate_.reset(NULL);
if (resource_context_.get()) {
BrowserThread::DeleteSoon(
BrowserThread::IO, FROM_HERE, resource_context_.release());
}
// Remove any BrowserContextKeyedServiceFactory associations.
BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
this);
}
base::FilePath CefBrowserContextImpl::GetPath() const {
@ -120,10 +79,6 @@ net::URLRequestContextGetter*
return GetRequestContext();
}
content::ResourceContext* CefBrowserContextImpl::GetResourceContext() {
return resource_context_.get();
}
content::BrowserPluginGuestManager* CefBrowserContextImpl::GetGuestManager() {
return NULL;
}
@ -147,12 +102,12 @@ net::URLRequestContextGetter* CefBrowserContextImpl::CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
DCHECK(!url_request_getter_.get());
url_request_getter_ = new CefURLRequestContextGetter(
url_request_getter_ = new CefURLRequestContextGetterImpl(
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
protocol_handlers,
request_interceptors.Pass());
resource_context_->set_url_request_context_getter(url_request_getter_.get());
resource_context()->set_url_request_context_getter(url_request_getter_.get());
return url_request_getter_.get();
}

View File

@ -8,6 +8,8 @@
#include "libcef/browser/browser_context.h"
#include "libcef/browser/url_request_context_getter_impl.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@ -18,12 +20,13 @@ class SpeechRecognitionPreferences;
}
class CefDownloadManagerDelegate;
class CefURLRequestContextGetter;
// Global BrowserContext implementation. Life span is controlled by
// CefRequestContextImpl and CefBrowserMainParts. Only accessed on the UI
// thread. See browser_context.h for an object relationship diagram.
class CefBrowserContextImpl : public CefBrowserContext {
public:
CefBrowserContextImpl();
~CefBrowserContextImpl() override;
// BrowserContext methods.
base::FilePath GetPath() const override;
@ -41,7 +44,6 @@ class CefBrowserContextImpl : public CefBrowserContext {
GetMediaRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory) override;
content::ResourceContext* GetResourceContext() override;
content::BrowserPluginGuestManager* GetGuestManager() override;
storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override;
content::PushMessagingService* GetPushMessagingService() override;
@ -60,11 +62,15 @@ class CefBrowserContextImpl : public CefBrowserContext {
override;
private:
class CefResourceContext;
// Only allow deletion via scoped_refptr().
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>;
friend class base::DeleteHelper<CefBrowserContextImpl>;
~CefBrowserContextImpl() override;
scoped_ptr<CefResourceContext> resource_context_;
scoped_ptr<CefDownloadManagerDelegate> download_manager_delegate_;
scoped_refptr<CefURLRequestContextGetter> url_request_getter_;
scoped_refptr<CefURLRequestContextGetterImpl> url_request_getter_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserContextImpl);
};

View File

@ -7,64 +7,19 @@
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_getter.h"
#include "libcef/browser/url_request_context_getter_proxy.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/threading/thread.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/storage_partition.h"
using content::BrowserThread;
class CefBrowserContextProxy::CefResourceContext :
public content::ResourceContext {
public:
CefResourceContext() : getter_(NULL) {}
// ResourceContext implementation:
net::HostResolver* GetHostResolver() override {
CHECK(getter_);
return getter_->GetHostResolver();
}
net::URLRequestContext* GetRequestContext() override {
CHECK(getter_);
return getter_->GetURLRequestContext();
}
void set_url_request_context_getter(CefURLRequestContextGetterProxy* getter) {
getter_ = getter;
}
private:
CefURLRequestContextGetterProxy* getter_;
DISALLOW_COPY_AND_ASSIGN(CefResourceContext);
};
CefBrowserContextProxy::CefBrowserContextProxy(
CefRefPtr<CefRequestContextHandler> handler,
CefBrowserContext* parent)
: refct_(0),
handler_(handler),
parent_(parent),
resource_context_(new CefResourceContext) {
BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
this);
scoped_refptr<CefBrowserContextImpl> parent)
: handler_(handler),
parent_(parent) {
}
CefBrowserContextProxy::~CefBrowserContextProxy() {
if (resource_context_.get()) {
BrowserThread::DeleteSoon(
BrowserThread::IO, FROM_HERE, resource_context_.release());
}
// Remove any BrowserContextKeyedServiceFactory associations.
BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
this);
}
base::FilePath CefBrowserContextProxy::GetPath() const {
@ -119,10 +74,6 @@ net::URLRequestContextGetter*
return GetRequestContext();
}
content::ResourceContext* CefBrowserContextProxy::GetResourceContext() {
return resource_context_.get();
}
content::BrowserPluginGuestManager* CefBrowserContextProxy::GetGuestManager() {
return parent_->GetGuestManager();
}
@ -148,9 +99,8 @@ net::URLRequestContextGetter* CefBrowserContextProxy::CreateRequestContext(
DCHECK(!url_request_getter_.get());
url_request_getter_ =
new CefURLRequestContextGetterProxy(handler_,
static_cast<CefURLRequestContextGetter*>(
CefContentBrowserClient::Get()->request_context().get()));
resource_context_->set_url_request_context_getter(url_request_getter_.get());
CefContentBrowserClient::Get()->request_context().get());
resource_context()->set_url_request_context_getter(url_request_getter_.get());
return url_request_getter_.get();
}

View File

@ -8,6 +8,7 @@
#include "include/cef_request_context_handler.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_context_impl.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
@ -21,17 +22,13 @@ class SpeechRecognitionPreferences;
class CefDownloadManagerDelegate;
class CefURLRequestContextGetterProxy;
// This class is only accessed on the UI thread.
// BrowserContext implementation for a particular CefRequestContext. Life span
// is controlled by CefRequestContextImpl. Only accessed on the UI thread. See
// browser_context.h for an object relationship diagram.
class CefBrowserContextProxy : public CefBrowserContext {
public:
CefBrowserContextProxy(CefRefPtr<CefRequestContextHandler> handler,
CefBrowserContext* parent);
~CefBrowserContextProxy() override;
// Reference counting and object life span is managed by
// CefContentBrowserClient.
void AddRef() { refct_++; }
bool Release() { return (--refct_ == 0); }
scoped_refptr<CefBrowserContextImpl> parent);
// BrowserContext methods.
base::FilePath GetPath() const override;
@ -49,7 +46,6 @@ class CefBrowserContextProxy : public CefBrowserContext {
GetMediaRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory) override;
content::ResourceContext* GetResourceContext() override;
content::BrowserPluginGuestManager* GetGuestManager() override;
storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override;
content::PushMessagingService* GetPushMessagingService() override;
@ -70,12 +66,15 @@ class CefBrowserContextProxy : public CefBrowserContext {
CefRefPtr<CefRequestContextHandler> handler() const { return handler_; }
private:
class CefResourceContext;
// Only allow deletion via scoped_refptr().
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>;
friend class base::DeleteHelper<CefBrowserContextProxy>;
~CefBrowserContextProxy() override;
int refct_;
CefRefPtr<CefRequestContextHandler> handler_;
CefBrowserContext* parent_;
scoped_ptr<CefResourceContext> resource_context_;
scoped_refptr<CefBrowserContextImpl> parent_;
scoped_ptr<CefDownloadManagerDelegate> download_manager_delegate_;
scoped_refptr<CefURLRequestContextGetterProxy> url_request_getter_;

View File

@ -8,7 +8,7 @@
#include <string>
#include <utility>
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_context_impl.h"
#include "libcef/browser/browser_info.h"
#include "libcef/browser/browser_pref_store.h"
#include "libcef/browser/chrome_scheme_handler.h"
@ -397,7 +397,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::CreateInternal(
DCHECK(opener == kNullWindowHandle || browser_info->is_popup());
if (!web_contents) {
CefBrowserContext* browser_context = NULL;
scoped_refptr<CefBrowserContext> browser_context = NULL;
if (request_context.get()) {
CefRequestContextImpl* request_context_impl =
static_cast<CefRequestContextImpl*>(request_context.get());
@ -408,7 +408,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::CreateInternal(
DCHECK(browser_context);
content::WebContents::CreateParams create_params(
browser_context);
browser_context.get());
CefWebContentsViewOSR* view_or = NULL;
if (window_info.windowless_rendering_enabled) {
@ -756,13 +756,13 @@ void CefBrowserHostImpl::StartDownload(const CefString& url) {
if (!web_contents())
return;
CefBrowserContext* context =
scoped_refptr<CefBrowserContext> context =
static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext());
if (!context)
if (!context.get())
return;
content::DownloadManager* manager =
content::BrowserContext::GetDownloadManager(context);
content::BrowserContext::GetDownloadManager(context.get());
if (!manager)
return;
@ -2759,7 +2759,7 @@ CefBrowserHostImpl::CefBrowserHostImpl(
web_contents_.reset(web_contents);
web_contents->SetDelegate(this);
CefBrowserContext* browser_context =
scoped_refptr<CefBrowserContext> browser_context =
static_cast<CefBrowserContext*>(web_contents->GetBrowserContext());
request_context_ = new CefRequestContextImpl(browser_context);

View File

@ -7,9 +7,11 @@
#include <string>
#include "libcef/browser/browser_context_impl.h"
#include "libcef/browser/browser_context_proxy.h"
#include "libcef/browser/browser_message_loop.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/devtools_delegate.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net_resource_provider.h"
#include "base/bind.h"
@ -17,7 +19,6 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/net/proxy_service_factory.h"
#include "components/user_prefs/user_prefs.h"
#include "content/browser/webui/content_web_ui_controller_factory.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/web_ui_controller_factory.h"
@ -126,8 +127,8 @@ int CefBrowserMainParts::PreCreateThreads() {
}
void CefBrowserMainParts::PreMainMessageLoopRun() {
// Create the global browser context.
global_browser_context_.reset(new CefBrowserContextImpl());
// Create the global BrowserContext.
global_browser_context_ = new CefBrowserContextImpl();
// Initialize the proxy configuration service. This needs to occur before
// CefURLRequestContextGetter::GetURLRequestContext() is called for the
@ -136,9 +137,12 @@ void CefBrowserMainParts::PreMainMessageLoopRun() {
ProxyServiceFactory::CreateProxyConfigService(
pref_proxy_config_tracker_.get()));
// Initialize the request context getter. This indirectly triggers a call
// to CefURLRequestContextGetter::GetURLRequestContext() on the IO thread.
global_request_context_ = global_browser_context_->GetRequestContext();
// Create the global URLRequestContextGetter via an indirect call to
// CefBrowserContextImpl::CreateRequestContext. Triggers a call to
// CefURLRequestContextGetter::GetURLRequestContext() on the IO thread which
// creates the URLRequestContext.
global_request_context_ = static_cast<CefURLRequestContextGetterImpl*>(
global_browser_context_->GetRequestContext());
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
@ -153,10 +157,6 @@ void CefBrowserMainParts::PreMainMessageLoopRun() {
LOG(WARNING) << "Invalid http debugger port number " << port;
}
}
// Spell checking support and possibly other subsystems retrieve the
// PrefService associated with a BrowserContext via UserPrefs::Get().
user_prefs::UserPrefs::Set(browser_context(), pref_service());
}
void CefBrowserMainParts::PostMainMessageLoopRun() {
@ -166,12 +166,13 @@ void CefBrowserMainParts::PostMainMessageLoopRun() {
}
pref_proxy_config_tracker_->DetachFromPrefService();
// Only the global browser context should still exist.
DCHECK(browser_contexts_.empty());
browser_contexts_.clear();
global_request_context_ = NULL;
global_browser_context_.reset();
global_browser_context_ = NULL;
#ifndef NDEBUG
// No CefBrowserContext instances should exist at this point.
DCHECK_EQ(0, CefBrowserContext::DebugObjCt);
#endif
}
void CefBrowserMainParts::PostDestroyThreads() {
@ -182,25 +183,10 @@ void CefBrowserMainParts::PostDestroyThreads() {
delete views::ViewsDelegate::views_delegate;
#endif
#ifndef NDEBUG
// No CefURLRequestContext instances should exist at this point.
DCHECK_EQ(0, CefURLRequestContext::DebugObjCt);
#endif
PlatformCleanup();
}
void CefBrowserMainParts::AddBrowserContext(CefBrowserContext* context) {
// Spell checking support and possibly other subsystems retrieve the
// PrefService associated with a BrowserContext via UserPrefs::Get().
user_prefs::UserPrefs::Set(context, pref_service());
browser_contexts_.push_back(context);
}
void CefBrowserMainParts::RemoveBrowserContext(CefBrowserContext* context) {
ScopedVector<CefBrowserContext>::iterator it = browser_contexts_.begin();
for (; it != browser_contexts_.end(); ++it) {
if (*it == context) {
browser_contexts_.erase(it);
return;
}
}
NOTREACHED();
}

View File

@ -7,6 +7,8 @@
#pragma once
#include "libcef/browser/browser_pref_store.h"
#include "libcef/browser/browser_context_impl.h"
#include "libcef/browser/url_request_context_getter_impl.h"
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
@ -27,7 +29,6 @@ namespace content {
struct MainFunctionParams;
}
class CefBrowserContext;
class CefDevToolsDelegate;
class CefBrowserMainParts : public content::BrowserMainParts {
@ -44,10 +45,10 @@ class CefBrowserMainParts : public content::BrowserMainParts {
void PostMainMessageLoopRun() override;
void PostDestroyThreads() override;
CefBrowserContext* browser_context() const {
return global_browser_context_.get();
scoped_refptr<CefBrowserContextImpl> browser_context() const {
return global_browser_context_;
}
scoped_refptr<net::URLRequestContextGetter> request_context() const {
scoped_refptr<CefURLRequestContextGetterImpl> request_context() const {
return global_request_context_;
}
CefDevToolsDelegate* devtools_delegate() const {
@ -58,16 +59,12 @@ class CefBrowserMainParts : public content::BrowserMainParts {
return proxy_config_service_.Pass();
}
void AddBrowserContext(CefBrowserContext* context);
void RemoveBrowserContext(CefBrowserContext* context);
private:
void PlatformInitialize();
void PlatformCleanup();
scoped_ptr<CefBrowserContext> global_browser_context_;
scoped_refptr<net::URLRequestContextGetter> global_request_context_;
ScopedVector<CefBrowserContext> browser_contexts_;
scoped_refptr<CefBrowserContextImpl> global_browser_context_;
scoped_refptr<CefURLRequestContextGetterImpl> global_request_context_;
CefDevToolsDelegate* devtools_delegate_; // Deletes itself.
scoped_ptr<base::MessageLoop> message_loop_;
scoped_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;

View File

@ -6,8 +6,6 @@
#include <algorithm>
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_context_proxy.h"
#include "libcef/browser/browser_info.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/browser_main.h"
@ -558,39 +556,6 @@ scoped_refptr<CefBrowserInfo> CefContentBrowserClient::GetBrowserInfoForFrame(
return scoped_refptr<CefBrowserInfo>();
}
CefBrowserContext* CefContentBrowserClient::CreateBrowserContextProxy(
CefRefPtr<CefRequestContextHandler> handler) {
CEF_REQUIRE_UIT();
CefBrowserContextProxy* context =
new CefBrowserContextProxy(handler, browser_context());
browser_main_parts_->AddBrowserContext(context);
context->AddRef();
return context;
}
void CefContentBrowserClient::AddBrowserContextReference(
CefBrowserContext* context) {
CEF_REQUIRE_UIT();
// Skip the global browser context.
if (context == browser_context())
return;
CefBrowserContextProxy* proxy = static_cast<CefBrowserContextProxy*>(context);
proxy->AddRef();
}
void CefContentBrowserClient::RemoveBrowserContextReference(
CefBrowserContext* context) {
CEF_REQUIRE_UIT();
// Skip the global browser context.
if (context == browser_context())
return;
CefBrowserContextProxy* proxy = static_cast<CefBrowserContextProxy*>(context);
if (proxy->Release())
browser_main_parts_->RemoveBrowserContext(proxy);
}
content::BrowserMainParts* CefContentBrowserClient::CreateBrowserMainParts(
const content::MainFunctionParams& parameters) {
browser_main_parts_ = new CefBrowserMainParts(parameters);
@ -612,18 +577,15 @@ void CefContentBrowserClient::RenderProcessWillLaunch(
host->AddFilter(new SpellCheckMessageFilterMac(id));
#endif
}
AddBrowserContextReference(
static_cast<CefBrowserContext*>(host->GetBrowserContext()));
}
net::URLRequestContextGetter* CefContentBrowserClient::CreateRequestContext(
content::BrowserContext* content_browser_context,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
CefBrowserContext* cef_browser_context =
scoped_refptr<CefBrowserContext> context =
static_cast<CefBrowserContext*>(content_browser_context);
return cef_browser_context->CreateRequestContext(
return context->CreateRequestContext(
protocol_handlers,
request_interceptors.Pass());
}
@ -635,9 +597,9 @@ CefContentBrowserClient::CreateRequestContextForStoragePartition(
bool in_memory,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
CefBrowserContext* cef_browser_context =
scoped_refptr<CefBrowserContext> context =
static_cast<CefBrowserContext*>(content_browser_context);
return cef_browser_context->CreateRequestContextForStoragePartition(
return context->CreateRequestContextForStoragePartition(
partition_path,
in_memory,
protocol_handlers,
@ -1024,7 +986,7 @@ std::string CefContentBrowserClient::GetDefaultDownloadName() {
content::DevToolsManagerDelegate*
CefContentBrowserClient::GetDevToolsManagerDelegate() {
return new CefDevToolsManagerDelegate(browser_context());
return new CefDevToolsManagerDelegate(browser_context().get());
}
#if defined(OS_POSIX) && !defined(OS_MACOSX)
@ -1074,11 +1036,12 @@ void CefContentBrowserClient::set_last_create_window_params(
last_create_window_params_ = params;
}
CefBrowserContext* CefContentBrowserClient::browser_context() const {
scoped_refptr<CefBrowserContextImpl>
CefContentBrowserClient::browser_context() const {
return browser_main_parts_->browser_context();
}
scoped_refptr<net::URLRequestContextGetter>
scoped_refptr<CefURLRequestContextGetterImpl>
CefContentBrowserClient::request_context() const {
return browser_main_parts_->request_context();
}

View File

@ -13,6 +13,8 @@
#include <utility>
#include "include/cef_request_context_handler.h"
#include "libcef/browser/browser_context_impl.h"
#include "libcef/browser/url_request_context_getter_impl.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
@ -20,10 +22,8 @@
#include "base/synchronization/lock.h"
#include "content/public/browser/content_browser_client.h"
#include "net/proxy/proxy_config_service.h"
#include "net/url_request/url_request_context_getter.h"
#include "url/gurl.h"
class CefBrowserContext;
class CefBrowserInfo;
class CefBrowserMainParts;
class CefDevToolsDelegate;
@ -68,16 +68,6 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
scoped_refptr<CefBrowserInfo> GetBrowserInfoForFrame(int render_process_id,
int render_routing_id);
// Create and return a new CefBrowserContextProxy object.
CefBrowserContext* CreateBrowserContextProxy(
CefRefPtr<CefRequestContextHandler> handler);
// BrowserContexts are nominally owned by RenderViewHosts and
// CefRequestContextImpls. Keep track of how many objects reference a given
// context and delete the context when the reference count reaches zero.
void AddBrowserContextReference(CefBrowserContext* context);
void RemoveBrowserContextReference(CefBrowserContext* context);
// ContentBrowserClient implementation.
content::BrowserMainParts* CreateBrowserMainParts(
const content::MainFunctionParams& parameters) override;
@ -177,8 +167,8 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
};
void set_last_create_window_params(const LastCreateWindowParams& params);
CefBrowserContext* browser_context() const;
scoped_refptr<net::URLRequestContextGetter> request_context() const;
scoped_refptr<CefBrowserContextImpl> browser_context() const;
scoped_refptr<CefURLRequestContextGetterImpl> request_context() const;
CefDevToolsDelegate* devtools_delegate() const;
PrefService* pref_service() const;

View File

@ -352,13 +352,6 @@ void CefContext::OnContextInitialized() {
// Register internal scheme handlers.
scheme::RegisterInternalHandlers();
// Register for notifications.
registrar_.reset(new content::NotificationRegistrar());
registrar_->Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
content::NotificationService::AllBrowserContextsAndSources());
registrar_->Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
content::NotificationService::AllBrowserContextsAndSources());
// Must be created after the NotificationService.
print_job_manager_.reset(new printing::PrintJobManager());
@ -384,8 +377,6 @@ void CefContext::FinishShutdownOnUIThread(
CefContentBrowserClient::Get()->DestroyAllBrowsers();
registrar_.reset();
if (trace_subscriber_.get())
trace_subscriber_.reset(NULL);
@ -408,16 +399,3 @@ void CefContext::FinalizeShutdown() {
main_runner_.reset(NULL);
main_delegate_.reset(NULL);
}
void CefContext::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_TERMINATED ||
type == content::NOTIFICATION_RENDERER_PROCESS_CLOSED);
content::RenderProcessHost* rph =
content::Source<content::RenderProcessHost>(source).ptr();
DCHECK(rph);
CefContentBrowserClient::Get()->RemoveBrowserContextReference(
static_cast<CefBrowserContext*>(rph->GetBrowserContext()));
}

View File

@ -16,8 +16,6 @@
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/platform_thread.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
namespace base {
class WaitableEvent;
@ -35,12 +33,12 @@ class CefBrowserHostImpl;
class CefMainDelegate;
class CefTraceSubscriber;
class CefContext : public content::NotificationObserver {
class CefContext {
public:
typedef std::list<CefRefPtr<CefBrowserHostImpl> > BrowserList;
CefContext();
~CefContext() override;
~CefContext();
// Returns the singleton CefContext instance.
static CefContext* Get();
@ -82,11 +80,6 @@ class CefContext : public content::NotificationObserver {
// Destroys the main runner and related objects.
void FinalizeShutdown();
// NotificationObserver implementation.
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
// Track context state.
bool initialized_;
bool shutting_down_;
@ -103,7 +96,6 @@ class CefContext : public content::NotificationObserver {
scoped_ptr<CefTraceSubscriber> trace_subscriber_;
// Only accessed on the UI Thread.
scoped_ptr<content::NotificationRegistrar> registrar_;
scoped_ptr<printing::PrintJobManager> print_job_manager_;
};

View File

@ -117,9 +117,8 @@ void CefCookieManagerImpl::SetSupportedSchemes(
if (is_global_) {
// Global changes are handled by the request context.
scoped_refptr<CefURLRequestContextGetter> getter =
static_cast<CefURLRequestContextGetter*>(
CefContentBrowserClient::Get()->request_context().get());
scoped_refptr<CefURLRequestContextGetterImpl> getter =
CefContentBrowserClient::Get()->request_context();
std::vector<std::string> scheme_vec;
std::vector<CefString>::const_iterator it = schemes.begin();
@ -274,9 +273,8 @@ bool CefCookieManagerImpl::SetStoragePath(
if (is_global_) {
// Global path changes are handled by the request context.
scoped_refptr<CefURLRequestContextGetter> getter =
static_cast<CefURLRequestContextGetter*>(
CefContentBrowserClient::Get()->request_context().get());
scoped_refptr<CefURLRequestContextGetterImpl> getter =
CefContentBrowserClient::Get()->request_context();
getter->SetCookieStoragePath(new_path, persist_session_cookies);
cookie_monster_ = getter->GetURLRequestContext()->cookie_store()->
GetCookieMonster();
@ -359,9 +357,11 @@ bool CefCookieManagerImpl::FlushStore(
void CefCookieManagerImpl::SetGlobal() {
if (CEF_CURRENTLY_ON_IOT()) {
if (CefContentBrowserClient::Get()->request_context().get()) {
cookie_monster_ = CefContentBrowserClient::Get()->request_context()->
GetURLRequestContext()->cookie_store()->GetCookieMonster();
scoped_refptr<CefURLRequestContextGetterImpl> getter =
CefContentBrowserClient::Get()->request_context();
if (getter.get()) {
cookie_monster_ =
getter->GetURLRequestContext()->cookie_store()->GetCookieMonster();
DCHECK(cookie_monster_.get());
}
} else {

View File

@ -0,0 +1,139 @@
// Copyright (c) 2015 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/cookie_store_proxy.h"
#include "libcef/browser/cookie_manager_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_impl.h"
#include "base/logging.h"
#include "net/url_request/url_request_context.h"
CefCookieStoreProxy::CefCookieStoreProxy(
CefURLRequestContextImpl* parent,
CefRefPtr<CefRequestContextHandler> handler)
: parent_(parent),
handler_(handler) {
CEF_REQUIRE_IOT();
}
CefCookieStoreProxy::~CefCookieStoreProxy() {
CEF_REQUIRE_IOT();
}
void CefCookieStoreProxy::Detach() {
CEF_REQUIRE_IOT();
parent_ = NULL;
}
void CefCookieStoreProxy::SetCookieWithOptionsAsync(
const GURL& url,
const std::string& cookie_line,
const net::CookieOptions& options,
const SetCookiesCallback& callback) {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
if (cookie_store.get()) {
cookie_store->SetCookieWithOptionsAsync(url, cookie_line, options,
callback);
}
}
void CefCookieStoreProxy::GetCookiesWithOptionsAsync(
const GURL& url, const net::CookieOptions& options,
const GetCookiesCallback& callback) {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
if (cookie_store.get())
cookie_store->GetCookiesWithOptionsAsync(url, options, callback);
}
void CefCookieStoreProxy::DeleteCookieAsync(
const GURL& url,
const std::string& cookie_name,
const base::Closure& callback) {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
if (cookie_store.get())
cookie_store->DeleteCookieAsync(url, cookie_name, callback);
}
void CefCookieStoreProxy::GetAllCookiesForURLAsync(
const GURL& url,
const GetCookieListCallback& callback) {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
if (cookie_store.get())
cookie_store->GetAllCookiesForURLAsync(url, callback);
}
void CefCookieStoreProxy::DeleteAllCreatedBetweenAsync(
const base::Time& delete_begin,
const base::Time& delete_end,
const DeleteCallback& callback) {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
if (cookie_store.get()) {
cookie_store->DeleteAllCreatedBetweenAsync(delete_begin, delete_end,
callback);
}
}
void CefCookieStoreProxy::DeleteAllCreatedBetweenForHostAsync(
const base::Time delete_begin,
const base::Time delete_end,
const GURL& url,
const DeleteCallback& callback) {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
if (cookie_store.get()) {
cookie_store->DeleteAllCreatedBetweenForHostAsync(delete_begin, delete_end,
url, callback);
}
}
void CefCookieStoreProxy::DeleteSessionCookiesAsync(
const DeleteCallback& callback) {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
if (cookie_store.get())
cookie_store->DeleteSessionCookiesAsync(callback);
}
net::CookieMonster* CefCookieStoreProxy::GetCookieMonster() {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
if (cookie_store.get())
return cookie_store->GetCookieMonster();
return NULL;
}
scoped_ptr<net::CookieStore::CookieChangedSubscription>
CefCookieStoreProxy::AddCallbackForCookie(
const GURL& url,
const std::string& name,
const CookieChangedCallback& callback) {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
if (cookie_store.get())
return cookie_store->AddCallbackForCookie(url, name, callback);
return NULL;
}
net::CookieStore* CefCookieStoreProxy::GetCookieStore() {
CEF_REQUIRE_IOT();
scoped_refptr<net::CookieStore> cookie_store;
if (handler_.get()) {
// Get the manager from the handler.
CefRefPtr<CefCookieManager> manager = handler_->GetCookieManager();
if (manager.get()) {
cookie_store = reinterpret_cast<CefCookieManagerImpl*>(manager.get())->
cookie_monster();
DCHECK(cookie_store.get());
return cookie_store.get();
}
}
DCHECK(parent_);
if (parent_) {
// Use the global cookie store.
cookie_store = parent_->cookie_store();
DCHECK(cookie_store.get());
}
return cookie_store.get();
}

View File

@ -0,0 +1,69 @@
// Copyright (c) 2015 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_PROXY_H_
#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;
// 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.
class CefCookieStoreProxy : public net::CookieStore {
public:
CefCookieStoreProxy(CefURLRequestContextImpl* parent,
CefRefPtr<CefRequestContextHandler> handler);
~CefCookieStoreProxy() override;
// The |parent_| object may no longer be valid after this method is called.
void Detach();
// net::CookieStore methods.
void SetCookieWithOptionsAsync(
const GURL& url,
const std::string& cookie_line,
const net::CookieOptions& options,
const SetCookiesCallback& callback) override;
void GetCookiesWithOptionsAsync(
const GURL& url, const net::CookieOptions& options,
const GetCookiesCallback& callback) override;
void DeleteCookieAsync(const GURL& url,
const std::string& cookie_name,
const base::Closure& callback) override;
void GetAllCookiesForURLAsync(
const GURL& url,
const GetCookieListCallback& callback) override;
void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin,
const base::Time& delete_end,
const DeleteCallback& callback) override;
void DeleteAllCreatedBetweenForHostAsync(
const base::Time delete_begin,
const base::Time delete_end,
const GURL& url,
const DeleteCallback& callback) override;
void DeleteSessionCookiesAsync(const DeleteCallback& callback) override;
net::CookieMonster* GetCookieMonster() override;
scoped_ptr<CookieChangedSubscription> AddCallbackForCookie(
const GURL& url,
const std::string& name,
const CookieChangedCallback& callback) override;
private:
net::CookieStore* GetCookieStore();
// The |parent_| pointer is kept alive by CefURLRequestContextGetterProxy
// which has a ref to the owning CefURLRequestContextGetterImpl. Detach() will
// be called when the CefURLRequestContextGetterProxy is destroyed.
CefURLRequestContextImpl* parent_;
CefRefPtr<CefRequestContextHandler> handler_;
DISALLOW_COPY_AND_ASSIGN(CefCookieStoreProxy);
};
#endif // CEF_LIBCEF_BROWSER_COOKIE_STORE_PROXY_H_

View File

@ -3,6 +3,7 @@
// can be found in the LICENSE file.
#include "libcef/browser/request_context_impl.h"
#include "libcef/browser/browser_context_impl.h"
#include "libcef/browser/browser_context_proxy.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
@ -12,11 +13,6 @@
namespace {
void RemoveContextRef(CefBrowserContext* browser_context) {
CefContentBrowserClient::Get()->RemoveBrowserContextReference(
browser_context);
}
base::StaticAtomicSequenceNumber g_next_id;
} // namespace
@ -31,7 +27,7 @@ CefRefPtr<CefRequestContext> CefRequestContext::GetGlobalContext() {
}
return new CefRequestContextImpl(
CefContentBrowserClient::Get()->browser_context());
CefContentBrowserClient::Get()->browser_context().get());
}
CefRefPtr<CefRequestContext> CefRequestContext::CreateContext(
@ -48,40 +44,33 @@ CefRefPtr<CefRequestContext> CefRequestContext::CreateContext(
// CefBrowserContextImpl
CefRequestContextImpl::CefRequestContextImpl(
CefBrowserContext* browser_context)
scoped_refptr<CefBrowserContext> browser_context)
: browser_context_(browser_context),
unique_id_(0) {
DCHECK(browser_context);
DCHECK(browser_context.get());
if (!IsGlobal()) {
CEF_REQUIRE_UIT();
CefBrowserContextProxy* proxy =
static_cast<CefBrowserContextProxy*>(browser_context);
scoped_refptr<CefBrowserContextProxy> proxy =
static_cast<CefBrowserContextProxy*>(browser_context.get());
handler_ = proxy->handler();
CefContentBrowserClient::Get()->AddBrowserContextReference(browser_context);
}
}
CefRequestContextImpl::CefRequestContextImpl(
CefRefPtr<CefRequestContextHandler> handler)
: browser_context_(NULL),
handler_(handler),
: handler_(handler),
unique_id_(g_next_id.GetNext()) {
}
CefRequestContextImpl::~CefRequestContextImpl() {
if (browser_context_) {
if (CEF_CURRENTLY_ON_UIT())
RemoveContextRef(browser_context_);
else
CEF_POST_TASK(CEF_UIT, base::Bind(RemoveContextRef, browser_context_));
}
}
CefBrowserContext* CefRequestContextImpl::GetOrCreateBrowserContext() {
scoped_refptr<CefBrowserContext>
CefRequestContextImpl::GetOrCreateBrowserContext() {
CEF_REQUIRE_UIT();
if (!browser_context_) {
browser_context_ =
CefContentBrowserClient::Get()->CreateBrowserContextProxy(handler_);
browser_context_ = new CefBrowserContextProxy(
handler_, CefContentBrowserClient::Get()->browser_context());
}
return browser_context_;
}

View File

@ -7,23 +7,23 @@
#pragma once
#include "include/cef_request_context.h"
class CefBrowserContext;
#include "libcef/browser/browser_context.h"
class CefRequestContextImpl : public CefRequestContext {
public:
explicit CefRequestContextImpl(CefBrowserContext* browser_context);
explicit CefRequestContextImpl(
scoped_refptr<CefBrowserContext> browser_context);
explicit CefRequestContextImpl(CefRefPtr<CefRequestContextHandler> handler);
~CefRequestContextImpl() override;
CefBrowserContext* GetOrCreateBrowserContext();
scoped_refptr<CefBrowserContext> GetOrCreateBrowserContext();
bool IsSame(CefRefPtr<CefRequestContext> other) override;
bool IsGlobal() override;
CefRefPtr<CefRequestContextHandler> GetHandler() override;
protected:
CefBrowserContext* browser_context_;
scoped_refptr<CefBrowserContext> browser_context_;
CefRefPtr<CefRequestContextHandler> handler_;
// Used to uniquely identify CefRequestContext objects before an associated

View File

@ -0,0 +1,42 @@
// Copyright (c) 2015 The Chromium 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/resource_context.h"
#include "libcef/browser/url_request_context_getter.h"
#include "base/logging.h"
#include "content/public/browser/browser_thread.h"
CefResourceContext::CefResourceContext() {
}
CefResourceContext::~CefResourceContext() {
if (getter_.get()) {
// When the parent object (ResourceContext) destructor executes all
// associated URLRequests should be destroyed. If there are no other
// references it should then be safe to destroy the URLRequestContextGetter
// which owns the URLRequestContext.
getter_->AddRef();
CefURLRequestContextGetter* raw_getter = getter_.get();
getter_ = NULL;
content::BrowserThread::ReleaseSoon(
content::BrowserThread::IO, FROM_HERE, raw_getter);
}
}
net::HostResolver* CefResourceContext::GetHostResolver() {
CHECK(getter_.get());
return getter_->GetHostResolver();
}
net::URLRequestContext* CefResourceContext::GetRequestContext() {
CHECK(getter_.get());
return getter_->GetURLRequestContext();
}
void CefResourceContext::set_url_request_context_getter(
scoped_refptr<CefURLRequestContextGetter> getter) {
DCHECK(!getter_.get());
getter_ = getter;
}

View File

@ -0,0 +1,39 @@
// Copyright (c) 2015 The Chromium 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_RESOURCE_CONTEXT_H_
#define CEF_LIBCEF_BROWSER_RESOURCE_CONTEXT_H_
#pragma once
#include "content/public/browser/resource_context.h"
class CefURLRequestContextGetter;
// Acts as a bridge for resource loading. Life span is controlled by
// CefBrowserContext. Created on the UI thread but accessed and destroyed on the
// IO thread. URLRequest objects are associated with the ResourceContext via
// ResourceDispatcherHost. When the ResourceContext is destroyed all outstanding
// URLRequest objects will be deleted via the ResourceLoader that owns them and
// removed from the associated URLRequestContext. Other URLRequest objects may
// be created via URLFetcher that are not associated with a RequestContext.
// See browser_context.h for an object relationship diagram.
class CefResourceContext : public content::ResourceContext {
public:
CefResourceContext();
~CefResourceContext() override;
// ResourceContext implementation.
net::HostResolver* GetHostResolver() override;
net::URLRequestContext* GetRequestContext() override;
void set_url_request_context_getter(
scoped_refptr<CefURLRequestContextGetter> getter);
private:
scoped_refptr<CefURLRequestContextGetter> getter_;
DISALLOW_COPY_AND_ASSIGN(CefResourceContext);
};
#endif // CEF_LIBCEF_BROWSER_RESOURCE_CONTEXT_H_

View File

@ -196,9 +196,8 @@ class CefUrlRequestManager {
private:
net::URLRequestJobFactoryImpl* GetJobFactoryImpl() {
return static_cast<CefURLRequestContextGetter*>(
CefContentBrowserClient::Get()->request_context().get())->
job_factory_impl();
return CefContentBrowserClient::Get()->request_context()->
job_factory_impl();
}
// Add or remove the protocol handler if necessary. |scheme| will already be

View File

@ -0,0 +1,21 @@
// Copyright (c) 2015 The Chromium 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/url_request_context.h"
#ifndef NDEBUG
base::AtomicRefCount CefURLRequestContext::DebugObjCt = 0;
#endif
CefURLRequestContext::CefURLRequestContext() {
#ifndef NDEBUG
base::AtomicRefCountInc(&DebugObjCt);
#endif
}
CefURLRequestContext::~CefURLRequestContext() {
#ifndef NDEBUG
base::AtomicRefCountDec(&DebugObjCt);
#endif
}

View File

@ -0,0 +1,30 @@
// Copyright (c) 2015 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_URL_REQUEST_CONTEXT_H_
#define CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_H_
#pragma once
#include "net/url_request/url_request_context.h"
// Owns URLRequest instances and provides access to network-related
// functionality. Life span is controlled by CefURLRequestContextGetter*. Only
// accessed on the IO thread. URLRequest objects are created via ResourceContext
// and URLFetcher. All URLRequest objects must be destroyed before this object
// is destroyed. See browser_context.h for an object relationship diagram.
class CefURLRequestContext : public net::URLRequestContext {
public:
CefURLRequestContext();
~CefURLRequestContext() override;
#ifndef NDEBUG
// Simple tracking of allocated objects.
static base::AtomicRefCount DebugObjCt; // NOLINT(runtime/int)
#endif
private:
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContext);
};
#endif // CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_H_

View File

@ -1,4 +1,4 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@ -6,125 +6,24 @@
#define CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_
#pragma once
#include <set>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/content_browser_client.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_job_factory.h"
namespace base {
class MessageLoop;
}
namespace net {
class FtpTransactionFactory;
class HostResolver;
class ProxyConfigService;
class URLRequestContextStorage;
class URLRequestJobFactory;
class URLRequestJobFactoryImpl;
class URLSecurityManager;
}
class CefURLRequestContextProxy;
/*
// Classes used in network request processing:
//
// RC = net::URLRequestContext
// Owns various network-related objects including the global cookie manager.
//
// RCP = CefURLRequestContextProxy
// Creates the CSP and forwards requests to the objects owned by RC.
//
// CSP = CefCookieStoreProxy
// Gives the CefCookieManager associated with CefBrowserHostImpl an
// opportunity to handle cookie requests. Otherwise forwards requests via RC
// to the global cookie manager.
//
// RCG = CefURLRequestContextGetter
// Creates the RC and manages RCP lifespan.
//
// RCGP = CefURLRequestContextGetterProxy
// Causes the RCG to create and destroy browser-specific RCPs.
//
// Relationship diagram:
// ref = reference (scoped_refptr)
// own = ownership (scoped_ptr)
// ptr = raw pointer
//
// global cookie manager, etc...
// ^
// |
// /-own-> RC <-ptr-\
// / \
// / /<-ptr-\ \
// / / \ \
// CefBrowserContext -ref-> RCG --own-> RCP --ref-> CSP
// ^ ^ /
// ref ptr /
// | / /
// CefBrowserHostImpl -ref-> RCGP----/ /
// ^ /
// \-ref--------------------------/
*/
// Responsible for creating and owning the URLRequestContext and all network-
// related functionality. Life span is primarily controlled by
// CefResourceContext*. See browser_context.h for an object relationship
// diagram.
class CefURLRequestContextGetter : public net::URLRequestContextGetter {
public:
CefURLRequestContextGetter(
base::MessageLoop* io_loop,
base::MessageLoop* file_loop,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors);
~CefURLRequestContextGetter() override;
CefURLRequestContextGetter() {}
// net::URLRequestContextGetter implementation.
net::URLRequestContext* GetURLRequestContext() override;
scoped_refptr<base::SingleThreadTaskRunner>
GetNetworkTaskRunner() const override;
net::HostResolver* host_resolver();
net::URLRequestJobFactoryImpl* job_factory_impl() const {
return job_factory_impl_;
}
void SetCookieStoragePath(const base::FilePath& path,
bool persist_session_cookies);
void SetCookieSupportedSchemes(const std::vector<std::string>& schemes);
// Manage URLRequestContext proxy objects. It's important that proxy objects
// not be destroyed while any in-flight URLRequests exist. These methods
// manage that requirement.
CefURLRequestContextProxy* CreateURLRequestContextProxy();
void ReleaseURLRequestContextProxy(CefURLRequestContextProxy* proxy);
// Called from CefResourceContext::GetHostResolver().
virtual net::HostResolver* GetHostResolver() const = 0;
private:
void CreateProxyConfigService();
base::MessageLoop* io_loop_;
base::MessageLoop* file_loop_;
scoped_ptr<net::ProxyConfigService> proxy_config_service_;
scoped_ptr<net::URLRequestContextStorage> storage_;
scoped_ptr<net::URLRequestContext> url_request_context_;
scoped_ptr<net::URLSecurityManager> url_security_manager_;
scoped_ptr<net::FtpTransactionFactory> ftp_transaction_factory_;
content::ProtocolHandlerMap protocol_handlers_;
content::URLRequestInterceptorScopedVector request_interceptors_;
net::URLRequestJobFactoryImpl* job_factory_impl_;
typedef std::set<CefURLRequestContextProxy*> RequestContextProxySet;
RequestContextProxySet url_request_context_proxies_;
base::FilePath cookie_store_path_;
std::vector<std::string> cookie_supported_schemes_;
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextGetter);
};

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/url_request_context_getter.h"
#include "libcef/browser/url_request_context_getter_impl.h"
#if defined(OS_WIN)
#include <winhttp.h>
@ -15,7 +15,6 @@
#include "libcef/browser/scheme_handler.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_network_delegate.h"
#include "libcef/browser/url_request_context_proxy.h"
#include "libcef/browser/url_request_interceptor.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/content_client.h"
@ -98,7 +97,7 @@ class CefHttpUserAgentSettings : public net::HttpUserAgentSettings {
} // namespace
CefURLRequestContextGetter::CefURLRequestContextGetter(
CefURLRequestContextGetterImpl::CefURLRequestContextGetterImpl(
base::MessageLoop* io_loop,
base::MessageLoop* file_loop,
content::ProtocolHandlerMap* protocol_handlers,
@ -112,9 +111,8 @@ CefURLRequestContextGetter::CefURLRequestContextGetter(
std::swap(protocol_handlers_, *protocol_handlers);
}
CefURLRequestContextGetter::~CefURLRequestContextGetter() {
CefURLRequestContextGetterImpl::~CefURLRequestContextGetterImpl() {
CEF_REQUIRE_IOT();
STLDeleteElements(&url_request_context_proxies_);
// Delete the ProxyService object here so that any pending requests will be
// canceled before the associated URLRequestContext is destroyed in this
@ -122,7 +120,7 @@ CefURLRequestContextGetter::~CefURLRequestContextGetter() {
storage_->set_proxy_service(NULL);
}
net::URLRequestContext* CefURLRequestContextGetter::GetURLRequestContext() {
net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
CEF_REQUIRE_IOT();
if (!url_request_context_.get()) {
@ -131,7 +129,7 @@ net::URLRequestContext* CefURLRequestContextGetter::GetURLRequestContext() {
base::CommandLine::ForCurrentProcess();
const CefSettings& settings = CefContext::Get()->settings();
url_request_context_.reset(new net::URLRequestContext());
url_request_context_.reset(new CefURLRequestContextImpl());
storage_.reset(
new net::URLRequestContextStorage(url_request_context_.get()));
@ -262,15 +260,15 @@ net::URLRequestContext* CefURLRequestContextGetter::GetURLRequestContext() {
}
scoped_refptr<base::SingleThreadTaskRunner>
CefURLRequestContextGetter::GetNetworkTaskRunner() const {
CefURLRequestContextGetterImpl::GetNetworkTaskRunner() const {
return BrowserThread::GetMessageLoopProxyForThread(CEF_IOT);
}
net::HostResolver* CefURLRequestContextGetter::host_resolver() {
net::HostResolver* CefURLRequestContextGetterImpl::GetHostResolver() const {
return url_request_context_->host_resolver();
}
void CefURLRequestContextGetter::SetCookieStoragePath(
void CefURLRequestContextGetterImpl::SetCookieStoragePath(
const base::FilePath& path,
bool persist_session_cookies) {
CEF_REQUIRE_IOT();
@ -317,7 +315,7 @@ void CefURLRequestContextGetter::SetCookieStoragePath(
SetCookieSupportedSchemes(cookie_supported_schemes_);
}
void CefURLRequestContextGetter::SetCookieSupportedSchemes(
void CefURLRequestContextGetterImpl::SetCookieSupportedSchemes(
const std::vector<std::string>& schemes) {
CEF_REQUIRE_IOT();
@ -345,52 +343,7 @@ void CefURLRequestContextGetter::SetCookieSupportedSchemes(
delete [] arr;
}
CefURLRequestContextProxy*
CefURLRequestContextGetter::CreateURLRequestContextProxy() {
CEF_REQUIRE_IOT();
CefURLRequestContextProxy* proxy = new CefURLRequestContextProxy(this);
url_request_context_proxies_.insert(proxy);
return proxy;
}
void CefURLRequestContextGetter::ReleaseURLRequestContextProxy(
CefURLRequestContextProxy* proxy) {
CEF_REQUIRE_IOT();
// Don't do anything if we're currently shutting down. The proxy objects will
// be deleted when this object is destroyed.
if (CefContext::Get()->shutting_down())
return;
if (proxy->url_requests()->size() == 0) {
// Safe to delete the proxy.
RequestContextProxySet::iterator it =
url_request_context_proxies_.find(proxy);
DCHECK(it != url_request_context_proxies_.end());
url_request_context_proxies_.erase(it);
delete proxy;
} else {
proxy->increment_delete_try_count();
if (proxy->delete_try_count() <= 1) {
// Cancel the pending requests. This may result in additional tasks being
// posted on the IO thread.
std::set<const net::URLRequest*>::iterator it =
proxy->url_requests()->begin();
for (; it != proxy->url_requests()->end(); ++it)
const_cast<net::URLRequest*>(*it)->Cancel();
// Try to delete the proxy again later.
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefURLRequestContextGetter::ReleaseURLRequestContextProxy,
this, proxy));
} else {
NOTREACHED() <<
"too many retries to delete URLRequestContext proxy object";
}
}
}
void CefURLRequestContextGetter::CreateProxyConfigService() {
void CefURLRequestContextGetterImpl::CreateProxyConfigService() {
if (proxy_config_service_.get())
return;

View File

@ -0,0 +1,85 @@
// Copyright (c) 2011 The Chromium 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_URL_REQUEST_CONTEXT_GETTER_IMPL_H_
#define CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_GETTER_IMPL_H_
#pragma once
#include <string>
#include <vector>
#include "libcef/browser/url_request_context_getter.h"
#include "libcef/browser/url_request_context_impl.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/content_browser_client.h"
#include "net/url_request/url_request_job_factory.h"
namespace base {
class MessageLoop;
}
namespace net {
class FtpTransactionFactory;
class ProxyConfigService;
class URLRequestContextStorage;
class URLRequestJobFactory;
class URLRequestJobFactoryImpl;
class URLSecurityManager;
}
// Global URLRequestContextGetter implementation. Life span is primarily
// controlled by CefResourceContext and CefBrowserMainParts. Created on the UI
// thread but accessed and destroyed on the IO thread. See browser_context.h
// for an object relationship diagram.
class CefURLRequestContextGetterImpl : public CefURLRequestContextGetter {
public:
CefURLRequestContextGetterImpl(
base::MessageLoop* io_loop,
base::MessageLoop* file_loop,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors);
~CefURLRequestContextGetterImpl() override;
// net::URLRequestContextGetter implementation.
net::URLRequestContext* GetURLRequestContext() override;
scoped_refptr<base::SingleThreadTaskRunner>
GetNetworkTaskRunner() const override;
// CefURLRequestContextGetter implementation.
net::HostResolver* GetHostResolver() const override;
net::URLRequestJobFactoryImpl* job_factory_impl() const {
return job_factory_impl_;
}
void SetCookieStoragePath(const base::FilePath& path,
bool persist_session_cookies);
void SetCookieSupportedSchemes(const std::vector<std::string>& schemes);
private:
void CreateProxyConfigService();
base::MessageLoop* io_loop_;
base::MessageLoop* file_loop_;
scoped_ptr<net::ProxyConfigService> proxy_config_service_;
scoped_ptr<net::URLRequestContextStorage> storage_;
scoped_ptr<CefURLRequestContextImpl> url_request_context_;
scoped_ptr<net::URLSecurityManager> url_security_manager_;
scoped_ptr<net::FtpTransactionFactory> ftp_transaction_factory_;
content::ProtocolHandlerMap protocol_handlers_;
content::URLRequestInterceptorScopedVector request_interceptors_;
net::URLRequestJobFactoryImpl* job_factory_impl_;
base::FilePath cookie_store_path_;
std::vector<std::string> cookie_supported_schemes_;
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextGetterImpl);
};
#endif // CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_GETTER_IMPL_H_

View File

@ -9,27 +9,26 @@
CefURLRequestContextGetterProxy::CefURLRequestContextGetterProxy(
CefRefPtr<CefRequestContextHandler> handler,
CefURLRequestContextGetter* parent)
scoped_refptr<CefURLRequestContextGetterImpl> parent)
: handler_(handler),
parent_(parent),
context_proxy_(NULL) {
parent_(parent) {
DCHECK(parent);
}
CefURLRequestContextGetterProxy::~CefURLRequestContextGetterProxy() {
CEF_REQUIRE_IOT();
if (context_proxy_)
parent_->ReleaseURLRequestContextProxy(context_proxy_);
}
net::URLRequestContext*
CefURLRequestContextGetterProxy::GetURLRequestContext() {
CEF_REQUIRE_IOT();
if (!context_proxy_) {
context_proxy_ = parent_->CreateURLRequestContextProxy();
context_proxy_->Initialize(handler_);
context_proxy_.reset(
new CefURLRequestContextProxy(static_cast<CefURLRequestContextImpl*>(
parent_->GetURLRequestContext()),
handler_));
}
return context_proxy_;
return context_proxy_.get();
}
scoped_refptr<base::SingleThreadTaskRunner>
@ -38,5 +37,5 @@ scoped_refptr<base::SingleThreadTaskRunner>
}
net::HostResolver* CefURLRequestContextGetterProxy::GetHostResolver() const {
return parent_->host_resolver();
return parent_->GetHostResolver();
}

View File

@ -7,21 +7,21 @@
#pragma once
#include "include/cef_request_context_handler.h"
#include "libcef/browser/url_request_context_getter.h"
#include "libcef/browser/url_request_context_getter_impl.h"
#include "base/memory/scoped_ptr.h"
#include "net/url_request/url_request_context_getter.h"
class CefURLRequestContextGetter;
class CefURLRequestContextProxy;
namespace net {
class HostResolver;
}
class CefURLRequestContextGetterProxy : public net::URLRequestContextGetter {
// URLRequestContextGetter implementation for a particular CefRequestContext.
// Life span is primarily controlled by CefResourceContext. Only accessed on the
// IO thread. See browser_context.h for an object relationship diagram.
class CefURLRequestContextGetterProxy : public CefURLRequestContextGetter {
public:
CefURLRequestContextGetterProxy(CefRefPtr<CefRequestContextHandler> handler,
CefURLRequestContextGetter* parent);
CefURLRequestContextGetterProxy(
CefRefPtr<CefRequestContextHandler> handler,
scoped_refptr<CefURLRequestContextGetterImpl> parent);
~CefURLRequestContextGetterProxy() override;
// net::URLRequestContextGetter implementation.
@ -29,16 +29,20 @@ class CefURLRequestContextGetterProxy : public net::URLRequestContextGetter {
scoped_refptr<base::SingleThreadTaskRunner>
GetNetworkTaskRunner() const override;
net::HostResolver* GetHostResolver() const;
// CefURLRequestContextGetter implementation.
net::HostResolver* GetHostResolver() const override;
CefRefPtr<CefRequestContextHandler> handler() const { return handler_; }
private:
CefRefPtr<CefRequestContextHandler> handler_;
scoped_refptr<CefURLRequestContextGetter> parent_;
// The |context_proxy_| object is owned by |parent_|.
CefURLRequestContextProxy* context_proxy_;
// The CefURLRequestContextImpl owned by |parent_| is passed as a raw pointer
// to CefURLRequestContextProxy and CefCookieStoreProxy. This reference is
// necessary to keep it alive.
scoped_refptr<CefURLRequestContextGetterImpl> parent_;
scoped_ptr<CefURLRequestContextProxy> context_proxy_;
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextGetterProxy);
};

View File

@ -0,0 +1,22 @@
// Copyright (c) 2015 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_URL_REQUEST_CONTEXT_IMPL_H_
#define CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_IMPL_H_
#pragma once
#include "libcef/browser/url_request_context.h"
// Global URLRequestContext implementation. Life span is controlled by
// CefURLRequestContextGetterImpl. Only accessed on the IO thread. See
// browser_context.h for an object relationship diagram.
class CefURLRequestContextImpl : public CefURLRequestContext {
public:
CefURLRequestContextImpl() {}
private:
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextImpl);
};
#endif // CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_IMPL_H_

View File

@ -4,170 +4,41 @@
#include "libcef/browser/url_request_context_proxy.h"
#include <string>
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/cookie_manager_impl.h"
#include "libcef/browser/cookie_store_proxy.h"
#include "libcef/browser/thread_util.h"
#include "base/logging.h"
#include "base/message_loop/message_loop_proxy.h"
#include "net/cookies/cookie_store.h"
#include "net/url_request/url_request_context_getter.h"
namespace {
class CefCookieStoreProxy : public net::CookieStore {
public:
CefCookieStoreProxy(net::URLRequestContext* parent,
CefRefPtr<CefRequestContextHandler> handler)
: parent_(parent),
handler_(handler) {
}
~CefCookieStoreProxy() override {
CEF_REQUIRE_IOT();
}
// net::CookieStore methods.
void SetCookieWithOptionsAsync(
const GURL& url,
const std::string& cookie_line,
const net::CookieOptions& options,
const SetCookiesCallback& callback) override {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->SetCookieWithOptionsAsync(url, cookie_line, options,
callback);
}
void GetCookiesWithOptionsAsync(
const GURL& url, const net::CookieOptions& options,
const GetCookiesCallback& callback) override {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->GetCookiesWithOptionsAsync(url, options, callback);
}
void DeleteCookieAsync(const GURL& url,
const std::string& cookie_name,
const base::Closure& callback) override {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->DeleteCookieAsync(url, cookie_name, callback);
}
void GetAllCookiesForURLAsync(
const GURL& url,
const GetCookieListCallback& callback) override {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->GetAllCookiesForURLAsync(url, callback);
}
void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin,
const base::Time& delete_end,
const DeleteCallback& callback) override {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->DeleteAllCreatedBetweenAsync(delete_begin, delete_end,
callback);
}
void DeleteAllCreatedBetweenForHostAsync(
const base::Time delete_begin,
const base::Time delete_end,
const GURL& url,
const DeleteCallback& callback) override {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->DeleteAllCreatedBetweenForHostAsync(delete_begin, delete_end,
url, callback);
}
void DeleteSessionCookiesAsync(const DeleteCallback& callback) override {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->DeleteSessionCookiesAsync(callback);
}
net::CookieMonster* GetCookieMonster() override {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
return cookie_store->GetCookieMonster();
}
scoped_ptr<CookieChangedSubscription> AddCallbackForCookie(
const GURL& url,
const std::string& name,
const CookieChangedCallback& callback) override {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
return cookie_store->AddCallbackForCookie(url, name, callback);
}
private:
net::CookieStore* GetCookieStore() {
CEF_REQUIRE_IOT();
scoped_refptr<net::CookieStore> cookie_store;
if (handler_.get()) {
// Get the manager from the handler.
CefRefPtr<CefCookieManager> manager = handler_->GetCookieManager();
if (manager.get()) {
cookie_store =
reinterpret_cast<CefCookieManagerImpl*>(
manager.get())->cookie_monster();
DCHECK(cookie_store.get());
}
}
if (!cookie_store.get()) {
// Use the global cookie store.
cookie_store = parent_->cookie_store();
}
DCHECK(cookie_store.get());
return cookie_store.get();
}
// This pointer is guaranteed by the CefRequestContextProxy object.
net::URLRequestContext* parent_;
CefRefPtr<CefRequestContextHandler> handler_;
DISALLOW_COPY_AND_ASSIGN(CefCookieStoreProxy);
};
} // namespace
#include "libcef/browser/url_request_context_impl.h"
CefURLRequestContextProxy::CefURLRequestContextProxy(
net::URLRequestContextGetter* parent)
: parent_(parent),
delete_try_count_(0) {
CefURLRequestContextImpl* parent,
CefRefPtr<CefRequestContextHandler> handler) {
CEF_REQUIRE_IOT();
// Cookie store that proxies to the browser implementation.
cookie_store_proxy_ = new CefCookieStoreProxy(parent, handler);
set_cookie_store(cookie_store_proxy_.get());
// All other values refer to the parent request context.
set_net_log(parent->net_log());
set_host_resolver(parent->host_resolver());
set_cert_verifier(parent->cert_verifier());
set_transport_security_state(parent->transport_security_state());
set_channel_id_service(parent->channel_id_service());
set_fraudulent_certificate_reporter(
parent->fraudulent_certificate_reporter());
set_proxy_service(parent->proxy_service());
set_ssl_config_service(parent->ssl_config_service());
set_http_auth_handler_factory(parent->http_auth_handler_factory());
set_http_transaction_factory(parent->http_transaction_factory());
set_network_delegate(parent->network_delegate());
set_http_server_properties(parent->http_server_properties());
set_transport_security_state(parent->transport_security_state());
set_http_user_agent_settings(const_cast<net::HttpUserAgentSettings*>(
parent->http_user_agent_settings()));
set_job_factory(parent->job_factory());
}
CefURLRequestContextProxy::~CefURLRequestContextProxy() {
CEF_REQUIRE_IOT();
}
void CefURLRequestContextProxy::Initialize(
CefRefPtr<CefRequestContextHandler> handler) {
CEF_REQUIRE_IOT();
net::URLRequestContext* context = parent_->GetURLRequestContext();
// Cookie store that proxies to the browser implementation.
cookie_store_proxy_ = new CefCookieStoreProxy(context, handler);
set_cookie_store(cookie_store_proxy_.get());
// All other values refer to the parent request context.
set_net_log(context->net_log());
set_host_resolver(context->host_resolver());
set_cert_verifier(context->cert_verifier());
set_transport_security_state(context->transport_security_state());
set_channel_id_service(context->channel_id_service());
set_fraudulent_certificate_reporter(
context->fraudulent_certificate_reporter());
set_proxy_service(context->proxy_service());
set_ssl_config_service(context->ssl_config_service());
set_http_auth_handler_factory(context->http_auth_handler_factory());
set_http_transaction_factory(context->http_transaction_factory());
set_network_delegate(context->network_delegate());
set_http_server_properties(context->http_server_properties());
set_transport_security_state(context->transport_security_state());
set_http_user_agent_settings(const_cast<net::HttpUserAgentSettings*>(
context->http_user_agent_settings()));
set_job_factory(context->job_factory());
// The CookieStore may outlive this object.
cookie_store_proxy_->Detach();
}

View File

@ -7,35 +7,28 @@
#pragma once
#include "include/cef_request_context_handler.h"
#include "libcef/browser/cookie_store_proxy.h"
#include "libcef/browser/url_request_context.h"
#include "base/memory/scoped_ptr.h"
#include "net/url_request/url_request_context.h"
class CefBrowserHostImpl;
class CefURLRequestContextImpl;
namespace net {
class CookieStore;
class URLRequestContextGetter;
}
class CefURLRequestContextProxy : public net::URLRequestContext {
// URLRequestContext implementation for a particular CefRequestContext. Life
// span is controlled by CefURLRequestContextGetterProxy. Only accessed on the
// IO thread. See browser_context.h for an object relationship diagram.
class CefURLRequestContextProxy : public CefURLRequestContext {
public:
explicit CefURLRequestContextProxy(net::URLRequestContextGetter* parent);
// The |parent| pointer is kept alive by CefURLRequestContextGetterProxy
// which has a ref to the owning CefURLRequestContextGetterImpl. It is
// guaranteed to outlive this object.
CefURLRequestContextProxy(CefURLRequestContextImpl* parent,
CefRefPtr<CefRequestContextHandler> handler);
~CefURLRequestContextProxy() override;
void Initialize(CefRefPtr<CefRequestContextHandler> handler);
// We may try to delete this proxy multiple times if URLRequests are still
// pending. Keep track of the number of tries so that they don't become
// excessive.
int delete_try_count() const { return delete_try_count_; }
void increment_delete_try_count() { delete_try_count_++; }
private:
net::URLRequestContextGetter* parent_;
scoped_refptr<net::CookieStore> cookie_store_proxy_;
int delete_try_count_;
scoped_refptr<CefCookieStoreProxy> cookie_store_proxy_;
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextProxy);
};

View File

@ -46,7 +46,8 @@ class BrowserWindow : public ClientHandler::Delegate {
// Create a new browser and native window.
virtual void CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) = 0;
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) = 0;
// Retrieve the configuration that will be used when creating a popup window.
// The popup browser will initially be parented to |temp_handle| which should

View File

@ -924,9 +924,11 @@ BrowserWindowOsrGtk::BrowserWindowOsrGtk(BrowserWindow::Delegate* delegate,
client_handler_ = new ClientHandlerOsr(this, this, startup_url);
}
void BrowserWindowOsrGtk::CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) {
void BrowserWindowOsrGtk::CreateBrowser(
ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) {
REQUIRE_MAIN_THREAD();
// Create the native window.
@ -944,7 +946,7 @@ void BrowserWindowOsrGtk::CreateBrowser(ClientWindowHandle parent_handle,
// Create the browser asynchronously.
CefBrowserHost::CreateBrowser(window_info, client_handler_,
client_handler_->startup_url(),
settings, NULL);
settings, request_context);
}
void BrowserWindowOsrGtk::GetPopupConfig(CefWindowHandle temp_handle,

View File

@ -28,7 +28,8 @@ class BrowserWindowOsrGtk : public BrowserWindow,
// BrowserWindow methods.
void CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) OVERRIDE;
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) OVERRIDE;
void GetPopupConfig(CefWindowHandle temp_handle,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,

View File

@ -29,7 +29,8 @@ class BrowserWindowOsrMac : public BrowserWindow,
// BrowserWindow methods.
void CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) OVERRIDE;
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) OVERRIDE;
void GetPopupConfig(CefWindowHandle temp_handle,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,

View File

@ -1100,9 +1100,11 @@ BrowserWindowOsrMac::~BrowserWindowOsrMac() {
}
}
void BrowserWindowOsrMac::CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) {
void BrowserWindowOsrMac::CreateBrowser(
ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) {
REQUIRE_MAIN_THREAD();
// Create the native NSView.
@ -1114,7 +1116,7 @@ void BrowserWindowOsrMac::CreateBrowser(ClientWindowHandle parent_handle,
// Create the browser asynchronously.
CefBrowserHost::CreateBrowser(window_info, client_handler_,
client_handler_->startup_url(),
settings, NULL);
settings, request_context);
}
void BrowserWindowOsrMac::GetPopupConfig(CefWindowHandle temp_handle,

View File

@ -19,15 +19,17 @@ BrowserWindowOsrWin::BrowserWindowOsrWin(BrowserWindow::Delegate* delegate,
client_handler_ = new ClientHandlerOsr(this, osr_window_.get(), startup_url);
}
void BrowserWindowOsrWin::CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) {
void BrowserWindowOsrWin::CreateBrowser(
ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) {
REQUIRE_MAIN_THREAD();
// Create the new browser and native window on the UI thread.
RECT wnd_rect = {rect.x, rect.y, rect.x + rect.width, rect.y + rect.height};
osr_window_->CreateBrowser(parent_handle, wnd_rect, client_handler_, settings,
client_handler_->startup_url());
request_context, client_handler_->startup_url());
}
void BrowserWindowOsrWin::GetPopupConfig(CefWindowHandle temp_handle,

View File

@ -27,7 +27,8 @@ class BrowserWindowOsrWin : public BrowserWindow,
// BrowserWindow methods.
void CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) OVERRIDE;
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) OVERRIDE;
void GetPopupConfig(CefWindowHandle temp_handle,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,

View File

@ -88,9 +88,11 @@ BrowserWindowStdGtk::BrowserWindowStdGtk(Delegate* delegate,
client_handler_ = new ClientHandlerStd(this, startup_url);
}
void BrowserWindowStdGtk::CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) {
void BrowserWindowStdGtk::CreateBrowser(
ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) {
REQUIRE_MAIN_THREAD();
CefWindowInfo window_info;
@ -98,7 +100,7 @@ void BrowserWindowStdGtk::CreateBrowser(ClientWindowHandle parent_handle,
CefBrowserHost::CreateBrowser(window_info, client_handler_,
client_handler_->startup_url(),
settings, NULL);
settings, request_context);
}
void BrowserWindowStdGtk::GetPopupConfig(CefWindowHandle temp_handle,

View File

@ -23,7 +23,8 @@ class BrowserWindowStdGtk : public BrowserWindow {
// BrowserWindow methods.
void CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) OVERRIDE;
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) OVERRIDE;
void GetPopupConfig(CefWindowHandle temp_handle,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,

View File

@ -23,7 +23,8 @@ class BrowserWindowStdMac : public BrowserWindow {
// BrowserWindow methods.
void CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) OVERRIDE;
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) OVERRIDE;
void GetPopupConfig(CefWindowHandle temp_handle,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,

View File

@ -18,9 +18,11 @@ BrowserWindowStdMac::BrowserWindowStdMac(Delegate* delegate,
client_handler_ = new ClientHandlerStd(this, startup_url);
}
void BrowserWindowStdMac::CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) {
void BrowserWindowStdMac::CreateBrowser(
ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) {
REQUIRE_MAIN_THREAD();
CefWindowInfo window_info;
@ -29,7 +31,7 @@ void BrowserWindowStdMac::CreateBrowser(ClientWindowHandle parent_handle,
CefBrowserHost::CreateBrowser(window_info, client_handler_,
client_handler_->startup_url(),
settings, NULL);
settings, request_context);
}
void BrowserWindowStdMac::GetPopupConfig(CefWindowHandle temp_handle,

View File

@ -15,9 +15,11 @@ BrowserWindowStdWin::BrowserWindowStdWin(Delegate* delegate,
client_handler_ = new ClientHandlerStd(this, startup_url);
}
void BrowserWindowStdWin::CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) {
void BrowserWindowStdWin::CreateBrowser(
ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) {
REQUIRE_MAIN_THREAD();
CefWindowInfo window_info;
@ -26,7 +28,7 @@ void BrowserWindowStdWin::CreateBrowser(ClientWindowHandle parent_handle,
CefBrowserHost::CreateBrowser(window_info, client_handler_,
client_handler_->startup_url(),
settings, NULL);
settings, request_context);
}
void BrowserWindowStdWin::GetPopupConfig(CefWindowHandle temp_handle,

View File

@ -23,7 +23,8 @@ class BrowserWindowStdWin : public BrowserWindow {
// BrowserWindow methods.
void CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) OVERRIDE;
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context) OVERRIDE;
void GetPopupConfig(CefWindowHandle temp_handle,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,

View File

@ -82,65 +82,6 @@ std::string GetBinaryString(CefRefPtr<CefBinaryValue> value) {
return CefBase64Encode(src.data(), src.size());
}
std::string GetErrorString(cef_errorcode_t code) {
// Case condition that returns |code| as a string.
#define CASE(code) case code: return #code
switch (code) {
CASE(ERR_NONE);
CASE(ERR_FAILED);
CASE(ERR_ABORTED);
CASE(ERR_INVALID_ARGUMENT);
CASE(ERR_INVALID_HANDLE);
CASE(ERR_FILE_NOT_FOUND);
CASE(ERR_TIMED_OUT);
CASE(ERR_FILE_TOO_BIG);
CASE(ERR_UNEXPECTED);
CASE(ERR_ACCESS_DENIED);
CASE(ERR_NOT_IMPLEMENTED);
CASE(ERR_CONNECTION_CLOSED);
CASE(ERR_CONNECTION_RESET);
CASE(ERR_CONNECTION_REFUSED);
CASE(ERR_CONNECTION_ABORTED);
CASE(ERR_CONNECTION_FAILED);
CASE(ERR_NAME_NOT_RESOLVED);
CASE(ERR_INTERNET_DISCONNECTED);
CASE(ERR_SSL_PROTOCOL_ERROR);
CASE(ERR_ADDRESS_INVALID);
CASE(ERR_ADDRESS_UNREACHABLE);
CASE(ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
CASE(ERR_TUNNEL_CONNECTION_FAILED);
CASE(ERR_NO_SSL_VERSIONS_ENABLED);
CASE(ERR_SSL_VERSION_OR_CIPHER_MISMATCH);
CASE(ERR_SSL_RENEGOTIATION_REQUESTED);
CASE(ERR_CERT_COMMON_NAME_INVALID);
CASE(ERR_CERT_DATE_INVALID);
CASE(ERR_CERT_AUTHORITY_INVALID);
CASE(ERR_CERT_CONTAINS_ERRORS);
CASE(ERR_CERT_NO_REVOCATION_MECHANISM);
CASE(ERR_CERT_UNABLE_TO_CHECK_REVOCATION);
CASE(ERR_CERT_REVOKED);
CASE(ERR_CERT_INVALID);
CASE(ERR_CERT_END);
CASE(ERR_INVALID_URL);
CASE(ERR_DISALLOWED_URL_SCHEME);
CASE(ERR_UNKNOWN_URL_SCHEME);
CASE(ERR_TOO_MANY_REDIRECTS);
CASE(ERR_UNSAFE_REDIRECT);
CASE(ERR_UNSAFE_PORT);
CASE(ERR_INVALID_RESPONSE);
CASE(ERR_INVALID_CHUNKED_ENCODING);
CASE(ERR_METHOD_NOT_SUPPORTED);
CASE(ERR_UNEXPECTED_PROXY_AUTH);
CASE(ERR_EMPTY_RESPONSE);
CASE(ERR_RESPONSE_HEADERS_TOO_BIG);
CASE(ERR_CACHE_MISS);
CASE(ERR_INSECURE_RESPONSE);
default:
return "UNKNOWN";
}
}
// Load a data: URI containing the error message.
void LoadErrorPage(CefRefPtr<CefFrame> frame,
const std::string& failed_url,
@ -151,7 +92,7 @@ void LoadErrorPage(CefRefPtr<CefFrame> frame,
"<body bgcolor=\"white\">"
"<h3>Page failed to load.</h3>"
"URL: <a href=\"" << failed_url << "\">"<< failed_url << "</a>"
"<br/>Error: " << GetErrorString(error_code) <<
"<br/>Error: " << test_runner::GetErrorString(error_code) <<
" (" << error_code << ")";
if (!other_info.empty())

View File

@ -82,12 +82,13 @@ void OsrWindowWin::CreateBrowser(HWND parent_hwnd,
const RECT& rect,
CefRefPtr<CefClient> handler,
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context,
const std::string& startup_url) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute this method on the UI thread.
CefPostTask(TID_UI, base::Bind(&OsrWindowWin::CreateBrowser, this,
parent_hwnd, rect, handler, settings,
startup_url));
request_context, startup_url));
return;
}
@ -99,7 +100,7 @@ void OsrWindowWin::CreateBrowser(HWND parent_hwnd,
// Create the browser asynchronously.
CefBrowserHost::CreateBrowser(window_info, handler, startup_url, settings,
NULL);
request_context);
}
void OsrWindowWin::ShowPopup(HWND parent_hwnd,

View File

@ -48,6 +48,7 @@ class OsrWindowWin :
const RECT& rect,
CefRefPtr<CefClient> handler,
const CefBrowserSettings& settings,
CefRefPtr<CefRequestContext> request_context,
const std::string& startup_url);
// Show the popup window with correct parent and bounds in parent coordinates.

View File

@ -47,10 +47,11 @@
#define IDS_OSRTEST 1005
#define IDS_OTHER_TESTS 1006
#define IDS_PERFORMANCE 1007
#define IDS_TRANSPARENCY 1008
#define IDS_WINDOW 1009
#define IDS_XMLHTTPREQUEST 1010
#define IDS_PERFORMANCE2 1011
#define IDS_PERFORMANCE2 1008
#define IDS_TRANSPARENCY 1009
#define IDS_URLREQUEST 1010
#define IDS_WINDOW 1011
#define IDS_XMLHTTPREQUEST 1012
// Next default values for new objects
//

View File

@ -45,6 +45,7 @@ int GetResourceId(const char* resource_name) {
{"performance.html", IDS_PERFORMANCE},
{"performance2.html", IDS_PERFORMANCE2},
{"transparency.html", IDS_TRANSPARENCY},
{"urlrequest.html", IDS_URLREQUEST},
{"window.html", IDS_WINDOW},
{"xmlhttprequest.html", IDS_XMLHTTPREQUEST},
};

View File

@ -25,6 +25,11 @@ class RootWindow :
// of this class will be called on the main thread.
class Delegate {
public:
// Called to retrieve the CefRequestContext for browser. Only called for
// non-popup browsers. May return NULL.
virtual CefRefPtr<CefRequestContext> GetRequestContext(
RootWindow* root_window) = 0;
// Called to execute a test. See resource.h for |test_id| values.
virtual void OnTest(RootWindow* root_window, int test_id) = 0;

View File

@ -319,7 +319,8 @@ void RootWindowGtk::CreateRootWindow(const CefBrowserSettings& settings) {
if (!is_popup_) {
// Create the browser window.
browser_window_->CreateBrowser(parent, browser_bounds_, settings);
browser_window_->CreateBrowser(parent, browser_bounds_, settings,
delegate_->GetRequestContext(this));
} else {
// With popups we already have a browser window. Parent the browser window
// to the root window and show it in the correct location.

View File

@ -522,7 +522,8 @@ void RootWindowMac::CreateRootWindow(const CefBrowserSettings& settings) {
if (!is_popup_) {
// Create the browser window.
browser_window_->CreateBrowser(contentView, CefRect(0, 0, width, height),
settings);
settings,
delegate_->GetRequestContext(this));
} else {
// With popups we already have a browser window. Parent the browser window
// to the root window and show it in the correct location.

View File

@ -5,14 +5,21 @@
#include "cefclient/browser/root_window_manager.h"
#include "include/base/cef_bind.h"
#include "include/base/cef_logging.h"
#include "include/wrapper/cef_helpers.h"
#include "cefclient/browser/main_context.h"
#include "cefclient/browser/test_runner.h"
#include "cefclient/common/client_switches.h"
namespace client {
RootWindowManager::RootWindowManager(bool terminate_when_all_windows_closed)
: terminate_when_all_windows_closed_(terminate_when_all_windows_closed) {
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
DCHECK(command_line.get());
request_context_per_browser_ =
command_line->HasSwitch(switches::kRequestContextPerBrowser);
}
RootWindowManager::~RootWindowManager() {
@ -100,6 +107,19 @@ void RootWindowManager::OnRootWindowCreated(
root_windows_.insert(root_window);
}
CefRefPtr<CefRequestContext> RootWindowManager::GetRequestContext(
RootWindow* root_window) {
REQUIRE_MAIN_THREAD();
if (request_context_per_browser_) {
// Create a new request context for each browser.
return CefRequestContext::CreateContext(NULL);
}
// All browsers will share the global request context.
return NULL;
}
void RootWindowManager::OnTest(RootWindow* root_window, int test_id) {
REQUIRE_MAIN_THREAD();

View File

@ -64,11 +64,14 @@ class RootWindowManager : public RootWindow::Delegate {
void OnRootWindowCreated(scoped_refptr<RootWindow> root_window);
// RootWindow::Delegate methods.
CefRefPtr<CefRequestContext> GetRequestContext(
RootWindow* root_window) OVERRIDE;
void OnTest(RootWindow* root_window, int test_id) OVERRIDE;
void OnExit(RootWindow* root_window) OVERRIDE;
void OnRootWindowDestroyed(RootWindow* root_window) OVERRIDE;
const bool terminate_when_all_windows_closed_;
bool request_context_per_browser_;
// Existing root windows. Only accessed on the main thread.
typedef std::set<scoped_refptr<RootWindow> > RootWindowSet;

View File

@ -325,7 +325,8 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) {
CefRect cef_rect(rect.left, rect.top,
rect.right - rect.left,
rect.bottom - rect.top);
browser_window_->CreateBrowser(hwnd_, cef_rect, settings);
browser_window_->CreateBrowser(hwnd_, cef_rect, settings,
delegate_->GetRequestContext(this));
} else {
// With popups we already have a browser window. Parent the browser window
// to the root window and show it in the correct location.

View File

@ -19,6 +19,7 @@
#include "cefclient/browser/resource.h"
#include "cefclient/browser/resource_util.h"
#include "cefclient/browser/scheme_test.h"
#include "cefclient/browser/urlrequest_test.h"
#include "cefclient/browser/window_test.h"
namespace client {
@ -376,6 +377,65 @@ std::string GetDataURI(const std::string& data,
CefURIEncode(CefBase64Encode(data.data(), data.size()), false).ToString();
}
std::string GetErrorString(cef_errorcode_t code) {
// Case condition that returns |code| as a string.
#define CASE(code) case code: return #code
switch (code) {
CASE(ERR_NONE);
CASE(ERR_FAILED);
CASE(ERR_ABORTED);
CASE(ERR_INVALID_ARGUMENT);
CASE(ERR_INVALID_HANDLE);
CASE(ERR_FILE_NOT_FOUND);
CASE(ERR_TIMED_OUT);
CASE(ERR_FILE_TOO_BIG);
CASE(ERR_UNEXPECTED);
CASE(ERR_ACCESS_DENIED);
CASE(ERR_NOT_IMPLEMENTED);
CASE(ERR_CONNECTION_CLOSED);
CASE(ERR_CONNECTION_RESET);
CASE(ERR_CONNECTION_REFUSED);
CASE(ERR_CONNECTION_ABORTED);
CASE(ERR_CONNECTION_FAILED);
CASE(ERR_NAME_NOT_RESOLVED);
CASE(ERR_INTERNET_DISCONNECTED);
CASE(ERR_SSL_PROTOCOL_ERROR);
CASE(ERR_ADDRESS_INVALID);
CASE(ERR_ADDRESS_UNREACHABLE);
CASE(ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
CASE(ERR_TUNNEL_CONNECTION_FAILED);
CASE(ERR_NO_SSL_VERSIONS_ENABLED);
CASE(ERR_SSL_VERSION_OR_CIPHER_MISMATCH);
CASE(ERR_SSL_RENEGOTIATION_REQUESTED);
CASE(ERR_CERT_COMMON_NAME_INVALID);
CASE(ERR_CERT_DATE_INVALID);
CASE(ERR_CERT_AUTHORITY_INVALID);
CASE(ERR_CERT_CONTAINS_ERRORS);
CASE(ERR_CERT_NO_REVOCATION_MECHANISM);
CASE(ERR_CERT_UNABLE_TO_CHECK_REVOCATION);
CASE(ERR_CERT_REVOKED);
CASE(ERR_CERT_INVALID);
CASE(ERR_CERT_END);
CASE(ERR_INVALID_URL);
CASE(ERR_DISALLOWED_URL_SCHEME);
CASE(ERR_UNKNOWN_URL_SCHEME);
CASE(ERR_TOO_MANY_REDIRECTS);
CASE(ERR_UNSAFE_REDIRECT);
CASE(ERR_UNSAFE_PORT);
CASE(ERR_INVALID_RESPONSE);
CASE(ERR_INVALID_CHUNKED_ENCODING);
CASE(ERR_METHOD_NOT_SUPPORTED);
CASE(ERR_UNEXPECTED_PROXY_AUTH);
CASE(ERR_EMPTY_RESPONSE);
CASE(ERR_RESPONSE_HEADERS_TOO_BIG);
CASE(ERR_CACHE_MISS);
CASE(ERR_INSECURE_RESPONSE);
default:
return "UNKNOWN";
}
}
CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
@ -426,6 +486,9 @@ void CreateMessageHandlers(MessageHandlerSet& handlers) {
// Create the binding test handlers.
binding_test::CreateMessageHandlers(handlers);
// Create the urlrequest test handlers.
urlrequest_test::CreateMessageHandlers(handlers);
// Create the window test handlers.
window_test::CreateMessageHandlers(handlers);
}

View File

@ -27,6 +27,9 @@ std::string DumpRequestContents(CefRefPtr<CefRequest> request);
std::string GetDataURI(const std::string& data,
const std::string& mime_type);
// Returns the string representation of the specified error code.
std::string GetErrorString(cef_errorcode_t code);
// Get test resources.
CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,

View File

@ -0,0 +1,188 @@
// Copyright (c) 2015 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 "cefclient/browser/urlrequest_test.h"
#include <string>
#include "include/base/cef_bind.h"
#include "include/base/cef_callback.h"
#include "include/base/cef_logging.h"
#include "include/cef_urlrequest.h"
#include "include/wrapper/cef_helpers.h"
namespace client {
namespace urlrequest_test {
namespace {
const char kTestUrl[] = "http://tests/urlrequest";
const char kTestMessageName[] = "URLRequestTest";
// Implementation of CefURLRequestClient that stores response information. Only
// accessed on the UI thread.
class RequestClient : public CefURLRequestClient {
public:
// Callback to be executed on request completion.
typedef base::Callback<void(CefURLRequest::ErrorCode /*error_code*/,
const std::string& /*download_data*/)> Callback;
explicit RequestClient(const Callback& callback)
: callback_(callback) {
CEF_REQUIRE_UI_THREAD();
DCHECK(!callback_.is_null());
}
void Detach() {
CEF_REQUIRE_UI_THREAD();
if (!callback_.is_null())
callback_.Reset();
}
void OnRequestComplete(CefRefPtr<CefURLRequest> request) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
if (!callback_.is_null()) {
callback_.Run(request->GetRequestError(), download_data_);
callback_.Reset();
}
}
void OnUploadProgress(CefRefPtr<CefURLRequest> request,
int64 current,
int64 total) OVERRIDE {
}
void OnDownloadProgress(CefRefPtr<CefURLRequest> request,
int64 current,
int64 total) OVERRIDE {
}
void OnDownloadData(CefRefPtr<CefURLRequest> request,
const void* data,
size_t data_length) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
download_data_ += std::string(static_cast<const char*>(data), data_length);
}
bool GetAuthCredentials(bool isProxy,
const CefString& host,
int port,
const CefString& realm,
const CefString& scheme,
CefRefPtr<CefAuthCallback> callback) OVERRIDE {
return false;
}
private:
Callback callback_;
std::string download_data_;
IMPLEMENT_REFCOUNTING(RequestClient);
DISALLOW_COPY_AND_ASSIGN(RequestClient);
};
// Handle messages in the browser process. Only accessed on the UI thread.
class Handler : public CefMessageRouterBrowserSide::Handler {
public:
Handler() {
CEF_REQUIRE_UI_THREAD();
}
~Handler() {
CancelPendingRequest();
}
// Called due to cefQuery execution in urlrequest.html.
bool OnQuery(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64 query_id,
const CefString& request,
bool persistent,
CefRefPtr<Callback> callback) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
// Only handle messages from the test URL.
const std::string& url = frame->GetURL();
if (url.find(kTestUrl) != 0)
return false;
const std::string& message_name = request;
if (message_name.find(kTestMessageName) == 0) {
const std::string& url = message_name.substr(sizeof(kTestMessageName));
CancelPendingRequest();
DCHECK(!callback_.get());
DCHECK(!urlrequest_.get());
callback_ = callback;
// Create a CefRequest for the specified URL.
CefRefPtr<CefRequest> request = CefRequest::Create();
request->SetURL(url);
request->SetMethod("GET");
// Callback to be executed on request completion.
// It's safe to use base::Unretained() here because there is only one
// RequestClient pending at any given time and we explicitly detach the
// callback in the Handler destructor.
const RequestClient::Callback& callback =
base::Bind(&Handler::OnRequestComplete, base::Unretained(this));
// Create and start the new CefURLRequest.
urlrequest_ = CefURLRequest::Create(request, new RequestClient(callback));
return true;
}
return false;
}
private:
// Cancel the currently pending URL request, if any.
void CancelPendingRequest() {
CEF_REQUIRE_UI_THREAD();
if (urlrequest_.get()) {
// Don't execute the callback when we explicitly cancel the request.
static_cast<RequestClient*>(urlrequest_->GetClient().get())->Detach();
urlrequest_->Cancel();
urlrequest_ = NULL;
}
if (callback_.get()) {
// Must always execute |callback_| before deleting it.
callback_->Failure(ERR_ABORTED, test_runner::GetErrorString(ERR_ABORTED));
callback_ = NULL;
}
}
void OnRequestComplete(CefURLRequest::ErrorCode error_code,
const std::string& download_data) {
CEF_REQUIRE_UI_THREAD();
if (error_code == ERR_NONE)
callback_->Success(download_data);
else
callback_->Failure(error_code, test_runner::GetErrorString(error_code));
callback_ = NULL;
urlrequest_ = NULL;
}
CefRefPtr<Callback> callback_;
CefRefPtr<CefURLRequest> urlrequest_;
DISALLOW_COPY_AND_ASSIGN(Handler);
};
} // namespace
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers) {
handlers.insert(new Handler());
}
} // namespace urlrequest_test
} // namespace client

View File

@ -0,0 +1,20 @@
// Copyright (c) 2015 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_TESTS_CEFCLIENT_BROWSER_URLREQUEST_TEST_H_
#define CEF_TESTS_CEFCLIENT_BROWSER_URLREQUEST_TEST_H_
#pragma once
#include "cefclient/browser/test_runner.h"
namespace client {
namespace urlrequest_test {
// Create message handlers. Called from test_runner.cc.
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers);
} // namespace urlrequest_test
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_BROWSER_URLREQUEST_TEST_H_

View File

@ -25,6 +25,7 @@ const char kOffScreenFrameRate[] = "off-screen-frame-rate";
const char kTransparentPaintingEnabled[] = "transparent-painting-enabled";
const char kShowUpdateRect[] = "show-update-rect";
const char kMouseCursorChangeDisabled[] = "mouse-cursor-change-disabled";
const char kRequestContextPerBrowser[] = "request-context-per-browser";
} // namespace switches
} // namespace client

View File

@ -19,6 +19,7 @@ extern const char kOffScreenFrameRate[];
extern const char kTransparentPaintingEnabled[];
extern const char kShowUpdateRect[];
extern const char kMouseCursorChangeDisabled[];
extern const char kRequestContextPerBrowser[];
} // namespace switches
} // namespace client

View File

@ -25,6 +25,7 @@
<li><a href="http://tests/transparency">Transparency</a></li>
<li><a href="http://webglsamples.googlecode.com/hg/field/field.html">WebGL</a></li>
<li><a href="http://apprtc.appspot.com/">WebRTC</a> - requires "enable-media-stream" flag</li>
<li><a href="http://tests/urlrequest">CefURLRequest</a></li>
<li><a href="http://tests/xmlhttprequest">XMLHttpRequest</a></li>
<li><a href="javascript:window.print();">Print this page with &quot;javascript:window.print();&quot;</a></li>
</ul>

View File

@ -0,0 +1,27 @@
<html>
<body bgcolor="white">
<script language="JavaScript">
// Send a query to the browser process.
function execURLRequest() {
document.getElementById('ta').value = 'Request pending...';
// Results in a call to the OnQuery method in urlrequest_test.cpp
window.cefQuery({
request: 'URLRequestTest:' + document.getElementById("url").value,
onSuccess: function(response) {
document.getElementById('ta').value = response;
},
onFailure: function(error_code, error_message) {
document.getElementById('ta').value = 'Failed with error ' + error_message + ' (' + error_code + ')';
}
});
}
</script>
<form>
URL: <input type="text" id="url" value="http://www.google.com">
<br/><input type="button" onclick="execURLRequest();" value="Execute CefURLRequest">
<br/><textarea rows="10" cols="40" id="ta"></textarea>
</form>
</body>
</html>

View File

@ -38,6 +38,7 @@ IDS_OTHER_TESTS BINARY "..\\other_tests.html"
IDS_PERFORMANCE BINARY "..\\performance.html"
IDS_PERFORMANCE2 BINARY "..\\performance2.html"
IDS_TRANSPARENCY BINARY "..\\transparency.html"
IDS_URLREQUEST BINARY "..\\urlrequest.html"
IDS_WINDOW BINARY "..\\window.html"
IDS_XMLHTTPREQUEST BINARY "..\\xmlhttprequest.html"