Fix possible use after shutdown of BrowserContext (fixes issue #3193)
This commit is contained in:
parent
839fdb211c
commit
ff0e5c0348
|
@ -213,6 +213,9 @@ void CefBrowserContext::Shutdown() {
|
||||||
|
|
||||||
// Destroy objects that may hold references to the MediaRouter.
|
// Destroy objects that may hold references to the MediaRouter.
|
||||||
media_router_manager_.reset();
|
media_router_manager_.reset();
|
||||||
|
|
||||||
|
// Invalidate any Getter references to this object.
|
||||||
|
weak_ptr_factory_.InvalidateWeakPtrs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserContext::AddCefRequestContext(CefRequestContextImpl* context) {
|
void CefBrowserContext::AddCefRequestContext(CefRequestContextImpl* context) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ CefBrowserContext* GetBrowserContext(const CefBrowserContext::Getter& getter) {
|
||||||
CEF_REQUIRE_UIT();
|
CEF_REQUIRE_UIT();
|
||||||
DCHECK(!getter.is_null());
|
DCHECK(!getter.is_null());
|
||||||
|
|
||||||
// Will return nullptr if the BrowserContext has been destroyed.
|
// Will return nullptr if the BrowserContext has been shut down.
|
||||||
return getter.Run();
|
return getter.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ CefBrowserContext* GetBrowserContext(const CefBrowserContext::Getter& getter) {
|
||||||
CEF_REQUIRE_UIT();
|
CEF_REQUIRE_UIT();
|
||||||
DCHECK(!getter.is_null());
|
DCHECK(!getter.is_null());
|
||||||
|
|
||||||
// Will return nullptr if the BrowserContext has been destroyed.
|
// Will return nullptr if the BrowserContext has been shut down.
|
||||||
return getter.Run();
|
return getter.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,16 @@ namespace cookie_helper {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Do not keep a reference to the CookieManager returned by this method.
|
// Do not keep a reference to the object returned by this method.
|
||||||
|
CefBrowserContext* GetBrowserContext(const CefBrowserContext::Getter& getter) {
|
||||||
|
CEF_REQUIRE_UIT();
|
||||||
|
DCHECK(!getter.is_null());
|
||||||
|
|
||||||
|
// Will return nullptr if the BrowserContext has been shut down.
|
||||||
|
return getter.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not keep a reference to the object returned by this method.
|
||||||
network::mojom::CookieManager* GetCookieManager(
|
network::mojom::CookieManager* GetCookieManager(
|
||||||
content::BrowserContext* browser_context) {
|
content::BrowserContext* browser_context) {
|
||||||
CEF_REQUIRE_UIT();
|
CEF_REQUIRE_UIT();
|
||||||
|
@ -82,13 +91,22 @@ void GetCookieListCallback(const AllowCookieCallback& allow_cookie_callback,
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadCookiesOnUIThread(
|
void LoadCookiesOnUIThread(
|
||||||
content::BrowserContext* browser_context,
|
const CefBrowserContext::Getter& browser_context_getter,
|
||||||
const GURL& url,
|
const GURL& url,
|
||||||
const net::CookieOptions& options,
|
const net::CookieOptions& options,
|
||||||
net::CookiePartitionKeyCollection cookie_partition_key_collection,
|
net::CookiePartitionKeyCollection cookie_partition_key_collection,
|
||||||
const AllowCookieCallback& allow_cookie_callback,
|
const AllowCookieCallback& allow_cookie_callback,
|
||||||
DoneCookieCallback done_callback) {
|
DoneCookieCallback done_callback) {
|
||||||
CEF_REQUIRE_UIT();
|
auto cef_browser_context = GetBrowserContext(browser_context_getter);
|
||||||
|
auto browser_context =
|
||||||
|
cef_browser_context ? cef_browser_context->AsBrowserContext() : nullptr;
|
||||||
|
if (!browser_context) {
|
||||||
|
GetCookieListCallback(allow_cookie_callback, std::move(done_callback),
|
||||||
|
net::CookieAccessResultList(),
|
||||||
|
net::CookieAccessResultList());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GetCookieManager(browser_context)
|
GetCookieManager(browser_context)
|
||||||
->GetCookieList(
|
->GetCookieList(
|
||||||
url, options, cookie_partition_key_collection,
|
url, options, cookie_partition_key_collection,
|
||||||
|
@ -126,15 +144,23 @@ void SetCanonicalCookieCallback(SaveCookiesProgress* progress,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveCookiesOnUIThread(content::BrowserContext* browser_context,
|
void SaveCookiesOnUIThread(
|
||||||
|
const CefBrowserContext::Getter& browser_context_getter,
|
||||||
const GURL& url,
|
const GURL& url,
|
||||||
const net::CookieOptions& options,
|
const net::CookieOptions& options,
|
||||||
int total_count,
|
int total_count,
|
||||||
net::CookieList cookies,
|
net::CookieList cookies,
|
||||||
DoneCookieCallback done_callback) {
|
DoneCookieCallback done_callback) {
|
||||||
CEF_REQUIRE_UIT();
|
|
||||||
DCHECK(!cookies.empty());
|
DCHECK(!cookies.empty());
|
||||||
|
|
||||||
|
auto cef_browser_context = GetBrowserContext(browser_context_getter);
|
||||||
|
auto browser_context =
|
||||||
|
cef_browser_context ? cef_browser_context->AsBrowserContext() : nullptr;
|
||||||
|
if (!browser_context) {
|
||||||
|
std::move(done_callback).Run(0, net::CookieList());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
network::mojom::CookieManager* cookie_manager =
|
network::mojom::CookieManager* cookie_manager =
|
||||||
GetCookieManager(browser_context);
|
GetCookieManager(browser_context);
|
||||||
|
|
||||||
|
@ -186,7 +212,7 @@ bool IsCookieableScheme(
|
||||||
return url.SchemeIsHTTPOrHTTPS() || url.SchemeIsWSOrWSS();
|
return url.SchemeIsHTTPOrHTTPS() || url.SchemeIsWSOrWSS();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadCookies(content::BrowserContext* browser_context,
|
void LoadCookies(const CefBrowserContext::Getter& browser_context_getter,
|
||||||
const network::ResourceRequest& request,
|
const network::ResourceRequest& request,
|
||||||
const AllowCookieCallback& allow_cookie_callback,
|
const AllowCookieCallback& allow_cookie_callback,
|
||||||
DoneCookieCallback done_callback) {
|
DoneCookieCallback done_callback) {
|
||||||
|
@ -201,14 +227,13 @@ void LoadCookies(content::BrowserContext* browser_context,
|
||||||
}
|
}
|
||||||
|
|
||||||
CEF_POST_TASK(
|
CEF_POST_TASK(
|
||||||
CEF_UIT,
|
CEF_UIT, base::BindOnce(LoadCookiesOnUIThread, browser_context_getter,
|
||||||
base::BindOnce(LoadCookiesOnUIThread, browser_context, request.url,
|
request.url, GetCookieOptions(request),
|
||||||
GetCookieOptions(request),
|
|
||||||
net::CookiePartitionKeyCollection(),
|
net::CookiePartitionKeyCollection(),
|
||||||
allow_cookie_callback, std::move(done_callback)));
|
allow_cookie_callback, std::move(done_callback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveCookies(content::BrowserContext* browser_context,
|
void SaveCookies(const CefBrowserContext::Getter& browser_context_getter,
|
||||||
const network::ResourceRequest& request,
|
const network::ResourceRequest& request,
|
||||||
net::HttpResponseHeaders* headers,
|
net::HttpResponseHeaders* headers,
|
||||||
const AllowCookieCallback& allow_cookie_callback,
|
const AllowCookieCallback& allow_cookie_callback,
|
||||||
|
@ -256,8 +281,8 @@ void SaveCookies(content::BrowserContext* browser_context,
|
||||||
if (!allowed_cookies.empty()) {
|
if (!allowed_cookies.empty()) {
|
||||||
CEF_POST_TASK(
|
CEF_POST_TASK(
|
||||||
CEF_UIT,
|
CEF_UIT,
|
||||||
base::BindOnce(SaveCookiesOnUIThread, browser_context, request.url,
|
base::BindOnce(SaveCookiesOnUIThread, browser_context_getter,
|
||||||
GetCookieOptions(request), total_count,
|
request.url, GetCookieOptions(request), total_count,
|
||||||
std::move(allowed_cookies), std::move(done_callback)));
|
std::move(allowed_cookies), std::move(done_callback)));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,13 +5,11 @@
|
||||||
#ifndef CEF_LIBCEF_BROWSER_NET_SERVICE_COOKIE_HELPER_H_
|
#ifndef CEF_LIBCEF_BROWSER_NET_SERVICE_COOKIE_HELPER_H_
|
||||||
#define CEF_LIBCEF_BROWSER_NET_SERVICE_COOKIE_HELPER_H_
|
#define CEF_LIBCEF_BROWSER_NET_SERVICE_COOKIE_HELPER_H_
|
||||||
|
|
||||||
|
#include "libcef/browser/browser_context.h"
|
||||||
|
|
||||||
#include "base/callback_forward.h"
|
#include "base/callback_forward.h"
|
||||||
#include "net/cookies/canonical_cookie.h"
|
#include "net/cookies/canonical_cookie.h"
|
||||||
|
|
||||||
namespace content {
|
|
||||||
class BrowserContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace net {
|
namespace net {
|
||||||
class HttpResponseHeaders;
|
class HttpResponseHeaders;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +42,7 @@ using DoneCookieCallback =
|
||||||
// both retrieved and allowed by |allow_cookie_callback|. The loaded cookies
|
// both retrieved and allowed by |allow_cookie_callback|. The loaded cookies
|
||||||
// will not be set on |request|; that should be done in |done_callback|. Must be
|
// will not be set on |request|; that should be done in |done_callback|. Must be
|
||||||
// called on the IO thread.
|
// called on the IO thread.
|
||||||
void LoadCookies(content::BrowserContext* browser_context,
|
void LoadCookies(const CefBrowserContext::Getter& browser_context_getter,
|
||||||
const network::ResourceRequest& request,
|
const network::ResourceRequest& request,
|
||||||
const AllowCookieCallback& allow_cookie_callback,
|
const AllowCookieCallback& allow_cookie_callback,
|
||||||
DoneCookieCallback done_callback);
|
DoneCookieCallback done_callback);
|
||||||
|
@ -55,7 +53,7 @@ void LoadCookies(content::BrowserContext* browser_context,
|
||||||
// retrieved, and |allowed_cookies| representing the list of cookies that were
|
// retrieved, and |allowed_cookies| representing the list of cookies that were
|
||||||
// both allowed by |allow_cookie_callback| an successfully saved. Must be called
|
// both allowed by |allow_cookie_callback| an successfully saved. Must be called
|
||||||
// on the IO thread.
|
// on the IO thread.
|
||||||
void SaveCookies(content::BrowserContext* browser_context,
|
void SaveCookies(const CefBrowserContext::Getter& browser_context_getter,
|
||||||
const network::ResourceRequest& request,
|
const network::ResourceRequest& request,
|
||||||
net::HttpResponseHeaders* headers,
|
net::HttpResponseHeaders* headers,
|
||||||
const AllowCookieCallback& allow_cookie_callback,
|
const AllowCookieCallback& allow_cookie_callback,
|
||||||
|
|
|
@ -23,7 +23,7 @@ CefBrowserContext* GetBrowserContext(const CefBrowserContext::Getter& getter) {
|
||||||
CEF_REQUIRE_UIT();
|
CEF_REQUIRE_UIT();
|
||||||
DCHECK(!getter.is_null());
|
DCHECK(!getter.is_null());
|
||||||
|
|
||||||
// Will return nullptr if the BrowserContext has been destroyed.
|
// Will return nullptr if the BrowserContext has been shut down.
|
||||||
return getter.Run();
|
return getter.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -244,10 +244,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||||
const base::RepeatingClosure& unhandled_request_callback) {
|
const base::RepeatingClosure& unhandled_request_callback) {
|
||||||
CEF_REQUIRE_UIT();
|
CEF_REQUIRE_UIT();
|
||||||
|
|
||||||
browser_context_ = browser_context;
|
|
||||||
|
|
||||||
auto profile = Profile::FromBrowserContext(browser_context);
|
auto profile = Profile::FromBrowserContext(browser_context);
|
||||||
auto cef_browser_context = CefBrowserContext::FromProfile(profile);
|
auto cef_browser_context = CefBrowserContext::FromProfile(profile);
|
||||||
|
browser_context_getter_ = cef_browser_context->getter();
|
||||||
iothread_state_ = cef_browser_context->iothread_state();
|
iothread_state_ = cef_browser_context->iothread_state();
|
||||||
CHECK(iothread_state_);
|
CHECK(iothread_state_);
|
||||||
cookieable_schemes_ = cef_browser_context->GetCookieableSchemes();
|
cookieable_schemes_ = cef_browser_context->GetCookieableSchemes();
|
||||||
|
@ -291,7 +290,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||||
std::unique_ptr<DestructionObserver> observer) {}
|
std::unique_ptr<DestructionObserver> observer) {}
|
||||||
|
|
||||||
// Only accessed on the UI thread.
|
// Only accessed on the UI thread.
|
||||||
content::BrowserContext* browser_context_ = nullptr;
|
CefBrowserContext::Getter browser_context_getter_;
|
||||||
|
|
||||||
bool initialized_ = false;
|
bool initialized_ = false;
|
||||||
|
|
||||||
|
@ -410,7 +409,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||||
static void TryCreateURLLoaderNetworkObserver(
|
static void TryCreateURLLoaderNetworkObserver(
|
||||||
std::unique_ptr<PendingRequest> pending_request,
|
std::unique_ptr<PendingRequest> pending_request,
|
||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
content::BrowserContext* browser_context,
|
const CefBrowserContext::Getter& browser_context_getter,
|
||||||
base::WeakPtr<InterceptedRequestHandlerWrapper> self) {
|
base::WeakPtr<InterceptedRequestHandlerWrapper> self) {
|
||||||
CEF_REQUIRE_UIT();
|
CEF_REQUIRE_UIT();
|
||||||
|
|
||||||
|
@ -428,11 +427,17 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||||
->CreateURLLoaderNetworkObserver();
|
->CreateURLLoaderNetworkObserver();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
auto cef_browser_context = browser_context_getter.Run();
|
||||||
|
auto browser_context = cef_browser_context
|
||||||
|
? cef_browser_context->AsBrowserContext()
|
||||||
|
: nullptr;
|
||||||
|
if (browser_context) {
|
||||||
url_loader_network_observer =
|
url_loader_network_observer =
|
||||||
static_cast<content::StoragePartitionImpl*>(
|
static_cast<content::StoragePartitionImpl*>(
|
||||||
browser_context->GetDefaultStoragePartition())
|
browser_context->GetDefaultStoragePartition())
|
||||||
->CreateAuthCertObserverForServiceWorker();
|
->CreateAuthCertObserverForServiceWorker();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CEF_POST_TASK(CEF_IOT,
|
CEF_POST_TASK(CEF_IOT,
|
||||||
base::BindOnce(&InterceptedRequestHandlerWrapper::
|
base::BindOnce(&InterceptedRequestHandlerWrapper::
|
||||||
|
@ -488,7 +493,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||||
std::make_unique<PendingRequest>(
|
std::make_unique<PendingRequest>(
|
||||||
request_id, request, request_was_redirected,
|
request_id, request, request_was_redirected,
|
||||||
std::move(callback), std::move(cancel_callback)),
|
std::move(callback), std::move(cancel_callback)),
|
||||||
init_state_->frame_, init_state_->browser_context_,
|
init_state_->frame_,
|
||||||
|
init_state_->browser_context_getter_,
|
||||||
weak_ptr_factory_.GetWeakPtr()));
|
weak_ptr_factory_.GetWeakPtr()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -582,7 +588,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||||
&InterceptedRequestHandlerWrapper::ContinueWithLoadedCookies,
|
&InterceptedRequestHandlerWrapper::ContinueWithLoadedCookies,
|
||||||
weak_ptr_factory_.GetWeakPtr(), request_id, request,
|
weak_ptr_factory_.GetWeakPtr(), request_id, request,
|
||||||
std::move(callback));
|
std::move(callback));
|
||||||
cookie_helper::LoadCookies(init_state_->browser_context_, *request,
|
cookie_helper::LoadCookies(init_state_->browser_context_getter_, *request,
|
||||||
allow_cookie_callback,
|
allow_cookie_callback,
|
||||||
std::move(done_cookie_callback));
|
std::move(done_cookie_callback));
|
||||||
}
|
}
|
||||||
|
@ -960,8 +966,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||||
auto done_cookie_callback = base::BindOnce(
|
auto done_cookie_callback = base::BindOnce(
|
||||||
&InterceptedRequestHandlerWrapper::ContinueWithSavedCookies,
|
&InterceptedRequestHandlerWrapper::ContinueWithSavedCookies,
|
||||||
weak_ptr_factory_.GetWeakPtr(), request_id, std::move(callback));
|
weak_ptr_factory_.GetWeakPtr(), request_id, std::move(callback));
|
||||||
cookie_helper::SaveCookies(init_state_->browser_context_, *request, headers,
|
cookie_helper::SaveCookies(init_state_->browser_context_getter_, *request,
|
||||||
allow_cookie_callback,
|
headers, allow_cookie_callback,
|
||||||
std::move(done_cookie_callback));
|
std::move(done_cookie_callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue