mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
- Add download handling support via new CefDownloadHandler and CefDownloadItem interfaces (issue #516).
- Fix setting of CefKeyEvent.focus_on_editable_field when the underlying RenderViewHost changes. - Fix potential crash if URLRequest objects are still in-progress upon shutdown. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@715 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
@ -181,12 +181,14 @@ CefBrowserContext::CefBrowserContext() {
|
||||
}
|
||||
|
||||
CefBrowserContext::~CefBrowserContext() {
|
||||
if (download_manager_.get())
|
||||
download_manager_->Shutdown();
|
||||
// Clear the download manager delegate here because otherwise we'll crash
|
||||
// when it's accessed from the content::BrowserContext destructor.
|
||||
if (download_manager_delegate_.get())
|
||||
BrowserContext::GetDownloadManager(this)->SetDelegate(NULL);
|
||||
|
||||
if (resource_context_.get()) {
|
||||
BrowserThread::DeleteSoon(
|
||||
BrowserThread::IO, FROM_HERE, resource_context_.release());
|
||||
BrowserThread::IO, FROM_HERE, resource_context_.release());
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,6 +202,8 @@ bool CefBrowserContext::IsOffTheRecord() const {
|
||||
|
||||
content::DownloadManagerDelegate*
|
||||
CefBrowserContext::GetDownloadManagerDelegate() {
|
||||
DCHECK(!download_manager_delegate_.get());
|
||||
|
||||
download_manager_delegate_ = new CefDownloadManagerDelegate();
|
||||
return download_manager_delegate_.get();
|
||||
}
|
||||
|
@ -14,11 +14,11 @@
|
||||
|
||||
namespace content {
|
||||
class DownloadManagerDelegate;
|
||||
class ResourceContext;
|
||||
class SpeechRecognitionPreferences;
|
||||
}
|
||||
|
||||
class CefDownloadManagerDelegate;
|
||||
class CefResourceContext;
|
||||
|
||||
class CefBrowserContext : public content::BrowserContext {
|
||||
public:
|
||||
@ -43,9 +43,8 @@ class CefBrowserContext : public content::BrowserContext {
|
||||
|
||||
private:
|
||||
|
||||
scoped_ptr<content::ResourceContext> resource_context_;
|
||||
scoped_ptr<CefResourceContext> resource_context_;
|
||||
scoped_refptr<CefDownloadManagerDelegate> download_manager_delegate_;
|
||||
scoped_refptr<content::DownloadManager> download_manager_;
|
||||
scoped_refptr<net::URLRequestContextGetter> url_request_getter_;
|
||||
scoped_refptr<content::GeolocationPermissionContext>
|
||||
geolocation_permission_context_;
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "libcef/browser/devtools_delegate.h"
|
||||
#include "libcef/browser/navigate_params.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 "libcef/common/cef_messages.h"
|
||||
#include "libcef/common/http_header_utils.h"
|
||||
#include "libcef/common/main_delegate.h"
|
||||
@ -600,7 +602,8 @@ net::URLRequestContextGetter* CefBrowserHostImpl::GetRequestContext() {
|
||||
if (!request_context_proxy_) {
|
||||
request_context_proxy_ =
|
||||
new CefURLRequestContextGetterProxy(this,
|
||||
_Context->browser_context()->GetRequestContext());
|
||||
static_cast<CefURLRequestContextGetter*>(
|
||||
_Context->browser_context()->GetRequestContext()));
|
||||
}
|
||||
return request_context_proxy_.get();
|
||||
}
|
||||
@ -1128,19 +1131,13 @@ void CefBrowserHostImpl::RequestMediaAccessPermission(
|
||||
|
||||
void CefBrowserHostImpl::RenderViewCreated(
|
||||
content::RenderViewHost* render_view_host) {
|
||||
base::AutoLock lock_scope(state_lock_);
|
||||
SetRenderViewHost(render_view_host);
|
||||
}
|
||||
|
||||
render_view_id_ = render_view_host->GetRoutingID();
|
||||
render_process_id_ = render_view_host->GetProcess()->GetID();
|
||||
|
||||
// Update the DevTools URLs, if any.
|
||||
CefDevToolsDelegate* devtools_delegate = _Context->devtools_delegate();
|
||||
if (devtools_delegate) {
|
||||
devtools_url_http_ = devtools_delegate->GetDevToolsURL(render_view_host,
|
||||
true);
|
||||
devtools_url_chrome_ = devtools_delegate->GetDevToolsURL(render_view_host,
|
||||
false);
|
||||
}
|
||||
void CefBrowserHostImpl::RenderViewDeleted(
|
||||
content::RenderViewHost* render_view_host) {
|
||||
registrar_->Remove(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
|
||||
content::Source<content::RenderViewHost>(render_view_host));
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::RenderViewReady() {
|
||||
@ -1368,8 +1365,8 @@ CefBrowserHostImpl::CefBrowserHostImpl(const CefWindowInfo& window_info,
|
||||
settings_(settings),
|
||||
client_(client),
|
||||
opener_(opener),
|
||||
render_process_id_(web_contents->GetRenderProcessHost()->GetID()),
|
||||
render_view_id_(routing_id()),
|
||||
render_process_id_(0),
|
||||
render_view_id_(0),
|
||||
unique_id_(0),
|
||||
received_page_title_(false),
|
||||
is_loading_(false),
|
||||
@ -1387,21 +1384,35 @@ CefBrowserHostImpl::CefBrowserHostImpl(const CefWindowInfo& window_info,
|
||||
registrar_.reset(new content::NotificationRegistrar);
|
||||
registrar_->Add(this, content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
|
||||
content::Source<content::WebContents>(web_contents));
|
||||
registrar_->Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
|
||||
content::Source<content::RenderViewHost>(
|
||||
web_contents->GetRenderViewHost()));
|
||||
|
||||
response_manager_.reset(new CefResponseManager);
|
||||
|
||||
placeholder_frame_ =
|
||||
new CefFrameHostImpl(this, CefFrameHostImpl::kInvalidFrameId, true);
|
||||
|
||||
// Retrieve the DevTools URLs, if any.
|
||||
CefDevToolsDelegate* devtools_delegate = _Context->devtools_delegate();
|
||||
if (devtools_delegate) {
|
||||
devtools_url_http_ = devtools_delegate->GetDevToolsURL(
|
||||
web_contents->GetRenderViewHost(), true);
|
||||
devtools_url_chrome_ = devtools_delegate->GetDevToolsURL(
|
||||
web_contents->GetRenderViewHost(), false);
|
||||
SetRenderViewHost(web_contents->GetRenderViewHost());
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::SetRenderViewHost(content::RenderViewHost* rvh) {
|
||||
{
|
||||
base::AutoLock lock_scope(state_lock_);
|
||||
|
||||
render_view_id_ = rvh->GetRoutingID();
|
||||
render_process_id_ = rvh->GetProcess()->GetID();
|
||||
|
||||
// Update the DevTools URLs, if any.
|
||||
CefDevToolsDelegate* devtools_delegate = _Context->devtools_delegate();
|
||||
if (devtools_delegate) {
|
||||
devtools_url_http_ = devtools_delegate->GetDevToolsURL(rvh, true);
|
||||
devtools_url_chrome_ = devtools_delegate->GetDevToolsURL(rvh, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!registrar_->IsRegistered(
|
||||
this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
|
||||
content::Source<content::RenderViewHost>(rvh))) {
|
||||
registrar_->Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
|
||||
content::Source<content::RenderViewHost>(rvh));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "libcef/browser/frame_host_impl.h"
|
||||
#include "libcef/browser/javascript_dialog_creator.h"
|
||||
#include "libcef/browser/menu_creator.h"
|
||||
#include "libcef/browser/url_request_context_getter_proxy.h"
|
||||
#include "libcef/common/response_manager.h"
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
@ -29,6 +28,7 @@
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
namespace content {
|
||||
struct NativeWebKeyboardEvent;
|
||||
@ -239,8 +239,10 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
const content::MediaResponseCallback& callback) OVERRIDE;
|
||||
|
||||
// content::WebContentsObserver methods.
|
||||
virtual void RenderViewCreated(content::RenderViewHost* render_view_host)
|
||||
OVERRIDE;
|
||||
virtual void RenderViewCreated(
|
||||
content::RenderViewHost* render_view_host) OVERRIDE;
|
||||
virtual void RenderViewDeleted(
|
||||
content::RenderViewHost* render_view_host) OVERRIDE;
|
||||
virtual void RenderViewReady() OVERRIDE;
|
||||
virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
|
||||
virtual void DidCommitProvisionalLoadForFrame(
|
||||
@ -288,6 +290,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
content::WebContents* web_contents,
|
||||
CefWindowHandle opener);
|
||||
|
||||
// Initialize settings based on the specified RenderViewHost.
|
||||
void SetRenderViewHost(content::RenderViewHost* rvh);
|
||||
|
||||
// Updates and returns an existing frame or creates a new frame. Pass
|
||||
// CefFrameHostImpl::kUnspecifiedFrameId for |parent_frame_id| if unknown.
|
||||
CefRefPtr<CefFrame> GetOrCreateFrame(int64 frame_id,
|
||||
@ -404,7 +409,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
scoped_ptr<content::NotificationRegistrar> registrar_;
|
||||
|
||||
// Used for proxying cookie requests.
|
||||
scoped_refptr<CefURLRequestContextGetterProxy> request_context_proxy_;
|
||||
scoped_refptr<net::URLRequestContextGetter> request_context_proxy_;
|
||||
|
||||
// Manages response registrations.
|
||||
scoped_ptr<CefResponseManager> response_manager_;
|
||||
|
@ -54,18 +54,19 @@ void CefBrowserMainParts::PreMainMessageLoopStart() {
|
||||
}
|
||||
|
||||
int CefBrowserMainParts::PreCreateThreads() {
|
||||
PlatformInitialize();
|
||||
net::NetModule::SetResourceProvider(&ResourceProvider);
|
||||
|
||||
// Initialize the GpuDataManager before IO access restrictions are applied and
|
||||
// before the IO thread is started.
|
||||
content::GpuDataManager::GetInstance();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CefBrowserMainParts::PreMainMessageLoopRun() {
|
||||
browser_context_.reset(new CefBrowserContext());
|
||||
|
||||
PlatformInitialize();
|
||||
net::NetModule::SetResourceProvider(&ResourceProvider);
|
||||
|
||||
// Initialize the GpuDataManager before IO access restrictions are applied.
|
||||
content::GpuDataManager::GetInstance();
|
||||
|
||||
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
|
||||
if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
|
||||
std::string port_str =
|
||||
@ -82,13 +83,11 @@ void CefBrowserMainParts::PreMainMessageLoopRun() {
|
||||
}
|
||||
|
||||
void CefBrowserMainParts::PostMainMessageLoopRun() {
|
||||
PlatformCleanup();
|
||||
|
||||
if (devtools_delegate_)
|
||||
devtools_delegate_->Stop();
|
||||
browser_context_.reset();
|
||||
}
|
||||
|
||||
bool CefBrowserMainParts::MainMessageLoopRun(int* result_code) {
|
||||
return false;
|
||||
void CefBrowserMainParts::PostDestroyThreads() {
|
||||
PlatformCleanup();
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ class CefBrowserMainParts : public content::BrowserMainParts {
|
||||
virtual void PreMainMessageLoopStart() OVERRIDE;
|
||||
virtual int PreCreateThreads() OVERRIDE;
|
||||
virtual void PreMainMessageLoopRun() OVERRIDE;
|
||||
virtual bool MainMessageLoopRun(int* result_code) OVERRIDE;
|
||||
virtual void PostMainMessageLoopRun() OVERRIDE;
|
||||
virtual void PostDestroyThreads() OVERRIDE;
|
||||
|
||||
CefBrowserContext* browser_context() const { return browser_context_.get(); }
|
||||
CefDevToolsDelegate* devtools_delegate() const { return devtools_delegate_; }
|
||||
|
107
libcef/browser/download_item_impl.cc
Normal file
107
libcef/browser/download_item_impl.cc
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright (c) 2012 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/download_item_impl.h"
|
||||
|
||||
#include "libcef/common/time_util.h"
|
||||
|
||||
#include "content/public/browser/download_item.h"
|
||||
#include "googleurl/src/gurl.h"
|
||||
|
||||
|
||||
CefDownloadItemImpl::CefDownloadItemImpl(content::DownloadItem* value)
|
||||
: CefValueBase<CefDownloadItem, content::DownloadItem>(
|
||||
value, NULL, kOwnerNoDelete, true,
|
||||
new CefValueControllerNonThreadSafe()) {
|
||||
// Indicate that this object owns the controller.
|
||||
SetOwnsController();
|
||||
}
|
||||
|
||||
bool CefDownloadItemImpl::IsValid() {
|
||||
return !detached();
|
||||
}
|
||||
|
||||
bool CefDownloadItemImpl::IsInProgress() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, false);
|
||||
return const_value().IsInProgress();
|
||||
}
|
||||
|
||||
bool CefDownloadItemImpl::IsComplete() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, false);
|
||||
return const_value().IsComplete();
|
||||
}
|
||||
|
||||
bool CefDownloadItemImpl::IsCanceled() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, false);
|
||||
return const_value().IsCancelled();
|
||||
}
|
||||
|
||||
int64 CefDownloadItemImpl::GetCurrentSpeed() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, 0);
|
||||
return const_value().CurrentSpeed();
|
||||
}
|
||||
|
||||
int CefDownloadItemImpl::GetPercentComplete() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, -1);
|
||||
return const_value().PercentComplete();
|
||||
}
|
||||
|
||||
int64 CefDownloadItemImpl::GetTotalBytes() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, 0);
|
||||
return const_value().GetTotalBytes();
|
||||
}
|
||||
|
||||
int64 CefDownloadItemImpl::GetReceivedBytes() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, 0);
|
||||
return const_value().GetReceivedBytes();
|
||||
}
|
||||
|
||||
CefTime CefDownloadItemImpl::GetStartTime() {
|
||||
CefTime time;
|
||||
CEF_VALUE_VERIFY_RETURN(false, time);
|
||||
cef_time_from_basetime(const_value().GetStartTime(), time);
|
||||
return time;
|
||||
}
|
||||
|
||||
CefTime CefDownloadItemImpl::GetEndTime() {
|
||||
CefTime time;
|
||||
CEF_VALUE_VERIFY_RETURN(false, time);
|
||||
cef_time_from_basetime(const_value().GetEndTime(), time);
|
||||
return time;
|
||||
}
|
||||
|
||||
CefString CefDownloadItemImpl::GetFullPath() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, CefString());
|
||||
return const_value().GetFullPath().value();
|
||||
}
|
||||
|
||||
int32 CefDownloadItemImpl::GetId() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, 0);
|
||||
return const_value().GetId();
|
||||
}
|
||||
|
||||
CefString CefDownloadItemImpl::GetURL() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, CefString());
|
||||
return const_value().GetURL().spec();
|
||||
}
|
||||
|
||||
CefString CefDownloadItemImpl::GetSuggestedFileName() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, CefString());
|
||||
return const_value().GetSuggestedFilename();
|
||||
}
|
||||
|
||||
CefString CefDownloadItemImpl::GetContentDisposition() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, CefString());
|
||||
return const_value().GetContentDisposition();
|
||||
}
|
||||
|
||||
CefString CefDownloadItemImpl::GetMimeType() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, CefString());
|
||||
return const_value().GetMimeType();
|
||||
}
|
||||
|
||||
CefString CefDownloadItemImpl::GetReferrerCharset() {
|
||||
CEF_VALUE_VERIFY_RETURN(false, CefString());
|
||||
return const_value().GetReferrerCharset();
|
||||
}
|
45
libcef/browser/download_item_impl.h
Normal file
45
libcef/browser/download_item_impl.h
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2012 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_DOWNLOAD_ITEM_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_DOWNLOAD_ITEM_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_download_item.h"
|
||||
#include "libcef/common/value_base.h"
|
||||
|
||||
namespace content {
|
||||
class DownloadItem;
|
||||
}
|
||||
|
||||
// CefDownloadItem implementation
|
||||
class CefDownloadItemImpl
|
||||
: public CefValueBase<CefDownloadItem, content::DownloadItem> {
|
||||
public:
|
||||
explicit CefDownloadItemImpl(content::DownloadItem* value);
|
||||
|
||||
// CefDownloadItem methods.
|
||||
virtual bool IsValid() OVERRIDE;
|
||||
virtual bool IsInProgress() OVERRIDE;
|
||||
virtual bool IsComplete() OVERRIDE;
|
||||
virtual bool IsCanceled() OVERRIDE;
|
||||
virtual int64 GetCurrentSpeed() OVERRIDE;
|
||||
virtual int GetPercentComplete() OVERRIDE;
|
||||
virtual int64 GetTotalBytes() OVERRIDE;
|
||||
virtual int64 GetReceivedBytes() OVERRIDE;
|
||||
virtual CefTime GetStartTime() OVERRIDE;
|
||||
virtual CefTime GetEndTime() OVERRIDE;
|
||||
virtual CefString GetFullPath() OVERRIDE;
|
||||
virtual int32 GetId() OVERRIDE;
|
||||
virtual CefString GetURL() OVERRIDE;
|
||||
virtual CefString GetSuggestedFileName() OVERRIDE;
|
||||
virtual CefString GetContentDisposition() OVERRIDE;
|
||||
virtual CefString GetMimeType() OVERRIDE;
|
||||
virtual CefString GetReferrerCharset() OVERRIDE;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CefDownloadItemImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_DOWNLOAD_ITEM_IMPL_H_
|
@ -4,65 +4,226 @@
|
||||
|
||||
#include "libcef/browser/download_manager_delegate.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h>
|
||||
#include <commdlg.h>
|
||||
#endif
|
||||
#include "include/cef_download_handler.h"
|
||||
#include "libcef/browser/browser_context.h"
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/download_item_impl.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/utf_string_conversions.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "net/base/net_util.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
using content::DownloadItem;
|
||||
using content::DownloadManager;
|
||||
using content::WebContents;
|
||||
|
||||
CefDownloadManagerDelegate::CefDownloadManagerDelegate()
|
||||
: download_manager_(NULL) {
|
||||
|
||||
namespace {
|
||||
|
||||
// Helper function to retrieve the CefBrowserHostImpl.
|
||||
CefRefPtr<CefBrowserHostImpl> GetBrowser(DownloadItem* item) {
|
||||
content::WebContents* contents = item->GetWebContents();
|
||||
if (!contents)
|
||||
return NULL;
|
||||
|
||||
return CefBrowserHostImpl::GetBrowserForContents(contents).get();
|
||||
}
|
||||
|
||||
// Helper function to retrieve the CefDownloadHandler.
|
||||
CefRefPtr<CefDownloadHandler> GetDownloadHandler(
|
||||
CefRefPtr<CefBrowserHostImpl> browser) {
|
||||
CefRefPtr<CefClient> client = browser->GetClient();
|
||||
if (client.get())
|
||||
return client->GetDownloadHandler();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Helper function to retrieve the DownloadManager.
|
||||
scoped_refptr<content::DownloadManager> GetDownloadManager() {
|
||||
return content::BrowserContext::GetDownloadManager(
|
||||
_Context->browser_context());
|
||||
}
|
||||
|
||||
|
||||
// CefBeforeDownloadCallback implementation.
|
||||
class CefBeforeDownloadCallbackImpl : public CefBeforeDownloadCallback {
|
||||
public:
|
||||
CefBeforeDownloadCallbackImpl(int32 download_id,
|
||||
const FilePath& suggested_name)
|
||||
: download_id_(download_id),
|
||||
suggested_name_(suggested_name) {
|
||||
}
|
||||
|
||||
virtual void Continue(const CefString& download_path,
|
||||
bool show_dialog) OVERRIDE {
|
||||
if (CEF_CURRENTLY_ON_UIT()) {
|
||||
if (download_id_ <= 0)
|
||||
return;
|
||||
|
||||
scoped_refptr<content::DownloadManager> manager = GetDownloadManager();
|
||||
if (manager) {
|
||||
FilePath path = FilePath(download_path);
|
||||
CEF_POST_TASK(CEF_FILET,
|
||||
base::Bind(&CefBeforeDownloadCallbackImpl::GenerateFilename,
|
||||
download_id_, suggested_name_, path, show_dialog));
|
||||
}
|
||||
|
||||
download_id_ = 0;
|
||||
} else {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBeforeDownloadCallbackImpl::Continue, this,
|
||||
download_path, show_dialog));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static void GenerateFilename(int32 download_id,
|
||||
const FilePath& suggested_name,
|
||||
const FilePath& download_path,
|
||||
bool show_dialog) {
|
||||
FilePath suggested_path = download_path;
|
||||
if (!suggested_path.empty()) {
|
||||
// Create the directory if necessary.
|
||||
FilePath dir_path = suggested_path.DirName();
|
||||
if (!file_util::DirectoryExists(dir_path) &&
|
||||
!file_util::CreateDirectory(dir_path)) {
|
||||
NOTREACHED() << "failed to create the download directory";
|
||||
suggested_path.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (suggested_path.empty()) {
|
||||
if (PathService::Get(base::DIR_TEMP, &suggested_path)) {
|
||||
// Use the temp directory.
|
||||
suggested_path = suggested_path.Append(suggested_name);
|
||||
} else {
|
||||
// Use the current working directory.
|
||||
suggested_path = suggested_name;
|
||||
}
|
||||
}
|
||||
|
||||
content::DownloadItem::TargetDisposition disposition = show_dialog ?
|
||||
DownloadItem::TARGET_DISPOSITION_PROMPT :
|
||||
DownloadItem::TARGET_DISPOSITION_OVERWRITE;
|
||||
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBeforeDownloadCallbackImpl::RestartDownload,
|
||||
download_id, suggested_path, disposition));
|
||||
}
|
||||
|
||||
static void RestartDownload(int32 download_id,
|
||||
const FilePath& suggested_path,
|
||||
DownloadItem::TargetDisposition disposition) {
|
||||
scoped_refptr<content::DownloadManager> manager = GetDownloadManager();
|
||||
if (!manager)
|
||||
return;
|
||||
|
||||
DownloadItem* item = manager->GetActiveDownloadItem(download_id);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
item->OnTargetPathDetermined(suggested_path,
|
||||
disposition,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
|
||||
manager->RestartDownload(download_id);
|
||||
}
|
||||
|
||||
int32 download_id_;
|
||||
FilePath suggested_name_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CefBeforeDownloadCallbackImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefBeforeDownloadCallbackImpl);
|
||||
};
|
||||
|
||||
|
||||
// CefDownloadItemCallback implementation.
|
||||
class CefDownloadItemCallbackImpl : public CefDownloadItemCallback {
|
||||
public:
|
||||
explicit CefDownloadItemCallbackImpl(int32 download_id)
|
||||
: download_id_(download_id) {
|
||||
}
|
||||
|
||||
virtual void Cancel() OVERRIDE {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefDownloadItemCallbackImpl::DoCancel, this));
|
||||
}
|
||||
|
||||
private:
|
||||
void DoCancel() {
|
||||
if (download_id_ <= 0)
|
||||
return;
|
||||
|
||||
scoped_refptr<content::DownloadManager> manager = GetDownloadManager();
|
||||
if (manager) {
|
||||
content::DownloadItem* item =
|
||||
manager->GetActiveDownloadItem(download_id_);
|
||||
if (item && item->IsInProgress())
|
||||
item->Cancel(true);
|
||||
}
|
||||
|
||||
download_id_ = 0;
|
||||
}
|
||||
|
||||
int32 download_id_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CefDownloadItemCallbackImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefDownloadItemCallbackImpl);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
CefDownloadManagerDelegate::CefDownloadManagerDelegate() {
|
||||
}
|
||||
|
||||
CefDownloadManagerDelegate::~CefDownloadManagerDelegate() {
|
||||
}
|
||||
|
||||
void CefDownloadManagerDelegate::SetDownloadManager(
|
||||
DownloadManager* download_manager) {
|
||||
download_manager_ = download_manager;
|
||||
}
|
||||
|
||||
bool CefDownloadManagerDelegate::ShouldStartDownload(int32 download_id) {
|
||||
DownloadItem* download =
|
||||
download_manager_->GetActiveDownloadItem(download_id);
|
||||
scoped_refptr<content::DownloadManager> manager = GetDownloadManager();
|
||||
DownloadItem* item = manager->GetActiveDownloadItem(download_id);
|
||||
|
||||
if (!download->GetForcedFilePath().empty()) {
|
||||
download->OnTargetPathDetermined(
|
||||
download->GetForcedFilePath(),
|
||||
if (!item->GetForcedFilePath().empty()) {
|
||||
item->OnTargetPathDetermined(
|
||||
item->GetForcedFilePath(),
|
||||
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
|
||||
return true;
|
||||
}
|
||||
|
||||
FilePath generated_name = net::GenerateFileName(
|
||||
download->GetURL(),
|
||||
download->GetContentDisposition(),
|
||||
download->GetReferrerCharset(),
|
||||
download->GetSuggestedFilename(),
|
||||
download->GetMimeType(),
|
||||
"download");
|
||||
CefRefPtr<CefBrowserHostImpl> browser = GetBrowser(item);
|
||||
CefRefPtr<CefDownloadHandler> handler;
|
||||
if (browser.get())
|
||||
handler = GetDownloadHandler(browser);
|
||||
|
||||
if (handler.get()) {
|
||||
FilePath suggested_name = net::GenerateFileName(
|
||||
item->GetURL(),
|
||||
item->GetContentDisposition(),
|
||||
item->GetReferrerCharset(),
|
||||
item->GetSuggestedFilename(),
|
||||
item->GetMimeType(),
|
||||
"download");
|
||||
|
||||
CefRefPtr<CefDownloadItemImpl> download_item(new CefDownloadItemImpl(item));
|
||||
CefRefPtr<CefBeforeDownloadCallback> callback(
|
||||
new CefBeforeDownloadCallbackImpl(download_id, suggested_name));
|
||||
|
||||
handler->OnBeforeDownload(browser.get(), download_item.get(),
|
||||
suggested_name.value(), callback);
|
||||
|
||||
download_item->Detach(NULL);
|
||||
}
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::FILE,
|
||||
FROM_HERE,
|
||||
base::Bind(
|
||||
&CefDownloadManagerDelegate::GenerateFilename,
|
||||
this, download_id, generated_name));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -77,47 +238,35 @@ void CefDownloadManagerDelegate::ChooseDownloadPath(
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
|
||||
scoped_refptr<content::DownloadManager> manager = GetDownloadManager();
|
||||
if (result.empty()) {
|
||||
download_manager_->FileSelectionCanceled(item->GetId());
|
||||
manager->FileSelectionCanceled(item->GetId());
|
||||
} else {
|
||||
download_manager_->FileSelected(result, item->GetId());
|
||||
manager->FileSelected(result, item->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
void CefDownloadManagerDelegate::AddItemToPersistentStore(
|
||||
content::DownloadItem* item) {
|
||||
DownloadItem* item) {
|
||||
static int next_id;
|
||||
download_manager_->OnItemAddedToPersistentStore(item->GetId(), ++next_id);
|
||||
scoped_refptr<content::DownloadManager> manager = GetDownloadManager();
|
||||
manager->OnItemAddedToPersistentStore(item->GetId(), ++next_id);
|
||||
}
|
||||
|
||||
void CefDownloadManagerDelegate::GenerateFilename(
|
||||
int32 download_id,
|
||||
const FilePath& generated_name) {
|
||||
FilePath suggested_path = download_manager_->GetBrowserContext()->GetPath().
|
||||
Append(FILE_PATH_LITERAL("Downloads"));
|
||||
if (!file_util::DirectoryExists(suggested_path))
|
||||
file_util::CreateDirectory(suggested_path);
|
||||
void CefDownloadManagerDelegate::UpdateItemInPersistentStore(
|
||||
DownloadItem* item) {
|
||||
CefRefPtr<CefBrowserHostImpl> browser = GetBrowser(item);
|
||||
CefRefPtr<CefDownloadHandler> handler;
|
||||
if (browser.get())
|
||||
handler = GetDownloadHandler(browser);
|
||||
|
||||
suggested_path = suggested_path.Append(generated_name);
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(
|
||||
&CefDownloadManagerDelegate::RestartDownload,
|
||||
this, download_id, suggested_path));
|
||||
}
|
||||
|
||||
void CefDownloadManagerDelegate::RestartDownload(
|
||||
int32 download_id,
|
||||
const FilePath& suggested_path) {
|
||||
DownloadItem* download =
|
||||
download_manager_->GetActiveDownloadItem(download_id);
|
||||
if (!download)
|
||||
return;
|
||||
|
||||
// Since we have no download UI, show the user a dialog always.
|
||||
download->OnTargetPathDetermined(suggested_path,
|
||||
DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
|
||||
download_manager_->RestartDownload(download_id);
|
||||
if (handler.get()) {
|
||||
CefRefPtr<CefDownloadItemImpl> download_item(new CefDownloadItemImpl(item));
|
||||
CefRefPtr<CefDownloadItemCallback> callback(
|
||||
new CefDownloadItemCallbackImpl(item->GetId()));
|
||||
|
||||
handler->OnDownloadUpdated(browser.get(), download_item.get(), callback);
|
||||
|
||||
download_item->Detach(NULL);
|
||||
}
|
||||
}
|
||||
|
@ -22,28 +22,21 @@ class CefDownloadManagerDelegate
|
||||
public:
|
||||
CefDownloadManagerDelegate();
|
||||
|
||||
void SetDownloadManager(content::DownloadManager* manager);
|
||||
|
||||
// DownloadManagerDelegate methods.
|
||||
virtual bool ShouldStartDownload(int32 download_id) OVERRIDE;
|
||||
virtual void ChooseDownloadPath(content::DownloadItem* item) OVERRIDE;
|
||||
virtual void AddItemToPersistentStore(content::DownloadItem* item) OVERRIDE;
|
||||
virtual void UpdateItemInPersistentStore(
|
||||
content::DownloadItem* item) OVERRIDE;
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<CefDownloadManagerDelegate>;
|
||||
|
||||
virtual ~CefDownloadManagerDelegate();
|
||||
|
||||
void GenerateFilename(int32 download_id,
|
||||
const FilePath& generated_name);
|
||||
void RestartDownload(int32 download_id,
|
||||
const FilePath& suggested_path);
|
||||
|
||||
FilePath PlatformChooseDownloadPath(content::WebContents* web_contents,
|
||||
const FilePath& suggested_path);
|
||||
|
||||
content::DownloadManager* download_manager_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefDownloadManagerDelegate);
|
||||
};
|
||||
|
||||
|
@ -12,6 +12,11 @@ CefResourceContext::CefResourceContext(
|
||||
}
|
||||
|
||||
CefResourceContext::~CefResourceContext() {
|
||||
// Destroy the getter after content::ResourceContext has finished destructing.
|
||||
// Otherwise, the URLRequestContext objects will be deleted before
|
||||
// ResourceDispatcherHost has canceled any pending URLRequests.
|
||||
content::BrowserThread::ReleaseSoon(
|
||||
content::BrowserThread::IO, FROM_HERE, getter_.release());
|
||||
}
|
||||
|
||||
net::HostResolver* CefResourceContext::GetHostResolver() {
|
||||
|
@ -13,10 +13,12 @@
|
||||
#include "libcef/browser/context.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 "base/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/string_split.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "base/threading/worker_pool.h"
|
||||
@ -137,6 +139,7 @@ CefURLRequestContextGetter::CefURLRequestContextGetter(
|
||||
}
|
||||
|
||||
CefURLRequestContextGetter::~CefURLRequestContextGetter() {
|
||||
STLDeleteElements(&url_request_context_proxies_);
|
||||
}
|
||||
|
||||
net::URLRequestContext* CefURLRequestContextGetter::GetURLRequestContext() {
|
||||
@ -353,6 +356,51 @@ 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 (_Context->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() {
|
||||
if (proxy_config_service_.get())
|
||||
return;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -16,6 +17,7 @@
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
class CefRequestInterceptor;
|
||||
class CefURLRequestContextProxy;
|
||||
class MessageLoop;
|
||||
|
||||
namespace net {
|
||||
@ -44,6 +46,12 @@ class CefURLRequestContextGetter : public net::URLRequestContextGetter {
|
||||
void SetCookieStoragePath(const FilePath& path);
|
||||
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);
|
||||
|
||||
private:
|
||||
void CreateProxyConfigService();
|
||||
|
||||
@ -57,6 +65,9 @@ class CefURLRequestContextGetter : public net::URLRequestContextGetter {
|
||||
scoped_ptr<net::URLRequestContext> url_request_context_;
|
||||
scoped_ptr<net::URLSecurityManager> url_security_manager_;
|
||||
|
||||
typedef std::set<CefURLRequestContextProxy*> RequestContextProxySet;
|
||||
RequestContextProxySet url_request_context_proxies_;
|
||||
|
||||
FilePath cookie_store_path_;
|
||||
std::vector<std::string> cookie_supported_schemes_;
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/cookie_manager_impl.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/browser/url_request_context_getter.h"
|
||||
#include "libcef/browser/url_request_context_proxy.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/message_loop_proxy.h"
|
||||
@ -117,69 +119,32 @@ class CefCookieStoreProxy : public net::CookieStore {
|
||||
DISALLOW_COPY_AND_ASSIGN(CefCookieStoreProxy);
|
||||
};
|
||||
|
||||
class CefRequestContextProxy : public net::URLRequestContext {
|
||||
public:
|
||||
CefRequestContextProxy(CefBrowserHostImpl* browser,
|
||||
net::URLRequestContextGetter* parent)
|
||||
: parent_(parent) {
|
||||
net::URLRequestContext* context = parent->GetURLRequestContext();
|
||||
|
||||
// Cookie store that proxies to the browser implementation.
|
||||
cookie_store_proxy_ = new CefCookieStoreProxy(browser, context);
|
||||
set_cookie_store(cookie_store_proxy_);
|
||||
|
||||
// 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_server_bound_cert_service(context->server_bound_cert_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_ftp_transaction_factory(context->ftp_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_accept_charset(context->accept_charset());
|
||||
set_accept_language(context->accept_language());
|
||||
set_referrer_charset(context->referrer_charset());
|
||||
set_job_factory(context->job_factory());
|
||||
}
|
||||
|
||||
virtual const std::string& GetUserAgent(const GURL& url) const OVERRIDE {
|
||||
return parent_->GetURLRequestContext()->GetUserAgent(url);
|
||||
}
|
||||
|
||||
private:
|
||||
net::URLRequestContextGetter* parent_;
|
||||
scoped_refptr<net::CookieStore> cookie_store_proxy_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefRequestContextProxy);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
CefURLRequestContextGetterProxy::CefURLRequestContextGetterProxy(
|
||||
CefBrowserHostImpl* browser,
|
||||
net::URLRequestContextGetter* parent)
|
||||
CefURLRequestContextGetter* parent)
|
||||
: browser_(browser),
|
||||
parent_(parent) {
|
||||
parent_(parent),
|
||||
context_proxy_(NULL) {
|
||||
DCHECK(browser);
|
||||
DCHECK(parent);
|
||||
}
|
||||
|
||||
CefURLRequestContextGetterProxy::~CefURLRequestContextGetterProxy() {
|
||||
if (context_proxy_)
|
||||
parent_->ReleaseURLRequestContextProxy(context_proxy_);
|
||||
}
|
||||
|
||||
net::URLRequestContext*
|
||||
CefURLRequestContextGetterProxy::GetURLRequestContext() {
|
||||
CEF_REQUIRE_IOT();
|
||||
if (!context_proxy_.get()) {
|
||||
context_proxy_.reset(
|
||||
new CefRequestContextProxy(browser_, parent_));
|
||||
if (!context_proxy_) {
|
||||
context_proxy_ = parent_->CreateURLRequestContextProxy();
|
||||
context_proxy_->Initialize(browser_);
|
||||
}
|
||||
return context_proxy_.get();
|
||||
return context_proxy_;
|
||||
}
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner>
|
||||
|
@ -10,11 +10,14 @@
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
class CefBrowserHostImpl;
|
||||
class CefURLRequestContextGetter;
|
||||
class CefURLRequestContextProxy;
|
||||
|
||||
class CefURLRequestContextGetterProxy : public net::URLRequestContextGetter {
|
||||
public:
|
||||
CefURLRequestContextGetterProxy(CefBrowserHostImpl* browser,
|
||||
net::URLRequestContextGetter* parent);
|
||||
CefURLRequestContextGetter* parent);
|
||||
virtual ~CefURLRequestContextGetterProxy();
|
||||
|
||||
// net::URLRequestContextGetter implementation.
|
||||
virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
|
||||
@ -23,8 +26,10 @@ class CefURLRequestContextGetterProxy : public net::URLRequestContextGetter {
|
||||
|
||||
private:
|
||||
CefBrowserHostImpl* browser_;
|
||||
scoped_refptr<net::URLRequestContextGetter> parent_;
|
||||
scoped_ptr<net::URLRequestContext> context_proxy_;
|
||||
scoped_refptr<CefURLRequestContextGetter> parent_;
|
||||
|
||||
// The |context_proxy_| object is owned by |parent_|.
|
||||
CefURLRequestContextProxy* context_proxy_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextGetterProxy);
|
||||
};
|
||||
|
164
libcef/browser/url_request_context_proxy.cc
Normal file
164
libcef/browser/url_request_context_proxy.cc
Normal file
@ -0,0 +1,164 @@
|
||||
// Copyright (c) 2012 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/url_request_context_proxy.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/cookie_manager_impl.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/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:
|
||||
explicit CefCookieStoreProxy(CefBrowserHostImpl* browser,
|
||||
net::URLRequestContext* parent)
|
||||
: parent_(parent),
|
||||
browser_(browser) {
|
||||
}
|
||||
|
||||
// net::CookieStore methods.
|
||||
virtual 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);
|
||||
}
|
||||
|
||||
virtual 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 GetCookiesWithInfoAsync(
|
||||
const GURL& url,
|
||||
const net::CookieOptions& options,
|
||||
const GetCookieInfoCallback& callback) OVERRIDE {
|
||||
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
|
||||
cookie_store->GetCookiesWithInfoAsync(url, options, callback);
|
||||
}
|
||||
|
||||
virtual 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);
|
||||
}
|
||||
|
||||
virtual 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);
|
||||
}
|
||||
|
||||
virtual void DeleteSessionCookiesAsync(const DeleteCallback& callback)
|
||||
OVERRIDE {
|
||||
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
|
||||
cookie_store->DeleteSessionCookiesAsync(callback);
|
||||
}
|
||||
|
||||
virtual net::CookieMonster* GetCookieMonster() OVERRIDE {
|
||||
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
|
||||
return cookie_store->GetCookieMonster();
|
||||
}
|
||||
|
||||
private:
|
||||
net::CookieStore* GetCookieStore() {
|
||||
CEF_REQUIRE_IOT();
|
||||
|
||||
scoped_refptr<net::CookieStore> cookie_store;
|
||||
|
||||
CefRefPtr<CefClient> client = browser_->GetClient();
|
||||
if (client.get()) {
|
||||
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
|
||||
if (handler.get()) {
|
||||
// Get the manager from the handler.
|
||||
CefRefPtr<CefCookieManager> manager =
|
||||
handler->GetCookieManager(browser_,
|
||||
browser_->GetLoadingURL().spec());
|
||||
if (manager.get()) {
|
||||
cookie_store =
|
||||
reinterpret_cast<CefCookieManagerImpl*>(
|
||||
manager.get())->cookie_monster();
|
||||
DCHECK(cookie_store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cookie_store) {
|
||||
// Use the global cookie store.
|
||||
cookie_store = parent_->cookie_store();
|
||||
}
|
||||
|
||||
DCHECK(cookie_store);
|
||||
return cookie_store;
|
||||
}
|
||||
|
||||
// This pointer is guaranteed by the CefRequestContextProxy object.
|
||||
net::URLRequestContext* parent_;
|
||||
CefBrowserHostImpl* browser_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefCookieStoreProxy);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
CefURLRequestContextProxy::CefURLRequestContextProxy(
|
||||
net::URLRequestContextGetter* parent)
|
||||
: parent_(parent),
|
||||
delete_try_count_(0) {
|
||||
}
|
||||
|
||||
CefURLRequestContextProxy::~CefURLRequestContextProxy() {
|
||||
}
|
||||
|
||||
const std::string& CefURLRequestContextProxy::GetUserAgent(const GURL& url) const {
|
||||
return parent_->GetURLRequestContext()->GetUserAgent(url);
|
||||
}
|
||||
|
||||
void CefURLRequestContextProxy::Initialize(CefBrowserHostImpl* browser) {
|
||||
CEF_REQUIRE_IOT();
|
||||
|
||||
net::URLRequestContext* context = parent_->GetURLRequestContext();
|
||||
|
||||
// Cookie store that proxies to the browser implementation.
|
||||
cookie_store_proxy_ = new CefCookieStoreProxy(browser, context);
|
||||
set_cookie_store(cookie_store_proxy_);
|
||||
|
||||
// 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_server_bound_cert_service(context->server_bound_cert_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_ftp_transaction_factory(context->ftp_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_accept_charset(context->accept_charset());
|
||||
set_accept_language(context->accept_language());
|
||||
set_referrer_charset(context->referrer_charset());
|
||||
set_job_factory(context->job_factory());
|
||||
}
|
43
libcef/browser/url_request_context_proxy.h
Normal file
43
libcef/browser/url_request_context_proxy.h
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2012 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_PROXY_H_
|
||||
#define CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_PROXY_H_
|
||||
#pragma once
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
|
||||
class CefBrowserHostImpl;
|
||||
|
||||
namespace net {
|
||||
class CookieStore;
|
||||
class URLRequestContextGetter;
|
||||
}
|
||||
|
||||
class CefURLRequestContextProxy : public net::URLRequestContext {
|
||||
public:
|
||||
explicit CefURLRequestContextProxy(net::URLRequestContextGetter* parent);
|
||||
virtual ~CefURLRequestContextProxy();
|
||||
|
||||
virtual const std::string& GetUserAgent(const GURL& url) const OVERRIDE;
|
||||
|
||||
void Initialize(CefBrowserHostImpl* browser);
|
||||
|
||||
// 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_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextProxy);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_PROXY_H_
|
Reference in New Issue
Block a user