Remove the old network implementation (see issue #2622)

The `--disable-features=NetworkService` flag is no longer supported.
This commit is contained in:
Marshall Greenblatt
2019-07-29 17:27:12 -04:00
parent ccb06ce3cb
commit 67b61c4af9
76 changed files with 296 additions and 6113 deletions

View File

@@ -1,497 +0,0 @@
// 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/net/browser_urlrequest_old_impl.h"
#include <string>
#include <utility>
#include "libcef/browser/browser_context.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/net/url_request_user_data.h"
#include "libcef/browser/request_context_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/response_impl.h"
#include "libcef/common/task_runner_impl.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_fetcher_response_writer.h"
#include "net/url_request/url_request_status.h"
using content::BrowserThread;
namespace {
class CefURLFetcherDelegate : public net::URLFetcherDelegate {
public:
CefURLFetcherDelegate(CefBrowserURLRequestOld::Context* context,
int request_flags);
~CefURLFetcherDelegate() override;
// net::URLFetcherDelegate methods.
void OnURLFetchComplete(const net::URLFetcher* source) override;
void OnURLFetchDownloadProgress(const net::URLFetcher* source,
int64 current,
int64 total,
int64_t current_network_bytes) override;
void OnURLFetchUploadProgress(const net::URLFetcher* source,
int64 current,
int64 total) override;
private:
// The context_ pointer will outlive this object.
CefBrowserURLRequestOld::Context* context_;
int request_flags_;
};
class CefURLFetcherResponseWriter : public net::URLFetcherResponseWriter {
public:
CefURLFetcherResponseWriter(
CefRefPtr<CefBrowserURLRequestOld> url_request,
scoped_refptr<base::SequencedTaskRunner> task_runner)
: url_request_(url_request), task_runner_(task_runner) {}
// net::URLFetcherResponseWriter methods.
int Initialize(net::CompletionOnceCallback callback) override {
return net::OK;
}
int Write(net::IOBuffer* buffer,
int num_bytes,
net::CompletionOnceCallback callback) override {
if (url_request_.get()) {
task_runner_->PostTask(
FROM_HERE,
base::Bind(&CefURLFetcherResponseWriter::WriteOnClientThread,
url_request_, scoped_refptr<net::IOBuffer>(buffer),
num_bytes, base::Passed(std::move(callback)),
CefTaskRunnerImpl::GetCurrentTaskRunner()));
return net::ERR_IO_PENDING;
}
return num_bytes;
}
int Finish(int net_error, net::CompletionOnceCallback callback) override {
if (url_request_.get())
url_request_ = NULL;
return net::OK;
}
private:
static void WriteOnClientThread(
CefRefPtr<CefBrowserURLRequestOld> url_request,
scoped_refptr<net::IOBuffer> buffer,
int num_bytes,
net::CompletionOnceCallback callback,
scoped_refptr<base::SequencedTaskRunner> source_message_loop_proxy) {
CefRefPtr<CefURLRequestClient> client = url_request->GetClient();
if (client.get())
client->OnDownloadData(url_request.get(), buffer->data(), num_bytes);
source_message_loop_proxy->PostTask(
FROM_HERE,
base::Bind(&CefURLFetcherResponseWriter::ContinueOnSourceThread,
num_bytes, base::Passed(std::move(callback))));
}
static void ContinueOnSourceThread(int num_bytes,
net::CompletionOnceCallback callback) {
std::move(callback).Run(num_bytes);
}
CefRefPtr<CefBrowserURLRequestOld> url_request_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
DISALLOW_COPY_AND_ASSIGN(CefURLFetcherResponseWriter);
};
std::unique_ptr<base::SupportsUserData::Data> CreateURLRequestUserData(
CefRefPtr<CefURLRequestClient> client) {
return base::WrapUnique(new CefURLRequestUserData(client));
}
} // namespace
// CefBrowserURLRequestOld::Context
// ----------------------------------------------
class CefBrowserURLRequestOld::Context
: public base::RefCountedThreadSafe<CefBrowserURLRequestOld::Context> {
public:
Context(CefRefPtr<CefBrowserURLRequestOld> url_request,
CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client,
CefRefPtr<CefRequestContext> request_context)
: url_request_(url_request),
request_(request),
client_(client),
request_context_(request_context),
task_runner_(CefTaskRunnerImpl::GetCurrentTaskRunner()),
status_(UR_IO_PENDING),
error_code_(ERR_NONE),
response_was_cached_(false),
upload_data_size_(0),
got_upload_progress_complete_(false) {
// Mark the request as read-only.
static_cast<CefRequestImpl*>(request_.get())->SetReadOnly(true);
}
inline bool CalledOnValidThread() {
return task_runner_->RunsTasksInCurrentSequence();
}
bool Start() {
DCHECK(CalledOnValidThread());
const GURL& url = GURL(request_->GetURL().ToString());
if (!url.is_valid())
return false;
const std::string& method =
base::ToLowerASCII(request_->GetMethod().ToString());
net::URLFetcher::RequestType request_type = net::URLFetcher::GET;
if (base::LowerCaseEqualsASCII(method, "get")) {
} else if (base::LowerCaseEqualsASCII(method, "post")) {
request_type = net::URLFetcher::POST;
} else if (base::LowerCaseEqualsASCII(method, "head")) {
request_type = net::URLFetcher::HEAD;
} else if (base::LowerCaseEqualsASCII(method, "delete")) {
request_type = net::URLFetcher::DELETE_REQUEST;
} else if (base::LowerCaseEqualsASCII(method, "put")) {
request_type = net::URLFetcher::PUT;
} else {
NOTREACHED() << "invalid request type";
return false;
}
base::PostTaskWithTraitsAndReply(
FROM_HERE, {BrowserThread::UI},
base::Bind(
&CefBrowserURLRequestOld::Context::GetRequestContextOnUIThread,
this),
base::Bind(
&CefBrowserURLRequestOld::Context::ContinueOnOriginatingThread,
this, url, request_type));
return true;
}
void GetRequestContextOnUIThread() {
CEF_REQUIRE_UIT();
// Get or create the request context and browser context.
CefRefPtr<CefRequestContextImpl> request_context_impl =
CefRequestContextImpl::GetOrCreateForRequestContext(request_context_);
DCHECK(request_context_impl.get());
CefBrowserContext* browser_context =
request_context_impl->GetBrowserContext();
DCHECK(browser_context);
if (!request_context_.get())
request_context_ = request_context_impl.get();
// The request context is created on the UI thread but accessed and
// destroyed on the IO thread.
url_request_getter_ = browser_context->GetRequestContext();
}
void ContinueOnOriginatingThread(const GURL& url,
net::URLFetcher::RequestType request_type) {
DCHECK(CalledOnValidThread());
int request_flags = request_->GetFlags();
fetcher_delegate_.reset(new CefURLFetcherDelegate(this, request_flags));
fetcher_ =
net::URLFetcher::Create(url, request_type, fetcher_delegate_.get());
DCHECK(url_request_getter_.get());
fetcher_->SetRequestContext(url_request_getter_.get());
static_cast<CefRequestImpl*>(request_.get())
->Get(*fetcher_, upload_data_size_);
fetcher_->SetURLRequestUserData(
CefURLRequestUserData::kUserDataKey,
base::Bind(&CreateURLRequestUserData, client_));
std::unique_ptr<net::URLFetcherResponseWriter> response_writer;
if (request_flags & UR_FLAG_NO_DOWNLOAD_DATA) {
response_writer.reset(new CefURLFetcherResponseWriter(NULL, NULL));
} else {
response_writer.reset(
new CefURLFetcherResponseWriter(url_request_, task_runner_));
}
fetcher_->SaveResponseWithWriter(std::move(response_writer));
fetcher_->Start();
}
void Cancel() {
DCHECK(CalledOnValidThread());
// The request may already be complete.
if (!fetcher_.get())
return;
// Cancel the fetch by deleting the fetcher.
fetcher_.reset(NULL);
status_ = UR_CANCELED;
error_code_ = ERR_ABORTED;
OnComplete();
}
void OnComplete() {
DCHECK(CalledOnValidThread());
if (fetcher_.get()) {
const net::URLRequestStatus& status = fetcher_->GetStatus();
if (status.is_success())
NotifyUploadProgressIfNecessary();
switch (status.status()) {
case net::URLRequestStatus::SUCCESS:
status_ = UR_SUCCESS;
break;
case net::URLRequestStatus::IO_PENDING:
status_ = UR_IO_PENDING;
break;
case net::URLRequestStatus::CANCELED:
status_ = UR_CANCELED;
break;
case net::URLRequestStatus::FAILED:
status_ = UR_FAILED;
break;
}
error_code_ = static_cast<CefURLRequest::ErrorCode>(status.error());
if (!response_.get())
OnResponse();
}
DCHECK(url_request_.get());
client_->OnRequestComplete(url_request_.get());
if (fetcher_.get())
fetcher_.reset(NULL);
// This may result in the Context object being deleted.
url_request_ = NULL;
}
void OnDownloadProgress(int64 current, int64 total) {
DCHECK(CalledOnValidThread());
DCHECK(url_request_.get());
if (!response_.get())
OnResponse();
NotifyUploadProgressIfNecessary();
client_->OnDownloadProgress(url_request_.get(), current, total);
}
void OnDownloadData(std::unique_ptr<std::string> download_data) {
DCHECK(CalledOnValidThread());
DCHECK(url_request_.get());
if (!response_.get())
OnResponse();
client_->OnDownloadData(url_request_.get(), download_data->c_str(),
download_data->length());
}
void OnUploadProgress(int64 current, int64 total) {
DCHECK(CalledOnValidThread());
DCHECK(url_request_.get());
if (current == total)
got_upload_progress_complete_ = true;
client_->OnUploadProgress(url_request_.get(), current, total);
}
CefRefPtr<CefRequest> request() const { return request_; }
CefRefPtr<CefURLRequestClient> client() const { return client_; }
CefURLRequest::Status status() const { return status_; }
CefURLRequest::ErrorCode error_code() const { return error_code_; }
CefRefPtr<CefResponse> response() const { return response_; }
bool response_was_cached() const { return response_was_cached_; }
private:
friend class base::RefCountedThreadSafe<CefBrowserURLRequestOld::Context>;
~Context() {
if (fetcher_.get()) {
// Delete the fetcher object on the thread that created it.
task_runner_->DeleteSoon(FROM_HERE, fetcher_.release());
}
}
void NotifyUploadProgressIfNecessary() {
if (!got_upload_progress_complete_ && upload_data_size_ > 0) {
// URLFetcher sends upload notifications using a timer and will not send
// a notification if the request completes too quickly. We therefore
// send the notification here if necessary.
client_->OnUploadProgress(url_request_.get(), upload_data_size_,
upload_data_size_);
got_upload_progress_complete_ = true;
}
}
void OnResponse() {
if (fetcher_.get()) {
response_was_cached_ = fetcher_->WasCached();
response_ = new CefResponseImpl();
CefResponseImpl* responseImpl =
static_cast<CefResponseImpl*>(response_.get());
responseImpl->SetURL(fetcher_->GetURL().spec());
responseImpl->SetStatus(fetcher_->GetResponseCode());
net::HttpResponseHeaders* headers = fetcher_->GetResponseHeaders();
if (headers)
responseImpl->SetResponseHeaders(*headers);
responseImpl->SetReadOnly(true);
}
}
// Members only accessed on the initialization thread.
CefRefPtr<CefBrowserURLRequestOld> url_request_;
CefRefPtr<CefRequest> request_;
CefRefPtr<CefURLRequestClient> client_;
CefRefPtr<CefRequestContext> request_context_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
std::unique_ptr<net::URLFetcher> fetcher_;
std::unique_ptr<CefURLFetcherDelegate> fetcher_delegate_;
CefURLRequest::Status status_;
CefURLRequest::ErrorCode error_code_;
CefRefPtr<CefResponse> response_;
bool response_was_cached_;
int64 upload_data_size_;
bool got_upload_progress_complete_;
scoped_refptr<net::URLRequestContextGetter> url_request_getter_;
};
// CefURLFetcherDelegate ------------------------------------------------------
namespace {
CefURLFetcherDelegate::CefURLFetcherDelegate(
CefBrowserURLRequestOld::Context* context,
int request_flags)
: context_(context), request_flags_(request_flags) {}
CefURLFetcherDelegate::~CefURLFetcherDelegate() {}
void CefURLFetcherDelegate::OnURLFetchComplete(const net::URLFetcher* source) {
// Complete asynchronously so as not to delete the URLFetcher while it's still
// in the call stack.
CefTaskRunnerImpl::GetCurrentTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&CefBrowserURLRequestOld::Context::OnComplete, context_));
}
void CefURLFetcherDelegate::OnURLFetchDownloadProgress(
const net::URLFetcher* source,
int64 current,
int64 total,
int64_t current_network_bytes) {
context_->OnDownloadProgress(current, total);
}
void CefURLFetcherDelegate::OnURLFetchUploadProgress(
const net::URLFetcher* source,
int64 current,
int64 total) {
if (request_flags_ & UR_FLAG_REPORT_UPLOAD_PROGRESS)
context_->OnUploadProgress(current, total);
}
} // namespace
// CefBrowserURLRequestOld
// -------------------------------------------------------
CefBrowserURLRequestOld::CefBrowserURLRequestOld(
CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client,
CefRefPtr<CefRequestContext> request_context) {
context_ = new Context(this, request, client, request_context);
}
CefBrowserURLRequestOld::~CefBrowserURLRequestOld() {}
bool CefBrowserURLRequestOld::Start() {
if (!VerifyContext())
return false;
return context_->Start();
}
CefRefPtr<CefRequest> CefBrowserURLRequestOld::GetRequest() {
if (!VerifyContext())
return NULL;
return context_->request();
}
CefRefPtr<CefURLRequestClient> CefBrowserURLRequestOld::GetClient() {
if (!VerifyContext())
return NULL;
return context_->client();
}
CefURLRequest::Status CefBrowserURLRequestOld::GetRequestStatus() {
if (!VerifyContext())
return UR_UNKNOWN;
return context_->status();
}
CefURLRequest::ErrorCode CefBrowserURLRequestOld::GetRequestError() {
if (!VerifyContext())
return ERR_NONE;
return context_->error_code();
}
CefRefPtr<CefResponse> CefBrowserURLRequestOld::GetResponse() {
if (!VerifyContext())
return NULL;
return context_->response();
}
bool CefBrowserURLRequestOld::ResponseWasCached() {
if (!VerifyContext())
return false;
return context_->response_was_cached();
}
void CefBrowserURLRequestOld::Cancel() {
if (!VerifyContext())
return;
return context_->Cancel();
}
bool CefBrowserURLRequestOld::VerifyContext() {
DCHECK(context_.get());
if (!context_->CalledOnValidThread()) {
NOTREACHED() << "called on invalid thread";
return false;
}
return true;
}

View File

@@ -1,40 +0,0 @@
// 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_NET_BROWSER_URLREQUEST_OLD_IMPL_H_
#define CEF_LIBCEF_BROWSER_NET_BROWSER_URLREQUEST_OLD_IMPL_H_
#include "include/cef_urlrequest.h"
#include "base/memory/ref_counted.h"
class CefBrowserURLRequestOld : public CefURLRequest {
public:
class Context;
CefBrowserURLRequestOld(CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client,
CefRefPtr<CefRequestContext> request_context);
~CefBrowserURLRequestOld() override;
bool Start();
// CefURLRequest methods.
CefRefPtr<CefRequest> GetRequest() override;
CefRefPtr<CefURLRequestClient> GetClient() override;
Status GetRequestStatus() override;
ErrorCode GetRequestError() override;
CefRefPtr<CefResponse> GetResponse() override;
bool ResponseWasCached() override;
void Cancel() override;
private:
bool VerifyContext();
scoped_refptr<Context> context_;
IMPLEMENT_REFCOUNTING(CefBrowserURLRequestOld);
};
#endif // CEF_LIBCEF_BROWSER_NET_BROWSER_URLREQUEST_OLD_IMPL_H_

View File

@@ -16,7 +16,6 @@
#include "libcef/browser/extensions/chrome_api_registration.h"
#include "libcef/browser/frame_host_impl.h"
#include "libcef/browser/net/internal_scheme_handler.h"
#include "libcef/browser/net/url_request_manager.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/content_client.h"
@@ -43,7 +42,6 @@
#include "content/public/common/url_utils.h"
#include "content/public/common/user_agent.h"
#include "ipc/ipc_channel.h"
#include "net/url_request/url_request.h"
#include "v8/include/v8.h"
using extensions::api::cef::kSupportedAPIs;
@@ -171,31 +169,6 @@ const char* kAllowedDebugURLs[] = {
content::kChromeUIBrowserCrashURL,
};
// Returns true for debug URLs that receive special handling (for crashes, etc).
bool IsDebugURL(const GURL& url) {
// URLs handled by the renderer process in
// content/renderer/render_frame_impl.cc MaybeHandleDebugURL().
if (content::IsRendererDebugURL(url))
return true;
// Also include URLs handled by the browser process in
// content/browser/frame_host/debug_urls.cc HandleDebugURL().
for (size_t i = 0; i < chrome::kNumberOfChromeDebugURLs; ++i) {
GURL host(chrome::kChromeDebugURLs[i]);
if (url.GetOrigin() == host.GetOrigin())
return true;
}
for (size_t i = 0;
i < sizeof(kAllowedDebugURLs) / sizeof(kAllowedDebugURLs[0]); ++i) {
GURL host(kAllowedDebugURLs[i]);
if (url.GetOrigin() == host.GetOrigin())
return true;
}
return false;
}
void GetDebugURLs(std::vector<std::string>* urls) {
for (size_t i = 0; i < chrome::kNumberOfChromeDebugURLs; ++i) {
urls->push_back(chrome::kChromeDebugURLs[i]);
@@ -791,43 +764,6 @@ void DidFinishChromeVersionLoad(CefRefPtr<CefFrame> frame) {
CefVisitWebPluginInfo(new Visitor(frame));
}
// Wrapper for a ChromeProtocolHandler instance from
// content/browser/webui/url_data_manager_backend.cc.
class ChromeProtocolHandlerWrapper
: public net::URLRequestJobFactory::ProtocolHandler {
public:
ChromeProtocolHandlerWrapper(
CefURLRequestManager* request_manager,
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>
chrome_protocol_handler)
: request_manager_(request_manager),
chrome_protocol_handler_(std::move(chrome_protocol_handler)) {
DCHECK(request_manager_);
}
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
// Don't handle debug URLs.
if (IsDebugURL(request->url()))
return nullptr;
// Only allow WebUI to handle chrome:// URLs whitelisted by CEF.
if (CefWebUIControllerFactory::AllowWebUIForURL(request->url())) {
return chrome_protocol_handler_->MaybeCreateJob(request,
network_delegate);
}
// Use the protocol handler registered with CEF.
return request_manager_->GetRequestJob(request, network_delegate);
}
private:
CefURLRequestManager* request_manager_;
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>
chrome_protocol_handler_;
};
} // namespace
void RegisterWebUIControllerFactory() {
@@ -858,15 +794,4 @@ bool IsWebUIAllowedToMakeNetworkRequests(const url::Origin& origin) {
return CefWebUIControllerFactory::IsWebUIAllowedToMakeNetworkRequests(origin);
}
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>
WrapChromeProtocolHandler(
CefURLRequestManager* request_manager,
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>
chrome_protocol_handler) {
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler> ret(
new ChromeProtocolHandlerWrapper(request_manager,
std::move(chrome_protocol_handler)));
return ret;
}
} // namespace scheme

View File

@@ -12,7 +12,6 @@
#include "include/cef_frame.h"
#include "include/cef_process_message.h"
#include "net/url_request/url_request_job_factory.h"
#include "url/gurl.h"
namespace base {
@@ -27,8 +26,6 @@ namespace url {
class Origin;
}
class CefURLRequestManager;
namespace scheme {
extern const char kChromeURL[];
@@ -45,14 +42,6 @@ void DidFinishChromeLoad(CefRefPtr<CefFrame> frame, const GURL& validated_url);
// Returns true if WebUI is allowed to make network requests.
bool IsWebUIAllowedToMakeNetworkRequests(const url::Origin& origin);
// Create a new ProtocolHandler that will filter the URLs passed to the default
// "chrome" protocol handler and forward the rest to CEF's handler.
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>
WrapChromeProtocolHandler(
CefURLRequestManager* request_manager,
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>
chrome_protocol_handler);
} // namespace scheme
#endif // CEF_LIBCEF_BROWSER_CHROME_SCHEME_HANDLER_H_

View File

@@ -1,475 +0,0 @@
// 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/net/cookie_manager_old_impl.h"
#include <set>
#include <string>
#include <vector>
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/net/network_delegate.h"
#include "libcef/common/net_service/net_service_util.h"
#include "libcef/common/task_runner_impl.h"
#include "libcef/common/time_util.h"
#include "base/bind.h"
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/browser_process.h"
#include "components/net_log/chrome_net_log.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "net/url_request/url_request_context.h"
#include "url/gurl.h"
using content::BrowserThread;
namespace {
// Callback class for visiting cookies.
class VisitCookiesCallback
: public base::RefCountedThreadSafe<VisitCookiesCallback> {
public:
explicit VisitCookiesCallback(
const CefCookieManagerOldImpl::CookieStoreGetter& cookie_store_getter,
CefRefPtr<CefCookieVisitor> visitor)
: cookie_store_getter_(cookie_store_getter), visitor_(visitor) {}
void Run(const net::CookieList& list,
const net::CookieStatusList& excluded_list) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::Bind(&VisitCookiesCallback::Run, this, list,
excluded_list));
return;
}
int total = list.size(), count = 0;
net::CookieList::const_iterator it = list.begin();
for (; it != list.end(); ++it, ++count) {
CefCookie cookie;
const net::CanonicalCookie& cc = *(it);
net_service::MakeCefCookie(cc, cookie);
bool deleteCookie = false;
bool keepLooping = visitor_->Visit(cookie, count, total, deleteCookie);
if (deleteCookie) {
CEF_POST_TASK(
CEF_IOT,
base::Bind(&VisitCookiesCallback::DeleteOnIOThread, this, cc));
}
if (!keepLooping)
break;
}
}
private:
friend class base::RefCountedThreadSafe<VisitCookiesCallback>;
~VisitCookiesCallback() {}
void DeleteOnIOThread(const net::CanonicalCookie& cc) {
net::CookieStore* cookie_store = cookie_store_getter_.Run();
if (cookie_store) {
cookie_store->DeleteCanonicalCookieAsync(
cc, net::CookieMonster::DeleteCallback());
}
}
CefCookieManagerOldImpl::CookieStoreGetter cookie_store_getter_;
CefRefPtr<CefCookieVisitor> visitor_;
};
// Always execute the callback asynchronously.
void RunAsyncCompletionOnUIThread(CefRefPtr<CefCompletionCallback> callback) {
if (!callback.get())
return;
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefCompletionCallback::OnComplete, callback.get()));
}
// Always execute the callback asynchronously.
void DeleteCookiesCallbackImpl(CefRefPtr<CefDeleteCookiesCallback> callback,
uint32_t num_deleted) {
if (!callback.get())
return;
CEF_POST_TASK(CEF_UIT, base::Bind(&CefDeleteCookiesCallback::OnComplete,
callback.get(), num_deleted));
}
// Always execute the callback asynchronously.
void SetCookieCallbackImpl(CefRefPtr<CefSetCookieCallback> callback,
net::CanonicalCookie::CookieInclusionStatus status) {
if (!callback.get())
return;
CEF_POST_TASK(
CEF_UIT,
base::Bind(
&CefSetCookieCallback::OnComplete, callback.get(),
status == net::CanonicalCookie::CookieInclusionStatus::INCLUDE));
}
} // namespace
CefCookieManagerOldImpl::CefCookieManagerOldImpl() {}
CefCookieManagerOldImpl::~CefCookieManagerOldImpl() {
CEF_REQUIRE_IOT();
}
void CefCookieManagerOldImpl::Initialize(
CefRefPtr<CefRequestContextImpl> request_context,
const CefString& path,
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback) {
DCHECK(request_context.get());
request_context_ = request_context;
request_context_->GetRequestContextImpl(
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
base::Bind(&CefCookieManagerOldImpl::InitWithContext, this, callback));
}
void CefCookieManagerOldImpl::GetCookieStore(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const CookieStoreCallback& callback) {
if (!task_runner.get())
task_runner = CefTaskRunnerImpl::GetCurrentTaskRunner();
if (!CEF_CURRENTLY_ON_IOT()) {
CEF_POST_TASK(CEF_IOT, base::Bind(&CefCookieManagerOldImpl::GetCookieStore,
this, task_runner, callback));
return;
}
RunMethodWithContext(
base::Bind(&CefCookieManagerOldImpl::GetCookieStoreWithContext, this,
task_runner, callback));
}
net::CookieStore* CefCookieManagerOldImpl::GetExistingCookieStore() {
CEF_REQUIRE_IOT();
if (request_context_impl_.get()) {
net::CookieStore* cookie_store =
request_context_impl_->GetExistingCookieStore();
DCHECK(cookie_store);
return cookie_store;
}
LOG(ERROR) << "Cookie store does not exist";
return nullptr;
}
void CefCookieManagerOldImpl::SetSupportedSchemes(
const std::vector<CefString>& schemes,
bool include_defaults,
CefRefPtr<CefCompletionCallback> callback) {
if (!CEF_CURRENTLY_ON_IOT()) {
CEF_POST_TASK(
CEF_IOT, base::Bind(&CefCookieManagerOldImpl::SetSupportedSchemes, this,
schemes, include_defaults, callback));
return;
}
std::vector<std::string> scheme_set;
std::vector<CefString>::const_iterator it = schemes.begin();
for (; it != schemes.end(); ++it)
scheme_set.push_back(*it);
SetSupportedSchemesInternal(scheme_set, include_defaults, callback);
}
bool CefCookieManagerOldImpl::VisitAllCookies(
CefRefPtr<CefCookieVisitor> visitor) {
GetCookieStore(
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
base::Bind(&CefCookieManagerOldImpl::VisitAllCookiesInternal, this,
visitor));
return true;
}
bool CefCookieManagerOldImpl::VisitUrlCookies(
const CefString& url,
bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor) {
GetCookieStore(
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
base::Bind(&CefCookieManagerOldImpl::VisitUrlCookiesInternal, this, url,
includeHttpOnly, visitor));
return true;
}
bool CefCookieManagerOldImpl::SetCookie(
const CefString& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback) {
GURL gurl = GURL(url.ToString());
if (!gurl.is_valid())
return false;
GetCookieStore(
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
base::Bind(&CefCookieManagerOldImpl::SetCookieInternal, this, gurl,
cookie, callback));
return true;
}
bool CefCookieManagerOldImpl::DeleteCookies(
const CefString& url,
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback) {
// Empty URLs are allowed but not invalid URLs.
GURL gurl = GURL(url.ToString());
if (!gurl.is_empty() && !gurl.is_valid())
return false;
GetCookieStore(
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
base::Bind(&CefCookieManagerOldImpl::DeleteCookiesInternal, this, gurl,
cookie_name, callback));
return true;
}
bool CefCookieManagerOldImpl::FlushStore(
CefRefPtr<CefCompletionCallback> callback) {
GetCookieStore(
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
base::Bind(&CefCookieManagerOldImpl::FlushStoreInternal, this, callback));
return true;
}
// static
void CefCookieManagerOldImpl::SetCookieMonsterSchemes(
net::CookieMonster* cookie_monster,
const std::vector<std::string>& schemes,
bool include_defaults) {
CEF_REQUIRE_IOT();
std::vector<std::string> all_schemes = schemes;
if (include_defaults) {
// Add default schemes that should always support cookies.
all_schemes.push_back("http");
all_schemes.push_back("https");
all_schemes.push_back("ws");
all_schemes.push_back("wss");
}
cookie_monster->SetCookieableSchemes(
all_schemes, net::CookieStore::SetCookieableSchemesCallback());
}
void CefCookieManagerOldImpl::RunMethodWithContext(
const CefRequestContextImpl::RequestContextCallback& method) {
CEF_REQUIRE_IOT();
if (request_context_impl_.get()) {
method.Run(request_context_impl_);
} else if (request_context_.get()) {
// Try again after the request context is initialized.
request_context_->GetRequestContextImpl(
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
method);
} else {
NOTREACHED();
}
}
void CefCookieManagerOldImpl::InitWithContext(
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefURLRequestContextGetter> request_context) {
CEF_REQUIRE_IOT();
DCHECK(!request_context_impl_.get());
request_context_impl_ = request_context;
// Clear the CefRequestContextImpl reference here to avoid a potential
// reference loop between CefRequestContextImpl (which has a reference to
// CefRequestContextHandler), CefRequestContextHandler (which may keep a
// reference to this object) and this object.
request_context_ = NULL;
RunAsyncCompletionOnUIThread(callback);
}
void CefCookieManagerOldImpl::SetSupportedSchemesWithContext(
const std::vector<std::string>& schemes,
bool include_defaults,
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefURLRequestContextGetter> request_context) {
CEF_REQUIRE_IOT();
request_context->SetCookieSupportedSchemes(schemes, include_defaults);
RunAsyncCompletionOnUIThread(callback);
}
void CefCookieManagerOldImpl::GetCookieStoreWithContext(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const CookieStoreCallback& callback,
scoped_refptr<CefURLRequestContextGetter> request_context) {
CEF_REQUIRE_IOT();
DCHECK(request_context->GetExistingCookieStore());
const CookieStoreGetter& cookie_store_getter = base::Bind(
&CefURLRequestContextGetter::GetExistingCookieStore, request_context);
if (task_runner->BelongsToCurrentThread()) {
// Execute the callback immediately.
callback.Run(cookie_store_getter);
} else {
// Execute the callback on the target thread.
task_runner->PostTask(FROM_HERE, base::Bind(callback, cookie_store_getter));
}
}
void CefCookieManagerOldImpl::SetSupportedSchemesInternal(
const std::vector<std::string>& schemes,
bool include_defaults,
CefRefPtr<CefCompletionCallback> callback) {
CEF_REQUIRE_IOT();
RunMethodWithContext(
base::Bind(&CefCookieManagerOldImpl::SetSupportedSchemesWithContext, this,
schemes, include_defaults, callback));
}
void CefCookieManagerOldImpl::VisitAllCookiesInternal(
CefRefPtr<CefCookieVisitor> visitor,
const CookieStoreGetter& cookie_store_getter) {
CEF_REQUIRE_IOT();
net::CookieStore* cookie_store = cookie_store_getter.Run();
if (!cookie_store)
return;
scoped_refptr<VisitCookiesCallback> callback(
new VisitCookiesCallback(cookie_store_getter, visitor));
cookie_store->GetAllCookiesAsync(
base::Bind(&VisitCookiesCallback::Run, callback.get()));
}
void CefCookieManagerOldImpl::VisitUrlCookiesInternal(
const CefString& url,
bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor,
const CookieStoreGetter& cookie_store_getter) {
CEF_REQUIRE_IOT();
net::CookieStore* cookie_store = cookie_store_getter.Run();
if (!cookie_store)
return;
net::CookieOptions options;
if (includeHttpOnly)
options.set_include_httponly();
scoped_refptr<VisitCookiesCallback> callback(
new VisitCookiesCallback(cookie_store_getter, visitor));
GURL gurl = GURL(url.ToString());
cookie_store->GetCookieListWithOptionsAsync(
gurl, options, base::Bind(&VisitCookiesCallback::Run, callback.get()));
}
void CefCookieManagerOldImpl::SetCookieInternal(
const GURL& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback,
const CookieStoreGetter& cookie_store_getter) {
CEF_REQUIRE_IOT();
net::CookieStore* cookie_store = cookie_store_getter.Run();
if (!cookie_store) {
if (callback.get()) {
CEF_POST_TASK(CEF_IOT, base::Bind(&CefSetCookieCallback::OnComplete,
callback.get(), false));
}
return;
}
std::string name = CefString(&cookie.name).ToString();
std::string value = CefString(&cookie.value).ToString();
std::string domain = CefString(&cookie.domain).ToString();
std::string path = CefString(&cookie.path).ToString();
base::Time expiration_time;
if (cookie.has_expires)
cef_time_to_basetime(cookie.expires, expiration_time);
auto canonical_cookie = net::CanonicalCookie::CreateSanitizedCookie(
url, name, value, domain, path,
base::Time(), // Creation time.
expiration_time,
base::Time(), // Last access time.
cookie.secure ? true : false, cookie.httponly ? true : false,
net::CookieSameSite::UNSPECIFIED, net::COOKIE_PRIORITY_DEFAULT);
net::CookieOptions options;
if (cookie.httponly)
options.set_include_httponly();
if (!canonical_cookie) {
SetCookieCallbackImpl(
callback,
net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
return;
}
cookie_store->SetCanonicalCookieAsync(
std::move(canonical_cookie), url.scheme(), options,
base::Bind(SetCookieCallbackImpl, callback));
}
void CefCookieManagerOldImpl::DeleteCookiesInternal(
const GURL& url,
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback,
const CookieStoreGetter& cookie_store_getter) {
CEF_REQUIRE_IOT();
net::CookieStore* cookie_store = cookie_store_getter.Run();
if (!cookie_store) {
if (callback.get()) {
CEF_POST_TASK(CEF_IOT, base::Bind(&CefDeleteCookiesCallback::OnComplete,
callback.get(), 0));
}
return;
}
if (url.is_empty()) {
// Delete all cookies.
cookie_store->DeleteAllAsync(
base::Bind(DeleteCookiesCallbackImpl, callback));
} else if (cookie_name.empty()) {
// Delete all matching host cookies.
net::CookieDeletionInfo delete_info;
delete_info.host = url.host();
cookie_store->DeleteAllMatchingInfoAsync(
delete_info, base::Bind(DeleteCookiesCallbackImpl, callback));
} else {
// Delete all matching host and domain cookies.
net::CookieDeletionInfo delete_info;
delete_info.url = url;
delete_info.name = cookie_name;
cookie_store->DeleteAllMatchingInfoAsync(
delete_info, base::Bind(DeleteCookiesCallbackImpl, callback));
}
}
void CefCookieManagerOldImpl::FlushStoreInternal(
CefRefPtr<CefCompletionCallback> callback,
const CookieStoreGetter& cookie_store_getter) {
CEF_REQUIRE_IOT();
net::CookieStore* cookie_store = cookie_store_getter.Run();
if (!cookie_store) {
RunAsyncCompletionOnUIThread(callback);
return;
}
cookie_store->FlushStore(base::Bind(RunAsyncCompletionOnUIThread, callback));
}

View File

@@ -1,110 +0,0 @@
// 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_NET_COOKIE_MANAGER_OLD_IMPL_H_
#define CEF_LIBCEF_BROWSER_NET_COOKIE_MANAGER_OLD_IMPL_H_
#include <set>
#include "include/cef_cookie.h"
#include "libcef/browser/request_context_impl.h"
#include "libcef/browser/thread_util.h"
#include "base/files/file_path.h"
#include "net/cookies/cookie_monster.h"
// Implementation of the CefCookieManager interface.
class CefCookieManagerOldImpl : public CefCookieManager {
public:
CefCookieManagerOldImpl();
~CefCookieManagerOldImpl() override;
// Must be called immediately after this object is created when |is_blocking|
// is false.
void Initialize(CefRefPtr<CefRequestContextImpl> request_context,
const CefString& path,
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback);
// Executes |callback| either synchronously or asynchronously with the
// CookieStoreGetter when the cookie store object is available. If
// |task_runner| is NULL the callback will be executed on the originating
// thread. CookieStoreGetter can only be executed on, and the resulting cookie
// store object can only be accessed on, the IO thread.
typedef base::Callback<net::CookieStore*()> CookieStoreGetter;
typedef base::Callback<void(const CookieStoreGetter&)> CookieStoreCallback;
void GetCookieStore(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const CookieStoreCallback& callback);
// Returns the existing cookie store object. Logs an error if the cookie
// store does not yet exist. Must be called on the IO thread.
net::CookieStore* GetExistingCookieStore();
// CefCookieManager methods.
void SetSupportedSchemes(const std::vector<CefString>& schemes,
bool include_defaults,
CefRefPtr<CefCompletionCallback> callback) override;
bool VisitAllCookies(CefRefPtr<CefCookieVisitor> visitor) override;
bool VisitUrlCookies(const CefString& url,
bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor) override;
bool SetCookie(const CefString& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback) override;
bool DeleteCookies(const CefString& url,
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback) override;
bool FlushStore(CefRefPtr<CefCompletionCallback> callback) override;
// Set the schemes supported by |cookie_monster|.
static void SetCookieMonsterSchemes(net::CookieMonster* cookie_monster,
const std::vector<std::string>& schemes,
bool include_defaults);
private:
// Execute |method| on the IO thread once the request context is available.
void RunMethodWithContext(
const CefRequestContextImpl::RequestContextCallback& method);
void InitWithContext(
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefURLRequestContextGetter> request_context);
void SetSupportedSchemesWithContext(
const std::vector<std::string>& schemes,
bool include_defaults,
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefURLRequestContextGetter> request_context);
void GetCookieStoreWithContext(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const CookieStoreCallback& callback,
scoped_refptr<CefURLRequestContextGetter> request_context);
void SetSupportedSchemesInternal(const std::vector<std::string>& schemes,
bool include_defaults,
CefRefPtr<CefCompletionCallback> callback);
void VisitAllCookiesInternal(CefRefPtr<CefCookieVisitor> visitor,
const CookieStoreGetter& cookie_store_getter);
void VisitUrlCookiesInternal(const CefString& url,
bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor,
const CookieStoreGetter& cookie_store_getter);
void SetCookieInternal(const GURL& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback,
const CookieStoreGetter& cookie_store_getter);
void DeleteCookiesInternal(const GURL& url,
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback,
const CookieStoreGetter& cookie_store_getter);
void FlushStoreInternal(CefRefPtr<CefCompletionCallback> callback,
const CookieStoreGetter& cookie_store_getter);
// Context that owns the cookie monster.
CefRefPtr<CefRequestContextImpl> request_context_;
scoped_refptr<CefURLRequestContextGetter> request_context_impl_;
IMPLEMENT_REFCOUNTING_DELETE_ON_IOT(CefCookieManagerOldImpl);
};
#endif // CEF_LIBCEF_BROWSER_NET_COOKIE_MANAGER_OLD_IMPL_H_

View File

@@ -6,7 +6,6 @@
#include "libcef/browser/context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net_service/util.h"
#include "base/files/file_util.h"
#include "base/logging.h"
@@ -43,10 +42,5 @@ void CefLoadCRLSetsFile(const CefString& path) {
return;
}
if (!net_service::IsEnabled()) {
NOTIMPLEMENTED();
return;
}
CEF_POST_USER_VISIBLE_TASK(base::BindOnce(&LoadFromDisk, path));
}

