mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
When NetworkService is enabled requests created using CefFrame::CreateURLRequest will call CefRequestHandler::GetAuthCredentials for the associated browser after calling CefURLRequestClient::GetAuthCredentials if that call returns false.
This commit is contained in:
@ -22,12 +22,88 @@
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "content/public/browser/global_request_id.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "services/network/public/cpp/shared_url_loader_factory.h"
|
||||
#include "services/network/public/cpp/simple_url_loader.h"
|
||||
#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const int32_t kInitialRequestID = -2;
|
||||
|
||||
// Request ID for requests initiated by CefBrowserURLRequest. request_ids
|
||||
// generated by child processes are counted up from 0, while browser
|
||||
// created requests start at -2 and go down from there. (We need to start at -2
|
||||
// because -1 is used as a special value all over the resource_dispatcher_host
|
||||
// for uninitialized variables.) The resource_dispatcher_host code path is not
|
||||
// used when NetworkService is enabled so it's safe to repurpose the -2 and
|
||||
// below range here.
|
||||
// This method is only called on the UI thread.
|
||||
int32_t MakeRequestID() {
|
||||
static int32_t request_id = kInitialRequestID;
|
||||
return --request_id;
|
||||
}
|
||||
|
||||
// Manages the mapping of request IDs to request objects.
|
||||
class RequestManager {
|
||||
public:
|
||||
RequestManager() {}
|
||||
~RequestManager() { DCHECK(map_.empty()); }
|
||||
|
||||
void Add(int32_t request_id,
|
||||
CefRefPtr<CefBrowserURLRequest> request,
|
||||
CefRefPtr<CefURLRequestClient> client) {
|
||||
DCHECK_LE(request_id, kInitialRequestID);
|
||||
|
||||
base::AutoLock lock_scope(lock_);
|
||||
DCHECK(map_.find(request_id) == map_.end());
|
||||
map_.insert(std::make_pair(request_id, std::make_pair(request, client)));
|
||||
}
|
||||
|
||||
void Remove(int32_t request_id) {
|
||||
if (request_id > kInitialRequestID)
|
||||
return;
|
||||
|
||||
base::AutoLock lock_scope(lock_);
|
||||
RequestMap::iterator it = map_.find(request_id);
|
||||
DCHECK(it != map_.end());
|
||||
map_.erase(it);
|
||||
}
|
||||
|
||||
base::Optional<CefBrowserURLRequest::RequestInfo> Get(int32_t request_id) {
|
||||
if (request_id > kInitialRequestID)
|
||||
return base::nullopt;
|
||||
|
||||
base::AutoLock lock_scope(lock_);
|
||||
RequestMap::const_iterator it = map_.find(request_id);
|
||||
if (it != map_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return base::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
base::Lock lock_;
|
||||
|
||||
using RequestMap = std::map<int32_t, CefBrowserURLRequest::RequestInfo>;
|
||||
RequestMap map_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RequestManager);
|
||||
};
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
// Because of DCHECK()s in the object destructor.
|
||||
base::LazyInstance<RequestManager>::DestructorAtExit g_manager =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
#else
|
||||
base::LazyInstance<RequestManager>::Leaky g_manager = LAZY_INSTANCE_INITIALIZER;
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
// CefBrowserURLRequest::Context ----------------------------------------------
|
||||
|
||||
class CefBrowserURLRequest::Context
|
||||
@ -113,6 +189,7 @@ class CefBrowserURLRequest::Context
|
||||
request_context_impl->GetBrowserContext();
|
||||
DCHECK(browser_context);
|
||||
|
||||
int render_frame_id = MSG_ROUTING_NONE;
|
||||
scoped_refptr<net_service::URLLoaderFactoryGetter> loader_factory_getter;
|
||||
if (frame) {
|
||||
// The request will be associated with this frame/browser if it's valid,
|
||||
@ -120,6 +197,14 @@ class CefBrowserURLRequest::Context
|
||||
content::RenderFrameHost* rfh =
|
||||
static_cast<CefFrameHostImpl*>(frame.get())->GetRenderFrameHost();
|
||||
if (rfh) {
|
||||
// In cases where authentication is required this value will be passed
|
||||
// as the |routing_id| parameter to
|
||||
// NetworkServiceClient::OnAuthRequired. Despite the naming the
|
||||
// GetWebContents method in network_service_client.cc expects it to be a
|
||||
// FrameTreeNodeId. The |process_id| parameter will always be
|
||||
// network::mojom::kBrowserProcessId (value 0) for these requests.
|
||||
render_frame_id = rfh->GetFrameTreeNodeId();
|
||||
|
||||
loader_factory_getter =
|
||||
net_service::URLLoaderFactoryGetter::Create(rfh, browser_context);
|
||||
}
|
||||
@ -132,10 +217,12 @@ class CefBrowserURLRequest::Context
|
||||
FROM_HERE,
|
||||
base::BindOnce(
|
||||
&CefBrowserURLRequest::Context::ContinueOnOriginatingThread, self,
|
||||
loader_factory_getter));
|
||||
render_frame_id, MakeRequestID(), loader_factory_getter));
|
||||
}
|
||||
|
||||
void ContinueOnOriginatingThread(
|
||||
int render_frame_id,
|
||||
int32_t request_id,
|
||||
scoped_refptr<net_service::URLLoaderFactoryGetter>
|
||||
loader_factory_getter) {
|
||||
DCHECK(CalledOnValidThread());
|
||||
@ -163,6 +250,8 @@ class CefBrowserURLRequest::Context
|
||||
static_cast<CefRequestImpl*>(request_.get())
|
||||
->Get(resource_request.get(), false);
|
||||
|
||||
resource_request->render_frame_id = render_frame_id;
|
||||
|
||||
// SimpleURLLoader is picky about the body contents. Try to populate them
|
||||
// correctly below.
|
||||
auto request_body = resource_request->request_body;
|
||||
@ -187,6 +276,11 @@ class CefBrowserURLRequest::Context
|
||||
loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
|
||||
NO_TRAFFIC_ANNOTATION_YET);
|
||||
|
||||
// Associate the request with |request_id|.
|
||||
request_id_ = request_id;
|
||||
loader_->SetRequestId(request_id);
|
||||
g_manager.Get().Add(request_id, url_request_, client_);
|
||||
|
||||
if (request_body) {
|
||||
if (request_body->elements()->size() == 1) {
|
||||
const auto& element = (*request_body->elements())[0];
|
||||
@ -294,6 +388,7 @@ class CefBrowserURLRequest::Context
|
||||
DCHECK(request_->GetFlags() | UR_FLAG_STOP_ON_REDIRECT);
|
||||
|
||||
response_->SetReadOnly(false);
|
||||
response_->SetURL(redirect_info.new_url.spec());
|
||||
response_->SetResponseHeaders(*response_head.headers);
|
||||
response_->SetReadOnly(true);
|
||||
|
||||
@ -403,6 +498,8 @@ class CefBrowserURLRequest::Context
|
||||
DCHECK(CalledOnValidThread());
|
||||
DCHECK(url_request_);
|
||||
|
||||
g_manager.Get().Remove(request_id_);
|
||||
|
||||
client_ = nullptr;
|
||||
request_context_ = nullptr;
|
||||
|
||||
@ -439,6 +536,8 @@ class CefBrowserURLRequest::Context
|
||||
scoped_refptr<net_service::URLLoaderFactoryGetter> loader_factory_getter_;
|
||||
std::unique_ptr<network::SimpleURLLoader> loader_;
|
||||
|
||||
int32_t request_id_ = 0;
|
||||
|
||||
CefURLRequest::Status status_ = UR_IO_PENDING;
|
||||
CefRefPtr<CefResponseImpl> response_;
|
||||
bool response_was_cached_ = false;
|
||||
@ -453,6 +552,22 @@ class CefBrowserURLRequest::Context
|
||||
|
||||
// CefBrowserURLRequest -------------------------------------------------------
|
||||
|
||||
// static
|
||||
base::Optional<CefBrowserURLRequest::RequestInfo>
|
||||
CefBrowserURLRequest::FromRequestID(int32_t request_id) {
|
||||
return g_manager.Get().Get(request_id);
|
||||
}
|
||||
|
||||
// static
|
||||
base::Optional<CefBrowserURLRequest::RequestInfo>
|
||||
CefBrowserURLRequest::FromRequestID(
|
||||
const content::GlobalRequestID& request_id) {
|
||||
if (request_id.child_id == network::mojom::kBrowserProcessId) {
|
||||
return FromRequestID(request_id.request_id);
|
||||
}
|
||||
return base::nullopt;
|
||||
}
|
||||
|
||||
CefBrowserURLRequest::CefBrowserURLRequest(
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
|
Reference in New Issue
Block a user