Add NetworkService support for CefURLRequest (see issue #2622).

Requests created using CefURLRequest::Create are not associated with a
browser/frame. When originating from the render process these requests cannot be
intercepted and consequently only http(s) and blob requests are supported. To
work around this limitation a new CefFrame::CreateURLRequest method has been
added that allows the request to be associated with that browser/frame for
interception purposes.

This change also fixes an issue with the NetworkService implementation where
redirected requests could result in two parallel requests being sent to the
target server.

To test: URLRequestTest.* tests pass with NetworkService enabled.
This commit is contained in:
Marshall Greenblatt
2019-05-10 18:14:48 -04:00
parent f9b042c375
commit ba0e1b5719
43 changed files with 1637 additions and 344 deletions

View File

@@ -243,6 +243,15 @@ void CefContentRendererClient::OnGuestViewDestroyed(CefGuestView* guest_view) {
NOTREACHED();
}
blink::WebURLLoaderFactory*
CefContentRendererClient::GetDefaultURLLoaderFactory() {
if (!default_url_loader_factory_) {
default_url_loader_factory_ =
blink::Platform::Current()->CreateDefaultURLLoaderFactory();
}
return default_url_loader_factory_.get();
}
void CefContentRendererClient::WebKitInitialized() {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
@@ -302,9 +311,6 @@ void CefContentRendererClient::WebKitInitialized() {
}
}
url_loader_factory_ =
blink::Platform::Current()->CreateDefaultURLLoaderFactory();
// Notify the render process handler.
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
if (application.get()) {

View File

@@ -87,10 +87,9 @@ class CefContentRendererClient
return uncaught_exception_stack_size_;
}
// Used by CefRenderURLRequest to create WebURLLoaders.
blink::WebURLLoaderFactory* url_loader_factory() const {
return url_loader_factory_.get();
}
// Returns a factory that only supports unintercepted http(s) and blob
// requests. Used by CefRenderURLRequest.
blink::WebURLLoaderFactory* GetDefaultURLLoaderFactory();
void WebKitInitialized();
@@ -169,7 +168,8 @@ class CefContentRendererClient
std::unique_ptr<CefRenderThreadObserver> observer_;
std::unique_ptr<web_cache::WebCacheImpl> web_cache_impl_;
std::unique_ptr<SpellCheck> spellcheck_;
std::unique_ptr<blink::WebURLLoaderFactory> url_loader_factory_;
std::unique_ptr<blink::WebURLLoaderFactory> default_url_loader_factory_;
// Map of RenderView pointers to CefBrowserImpl references.
typedef std::map<content::RenderView*, CefRefPtr<CefBrowserImpl>> BrowserMap;

View File

@@ -24,10 +24,11 @@
#include "libcef/renderer/browser_impl.h"
#include "libcef/renderer/dom_document_impl.h"
#include "libcef/renderer/render_frame_util.h"
#include "libcef/renderer/render_urlrequest_impl.h"
#include "libcef/renderer/thread_util.h"
#include "libcef/renderer/v8_impl.h"
#include "content/public/renderer/render_frame.h"
#include "content/renderer/render_frame_impl.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
@@ -275,9 +276,36 @@ void CefFrameImpl::VisitDOM(CefRefPtr<CefDOMVisitor> visitor) {
documentImpl->Detach();
}
CefRefPtr<CefURLRequest> CefFrameImpl::CreateURLRequest(
CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client) {
CEF_REQUIRE_RT_RETURN(NULL);
if (!request || !client || !frame_)
return NULL;
CefRefPtr<CefRenderURLRequest> impl =
new CefRenderURLRequest(this, request, client);
if (impl->Start())
return impl.get();
return NULL;
}
blink::WebURLLoaderFactory* CefFrameImpl::GetURLLoaderFactory() {
CEF_REQUIRE_RT();
if (!url_loader_factory_ && frame_) {
auto render_frame = content::RenderFrameImpl::FromWebFrame(frame_);
if (render_frame) {
url_loader_factory_ = render_frame->CreateURLLoaderFactory();
}
}
return url_loader_factory_.get();
}
void CefFrameImpl::Detach() {
browser_ = NULL;
frame_ = NULL;
url_loader_factory_.reset();
}
void CefFrameImpl::ExecuteCommand(const std::string& command) {

View File

@@ -14,7 +14,8 @@ class CefBrowserImpl;
namespace blink {
class WebLocalFrame;
}
class WebURLLoaderFactory;
} // namespace blink
// Implementation of CefFrame. CefFrameImpl objects are owned by the
// CefBrowerImpl and will be detached when the browser is notified that the
@@ -53,6 +54,12 @@ class CefFrameImpl : public CefFrame {
CefRefPtr<CefBrowser> GetBrowser() override;
CefRefPtr<CefV8Context> GetV8Context() override;
void VisitDOM(CefRefPtr<CefDOMVisitor> visitor) override;
CefRefPtr<CefURLRequest> CreateURLRequest(
CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client) override;
// Used by CefRenderURLRequest.
blink::WebURLLoaderFactory* GetURLLoaderFactory();
void Detach();
@@ -65,6 +72,8 @@ class CefFrameImpl : public CefFrame {
blink::WebLocalFrame* frame_;
int64 frame_id_;
std::unique_ptr<blink::WebURLLoaderFactory> url_loader_factory_;
IMPLEMENT_REFCOUNTING(CefFrameImpl);
DISALLOW_COPY_AND_ASSIGN(CefFrameImpl);
};

View File

@@ -20,7 +20,7 @@
#include "libcef/common/cef_messages.h"
#include "libcef/common/content_client.h"
#include "libcef/renderer/blink_glue.h"
#include "libcef/renderer/content_renderer_client.h"
#include "libcef/renderer/browser_impl.h"
#include "libcef/renderer/v8_impl.h"
#include "content/public/renderer/render_frame.h"

View File

@@ -81,9 +81,11 @@ class CefRenderURLRequest::Context
: public base::RefCountedThreadSafe<CefRenderURLRequest::Context> {
public:
Context(CefRefPtr<CefRenderURLRequest> url_request,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client)
: url_request_(url_request),
frame_(frame),
request_(request),
client_(client),
task_runner_(CefTaskRunnerImpl::GetCurrentTaskRunner()),
@@ -121,10 +123,19 @@ class CefRenderURLRequest::Context
urlRequest.SetRequestorOrigin(
blink::WebSecurityOrigin::Create(urlRequest.Url()));
loader_ =
CefContentRendererClient::Get()->url_loader_factory()->CreateURLLoader(
urlRequest, blink::scheduler::WebResourceLoadingTaskRunnerHandle::
CreateUnprioritized(task_runner_.get()));
blink::WebURLLoaderFactory* factory = nullptr;
if (frame_) {
// This factory supports all requests.
factory = static_cast<CefFrameImpl*>(frame_.get())->GetURLLoaderFactory();
}
if (!factory) {
// This factory only supports unintercepted http(s) and blob requests.
factory = CefContentRendererClient::Get()->GetDefaultURLLoaderFactory();
}
loader_ = factory->CreateURLLoader(
urlRequest, blink::scheduler::WebResourceLoadingTaskRunnerHandle::
CreateUnprioritized(task_runner_.get()));
loader_->LoadAsynchronously(urlRequest, url_client_.get());
return true;
}
@@ -316,6 +327,7 @@ class CefRenderURLRequest::Context
// Members only accessed on the initialization thread.
CefRefPtr<CefRenderURLRequest> url_request_;
CefRefPtr<CefFrame> frame_;
CefRefPtr<CefRequest> request_;
CefRefPtr<CefURLRequestClient> client_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
@@ -404,9 +416,10 @@ bool CefWebURLLoaderClient::WillFollowRedirect(
// CefRenderURLRequest --------------------------------------------------------
CefRenderURLRequest::CefRenderURLRequest(
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client) {
context_ = new Context(this, request, client);
context_ = new Context(this, frame, request, client);
}
CefRenderURLRequest::~CefRenderURLRequest() {}

View File

@@ -5,6 +5,7 @@
#ifndef CEF_LIBCEF_RENDERER_RENDER_URLREQUEST_IMPL_H_
#define CEF_LIBCEF_RENDERER_RENDER_URLREQUEST_IMPL_H_
#include "include/cef_frame.h"
#include "include/cef_urlrequest.h"
#include "base/memory/ref_counted.h"
@@ -13,7 +14,11 @@ class CefRenderURLRequest : public CefURLRequest {
public:
class Context;
CefRenderURLRequest(CefRefPtr<CefRequest> request,
// If |frame| is nullptr the default URLLoaderFactory will be used. That
// factory only supports http(s) and blob requests that cannot be
// intercepted in the browser process.
CefRenderURLRequest(CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client);
~CefRenderURLRequest() override;