View File

@@ -7,7 +7,6 @@
#include <string>
#include "libcef/browser/net/internal_scheme_handler.h"
#include "libcef/browser/net/url_request_manager.h"
#include "libcef/browser/resource_context.h"
#include "base/memory/ptr_util.h"
@@ -41,12 +40,6 @@ class Delegate : public InternalHandlerDelegate {
} // namespace
void RegisterChromeDevToolsHandler(CefURLRequestManager* request_manager) {
request_manager->AddFactory(
content::kChromeDevToolsScheme, kChromeDevToolsHost,
CreateInternalHandlerFactory(base::WrapUnique(new Delegate())));
}
void RegisterChromeDevToolsHandler(CefResourceContext* resource_context) {
resource_context->RegisterSchemeHandlerFactory(
content::kChromeDevToolsScheme, kChromeDevToolsHost,

View File

@@ -7,14 +7,12 @@
#pragma once
class CefResourceContext;
class CefURLRequestManager;
namespace scheme {
extern const char kChromeDevToolsHost[];
// Register the chrome-devtools scheme handler.
void RegisterChromeDevToolsHandler(CefURLRequestManager* request_manager);
void RegisterChromeDevToolsHandler(CefResourceContext* resource_context);
} // namespace scheme

View File

@@ -1,315 +0,0 @@
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "libcef/browser/net/net_util.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/resource_context.h"
#include "libcef/common/net/scheme_registration.h"
#include "base/optional.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/resource_request_info.h"
#include "net/url_request/url_request.h"
#include "url/origin.h"
#include "url/url_constants.h"
namespace net_util {
namespace {
CefString SerializeRequestInitiator(
base::Optional<url::Origin> request_initiator) {
if (request_initiator.has_value())
return request_initiator->Serialize();
return "null";
}
CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
CefResourceContext* resource_context,
int render_process_id,
int render_frame_id,
int frame_tree_node_id,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool is_navigation,
bool is_download,
base::Optional<url::Origin> request_initiator) {
CEF_REQUIRE_IOT();
DCHECK(resource_context);
DCHECK(request);
CefRefPtr<CefResourceRequestHandler> resource_request_handler;
const CefString& request_initiator_str =
SerializeRequestInitiator(request_initiator);
const bool is_custom_scheme =
!GURL(request->GetURL().ToString()).SchemeIsHTTPOrHTTPS();
// Not supported by the old network implementation, but keep the value
// consistent with the NetworkService implementation.
bool disable_default_handling = is_custom_scheme;
// Give the browser handler a chance first.
if (browser) {
DCHECK(frame);
CefRefPtr<CefClient> client = browser->GetHost()->GetClient();
if (client) {
CefRefPtr<CefRequestHandler> request_handler =
client->GetRequestHandler();
if (request_handler) {
resource_request_handler = request_handler->GetResourceRequestHandler(
browser, frame, request, is_navigation, is_download,
request_initiator_str, disable_default_handling);
}
}
}
// Give the request context handler a chance.
if (!resource_request_handler) {
CefRefPtr<CefRequestContextHandler> request_context_handler =
resource_context->GetHandler(render_process_id, render_frame_id,
frame_tree_node_id, false);
if (request_context_handler) {
resource_request_handler =
request_context_handler->GetResourceRequestHandler(
browser, frame, request, is_navigation, is_download,
request_initiator_str, disable_default_handling);
}
}
return resource_request_handler;
}
void HandleExternalProtocolOnIOThread(CefResourceContext* resource_context,
int render_process_id,
CefRefPtr<CefBrowserHostImpl> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequestImpl> request) {
CEF_REQUIRE_IOT();
CefRefPtr<CefResourceRequestHandler> request_handler =
GetResourceRequestHandler(
resource_context, render_process_id, -1, -1, browser.get(), frame,
request.get(), true /* is_navigation */, false /* is_download */,
base::Optional<url::Origin>());
if (!request_handler)
return;
bool allow_os_execution = false;
request_handler->OnProtocolExecution(browser, frame, request.get(),
allow_os_execution);
if (allow_os_execution) {
const GURL& url = GURL(request->GetURL().ToString());
CefBrowserPlatformDelegate::HandleExternalProtocol(url);
}
}
} // namespace
bool IsInternalRequest(const net::URLRequest* request) {
// With PlzNavigate we now receive blob URLs. Ignore these URLs.
// See https://crbug.com/776884 for details.
if (request->url().SchemeIs(url::kBlobScheme)) {
return true;
}
return false;
}
CefRefPtr<CefBrowserHostImpl> GetBrowserForRequest(
const net::URLRequest* request) {
DCHECK(request);
CEF_REQUIRE_IOT();
// When navigating the main frame a new (pre-commit) URLRequest will be
// created before the RenderFrameHost. Consequently we can't rely on
// ResourceRequestInfo::GetRenderFrameForRequest returning a valid frame
// ID. See https://crbug.com/776884 for background.
int render_process_id = -1;
int render_frame_id = MSG_ROUTING_NONE;
if (content::ResourceRequestInfo::GetRenderFrameForRequest(
request, &render_process_id, &render_frame_id) &&
render_process_id >= 0 && render_frame_id >= 0) {
return CefBrowserHostImpl::GetBrowserForFrameRoute(render_process_id,
render_frame_id);
}
content::ResourceRequestInfo* request_info =
content::ResourceRequestInfo::ForRequest(request);
if (request_info) {
return CefBrowserHostImpl::GetBrowserForFrameTreeNode(
request_info->GetFrameTreeNodeId());
}
return nullptr;
}
CefRefPtr<CefFrame> GetFrameForRequest(
scoped_refptr<CefBrowserInfo> browser_info,
const net::URLRequest* request) {
CEF_REQUIRE_IOT();
content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
if (!info)
return nullptr;
// Try to locate the most reasonable match by ID.
auto frame =
browser_info->GetFrameForFrameTreeNode(info->GetFrameTreeNodeId());
if (!frame) {
frame = browser_info->GetFrameForRoute(info->GetRouteID(),
info->GetRenderFrameID());
}
if (frame)
return frame;
// The IsMainFrame() flag isn't completely reliable, so do this after
// searching by ID.
if (info->IsMainFrame())
return browser_info->GetMainFrame();
// Create a temporary frame object for requests referencing sub-frames that
// don't yet exist. Use the main frame as the parent because we don't know
// the real parent.
return browser_info->CreateTempSubFrame(CefFrameHostImpl::kInvalidFrameId);
}
CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
const net::URLRequest* request,
CefRefPtr<CefRequestImpl>& cef_request,
CefRefPtr<CefBrowser>& cef_browser,
CefRefPtr<CefFrame>& cef_frame) {
CEF_REQUIRE_IOT();
content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
if (!info)
return nullptr;
// Initiator will be non-null for subresource loads.
const bool is_navigation =
ui::PageTransitionIsNewNavigation(info->GetPageTransition()) &&
!request->initiator().has_value();
const bool is_download = info->IsDownload();
const CefString& request_initiator =
SerializeRequestInitiator(request->initiator());
const bool is_custom_scheme =
!scheme::IsInternalHandledScheme(request->url().scheme());
// Not supported by the old network implementation, but keep the value
// consistent with the NetworkService implementation.
bool disable_default_handling = is_custom_scheme;
CefRefPtr<CefResourceRequestHandler> resource_request_handler;
CefRefPtr<CefBrowserHostImpl> browser = GetBrowserForRequest(request);
CefRefPtr<CefFrame> frame;
CefRefPtr<CefRequestImpl> requestPtr;
// Give the browser handler a chance first.
if (browser) {
// A frame should always exist, or be created.
frame = GetFrameForRequest(browser->browser_info(), request);
DCHECK(frame);
CefRefPtr<CefClient> client = browser->GetClient();
if (client) {
CefRefPtr<CefRequestHandler> request_handler =
client->GetRequestHandler();
if (request_handler) {
requestPtr = new CefRequestImpl();
requestPtr->Set(request);
requestPtr->SetReadOnly(true);
resource_request_handler = request_handler->GetResourceRequestHandler(
browser.get(), frame, requestPtr.get(), is_navigation, is_download,
request_initiator, disable_default_handling);
}
}
}
// Give the request context handler a chance.
if (!resource_request_handler) {
CefResourceContext* resource_context =
static_cast<CefResourceContext*>(info->GetContext());
if (!resource_context)
return nullptr;
const int render_process_id = info->GetChildID();
const int render_frame_id = info->GetRenderFrameID();
const int frame_tree_node_id = info->GetFrameTreeNodeId();
CefRefPtr<CefRequestContextHandler> request_context_handler =
resource_context->GetHandler(render_process_id, render_frame_id,
frame_tree_node_id, false);
if (request_context_handler) {
if (!requestPtr) {
requestPtr = new CefRequestImpl();
requestPtr->Set(request);
requestPtr->SetReadOnly(true);
}
resource_request_handler =
request_context_handler->GetResourceRequestHandler(
browser.get(), frame, requestPtr.get(), is_navigation,
is_download, request_initiator, disable_default_handling);
}
}
if (resource_request_handler) {
// Success! Return all the objects that were discovered/created.
cef_request = requestPtr;
cef_browser = browser.get();
cef_frame = frame;
}
return resource_request_handler;
}
void HandleExternalProtocol(
CefRefPtr<CefRequestImpl> request,
const content::ResourceRequestInfo::WebContentsGetter&
web_contents_getter) {
DCHECK(request);
DCHECK(request->IsReadOnly());
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(HandleExternalProtocol, request,
web_contents_getter));
return;
}
content::WebContents* web_contents = web_contents_getter.Run();
if (!web_contents)
return;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForContents(web_contents);
if (!browser)
return;
content::BrowserContext* browser_context = web_contents->GetBrowserContext();
DCHECK(browser_context);
CefResourceContext* resource_context =
static_cast<CefResourceContext*>(browser_context->GetResourceContext());
DCHECK(resource_context);
const int render_process_id =
web_contents->GetRenderViewHost()->GetProcess()->GetID();
CEF_POST_TASK(
CEF_IOT, base::Bind(HandleExternalProtocolOnIOThread,
base::Unretained(resource_context), render_process_id,
browser, browser->GetMainFrame(), request));
}
} // namespace net_util

View File

@@ -1,56 +0,0 @@
// Copyright (c) 2017 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_NET_NET_UTIL_H_
#define CEF_LIBCEF_BROWSER_NET_NET_UTIL_H_
#pragma once
#include "include/cef_resource_request_handler.h"
#include "libcef/common/request_impl.h"
#include "content/public/browser/resource_request_info.h"
namespace net {
class URLRequest;
}
class GURL;
class CefBrowserHostImpl;
class CefBrowserInfo;
namespace net_util {
// Returns true if |request| is handled internally and should not be exposed via
// the CEF API.
bool IsInternalRequest(const net::URLRequest* request);
// Returns the browser associated with the specified URLRequest.
CefRefPtr<CefBrowserHostImpl> GetBrowserForRequest(
const net::URLRequest* request);
// Returns the frame associated with the specified URLRequest.
CefRefPtr<CefFrame> GetFrameForRequest(
scoped_refptr<CefBrowserInfo> browser_info,
const net::URLRequest* request);
// Returns the appropriate CefResourceRequestHandler as determined by the
// associated CefBrowser/CefRequestHandler and/or CefRequestContextHandler, if
// any. The out-params will be nullptr if no handler is returned. Otherwise,
// the |cef_request| parameter will be set based on the contents of |request|
// (read-only by default), and the |cef_browser| and |cef_frame| parameters
// will be set if the request is associated with a browser.
CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
const net::URLRequest* request,
CefRefPtr<CefRequestImpl>& cef_request,
CefRefPtr<CefBrowser>& cef_browser,
CefRefPtr<CefFrame>& cef_frame);
void HandleExternalProtocol(
CefRefPtr<CefRequestImpl> request,
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter);
} // namespace net_util
#endif // CEF_LIBCEF_BROWSER_NET_NET_UTIL_H_

View File

@@ -1,515 +0,0 @@
// 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/net/network_delegate.h"
#include <string>
#include <utility>
#include "include/cef_urlrequest.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/net/cookie_manager_old_impl.h"
#include "libcef/browser/net/net_util.h"
#include "libcef/browser/net/source_stream.h"
#include "libcef/browser/net/url_request_user_data.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net_service/net_service_util.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/response_impl.h"
#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string_util.h"
#include "chrome/common/net/safe_search_util.h"
#include "components/prefs/pref_member.h"
#include "components/prefs/pref_service.h"
#include "content/public/common/content_switches.h"
#include "net/base/net_errors.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
namespace {
const void* kAuthCallbackHolderUserDataKey =
static_cast<const void*>(&kAuthCallbackHolderUserDataKey);
class CefBeforeResourceLoadCallbackImpl : public CefRequestCallback {
public:
typedef net::CompletionOnceCallback CallbackType;
CefBeforeResourceLoadCallbackImpl(CefRefPtr<CefRequestImpl> cef_request,
GURL* new_url,
net::URLRequest* url_request,
bool force_google_safesearch,
CallbackType callback)
: cef_request_(cef_request),
new_url_(new_url),
url_request_(url_request),
force_google_safesearch_(force_google_safesearch),
callback_(std::move(callback)) {
DCHECK(new_url);
DCHECK(url_request_);
// Add an association between the URLRequest and this object.
url_request_->SetUserData(UserDataKey(),
base::WrapUnique(new Disconnector(this)));
}
~CefBeforeResourceLoadCallbackImpl() {
if (!callback_.is_null()) {
// The callback is still pending. Cancel it now.
if (CEF_CURRENTLY_ON_IOT()) {
RunNow(cef_request_, new_url_, url_request_, std::move(callback_),
force_google_safesearch_, false);
} else {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefBeforeResourceLoadCallbackImpl::RunNow,
cef_request_, new_url_, url_request_,
base::Passed(std::move(callback_)),
force_google_safesearch_, false));
}
}
}
void Continue(bool allow) override {
// Always continue asynchronously.
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefBeforeResourceLoadCallbackImpl::ContinueNow,
this, allow));
}
void Cancel() override { Continue(false); }
void ContinueNow(bool allow) {
CEF_REQUIRE_IOT();
if (!callback_.is_null()) {
RunNow(cef_request_, new_url_, url_request_, std::move(callback_),
force_google_safesearch_, allow);
Disconnect();
}
}
private:
void Disconnect() {
CEF_REQUIRE_IOT();
cef_request_ = nullptr;
new_url_ = nullptr;
url_request_ = nullptr;
callback_.Reset();
}
// Used to disconnect the callback when the associated URLRequest is
// destroyed.
class Disconnector : public base::SupportsUserData::Data {
public:
explicit Disconnector(CefBeforeResourceLoadCallbackImpl* callback)
: callback_(callback) {}
~Disconnector() override {
if (callback_)
callback_->Disconnect();
}
void Disconnect() { callback_ = NULL; }
private:
CefBeforeResourceLoadCallbackImpl* callback_;
};
static void RunNow(CefRefPtr<CefRequestImpl> cef_request,
GURL* new_url,
net::URLRequest* request,
CallbackType callback,
bool force_google_safesearch,
bool allow) {
CEF_REQUIRE_IOT();
if (allow) {
// Update the URLRequest with only the values that have been changed by
// the client.
cef_request->Get(request, true);
if (!!(cef_request->GetChanges() & CefRequestImpl::kChangedUrl)) {
// If the URL was changed then redirect the request.
GURL url = GURL(cef_request->GetURL().ToString());
DCHECK_NE(url, request->url());
new_url->Swap(&url);
}
}
// Remove the association between the URLRequest and this object.
Disconnector* disconnector =
static_cast<Disconnector*>(request->GetUserData(UserDataKey()));
DCHECK(disconnector);
disconnector->Disconnect();
request->RemoveUserData(UserDataKey());
// Only execute the callback if the request has not been canceled.
if (request->status().status() != net::URLRequestStatus::CANCELED) {
if (force_google_safesearch && allow && new_url->is_empty())
safe_search_util::ForceGoogleSafeSearch(request->url(), new_url);
std::move(callback).Run(allow ? net::OK : net::ERR_ABORTED);
}
}
static inline void* UserDataKey() { return &kLocatorKey; }
CefRefPtr<CefRequestImpl> cef_request_;
const GURL old_url_;
GURL* new_url_;
net::URLRequest* url_request_;
bool force_google_safesearch_;
CallbackType callback_;
// The user data key.
static int kLocatorKey;
IMPLEMENT_REFCOUNTING(CefBeforeResourceLoadCallbackImpl);
DISALLOW_COPY_AND_ASSIGN(CefBeforeResourceLoadCallbackImpl);
};
int CefBeforeResourceLoadCallbackImpl::kLocatorKey = 0;
class CefAuthCallbackImpl : public CefAuthCallback {
public:
typedef net::NetworkDelegate::AuthCallback CallbackType;
CefAuthCallbackImpl(CallbackType callback, net::AuthCredentials* credentials)
: callback_(std::move(callback)), credentials_(credentials) {}
~CefAuthCallbackImpl() override {
if (!callback_.is_null()) {
// The auth callback is still pending. Cancel it now.
if (CEF_CURRENTLY_ON_IOT()) {
CancelNow(std::move(callback_));
} else {
CEF_POST_TASK(CEF_IOT, base::Bind(&CefAuthCallbackImpl::CancelNow,
base::Passed(std::move(callback_))));
}
}
}
void Continue(const CefString& username, const CefString& password) override {
if (CEF_CURRENTLY_ON_IOT()) {
if (!callback_.is_null()) {
credentials_->Set(username, password);
std::move(callback_).Run(
net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);
}
} else {
CEF_POST_TASK(CEF_IOT, base::Bind(&CefAuthCallbackImpl::Continue, this,
username, password));
}
}
void Cancel() override {
if (CEF_CURRENTLY_ON_IOT()) {
if (!callback_.is_null()) {
CancelNow(std::move(callback_));
}
} else {
CEF_POST_TASK(CEF_IOT, base::Bind(&CefAuthCallbackImpl::Cancel, this));
}
}
CallbackType Disconnect() WARN_UNUSED_RESULT { return std::move(callback_); }
private:
static void CancelNow(CallbackType callback) {
CEF_REQUIRE_IOT();
std::move(callback).Run(
net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION);
}
CallbackType callback_;
net::AuthCredentials* credentials_;
IMPLEMENT_REFCOUNTING(CefAuthCallbackImpl);
};
// Invalidates CefAuthCallbackImpl::callback_ if the URLRequest is deleted
// before the callback.
class AuthCallbackHolder : public base::SupportsUserData::Data {
public:
explicit AuthCallbackHolder(CefRefPtr<CefAuthCallbackImpl> callback)
: callback_(callback) {}
~AuthCallbackHolder() override { callback_->Disconnect().Reset(); }
private:
CefRefPtr<CefAuthCallbackImpl> callback_;
};
} // namespace
CefNetworkDelegate::CefNetworkDelegate() : force_google_safesearch_(nullptr) {}
CefNetworkDelegate::~CefNetworkDelegate() {}
std::unique_ptr<net::SourceStream> CefNetworkDelegate::CreateSourceStream(
net::URLRequest* request,
std::unique_ptr<net::SourceStream> upstream) {
if (net_util::IsInternalRequest(request))
return upstream;
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
if (handler) {
CefRefPtr<CefResponseImpl> responsePtr = new CefResponseImpl();
responsePtr->Set(request);
responsePtr->SetReadOnly(true);
CefRefPtr<CefResponseFilter> cef_filter =
handler->GetResourceResponseFilter(browser, frame, requestPtr.get(),
responsePtr.get());
if (cef_filter && cef_filter->InitFilter()) {
return std::make_unique<CefSourceStream>(cef_filter, std::move(upstream));
}
}
return upstream;
}
int CefNetworkDelegate::OnBeforeURLRequest(net::URLRequest* request,
net::CompletionOnceCallback callback,
GURL* new_url) {
if (net_util::IsInternalRequest(request))
return net::OK;
const bool force_google_safesearch =
(force_google_safesearch_ && force_google_safesearch_->GetValue());
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
if (handler) {
// The following callback allows modification of the request object.
requestPtr->SetReadOnly(false);
CefBrowserHostImpl* browser_impl =
static_cast<CefBrowserHostImpl*>(browser.get());
if (browser_impl) {
const CefBrowserSettings& browser_settings = browser_impl->settings();
if (browser_settings.accept_language_list.length > 0) {
const std::string& accept_language =
net::HttpUtil::GenerateAcceptLanguageHeader(
CefString(&browser_settings.accept_language_list));
request->SetExtraRequestHeaderByName(
net::HttpRequestHeaders::kAcceptLanguage, accept_language, false);
requestPtr->SetHeaderByName(net::HttpRequestHeaders::kAcceptLanguage,
accept_language, false);
}
}
requestPtr->SetTrackChanges(true);
CefRefPtr<CefBeforeResourceLoadCallbackImpl> callbackImpl(
new CefBeforeResourceLoadCallbackImpl(requestPtr, new_url, request,
force_google_safesearch,
std::move(callback)));
// Give the client an opportunity to evaluate the request.
cef_return_value_t retval = handler->OnBeforeResourceLoad(
browser, frame, requestPtr.get(), callbackImpl.get());
if (retval == RV_CANCEL) {
// Cancel the request.
callbackImpl->Continue(false);
} else if (retval == RV_CONTINUE) {
// Continue the request.
callbackImpl->Continue(true);
}
// Continue or cancel the request asynchronously.
return net::ERR_IO_PENDING;
}
if (force_google_safesearch && new_url->is_empty())
safe_search_util::ForceGoogleSafeSearch(request->url(), new_url);
// Continue the request immediately.
return net::OK;
}
void CefNetworkDelegate::OnCompleted(net::URLRequest* request,
bool started,
int net_error) {
if (net_util::IsInternalRequest(request))
return;
if (!started)
return;
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
if (!handler)
return;
CefRefPtr<CefResponseImpl> responsePtr = new CefResponseImpl();
responsePtr->Set(request);
responsePtr->SetReadOnly(true);
cef_urlrequest_status_t status = UR_UNKNOWN;
switch (request->status().status()) {
case net::URLRequestStatus::SUCCESS:
status = UR_SUCCESS;
break;
case net::URLRequestStatus::CANCELED:
status = UR_CANCELED;
break;
case net::URLRequestStatus::FAILED:
status = UR_FAILED;
break;
default:
NOTREACHED();
break;
}
const int64 received_content_length =
request->received_response_content_length();
handler->OnResourceLoadComplete(browser, frame, requestPtr.get(),
responsePtr.get(), status,
received_content_length);
}
net::NetworkDelegate::AuthRequiredResponse CefNetworkDelegate::OnAuthRequired(
net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
AuthCallback callback,
net::AuthCredentials* credentials) {
if (net_util::IsInternalRequest(request))
return AUTH_REQUIRED_RESPONSE_NO_ACTION;
CefRefPtr<CefBrowserHostImpl> browser =
net_util::GetBrowserForRequest(request);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefAuthCallbackImpl> callbackPtr(
new CefAuthCallbackImpl(std::move(callback), credentials));
if (handler->GetAuthCredentials(
browser.get(), request->url().spec(), auth_info.is_proxy,
auth_info.challenger.host(), auth_info.challenger.port(),
auth_info.realm, auth_info.scheme, callbackPtr.get())) {
request->SetUserData(
kAuthCallbackHolderUserDataKey,
std::make_unique<AuthCallbackHolder>(callbackPtr));
return AUTH_REQUIRED_RESPONSE_IO_PENDING;
} else {
callback = callbackPtr->Disconnect();
}
}
}
}
CefURLRequestUserData* user_data =
(CefURLRequestUserData*)request->GetUserData(
CefURLRequestUserData::kUserDataKey);
if (user_data) {
CefRefPtr<CefURLRequestClient> client = user_data->GetClient();
if (client.get()) {
CefRefPtr<CefAuthCallbackImpl> callbackPtr(
new CefAuthCallbackImpl(std::move(callback), credentials));
if (client->GetAuthCredentials(
auth_info.is_proxy, auth_info.challenger.host(),
auth_info.challenger.port(), auth_info.realm, auth_info.scheme,
callbackPtr.get())) {
request->SetUserData(kAuthCallbackHolderUserDataKey,
std::make_unique<AuthCallbackHolder>(callbackPtr));
return AUTH_REQUIRED_RESPONSE_IO_PENDING;
} else {
callback = callbackPtr->Disconnect();
}
}
}
return AUTH_REQUIRED_RESPONSE_NO_ACTION;
}
bool CefNetworkDelegate::OnCanGetCookies(const net::URLRequest& request,
const net::CookieList& cookie_list,
bool allowed_from_caller) {
if (!allowed_from_caller)
return false;
if (net_util::IsInternalRequest(&request))
return true;
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(&request, requestPtr, browser, frame);
if (!handler)
return true;
CefRefPtr<CefCookieAccessFilter> cookie_filter =
handler->GetCookieAccessFilter(browser, frame, requestPtr.get());
if (!cookie_filter)
return true;
bool cookie_blocked = false;
for (const auto& cookie : cookie_list) {
CefCookie cef_cookie;
if (!net_service::MakeCefCookie(cookie, cef_cookie))
continue;
if (!cookie_filter->CanSendCookie(browser, frame, requestPtr.get(),
cef_cookie)) {
if (!cookie_blocked)
cookie_blocked = true;
}
}
return !cookie_blocked;
}
bool CefNetworkDelegate::OnCanSetCookie(const net::URLRequest& request,
const net::CanonicalCookie& cookie,
net::CookieOptions* options,
bool allowed_from_caller) {
if (!allowed_from_caller)
return false;
if (net_util::IsInternalRequest(&request))
return true;
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(&request, requestPtr, browser, frame);
if (!handler)
return true;
CefRefPtr<CefCookieAccessFilter> cookie_filter =
handler->GetCookieAccessFilter(browser, frame, requestPtr.get());
if (!cookie_filter)
return true;
CefCookie cef_cookie;
if (!net_service::MakeCefCookie(cookie, cef_cookie))
return true;
CefRefPtr<CefResponseImpl> responsePtr = new CefResponseImpl();
responsePtr->Set(&request);
responsePtr->SetReadOnly(true);
return cookie_filter->CanSaveCookie(browser, frame, requestPtr.get(),
responsePtr.get(), cef_cookie);
}
bool CefNetworkDelegate::OnCanAccessFile(
const net::URLRequest& request,
const base::FilePath& original_path,
const base::FilePath& absolute_path) const {
return true;
}

View File

@@ -1,60 +0,0 @@
// 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_NET_NETWORK_DELEGATE_H_
#define CEF_LIBCEF_BROWSER_NET_NETWORK_DELEGATE_H_
#pragma once
#include "base/macros.h"
#include "net/base/network_delegate_impl.h"
template <class T>
class PrefMember;
typedef PrefMember<bool> BooleanPrefMember;
// Used for intercepting resource requests, redirects and responses. The single
// instance of this class is managed by CefURLRequestContextGetter.
class CefNetworkDelegate : public net::NetworkDelegateImpl {
public:
CefNetworkDelegate();
~CefNetworkDelegate() override;
void set_force_google_safesearch(BooleanPrefMember* force_google_safesearch) {
force_google_safesearch_ = force_google_safesearch;
}
private:
// net::NetworkDelegate methods.
std::unique_ptr<net::SourceStream> CreateSourceStream(
net::URLRequest* request,
std::unique_ptr<net::SourceStream> upstream) override;
int OnBeforeURLRequest(net::URLRequest* request,
net::CompletionOnceCallback callback,
GURL* new_url) override;
AuthRequiredResponse OnAuthRequired(
net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
AuthCallback callback,
net::AuthCredentials* credentials) override;
void OnCompleted(net::URLRequest* request,
bool started,
int net_error) override;
bool OnCanGetCookies(const net::URLRequest& request,
const net::CookieList& cookie_list,
bool allowed_from_caller) override;
bool OnCanSetCookie(const net::URLRequest& request,
const net::CanonicalCookie& cookie,
net::CookieOptions* options,
bool allowed_from_caller) override;
bool OnCanAccessFile(const net::URLRequest& request,
const base::FilePath& original_path,
const base::FilePath& absolute_path) const override;
// Weak, owned by our owner (CefURLRequestContextGetter).
BooleanPrefMember* force_google_safesearch_;
DISALLOW_COPY_AND_ASSIGN(CefNetworkDelegate);
};
#endif // CEF_LIBCEF_BROWSER_NET_NETWORK_DELEGATE_H_

