Allow clients to clear certificate exceptions and close connections (issue #1793)
This commit is contained in:
parent
e601e76445
commit
fabd3db33e
|
@ -38,6 +38,7 @@
|
||||||
#define CEF_INCLUDE_CAPI_CEF_REQUEST_CONTEXT_CAPI_H_
|
#define CEF_INCLUDE_CAPI_CEF_REQUEST_CONTEXT_CAPI_H_
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/capi/cef_callback_capi.h"
|
||||||
#include "include/capi/cef_cookie_capi.h"
|
#include "include/capi/cef_cookie_capi.h"
|
||||||
#include "include/capi/cef_request_context_handler_capi.h"
|
#include "include/capi/cef_request_context_handler_capi.h"
|
||||||
#include "include/capi/cef_values_capi.h"
|
#include "include/capi/cef_values_capi.h"
|
||||||
|
@ -199,6 +200,28 @@ typedef struct _cef_request_context_t {
|
||||||
int (CEF_CALLBACK *set_preference)(struct _cef_request_context_t* self,
|
int (CEF_CALLBACK *set_preference)(struct _cef_request_context_t* self,
|
||||||
const cef_string_t* name, struct _cef_value_t* value,
|
const cef_string_t* name, struct _cef_value_t* value,
|
||||||
cef_string_t* error);
|
cef_string_t* error);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Clears all certificate exceptions that were added as part of handling
|
||||||
|
// cef_request_tHandler::on_certificate_error(). If you call this it is
|
||||||
|
// recommended that you also call close_all_connections() or you risk not
|
||||||
|
// being prompted again for server certificates if you reconnect quickly. If
|
||||||
|
// |callback| is non-NULL it will be executed on the UI thread after
|
||||||
|
// completion.
|
||||||
|
///
|
||||||
|
void (CEF_CALLBACK *clear_certificate_exceptions)(
|
||||||
|
struct _cef_request_context_t* self,
|
||||||
|
struct _cef_completion_callback_t* callback);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Clears all active and idle connections that Chromium currently has. This is
|
||||||
|
// only recommended if you have released all other CEF objects but don't yet
|
||||||
|
// want to call cef_shutdown(). If |callback| is non-NULL it will be executed
|
||||||
|
// on the UI thread after completion.
|
||||||
|
///
|
||||||
|
void (CEF_CALLBACK *close_all_connections)(
|
||||||
|
struct _cef_request_context_t* self,
|
||||||
|
struct _cef_completion_callback_t* callback);
|
||||||
} cef_request_context_t;
|
} cef_request_context_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#define CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_
|
#define CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/cef_callback.h"
|
||||||
#include "include/cef_cookie.h"
|
#include "include/cef_cookie.h"
|
||||||
#include "include/cef_request_context_handler.h"
|
#include "include/cef_request_context_handler.h"
|
||||||
#include "include/cef_values.h"
|
#include "include/cef_values.h"
|
||||||
|
@ -217,6 +218,28 @@ class CefRequestContext : public virtual CefBase {
|
||||||
virtual bool SetPreference(const CefString& name,
|
virtual bool SetPreference(const CefString& name,
|
||||||
CefRefPtr<CefValue> value,
|
CefRefPtr<CefValue> value,
|
||||||
CefString& error) =0;
|
CefString& error) =0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Clears all certificate exceptions that were added as part of handling
|
||||||
|
// CefRequestHandler::OnCertificateError(). If you call this it is
|
||||||
|
// recommended that you also call CloseAllConnections() or you risk not
|
||||||
|
// being prompted again for server certificates if you reconnect quickly.
|
||||||
|
// If |callback| is non-NULL it will be executed on the UI thread after
|
||||||
|
// completion.
|
||||||
|
///
|
||||||
|
/*--cef(optional_param=callback)--*/
|
||||||
|
virtual void ClearCertificateExceptions(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback) =0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Clears all active and idle connections that Chromium currently has.
|
||||||
|
// This is only recommended if you have released all other CEF objects but
|
||||||
|
// don't yet want to call CefShutdown(). If |callback| is non-NULL it will be
|
||||||
|
// executed on the UI thread after completion.
|
||||||
|
///
|
||||||
|
/*--cef(optional_param=callback)--*/
|
||||||
|
virtual void CloseAllConnections(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_
|
#endif // CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
#include "base/strings/stringprintf.h"
|
#include "base/strings/stringprintf.h"
|
||||||
#include "components/prefs/pref_service.h"
|
#include "components/prefs/pref_service.h"
|
||||||
#include "content/public/browser/plugin_service.h"
|
#include "content/public/browser/plugin_service.h"
|
||||||
|
#include "content/public/browser/ssl_host_state_delegate.h"
|
||||||
|
#include "net/http/http_cache.h"
|
||||||
|
#include "net/http/http_transaction_factory.h"
|
||||||
|
|
||||||
using content::BrowserThread;
|
using content::BrowserThread;
|
||||||
|
|
||||||
|
@ -444,6 +447,22 @@ bool CefRequestContextImpl::SetPreference(const CefString& name,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefRequestContextImpl::ClearCertificateExceptions(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback) {
|
||||||
|
GetBrowserContext(
|
||||||
|
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
|
||||||
|
base::Bind(&CefRequestContextImpl::ClearCertificateExceptionsInternal,
|
||||||
|
this, callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefRequestContextImpl::CloseAllConnections(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback) {
|
||||||
|
GetRequestContextImpl(
|
||||||
|
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
|
||||||
|
base::Bind(&CefRequestContextImpl::CloseAllConnectionsInternal, this,
|
||||||
|
callback));
|
||||||
|
}
|
||||||
|
|
||||||
CefRequestContextImpl::CefRequestContextImpl(
|
CefRequestContextImpl::CefRequestContextImpl(
|
||||||
scoped_refptr<CefBrowserContext> browser_context)
|
scoped_refptr<CefBrowserContext> browser_context)
|
||||||
: browser_context_(browser_context),
|
: browser_context_(browser_context),
|
||||||
|
@ -548,3 +567,41 @@ void CefRequestContextImpl::PurgePluginListCacheInternal(
|
||||||
content::PluginService::GetInstance()->PurgePluginListCache(
|
content::PluginService::GetInstance()->PurgePluginListCache(
|
||||||
browser_context.get(), false);
|
browser_context.get(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefRequestContextImpl::ClearCertificateExceptionsInternal(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback,
|
||||||
|
scoped_refptr<CefBrowserContext> browser_context) {
|
||||||
|
CEF_REQUIRE_UIT();
|
||||||
|
|
||||||
|
content::SSLHostStateDelegate* ssl_delegate =
|
||||||
|
browser_context->GetSSLHostStateDelegate();
|
||||||
|
if (ssl_delegate)
|
||||||
|
ssl_delegate->Clear();
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
CEF_POST_TASK(CEF_UIT,
|
||||||
|
base::Bind(&CefCompletionCallback::OnComplete, callback.get()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefRequestContextImpl::CloseAllConnectionsInternal(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback,
|
||||||
|
scoped_refptr<CefURLRequestContextGetterImpl> request_context) {
|
||||||
|
CEF_REQUIRE_IOT();
|
||||||
|
|
||||||
|
net::URLRequestContext* url_context = request_context->GetURLRequestContext();
|
||||||
|
if (url_context) {
|
||||||
|
net::HttpTransactionFactory* http_factory =
|
||||||
|
url_context->http_transaction_factory();
|
||||||
|
if (http_factory) {
|
||||||
|
net::HttpCache* cache = http_factory->GetCache();
|
||||||
|
if (cache)
|
||||||
|
cache->CloseAllConnections();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
CEF_POST_TASK(CEF_UIT,
|
||||||
|
base::Bind(&CefCompletionCallback::OnComplete, callback.get()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -69,6 +69,9 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||||
bool SetPreference(const CefString& name,
|
bool SetPreference(const CefString& name,
|
||||||
CefRefPtr<CefValue> value,
|
CefRefPtr<CefValue> value,
|
||||||
CefString& error) override;
|
CefString& error) override;
|
||||||
|
void ClearCertificateExceptions(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback) override;
|
||||||
|
void CloseAllConnections(CefRefPtr<CefCompletionCallback> callback) override;
|
||||||
|
|
||||||
const CefRequestContextSettings& settings() const { return settings_; }
|
const CefRequestContextSettings& settings() const { return settings_; }
|
||||||
|
|
||||||
|
@ -103,6 +106,12 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||||
void PurgePluginListCacheInternal(
|
void PurgePluginListCacheInternal(
|
||||||
bool reload_pages,
|
bool reload_pages,
|
||||||
scoped_refptr<CefBrowserContext> browser_context);
|
scoped_refptr<CefBrowserContext> browser_context);
|
||||||
|
void ClearCertificateExceptionsInternal(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback,
|
||||||
|
scoped_refptr<CefBrowserContext> browser_context);
|
||||||
|
void CloseAllConnectionsInternal(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback,
|
||||||
|
scoped_refptr<CefURLRequestContextGetterImpl> request_context);
|
||||||
|
|
||||||
scoped_refptr<CefBrowserContext> browser_context_;
|
scoped_refptr<CefBrowserContext> browser_context_;
|
||||||
CefRequestContextSettings settings_;
|
CefRequestContextSettings settings_;
|
||||||
|
|
|
@ -350,6 +350,34 @@ int CEF_CALLBACK request_context_set_preference(
|
||||||
return _retval;
|
return _retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CEF_CALLBACK request_context_clear_certificate_exceptions(
|
||||||
|
struct _cef_request_context_t* self, cef_completion_callback_t* callback) {
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return;
|
||||||
|
// Unverified params: callback
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
CefRequestContextCppToC::Get(self)->ClearCertificateExceptions(
|
||||||
|
CefCompletionCallbackCToCpp::Wrap(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEF_CALLBACK request_context_close_all_connections(
|
||||||
|
struct _cef_request_context_t* self, cef_completion_callback_t* callback) {
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return;
|
||||||
|
// Unverified params: callback
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
CefRequestContextCppToC::Get(self)->CloseAllConnections(
|
||||||
|
CefCompletionCallbackCToCpp::Wrap(callback));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
@ -374,6 +402,9 @@ CefRequestContextCppToC::CefRequestContextCppToC() {
|
||||||
GetStruct()->get_all_preferences = request_context_get_all_preferences;
|
GetStruct()->get_all_preferences = request_context_get_all_preferences;
|
||||||
GetStruct()->can_set_preference = request_context_can_set_preference;
|
GetStruct()->can_set_preference = request_context_can_set_preference;
|
||||||
GetStruct()->set_preference = request_context_set_preference;
|
GetStruct()->set_preference = request_context_set_preference;
|
||||||
|
GetStruct()->clear_certificate_exceptions =
|
||||||
|
request_context_clear_certificate_exceptions;
|
||||||
|
GetStruct()->close_all_connections = request_context_close_all_connections;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> CefRefPtr<CefRequestContext> CefCppToC<CefRequestContextCppToC,
|
template<> CefRefPtr<CefRequestContext> CefCppToC<CefRequestContextCppToC,
|
||||||
|
|
|
@ -325,6 +325,36 @@ bool CefRequestContextCToCpp::SetPreference(const CefString& name,
|
||||||
return _retval?true:false;
|
return _retval?true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefRequestContextCToCpp::ClearCertificateExceptions(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback) {
|
||||||
|
cef_request_context_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, clear_certificate_exceptions))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Unverified params: callback
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
_struct->clear_certificate_exceptions(_struct,
|
||||||
|
CefCompletionCallbackCppToC::Wrap(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefRequestContextCToCpp::CloseAllConnections(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback) {
|
||||||
|
cef_request_context_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, close_all_connections))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Unverified params: callback
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
_struct->close_all_connections(_struct,
|
||||||
|
CefCompletionCallbackCppToC::Wrap(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// CONSTRUCTOR - Do not edit by hand.
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,9 @@ class CefRequestContextCToCpp
|
||||||
bool CanSetPreference(const CefString& name) OVERRIDE;
|
bool CanSetPreference(const CefString& name) OVERRIDE;
|
||||||
bool SetPreference(const CefString& name, CefRefPtr<CefValue> value,
|
bool SetPreference(const CefString& name, CefRefPtr<CefValue> value,
|
||||||
CefString& error) OVERRIDE;
|
CefString& error) OVERRIDE;
|
||||||
|
void ClearCertificateExceptions(
|
||||||
|
CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
|
||||||
|
void CloseAllConnections(CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // USING_CEF_SHARED
|
#endif // USING_CEF_SHARED
|
||||||
|
|
|
@ -650,3 +650,135 @@ TEST(RequestContextTest, NoReferrerLinkDifferentOrigin) {
|
||||||
handler->ExecuteTest();
|
handler->ExecuteTest();
|
||||||
ReleaseAndWaitForDestructor(handler);
|
ReleaseAndWaitForDestructor(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class MethodTestHandler : public TestHandler {
|
||||||
|
public:
|
||||||
|
enum Method {
|
||||||
|
METHOD_CLEAR_CERTIFICATE_EXCEPTIONS,
|
||||||
|
METHOD_CLOSE_ALL_CONNECTIONS,
|
||||||
|
};
|
||||||
|
|
||||||
|
class CompletionCallback : public CefCompletionCallback {
|
||||||
|
public:
|
||||||
|
explicit CompletionCallback(MethodTestHandler* test_handler)
|
||||||
|
: test_handler_(test_handler) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~CompletionCallback() override {
|
||||||
|
EXPECT_UI_THREAD();
|
||||||
|
|
||||||
|
// OnComplete should be executed.
|
||||||
|
EXPECT_FALSE(test_handler_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnComplete() override {
|
||||||
|
EXPECT_UI_THREAD();
|
||||||
|
|
||||||
|
// OnComplete should be executed only one time.
|
||||||
|
EXPECT_TRUE(test_handler_);
|
||||||
|
test_handler_->OnCompleteCallback();
|
||||||
|
test_handler_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MethodTestHandler* test_handler_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(CompletionCallback);
|
||||||
|
};
|
||||||
|
|
||||||
|
MethodTestHandler(bool global_context,
|
||||||
|
Method method)
|
||||||
|
: global_context_(global_context),
|
||||||
|
method_(method) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunTest() override {
|
||||||
|
const char kUrl[] = "http://tests/method.html";
|
||||||
|
|
||||||
|
AddResource(kUrl, "<html><body>Method</body></html>", "text/html");
|
||||||
|
|
||||||
|
CefRefPtr<CefRequestContext> request_context;
|
||||||
|
if (!global_context_) {
|
||||||
|
CefRequestContextSettings settings;
|
||||||
|
request_context = CefRequestContext::CreateContext(settings, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateBrowser(kUrl, request_context);
|
||||||
|
|
||||||
|
// Time out the test after a reasonable period of time.
|
||||||
|
SetTestTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
int httpStatusCode) override {
|
||||||
|
CefRefPtr<CefRequestContext> context =
|
||||||
|
browser->GetHost()->GetRequestContext();
|
||||||
|
CefRefPtr<CefCompletionCallback> callback = new CompletionCallback(this);
|
||||||
|
if (method_ == METHOD_CLEAR_CERTIFICATE_EXCEPTIONS)
|
||||||
|
context->ClearCertificateExceptions(callback);
|
||||||
|
else if (method_ == METHOD_CLOSE_ALL_CONNECTIONS)
|
||||||
|
context->CloseAllConnections(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnCompleteCallback() {
|
||||||
|
EXPECT_UI_THREAD();
|
||||||
|
EXPECT_FALSE(got_completion_callback_);
|
||||||
|
got_completion_callback_.yes();
|
||||||
|
DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DestroyTest() override {
|
||||||
|
EXPECT_TRUE(got_completion_callback_);
|
||||||
|
TestHandler::DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool global_context_;
|
||||||
|
const Method method_;
|
||||||
|
|
||||||
|
TrackCallback got_completion_callback_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(MethodTestHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Test CefRequestContext::ClearCertificateExceptions with the global context.
|
||||||
|
TEST(RequestContextTest, ClearCertificateExceptionsGlobal) {
|
||||||
|
CefRefPtr<MethodTestHandler> handler =
|
||||||
|
new MethodTestHandler(true,
|
||||||
|
MethodTestHandler::METHOD_CLEAR_CERTIFICATE_EXCEPTIONS);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test CefRequestContext::ClearCertificateExceptions with a custom context.
|
||||||
|
TEST(RequestContextTest, ClearCertificateExceptionsCustom) {
|
||||||
|
CefRefPtr<MethodTestHandler> handler =
|
||||||
|
new MethodTestHandler(false,
|
||||||
|
MethodTestHandler::METHOD_CLEAR_CERTIFICATE_EXCEPTIONS);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test CefRequestContext::CloseAllConnections with the global context.
|
||||||
|
TEST(RequestContextTest, CloseAllConnectionsGlobal) {
|
||||||
|
CefRefPtr<MethodTestHandler> handler =
|
||||||
|
new MethodTestHandler(true,
|
||||||
|
MethodTestHandler::METHOD_CLOSE_ALL_CONNECTIONS);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test CefRequestContext::CloseAllConnections with a custom context.
|
||||||
|
TEST(RequestContextTest, CloseAllConnectionsCustom) {
|
||||||
|
CefRefPtr<MethodTestHandler> handler =
|
||||||
|
new MethodTestHandler(false,
|
||||||
|
MethodTestHandler::METHOD_CLOSE_ALL_CONNECTIONS);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
Loading…
Reference in New Issue