View File

@@ -1,592 +0,0 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2009 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/net/resource_request_job.h"
#include <map>
#include <vector>
#include "include/cef_callback.h"
#include "include/cef_parser.h"
#include "libcef/browser/net/cookie_manager_old_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net_service/net_service_util.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/response_impl.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "net/base/http_user_agent_settings.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/mime_util.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
using net::URLRequestStatus;
namespace {
using HeaderMap = std::multimap<CefString, CefString>;
struct CaseInsensitiveComparator {
base::StringPiece search;
CaseInsensitiveComparator(const std::string& s) : search(s) {}
bool operator()(const HeaderMap::value_type& p) const {
return base::EqualsCaseInsensitiveASCII(search, p.first.ToString());
}
};
HeaderMap::const_iterator FindHeader(const HeaderMap& m,
const std::string& name) {
return std::find_if(m.begin(), m.end(), CaseInsensitiveComparator(name));
}
bool SetHeaderIfMissing(CefRequest::HeaderMap& headerMap,
const std::string& name,
const std::string& value) {
if (value.empty())
return false;
CefRequest::HeaderMap::const_iterator it = headerMap.find(name);
if (it == headerMap.end()) {
headerMap.insert(std::make_pair(name, value));
return true;
}
return false;
}
} // namespace
// Client callback for asynchronous response continuation.
class CefResourceRequestJobCallback : public CefCallback {
public:
enum Type {
HEADERS_AVAILABLE,
BYTES_AVAILABLE,
};
explicit CefResourceRequestJobCallback(CefResourceRequestJob* job, Type type)
: job_(job), type_(type), dest_(NULL), dest_size_(0) {}
void Continue() override {
// Continue asynchronously.
CEF_POST_TASK(
CEF_IOT,
base::Bind(&CefResourceRequestJobCallback::ContinueOnIOThread, this));
}
void Cancel() override {
// Cancel asynchronously.
CEF_POST_TASK(
CEF_IOT,
base::Bind(&CefResourceRequestJobCallback::CancelOnIOThread, this));
}
void Detach() {
CEF_REQUIRE_IOT();
job_ = NULL;
}
void SetDestination(net::IOBuffer* dest, int dest_size) {
CEF_REQUIRE_IOT();
// Should not be called multiple times while IO is pending.
DCHECK(!dest_);
dest_ = dest;
dest_size_ = dest_size;
}
private:
void ContinueOnIOThread() {
CEF_REQUIRE_IOT();
// Return early if the callback has already been detached.
if (!job_)
return;
if (type_ == HEADERS_AVAILABLE) {
// Callback for headers available.
if (!job_->has_response_started()) {
// Send header information.
job_->SendHeaders();
}
// This type of callback only ever needs to be called once.
Detach();
} else if (type_ == BYTES_AVAILABLE) {
// Callback for bytes available.
if (job_->has_response_started() && job_->GetStatus().is_io_pending()) {
// Read the bytes. They should be available but, if not, wait again.
int bytes_read = job_->ReadRawData(dest_, dest_size_);
if (bytes_read == net::ERR_IO_PENDING) {
// Still pending, nothing to do...
} else if (bytes_read >= 0) {
// Must clear the members here because they may be reset as a result
// of calling ReadRawDataComplete.
dest_size_ = 0;
dest_ = NULL;
// Notify about the available bytes. If bytes_read > 0 then
// ReadRawData may be called from URLRequest::Read. If bytes_read == 0
// then Kill will be called from the URLRequest destructor.
job_->ReadRawDataComplete(bytes_read);
} else {
// Failed due to an error.
NOTREACHED() << "ReadRawData returned error " << bytes_read;
job_->ReadRawDataComplete(bytes_read);
Detach();
}
}
}
}
void CancelOnIOThread() {
CEF_REQUIRE_IOT();
if (job_)
job_->Kill();
}
CefResourceRequestJob* job_;
Type type_;
net::IOBuffer* dest_;
int dest_size_;
IMPLEMENT_REFCOUNTING(CefResourceRequestJobCallback);
};
CefResourceRequestJob::CefResourceRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
CefRefPtr<CefResourceHandler> handler)
: net::URLRequestJob(request, network_delegate),
handler_(handler),
done_(false),
remaining_bytes_(0),
sent_bytes_(0),
response_cookies_save_index_(0),
weak_factory_(this) {}
CefResourceRequestJob::~CefResourceRequestJob() {}
void CefResourceRequestJob::Start() {
CEF_REQUIRE_IOT();
request_start_time_ = base::Time::Now();
cef_request_ = CefRequest::Create();
// Populate the request data.
static_cast<CefRequestImpl*>(cef_request_.get())->Set(request_);
// Add default headers if not already specified.
const net::URLRequestContext* context = request_->context();
if (context) {
CefRequest::HeaderMap headerMap;
cef_request_->GetHeaderMap(headerMap);
bool changed = false;
const net::HttpUserAgentSettings* ua_settings =
context->http_user_agent_settings();
if (ua_settings) {
if (SetHeaderIfMissing(headerMap,
net::HttpRequestHeaders::kAcceptLanguage,
ua_settings->GetAcceptLanguage())) {
changed = true;
}
if (SetHeaderIfMissing(headerMap, net::HttpRequestHeaders::kUserAgent,
ua_settings->GetUserAgent())) {
changed = true;
}
}
if (changed)
cef_request_->SetHeaderMap(headerMap);
}
AddCookieHeaderAndStart();
}
void CefResourceRequestJob::Kill() {
CEF_REQUIRE_IOT();
if (!done_) {
// Notify the handler that the request has been canceled.
handler_->Cancel();
}
if (callback_.get()) {
callback_->Detach();
callback_ = NULL;
}
net::URLRequestJob::Kill();
}
// This method will be called by URLRequestJob::Read and our callback.
// It can indicate the following states:
// 1. Return ERR_IO_PENDING, and call ReadRawDataComplete when the read
// completes in any way, or
// 2. Return a count of bytes read >= 0, indicating synchronous success, or
// 3. Return another error code < 0, indicating synchronous failure.
int CefResourceRequestJob::ReadRawData(net::IOBuffer* dest, int dest_size) {
CEF_REQUIRE_IOT();
DCHECK_NE(dest_size, 0);
if (remaining_bytes_ == 0) {
// No more data to read.
DoneWithRequest();
return 0;
} else if (remaining_bytes_ > 0 && remaining_bytes_ < dest_size) {
// The handler knows the content size beforehand.
dest_size = static_cast<int>(remaining_bytes_);
}
if (!callback_.get()) {
// Create the bytes available callback that will be used until the request
// is completed.
callback_ = new CefResourceRequestJobCallback(
this, CefResourceRequestJobCallback::BYTES_AVAILABLE);
}
// Read response data from the handler.
int bytes_read = 0;
bool rv = handler_->ReadResponse(dest->data(), dest_size, bytes_read,
callback_.get());
if (!rv) {
// The handler has indicated completion of the request.
DoneWithRequest();
return 0;
} else if (bytes_read == 0) {
// Continue reading asynchronously. May happen multiple times in a row so
// only set destination members the first time.
if (!GetStatus().is_io_pending())
callback_->SetDestination(dest, dest_size);
return net::ERR_IO_PENDING;
} else if (bytes_read > dest_size) {
// Normalize the return value.
bytes_read = dest_size;
}
sent_bytes_ += bytes_read;
if (remaining_bytes_ > 0)
remaining_bytes_ -= bytes_read;
// Continue calling this method.
return bytes_read;
}
void CefResourceRequestJob::GetResponseInfo(net::HttpResponseInfo* info) {
CEF_REQUIRE_IOT();
info->headers = GetResponseHeaders();
}
void CefResourceRequestJob::GetLoadTimingInfo(
net::LoadTimingInfo* load_timing_info) const {
// If haven't made it far enough to receive any headers, don't return
// anything. This makes for more consistent behavior in the case of errors.
if (!response_.get() || receive_headers_end_.is_null())
return;
load_timing_info->request_start_time = request_start_time_;
load_timing_info->receive_headers_end = receive_headers_end_;
}
bool CefResourceRequestJob::IsRedirectResponse(
GURL* location,
int* http_status_code,
bool* insecure_scheme_was_upgraded) {
CEF_REQUIRE_IOT();
bool redirect = false;
*insecure_scheme_was_upgraded = false;
if (redirect_url_.is_valid()) {
// Redirect to the new URL.
*http_status_code = 303;
location->Swap(&redirect_url_);
redirect = true;
} else if (response_.get()) {
// Check for HTTP 302 or HTTP 303 redirect.
int status = response_->GetStatus();
if (net::HttpResponseHeaders::IsRedirectResponseCode(status)) {
CefResponse::HeaderMap headerMap;
response_->GetHeaderMap(headerMap);
CefRequest::HeaderMap::const_iterator iter =
FindHeader(headerMap, "Location");
if (iter != headerMap.end()) {
GURL new_url = request_->url().Resolve(std::string(iter->second));
if (new_url.is_valid()) {
*http_status_code = status;
*location = new_url;
redirect = true;
}
}
}
}
if (redirect) {
// Set the correct response status. This avoids a DCHECK in
// RedirectInfo::ComputeRedirectInfo.
request_->response_headers()->ReplaceStatusLine(
net_service::MakeStatusLine(*http_status_code, std::string(), true));
}
return redirect;
}
bool CefResourceRequestJob::GetMimeType(std::string* mime_type) const {
CEF_REQUIRE_IOT();
if (response_.get())
*mime_type = response_->GetMimeType();
return true;
}
bool CefResourceRequestJob::GetCharset(std::string* charset) {
CEF_REQUIRE_IOT();
if (net::HttpResponseHeaders* headers = GetResponseHeaders())
return headers->GetCharset(charset);
return false;
}
int CefResourceRequestJob::GetResponseCode() const {
CEF_REQUIRE_IOT();
if (response_.get())
return response_->GetStatus();
return -1;
}
void CefResourceRequestJob::SendHeaders() {
CEF_REQUIRE_IOT();
// Clear the headers available callback.
callback_ = NULL;
// We may have been orphaned...
if (!request())
return;
response_ = new CefResponseImpl();
remaining_bytes_ = 0;
// Set the response mime type if it can be determined from the file extension.
if (request_->url().has_path()) {
const std::string& path = request_->url().path();
size_t found = path.find_last_of(".");
if (found != std::string::npos) {
std::string suggest_mime_type;
if (net::GetWellKnownMimeTypeFromExtension(
base::FilePath::FromUTF8Unsafe(path.substr(found + 1)).value(),
&suggest_mime_type)) {
response_->SetMimeType(suggest_mime_type);
}
}
}
CefString redirectUrl;
// Get header information from the handler.
handler_->GetResponseHeaders(response_, remaining_bytes_, redirectUrl);
receive_headers_end_ = base::TimeTicks::Now();
if (response_->GetError() != ERR_NONE) {
const URLRequestStatus& status =
URLRequestStatus::FromError(response_->GetError());
if (status.status() == URLRequestStatus::CANCELED ||
status.status() == URLRequestStatus::FAILED) {
NotifyStartError(status);
return;
}
}
if (!redirectUrl.empty()) {
std::string redirectUrlStr = redirectUrl;
redirect_url_ = request_->url().Resolve(redirectUrlStr);
}
if (remaining_bytes_ > 0)
set_expected_content_size(remaining_bytes_);
// Continue processing the request.
SaveCookiesAndNotifyHeadersComplete();
}
void CefResourceRequestJob::AddCookieHeaderAndStart() {
// If the request was destroyed, then there is no more work to do.
if (!request_)
return;
net::CookieStore* cookie_store = request_->context()->cookie_store();
if (cookie_store &&
!(request_->load_flags() & net::LOAD_DO_NOT_SEND_COOKIES)) {
cookie_store->GetAllCookiesForURLAsync(
request_->url(),
base::Bind(&CefResourceRequestJob::CheckCookiePolicyAndLoad,
weak_factory_.GetWeakPtr()));
} else {
DoStartTransaction();
}
}
void CefResourceRequestJob::DoLoadCookies() {
net::CookieOptions options;
options.set_include_httponly();
request_->context()->cookie_store()->GetCookieListWithOptionsAsync(
request_->url(), options,
base::Bind(&CefResourceRequestJob::OnCookiesLoaded,
weak_factory_.GetWeakPtr()));
}
void CefResourceRequestJob::CheckCookiePolicyAndLoad(
const net::CookieList& cookie_list,
const net::CookieStatusList& excluded_list) {
const bool can_get_cookies =
!cookie_list.empty() && CanGetCookies(cookie_list);
if (can_get_cookies)
DoLoadCookies();
else
DoStartTransaction();
}
void CefResourceRequestJob::OnCookiesLoaded(
const net::CookieList& cookie_list,
const net::CookieStatusList& excluded_list) {
if (!cookie_list.empty()) {
const std::string& cookie_line =
net::CanonicalCookie::BuildCookieLine(cookie_list);
CefRequest::HeaderMap headerMap;
cef_request_->GetHeaderMap(headerMap);
headerMap.insert(
std::make_pair(net::HttpRequestHeaders::kCookie, cookie_line));
cef_request_->SetHeaderMap(headerMap);
}
DoStartTransaction();
}
void CefResourceRequestJob::DoStartTransaction() {
// We may have been canceled while retrieving cookies.
if (GetStatus().is_success()) {
StartTransaction();
} else {
NotifyCanceled();
}
}
void CefResourceRequestJob::StartTransaction() {
// Create the callback that will be used to notify when header information is
// available.
callback_ = new CefResourceRequestJobCallback(
this, CefResourceRequestJobCallback::HEADERS_AVAILABLE);
// Protect against deletion of this object.
base::WeakPtr<CefResourceRequestJob> weak_ptr(weak_factory_.GetWeakPtr());
// Handler can decide whether to process the request.
bool rv = handler_->ProcessRequest(cef_request_, callback_.get());
if (weak_ptr.get() && !rv) {
// Cancel the request.
NotifyCanceled();
}
}
net::HttpResponseHeaders* CefResourceRequestJob::GetResponseHeaders() {
DCHECK(response_.get());
if (!response_headers_.get()) {
CefResponseImpl* responseImpl =
static_cast<CefResponseImpl*>(response_.get());
response_headers_ = responseImpl->GetResponseHeaders();
}
return response_headers_.get();
}
void CefResourceRequestJob::SaveCookiesAndNotifyHeadersComplete() {
if (request_->load_flags() & net::LOAD_DO_NOT_SAVE_COOKIES) {
NotifyHeadersComplete();
return;
}
response_cookies_.clear();
response_cookies_save_index_ = 0;
FetchResponseCookies(&response_cookies_);
// Now, loop over the response cookies, and attempt to persist each.
SaveNextCookie();
}
void CefResourceRequestJob::SaveNextCookie() {
if (response_cookies_save_index_ == response_cookies_.size()) {
response_cookies_.clear();
response_cookies_save_index_ = 0;
NotifyHeadersComplete();
return;
}
const std::string& cookie_line =
response_cookies_[response_cookies_save_index_];
net::CookieOptions options;
options.set_include_httponly();
std::unique_ptr<net::CanonicalCookie> cookie = net::CanonicalCookie::Create(
request_->url(), cookie_line, base::Time::Now(), options);
const bool can_set_cookie = cookie && CanSetCookie(*cookie, &options);
if (can_set_cookie) {
request_->context()->cookie_store()->SetCanonicalCookieAsync(
std::move(cookie), request_->url().scheme(), options,
base::Bind(&CefResourceRequestJob::OnCookieSaved,
weak_factory_.GetWeakPtr()));
return;
}
CookieHandled();
}
void CefResourceRequestJob::OnCookieSaved(
net::CanonicalCookie::CookieInclusionStatus status) {
CookieHandled();
}
void CefResourceRequestJob::CookieHandled() {
response_cookies_save_index_++;
// We may have been canceled within OnSetCookie.
if (GetStatus().is_success()) {
SaveNextCookie();
} else {
NotifyCanceled();
}
}
void CefResourceRequestJob::FetchResponseCookies(
std::vector<std::string>* cookies) {
const std::string name = "Set-Cookie";
std::string value;
size_t iter = 0;
net::HttpResponseHeaders* headers = GetResponseHeaders();
while (headers->EnumerateHeader(&iter, name, &value)) {
if (!value.empty())
cookies->push_back(value);
}
}
void CefResourceRequestJob::DoneWithRequest() {
if (done_)
return;
done_ = true;
if (request_)
request_->set_received_response_content_length(sent_bytes_);
}

View File

@@ -1,92 +0,0 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2009 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_REQUEST_JOB_H_
#define CEF_LIBCEF_BROWSER_RESOURCE_REQUEST_JOB_H_
#include <stdint.h>
#include <string>
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_request_handler.h"
#include "net/cookies/cookie_monster.h"
#include "net/url_request/url_request_job.h"
namespace net {
class HttpResponseHeaders;
class URLRequest;
} // namespace net
class CefResourceRequestJobCallback;
class CefResourceRequestJob : public net::URLRequestJob {
public:
CefResourceRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
CefRefPtr<CefResourceHandler> handler);
~CefResourceRequestJob() override;
private:
// net::URLRequestJob methods.
void Start() override;
void Kill() override;
int ReadRawData(net::IOBuffer* dest, int dest_size) override;
void GetResponseInfo(net::HttpResponseInfo* info) override;
void GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override;
bool IsRedirectResponse(GURL* location,
int* http_status_code,
bool* insecure_scheme_was_upgraded) override;
bool GetMimeType(std::string* mime_type) const override;
bool GetCharset(std::string* charset) override;
int GetResponseCode() const override;
void SendHeaders();
// Used for sending cookies with the request.
void AddCookieHeaderAndStart();
void DoLoadCookies();
void CheckCookiePolicyAndLoad(const net::CookieList& cookie_list,
const net::CookieStatusList& excluded_list);
void OnCookiesLoaded(const net::CookieList& cookie_list,
const net::CookieStatusList& excluded_list);
void DoStartTransaction();
void StartTransaction();
// Used for saving cookies returned as part of the response.
net::HttpResponseHeaders* GetResponseHeaders();
void SaveCookiesAndNotifyHeadersComplete();
void SaveNextCookie();
void OnCookieSaved(net::CanonicalCookie::CookieInclusionStatus status);
void CookieHandled();
void FetchResponseCookies(std::vector<std::string>* cookies);
void DoneWithRequest();
CefRefPtr<CefResourceHandler> handler_;
bool done_;
CefRefPtr<CefResponse> response_;
GURL redirect_url_;
int64_t remaining_bytes_;
int64_t sent_bytes_;
CefRefPtr<CefRequest> cef_request_;
CefRefPtr<CefResourceRequestJobCallback> callback_;
scoped_refptr<net::HttpResponseHeaders> response_headers_;
std::vector<std::string> response_cookies_;
size_t response_cookies_save_index_;
base::Time request_start_time_;
base::TimeTicks receive_headers_end_;
// Must be the last member.
base::WeakPtrFactory<CefResourceRequestJob> weak_factory_;
friend class CefResourceRequestJobCallback;
DISALLOW_COPY_AND_ASSIGN(CefResourceRequestJob);
};
#endif // CEF_LIBCEF_BROWSER_RESOURCE_REQUEST_JOB_H_

View File

@@ -8,74 +8,12 @@
#include "libcef/browser/net/chrome_scheme_handler.h"
#include "libcef/browser/net/devtools_scheme_handler.h"
#include "libcef/browser/resource_context.h"
#include "libcef/common/net/scheme_registration.h"
#include "base/memory/ptr_util.h"
#include "base/task/post_task.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/url_constants.h"
#include "net/net_buildflags.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/file_protocol_handler.h"
#include "net/url_request/ftp_protocol_handler.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "url/url_constants.h"
namespace scheme {
void InstallInternalProtectedHandlers(
net::URLRequestJobFactoryImpl* job_factory,
CefURLRequestManager* request_manager,
content::ProtocolHandlerMap* protocol_handlers,
net::HostResolver* host_resolver) {
protocol_handlers->insert(std::make_pair(
url::kDataScheme, std::make_unique<net::DataProtocolHandler>()));
protocol_handlers->insert(std::make_pair(
url::kFileScheme,
std::make_unique<net::FileProtocolHandler>(
base::CreateTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}))));
#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
protocol_handlers->insert(std::make_pair(
url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver)));
#endif
for (content::ProtocolHandlerMap::iterator it = protocol_handlers->begin();
it != protocol_handlers->end(); ++it) {
const std::string& scheme = it->first;
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>
protocol_handler;
if (scheme == content::kChromeDevToolsScheme) {
// Don't use the default "chrome-devtools" handler.
continue;
} else if (scheme == content::kChromeUIScheme) {
// Filter the URLs that are passed to the default "chrome" handler so as
// not to interfere with CEF's "chrome" handler.
protocol_handler.reset(
scheme::WrapChromeProtocolHandler(
request_manager, base::WrapUnique(it->second.release()))
.release());
} else {
protocol_handler.reset(it->second.release());
}
// Make sure IsInternalProtectedScheme() stays synchronized with what
// Chromium is actually giving us.
DCHECK(IsInternalProtectedScheme(scheme));
bool set_protocol = job_factory->SetProtocolHandler(
scheme, base::WrapUnique(protocol_handler.release()));
DCHECK(set_protocol);
}
}
void RegisterInternalHandlers(CefURLRequestManager* request_manager) {
scheme::RegisterChromeDevToolsHandler(request_manager);
}
void RegisterInternalHandlers(CefResourceContext* resource_context) {
scheme::RegisterChromeDevToolsHandler(resource_context);
}

View File

@@ -11,26 +11,11 @@
#include "content/public/browser/browser_context.h"
#include "url/gurl.h"
namespace net {
class HostResolver;
class URLRequestJobFactoryImpl;
} // namespace net
class CefResourceContext;
class CefURLRequestManager;
namespace scheme {
// Install the internal scheme handlers provided by Chromium that cannot be
// overridden.
void InstallInternalProtectedHandlers(
net::URLRequestJobFactoryImpl* job_factory,
CefURLRequestManager* request_manager,
content::ProtocolHandlerMap* protocol_handlers,
net::HostResolver* host_resolver);
// Register the internal scheme handlers that can be overridden.
void RegisterInternalHandlers(CefURLRequestManager* request_manager);
void RegisterInternalHandlers(CefResourceContext* resource_context);
// Used to fire any asynchronous content updates.

View File

@@ -1,74 +0,0 @@
// Copyright 2016 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/net/source_stream.h"
#include <utility>
#include "net/base/io_buffer.h"
// Use TYPE_INVALID so that URLRequestJob::NotifyHeadersComplete() doesn't
// assume that the "content-length" header is accurate.
CefSourceStream::CefSourceStream(CefRefPtr<CefResponseFilter> cef_filter,
std::unique_ptr<net::SourceStream> upstream)
: net::FilterSourceStream(net::SourceStream::TYPE_INVALID,
std::move(upstream)),
cef_filter_(cef_filter) {}
int CefSourceStream::FilterData(net::IOBuffer* output_buffer,
int output_buffer_size,
net::IOBuffer* input_buffer,
int input_buffer_size,
int* consumed_bytes,
bool upstream_eof_reached) {
if (!output_buffer || output_buffer_size <= 0)
return net::ERR_CONTENT_DECODING_FAILED;
if (input_buffer_size == 0 && last_status_ == RESPONSE_FILTER_DONE) {
// No more input data. Respect the client's desire to be done with
// outputting data.
*consumed_bytes = 0;
return 0;
}
size_t data_in_size = static_cast<size_t>(input_buffer_size);
size_t data_in_read = 0;
size_t data_out_size = static_cast<size_t>(output_buffer_size);
size_t data_out_written = 0;
last_status_ = cef_filter_->Filter(
data_in_size > 0 ? input_buffer->data() : nullptr, data_in_size,
data_in_read, output_buffer->data(), data_out_size, data_out_written);
// Return early if there's an error.
if (last_status_ == RESPONSE_FILTER_ERROR)
return net::ERR_CONTENT_DECODING_FAILED;
// Validate the out values.
if (data_in_read > data_in_size) {
LOG(ERROR) << "potential buffer overflow; data_in_read > data_in_size";
return net::ERR_CONTENT_DECODING_FAILED;
}
if (data_out_written > data_out_size) {
LOG(ERROR) << "potential buffer overflow; data_out_written > data_out_size";
return net::ERR_CONTENT_DECODING_FAILED;
}
// If FilterData() returns 0, *|consumed_bytes| must be equal to
// |input_buffer_size|.
if (data_out_written == 0 && data_in_read != data_in_size) {
LOG(ERROR) << "when no data is written all input must be consumed; "
"data_out_written == 0 && data_in_read != data_in_size";
return net::ERR_CONTENT_DECODING_FAILED;
}
*consumed_bytes = static_cast<int>(data_in_read);
// Output the number of bytes written.
return static_cast<int>(data_out_written);
}
std::string CefSourceStream::GetTypeAsString() const {
return "cef_filter";
}

View File

@@ -1,34 +0,0 @@
// Copyright 2016 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_NET_SOURCE_STREAM_H_
#define CEF_LIBCEF_BROWSER_NET_SOURCE_STREAM_H_
#include "include/cef_response_filter.h"
#include "base/macros.h"
#include "net/filter/filter_source_stream.h"
class CefSourceStream : public net::FilterSourceStream {
public:
CefSourceStream(CefRefPtr<CefResponseFilter> cef_filter,
std::unique_ptr<net::SourceStream> upstream);
int FilterData(net::IOBuffer* output_buffer,
int output_buffer_size,
net::IOBuffer* input_buffer,
int input_buffer_size,
int* consumed_bytes,
bool upstream_eof_reached) override;
std::string GetTypeAsString() const override;
private:
CefRefPtr<CefResponseFilter> cef_filter_;
cef_response_filter_status_t last_status_ = RESPONSE_FILTER_NEED_MORE_DATA;
DISALLOW_COPY_AND_ASSIGN(CefSourceStream);
};
#endif // CEF_LIBCEF_BROWSER_NET_SOURCE_STREAM_H_

View File

@@ -1,21 +0,0 @@
// 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/net/url_request_context.h"
#if DCHECK_IS_ON()
base::AtomicRefCount CefURLRequestContext::DebugObjCt;
#endif
CefURLRequestContext::CefURLRequestContext() {
#if DCHECK_IS_ON()
DebugObjCt.Increment();
#endif
}
CefURLRequestContext::~CefURLRequestContext() {
#if DCHECK_IS_ON()
DebugObjCt.Decrement();
#endif
}

View File

@@ -1,31 +0,0 @@
// 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_NET_URL_REQUEST_CONTEXT_H_
#define CEF_LIBCEF_BROWSER_NET_URL_REQUEST_CONTEXT_H_
#pragma once
#include "base/logging.h"
#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;
#if DCHECK_IS_ON()
// Simple tracking of allocated objects.
static base::AtomicRefCount DebugObjCt;
#endif
private:
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContext);
};
#endif // CEF_LIBCEF_BROWSER_NET_URL_REQUEST_CONTEXT_H_

View File

@@ -1,556 +0,0 @@
// Copyright (c) 2012 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/net/url_request_context_getter.h"
#include <string>
#include <utility>
#include <vector>
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/net/cookie_manager_old_impl.h"
#include "libcef/browser/net/network_delegate.h"
#include "libcef/browser/net/scheme_handler.h"
#include "libcef/browser/net/url_request_interceptor.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/content_client.h"
#include "base/build_time.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/certificate_transparency/chrome_ct_policy_enforcer.h"
#include "components/certificate_transparency/ct_known_logs.h"
#include "components/net_log/chrome_net_log.h"
#include "components/network_session_configurator/browser/network_session_configurator.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "net/base/http_user_agent_settings.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_log_verifier.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/cookies/cookie_monster.h"
#include "net/dns/host_resolver.h"
#include "net/extras/sqlite/sqlite_persistent_cookie_store.h"
#include "net/ftp/ftp_network_layer.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_preferences.h"
#include "net/http/http_cache.h"
#include "net/http/http_server_properties_impl.h"
#include "net/http/http_util.h"
#include "net/http/transport_security_state.h"
#include "net/proxy_resolution/dhcp_pac_file_fetcher_factory.h"
#include "net/proxy_resolution/pac_file_fetcher_impl.h"
#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_storage.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_job_manager.h"
#include "services/network/proxy_service_mojo.h"
#include "url/url_constants.h"
#if defined(OS_WIN)
#include <winhttp.h>
#endif
#if defined(USE_NSS_CERTS)
#include "net/cert_net/nss_ocsp.h"
#endif
using content::BrowserThread;
#if defined(OS_WIN)
#pragma comment(lib, "winhttp.lib")
#endif
namespace {
// An implementation of |HttpUserAgentSettings| that provides a static
// HTTP Accept-Language header value and uses |content::GetUserAgent|
// to provide the HTTP User-Agent header value.
class CefHttpUserAgentSettings : public net::HttpUserAgentSettings {
public:
explicit CefHttpUserAgentSettings(const std::string& raw_language_list)
: http_accept_language_(
net::HttpUtil::GenerateAcceptLanguageHeader(raw_language_list)) {
CEF_REQUIRE_IOT();
}
// net::HttpUserAgentSettings implementation
std::string GetAcceptLanguage() const override {
CEF_REQUIRE_IOT();
return http_accept_language_;
}
std::string GetUserAgent() const override {
CEF_REQUIRE_IOT();
return CefContentClient::Get()->browser()->GetUserAgent();
}
private:
const std::string http_accept_language_;
DISALLOW_COPY_AND_ASSIGN(CefHttpUserAgentSettings);
};
// Based on ProxyResolutionServiceFactory::CreateProxyResolutionService which
// was deleted in http://crrev.com/1c261ff4.
std::unique_ptr<net::ProxyResolutionService> CreateProxyResolutionService(
net::NetLog* net_log,
net::URLRequestContext* context,
net::NetworkDelegate* network_delegate,
proxy_resolver::mojom::ProxyResolverFactoryPtr proxy_resolver_factory,
std::unique_ptr<net::ProxyConfigService> proxy_config_service,
const base::CommandLine& command_line,
bool quick_check_enabled) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
bool use_v8 = !command_line.HasSwitch(switches::kWinHttpProxyResolver);
// TODO(eroman): Figure out why this doesn't work in single-process mode.
// Should be possible now that a private isolate is used.
// http://crbug.com/474654
if (use_v8 && command_line.HasSwitch(switches::kSingleProcess)) {
LOG(ERROR) << "Cannot use V8 Proxy resolver in single process mode.";
use_v8 = false; // Fallback to non-v8 implementation.
}
std::unique_ptr<net::ProxyResolutionService> proxy_service;
if (use_v8) {
std::unique_ptr<net::DhcpPacFileFetcher> dhcp_pac_file_fetcher;
net::DhcpPacFileFetcherFactory dhcp_factory;
dhcp_pac_file_fetcher = dhcp_factory.Create(context);
proxy_service = network::CreateProxyResolutionServiceUsingMojoFactory(
std::move(proxy_resolver_factory), std::move(proxy_config_service),
net::PacFileFetcherImpl::Create(context),
std::move(dhcp_pac_file_fetcher), context->host_resolver(), net_log,
network_delegate);
} else {
proxy_service = net::ProxyResolutionService::CreateUsingSystemProxyResolver(
std::move(proxy_config_service), net_log);
}
proxy_service->set_quick_check_enabled(quick_check_enabled);
return proxy_service;
}
// Based on net::ct::CreateLogVerifiersForKnownLogs which was deleted in
// https://crrev.com/24711fe395.
std::vector<scoped_refptr<const net::CTLogVerifier>>
CreateLogVerifiersForKnownLogs() {
std::vector<scoped_refptr<const net::CTLogVerifier>> verifiers;
for (const auto& log : certificate_transparency::GetKnownLogs()) {
scoped_refptr<const net::CTLogVerifier> log_verifier =
net::CTLogVerifier::Create(
base::StringPiece(log.log_key, log.log_key_length), log.log_name);
// Make sure no null logs enter verifiers. Parsing of all statically
// configured logs should always succeed, unless there has been binary or
// memory corruption.
CHECK(log_verifier);
verifiers.push_back(std::move(log_verifier));
}
return verifiers;
}
} // namespace
CefURLRequestContextGetter::CefURLRequestContextGetter(
const CefRequestContextSettings& settings,
PrefService* pref_service,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
content::ProtocolHandlerMap* protocol_handlers,
std::unique_ptr<net::ProxyConfigService> proxy_config_service,
content::URLRequestInterceptorScopedVector request_interceptors)
: settings_(settings), io_state_(std::make_unique<IOState>()) {
// Must first be created on the UI thread.
CEF_REQUIRE_UIT();
io_state_->net_log_ = g_browser_process->net_log(),
DCHECK(io_state_->net_log_);
io_state_->io_task_runner_ = std::move(io_task_runner);
io_state_->proxy_resolver_factory_ =
ChromeMojoProxyResolverFactory::CreateWithStrongBinding();
io_state_->proxy_config_service_ = std::move(proxy_config_service);
io_state_->request_interceptors_ = std::move(request_interceptors);
std::swap(io_state_->protocol_handlers_, *protocol_handlers);
auto io_thread_proxy =
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
quick_check_enabled_.Init(prefs::kQuickCheckEnabled, pref_service);
quick_check_enabled_.MoveToThread(io_thread_proxy);
force_google_safesearch_.Init(prefs::kForceGoogleSafeSearch, pref_service);
force_google_safesearch_.MoveToThread(io_thread_proxy);
#if defined(OS_POSIX) && !defined(OS_ANDROID)
io_state_->gsapi_library_name_ =
pref_service->GetString(prefs::kGSSAPILibraryName);
#endif
auth_server_whitelist_.Init(
prefs::kAuthServerWhitelist, pref_service,
base::Bind(&CefURLRequestContextGetter::UpdateServerWhitelist,
base::Unretained(this)));
auth_server_whitelist_.MoveToThread(io_thread_proxy);
auth_negotiate_delegate_whitelist_.Init(
prefs::kAuthNegotiateDelegateWhitelist, pref_service,
base::Bind(&CefURLRequestContextGetter::UpdateDelegateWhitelist,
base::Unretained(this)));
auth_negotiate_delegate_whitelist_.MoveToThread(io_thread_proxy);
}
CefURLRequestContextGetter::~CefURLRequestContextGetter() {
CEF_REQUIRE_IOT();
// This destructor may not be called during shutdown. Perform any required
// shutdown in ShutdownOnIOThread() instead.
}
// static
void CefURLRequestContextGetter::RegisterPrefs(PrefRegistrySimple* registry) {
// Based on IOThread::RegisterPrefs.
#if defined(OS_POSIX) && !defined(OS_ANDROID)
registry->RegisterStringPref(prefs::kGSSAPILibraryName, std::string());
#endif
registry->RegisterBooleanPref(prefs::kQuickCheckEnabled, true);
// Based on ProfileImpl::RegisterProfilePrefs.
registry->RegisterBooleanPref(prefs::kForceGoogleSafeSearch, false);
// Based on IOThread::RegisterPrefs.
registry->RegisterStringPref(prefs::kAuthServerWhitelist, "");
registry->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist, "");
}
void CefURLRequestContextGetter::ShutdownOnUIThread() {
CEF_REQUIRE_UIT();
quick_check_enabled_.Destroy();
force_google_safesearch_.Destroy();
auth_server_whitelist_.Destroy();
auth_negotiate_delegate_whitelist_.Destroy();
CEF_POST_TASK(
CEF_IOT,
base::Bind(&CefURLRequestContextGetter::ShutdownOnIOThread, this));
}
void CefURLRequestContextGetter::ShutdownOnIOThread() {
CEF_REQUIRE_IOT();
shutting_down_ = true;
// Delete the ProxyResolutionService object here so that any pending requests
// will be canceled before the URLRequestContext is destroyed.
io_state_->storage_->set_proxy_resolution_service(NULL);
io_state_.reset();
NotifyContextShuttingDown();
}
net::URLRequestContext* CefURLRequestContextGetter::GetURLRequestContext() {
CEF_REQUIRE_IOT();
if (shutting_down_)
return nullptr;
if (!io_state_->url_request_context_.get()) {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
base::FilePath cache_path;
if (settings_.cache_path.length > 0)
cache_path = base::FilePath(CefString(&settings_.cache_path));
io_state_->url_request_context_.reset(new CefURLRequestContext());
io_state_->url_request_context_->set_net_log(io_state_->net_log_);
io_state_->url_request_context_->set_enable_brotli(true);
io_state_->storage_.reset(new net::URLRequestContextStorage(
io_state_->url_request_context_.get()));
SetCookieStoragePath(cache_path,
settings_.persist_session_cookies ? true : false);
std::unique_ptr<CefNetworkDelegate> network_delegate(
new CefNetworkDelegate());
network_delegate->set_force_google_safesearch(&force_google_safesearch_);
io_state_->storage_->set_network_delegate(std::move(network_delegate));
const std::string& accept_language =
settings_.accept_language_list.length > 0
? CefString(&settings_.accept_language_list)
: "en-US,en";
io_state_->storage_->set_http_user_agent_settings(
base::WrapUnique(new CefHttpUserAgentSettings(accept_language)));
io_state_->storage_->set_host_resolver(
net::HostResolver::CreateStandaloneResolver(io_state_->net_log_));
io_state_->storage_->set_cert_verifier(
net::CertVerifier::CreateDefault(/*cert_net_fetcher=*/nullptr));
std::unique_ptr<net::TransportSecurityState> transport_security_state(
new net::TransportSecurityState);
transport_security_state->set_enforce_net_security_expiration(
settings_.enable_net_security_expiration ? true : false);
io_state_->storage_->set_transport_security_state(
std::move(transport_security_state));
std::vector<scoped_refptr<const net::CTLogVerifier>> ct_logs(
CreateLogVerifiersForKnownLogs());
std::unique_ptr<net::MultiLogCTVerifier> ct_verifier(
new net::MultiLogCTVerifier());
ct_verifier->AddLogs(ct_logs);
io_state_->storage_->set_cert_transparency_verifier(std::move(ct_verifier));
std::unique_ptr<certificate_transparency::ChromeCTPolicyEnforcer>
ct_policy_enforcer(new certificate_transparency::ChromeCTPolicyEnforcer(
base::GetBuildTime(),
certificate_transparency::GetDisqualifiedLogs(),
certificate_transparency::GetLogsOperatedByGoogle()));
io_state_->storage_->set_ct_policy_enforcer(std::move(ct_policy_enforcer));
std::unique_ptr<net::ProxyResolutionService> system_proxy_service =
CreateProxyResolutionService(
io_state_->net_log_, io_state_->url_request_context_.get(),
io_state_->url_request_context_->network_delegate(),
std::move(io_state_->proxy_resolver_factory_),
std::move(io_state_->proxy_config_service_), *command_line,
quick_check_enabled_.GetValue());
io_state_->storage_->set_proxy_resolution_service(
std::move(system_proxy_service));
io_state_->storage_->set_ssl_config_service(
std::make_unique<net::SSLConfigServiceDefaults>());
std::vector<std::string> supported_schemes;
supported_schemes.push_back("basic");
supported_schemes.push_back("digest");
supported_schemes.push_back("ntlm");
supported_schemes.push_back("negotiate");
io_state_->http_auth_preferences_.reset(new net::HttpAuthPreferences());
io_state_->storage_->set_http_auth_handler_factory(
net::HttpAuthHandlerRegistryFactory::Create(
io_state_->http_auth_preferences_.get(), supported_schemes
#if defined(OS_POSIX) && !defined(OS_ANDROID)
,
io_state_->gsapi_library_name_
#endif
));
io_state_->storage_->set_http_server_properties(
base::WrapUnique(new net::HttpServerPropertiesImpl));
base::FilePath http_cache_path;
if (!cache_path.empty())
http_cache_path = cache_path.Append(FILE_PATH_LITERAL("Cache"));
UpdateServerWhitelist();
UpdateDelegateWhitelist();
std::unique_ptr<net::HttpCache::DefaultBackend> main_backend(
new net::HttpCache::DefaultBackend(
cache_path.empty() ? net::MEMORY_CACHE : net::DISK_CACHE,
net::CACHE_BACKEND_DEFAULT, http_cache_path, 0));
net::HttpNetworkSession::Context network_session_context;
network_session_context.host_resolver =
io_state_->url_request_context_->host_resolver();
network_session_context.cert_verifier =
io_state_->url_request_context_->cert_verifier();
network_session_context.transport_security_state =
io_state_->url_request_context_->transport_security_state();
network_session_context.cert_transparency_verifier =
io_state_->url_request_context_->cert_transparency_verifier();
network_session_context.ct_policy_enforcer =
io_state_->url_request_context_->ct_policy_enforcer();
network_session_context.proxy_resolution_service =
io_state_->url_request_context_->proxy_resolution_service();
network_session_context.ssl_config_service =
io_state_->url_request_context_->ssl_config_service();
network_session_context.http_auth_handler_factory =
io_state_->url_request_context_->http_auth_handler_factory();
network_session_context.http_server_properties =
io_state_->url_request_context_->http_server_properties();
network_session_context.net_log = io_state_->net_log_;
net::HttpNetworkSession::Params network_session_params;
network_session_configurator::ParseCommandLineAndFieldTrials(
*base::CommandLine::ForCurrentProcess(),
false /* is_quic_force_disabled */,
CefContentClient::Get()
->browser()
->GetUserAgent() /* quic_user_agent_id */,
&network_session_params);
network_session_params.ignore_certificate_errors =
settings_.ignore_certificate_errors ? true : false;
io_state_->storage_->set_http_network_session(
base::WrapUnique(new net::HttpNetworkSession(network_session_params,
network_session_context)));
io_state_->storage_->set_http_transaction_factory(
base::WrapUnique(new net::HttpCache(
io_state_->storage_->http_network_session(),
std::move(main_backend), true /* set_up_quic_server_info */)));
std::unique_ptr<net::URLRequestJobFactoryImpl> job_factory(
new net::URLRequestJobFactoryImpl());
io_state_->url_request_manager_.reset(
new CefURLRequestManager(job_factory.get()));
// Install internal scheme handlers that cannot be overridden.
scheme::InstallInternalProtectedHandlers(
job_factory.get(), io_state_->url_request_manager_.get(),
&io_state_->protocol_handlers_, network_session_context.host_resolver);
io_state_->protocol_handlers_.clear();
// Register internal scheme handlers that can be overridden.
scheme::RegisterInternalHandlers(io_state_->url_request_manager_.get());
io_state_->request_interceptors_.push_back(
std::make_unique<CefRequestInterceptor>());
// Set up interceptors in the reverse order.
std::unique_ptr<net::URLRequestJobFactory> top_job_factory =
std::move(job_factory);
for (auto i = io_state_->request_interceptors_.rbegin();
i != io_state_->request_interceptors_.rend(); ++i) {
top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
std::move(top_job_factory), std::move(*i)));
}
io_state_->request_interceptors_.clear();
io_state_->storage_->set_job_factory(std::move(top_job_factory));
#if defined(USE_NSS_CERTS)
// Only do this for the first (global) request context.
static bool request_context_for_nss_set = false;
if (!request_context_for_nss_set) {
net::SetURLRequestContextForNSSHttpIO(
io_state_->url_request_context_.get());
request_context_for_nss_set = true;
}
#endif
}
return io_state_->url_request_context_.get();
}
scoped_refptr<base::SingleThreadTaskRunner>
CefURLRequestContextGetter::GetNetworkTaskRunner() const {
return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
}
net::HostResolver* CefURLRequestContextGetter::GetHostResolver() const {
return io_state_->url_request_context_->host_resolver();
}
void CefURLRequestContextGetter::SetCookieSupportedSchemes(
const std::vector<std::string>& schemes,
bool include_defaults) {
CEF_REQUIRE_IOT();
io_state_->cookie_supported_schemes_ = schemes;
io_state_->include_defaults_ = include_defaults;
CefCookieManagerOldImpl::SetCookieMonsterSchemes(
static_cast<net::CookieMonster*>(GetExistingCookieStore()), schemes,
include_defaults);
}
void CefURLRequestContextGetter::AddHandler(
CefRefPtr<CefRequestContextHandler> handler) {
if (!CEF_CURRENTLY_ON_IOT()) {
CEF_POST_TASK(CEF_IOT, base::Bind(&CefURLRequestContextGetter::AddHandler,
this, handler));
return;
}
io_state_->handler_list_.push_back(handler);
}
net::CookieStore* CefURLRequestContextGetter::GetExistingCookieStore() const {
CEF_REQUIRE_IOT();
if (io_state_->url_request_context_ &&
io_state_->url_request_context_->cookie_store()) {
return io_state_->url_request_context_->cookie_store();
}
LOG(ERROR) << "Cookie store does not exist";
return nullptr;
}
void CefURLRequestContextGetter::SetCookieStoragePath(
const base::FilePath& path,
bool persist_session_cookies) {
CEF_REQUIRE_IOT();
// The cookie store can't be changed during runtime.
DCHECK(!io_state_->url_request_context_->cookie_store());
scoped_refptr<net::SQLitePersistentCookieStore> persistent_store;
if (!path.empty()) {
// TODO(cef): Move directory creation to the blocking pool instead of
// allowing file IO on this thread.
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (base::DirectoryExists(path) || base::CreateDirectory(path)) {
const base::FilePath& cookie_path = path.AppendASCII("Cookies");
persistent_store = new net::SQLitePersistentCookieStore(
cookie_path,
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
// Intentionally using the background task runner exposed by CEF to
// facilitate unit test expectations. This task runner MUST be
// configured with BLOCK_SHUTDOWN.
CefContentBrowserClient::Get()->background_task_runner(),
persist_session_cookies, NULL);
} else {
NOTREACHED() << "The cookie storage directory could not be created";
}
}
// Set the new cookie store that will be used for all new requests. The old
// cookie store, if any, will be automatically flushed and closed when no
// longer referenced.
std::unique_ptr<net::CookieMonster> cookie_monster(
new net::CookieMonster(persistent_store.get(), io_state_->net_log_));
if (persistent_store.get() && persist_session_cookies)
cookie_monster->SetPersistSessionCookies(true);
io_state_->cookie_store_path_ = path;
// Restore the previously supported schemes.
CefCookieManagerOldImpl::SetCookieMonsterSchemes(
cookie_monster.get(), io_state_->cookie_supported_schemes_,
io_state_->include_defaults_);
io_state_->storage_->set_cookie_store(std::move(cookie_monster));
}
void CefURLRequestContextGetter::UpdateServerWhitelist() {
io_state_->http_auth_preferences_->SetServerWhitelist(
auth_server_whitelist_.GetValue());
}
void CefURLRequestContextGetter::UpdateDelegateWhitelist() {
io_state_->http_auth_preferences_->SetDelegateWhitelist(
auth_negotiate_delegate_whitelist_.GetValue());
}

View File

@@ -1,139 +0,0 @@
// 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_NET_URL_REQUEST_CONTEXT_GETTER_IMPL_H_
#define CEF_LIBCEF_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_IMPL_H_
#pragma once
#include <set>
#include <string>
#include "include/internal/cef_types_wrappers.h"
#include "libcef/browser/net/url_request_context.h"
#include "libcef/browser/net/url_request_manager.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
#include "components/prefs/pref_member.h"
#include "content/public/browser/browser_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_job_factory.h"
class PrefRegistrySimple;
class PrefService;
namespace base {
class MessageLoop;
}
namespace net {
class CookieMonster;
class FtpTransactionFactory;
class HttpAuthPreferences;
class ProxyConfigService;
class URLRequestContextStorage;
class URLRequestJobFactory;
class URLRequestJobFactoryImpl;
} // namespace net
// Isolated URLRequestContextGetter implementation. Life span is primarily
// controlled by CefResourceContext and (for the global context)
// CefBrowserMainParts. Created on the UI thread but accessed and destroyed on
// the IO thread. See browser_context.h for an object relationship diagram.
class CefURLRequestContextGetter : public net::URLRequestContextGetter {
public:
CefURLRequestContextGetter(
const CefRequestContextSettings& settings,
PrefService* pref_service,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
content::ProtocolHandlerMap* protocol_handlers,
std::unique_ptr<net::ProxyConfigService> proxy_config_service,
content::URLRequestInterceptorScopedVector request_interceptors);
~CefURLRequestContextGetter() override;
// Register preferences. Called from browser_prefs::CreatePrefService().
static void RegisterPrefs(PrefRegistrySimple* registry);
// Called when the BrowserContextImpl is destroyed.
void ShutdownOnUIThread();
// net::URLRequestContextGetter implementation.
net::URLRequestContext* GetURLRequestContext() override;
scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
const override;
// CefURLRequestContextGetter implementation.
net::HostResolver* GetHostResolver() const;
void SetCookieSupportedSchemes(const std::vector<std::string>& schemes,
bool include_defaults);
// Keep a reference to all handlers sharing this context so that they'll be
// kept alive until the context is destroyed.
void AddHandler(CefRefPtr<CefRequestContextHandler> handler);
// Returns the existing cookie store object. Logs an error if the cookie
// store does not yet exist. Must be called on the IO thread.
net::CookieStore* GetExistingCookieStore() const;
CefURLRequestManager* request_manager() const {
return io_state_->url_request_manager_.get();
}
private:
void SetCookieStoragePath(const base::FilePath& path,
bool persist_session_cookies);
void UpdateServerWhitelist();
void UpdateDelegateWhitelist();
void ShutdownOnIOThread();
const CefRequestContextSettings settings_;
bool shutting_down_ = false;
// State that is only accessed on the IO thread and will be reset in
// ShutdownOnIOThread().
struct IOState {
net::NetLog* net_log_ = nullptr; // Guaranteed to outlive this object.
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
#if defined(OS_POSIX) && !defined(OS_ANDROID)
std::string gsapi_library_name_;
#endif
std::unique_ptr<net::ProxyConfigService> proxy_config_service_;
std::unique_ptr<net::URLRequestContextStorage> storage_;
std::unique_ptr<net::HttpAuthPreferences> http_auth_preferences_;
std::unique_ptr<CefURLRequestContext> url_request_context_;
std::unique_ptr<CefURLRequestManager> url_request_manager_;
content::ProtocolHandlerMap protocol_handlers_;
content::URLRequestInterceptorScopedVector request_interceptors_;
base::FilePath cookie_store_path_;
std::vector<std::string> cookie_supported_schemes_;
bool include_defaults_ = true;
std::vector<CefRefPtr<CefRequestContextHandler>> handler_list_;
proxy_resolver::mojom::ProxyResolverFactoryPtr proxy_resolver_factory_;
};
std::unique_ptr<IOState> io_state_;
BooleanPrefMember quick_check_enabled_;
// Member variables which are pointed to by the various context objects.
mutable BooleanPrefMember force_google_safesearch_;
StringPrefMember auth_server_whitelist_;
StringPrefMember auth_negotiate_delegate_whitelist_;
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextGetter);
};
#endif // CEF_LIBCEF_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_IMPL_H_

View File

@@ -1,142 +0,0 @@
// 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/net/url_request_interceptor.h"
#include <string>
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/net/net_util.h"
#include "libcef/browser/net/resource_request_job.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net/http_header_utils.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/response_impl.h"
#include "net/base/upload_data_stream.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request_job_manager.h"
#include "net/url_request/url_request_redirect_job.h"
CefRequestInterceptor::CefRequestInterceptor() {
CEF_REQUIRE_IOT();
}
CefRequestInterceptor::~CefRequestInterceptor() {
CEF_REQUIRE_IOT();
}
net::URLRequestJob* CefRequestInterceptor::MaybeInterceptRequest(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const {
if (net_util::IsInternalRequest(request))
return nullptr;
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
if (handler) {
// Give the client an opportunity to replace the request.
CefRefPtr<CefResourceHandler> resourceHandler =
handler->GetResourceHandler(browser, frame, requestPtr.get());
if (resourceHandler) {
return new CefResourceRequestJob(request, network_delegate,
resourceHandler);
}
}
return nullptr;
}
net::URLRequestJob* CefRequestInterceptor::MaybeInterceptRedirect(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const GURL& location) const {
if (net_util::IsInternalRequest(request))
return nullptr;
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
if (handler) {
CefRefPtr<CefResponseImpl> responsePtr = new CefResponseImpl();
responsePtr->Set(request);
responsePtr->SetReadOnly(true);
// Give the client an opportunity to redirect the request.
CefString newUrlStr = location.spec();
handler->OnResourceRedirect(browser, frame, requestPtr.get(),
responsePtr.get(), newUrlStr);
if (newUrlStr != location.spec()) {
const GURL new_url = GURL(newUrlStr.ToString());
if (!new_url.is_empty() && new_url.is_valid()) {
return new net::URLRequestRedirectJob(
request, network_delegate, new_url,
net::URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT,
"Resource Redirect");
}
}
}
return nullptr;
}
net::URLRequestJob* CefRequestInterceptor::MaybeInterceptResponse(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const {
if (net_util::IsInternalRequest(request))
return nullptr;
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
if (!handler)
return nullptr;
// The below callback allows modification of the request object.
requestPtr->SetReadOnly(false);
requestPtr->SetTrackChanges(true);
CefRefPtr<CefResponseImpl> responsePtr = new CefResponseImpl();
responsePtr->Set(request);
responsePtr->SetReadOnly(true);
const GURL old_url = request->url();
// Give the client an opportunity to retry or redirect the request.
if (!handler->OnResourceResponse(browser, frame, requestPtr.get(),
responsePtr.get())) {
return nullptr;
}
// This flag will be reset by URLRequest::RestartWithJob() calling
// URLRequest::PrepareToRestart() after this method returns but we need it
// reset sooner so that we can modify the request headers without asserting.
request->set_is_pending(false);
// Update the URLRequest with only the values that have been changed by the
// client.
requestPtr->Get(request, true);
// If the URL was changed then redirect the request.
if (!!(requestPtr->GetChanges() & CefRequestImpl::kChangedUrl)) {
const GURL new_url = old_url.Resolve(requestPtr->GetURL().ToString());
if (new_url != old_url) {
return new net::URLRequestRedirectJob(
request, network_delegate, new_url,
net::URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT,
"Resource Redirect");
}
}
// Otherwise queue a new job.
return net::URLRequestJobManager::GetInstance()->CreateJob(request,
network_delegate);
}

View File

@@ -1,33 +0,0 @@
// 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_NET_URL_REQUEST_INTERCEPTOR_H_
#define CEF_LIBCEF_BROWSER_NET_URL_REQUEST_INTERCEPTOR_H_
#pragma once
#include "net/url_request/url_request_interceptor.h"
// Used for intercepting resource requests, redirects and responses. The single
// instance of this class is managed by CefURLRequestContextGetter.
class CefRequestInterceptor : public net::URLRequestInterceptor {
public:
CefRequestInterceptor();
~CefRequestInterceptor() override;
// net::URLRequestInterceptor methods.
net::URLRequestJob* MaybeInterceptRequest(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override;
net::URLRequestJob* MaybeInterceptRedirect(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const GURL& location) const override;
net::URLRequestJob* MaybeInterceptResponse(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override;
DISALLOW_COPY_AND_ASSIGN(CefRequestInterceptor);
};
#endif // CEF_LIBCEF_BROWSER_NET_URL_REQUEST_INTERCEPTOR_H_

View File

@@ -1,279 +0,0 @@
// Copyright (c) 2015 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2009 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/net/url_request_manager.h"
#include "include/cef_browser.h"
#include "include/cef_scheme.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/net/net_util.h"
#include "libcef/browser/net/resource_request_job.h"
#include "libcef/browser/net/scheme_handler.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net/scheme_registration.h"
#include "libcef/common/request_impl.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_http_job.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "url/third_party/mozilla/url_parse.h"
#include "url/url_util.h"
using net::URLRequestStatus;
namespace {
// Copied from net/url_request/url_request_job_manager.cc.
struct SchemeToFactory {
const char* scheme;
net::URLRequest::ProtocolFactory* factory;
};
static const SchemeToFactory kBuiltinFactories[] = {
{"http", net::URLRequestHttpJob::Factory},
{"https", net::URLRequestHttpJob::Factory},
};
bool IsBuiltinScheme(const std::string& scheme) {
for (size_t i = 0; i < base::size(kBuiltinFactories); ++i)
if (base::LowerCaseEqualsASCII(scheme, kBuiltinFactories[i].scheme))
return true;
return false;
}
net::URLRequestJob* GetBuiltinSchemeRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& scheme) {
// See if the request should be handled by a built-in protocol factory.
for (size_t i = 0; i < base::size(kBuiltinFactories); ++i) {
if (scheme == kBuiltinFactories[i].scheme) {
net::URLRequestJob* job =
(kBuiltinFactories[i].factory)(request, network_delegate, scheme);
DCHECK(job); // The built-in factories are not expected to fail!
return job;
}
}
return NULL;
}
std::string ToLower(const std::string& str) {
std::string str_lower = str;
std::transform(str_lower.begin(), str_lower.end(), str_lower.begin(),
towlower);
return str;
}
} // namespace
// Class used for creating URLRequestJob instances. The lifespan of this object
// is managed by URLRequestJobFactory.
class CefProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
public:
CefProtocolHandler(CefURLRequestManager* request_manager,
const std::string& scheme)
: request_manager_(request_manager), scheme_(scheme) {}
// From net::URLRequestJobFactory::ProtocolHandler
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
CEF_REQUIRE_IOT();
return request_manager_->GetRequestJob(request, network_delegate, scheme_);
}
private:
CefURLRequestManager* request_manager_;
std::string scheme_;
};
CefURLRequestManager::CefURLRequestManager(
net::URLRequestJobFactoryImpl* job_factory)
: job_factory_(job_factory) {
CEF_REQUIRE_IOT();
DCHECK(job_factory_);
}
CefURLRequestManager::~CefURLRequestManager() {
CEF_REQUIRE_IOT();
}
bool CefURLRequestManager::AddFactory(
const std::string& scheme,
const std::string& domain,
CefRefPtr<CefSchemeHandlerFactory> factory) {
if (!factory.get()) {
RemoveFactory(scheme, domain);
return true;
}
CEF_REQUIRE_IOT();
std::string scheme_lower = ToLower(scheme);
std::string domain_lower = ToLower(domain);
// Hostname is only supported for standard schemes.
if (!scheme::IsStandardScheme(scheme_lower))
domain_lower.clear();
SetProtocolHandlerIfNecessary(scheme_lower, true);
handler_map_[make_pair(scheme_lower, domain_lower)] = factory;
return true;
}
void CefURLRequestManager::RemoveFactory(const std::string& scheme,
const std::string& domain) {
CEF_REQUIRE_IOT();
std::string scheme_lower = ToLower(scheme);
std::string domain_lower = ToLower(domain);
// Hostname is only supported for standard schemes.
if (!scheme::IsStandardScheme(scheme_lower))
domain_lower.clear();
HandlerMap::iterator iter =
handler_map_.find(make_pair(scheme_lower, domain_lower));
if (iter != handler_map_.end()) {
handler_map_.erase(iter);
SetProtocolHandlerIfNecessary(scheme_lower, false);
}
}
// Clear all the existing URL handlers and unregister the ProtocolFactory.
void CefURLRequestManager::ClearFactories() {
CEF_REQUIRE_IOT();
// Create a unique set of scheme names.
std::set<std::string> schemes;
for (HandlerMap::const_iterator i = handler_map_.begin();
i != handler_map_.end(); ++i) {
schemes.insert(i->first.first);
}
for (std::set<std::string>::const_iterator scheme = schemes.begin();
scheme != schemes.end(); ++scheme) {
const std::string& scheme_name = *scheme;
if (!scheme::IsInternalProtectedScheme(scheme_name)) {
bool set_protocol = job_factory_->SetProtocolHandler(scheme_name, NULL);
DCHECK(set_protocol);
}
}
handler_map_.clear();
// Re-register internal scheme handlers that can be overridden.
scheme::RegisterInternalHandlers(this);
}
// Helper for chaining ProtocolHandler implementations.
net::URLRequestJob* CefURLRequestManager::GetRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) {
CEF_REQUIRE_IOT();
return GetRequestJob(request, network_delegate, request->url().scheme());
}
void CefURLRequestManager::SetProtocolHandlerIfNecessary(
const std::string& scheme,
bool add) {
// Don't modify a protocol handler for internal protected schemes or if the
// protocol handler is still needed by other registered factories.
if (scheme::IsInternalProtectedScheme(scheme) || HasFactory(scheme))
return;
bool set_protocol = job_factory_->SetProtocolHandler(
scheme,
base::WrapUnique(add ? new CefProtocolHandler(this, scheme) : NULL));
DCHECK(set_protocol);
}
bool CefURLRequestManager::HasFactory(const std::string& scheme) {
if (handler_map_.empty())
return false;
for (HandlerMap::const_iterator i = handler_map_.begin();
i != handler_map_.end(); ++i) {
if (scheme == i->first.first)
return true;
}
return false;
}
CefRefPtr<CefSchemeHandlerFactory> CefURLRequestManager::GetHandlerFactory(
net::URLRequest* request,
const std::string& scheme) {
CefRefPtr<CefSchemeHandlerFactory> factory;
if (request->url().is_valid() && scheme::IsStandardScheme(scheme)) {
// Check for a match with a domain first.
const std::string& domain = request->url().host();
HandlerMap::iterator i = handler_map_.find(make_pair(scheme, domain));
if (i != handler_map_.end())
factory = i->second;
}
if (!factory.get()) {
// Check for a match with no specified domain.
HandlerMap::iterator i =
handler_map_.find(make_pair(scheme, std::string()));
if (i != handler_map_.end())
factory = i->second;
}
return factory;
}
net::URLRequestJob* CefURLRequestManager::GetRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& scheme) {
net::URLRequestJob* job = NULL;
CefRefPtr<CefSchemeHandlerFactory> factory =
GetHandlerFactory(request, scheme);
if (factory.get()) {
CefRefPtr<CefBrowserHostImpl> browser =
net_util::GetBrowserForRequest(request);
CefRefPtr<CefFrame> frame;
if (browser.get()) {
frame = net_util::GetFrameForRequest(browser->browser_info(), request);
}
// Populate the request data.
CefRefPtr<CefRequestImpl> requestPtr(new CefRequestImpl());
requestPtr->Set(request);
// Call the handler factory to create the handler for the request.
CefRefPtr<CefResourceHandler> handler =
factory->Create(browser.get(), frame, scheme, requestPtr.get());
if (handler.get())
job = new CefResourceRequestJob(request, network_delegate, handler);
}
if (!job && IsBuiltinScheme(scheme)) {
// Give the built-in scheme handler a chance to handle the request.
job = GetBuiltinSchemeRequestJob(request, network_delegate, scheme);
}
#if DCHECK_IS_ON()
if (job)
DLOG(INFO) << "CefURLRequestManager hit for " << request->url().spec();
#endif
return job;
}

View File

@@ -1,81 +0,0 @@
// 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_NET_URL_REQUEST_MANAGER_H_
#define CEF_LIBCEF_BROWSER_NET_URL_REQUEST_MANAGER_H_
#pragma once
#include <map>
#include "include/cef_scheme.h"
namespace net {
class NetworkDelegate;
class URLRequest;
class URLRequestJob;
class URLRequestJobFactoryImpl;
} // namespace net
class CefProtocolHandler;
// Class that manages CefSchemeHandlerFactory instances. Only accessed on the IO
// thread.
class CefURLRequestManager {
public:
explicit CefURLRequestManager(net::URLRequestJobFactoryImpl* job_factory);
~CefURLRequestManager();
// Add |factory| for the specified |scheme| and |domain|. See documentation on
// CefRequestContext::RegisterSchemeHandlerFactory() for usage.
bool AddFactory(const std::string& scheme,
const std::string& domain,
CefRefPtr<CefSchemeHandlerFactory> factory);
// Remove all factories associated with the specified |scheme| and |domain|.
void RemoveFactory(const std::string& scheme, const std::string& domain);
// Clear all the existing URL handlers and unregister the ProtocolFactory.
void ClearFactories();
// Helper for chaining ProtocolHandler implementations.
net::URLRequestJob* GetRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate);
private:
friend class CefProtocolHandler;
// Add or remove the protocol handler if necessary. |scheme| will already be
// in lower case.
void SetProtocolHandlerIfNecessary(const std::string& scheme, bool add);
// Returns true if any factory currently exists for |scheme|. |scheme| will
// already be in lower case.
bool HasFactory(const std::string& scheme);
// Retrieve the matching handler factory, if any. |scheme| will already be in
// lower case.
CefRefPtr<CefSchemeHandlerFactory> GetHandlerFactory(
net::URLRequest* request,
const std::string& scheme);
// Create the job that will handle the request. |scheme| will already be in
// lower case.
net::URLRequestJob* GetRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& scheme);
// Life span of |job_factory_| is guaranteed by
// CefURLRequestContextGetter which also owns this object.
net::URLRequestJobFactoryImpl* job_factory_;
// Map (scheme, domain) to factories.
typedef std::map<std::pair<std::string, std::string>,
CefRefPtr<CefSchemeHandlerFactory>>
HandlerMap;
HandlerMap handler_map_;
DISALLOW_COPY_AND_ASSIGN(CefURLRequestManager);
};
#endif // CEF_LIBCEF_BROWSER_NET_URL_REQUEST_MANAGER_H_

View File

@@ -1,19 +0,0 @@
// Copyright (c) 2012 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/net/url_request_user_data.h"
CefURLRequestUserData::CefURLRequestUserData(
CefRefPtr<CefURLRequestClient> client)
: client_(client) {}
CefURLRequestUserData::~CefURLRequestUserData() {}
CefRefPtr<CefURLRequestClient> CefURLRequestUserData::GetClient() {
return client_;
}
// static
const void* CefURLRequestUserData::kUserDataKey =
static_cast<const void*>(&CefURLRequestUserData::kUserDataKey);

View File

@@ -1,27 +0,0 @@
// Copyright (c) 2012 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_NET_URL_REQUEST_USER_DATA_H_
#define CEF_LIBCEF_BROWSER_NET_URL_REQUEST_USER_DATA_H_
#include "include/cef_base.h"
#include "include/cef_urlrequest.h"
#include "base/supports_user_data.h"
// Used to annotate all URLRequests for which the request can be associated
// with the CefURLRequestClient.
class CefURLRequestUserData : public base::SupportsUserData::Data {
public:
CefURLRequestUserData(CefRefPtr<CefURLRequestClient> client);
~CefURLRequestUserData() override;
CefRefPtr<CefURLRequestClient> GetClient();
static const void* kUserDataKey;
private:
CefRefPtr<CefURLRequestClient> client_;
};
#endif // CEF_LIBCEF_BROWSER_NET_URL_REQUEST_USER_DATA_H_