mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Compare commits
31 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
16a67c4507 | ||
|
0ebdb473b1 | ||
|
c81164e2ce | ||
|
e0be1d916d | ||
|
d9915d728f | ||
|
5656baa197 | ||
|
fed0e1826a | ||
|
a9c022bd11 | ||
|
84fed5dc0e | ||
|
b34af23449 | ||
|
94d09f80e7 | ||
|
1c3d34bc32 | ||
|
4210896724 | ||
|
1931b9c969 | ||
|
fdd887b677 | ||
|
849a6e64dc | ||
|
5e9ca096e0 | ||
|
3b211d4bf5 | ||
|
2c92fcd3cd | ||
|
d792e5fddf | ||
|
f50b3c2d43 | ||
|
6ad1dea9fa | ||
|
542c867901 | ||
|
5da93a11c8 | ||
|
19229b6d38 | ||
|
90ecd35aff | ||
|
d3b54cbec7 | ||
|
3f2a3b1c67 | ||
|
699a922bd4 | ||
|
3b2e46543b | ||
|
b5e74dd297 |
4
BUILD.gn
4
BUILD.gn
@@ -407,6 +407,8 @@ static_library("libcef_static") {
|
||||
"libcef/browser/net_service/cookie_helper.h",
|
||||
"libcef/browser/net_service/cookie_manager_impl.cc",
|
||||
"libcef/browser/net_service/cookie_manager_impl.h",
|
||||
"libcef/browser/net_service/login_delegate.cc",
|
||||
"libcef/browser/net_service/login_delegate.h",
|
||||
"libcef/browser/net_service/proxy_url_loader_factory.cc",
|
||||
"libcef/browser/net_service/proxy_url_loader_factory.h",
|
||||
"libcef/browser/net_service/resource_handler_wrapper.cc",
|
||||
@@ -596,6 +598,8 @@ static_library("libcef_static") {
|
||||
"libcef/renderer/render_urlrequest_impl.cc",
|
||||
"libcef/renderer/render_urlrequest_impl.h",
|
||||
"libcef/renderer/thread_util.h",
|
||||
"libcef/renderer/url_loader_throttle_provider_impl.cc",
|
||||
"libcef/renderer/url_loader_throttle_provider_impl.h",
|
||||
"libcef/renderer/v8_impl.cc",
|
||||
"libcef/renderer/v8_impl.h",
|
||||
"libcef/utility/content_utility_client.cc",
|
||||
|
@@ -7,5 +7,5 @@
|
||||
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
|
||||
|
||||
{
|
||||
'chromium_checkout': 'refs/tags/75.0.3770.0'
|
||||
'chromium_checkout': 'refs/tags/75.0.3770.100'
|
||||
}
|
||||
|
@@ -374,6 +374,9 @@ if(OS_WINDOWS)
|
||||
1913 # VS2017 version 15.6
|
||||
1914 # VS2017 version 15.7
|
||||
1915 # VS2017 version 15.8
|
||||
1916 # VS2017 version 15.9
|
||||
1920 # VS2019 version 16.0
|
||||
1921 # VS2018 version 16.1
|
||||
)
|
||||
list(FIND supported_msvc_versions ${MSVC_VERSION} _index)
|
||||
if (${_index} EQUAL -1)
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=59376c6298df4489ecc34f3509a8d0e77e9d97f7$
|
||||
// $hash=fdfce3e4e33a1d4e1170497d2a476f0837994060$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_CONTEXT_CAPI_H_
|
||||
@@ -238,6 +238,15 @@ typedef struct _cef_request_context_t {
|
||||
struct _cef_request_context_t* self,
|
||||
struct _cef_completion_callback_t* callback);
|
||||
|
||||
///
|
||||
// Clears all HTTP authentication credentials that were added as part of
|
||||
// handling GetAuthCredentials. If |callback| is non-NULL it will be executed
|
||||
// on the UI thread after completion.
|
||||
///
|
||||
void(CEF_CALLBACK* clear_http_auth_credentials)(
|
||||
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
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=fce8beb9d3e8709a512077681455cb4ef92ef76d$
|
||||
// $hash=d9c4e8591ee39bd9d8c1714c0ca2417a7d2a38ea$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_HANDLER_CAPI_H_
|
||||
@@ -154,10 +154,11 @@ typedef struct _cef_request_handler_t {
|
||||
|
||||
///
|
||||
// Called on the IO thread when the browser needs credentials from the user.
|
||||
// |isProxy| indicates whether the host is a proxy server. |host| contains the
|
||||
// hostname and |port| contains the port number. |realm| is the realm of the
|
||||
// challenge and may be NULL. |scheme| is the authentication scheme used, such
|
||||
// as "basic" or "digest", and will be NULL if the source of the request is an
|
||||
// |origin_url| is the origin making this authentication request. |isProxy|
|
||||
// indicates whether the host is a proxy server. |host| contains the hostname
|
||||
// and |port| contains the port number. |realm| is the realm of the challenge
|
||||
// and may be NULL. |scheme| is the authentication scheme used, such as
|
||||
// "basic" or "digest", and will be NULL if the source of the request is an
|
||||
// FTP server. Return true (1) to continue the request and call
|
||||
// cef_auth_callback_t::cont() either in this function or at a later time when
|
||||
// the authentication information is available. Return false (0) to cancel the
|
||||
@@ -166,7 +167,7 @@ typedef struct _cef_request_handler_t {
|
||||
int(CEF_CALLBACK* get_auth_credentials)(
|
||||
struct _cef_request_handler_t* self,
|
||||
struct _cef_browser_t* browser,
|
||||
struct _cef_frame_t* frame,
|
||||
const cef_string_t* origin_url,
|
||||
int isProxy,
|
||||
const cef_string_t* host,
|
||||
int port,
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=f94ec1ef3928002394720160d526ed157282cc7a$
|
||||
// $hash=8c6ffeab9c9183cc5f77929839643767ce5c5c2f$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_RESOURCE_HANDLER_CAPI_H_
|
||||
@@ -151,9 +151,9 @@ typedef struct _cef_resource_handler_t {
|
||||
///
|
||||
// Skip response data when requested by a Range header. Skip over and discard
|
||||
// |bytes_to_skip| bytes of response data. If data is available immediately
|
||||
// set |bytes_skipped| to the number of of bytes skipped and return true (1).
|
||||
// To read the data at a later time set |bytes_skipped| to 0, return true (1)
|
||||
// and execute |callback| when the data is available. To indicate failure set
|
||||
// set |bytes_skipped| to the number of bytes skipped and return true (1). To
|
||||
// read the data at a later time set |bytes_skipped| to 0, return true (1) and
|
||||
// execute |callback| when the data is available. To indicate failure set
|
||||
// |bytes_skipped| to < 0 (e.g. -2 for ERR_FAILED) and return false (0). This
|
||||
// function will be called in sequence but not from a dedicated thread.
|
||||
///
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=af8ddd4d2d19e5b64d0a40778cb3c62fd5f1d8c9$
|
||||
// $hash=adb3ca1e315a28efed7b2305c8aceb9c5eafdc66$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_RESOURCE_REQUEST_HANDLER_CAPI_H_
|
||||
@@ -48,7 +48,6 @@
|
||||
#include "include/capi/cef_resource_handler_capi.h"
|
||||
#include "include/capi/cef_response_capi.h"
|
||||
#include "include/capi/cef_response_filter_capi.h"
|
||||
#include "include/internal/cef_types_wrappers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=3d31b2d1bad50deeb68a5e6318344024c2f3f5be$
|
||||
// $hash=77ac3a2aaea32b649185a58e4c2bbb13b7fe0540$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_URLREQUEST_CAPI_H_
|
||||
@@ -193,9 +193,11 @@ typedef struct _cef_urlrequest_client_t {
|
||||
// |isProxy| indicates whether the host is a proxy server. |host| contains the
|
||||
// hostname and |port| contains the port number. Return true (1) to continue
|
||||
// the request and call cef_auth_callback_t::cont() when the authentication
|
||||
// information is available. Return false (0) to cancel the request. This
|
||||
// function will only be called for requests initiated from the browser
|
||||
// process.
|
||||
// information is available. If the request has an associated browser/frame
|
||||
// then returning false (0) will result in a call to GetAuthCredentials on the
|
||||
// cef_request_tHandler associated with that browser, if any. Otherwise,
|
||||
// returning false (0) will cancel the request immediately. This function will
|
||||
// only be called for requests initiated from the browser process.
|
||||
///
|
||||
int(CEF_CALLBACK* get_auth_credentials)(
|
||||
struct _cef_urlrequest_client_t* self,
|
||||
|
@@ -34,7 +34,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=0bc0d1faa22392b4245dc6eaf56337e7847a1900$
|
||||
// $hash=467550bc7fb025b069edb9dc65988d8cb9c56fd2$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_API_HASH_H_
|
||||
@@ -47,13 +47,13 @@
|
||||
// way that may cause binary incompatibility with other builds. The universal
|
||||
// hash value will change if any platform is affected whereas the platform hash
|
||||
// values will change only if that particular platform is affected.
|
||||
#define CEF_API_HASH_UNIVERSAL "31b55dcbcf52e9f51fe423741f64e5c77e71c65a"
|
||||
#define CEF_API_HASH_UNIVERSAL "3f2fd465a9dc95ef7d645c0b3c8bdf4e26d9b26e"
|
||||
#if defined(OS_WIN)
|
||||
#define CEF_API_HASH_PLATFORM "afb8ea794d1bb0f56ba5ce1718a16e5dfd64229e"
|
||||
#define CEF_API_HASH_PLATFORM "37fc3765fe0ef3ef7542e6568e5689b3575968a8"
|
||||
#elif defined(OS_MACOSX)
|
||||
#define CEF_API_HASH_PLATFORM "e3a279cf087095495c08fd9fa88daef5dbafff3a"
|
||||
#define CEF_API_HASH_PLATFORM "dc61db096a4b62365b16d450fe4f898a9552da6a"
|
||||
#elif defined(OS_LINUX)
|
||||
#define CEF_API_HASH_PLATFORM "d25833941c670d82cff0aa0ccf47b557d6813634"
|
||||
#define CEF_API_HASH_PLATFORM "059d7243ae34aa5503c96a21ce24a673dddf4e64"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -249,6 +249,15 @@ class CefRequestContext : public virtual CefBaseRefCounted {
|
||||
virtual void ClearCertificateExceptions(
|
||||
CefRefPtr<CefCompletionCallback> callback) = 0;
|
||||
|
||||
///
|
||||
// Clears all HTTP authentication credentials that were added as part of
|
||||
// handling GetAuthCredentials. If |callback| is non-NULL it will be executed
|
||||
// on the UI thread after completion.
|
||||
///
|
||||
/*--cef(optional_param=callback)--*/
|
||||
virtual void ClearHttpAuthCredentials(
|
||||
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
|
||||
|
@@ -150,18 +150,19 @@ class CefRequestHandler : public virtual CefBaseRefCounted {
|
||||
|
||||
///
|
||||
// Called on the IO thread when the browser needs credentials from the user.
|
||||
// |isProxy| indicates whether the host is a proxy server. |host| contains the
|
||||
// hostname and |port| contains the port number. |realm| is the realm of the
|
||||
// challenge and may be empty. |scheme| is the authentication scheme used,
|
||||
// such as "basic" or "digest", and will be empty if the source of the request
|
||||
// is an FTP server. Return true to continue the request and call
|
||||
// |origin_url| is the origin making this authentication request. |isProxy|
|
||||
// indicates whether the host is a proxy server. |host| contains the hostname
|
||||
// and |port| contains the port number. |realm| is the realm of the challenge
|
||||
// and may be empty. |scheme| is the authentication scheme used, such as
|
||||
// "basic" or "digest", and will be empty if the source of the request is an
|
||||
// FTP server. Return true to continue the request and call
|
||||
// CefAuthCallback::Continue() either in this method or at a later time when
|
||||
// the authentication information is available. Return false to cancel the
|
||||
// request immediately.
|
||||
///
|
||||
/*--cef(optional_param=realm,optional_param=scheme)--*/
|
||||
virtual bool GetAuthCredentials(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
const CefString& origin_url,
|
||||
bool isProxy,
|
||||
const CefString& host,
|
||||
int port,
|
||||
|
@@ -142,7 +142,7 @@ class CefResourceHandler : public virtual CefBaseRefCounted {
|
||||
///
|
||||
// Skip response data when requested by a Range header. Skip over and discard
|
||||
// |bytes_to_skip| bytes of response data. If data is available immediately
|
||||
// set |bytes_skipped| to the number of of bytes skipped and return true. To
|
||||
// set |bytes_skipped| to the number of bytes skipped and return true. To
|
||||
// read the data at a later time set |bytes_skipped| to 0, return true and
|
||||
// execute |callback| when the data is available. To indicate failure set
|
||||
// |bytes_skipped| to < 0 (e.g. -2 for ERR_FAILED) and return false. This
|
||||
|
@@ -46,7 +46,6 @@
|
||||
#include "include/cef_resource_handler.h"
|
||||
#include "include/cef_response.h"
|
||||
#include "include/cef_response_filter.h"
|
||||
#include "include/internal/cef_types_wrappers.h"
|
||||
|
||||
class CefCookieAccessFilter;
|
||||
|
||||
|
@@ -186,8 +186,11 @@ class CefURLRequestClient : public virtual CefBaseRefCounted {
|
||||
// |isProxy| indicates whether the host is a proxy server. |host| contains the
|
||||
// hostname and |port| contains the port number. Return true to continue the
|
||||
// request and call CefAuthCallback::Continue() when the authentication
|
||||
// information is available. Return false to cancel the request. This method
|
||||
// will only be called for requests initiated from the browser process.
|
||||
// information is available. If the request has an associated browser/frame
|
||||
// then returning false will result in a call to GetAuthCredentials on the
|
||||
// CefRequestHandler associated with that browser, if any. Otherwise,
|
||||
// returning false will cancel the request immediately. This method will only
|
||||
// be called for requests initiated from the browser process.
|
||||
///
|
||||
/*--cef(optional_param=realm)--*/
|
||||
virtual bool GetAuthCredentials(bool isProxy,
|
||||
|
@@ -220,7 +220,7 @@ typedef struct _cef_settings_t {
|
||||
|
||||
///
|
||||
// The location where data for the global browser cache will be stored on
|
||||
// disk. In non-empty this must be either equal to or a child directory of
|
||||
// disk. If non-empty this must be either equal to or a child directory of
|
||||
// CefSettings.root_cache_path. If empty then browsers will be created in
|
||||
// "incognito mode" where in-memory caches are used for storage and no data is
|
||||
// persisted to disk. HTML5 databases such as localStorage will only persist
|
||||
|
@@ -544,6 +544,7 @@ struct CefSettingsTraits {
|
||||
cef_string_clear(&s->browser_subprocess_path);
|
||||
cef_string_clear(&s->framework_dir_path);
|
||||
cef_string_clear(&s->cache_path);
|
||||
cef_string_clear(&s->root_cache_path);
|
||||
cef_string_clear(&s->user_data_path);
|
||||
cef_string_clear(&s->user_agent);
|
||||
cef_string_clear(&s->product_version);
|
||||
@@ -572,6 +573,8 @@ struct CefSettingsTraits {
|
||||
|
||||
cef_string_set(src->cache_path.str, src->cache_path.length,
|
||||
&target->cache_path, copy);
|
||||
cef_string_set(src->root_cache_path.str, src->root_cache_path.length,
|
||||
&target->root_cache_path, copy);
|
||||
cef_string_set(src->user_data_path.str, src->user_data_path.length,
|
||||
&target->user_data_path, copy);
|
||||
target->persist_session_cookies = src->persist_session_cookies;
|
||||
|
@@ -97,8 +97,9 @@ class CefScopedArgArray {
|
||||
CefScopedArgArray(int argc, char* argv[]) {
|
||||
// argv should have (argc + 1) elements, the last one always being NULL.
|
||||
array_ = new char*[argc + 1];
|
||||
values_.resize(argc);
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
values_.push_back(argv[i]);
|
||||
values_[i] = argv[i];
|
||||
array_[i] = const_cast<char*>(values_[i].c_str());
|
||||
}
|
||||
array_[argc] = NULL;
|
||||
|
@@ -29,7 +29,7 @@ void CefAudioMirrorDestination::Start() {
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&content::AudioMirroringManager::StartMirroring,
|
||||
base::Unretained(mirroring_manager_),
|
||||
base::Unretained(this)));
|
||||
base::RetainedRef(this)));
|
||||
}
|
||||
|
||||
void CefAudioMirrorDestination::Stop() {
|
||||
@@ -39,7 +39,7 @@ void CefAudioMirrorDestination::Stop() {
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&content::AudioMirroringManager::StopMirroring,
|
||||
base::Unretained(mirroring_manager_),
|
||||
base::Unretained(this)));
|
||||
base::RetainedRef(this)));
|
||||
}
|
||||
|
||||
// Asynchronously query whether this MirroringDestination wants to consume
|
||||
@@ -56,7 +56,7 @@ void CefAudioMirrorDestination::QueryForMatches(
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(&CefAudioMirrorDestination::QueryForMatchesOnUIThread,
|
||||
base::Unretained(this), candidates,
|
||||
base::RetainedRef(this), candidates,
|
||||
media::BindToCurrentLoop(std::move(results_callback))));
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ media::AudioPushSink* CefAudioMirrorDestination::AddPushInput(
|
||||
return new CefAudioPushSink(
|
||||
params, browser_, cef_audio_handler_,
|
||||
base::Bind(&CefAudioMirrorDestination::ReleasePushInput,
|
||||
base::Unretained(this)));
|
||||
base::RetainedRef(this)));
|
||||
}
|
||||
|
||||
void CefAudioMirrorDestination::ReleasePushInput(CefAudioPushSink* sink) {
|
||||
|
@@ -22,14 +22,13 @@ class CefAudioPushSink;
|
||||
class CefBrowserHostImpl;
|
||||
|
||||
class CefAudioMirrorDestination
|
||||
: public content::AudioMirroringManager::MirroringDestination {
|
||||
: public base::RefCountedThreadSafe<CefAudioMirrorDestination>,
|
||||
public content::AudioMirroringManager::MirroringDestination {
|
||||
public:
|
||||
CefAudioMirrorDestination(CefRefPtr<CefBrowserHostImpl> browser,
|
||||
CefRefPtr<CefAudioHandler> cef_audio_handler,
|
||||
content::AudioMirroringManager* mirroring_manager);
|
||||
|
||||
virtual ~CefAudioMirrorDestination() = default;
|
||||
|
||||
// Start mirroring. This needs to be triggered on the IO thread.
|
||||
void Start();
|
||||
|
||||
@@ -65,6 +64,10 @@ class CefAudioMirrorDestination
|
||||
const media::AudioParameters& params) override;
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<CefAudioMirrorDestination>;
|
||||
|
||||
~CefAudioMirrorDestination() override = default;
|
||||
|
||||
void QueryForMatchesOnUIThread(
|
||||
const std::set<content::GlobalFrameRoutingId>& candidates,
|
||||
MatchesCallback results_callback);
|
||||
|
@@ -287,6 +287,10 @@ void CefBrowserContext::Initialize() {
|
||||
CefString(&context->settings().accept_language_list);
|
||||
}
|
||||
|
||||
if (!!settings_.persist_session_cookies) {
|
||||
set_should_persist_session_cookies(true);
|
||||
}
|
||||
|
||||
key_ = std::make_unique<ProfileKey>(GetPath());
|
||||
SimpleKeyMap::GetInstance()->Associate(this, key_.get());
|
||||
|
||||
|
@@ -183,6 +183,9 @@ class CefBrowserContext : public ChromeProfileStub,
|
||||
|
||||
// Values checked in ProfileNetworkContextService::CreateNetworkContextParams
|
||||
// when creating the NetworkContext.
|
||||
bool ShouldRestoreOldSessionCookies() override {
|
||||
return should_persist_session_cookies_;
|
||||
}
|
||||
bool ShouldPersistSessionCookies() override {
|
||||
return should_persist_session_cookies_;
|
||||
}
|
||||
|
@@ -1576,6 +1576,11 @@ CefRefPtr<CefFrame> CefBrowserHostImpl::GetFrameForHost(
|
||||
return browser_info_->GetFrameForHost(host);
|
||||
}
|
||||
|
||||
CefRefPtr<CefFrame> CefBrowserHostImpl::GetFrameForFrameTreeNode(
|
||||
int frame_tree_node_id) {
|
||||
return browser_info_->GetFrameForFrameTreeNode(frame_tree_node_id, nullptr);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::LoadMainFrameURL(const std::string& url,
|
||||
const content::Referrer& referrer,
|
||||
ui::PageTransition transition,
|
||||
@@ -2736,8 +2741,8 @@ bool CefBrowserHostImpl::StartAudioMirroring() {
|
||||
if (client_.get()) {
|
||||
CefRefPtr<CefAudioHandler> audio_handler = client_->GetAudioHandler();
|
||||
if (audio_handler.get()) {
|
||||
audio_mirror_destination_.reset(new CefAudioMirrorDestination(
|
||||
this, audio_handler, content::AudioMirroringManager::GetInstance()));
|
||||
audio_mirror_destination_ = new CefAudioMirrorDestination(
|
||||
this, audio_handler, content::AudioMirroringManager::GetInstance());
|
||||
audio_mirror_destination_->Start();
|
||||
return true;
|
||||
}
|
||||
|
@@ -299,6 +299,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
// Returns the frame associated with the specified RenderFrameHost.
|
||||
CefRefPtr<CefFrame> GetFrameForHost(const content::RenderFrameHost* host);
|
||||
|
||||
// Returns the frame associated with the specified FrameTreeNode ID.
|
||||
CefRefPtr<CefFrame> GetFrameForFrameTreeNode(int frame_tree_node_id);
|
||||
|
||||
// Load the specified URL in the main frame.
|
||||
void LoadMainFrameURL(const std::string& url,
|
||||
const content::Referrer& referrer,
|
||||
@@ -663,7 +666,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
bool is_background_host_ = false;
|
||||
|
||||
// Used to mirror audio streams
|
||||
std::unique_ptr<CefAudioMirrorDestination> audio_mirror_destination_;
|
||||
scoped_refptr<CefAudioMirrorDestination> audio_mirror_destination_;
|
||||
|
||||
// Used with auto-resize.
|
||||
bool auto_resize_enabled_ = false;
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "libcef/browser/media_capture_devices_dispatcher.h"
|
||||
#include "libcef/browser/net/chrome_scheme_handler.h"
|
||||
#include "libcef/browser/net/net_util.h"
|
||||
#include "libcef/browser/net_service/login_delegate.h"
|
||||
#include "libcef/browser/net_service/proxy_url_loader_factory.h"
|
||||
#include "libcef/browser/net_service/resource_request_handler_wrapper.h"
|
||||
#include "libcef/browser/plugins/plugin_service_filter.h"
|
||||
@@ -108,6 +109,7 @@
|
||||
#include "extensions/browser/io_thread_extension_message_filter.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/switches.h"
|
||||
#include "net/base/auth.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "services/network/public/cpp/network_switches.h"
|
||||
@@ -429,6 +431,7 @@ bool NavigationOnUIThread(
|
||||
bool is_main_frame,
|
||||
int64_t frame_id,
|
||||
int64_t parent_frame_id,
|
||||
int frame_tree_node_id,
|
||||
content::WebContents* source,
|
||||
const navigation_interception::NavigationParams& params) {
|
||||
CEF_REQUIRE_UIT();
|
||||
@@ -447,7 +450,9 @@ bool NavigationOnUIThread(
|
||||
frame = browser->GetMainFrame();
|
||||
} else if (frame_id >= 0) {
|
||||
frame = browser->GetFrame(frame_id);
|
||||
DCHECK(frame);
|
||||
}
|
||||
if (!frame && frame_tree_node_id >= 0) {
|
||||
frame = browser->GetFrameForFrameTreeNode(frame_tree_node_id);
|
||||
}
|
||||
if (!frame) {
|
||||
// Create a temporary frame object for navigation of sub-frames that
|
||||
@@ -1115,7 +1120,7 @@ CefContentBrowserClient::CreateThrottlesForNavigation(
|
||||
std::make_unique<navigation_interception::InterceptNavigationThrottle>(
|
||||
navigation_handle,
|
||||
base::Bind(&NavigationOnUIThread, is_main_frame, frame_id,
|
||||
parent_frame_id),
|
||||
parent_frame_id, navigation_handle->GetFrameTreeNodeId()),
|
||||
navigation_interception::SynchronyMode::kSync);
|
||||
throttles.push_back(std::move(throttle));
|
||||
|
||||
@@ -1195,6 +1200,21 @@ CefContentBrowserClient::CreateClientCertStore(
|
||||
->CreateClientCertStore();
|
||||
}
|
||||
|
||||
std::unique_ptr<content::LoginDelegate>
|
||||
CefContentBrowserClient::CreateLoginDelegate(
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
content::WebContents* web_contents,
|
||||
const content::GlobalRequestID& request_id,
|
||||
bool is_request_for_main_frame,
|
||||
const GURL& url,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers,
|
||||
bool first_auth_attempt,
|
||||
LoginAuthRequiredCallback auth_required_callback) {
|
||||
return std::make_unique<net_service::LoginDelegate>(
|
||||
auth_info, web_contents, request_id, url,
|
||||
std::move(auth_required_callback));
|
||||
}
|
||||
|
||||
void CefContentBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
|
||||
int frame_tree_node_id,
|
||||
NonNetworkURLLoaderFactoryMap* factories) {
|
||||
|
@@ -150,10 +150,17 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
|
||||
service_manager::BinderRegistry* registry,
|
||||
blink::AssociatedInterfaceRegistry* associated_registry,
|
||||
content::RenderProcessHost* render_process_host) override;
|
||||
|
||||
std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
|
||||
content::ResourceContext* resource_context) override;
|
||||
|
||||
std::unique_ptr<content::LoginDelegate> CreateLoginDelegate(
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
content::WebContents* web_contents,
|
||||
const content::GlobalRequestID& request_id,
|
||||
bool is_request_for_main_frame,
|
||||
const GURL& url,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers,
|
||||
bool first_auth_attempt,
|
||||
LoginAuthRequiredCallback auth_required_callback) override;
|
||||
void RegisterNonNetworkNavigationURLLoaderFactories(
|
||||
int frame_tree_node_id,
|
||||
NonNetworkURLLoaderFactoryMap* factories) override;
|
||||
|
@@ -199,7 +199,7 @@ void CefExtensionSystem::Init() {
|
||||
// mime_handler_private.idl), and returns the unique View ID via the
|
||||
// |payload| argument.
|
||||
// 5. The unique View ID arrives in the renderer process via
|
||||
// ResourceLoader::didReceiveData and triggers creation of a new Document.
|
||||
// ResourceLoader::DidReceiveData and triggers creation of a new Document.
|
||||
// DOMImplementation::createDocument indirectly calls
|
||||
// RendererBlinkPlatformImpl::getPluginList to retrieve the list of
|
||||
// supported plugins from the browser process. If a plugin supports the
|
||||
|
@@ -26,8 +26,9 @@
|
||||
(CefJavaScriptDialogRunner::DialogClosedCallback)callback;
|
||||
- (NSAlert*)alert;
|
||||
- (NSTextField*)textField;
|
||||
- (void)alertDidEndWithResult:(NSModalResponse)returnCode
|
||||
dialog:(CefJavaScriptDialogRunnerMac*)dialog;
|
||||
- (void)alertDidEnd:(NSAlert*)alert
|
||||
returnCode:(int)returnCode
|
||||
contextInfo:(void*)contextInfo;
|
||||
- (void)cancel;
|
||||
|
||||
@end
|
||||
@@ -57,8 +58,9 @@
|
||||
return textField_;
|
||||
}
|
||||
|
||||
- (void)alertDidEndWithResult:(NSModalResponse)returnCode
|
||||
dialog:(CefJavaScriptDialogRunnerMac*)dialog {
|
||||
- (void)alertDidEnd:(NSAlert*)alert
|
||||
returnCode:(int)returnCode
|
||||
contextInfo:(void*)contextInfo {
|
||||
if (returnCode == NSModalResponseStop)
|
||||
return;
|
||||
|
||||
@@ -139,11 +141,16 @@ void CefJavaScriptDialogRunnerMac::Run(
|
||||
// around the "callee requires a non-null argument" error that occurs when
|
||||
// building with the 10.11 SDK. See http://crbug.com/383820 for related
|
||||
// discussion.
|
||||
// We can't use the newer beginSheetModalForWindow:completionHandler: variant
|
||||
// because it fails silently when passed a nil argument (see issue #2726).
|
||||
id nilArg = nil;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
[alert beginSheetModalForWindow:nilArg // nil here makes it app-modal
|
||||
completionHandler:^void(NSModalResponse returnCode) {
|
||||
[helper_ alertDidEndWithResult:returnCode dialog:this];
|
||||
}];
|
||||
modalDelegate:helper_
|
||||
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
|
||||
contextInfo:this];
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
if ([alert accessoryView])
|
||||
[[alert window] makeFirstResponder:[alert accessoryView]];
|
||||
|
@@ -395,13 +395,10 @@ net::NetworkDelegate::AuthRequiredResponse CefNetworkDelegate::OnAuthRequired(
|
||||
if (client.get()) {
|
||||
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
|
||||
if (handler.get()) {
|
||||
CefRefPtr<CefFrame> frame =
|
||||
net_util::GetFrameForRequest(browser->browser_info(), request);
|
||||
|
||||
CefRefPtr<CefAuthCallbackImpl> callbackPtr(
|
||||
new CefAuthCallbackImpl(std::move(callback), credentials));
|
||||
if (handler->GetAuthCredentials(
|
||||
browser.get(), frame, auth_info.is_proxy,
|
||||
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(
|
||||
|
@@ -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,
|
||||
|
@@ -9,10 +9,28 @@
|
||||
|
||||
#include "include/cef_urlrequest.h"
|
||||
|
||||
#include "base/optional.h"
|
||||
|
||||
namespace content {
|
||||
struct GlobalRequestID;
|
||||
}
|
||||
|
||||
class CefBrowserURLRequest : public CefURLRequest {
|
||||
public:
|
||||
class Context;
|
||||
|
||||
// TODO(network): After the old network code path is deleted move the
|
||||
// CefURLRequestClient::GetAuthCredentials callback to the context thread and
|
||||
// return just the CefBrowserURLRequest object here. The *Client object can
|
||||
// then be retrieved by calling GetClient() from the required thread.
|
||||
using RequestInfo = std::pair<CefRefPtr<CefBrowserURLRequest>,
|
||||
CefRefPtr<CefURLRequestClient>>;
|
||||
|
||||
// Retrieve the request objects, if any, associated with |request_id|.
|
||||
static base::Optional<RequestInfo> FromRequestID(int32_t request_id);
|
||||
static base::Optional<RequestInfo> FromRequestID(
|
||||
const content::GlobalRequestID& request_id);
|
||||
|
||||
// If |frame| is nullptr requests can still be intercepted but no
|
||||
// browser/frame will be associated with them.
|
||||
CefBrowserURLRequest(CefRefPtr<CefFrame> frame,
|
||||
|
172
libcef/browser/net_service/login_delegate.cc
Normal file
172
libcef/browser/net_service/login_delegate.cc
Normal file
@@ -0,0 +1,172 @@
|
||||
// Copyright (c) 2019 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_service/login_delegate.h"
|
||||
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/net_service/browser_urlrequest_impl.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "content/public/browser/global_request_id.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
namespace net_service {
|
||||
|
||||
namespace {
|
||||
|
||||
class AuthCallbackImpl : public CefAuthCallback {
|
||||
public:
|
||||
explicit AuthCallbackImpl(base::WeakPtr<LoginDelegate> delegate)
|
||||
: delegate_(delegate),
|
||||
task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
|
||||
|
||||
~AuthCallbackImpl() override {
|
||||
if (delegate_.MaybeValid()) {
|
||||
// If |delegate_| isn't valid this will be a no-op.
|
||||
task_runner_->PostTask(FROM_HERE,
|
||||
base::BindOnce(&LoginDelegate::Cancel, delegate_));
|
||||
}
|
||||
}
|
||||
|
||||
void Continue(const CefString& username, const CefString& password) override {
|
||||
if (!task_runner_->RunsTasksInCurrentSequence()) {
|
||||
task_runner_->PostTask(
|
||||
FROM_HERE, base::BindOnce(&AuthCallbackImpl::Continue, this, username,
|
||||
password));
|
||||
return;
|
||||
}
|
||||
|
||||
if (delegate_) {
|
||||
delegate_->Continue(username, password);
|
||||
delegate_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Cancel() override {
|
||||
if (!task_runner_->RunsTasksInCurrentSequence()) {
|
||||
task_runner_->PostTask(FROM_HERE,
|
||||
base::BindOnce(&AuthCallbackImpl::Cancel, this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (delegate_) {
|
||||
delegate_->Cancel();
|
||||
delegate_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
base::WeakPtr<LoginDelegate> delegate_;
|
||||
scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(AuthCallbackImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(AuthCallbackImpl);
|
||||
};
|
||||
|
||||
void RunCallbackOnIOThread(
|
||||
CefRefPtr<CefBrowserHostImpl> browser,
|
||||
base::Optional<CefBrowserURLRequest::RequestInfo> url_request_info,
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const GURL& origin_url,
|
||||
CefRefPtr<AuthCallbackImpl> callback_impl) {
|
||||
CEF_REQUIRE_IOT();
|
||||
|
||||
// TODO(network): After the old network code path is deleted move this
|
||||
// callback to the BrowserURLRequest's context thread.
|
||||
if (url_request_info) {
|
||||
bool handled = url_request_info->second->GetAuthCredentials(
|
||||
auth_info.is_proxy, auth_info.challenger.host(),
|
||||
auth_info.challenger.port(), auth_info.realm, auth_info.scheme,
|
||||
callback_impl.get());
|
||||
if (handled) {
|
||||
// The user will execute the callback, or the request will be canceled on
|
||||
// AuthCallbackImpl destruction.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (browser) {
|
||||
CefRefPtr<CefClient> client = browser->GetClient();
|
||||
if (client) {
|
||||
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
|
||||
if (handler) {
|
||||
bool handled = handler->GetAuthCredentials(
|
||||
browser.get(), origin_url.spec(), auth_info.is_proxy,
|
||||
auth_info.challenger.host(), auth_info.challenger.port(),
|
||||
auth_info.realm, auth_info.scheme, callback_impl.get());
|
||||
if (handled) {
|
||||
// The user will execute the callback, or the request will be canceled
|
||||
// on AuthCallbackImpl destruction.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callback_impl->Cancel();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
LoginDelegate::LoginDelegate(const net::AuthChallengeInfo& auth_info,
|
||||
content::WebContents* web_contents,
|
||||
const content::GlobalRequestID& request_id,
|
||||
const GURL& origin_url,
|
||||
LoginAuthRequiredCallback callback)
|
||||
: callback_(std::move(callback)), weak_ptr_factory_(this) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
// May be nullptr for requests originating from CefURLRequest.
|
||||
CefRefPtr<CefBrowserHostImpl> browser;
|
||||
if (web_contents) {
|
||||
browser = CefBrowserHostImpl::GetBrowserForContents(web_contents);
|
||||
}
|
||||
|
||||
// |callback| needs to be executed asynchronously.
|
||||
CEF_POST_TASK(CEF_UIT, base::BindOnce(&LoginDelegate::Start,
|
||||
weak_ptr_factory_.GetWeakPtr(), browser,
|
||||
auth_info, request_id, origin_url));
|
||||
}
|
||||
|
||||
void LoginDelegate::Continue(const CefString& username,
|
||||
const CefString& password) {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (!callback_.is_null()) {
|
||||
std::move(callback_).Run(
|
||||
net::AuthCredentials(username.ToString16(), password.ToString16()));
|
||||
}
|
||||
}
|
||||
|
||||
void LoginDelegate::Cancel() {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (!callback_.is_null()) {
|
||||
std::move(callback_).Run(base::nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginDelegate::Start(CefRefPtr<CefBrowserHostImpl> browser,
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const content::GlobalRequestID& request_id,
|
||||
const GURL& origin_url) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
auto url_request_info = CefBrowserURLRequest::FromRequestID(request_id);
|
||||
|
||||
if (browser || url_request_info) {
|
||||
// AuthCallbackImpl is bound to the current thread.
|
||||
CefRefPtr<AuthCallbackImpl> callbackImpl =
|
||||
new AuthCallbackImpl(weak_ptr_factory_.GetWeakPtr());
|
||||
|
||||
// Execute callbacks on the IO thread to maintain the "old"
|
||||
// network_delegate callback behaviour.
|
||||
CEF_POST_TASK(CEF_IOT, base::BindOnce(&RunCallbackOnIOThread, browser,
|
||||
url_request_info, auth_info,
|
||||
origin_url, callbackImpl));
|
||||
} else {
|
||||
Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace net_service
|
50
libcef/browser/net_service/login_delegate.h
Normal file
50
libcef/browser/net_service/login_delegate.h
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2019 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_SERVICE_LOGIN_DELEGATE_H_
|
||||
#define CEF_LIBCEF_BROWSER_NET_SERVICE_LOGIN_DELEGATE_H_
|
||||
|
||||
#include "include/cef_base.h"
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "content/public/browser/content_browser_client.h"
|
||||
#include "content/public/browser/login_delegate.h"
|
||||
#include "net/base/auth.h"
|
||||
|
||||
namespace content {
|
||||
struct GlobalRequestID;
|
||||
class WebContents;
|
||||
} // namespace content
|
||||
|
||||
class CefBrowserHostImpl;
|
||||
class GURL;
|
||||
|
||||
namespace net_service {
|
||||
|
||||
class LoginDelegate : public content::LoginDelegate {
|
||||
public:
|
||||
// This object will be deleted when |callback| is executed or the request is
|
||||
// canceled. |callback| should not be executed after this object is deleted.
|
||||
LoginDelegate(const net::AuthChallengeInfo& auth_info,
|
||||
content::WebContents* web_contents,
|
||||
const content::GlobalRequestID& request_id,
|
||||
const GURL& origin_url,
|
||||
LoginAuthRequiredCallback callback);
|
||||
|
||||
void Continue(const CefString& username, const CefString& password);
|
||||
void Cancel();
|
||||
|
||||
private:
|
||||
void Start(CefRefPtr<CefBrowserHostImpl> browser,
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const content::GlobalRequestID& request_id,
|
||||
const GURL& origin_url);
|
||||
|
||||
LoginAuthRequiredCallback callback_;
|
||||
base::WeakPtrFactory<LoginDelegate> weak_ptr_factory_;
|
||||
};
|
||||
|
||||
} // namespace net_service
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_NET_SERVICE_LOGIN_DELEGATE_H_
|
@@ -17,6 +17,7 @@
|
||||
#include "content/public/browser/resource_context.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "net/http/http_status_code.h"
|
||||
#include "services/network/public/cpp/cors/cors.h"
|
||||
|
||||
namespace net_service {
|
||||
|
||||
@@ -40,7 +41,14 @@ class ResourceContextData : public base::SupportsUserData::Data {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
content::WebContents* web_contents = web_contents_getter.Run();
|
||||
DCHECK(web_contents);
|
||||
|
||||
// Maybe the browser was destroyed while AddProxyOnUIThread was pending.
|
||||
if (!web_contents) {
|
||||
// Delete on the IO thread as expected by mojo bindings.
|
||||
content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE,
|
||||
proxy);
|
||||
return;
|
||||
}
|
||||
|
||||
content::BrowserContext* browser_context =
|
||||
web_contents->GetBrowserContext();
|
||||
@@ -59,6 +67,12 @@ class ResourceContextData : public base::SupportsUserData::Data {
|
||||
content::ResourceContext* resource_context) {
|
||||
CEF_REQUIRE_IOT();
|
||||
|
||||
// Maybe the proxy was destroyed while AddProxyOnUIThread was pending.
|
||||
if (proxy->destroyed_) {
|
||||
delete proxy;
|
||||
return;
|
||||
}
|
||||
|
||||
auto* self = static_cast<ResourceContextData*>(
|
||||
resource_context->GetUserData(kResourceContextUserDataKey));
|
||||
if (!self) {
|
||||
@@ -595,12 +609,6 @@ void InterceptedRequest::BeforeRequestReceived(const GURL& original_url,
|
||||
// Equivalent to no interception.
|
||||
InterceptResponseReceived(original_url, nullptr);
|
||||
} else {
|
||||
if (request_.referrer.is_valid()) {
|
||||
// Intentionally override if referrer header already exists.
|
||||
request_.headers.SetHeader(net::HttpRequestHeaders::kReferer,
|
||||
request_.referrer.spec());
|
||||
}
|
||||
|
||||
// TODO(network): Verify the case when WebContents::RenderFrameDeleted is
|
||||
// called before network request is intercepted (i.e. if that's possible
|
||||
// and whether it can result in any issues).
|
||||
@@ -629,6 +637,20 @@ void InterceptedRequest::InterceptResponseReceived(
|
||||
head.encoded_data_length = head.headers->raw_headers().length();
|
||||
head.content_length = head.encoded_body_length = 0;
|
||||
|
||||
std::string origin;
|
||||
if (request_.headers.GetHeader(net::HttpRequestHeaders::kOrigin, &origin) &&
|
||||
origin != url::Origin().Serialize()) {
|
||||
// Allow redirects of cross-origin resource loads.
|
||||
head.headers->AddHeader(MakeHeader(
|
||||
network::cors::header_names::kAccessControlAllowOrigin, origin));
|
||||
}
|
||||
|
||||
if (request_.fetch_credentials_mode ==
|
||||
network::mojom::FetchCredentialsMode::kInclude) {
|
||||
head.headers->AddHeader(MakeHeader(
|
||||
network::cors::header_names::kAccessControlAllowCredentials, "true"));
|
||||
}
|
||||
|
||||
current_response_ = head;
|
||||
const net::RedirectInfo& redirect_info =
|
||||
MakeRedirectInfo(request_, head.headers.get(), request_.url, 0);
|
||||
@@ -815,6 +837,11 @@ void InterceptedRequest::ContinueToBeforeRedirect(
|
||||
request_.site_for_cookies = redirect_info.new_site_for_cookies;
|
||||
request_.referrer = GURL(redirect_info.new_referrer);
|
||||
request_.referrer_policy = redirect_info.new_referrer_policy;
|
||||
|
||||
// The request method can be changed to "GET". In this case we need to
|
||||
// reset the request body manually.
|
||||
if (request_.method == net::HttpRequestHeaders::kGetMethod)
|
||||
request_.request_body = nullptr;
|
||||
}
|
||||
|
||||
void InterceptedRequest::ContinueToResponseStarted(int error_code) {
|
||||
@@ -862,6 +889,9 @@ void InterceptedRequest::ContinueToResponseStarted(int error_code) {
|
||||
}
|
||||
|
||||
void InterceptedRequest::OnDestroy() {
|
||||
// We don't want any callbacks after this point.
|
||||
weak_factory_.InvalidateWeakPtrs();
|
||||
|
||||
factory_->request_handler_->OnRequestComplete(id_, request_, status_);
|
||||
|
||||
// Destroys |this|.
|
||||
@@ -1027,7 +1057,9 @@ ProxyURLLoaderFactory::ProxyURLLoaderFactory(
|
||||
url_loader_header_client_binding_.Bind(std::move(header_client_request));
|
||||
}
|
||||
|
||||
ProxyURLLoaderFactory::~ProxyURLLoaderFactory() {}
|
||||
ProxyURLLoaderFactory::~ProxyURLLoaderFactory() {
|
||||
CEF_REQUIRE_IOT();
|
||||
}
|
||||
|
||||
// static
|
||||
void ProxyURLLoaderFactory::CreateOnIOThread(
|
||||
@@ -1046,6 +1078,7 @@ void ProxyURLLoaderFactory::CreateOnIOThread(
|
||||
void ProxyURLLoaderFactory::SetDisconnectCallback(
|
||||
DisconnectCallback on_disconnect) {
|
||||
CEF_REQUIRE_IOT();
|
||||
DCHECK(!destroyed_);
|
||||
DCHECK(!on_disconnect_);
|
||||
on_disconnect_ = std::move(on_disconnect);
|
||||
}
|
||||
@@ -1179,8 +1212,14 @@ void ProxyURLLoaderFactory::MaybeDestroySelf() {
|
||||
if (target_factory_.is_bound() || !requests_.empty())
|
||||
return;
|
||||
|
||||
// Deletes |this|.
|
||||
std::move(on_disconnect_).Run(this);
|
||||
CHECK(!destroyed_);
|
||||
destroyed_ = true;
|
||||
|
||||
// In some cases we may be destroyed before SetDisconnectCallback is called.
|
||||
if (on_disconnect_) {
|
||||
// Deletes |this|.
|
||||
std::move(on_disconnect_).Run(this);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace net_service
|
||||
|
@@ -195,6 +195,7 @@ class ProxyURLLoaderFactory
|
||||
|
||||
std::unique_ptr<InterceptedRequestHandler> request_handler_;
|
||||
|
||||
bool destroyed_ = false;
|
||||
DisconnectCallback on_disconnect_;
|
||||
|
||||
// Map of request ID to request object.
|
||||
|
@@ -36,6 +36,9 @@ namespace net_service {
|
||||
|
||||
namespace {
|
||||
|
||||
const int kLoadNoCookiesFlags =
|
||||
net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
|
||||
|
||||
class RequestCallbackWrapper : public CefRequestCallback {
|
||||
public:
|
||||
using Callback = base::OnceCallback<void(bool /* allow */)>;
|
||||
@@ -163,7 +166,32 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
class DestructionObserver : public CefBrowserHostImpl::Observer,
|
||||
public CefContext::Observer {
|
||||
public:
|
||||
DestructionObserver() = default;
|
||||
explicit DestructionObserver(CefBrowserHostImpl* browser) {
|
||||
if (browser) {
|
||||
browser_info_ = browser->browser_info();
|
||||
browser->AddObserver(this);
|
||||
} else {
|
||||
CefContext::Get()->AddObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~DestructionObserver() {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (!registered_)
|
||||
return;
|
||||
|
||||
// Verify that the browser or context still exists before attempting to
|
||||
// remove the observer.
|
||||
if (browser_info_) {
|
||||
auto browser = browser_info_->browser();
|
||||
if (browser)
|
||||
browser->RemoveObserver(this);
|
||||
} else if (CefContext::Get()) {
|
||||
// Network requests may be torn down during shutdown, so we can't check
|
||||
// CONTEXT_STATE_VALID() here.
|
||||
CefContext::Get()->RemoveObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
void SetWrapper(base::WeakPtr<InterceptedRequestHandlerWrapper> wrapper) {
|
||||
CEF_REQUIRE_IOT();
|
||||
@@ -173,121 +201,190 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
void OnBrowserDestroyed(CefBrowserHostImpl* browser) override {
|
||||
CEF_REQUIRE_UIT();
|
||||
browser->RemoveObserver(this);
|
||||
registered_ = false;
|
||||
browser_info_ = nullptr;
|
||||
NotifyOnDestroyed();
|
||||
}
|
||||
|
||||
void OnContextDestroyed() override {
|
||||
CEF_REQUIRE_UIT();
|
||||
CefContext::Get()->RemoveObserver(this);
|
||||
registered_ = false;
|
||||
NotifyOnDestroyed();
|
||||
}
|
||||
|
||||
private:
|
||||
void NotifyOnDestroyed() {
|
||||
// It's not safe to test the WeakPtr on the UI thread, so we'll just post
|
||||
// a task which will be ignored if the WeakPtr is invalid.
|
||||
CEF_POST_TASK(CEF_IOT, base::BindOnce(
|
||||
&InterceptedRequestHandlerWrapper::OnDestroyed,
|
||||
wrapper_));
|
||||
if (wrapper_.MaybeValid()) {
|
||||
// This will be a no-op if the WeakPtr is invalid.
|
||||
CEF_POST_TASK(
|
||||
CEF_IOT,
|
||||
base::BindOnce(&InterceptedRequestHandlerWrapper::OnDestroyed,
|
||||
wrapper_));
|
||||
}
|
||||
}
|
||||
|
||||
scoped_refptr<CefBrowserInfo> browser_info_;
|
||||
bool registered_ = true;
|
||||
|
||||
base::WeakPtr<InterceptedRequestHandlerWrapper> wrapper_;
|
||||
DISALLOW_COPY_AND_ASSIGN(DestructionObserver);
|
||||
};
|
||||
|
||||
InterceptedRequestHandlerWrapper() : weak_ptr_factory_(this) {}
|
||||
// Holds state information for InterceptedRequestHandlerWrapper. State is
|
||||
// initialized on the UI thread and later passed to the *Wrapper object on
|
||||
// the IO thread.
|
||||
struct InitState {
|
||||
InitState() {}
|
||||
|
||||
~InterceptedRequestHandlerWrapper() override {
|
||||
// There should be no pending or in-progress requests during destruction.
|
||||
DCHECK(pending_requests_.empty());
|
||||
DCHECK(request_map_.empty());
|
||||
~InitState() {
|
||||
if (destruction_observer_) {
|
||||
if (initialized_) {
|
||||
// Clear the reference added in
|
||||
// InterceptedRequestHandlerWrapper::SetInitialized().
|
||||
destruction_observer_->SetWrapper(nullptr);
|
||||
}
|
||||
DeleteDestructionObserver();
|
||||
}
|
||||
}
|
||||
|
||||
if (destruction_observer_) {
|
||||
destruction_observer_->SetWrapper(nullptr);
|
||||
void Initialize(content::BrowserContext* browser_context,
|
||||
CefRefPtr<CefBrowserHostImpl> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
int frame_tree_node_id,
|
||||
bool is_navigation,
|
||||
bool is_download,
|
||||
const url::Origin& request_initiator) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
browser_context_ = browser_context;
|
||||
resource_context_ = static_cast<CefResourceContext*>(
|
||||
browser_context->GetResourceContext());
|
||||
DCHECK(resource_context_);
|
||||
|
||||
// We register to be notified of CEF context or browser destruction so
|
||||
// that we can stop accepting new requests and cancel pending/in-progress
|
||||
// requests in a timely manner (e.g. before we start asserting about
|
||||
// leaked objects during CEF shutdown).
|
||||
destruction_observer_.reset(new DestructionObserver(browser.get()));
|
||||
|
||||
if (browser) {
|
||||
// These references will be released in OnDestroyed().
|
||||
browser_ = browser;
|
||||
frame_ = frame;
|
||||
}
|
||||
|
||||
render_process_id_ = render_process_id;
|
||||
render_frame_id_ = render_frame_id;
|
||||
frame_tree_node_id_ = frame_tree_node_id;
|
||||
is_navigation_ = is_navigation;
|
||||
is_download_ = is_download;
|
||||
request_initiator_ = request_initiator.Serialize();
|
||||
|
||||
// Default values for standard headers.
|
||||
accept_language_ = ComputeAcceptLanguageFromPref(
|
||||
GetAcceptLanguageList(browser_context, browser));
|
||||
DCHECK(!accept_language_.empty());
|
||||
user_agent_ = CefContentClient::Get()->browser()->GetUserAgent();
|
||||
DCHECK(!user_agent_.empty());
|
||||
}
|
||||
|
||||
void DeleteDestructionObserver() {
|
||||
DCHECK(destruction_observer_);
|
||||
CEF_POST_TASK(
|
||||
CEF_UIT, base::BindOnce(&InterceptedRequestHandlerWrapper::
|
||||
RemoveDestructionObserverOnUIThread,
|
||||
browser_ ? browser_->browser_info() : nullptr,
|
||||
std::move(destruction_observer_)));
|
||||
}
|
||||
}
|
||||
|
||||
static void RemoveDestructionObserverOnUIThread(
|
||||
scoped_refptr<CefBrowserInfo> browser_info,
|
||||
std::unique_ptr<DestructionObserver> observer) {
|
||||
// Verify that the browser or context is still valid before attempting to
|
||||
// remove the observer.
|
||||
if (browser_info) {
|
||||
auto browser = browser_info->browser();
|
||||
if (browser)
|
||||
browser->RemoveObserver(observer.get());
|
||||
} else if (CONTEXT_STATE_VALID()) {
|
||||
CefContext::Get()->RemoveObserver(observer.get());
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize(content::BrowserContext* browser_context,
|
||||
CefRefPtr<CefBrowserHostImpl> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
int frame_tree_node_id,
|
||||
bool is_navigation,
|
||||
bool is_download,
|
||||
const url::Origin& request_initiator,
|
||||
bool is_external) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
browser_context_ = browser_context;
|
||||
resource_context_ =
|
||||
static_cast<CefResourceContext*>(browser_context->GetResourceContext());
|
||||
DCHECK(resource_context_);
|
||||
|
||||
// We register to be notified of CEF context or browser destruction so that
|
||||
// we can stop accepting new requests and cancel pending/in-progress
|
||||
// requests in a timely manner (e.g. before we start asserting about leaked
|
||||
// objects during CEF shutdown).
|
||||
destruction_observer_.reset(new DestructionObserver());
|
||||
|
||||
if (browser) {
|
||||
// These references will be released in OnDestroyed().
|
||||
browser_ = browser;
|
||||
frame_ = frame;
|
||||
browser->AddObserver(destruction_observer_.get());
|
||||
} else {
|
||||
CefContext::Get()->AddObserver(destruction_observer_.get());
|
||||
CEF_UIT,
|
||||
base::BindOnce(&InitState::DeleteDestructionObserverOnUIThread,
|
||||
std::move(destruction_observer_)));
|
||||
}
|
||||
|
||||
render_process_id_ = render_process_id;
|
||||
render_frame_id_ = render_frame_id;
|
||||
frame_tree_node_id_ = frame_tree_node_id;
|
||||
is_navigation_ = is_navigation;
|
||||
is_download_ = is_download;
|
||||
request_initiator_ = request_initiator.Serialize();
|
||||
is_external_ = is_external;
|
||||
static void DeleteDestructionObserverOnUIThread(
|
||||
std::unique_ptr<DestructionObserver> observer) {}
|
||||
|
||||
// Only accessed on the UI thread.
|
||||
content::BrowserContext* browser_context_ = nullptr;
|
||||
|
||||
bool initialized_ = false;
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser_;
|
||||
CefRefPtr<CefFrame> frame_;
|
||||
CefResourceContext* resource_context_ = nullptr;
|
||||
int render_process_id_ = 0;
|
||||
int render_frame_id_ = -1;
|
||||
int frame_tree_node_id_ = -1;
|
||||
bool is_navigation_ = true;
|
||||
bool is_download_ = false;
|
||||
CefString request_initiator_;
|
||||
|
||||
// Default values for standard headers.
|
||||
accept_language_ = ComputeAcceptLanguageFromPref(
|
||||
GetAcceptLanguageList(browser_context, browser));
|
||||
DCHECK(!accept_language_.empty());
|
||||
user_agent_ = CefContentClient::Get()->browser()->GetUserAgent();
|
||||
DCHECK(!user_agent_.empty());
|
||||
std::string accept_language_;
|
||||
std::string user_agent_;
|
||||
|
||||
CEF_POST_TASK(
|
||||
CEF_IOT,
|
||||
base::BindOnce(&InterceptedRequestHandlerWrapper::SetInitialized,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
// Used to receive destruction notification.
|
||||
std::unique_ptr<DestructionObserver> destruction_observer_;
|
||||
};
|
||||
|
||||
// Manages InterceptedRequestHandlerWrapper initialization. The *Wrapper
|
||||
// object is owned by ProxyURLLoaderFactory and may be deleted before
|
||||
// SetInitialized() is called.
|
||||
struct InitHelper : base::RefCountedThreadSafe<InitHelper> {
|
||||
public:
|
||||
explicit InitHelper(InterceptedRequestHandlerWrapper* wrapper)
|
||||
: wrapper_(wrapper) {}
|
||||
|
||||
void MaybeSetInitialized(std::unique_ptr<InitState> init_state) {
|
||||
CEF_POST_TASK(CEF_IOT, base::BindOnce(&InitHelper::SetInitialized, this,
|
||||
std::move(init_state)));
|
||||
}
|
||||
|
||||
void Disconnect() {
|
||||
base::AutoLock lock_scope(lock_);
|
||||
wrapper_ = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
void SetInitialized(std::unique_ptr<InitState> init_state) {
|
||||
base::AutoLock lock_scope(lock_);
|
||||
// May be nullptr if the InterceptedRequestHandlerWrapper has already
|
||||
// been deleted.
|
||||
if (!wrapper_)
|
||||
return;
|
||||
wrapper_->SetInitialized(std::move(init_state));
|
||||
wrapper_ = nullptr;
|
||||
}
|
||||
|
||||
base::Lock lock_;
|
||||
InterceptedRequestHandlerWrapper* wrapper_;
|
||||
};
|
||||
|
||||
InterceptedRequestHandlerWrapper()
|
||||
: init_helper_(base::MakeRefCounted<InitHelper>(this)),
|
||||
weak_ptr_factory_(this) {}
|
||||
|
||||
~InterceptedRequestHandlerWrapper() override {
|
||||
CEF_REQUIRE_IOT();
|
||||
|
||||
// There should be no in-progress requests during destruction.
|
||||
DCHECK(request_map_.empty());
|
||||
|
||||
// Don't continue with initialization if we get deleted before
|
||||
// SetInitialized is called asynchronously.
|
||||
init_helper_->Disconnect();
|
||||
}
|
||||
|
||||
void SetInitialized() {
|
||||
scoped_refptr<InitHelper> init_helper() const { return init_helper_; }
|
||||
|
||||
void SetInitialized(std::unique_ptr<InitState> init_state) {
|
||||
CEF_REQUIRE_IOT();
|
||||
initialized_ = true;
|
||||
DCHECK(!init_state_);
|
||||
init_state_ = std::move(init_state);
|
||||
|
||||
// Check that the CEF context or associated browser was not destroyed
|
||||
// between the calls to Initialize and SetInitialized, in which case
|
||||
// we won't get an OnDestroyed callback from DestructionObserver.
|
||||
if (browser_) {
|
||||
if (!browser_->browser_info()->browser()) {
|
||||
if (init_state_->browser_) {
|
||||
if (!init_state_->browser_->browser_info()->browser()) {
|
||||
OnDestroyed();
|
||||
return;
|
||||
}
|
||||
@@ -296,7 +393,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
destruction_observer_->SetWrapper(weak_ptr_factory_.GetWeakPtr());
|
||||
init_state_->initialized_ = true;
|
||||
init_state_->destruction_observer_->SetWrapper(
|
||||
weak_ptr_factory_.GetWeakPtr());
|
||||
|
||||
// Continue any pending requests.
|
||||
if (!pending_requests_.empty()) {
|
||||
@@ -320,7 +419,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!initialized_) {
|
||||
if (!init_state_) {
|
||||
// Queue requests until we're initialized.
|
||||
pending_requests_.push_back(std::make_unique<PendingRequest>(
|
||||
id, request, request_was_redirected, std::move(callback),
|
||||
@@ -333,19 +432,22 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
|
||||
// Add standard headers, if currently unspecified.
|
||||
request->headers.SetHeaderIfMissing(
|
||||
net::HttpRequestHeaders::kAcceptLanguage, accept_language_);
|
||||
net::HttpRequestHeaders::kAcceptLanguage,
|
||||
init_state_->accept_language_);
|
||||
request->headers.SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent,
|
||||
user_agent_);
|
||||
init_state_->user_agent_);
|
||||
|
||||
const bool is_external = IsExternalRequest(request);
|
||||
|
||||
// External requests will not have a default handler.
|
||||
bool intercept_only = is_external_;
|
||||
bool intercept_only = is_external;
|
||||
|
||||
CefRefPtr<CefRequestImpl> requestPtr;
|
||||
CefRefPtr<CefResourceRequestHandler> handler =
|
||||
GetHandler(id, request, &intercept_only, requestPtr);
|
||||
|
||||
CefRefPtr<CefSchemeHandlerFactory> scheme_factory =
|
||||
resource_context_->GetSchemeHandlerFactory(request->url);
|
||||
init_state_->resource_context_->GetSchemeHandlerFactory(request->url);
|
||||
if (scheme_factory && !requestPtr) {
|
||||
requestPtr = MakeRequest(request, id.hash(), true);
|
||||
}
|
||||
@@ -360,13 +462,13 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
std::move(cancel_callback));
|
||||
|
||||
if (handler) {
|
||||
state->cookie_filter_ =
|
||||
handler->GetCookieAccessFilter(browser_, frame_, requestPtr.get());
|
||||
state->cookie_filter_ = handler->GetCookieAccessFilter(
|
||||
init_state_->browser_, init_state_->frame_, requestPtr.get());
|
||||
}
|
||||
|
||||
auto exec_callback =
|
||||
base::BindOnce(std::move(callback), maybe_intercept_request,
|
||||
is_external_ ? true : intercept_only);
|
||||
is_external ? true : intercept_only);
|
||||
|
||||
if (!maybe_intercept_request) {
|
||||
// Cookies will be handled by the NetworkService.
|
||||
@@ -395,7 +497,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
auto done_cookie_callback = base::BindOnce(
|
||||
&InterceptedRequestHandlerWrapper::ContinueWithLoadedCookies,
|
||||
weak_ptr_factory_.GetWeakPtr(), id, request, std::move(callback));
|
||||
net_service::LoadCookies(browser_context_, *request, allow_cookie_callback,
|
||||
net_service::LoadCookies(init_state_->browser_context_, *request,
|
||||
allow_cookie_callback,
|
||||
std::move(done_cookie_callback));
|
||||
}
|
||||
|
||||
@@ -421,7 +524,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
CefCookie cef_cookie;
|
||||
if (net_service::MakeCefCookie(cookie, cef_cookie)) {
|
||||
*allow = state->cookie_filter_->CanSendCookie(
|
||||
browser_, frame_, state->pending_request_.get(), cef_cookie);
|
||||
init_state_->browser_, init_state_->frame_,
|
||||
state->pending_request_.get(), cef_cookie);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,8 +547,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
// Also add/save cookies ourselves for default-handled network requests
|
||||
// so that we can filter them. This will be a no-op for custom-handled
|
||||
// requests.
|
||||
request->load_flags |=
|
||||
net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
|
||||
request->load_flags |= kLoadNoCookiesFlags;
|
||||
}
|
||||
|
||||
if (!allowed_cookies.empty()) {
|
||||
@@ -490,7 +593,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
base::Passed(std::move(callback))));
|
||||
|
||||
cef_return_value_t retval = state->handler_->OnBeforeResourceLoad(
|
||||
browser_, frame_, state->pending_request_.get(), callbackPtr.get());
|
||||
init_state_->browser_, init_state_->frame_,
|
||||
state->pending_request_.get(), callbackPtr.get());
|
||||
if (retval != RV_CONTINUE_ASYNC) {
|
||||
// Continue or cancel the request immediately.
|
||||
callbackPtr->Continue(retval == RV_CONTINUE);
|
||||
@@ -555,12 +659,13 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
if (state->handler_) {
|
||||
// Does the client want to handle the request?
|
||||
resource_handler = state->handler_->GetResourceHandler(
|
||||
browser_, frame_, state->pending_request_.get());
|
||||
init_state_->browser_, init_state_->frame_,
|
||||
state->pending_request_.get());
|
||||
}
|
||||
if (!resource_handler && state->scheme_factory_) {
|
||||
// Does the scheme factory want to handle the request?
|
||||
resource_handler = state->scheme_factory_->Create(
|
||||
browser_, frame_, request->url.scheme(),
|
||||
init_state_->browser_, init_state_->frame_, request->url.scheme(),
|
||||
state->pending_request_.get());
|
||||
}
|
||||
|
||||
@@ -615,6 +720,11 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->cookie_filter_) {
|
||||
// Remove the flags that were added in ContinueWithLoadedCookies.
|
||||
request->load_flags &= ~kLoadNoCookiesFlags;
|
||||
}
|
||||
|
||||
if (!state->handler_) {
|
||||
// Cookies may come from a scheme handler.
|
||||
MaybeSaveCookies(
|
||||
@@ -646,9 +756,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
CefString newUrl = redirect_info.new_url.spec();
|
||||
CefString oldUrl = newUrl;
|
||||
bool url_changed = false;
|
||||
state->handler_->OnResourceRedirect(browser_, frame_,
|
||||
state->pending_request_.get(),
|
||||
state->pending_response_.get(), newUrl);
|
||||
state->handler_->OnResourceRedirect(
|
||||
init_state_->browser_, init_state_->frame_,
|
||||
state->pending_request_.get(), state->pending_response_.get(), newUrl);
|
||||
if (newUrl != oldUrl) {
|
||||
// Also support relative URLs.
|
||||
const GURL& url = redirect_info.new_url.Resolve(newUrl.ToString());
|
||||
@@ -684,9 +794,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
auto response_mode = ResponseMode::CONTINUE;
|
||||
GURL new_url;
|
||||
|
||||
if (state->handler_->OnResourceResponse(browser_, frame_,
|
||||
state->pending_request_.get(),
|
||||
state->pending_response_.get())) {
|
||||
if (state->handler_->OnResourceResponse(
|
||||
init_state_->browser_, init_state_->frame_,
|
||||
state->pending_request_.get(), state->pending_response_.get())) {
|
||||
// The request may have been modified.
|
||||
const auto changes = state->pending_request_->GetChanges();
|
||||
if (changes) {
|
||||
@@ -746,7 +856,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
auto done_cookie_callback = base::BindOnce(
|
||||
&InterceptedRequestHandlerWrapper::ContinueWithSavedCookies,
|
||||
weak_ptr_factory_.GetWeakPtr(), id, std::move(callback));
|
||||
net_service::SaveCookies(browser_context_, *request, head,
|
||||
net_service::SaveCookies(init_state_->browser_context_, *request, head,
|
||||
allow_cookie_callback,
|
||||
std::move(done_cookie_callback));
|
||||
}
|
||||
@@ -768,8 +878,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
CefCookie cef_cookie;
|
||||
if (net_service::MakeCefCookie(cookie, cef_cookie)) {
|
||||
*allow = state->cookie_filter_->CanSaveCookie(
|
||||
browser_, frame_, state->pending_request_.get(),
|
||||
state->pending_response_.get(), cef_cookie);
|
||||
init_state_->browser_, init_state_->frame_,
|
||||
state->pending_request_.get(), state->pending_response_.get(),
|
||||
cef_cookie);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -795,8 +906,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
|
||||
if (state->handler_) {
|
||||
auto filter = state->handler_->GetResourceResponseFilter(
|
||||
browser_, frame_, state->pending_request_.get(),
|
||||
state->pending_response_.get());
|
||||
init_state_->browser_, init_state_->frame_,
|
||||
state->pending_request_.get(), state->pending_response_.get());
|
||||
if (filter) {
|
||||
return CreateResponseFilterHandler(
|
||||
filter, std::move(body),
|
||||
@@ -831,14 +942,28 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
|
||||
RequestState* state = GetState(id);
|
||||
if (!state) {
|
||||
// The request may have been canceled during destruction.
|
||||
// The request may have been aborted during initialization or canceled
|
||||
// during destruction. This method will always be called before a request
|
||||
// is deleted, so if the request is currently pending also remove it from
|
||||
// the list.
|
||||
if (!pending_requests_.empty()) {
|
||||
PendingRequests::iterator it = pending_requests_.begin();
|
||||
for (; it != pending_requests_.end(); ++it) {
|
||||
if ((*it)->id_ == id) {
|
||||
pending_requests_.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_external = IsExternalRequest(&request);
|
||||
|
||||
// Redirection of standard custom schemes is handled with a restart, so we
|
||||
// get completion notifications for both the original (redirected) request
|
||||
// and the final request. Don't report completion of the redirected request.
|
||||
const bool ignore_result = is_external_ && request.url.IsStandard() &&
|
||||
const bool ignore_result = is_external && request.url.IsStandard() &&
|
||||
status.error_code == net::ERR_ABORTED &&
|
||||
state->pending_response_.get() &&
|
||||
net::HttpResponseHeaders::IsRedirectResponseCode(
|
||||
@@ -849,11 +974,11 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
|
||||
CallHandlerOnComplete(state, status);
|
||||
|
||||
if (status.error_code != 0 && is_external_) {
|
||||
if (status.error_code != 0 && is_external) {
|
||||
bool allow_os_execution = false;
|
||||
state->handler_->OnProtocolExecution(browser_, frame_,
|
||||
state->pending_request_.get(),
|
||||
allow_os_execution);
|
||||
state->handler_->OnProtocolExecution(
|
||||
init_state_->browser_, init_state_->frame_,
|
||||
state->pending_request_.get(), allow_os_execution);
|
||||
if (allow_os_execution) {
|
||||
CefBrowserPlatformDelegate::HandleExternalProtocol(request.url);
|
||||
}
|
||||
@@ -886,8 +1011,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
state->pending_response_->SetReadOnly(true);
|
||||
|
||||
state->handler_->OnResourceLoadComplete(
|
||||
browser_, frame_, state->pending_request_.get(),
|
||||
state->pending_response_.get(),
|
||||
init_state_->browser_, init_state_->frame_,
|
||||
state->pending_request_.get(), state->pending_response_.get(),
|
||||
status.error_code == 0 ? UR_SUCCESS : UR_FAILED,
|
||||
status.encoded_body_length);
|
||||
}
|
||||
@@ -902,9 +1027,10 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
|
||||
const int64 request_id = id.hash();
|
||||
|
||||
if (browser_) {
|
||||
if (init_state_->browser_) {
|
||||
// Maybe the browser's client wants to handle it?
|
||||
CefRefPtr<CefClient> client = browser_->GetHost()->GetClient();
|
||||
CefRefPtr<CefClient> client =
|
||||
init_state_->browser_->GetHost()->GetClient();
|
||||
if (client) {
|
||||
CefRefPtr<CefRequestHandler> request_handler =
|
||||
client->GetRequestHandler();
|
||||
@@ -912,8 +1038,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
requestPtr = MakeRequest(request, request_id, true);
|
||||
|
||||
handler = request_handler->GetResourceRequestHandler(
|
||||
browser_, frame_, requestPtr.get(), is_navigation_, is_download_,
|
||||
request_initiator_, *intercept_only);
|
||||
init_state_->browser_, init_state_->frame_, requestPtr.get(),
|
||||
init_state_->is_navigation_, init_state_->is_download_,
|
||||
init_state_->request_initiator_, *intercept_only);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -921,16 +1048,17 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
if (!handler) {
|
||||
// Maybe the request context wants to handle it?
|
||||
CefRefPtr<CefRequestContextHandler> context_handler =
|
||||
resource_context_->GetHandler(render_process_id_,
|
||||
request->render_frame_id,
|
||||
frame_tree_node_id_, false);
|
||||
init_state_->resource_context_->GetHandler(
|
||||
init_state_->render_process_id_, request->render_frame_id,
|
||||
init_state_->frame_tree_node_id_, false);
|
||||
if (context_handler) {
|
||||
if (!requestPtr)
|
||||
requestPtr = MakeRequest(request, request_id, true);
|
||||
|
||||
handler = context_handler->GetResourceRequestHandler(
|
||||
browser_, frame_, requestPtr.get(), is_navigation_, is_download_,
|
||||
request_initiator_, *intercept_only);
|
||||
init_state_->browser_, init_state_->frame_, requestPtr.get(),
|
||||
init_state_->is_navigation_, init_state_->is_download_,
|
||||
init_state_->request_initiator_, *intercept_only);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -964,10 +1092,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
// CEF context or associated browser is destroyed.
|
||||
void OnDestroyed() {
|
||||
CEF_REQUIRE_IOT();
|
||||
DCHECK(initialized_);
|
||||
DCHECK(init_state_);
|
||||
|
||||
DCHECK(destruction_observer_);
|
||||
destruction_observer_.reset();
|
||||
init_state_->DeleteDestructionObserver();
|
||||
|
||||
// Stop accepting new requests.
|
||||
shutting_down_ = true;
|
||||
@@ -990,10 +1117,10 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
network::URLLoaderCompletionStatus(net::ERR_ABORTED));
|
||||
}
|
||||
|
||||
if (browser_) {
|
||||
if (init_state_->browser_) {
|
||||
// Clear objects that reference the browser.
|
||||
browser_ = nullptr;
|
||||
frame_ = nullptr;
|
||||
init_state_->browser_ = nullptr;
|
||||
init_state_->frame_ = nullptr;
|
||||
}
|
||||
|
||||
// Execute cancel callbacks and delete pending and in-progress requests.
|
||||
@@ -1023,43 +1150,29 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
return requestPtr;
|
||||
}
|
||||
|
||||
bool initialized_ = false;
|
||||
// Returns true if |request| cannot be handled internally.
|
||||
static bool IsExternalRequest(const network::ResourceRequest* request) {
|
||||
return !scheme::IsInternalHandledScheme(request->url.scheme());
|
||||
}
|
||||
|
||||
scoped_refptr<InitHelper> init_helper_;
|
||||
std::unique_ptr<InitState> init_state_;
|
||||
|
||||
bool shutting_down_ = false;
|
||||
|
||||
// Only accessed on the UI thread.
|
||||
content::BrowserContext* browser_context_ = nullptr;
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser_;
|
||||
CefRefPtr<CefFrame> frame_;
|
||||
CefResourceContext* resource_context_ = nullptr;
|
||||
int render_process_id_ = 0;
|
||||
int render_frame_id_ = -1;
|
||||
int frame_tree_node_id_ = -1;
|
||||
bool is_navigation_ = true;
|
||||
bool is_download_ = false;
|
||||
CefString request_initiator_;
|
||||
bool is_external_ = false;
|
||||
|
||||
// Default values for standard headers.
|
||||
std::string accept_language_;
|
||||
std::string user_agent_;
|
||||
|
||||
using RequestMap = std::map<RequestId, std::unique_ptr<RequestState>>;
|
||||
RequestMap request_map_;
|
||||
|
||||
using PendingRequests = std::vector<std::unique_ptr<PendingRequest>>;
|
||||
PendingRequests pending_requests_;
|
||||
|
||||
// Used to receive destruction notification.
|
||||
std::unique_ptr<DestructionObserver> destruction_observer_;
|
||||
|
||||
base::WeakPtrFactory<InterceptedRequestHandlerWrapper> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(InterceptedRequestHandlerWrapper);
|
||||
};
|
||||
|
||||
void InitOnUIThread(
|
||||
InterceptedRequestHandlerWrapper* wrapper,
|
||||
scoped_refptr<InterceptedRequestHandlerWrapper::InitHelper> init_helper,
|
||||
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
|
||||
int frame_tree_node_id,
|
||||
const network::ResourceRequest& request) {
|
||||
@@ -1116,6 +1229,7 @@ void InitOnUIThread(
|
||||
}
|
||||
#endif
|
||||
|
||||
// May return nullptr for requests originating from guest views.
|
||||
browserPtr = CefBrowserHostImpl::GetBrowserForHost(frame);
|
||||
if (browserPtr) {
|
||||
framePtr = browserPtr->GetFrameForHost(frame);
|
||||
@@ -1133,10 +1247,14 @@ void InitOnUIThread(
|
||||
if (request.request_initiator.has_value())
|
||||
request_initiator = *request.request_initiator;
|
||||
|
||||
wrapper->Initialize(browser_context, browserPtr, framePtr, render_process_id,
|
||||
request.render_frame_id, frame_tree_node_id,
|
||||
is_navigation, is_download, request_initiator,
|
||||
true /* is_external */);
|
||||
auto init_state =
|
||||
std::make_unique<InterceptedRequestHandlerWrapper::InitState>();
|
||||
init_state->Initialize(browser_context, browserPtr, framePtr,
|
||||
render_process_id, request.render_frame_id,
|
||||
frame_tree_node_id, is_navigation, is_download,
|
||||
request_initiator);
|
||||
|
||||
init_helper->MaybeSetInitialized(std::move(init_state));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -1149,8 +1267,6 @@ std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
|
||||
bool is_download,
|
||||
const url::Origin& request_initiator) {
|
||||
CEF_REQUIRE_UIT();
|
||||
auto wrapper = std::make_unique<InterceptedRequestHandlerWrapper>();
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browserPtr;
|
||||
CefRefPtr<CefFrame> framePtr;
|
||||
int render_frame_id = -1;
|
||||
@@ -1160,6 +1276,8 @@ std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
|
||||
if (frame) {
|
||||
render_frame_id = frame->GetRoutingID();
|
||||
frame_tree_node_id = frame->GetFrameTreeNodeId();
|
||||
|
||||
// May return nullptr for requests originating from guest views.
|
||||
browserPtr = CefBrowserHostImpl::GetBrowserForHost(frame);
|
||||
if (browserPtr) {
|
||||
framePtr = browserPtr->GetFrameForHost(frame);
|
||||
@@ -1167,14 +1285,15 @@ std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
|
||||
}
|
||||
}
|
||||
|
||||
// Flag subresource loads of custom schemes.
|
||||
const bool is_external =
|
||||
!is_navigation && !is_download && !request_initiator.scheme().empty() &&
|
||||
!scheme::IsInternalHandledScheme(request_initiator.scheme());
|
||||
auto init_state =
|
||||
std::make_unique<InterceptedRequestHandlerWrapper::InitState>();
|
||||
init_state->Initialize(browser_context, browserPtr, framePtr,
|
||||
render_process_id, render_frame_id, frame_tree_node_id,
|
||||
is_navigation, is_download, request_initiator);
|
||||
|
||||
auto wrapper = std::make_unique<InterceptedRequestHandlerWrapper>();
|
||||
wrapper->init_helper()->MaybeSetInitialized(std::move(init_state));
|
||||
|
||||
wrapper->Initialize(browser_context, browserPtr, framePtr, render_process_id,
|
||||
render_frame_id, frame_tree_node_id, is_navigation,
|
||||
is_download, request_initiator, is_external);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@@ -1184,9 +1303,9 @@ std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
|
||||
const network::ResourceRequest& request) {
|
||||
CEF_REQUIRE_IOT();
|
||||
auto wrapper = std::make_unique<InterceptedRequestHandlerWrapper>();
|
||||
CEF_POST_TASK(CEF_UIT, base::BindOnce(
|
||||
InitOnUIThread, base::Unretained(wrapper.get()),
|
||||
web_contents_getter, frame_tree_node_id, request));
|
||||
CEF_POST_TASK(CEF_UIT, base::BindOnce(InitOnUIThread, wrapper->init_helper(),
|
||||
web_contents_getter, frame_tree_node_id,
|
||||
request));
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
@@ -546,6 +546,21 @@ void CefRequestContextImpl::ClearCertificateExceptions(
|
||||
this, callback));
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::ClearHttpAuthCredentials(
|
||||
CefRefPtr<CefCompletionCallback> callback) {
|
||||
if (net_service::IsEnabled()) {
|
||||
GetBrowserContext(
|
||||
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}),
|
||||
base::Bind(&CefRequestContextImpl::ClearHttpAuthCredentialsInternal,
|
||||
this, callback));
|
||||
} else {
|
||||
GetRequestContextImpl(
|
||||
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
|
||||
base::Bind(&CefRequestContextImpl::ClearHttpAuthCredentialsInternalOld,
|
||||
this, callback));
|
||||
}
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::CloseAllConnections(
|
||||
CefRefPtr<CefCompletionCallback> callback) {
|
||||
if (net_service::IsEnabled()) {
|
||||
@@ -847,6 +862,36 @@ void CefRequestContextImpl::ClearCertificateExceptionsInternal(
|
||||
}
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::ClearHttpAuthCredentialsInternal(
|
||||
CefRefPtr<CefCompletionCallback> callback,
|
||||
CefBrowserContext* browser_context) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
browser_context->GetNetworkContext()->ClearHttpAuthCache(
|
||||
base::Time(), base::Bind(&CefCompletionCallback::OnComplete, callback));
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::ClearHttpAuthCredentialsInternalOld(
|
||||
CefRefPtr<CefCompletionCallback> callback,
|
||||
scoped_refptr<CefURLRequestContextGetter> request_context) {
|
||||
CEF_REQUIRE_IOT();
|
||||
|
||||
net::URLRequestContext* url_context = request_context->GetURLRequestContext();
|
||||
if (url_context) {
|
||||
net::HttpNetworkSession* http_session =
|
||||
url_context->http_transaction_factory()->GetSession();
|
||||
DCHECK(http_session);
|
||||
|
||||
http_session->http_auth_cache()->ClearEntriesAddedSince(base::Time());
|
||||
http_session->CloseAllConnections();
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefCompletionCallback::OnComplete, callback));
|
||||
}
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::CloseAllConnectionsInternal(
|
||||
CefRefPtr<CefCompletionCallback> callback,
|
||||
CefBrowserContext* browser_context) {
|
||||
|
@@ -73,6 +73,8 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||
CefString& error) override;
|
||||
void ClearCertificateExceptions(
|
||||
CefRefPtr<CefCompletionCallback> callback) override;
|
||||
void ClearHttpAuthCredentials(
|
||||
CefRefPtr<CefCompletionCallback> callback) override;
|
||||
void CloseAllConnections(CefRefPtr<CefCompletionCallback> callback) override;
|
||||
void ResolveHost(const CefString& origin,
|
||||
CefRefPtr<CefResolveCallback> callback) override;
|
||||
@@ -157,6 +159,12 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||
void ClearCertificateExceptionsInternal(
|
||||
CefRefPtr<CefCompletionCallback> callback,
|
||||
CefBrowserContext* browser_context);
|
||||
void ClearHttpAuthCredentialsInternal(
|
||||
CefRefPtr<CefCompletionCallback> callback,
|
||||
CefBrowserContext* browser_context);
|
||||
void ClearHttpAuthCredentialsInternalOld(
|
||||
CefRefPtr<CefCompletionCallback> callback,
|
||||
scoped_refptr<CefURLRequestContextGetter> request_context);
|
||||
void CloseAllConnectionsInternal(CefRefPtr<CefCompletionCallback> callback,
|
||||
CefBrowserContext* browser_context);
|
||||
void CloseAllConnectionsInternalOld(
|
||||
|
@@ -566,6 +566,13 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
}
|
||||
}
|
||||
|
||||
if (features::kMimeHandlerViewInCrossProcessFrame.default_state ==
|
||||
base::FEATURE_ENABLED_BY_DEFAULT) {
|
||||
// TODO: Add support for cross-process mime handler view (see issue #2727)
|
||||
disable_features.push_back(
|
||||
features::kMimeHandlerViewInCrossProcessFrame.name);
|
||||
}
|
||||
|
||||
if (!disable_features.empty()) {
|
||||
DCHECK(!base::FeatureList::GetInstance());
|
||||
std::string disable_features_str =
|
||||
@@ -725,11 +732,9 @@ int CefMainDelegate::RunProcess(
|
||||
bool CefMainDelegate::CreateUIThread(base::OnceClosure setup_callback) {
|
||||
DCHECK(!ui_thread_);
|
||||
|
||||
std::unique_ptr<CefUIThread> thread;
|
||||
thread.reset(new CefUIThread(std::move(setup_callback)));
|
||||
thread->Start();
|
||||
thread->WaitUntilThreadStarted();
|
||||
ui_thread_.swap(thread);
|
||||
ui_thread_.reset(new CefUIThread(std::move(setup_callback)));
|
||||
ui_thread_->Start();
|
||||
ui_thread_->WaitUntilThreadStarted();
|
||||
|
||||
InitMessagePumpFactoryForUI();
|
||||
return true;
|
||||
|
@@ -1133,9 +1133,10 @@ void CefRequestImpl::Changed(uint8_t changes) {
|
||||
}
|
||||
if ((changes & kChangedHeaderMap) &&
|
||||
!(backup_->backups_ & kChangedHeaderMap)) {
|
||||
if (!backup_->headermap_)
|
||||
backup_->headermap_.reset(new HeaderMap());
|
||||
backup_->headermap_->swap(headermap_);
|
||||
backup_->headermap_.reset(new HeaderMap());
|
||||
if (!headermap_.empty()) {
|
||||
backup_->headermap_->insert(headermap_.begin(), headermap_.end());
|
||||
}
|
||||
backup_->backups_ |= kChangedHeaderMap;
|
||||
}
|
||||
if ((changes & kChangedFlags) && !(backup_->backups_ & kChangedFlags)) {
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "libcef/renderer/render_message_filter.h"
|
||||
#include "libcef/renderer/render_thread_observer.h"
|
||||
#include "libcef/renderer/thread_util.h"
|
||||
#include "libcef/renderer/url_loader_throttle_provider_impl.h"
|
||||
#include "libcef/renderer/v8_impl.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
@@ -603,12 +604,28 @@ void CefContentRendererClient::RunScriptsAtDocumentIdle(
|
||||
}
|
||||
|
||||
void CefContentRendererClient::DevToolsAgentAttached() {
|
||||
CEF_REQUIRE_RT();
|
||||
// WebWorkers may be creating agents on a different thread.
|
||||
if (!render_task_runner_->BelongsToCurrentThread()) {
|
||||
render_task_runner_->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&CefContentRendererClient::DevToolsAgentAttached,
|
||||
base::Unretained(this)));
|
||||
return;
|
||||
}
|
||||
|
||||
++devtools_agent_count_;
|
||||
}
|
||||
|
||||
void CefContentRendererClient::DevToolsAgentDetached() {
|
||||
CEF_REQUIRE_RT();
|
||||
// WebWorkers may be creating agents on a different thread.
|
||||
if (!render_task_runner_->BelongsToCurrentThread()) {
|
||||
render_task_runner_->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&CefContentRendererClient::DevToolsAgentDetached,
|
||||
base::Unretained(this)));
|
||||
return;
|
||||
}
|
||||
|
||||
--devtools_agent_count_;
|
||||
if (devtools_agent_count_ == 0 && uncaught_exception_stack_size_ > 0) {
|
||||
// When the last DevToolsAgent is detached the stack size is set to 0.
|
||||
@@ -623,6 +640,12 @@ void CefContentRendererClient::CreateRendererService(
|
||||
service_binding_.Bind(std::move(service_request));
|
||||
}
|
||||
|
||||
std::unique_ptr<content::URLLoaderThrottleProvider>
|
||||
CefContentRendererClient::CreateURLLoaderThrottleProvider(
|
||||
content::URLLoaderThrottleProviderType provider_type) {
|
||||
return std::make_unique<CefURLLoaderThrottleProviderImpl>(provider_type);
|
||||
}
|
||||
|
||||
void CefContentRendererClient::OnBindInterface(
|
||||
const service_manager::BindSourceInfo& remote_info,
|
||||
const std::string& name,
|
||||
|
@@ -138,6 +138,9 @@ class CefContentRendererClient
|
||||
void DevToolsAgentDetached() override;
|
||||
void CreateRendererService(
|
||||
service_manager::mojom::ServiceRequest service_request) override;
|
||||
std::unique_ptr<content::URLLoaderThrottleProvider>
|
||||
CreateURLLoaderThrottleProvider(
|
||||
content::URLLoaderThrottleProviderType provider_type) override;
|
||||
|
||||
// service_manager::Service implementation.
|
||||
void OnBindInterface(const service_manager::BindSourceInfo& remote_info,
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "libcef/renderer/blink_glue.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "content/public/renderer/render_thread.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "content/renderer/render_frame_impl.h"
|
||||
#include "third_party/blink/public/web/web_local_frame.h"
|
||||
@@ -20,7 +21,7 @@ int64_t GetIdentifier(blink::WebLocalFrame* frame) {
|
||||
// routing IDs are unique within a given renderer process.
|
||||
content::RenderFrame* render_frame =
|
||||
content::RenderFrame::FromWebFrame(frame);
|
||||
return frame_util::MakeFrameId(render_frame->GetRenderView()->GetRoutingID(),
|
||||
return frame_util::MakeFrameId(content::RenderThread::Get()->GetClientId(),
|
||||
render_frame->GetRoutingID());
|
||||
}
|
||||
|
||||
|
78
libcef/renderer/url_loader_throttle_provider_impl.cc
Normal file
78
libcef/renderer/url_loader_throttle_provider_impl.cc
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright 2018 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/renderer/url_loader_throttle_provider_impl.h"
|
||||
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/feature_list.h"
|
||||
#include "content/public/common/content_features.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "third_party/blink/public/platform/web_url.h"
|
||||
|
||||
CefURLLoaderThrottleProviderImpl::CefURLLoaderThrottleProviderImpl(
|
||||
content::URLLoaderThrottleProviderType type)
|
||||
: type_(type) {
|
||||
DETACH_FROM_THREAD(thread_checker_);
|
||||
}
|
||||
|
||||
CefURLLoaderThrottleProviderImpl::~CefURLLoaderThrottleProviderImpl() {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
}
|
||||
|
||||
CefURLLoaderThrottleProviderImpl::CefURLLoaderThrottleProviderImpl(
|
||||
const CefURLLoaderThrottleProviderImpl& other)
|
||||
: type_(other.type_) {
|
||||
DETACH_FROM_THREAD(thread_checker_);
|
||||
}
|
||||
|
||||
std::unique_ptr<content::URLLoaderThrottleProvider>
|
||||
CefURLLoaderThrottleProviderImpl::Clone() {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
return base::WrapUnique(new CefURLLoaderThrottleProviderImpl(*this));
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<content::URLLoaderThrottle>>
|
||||
CefURLLoaderThrottleProviderImpl::CreateThrottles(
|
||||
int render_frame_id,
|
||||
const blink::WebURLRequest& request,
|
||||
content::ResourceType resource_type) {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
|
||||
std::vector<std::unique_ptr<content::URLLoaderThrottle>> throttles;
|
||||
|
||||
bool network_service_enabled =
|
||||
base::FeatureList::IsEnabled(network::features::kNetworkService);
|
||||
// Some throttles have already been added in the browser for frame resources.
|
||||
// Don't add them for frame requests.
|
||||
bool is_frame_resource = content::IsResourceTypeFrame(resource_type);
|
||||
|
||||
DCHECK(!is_frame_resource ||
|
||||
type_ == content::URLLoaderThrottleProviderType::kFrame);
|
||||
|
||||
if (extensions::ExtensionsEnabled() && network_service_enabled &&
|
||||
type_ == content::URLLoaderThrottleProviderType::kFrame &&
|
||||
resource_type == content::ResourceType::kObject) {
|
||||
content::RenderFrame* render_frame =
|
||||
content::RenderFrame::FromRoutingID(render_frame_id);
|
||||
auto mime_handlers =
|
||||
extensions::MimeHandlerViewContainer::FromRenderFrame(render_frame);
|
||||
GURL gurl(request.Url());
|
||||
for (auto* handler : mime_handlers) {
|
||||
auto throttle = handler->MaybeCreatePluginThrottle(gurl);
|
||||
if (throttle) {
|
||||
throttles.push_back(std::move(throttle));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return throttles;
|
||||
}
|
||||
|
||||
void CefURLLoaderThrottleProviderImpl::SetOnline(bool is_online) {}
|
45
libcef/renderer/url_loader_throttle_provider_impl.h
Normal file
45
libcef/renderer/url_loader_throttle_provider_impl.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2018 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_RENDERER_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_
|
||||
#define CEF_LIBCEF_RENDERER_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/threading/thread_checker.h"
|
||||
#include "content/public/renderer/url_loader_throttle_provider.h"
|
||||
|
||||
// Instances must be constructed on the render thread, and then used and
|
||||
// destructed on a single thread, which can be different from the render thread.
|
||||
class CefURLLoaderThrottleProviderImpl
|
||||
: public content::URLLoaderThrottleProvider {
|
||||
public:
|
||||
explicit CefURLLoaderThrottleProviderImpl(
|
||||
content::URLLoaderThrottleProviderType type);
|
||||
|
||||
~CefURLLoaderThrottleProviderImpl() override;
|
||||
|
||||
// content::URLLoaderThrottleProvider implementation.
|
||||
std::unique_ptr<content::URLLoaderThrottleProvider> Clone() override;
|
||||
std::vector<std::unique_ptr<content::URLLoaderThrottle>> CreateThrottles(
|
||||
int render_frame_id,
|
||||
const blink::WebURLRequest& request,
|
||||
content::ResourceType resource_type) override;
|
||||
void SetOnline(bool is_online) override;
|
||||
|
||||
private:
|
||||
// This copy constructor works in conjunction with Clone(), not intended for
|
||||
// general use.
|
||||
CefURLLoaderThrottleProviderImpl(
|
||||
const CefURLLoaderThrottleProviderImpl& other);
|
||||
|
||||
content::URLLoaderThrottleProviderType type_;
|
||||
|
||||
THREAD_CHECKER(thread_checker_);
|
||||
|
||||
DISALLOW_ASSIGN(CefURLLoaderThrottleProviderImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_RENDERER_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=29ac900a92c4ec966cc115aae96c49b545bc9db9$
|
||||
// $hash=95cc8d1445764e1d1610b2047844b138e60542e6$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/request_context_cpptoc.h"
|
||||
@@ -373,6 +373,21 @@ void CEF_CALLBACK request_context_clear_certificate_exceptions(
|
||||
CefCompletionCallbackCToCpp::Wrap(callback));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK request_context_clear_http_auth_credentials(
|
||||
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)->ClearHttpAuthCredentials(
|
||||
CefCompletionCallbackCToCpp::Wrap(callback));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
request_context_close_all_connections(struct _cef_request_context_t* self,
|
||||
cef_completion_callback_t* callback) {
|
||||
@@ -549,6 +564,8 @@ CefRequestContextCppToC::CefRequestContextCppToC() {
|
||||
GetStruct()->set_preference = request_context_set_preference;
|
||||
GetStruct()->clear_certificate_exceptions =
|
||||
request_context_clear_certificate_exceptions;
|
||||
GetStruct()->clear_http_auth_credentials =
|
||||
request_context_clear_http_auth_credentials;
|
||||
GetStruct()->close_all_connections = request_context_close_all_connections;
|
||||
GetStruct()->resolve_host = request_context_resolve_host;
|
||||
GetStruct()->load_extension = request_context_load_extension;
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=370a54c21bec2aff5cf62b5897f5d43401e1ec31$
|
||||
// $hash=ab373b720fe3c700867f86ad29ffc8b3e518a92c$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/request_handler_cpptoc.h"
|
||||
@@ -159,7 +159,7 @@ request_handler_get_resource_request_handler(
|
||||
int CEF_CALLBACK
|
||||
request_handler_get_auth_credentials(struct _cef_request_handler_t* self,
|
||||
cef_browser_t* browser,
|
||||
cef_frame_t* frame,
|
||||
const cef_string_t* origin_url,
|
||||
int isProxy,
|
||||
const cef_string_t* host,
|
||||
int port,
|
||||
@@ -177,9 +177,9 @@ request_handler_get_auth_credentials(struct _cef_request_handler_t* self,
|
||||
DCHECK(browser);
|
||||
if (!browser)
|
||||
return 0;
|
||||
// Verify param: frame; type: refptr_diff
|
||||
DCHECK(frame);
|
||||
if (!frame)
|
||||
// Verify param: origin_url; type: string_byref_const
|
||||
DCHECK(origin_url);
|
||||
if (!origin_url)
|
||||
return 0;
|
||||
// Verify param: host; type: string_byref_const
|
||||
DCHECK(host);
|
||||
@@ -193,7 +193,7 @@ request_handler_get_auth_credentials(struct _cef_request_handler_t* self,
|
||||
|
||||
// Execute
|
||||
bool _retval = CefRequestHandlerCppToC::Get(self)->GetAuthCredentials(
|
||||
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
|
||||
CefBrowserCToCpp::Wrap(browser), CefString(origin_url),
|
||||
isProxy ? true : false, CefString(host), port, CefString(realm),
|
||||
CefString(scheme), CefAuthCallbackCToCpp::Wrap(callback));
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=8155639f093ff697fd30a9e330ae3470108251e5$
|
||||
// $hash=5036c24365fa0fdb3d7efc54670f3123a7104fa0$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/request_context_ctocpp.h"
|
||||
@@ -355,6 +355,22 @@ void CefRequestContextCToCpp::ClearCertificateExceptions(
|
||||
_struct, CefCompletionCallbackCppToC::Wrap(callback));
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefRequestContextCToCpp::ClearHttpAuthCredentials(
|
||||
CefRefPtr<CefCompletionCallback> callback) {
|
||||
cef_request_context_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, clear_http_auth_credentials))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Unverified params: callback
|
||||
|
||||
// Execute
|
||||
_struct->clear_http_auth_credentials(
|
||||
_struct, CefCompletionCallbackCppToC::Wrap(callback));
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefRequestContextCToCpp::CloseAllConnections(
|
||||
CefRefPtr<CefCompletionCallback> callback) {
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=00889895e17ac49f55668e395aa98a5f8312ee31$
|
||||
// $hash=dd07d0157b7e9128b240ed2b059f2358ebf9fc09$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_CONTEXT_CTOCPP_H_
|
||||
@@ -63,6 +63,8 @@ class CefRequestContextCToCpp
|
||||
CefString& error) OVERRIDE;
|
||||
void ClearCertificateExceptions(
|
||||
CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
|
||||
void ClearHttpAuthCredentials(
|
||||
CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
|
||||
void CloseAllConnections(CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
|
||||
void ResolveHost(const CefString& origin,
|
||||
CefRefPtr<CefResolveCallback> callback) OVERRIDE;
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=f286ec7520ee6b589b3ecafa409eb3f71c081e27$
|
||||
// $hash=ad2fb4fa8e7c8e265de6e03e2c8c8d3d28a7fd39$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/request_handler_ctocpp.h"
|
||||
@@ -151,7 +151,7 @@ CefRequestHandlerCToCpp::GetResourceRequestHandler(
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool CefRequestHandlerCToCpp::GetAuthCredentials(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
const CefString& origin_url,
|
||||
bool isProxy,
|
||||
const CefString& host,
|
||||
int port,
|
||||
@@ -170,9 +170,9 @@ bool CefRequestHandlerCToCpp::GetAuthCredentials(
|
||||
DCHECK(browser.get());
|
||||
if (!browser.get())
|
||||
return false;
|
||||
// Verify param: frame; type: refptr_diff
|
||||
DCHECK(frame.get());
|
||||
if (!frame.get())
|
||||
// Verify param: origin_url; type: string_byref_const
|
||||
DCHECK(!origin_url.empty());
|
||||
if (origin_url.empty())
|
||||
return false;
|
||||
// Verify param: host; type: string_byref_const
|
||||
DCHECK(!host.empty());
|
||||
@@ -186,8 +186,8 @@ bool CefRequestHandlerCToCpp::GetAuthCredentials(
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->get_auth_credentials(
|
||||
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
|
||||
isProxy, host.GetStruct(), port, realm.GetStruct(), scheme.GetStruct(),
|
||||
_struct, CefBrowserCppToC::Wrap(browser), origin_url.GetStruct(), isProxy,
|
||||
host.GetStruct(), port, realm.GetStruct(), scheme.GetStruct(),
|
||||
CefAuthCallbackCppToC::Wrap(callback));
|
||||
|
||||
// Return type: bool
|
||||
|
@@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=1e21398533e04c0dbd4143a3847b44fb43c64bc5$
|
||||
// $hash=dab1901a0bbeda97ef1efc8e5852964c318775f6$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_HANDLER_CTOCPP_H_
|
||||
@@ -54,7 +54,7 @@ class CefRequestHandlerCToCpp
|
||||
const CefString& request_initiator,
|
||||
bool& disable_default_handling) override;
|
||||
bool GetAuthCredentials(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
const CefString& origin_url,
|
||||
bool isProxy,
|
||||
const CefString& host,
|
||||
int port,
|
||||
|
@@ -368,9 +368,6 @@ patches = [
|
||||
{
|
||||
# macOS: Fix undesirable switch to discrete GPU during startup.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/2398
|
||||
#
|
||||
# macOS: Rely on symlinks to find the Libraries directory.
|
||||
# https://bugs.chromium.org/p/chromium/issues/detail?id=757974#c23
|
||||
'name': 'mac_gpu',
|
||||
},
|
||||
{
|
||||
@@ -423,6 +420,14 @@ patches = [
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/2622
|
||||
'name': 'services_network_2622',
|
||||
},
|
||||
{
|
||||
# Enhancements to NetworkService:
|
||||
# - Support customization of request_id via SimpleURLLoader.
|
||||
# - Remove the non-nullptr WebContents requirement from
|
||||
# NetworkServiceClient::OnAuthRequired.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/2718
|
||||
'name': 'services_network_request_id_2718',
|
||||
},
|
||||
{
|
||||
# Windows: Remove the base::Value is_standard_layout assert which will fail
|
||||
# for the cef_sandbox build, and which is no longer required.
|
||||
@@ -445,10 +450,5 @@ patches = [
|
||||
# unique_ptr types.
|
||||
# https://chromium-review.googlesource.com/c/chromium/src/+/1584292
|
||||
'name': 'compositor_frame_reporting_controller_1584292',
|
||||
},
|
||||
{
|
||||
# Fix AssertContextWasntDestroyed due to pointer reuse.
|
||||
# https://chromium-review.googlesource.com/c/chromium/src/+/1590418
|
||||
'name': 'simple_dependency_manager_1590418',
|
||||
}
|
||||
]
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git chrome/browser/BUILD.gn chrome/browser/BUILD.gn
|
||||
index 987b36217aad..832eab3ee56a 100644
|
||||
index 600fe26a3f35..1888bc494bcc 100644
|
||||
--- chrome/browser/BUILD.gn
|
||||
+++ chrome/browser/BUILD.gn
|
||||
@@ -8,6 +8,7 @@ import("//build/config/features.gni")
|
||||
@@ -29,7 +29,7 @@ index 987b36217aad..832eab3ee56a 100644
|
||||
if (is_android) {
|
||||
sources += [
|
||||
"after_startup_task_utils_android.cc",
|
||||
@@ -3916,7 +3922,7 @@ jumbo_split_static_library("browser") {
|
||||
@@ -3917,7 +3923,7 @@ jumbo_split_static_library("browser") {
|
||||
]
|
||||
}
|
||||
|
||||
|
@@ -51,7 +51,7 @@ index 6c8e21f6f5fe..4496c5579265 100644
|
||||
override;
|
||||
network::NetworkQualityTracker* network_quality_tracker() override;
|
||||
diff --git chrome/browser/ui/BUILD.gn chrome/browser/ui/BUILD.gn
|
||||
index 535c4f04c0f3..8cd8768022ae 100644
|
||||
index 7561cab16804..407f7a6008a3 100644
|
||||
--- chrome/browser/ui/BUILD.gn
|
||||
+++ chrome/browser/ui/BUILD.gn
|
||||
@@ -9,6 +9,7 @@ import("//build/config/features.gni")
|
||||
|
@@ -1,8 +1,8 @@
|
||||
diff --git chrome/browser/chrome_content_browser_client.cc chrome/browser/chrome_content_browser_client.cc
|
||||
index cf4250c7ba26..b8a05db7cced 100644
|
||||
index 26c3593d94d0..1ca67c62e464 100644
|
||||
--- chrome/browser/chrome_content_browser_client.cc
|
||||
+++ chrome/browser/chrome_content_browser_client.cc
|
||||
@@ -1049,12 +1049,16 @@ void LaunchURL(
|
||||
@@ -1063,12 +1063,16 @@ void LaunchURL(
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ index cf4250c7ba26..b8a05db7cced 100644
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch(switches::kUserAgent)) {
|
||||
diff --git chrome/browser/chrome_content_browser_client.h chrome/browser/chrome_content_browser_client.h
|
||||
index 07e0e051ff1d..41337a1719a1 100644
|
||||
index 6bbed7653db9..f663648004ee 100644
|
||||
--- chrome/browser/chrome_content_browser_client.h
|
||||
+++ chrome/browser/chrome_content_browser_client.h
|
||||
@@ -77,7 +77,8 @@ class Origin;
|
||||
|
@@ -125,7 +125,7 @@ index daf826ece047..615200c4b41c 100644
|
||||
// If we broke out of the loop, we have found an enabled plugin.
|
||||
bool enabled = i < matching_plugins.size();
|
||||
diff --git chrome/browser/plugins/plugin_utils.cc chrome/browser/plugins/plugin_utils.cc
|
||||
index 01ea0ba7f0cb..2828896bbcad 100644
|
||||
index 01ea0ba7f0cb..f573503df5c4 100644
|
||||
--- chrome/browser/plugins/plugin_utils.cc
|
||||
+++ chrome/browser/plugins/plugin_utils.cc
|
||||
@@ -5,6 +5,7 @@
|
||||
@@ -148,12 +148,15 @@ index 01ea0ba7f0cb..2828896bbcad 100644
|
||||
#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||
#include "extensions/browser/info_map.h"
|
||||
#include "extensions/common/constants.h"
|
||||
@@ -180,10 +186,23 @@ PluginUtils::GetMimeTypeToExtensionIdMap(
|
||||
@@ -180,10 +186,26 @@ PluginUtils::GetMimeTypeToExtensionIdMap(
|
||||
content::ResourceContext* resource_context) {
|
||||
base::flat_map<std::string, std::string> mime_type_to_extension_id_map;
|
||||
#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||
+
|
||||
+#if BUILDFLAG(ENABLE_CEF)
|
||||
+ if (!extensions::ExtensionsEnabled())
|
||||
+ return mime_type_to_extension_id_map;
|
||||
+
|
||||
+ CefResourceContext* context =
|
||||
+ static_cast<CefResourceContext*>(resource_context);
|
||||
+ bool profile_is_off_the_record = context->IsOffTheRecord();
|
||||
@@ -172,7 +175,7 @@ index 01ea0ba7f0cb..2828896bbcad 100644
|
||||
std::vector<std::string> whitelist = MimeTypesHandler::GetMIMETypeWhitelist();
|
||||
// Go through the white-listed extensions and try to use them to intercept
|
||||
// the URL request.
|
||||
@@ -198,7 +217,7 @@ PluginUtils::GetMimeTypeToExtensionIdMap(
|
||||
@@ -198,7 +220,7 @@ PluginUtils::GetMimeTypeToExtensionIdMap(
|
||||
}
|
||||
|
||||
if (extension_id == extension_misc::kPdfExtensionId &&
|
||||
|
@@ -262,10 +262,10 @@ index 3009401dac6b..b4c5a9e2db50 100644
|
||||
};
|
||||
|
||||
diff --git content/common/frame_messages.h content/common/frame_messages.h
|
||||
index 8673d65844ea..7d13c72dca9b 100644
|
||||
index 91e10a619343..9eeb813ea6d7 100644
|
||||
--- content/common/frame_messages.h
|
||||
+++ content/common/frame_messages.h
|
||||
@@ -1286,9 +1286,10 @@ IPC_MESSAGE_ROUTED1(FrameHostMsg_PepperStopsPlayback,
|
||||
@@ -1289,9 +1289,10 @@ IPC_MESSAGE_ROUTED1(FrameHostMsg_PepperStopsPlayback,
|
||||
// type. If there is no matching plugin, |found| is false.
|
||||
// |actual_mime_type| is the actual mime type supported by the
|
||||
// found plugin.
|
||||
@@ -278,10 +278,10 @@ index 8673d65844ea..7d13c72dca9b 100644
|
||||
std::string /* mime_type */,
|
||||
bool /* found */,
|
||||
diff --git content/public/browser/content_browser_client.h content/public/browser/content_browser_client.h
|
||||
index 0a1bf5d0b4d1..6dea4f0f4a44 100644
|
||||
index 39174b67d1d3..f5a825c113cf 100644
|
||||
--- content/public/browser/content_browser_client.h
|
||||
+++ content/public/browser/content_browser_client.h
|
||||
@@ -1460,6 +1460,15 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -1466,6 +1466,15 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
network::mojom::URLLoaderFactoryRequest* factory_request,
|
||||
network::mojom::URLLoaderFactory*& out_factory);
|
||||
|
||||
@@ -297,7 +297,7 @@ index 0a1bf5d0b4d1..6dea4f0f4a44 100644
|
||||
// Creates an OverlayWindow to be used for Picture-in-Picture. This window
|
||||
// will house the content shown when in Picture-in-Picture mode. This will
|
||||
// return a new OverlayWindow.
|
||||
@@ -1527,6 +1536,10 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -1533,6 +1542,10 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
// Used as part of the user agent string.
|
||||
virtual std::string GetProduct() const;
|
||||
|
||||
@@ -372,10 +372,10 @@ index 8935697155f5..179b6ebf1360 100644
|
||||
virtual void FocusedNodeChanged(const blink::WebNode& node) {}
|
||||
|
||||
diff --git content/renderer/render_frame_impl.cc content/renderer/render_frame_impl.cc
|
||||
index c75b6177f066..860bbe9e1c14 100644
|
||||
index dc3c7420d89d..7cf57b285d24 100644
|
||||
--- content/renderer/render_frame_impl.cc
|
||||
+++ content/renderer/render_frame_impl.cc
|
||||
@@ -3996,7 +3996,8 @@ blink::WebPlugin* RenderFrameImpl::CreatePlugin(
|
||||
@@ -4047,7 +4047,8 @@ blink::WebPlugin* RenderFrameImpl::CreatePlugin(
|
||||
std::string mime_type;
|
||||
bool found = false;
|
||||
Send(new FrameHostMsg_GetPluginInfo(
|
||||
@@ -385,7 +385,7 @@ index c75b6177f066..860bbe9e1c14 100644
|
||||
params.mime_type.Utf8(), &found, &info, &mime_type));
|
||||
if (!found)
|
||||
return nullptr;
|
||||
@@ -4422,6 +4423,8 @@ void RenderFrameImpl::FrameDetached(DetachType type) {
|
||||
@@ -4473,6 +4474,8 @@ void RenderFrameImpl::FrameDetached(DetachType type) {
|
||||
|
||||
void RenderFrameImpl::FrameFocused() {
|
||||
Send(new FrameHostMsg_FrameFocused(routing_id_));
|
||||
|
@@ -68,10 +68,10 @@ index c3511e3e6a66..3500f4a2b005 100644
|
||||
|
||||
void ChromeBrowserMainExtraPartsViewsLinux::ToolkitInitialized() {
|
||||
diff --git chrome/test/BUILD.gn chrome/test/BUILD.gn
|
||||
index 5406779a17c2..b1ed0f2c970b 100644
|
||||
index 63be9ca9369f..9f73a3c841f3 100644
|
||||
--- chrome/test/BUILD.gn
|
||||
+++ chrome/test/BUILD.gn
|
||||
@@ -4159,7 +4159,7 @@ test("unit_tests") {
|
||||
@@ -4170,7 +4170,7 @@ test("unit_tests") {
|
||||
"../browser/ui/input_method/input_method_engine_unittest.cc",
|
||||
]
|
||||
}
|
||||
@@ -80,7 +80,7 @@ index 5406779a17c2..b1ed0f2c970b 100644
|
||||
sources +=
|
||||
[ "../browser/ui/libgtkui/select_file_dialog_impl_gtk_unittest.cc" ]
|
||||
deps += [ "//build/config/linux/gtk" ]
|
||||
@@ -4180,7 +4180,7 @@ test("unit_tests") {
|
||||
@@ -4191,7 +4191,7 @@ test("unit_tests") {
|
||||
if (use_gio) {
|
||||
configs += [ "//build/linux:gio_config" ]
|
||||
}
|
||||
@@ -89,7 +89,7 @@ index 5406779a17c2..b1ed0f2c970b 100644
|
||||
deps += [ "//chrome/browser/ui/libgtkui" ]
|
||||
}
|
||||
|
||||
@@ -5206,7 +5206,7 @@ if (!is_android) {
|
||||
@@ -5217,7 +5217,7 @@ if (!is_android) {
|
||||
# suites, it seems like one or another starts timing out too.
|
||||
"../browser/ui/views/keyboard_access_browsertest.cc",
|
||||
]
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git base/files/file_path_watcher_linux.cc base/files/file_path_watcher_linux.cc
|
||||
index 22732f2864ef..7d5caef5c3b0 100644
|
||||
index 3f5eb8e2e002..245a0ca9055f 100644
|
||||
--- base/files/file_path_watcher_linux.cc
|
||||
+++ base/files/file_path_watcher_linux.cc
|
||||
@@ -5,6 +5,7 @@
|
||||
@@ -15,10 +15,10 @@ index 22732f2864ef..7d5caef5c3b0 100644
|
||||
|
||||
#include <algorithm>
|
||||
+#include <array>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
@@ -220,22 +222,15 @@ void InotifyReaderThreadDelegate::ThreadMain() {
|
||||
@@ -263,22 +265,15 @@ void InotifyReaderThreadDelegate::ThreadMain() {
|
||||
PlatformThread::SetName("inotify_reader");
|
||||
|
||||
// Make sure the file descriptors are good for use with select().
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git ui/gl/init/gl_initializer_mac.cc ui/gl/init/gl_initializer_mac.cc
|
||||
index 85cab0eaef3e..37b2d42a34f5 100644
|
||||
index 8d690474060f..03059842b1a4 100644
|
||||
--- ui/gl/init/gl_initializer_mac.cc
|
||||
+++ ui/gl/init/gl_initializer_mac.cc
|
||||
@@ -46,11 +46,8 @@ bool InitializeOneOffForSandbox() {
|
||||
@@ -16,14 +16,3 @@ index 85cab0eaef3e..37b2d42a34f5 100644
|
||||
if (GetGLImplementation() == kGLImplementationAppleGL) {
|
||||
attribs.push_back(kCGLPFARendererID);
|
||||
attribs.push_back(
|
||||
@@ -102,8 +99,8 @@ bool InitializeStaticEGLInternal(GLImplementation implementation) {
|
||||
// as app bundles. In that case, the .dylib is next to the executable.
|
||||
base::FilePath base_dir;
|
||||
if (base::mac::AmIBundled()) {
|
||||
- base_dir =
|
||||
- base::mac::FrameworkBundlePath().Append("Versions/Current/Libraries/");
|
||||
+ // Rely on symlinks to find the correct version.
|
||||
+ base_dir = base::mac::FrameworkBundlePath().Append("Libraries/");
|
||||
} else {
|
||||
if (!base::PathService::Get(base::FILE_EXE, &base_dir)) {
|
||||
LOG(ERROR) << "PathService::Get failed.";
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git content/public/common/common_param_traits_macros.h content/public/common/common_param_traits_macros.h
|
||||
index 24bded9417c5..cb5d04ab32ab 100644
|
||||
index c97b4e009baa..04dee2983825 100644
|
||||
--- content/public/common/common_param_traits_macros.h
|
||||
+++ content/public/common/common_param_traits_macros.h
|
||||
@@ -189,6 +189,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences)
|
||||
@@ -35,7 +35,7 @@ index a83015f3629a..fe79480e9af7 100644
|
||||
bool record_whole_document;
|
||||
|
||||
diff --git content/renderer/render_view_impl.cc content/renderer/render_view_impl.cc
|
||||
index 3e328daa5827..7d0869aa29fd 100644
|
||||
index 83e40b6568da..b47165e7ac74 100644
|
||||
--- content/renderer/render_view_impl.cc
|
||||
+++ content/renderer/render_view_impl.cc
|
||||
@@ -1026,6 +1026,8 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git chrome/browser/renderer_preferences_util.cc chrome/browser/renderer_preferences_util.cc
|
||||
index f5ed7f0683c5..5b31fb309985 100644
|
||||
index 77a1a97f5e8e..c4f1c94db8b3 100644
|
||||
--- chrome/browser/renderer_preferences_util.cc
|
||||
+++ chrome/browser/renderer_preferences_util.cc
|
||||
@@ -29,7 +29,8 @@
|
||||
|
@@ -35,7 +35,7 @@ index 2b24d1ac1b5b..6577495d87a9 100644
|
||||
base_cache_path.Append(chrome::kCacheDirname);
|
||||
network_context_params->http_cache_max_size =
|
||||
diff --git chrome/browser/profiles/profile.h chrome/browser/profiles/profile.h
|
||||
index e77d8abd6601..88331e9af5e0 100644
|
||||
index 737f5f8b8193..241edaa39671 100644
|
||||
--- chrome/browser/profiles/profile.h
|
||||
+++ chrome/browser/profiles/profile.h
|
||||
@@ -321,6 +321,11 @@ class Profile : public content::BrowserContext {
|
||||
@@ -132,10 +132,10 @@ index 8be1b9dea5f7..30f23449ac51 100644
|
||||
|
||||
void CookieManager::SetForceKeepSessionState() {
|
||||
diff --git services/network/network_context.cc services/network/network_context.cc
|
||||
index 9d6f7b930e11..c16e5ca90c14 100644
|
||||
index 9349b0bea419..167b6df982d0 100644
|
||||
--- services/network/network_context.cc
|
||||
+++ services/network/network_context.cc
|
||||
@@ -1742,6 +1742,7 @@ URLRequestContextOwner NetworkContext::ApplyContextParamsToBuilder(
|
||||
@@ -1753,6 +1753,7 @@ URLRequestContextOwner NetworkContext::ApplyContextParamsToBuilder(
|
||||
}
|
||||
|
||||
scoped_refptr<SessionCleanupCookieStore> session_cleanup_cookie_store;
|
||||
@@ -143,7 +143,7 @@ index 9d6f7b930e11..c16e5ca90c14 100644
|
||||
if (params_->cookie_path) {
|
||||
scoped_refptr<base::SequencedTaskRunner> client_task_runner =
|
||||
base::MessageLoopCurrent::Get()->task_runner();
|
||||
@@ -1769,18 +1770,27 @@ URLRequestContextOwner NetworkContext::ApplyContextParamsToBuilder(
|
||||
@@ -1780,18 +1781,27 @@ URLRequestContextOwner NetworkContext::ApplyContextParamsToBuilder(
|
||||
session_cleanup_cookie_store =
|
||||
base::MakeRefCounted<SessionCleanupCookieStore>(sqlite_store);
|
||||
|
||||
|
84
patch/patches/services_network_request_id_2718.patch
Normal file
84
patch/patches/services_network_request_id_2718.patch
Normal file
@@ -0,0 +1,84 @@
|
||||
diff --git content/browser/network_service_client.cc content/browser/network_service_client.cc
|
||||
index 8978b4628ffe..f4f554c940b5 100644
|
||||
--- content/browser/network_service_client.cc
|
||||
+++ content/browser/network_service_client.cc
|
||||
@@ -239,10 +239,6 @@ class LoginHandlerDelegate {
|
||||
}
|
||||
|
||||
WebContents* web_contents = web_contents_getter_.Run();
|
||||
- if (!web_contents) {
|
||||
- OnAuthCredentials(base::nullopt);
|
||||
- return;
|
||||
- }
|
||||
|
||||
// WeakPtr is not strictly necessary here due to OnRequestCancelled.
|
||||
creating_login_delegate_ = true;
|
||||
@@ -439,11 +435,6 @@ void NetworkServiceClient::OnAuthRequired(
|
||||
base::Callback<WebContents*(void)> web_contents_getter =
|
||||
base::BindRepeating(GetWebContents, process_id, routing_id);
|
||||
|
||||
- if (!web_contents_getter.Run()) {
|
||||
- std::move(auth_challenge_responder)->OnAuthCredentials(base::nullopt);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
if (ResourceDispatcherHostImpl::Get()->DoNotPromptForLogin(
|
||||
static_cast<ResourceType>(resource_type), url, site_for_cookies)) {
|
||||
std::move(auth_challenge_responder)->OnAuthCredentials(base::nullopt);
|
||||
diff --git services/network/public/cpp/simple_url_loader.cc services/network/public/cpp/simple_url_loader.cc
|
||||
index 0c4101672018..75c051f2bc44 100644
|
||||
--- services/network/public/cpp/simple_url_loader.cc
|
||||
+++ services/network/public/cpp/simple_url_loader.cc
|
||||
@@ -227,6 +227,7 @@ class SimpleURLLoaderImpl : public SimpleURLLoader,
|
||||
uint64_t length = std::numeric_limits<uint64_t>::max()) override;
|
||||
void SetRetryOptions(int max_retries, int retry_mode) override;
|
||||
void SetTimeoutDuration(base::TimeDelta timeout_duration) override;
|
||||
+ void SetRequestId(int32_t request_id) override;
|
||||
|
||||
int NetError() const override;
|
||||
const ResourceResponseHead* ResponseInfo() const override;
|
||||
@@ -344,6 +345,8 @@ class SimpleURLLoaderImpl : public SimpleURLLoader,
|
||||
// The next values contain all the information required to restart the
|
||||
// request.
|
||||
|
||||
+ int32_t request_id_ = 0;
|
||||
+
|
||||
// Populated in the constructor, and cleared once no longer needed, when no
|
||||
// more retries are possible.
|
||||
std::unique_ptr<ResourceRequest> resource_request_;
|
||||
@@ -1368,6 +1371,12 @@ void SimpleURLLoaderImpl::SetTimeoutDuration(base::TimeDelta timeout_duration) {
|
||||
timeout_duration_ = timeout_duration;
|
||||
}
|
||||
|
||||
+void SimpleURLLoaderImpl::SetRequestId(int32_t request_id) {
|
||||
+ // Check if a request has not yet been started.
|
||||
+ DCHECK(!body_handler_);
|
||||
+ request_id_ = request_id;
|
||||
+}
|
||||
+
|
||||
int SimpleURLLoaderImpl::NetError() const {
|
||||
// Should only be called once the request is compelete.
|
||||
DCHECK(request_state_->finished);
|
||||
@@ -1516,7 +1525,7 @@ void SimpleURLLoaderImpl::StartRequest(
|
||||
string_upload_data_pipe_getter_->GetPtrForNewUpload());
|
||||
}
|
||||
url_loader_factory->CreateLoaderAndStart(
|
||||
- mojo::MakeRequest(&url_loader_), 0 /* routing_id */, 0 /* request_id */,
|
||||
+ mojo::MakeRequest(&url_loader_), 0 /* routing_id */, request_id_,
|
||||
0 /* options */, *resource_request_, std::move(client_ptr),
|
||||
net::MutableNetworkTrafficAnnotationTag(annotation_tag_));
|
||||
|
||||
diff --git services/network/public/cpp/simple_url_loader.h services/network/public/cpp/simple_url_loader.h
|
||||
index f81788d25fda..ba8948be5ebf 100644
|
||||
--- services/network/public/cpp/simple_url_loader.h
|
||||
+++ services/network/public/cpp/simple_url_loader.h
|
||||
@@ -324,6 +324,9 @@ class COMPONENT_EXPORT(NETWORK_CPP) SimpleURLLoader {
|
||||
// as much time as it wants.
|
||||
virtual void SetTimeoutDuration(base::TimeDelta timeout_duration) = 0;
|
||||
|
||||
+ // Set the ID that will be associated with the request.
|
||||
+ virtual void SetRequestId(int32_t request_id) = 0;
|
||||
+
|
||||
// Returns the net::Error representing the final status of the request. May
|
||||
// only be called once the loader has informed the caller of completion.
|
||||
virtual int NetError() const = 0;
|
@@ -1,49 +0,0 @@
|
||||
diff --git chrome/browser/profiles/profile_key.cc chrome/browser/profiles/profile_key.cc
|
||||
index b225f2b..946403e 100644
|
||||
--- chrome/browser/profiles/profile_key.cc
|
||||
+++ chrome/browser/profiles/profile_key.cc
|
||||
@@ -5,9 +5,12 @@
|
||||
#include "chrome/browser/profiles/profile_key.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
+#include "components/keyed_service/core/simple_dependency_manager.h"
|
||||
|
||||
ProfileKey::ProfileKey(const base::FilePath& path, ProfileKey* original_key)
|
||||
- : SimpleFactoryKey(path), prefs_(nullptr), original_key_(original_key) {}
|
||||
+ : SimpleFactoryKey(path), prefs_(nullptr), original_key_(original_key) {
|
||||
+ SimpleDependencyManager::GetInstance()->MarkContextLive(this);
|
||||
+}
|
||||
|
||||
ProfileKey::~ProfileKey() = default;
|
||||
|
||||
diff --git components/keyed_service/core/simple_dependency_manager.cc components/keyed_service/core/simple_dependency_manager.cc
|
||||
index 254c6ef..57d20b9 100644
|
||||
--- components/keyed_service/core/simple_dependency_manager.cc
|
||||
+++ components/keyed_service/core/simple_dependency_manager.cc
|
||||
@@ -43,6 +43,10 @@
|
||||
DependencyManager::CreateContextServices(key, true);
|
||||
}
|
||||
|
||||
+void SimpleDependencyManager::MarkContextLive(SimpleFactoryKey* key) {
|
||||
+ DependencyManager::MarkContextLive(key);
|
||||
+}
|
||||
+
|
||||
SimpleDependencyManager::SimpleDependencyManager() = default;
|
||||
|
||||
SimpleDependencyManager::~SimpleDependencyManager() = default;
|
||||
diff --git components/keyed_service/core/simple_dependency_manager.h components/keyed_service/core/simple_dependency_manager.h
|
||||
index 72fa74c..480f971 100644
|
||||
--- components/keyed_service/core/simple_dependency_manager.h
|
||||
+++ components/keyed_service/core/simple_dependency_manager.h
|
||||
@@ -35,6 +35,11 @@
|
||||
// ServiceIsNULLWhileTesting().
|
||||
void CreateServicesForTest(SimpleFactoryKey* key);
|
||||
|
||||
+ // Marks |context| as live (i.e., not stale). This method can be called as a
|
||||
+ // safeguard against |AssertContextWasntDestroyed()| checks going off due to
|
||||
+ // |context| aliasing an instance from a prior construction.
|
||||
+ void MarkContextLive(SimpleFactoryKey* key);
|
||||
+
|
||||
private:
|
||||
~SimpleDependencyManager() override;
|
||||
|
@@ -52,7 +52,7 @@ index b2b3920da3b0..686afc464b42 100644
|
||||
std::move(stats_db), BrowserFeatureProvider::GetFactoryCB());
|
||||
decode_history = new_decode_history.get();
|
||||
diff --git content/browser/renderer_host/render_process_host_impl.cc content/browser/renderer_host/render_process_host_impl.cc
|
||||
index f3a90e61f2b4..a9d322d66d86 100644
|
||||
index 0866af8555cd..cc5750725c30 100644
|
||||
--- content/browser/renderer_host/render_process_host_impl.cc
|
||||
+++ content/browser/renderer_host/render_process_host_impl.cc
|
||||
@@ -2203,6 +2203,9 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
|
||||
|
@@ -39,7 +39,7 @@ index cce16a111356..9f0a8b73adb5 100644
|
||||
virtual void MenuWillShow() {}
|
||||
|
||||
diff --git ui/gfx/render_text.cc ui/gfx/render_text.cc
|
||||
index 9c38cd6d4fdb..dcd34308a8bc 100644
|
||||
index 9d665b99613c..543f79f3beb7 100644
|
||||
--- ui/gfx/render_text.cc
|
||||
+++ ui/gfx/render_text.cc
|
||||
@@ -514,6 +514,14 @@ void RenderText::SetElideBehavior(ElideBehavior elide_behavior) {
|
||||
@@ -240,7 +240,7 @@ index 9df5c850d12d..e7007ffbb762 100644
|
||||
std::unique_ptr<SelectionController> selection_controller_;
|
||||
|
||||
diff --git ui/views/controls/menu/menu_controller.cc ui/views/controls/menu/menu_controller.cc
|
||||
index 5e630a1a5f47..a3725641c2db 100644
|
||||
index eb93ba807319..b558892cc737 100644
|
||||
--- ui/views/controls/menu/menu_controller.cc
|
||||
+++ ui/views/controls/menu/menu_controller.cc
|
||||
@@ -2570,8 +2570,13 @@ MenuItemView* MenuController::FindNextSelectableMenuItem(
|
||||
|
@@ -411,7 +411,7 @@ index 5bcb8d8b9bae..020fa85573aa 100644
|
||||
if (native_widget_delegate->IsDialogBox()) {
|
||||
*style |= DS_MODALFRAME;
|
||||
diff --git ui/views/win/hwnd_message_handler.cc ui/views/win/hwnd_message_handler.cc
|
||||
index fb8e820175ac..66c5cb91f7e8 100644
|
||||
index 443003518ef8..c43981fbda23 100644
|
||||
--- ui/views/win/hwnd_message_handler.cc
|
||||
+++ ui/views/win/hwnd_message_handler.cc
|
||||
@@ -2918,10 +2918,13 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,
|
||||
|
@@ -1,8 +1,8 @@
|
||||
diff --git content/browser/web_contents/web_contents_impl.cc content/browser/web_contents/web_contents_impl.cc
|
||||
index 1491bf580c59..ab2c83357303 100644
|
||||
index 466510566050..edb615bb11b4 100644
|
||||
--- content/browser/web_contents/web_contents_impl.cc
|
||||
+++ content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -2068,21 +2068,30 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
|
||||
@@ -2070,21 +2070,30 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
|
||||
std::string unique_name;
|
||||
frame_tree_.root()->SetFrameName(params.main_frame_name, unique_name);
|
||||
|
||||
@@ -45,7 +45,7 @@ index 1491bf580c59..ab2c83357303 100644
|
||||
CHECK(render_view_host_delegate_view_);
|
||||
CHECK(view_.get());
|
||||
|
||||
@@ -2781,6 +2790,15 @@ void WebContentsImpl::CreateNewWindow(
|
||||
@@ -2783,6 +2792,15 @@ void WebContentsImpl::CreateNewWindow(
|
||||
create_params.renderer_initiated_creation =
|
||||
main_frame_route_id != MSG_ROUTING_NONE;
|
||||
|
||||
@@ -61,7 +61,7 @@ index 1491bf580c59..ab2c83357303 100644
|
||||
std::unique_ptr<WebContents> new_contents;
|
||||
if (!is_guest) {
|
||||
create_params.context = view_->GetNativeView();
|
||||
@@ -2813,7 +2831,7 @@ void WebContentsImpl::CreateNewWindow(
|
||||
@@ -2815,7 +2833,7 @@ void WebContentsImpl::CreateNewWindow(
|
||||
// TODO(brettw): It seems bogus that we have to call this function on the
|
||||
// newly created object and give it one of its own member variables.
|
||||
new_view->CreateViewForWidget(
|
||||
@@ -70,7 +70,7 @@ index 1491bf580c59..ab2c83357303 100644
|
||||
}
|
||||
// Save the created window associated with the route so we can show it
|
||||
// later.
|
||||
@@ -6372,7 +6390,7 @@ InterstitialPageImpl* WebContentsImpl::GetInterstitialForRenderManager() {
|
||||
@@ -6382,7 +6400,7 @@ InterstitialPageImpl* WebContentsImpl::GetInterstitialForRenderManager() {
|
||||
void WebContentsImpl::CreateRenderWidgetHostViewForRenderManager(
|
||||
RenderViewHost* render_view_host) {
|
||||
RenderWidgetHostViewBase* rwh_view =
|
||||
|
@@ -44,7 +44,7 @@ index a616fafed51f..dae131dad5de 100644
|
||||
.Top()
|
||||
.GetSecurityContext()
|
||||
diff --git third_party/blink/renderer/core/frame/local_frame.cc third_party/blink/renderer/core/frame/local_frame.cc
|
||||
index dd0e2f0df7b5..3c3ff59f72a9 100644
|
||||
index c1f7d53655bd..728fec52942f 100644
|
||||
--- third_party/blink/renderer/core/frame/local_frame.cc
|
||||
+++ third_party/blink/renderer/core/frame/local_frame.cc
|
||||
@@ -1257,7 +1257,7 @@ FrameResourceCoordinator* LocalFrame::GetFrameResourceCoordinator() {
|
||||
@@ -85,10 +85,10 @@ index 6435384652b7..79bd103df30d 100644
|
||||
|
||||
void DevToolsSession::FlushProtocolNotifications() {
|
||||
diff --git third_party/blink/renderer/core/page/page.cc third_party/blink/renderer/core/page/page.cc
|
||||
index 5480f0e29789..3bf2f35c9741 100644
|
||||
index 6cc6c5a6f38c..314334cde0d8 100644
|
||||
--- third_party/blink/renderer/core/page/page.cc
|
||||
+++ third_party/blink/renderer/core/page/page.cc
|
||||
@@ -180,7 +180,8 @@ Page::Page(PageClients& page_clients)
|
||||
@@ -185,7 +185,8 @@ Page::Page(PageClients& page_clients)
|
||||
MakeGarbageCollected<OverscrollController>(GetVisualViewport(),
|
||||
GetChromeClient())),
|
||||
link_highlights_(MakeGarbageCollected<LinkHighlights>(*this)),
|
||||
@@ -98,7 +98,7 @@ index 5480f0e29789..3bf2f35c9741 100644
|
||||
// TODO(pdr): Initialize |validation_message_client_| lazily.
|
||||
validation_message_client_(
|
||||
MakeGarbageCollected<ValidationMessageClientImpl>(*this)),
|
||||
@@ -337,21 +338,40 @@ void Page::InitialStyleChanged() {
|
||||
@@ -344,21 +345,40 @@ void Page::InitialStyleChanged() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ index 5480f0e29789..3bf2f35c9741 100644
|
||||
page->NotifyPluginsChanged();
|
||||
}
|
||||
}
|
||||
@@ -786,7 +806,8 @@ void Page::Trace(blink::Visitor* visitor) {
|
||||
@@ -801,7 +821,8 @@ void Page::Trace(blink::Visitor* visitor) {
|
||||
visitor->Trace(link_highlights_);
|
||||
visitor->Trace(spatial_navigation_controller_);
|
||||
visitor->Trace(main_frame_);
|
||||
@@ -159,7 +159,7 @@ index 5480f0e29789..3bf2f35c9741 100644
|
||||
visitor->Trace(plugins_changed_observers_);
|
||||
visitor->Trace(next_related_page_);
|
||||
diff --git third_party/blink/renderer/core/page/page.h third_party/blink/renderer/core/page/page.h
|
||||
index f3d748e4a3e7..3750ba015d76 100644
|
||||
index eb5e930c4653..3a12676266d3 100644
|
||||
--- third_party/blink/renderer/core/page/page.h
|
||||
+++ third_party/blink/renderer/core/page/page.h
|
||||
@@ -140,7 +140,8 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>,
|
||||
@@ -172,7 +172,7 @@ index f3d748e4a3e7..3750ba015d76 100644
|
||||
|
||||
// Resets the plugin data for all pages in the renderer process and notifies
|
||||
// PluginsChangedObservers.
|
||||
@@ -364,7 +365,8 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>,
|
||||
@@ -366,7 +367,8 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>,
|
||||
const Member<LinkHighlights> link_highlights_;
|
||||
Member<SpatialNavigationController> spatial_navigation_controller_;
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
diff --git third_party/blink/renderer/core/input/pointer_event_manager.cc third_party/blink/renderer/core/input/pointer_event_manager.cc
|
||||
index b84e3bdd6679..a0d65d9a65a1 100644
|
||||
index 6a7744b5f75f..1368809f0740 100644
|
||||
--- third_party/blink/renderer/core/input/pointer_event_manager.cc
|
||||
+++ third_party/blink/renderer/core/input/pointer_event_manager.cc
|
||||
@@ -285,7 +285,7 @@ void PointerEventManager::HandlePointerInterruption(
|
||||
@@ -311,7 +311,7 @@ void PointerEventManager::HandlePointerInterruption(
|
||||
for (auto pointer_event : canceled_pointer_events) {
|
||||
// If we are sending a pointercancel we have sent the pointerevent to some
|
||||
// target before.
|
||||
|
@@ -11,7 +11,7 @@ index f831c084e1d3..80dd4ea3a154 100644
|
||||
// Cancels and hides the current popup (datetime, select...) if any.
|
||||
virtual void CancelPagePopup() = 0;
|
||||
diff --git third_party/blink/renderer/core/exported/web_view_impl.cc third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
index fa2150289b4f..611dffb1ef7d 100644
|
||||
index 41e11e56e95b..e854d0326c2c 100644
|
||||
--- third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
+++ third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
@@ -238,8 +238,13 @@ void WebView::SetUseExternalPopupMenus(bool use_external_popup_menus) {
|
||||
@@ -39,7 +39,7 @@ index fa2150289b4f..611dffb1ef7d 100644
|
||||
fullscreen_controller_(std::make_unique<FullscreenController>(this)) {
|
||||
if (!AsView().client) {
|
||||
diff --git third_party/blink/renderer/core/exported/web_view_impl.h third_party/blink/renderer/core/exported/web_view_impl.h
|
||||
index aaa17462ee65..647b51d8fddc 100644
|
||||
index 64a22db62dba..09713163f4a0 100644
|
||||
--- third_party/blink/renderer/core/exported/web_view_impl.h
|
||||
+++ third_party/blink/renderer/core/exported/web_view_impl.h
|
||||
@@ -105,7 +105,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
|
||||
|
@@ -1,8 +1,8 @@
|
||||
diff --git chrome/app/generated_resources.grd chrome/app/generated_resources.grd
|
||||
index 4989fa559ee6..c6859944e8b4 100644
|
||||
index 27c735629140..929ddbca4a6c 100644
|
||||
--- chrome/app/generated_resources.grd
|
||||
+++ chrome/app/generated_resources.grd
|
||||
@@ -4644,7 +4644,7 @@ Keep your key file in a safe place. You will need it to create new versions of y
|
||||
@@ -4645,7 +4645,7 @@ Keep your key file in a safe place. You will need it to create new versions of y
|
||||
</message>
|
||||
</if>
|
||||
<message name="IDS_PLUGIN_BLOCKED_BY_POLICY" desc="The placeholder text for a plugin blocked by enterprise policy.">
|
||||
|
@@ -702,6 +702,32 @@ CefRefPtr<CefResourceRequestHandler> ClientHandler::GetResourceRequestHandler(
|
||||
return this;
|
||||
}
|
||||
|
||||
bool ClientHandler::GetAuthCredentials(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& origin_url,
|
||||
bool isProxy,
|
||||
const CefString& host,
|
||||
int port,
|
||||
const CefString& realm,
|
||||
const CefString& scheme,
|
||||
CefRefPtr<CefAuthCallback> callback) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
// Used for testing authentication with a proxy server.
|
||||
// For example, CCProxy on Windows.
|
||||
if (isProxy) {
|
||||
callback->Continue("guest", "guest");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Used for testing authentication with https://jigsaw.w3.org/HTTP/.
|
||||
if (host == "jigsaw.w3.org") {
|
||||
callback->Continue("guest", "guest");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClientHandler::OnQuotaRequest(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& origin_url,
|
||||
int64 new_size,
|
||||
|
@@ -229,6 +229,14 @@ class ClientHandler : public CefClient,
|
||||
bool is_download,
|
||||
const CefString& request_initiator,
|
||||
bool& disable_default_handling) OVERRIDE;
|
||||
bool GetAuthCredentials(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& origin_url,
|
||||
bool isProxy,
|
||||
const CefString& host,
|
||||
int port,
|
||||
const CefString& realm,
|
||||
const CefString& scheme,
|
||||
CefRefPtr<CefAuthCallback> callback) OVERRIDE;
|
||||
bool OnQuotaRequest(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& origin_url,
|
||||
int64 new_size,
|
||||
|
@@ -126,9 +126,10 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
const RequestClient::Callback& request_callback =
|
||||
base::Bind(&Handler::OnRequestComplete, base::Unretained(this));
|
||||
|
||||
// Create and start the new CefURLRequest.
|
||||
urlrequest_ = CefURLRequest::Create(
|
||||
cef_request, new RequestClient(request_callback), NULL);
|
||||
// Create and start a new CefURLRequest associated with the frame, so
|
||||
// that it shares authentication with ClientHandler::GetAuthCredentials.
|
||||
urlrequest_ = frame->CreateURLRequest(
|
||||
cef_request, new RequestClient(request_callback));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -7,11 +7,13 @@
|
||||
<ul>
|
||||
<li><a href="http://mudcu.be/labs/JS1k/BreathingGalaxies.html">Accelerated 2D Canvas</a></li>
|
||||
<li><a href="http://webkit.org/blog-files/3d-transforms/poster-circle.html">Accelerated Layers</a></li>
|
||||
<li><a href="https://jigsaw.w3.org/HTTP/Basic/">Authentication (Basic)</a> - credentials returned via GetAuthCredentials</li>
|
||||
<li><a href="https://jigsaw.w3.org/HTTP/Digest/">Authentication (Digest)</a> - credentials returned via GetAuthCredentials</li>
|
||||
<li><a href="http://html5advent2011.digitpaint.nl/3/index.html">Cursors</a></li>
|
||||
<li><a href="dialogs">Dialogs</a></li>
|
||||
<li><a href="http://html5demos.com/drag">Drag & Drop</a></li>
|
||||
<li><a href="draggable">Draggable Regions</a></li>
|
||||
<li><a href="drm">DRM (Clearkey, Widevine)</a></li>
|
||||
<li><a href="drm">DRM (Clearkey, Widevine)</a> - Widevine requires setup as described in cef_web_plugin.h</li>
|
||||
<li><a href="http://www.adobe.com/software/flash/about/">Flash Plugin</a> - requires "enable-system-flash" flag on Win/Mac and "ppapi-flash-path", "ppapi-flash-version" flags on Linux</li>
|
||||
<li><a href="http://www.html5test.com">HTML5 Feature Test</a></li>
|
||||
<li><a href="http://html5-demos.appspot.com/static/filesystem/filer.js/demos/index.html">HTML5 Filesystem</a> - requires "cache-path" flag</li>
|
||||
@@ -36,7 +38,7 @@
|
||||
<li><a href="urlrequest">CefURLRequest</a></li>
|
||||
<li><a href="xmlhttprequest">XMLHttpRequest</a></li>
|
||||
<li><a href="javascript:window.print();">Print this page with "javascript:window.print();"</a></li>
|
||||
<li><a href="https://patrickhlauke.github.io/touch">Touch Feature Tests</a> - requires "touch-events=enabled" flag (and CAPS LOCK on Mac for Trackpad simulation) </li>
|
||||
<li><a href="https://patrickhlauke.github.io/touch">Touch Feature Tests</a> - requires "touch-events=enabled" flag (and CAPS LOCK on Mac for Trackpad simulation)</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1067,13 +1067,13 @@ std::string GetCookieAccessUrl2(const std::string& scheme,
|
||||
}
|
||||
|
||||
void TestCookieString(const std::string& cookie_str,
|
||||
TrackCallback& got_cookie_js,
|
||||
TrackCallback& got_cookie_net) {
|
||||
int& cookie_js_ct,
|
||||
int& cookie_net_ct) {
|
||||
if (cookie_str.find("name_js=value_js") != std::string::npos) {
|
||||
got_cookie_js.yes();
|
||||
cookie_js_ct++;
|
||||
}
|
||||
if (cookie_str.find("name_net=value_net") != std::string::npos) {
|
||||
got_cookie_net.yes();
|
||||
cookie_net_ct++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1081,9 +1081,9 @@ struct CookieAccessData {
|
||||
CefRefPtr<CefResponse> response;
|
||||
std::string response_data;
|
||||
|
||||
TrackCallback got_request_;
|
||||
TrackCallback got_cookie_js_;
|
||||
TrackCallback got_cookie_net_;
|
||||
int request_ct_ = 0;
|
||||
int cookie_js_ct_ = 0;
|
||||
int cookie_net_ct_ = 0;
|
||||
};
|
||||
|
||||
class CookieAccessResponseHandler {
|
||||
@@ -1116,7 +1116,7 @@ class CookieAccessSchemeHandler : public CefResourceHandler {
|
||||
CefRequest::HeaderMap headerMap;
|
||||
request->GetHeaderMap(headerMap);
|
||||
const std::string& cookie_str = GetHeaderValue(headerMap, "Cookie");
|
||||
TestCookieString(cookie_str, data_->got_cookie_js_, data_->got_cookie_net_);
|
||||
TestCookieString(cookie_str, data_->cookie_js_ct_, data_->cookie_net_ct_);
|
||||
|
||||
// Continue immediately.
|
||||
callback->Continue();
|
||||
@@ -1203,7 +1203,7 @@ class CookieAccessSchemeHandlerFactory : public CefSchemeHandlerFactory,
|
||||
const std::string& url = request->GetURL();
|
||||
ResponseDataMap::const_iterator it = data_map_.find(url);
|
||||
if (it != data_map_.end()) {
|
||||
it->second->got_request_.yes();
|
||||
it->second->request_ct_++;
|
||||
|
||||
return new CookieAccessSchemeHandler(it->second);
|
||||
}
|
||||
@@ -1425,13 +1425,13 @@ class CookieAccessServerHandler : public CefServerHandler,
|
||||
const std::string& url = request->GetURL();
|
||||
ResponseDataMap::const_iterator it = data_map_.find(url);
|
||||
if (it != data_map_.end()) {
|
||||
it->second->got_request_.yes();
|
||||
it->second->request_ct_++;
|
||||
|
||||
CefRequest::HeaderMap headerMap;
|
||||
request->GetHeaderMap(headerMap);
|
||||
const std::string& cookie_str = GetHeaderValue(headerMap, "cookie");
|
||||
TestCookieString(cookie_str, it->second->got_cookie_js_,
|
||||
it->second->got_cookie_net_);
|
||||
TestCookieString(cookie_str, it->second->cookie_js_ct_,
|
||||
it->second->cookie_net_ct_);
|
||||
|
||||
SendResponse(server, connection_id, it->second->response,
|
||||
it->second->response_data);
|
||||
@@ -1593,10 +1593,8 @@ class CookieAccessTestHandler : public RoutingTestHandler,
|
||||
context_ = NULL;
|
||||
|
||||
// Got both network requests.
|
||||
EXPECT_TRUE(data1_.got_request_);
|
||||
EXPECT_TRUE(data2_.got_request_);
|
||||
|
||||
EXPECT_FALSE(got_cookie_manager_);
|
||||
EXPECT_EQ(1, data1_.request_ct_);
|
||||
EXPECT_EQ(1, data2_.request_ct_);
|
||||
|
||||
if (test_mode_ == ALLOW_NO_FILTER || test_mode_ == ALLOW_NO_HANDLER) {
|
||||
EXPECT_EQ(0, can_save_cookie1_ct_);
|
||||
@@ -1621,44 +1619,44 @@ class CookieAccessTestHandler : public RoutingTestHandler,
|
||||
|
||||
if (test_mode_ == BLOCK_ALL_COOKIES) {
|
||||
// Never get the JS cookie via JS.
|
||||
EXPECT_FALSE(got_cookie_js1_);
|
||||
EXPECT_FALSE(got_cookie_js2_);
|
||||
EXPECT_FALSE(got_cookie_js3_);
|
||||
EXPECT_EQ(0, cookie_js1_ct_);
|
||||
EXPECT_EQ(0, cookie_js2_ct_);
|
||||
EXPECT_EQ(0, cookie_js3_ct_);
|
||||
} else {
|
||||
// Always get the JS cookie via JS.
|
||||
EXPECT_TRUE(got_cookie_js1_);
|
||||
EXPECT_TRUE(got_cookie_js2_);
|
||||
EXPECT_TRUE(got_cookie_js3_);
|
||||
EXPECT_EQ(1, cookie_js1_ct_);
|
||||
EXPECT_EQ(1, cookie_js2_ct_);
|
||||
EXPECT_EQ(1, cookie_js3_ct_);
|
||||
}
|
||||
|
||||
// Only get the net cookie via JS if cookie write was allowed.
|
||||
if ((test_mode_ & BLOCK_WRITE) || test_mode_ == BLOCK_ALL_COOKIES) {
|
||||
EXPECT_FALSE(got_cookie_net1_);
|
||||
EXPECT_FALSE(got_cookie_net2_);
|
||||
EXPECT_FALSE(got_cookie_net3_);
|
||||
EXPECT_EQ(0, cookie_net1_ct_);
|
||||
EXPECT_EQ(0, cookie_net2_ct_);
|
||||
EXPECT_EQ(0, cookie_net3_ct_);
|
||||
} else {
|
||||
EXPECT_TRUE(got_cookie_net1_);
|
||||
EXPECT_TRUE(got_cookie_net2_);
|
||||
EXPECT_TRUE(got_cookie_net3_);
|
||||
EXPECT_EQ(1, cookie_net1_ct_);
|
||||
EXPECT_EQ(1, cookie_net2_ct_);
|
||||
EXPECT_EQ(1, cookie_net3_ct_);
|
||||
}
|
||||
|
||||
// No cookies sent for the 1st network request.
|
||||
EXPECT_FALSE(data1_.got_cookie_js_);
|
||||
EXPECT_FALSE(data1_.got_cookie_net_);
|
||||
EXPECT_EQ(0, data1_.cookie_js_ct_);
|
||||
EXPECT_EQ(0, data1_.cookie_net_ct_);
|
||||
|
||||
// 2nd network request...
|
||||
if ((test_mode_ & BLOCK_READ) || test_mode_ == BLOCK_ALL_COOKIES) {
|
||||
// No cookies sent if reading was blocked.
|
||||
EXPECT_FALSE(data2_.got_cookie_js_);
|
||||
EXPECT_FALSE(data2_.got_cookie_net_);
|
||||
EXPECT_EQ(0, data2_.cookie_js_ct_);
|
||||
EXPECT_EQ(0, data2_.cookie_net_ct_);
|
||||
} else if (test_mode_ & BLOCK_WRITE) {
|
||||
// Only JS cookie sent if writing was blocked.
|
||||
EXPECT_TRUE(data2_.got_cookie_js_);
|
||||
EXPECT_FALSE(data2_.got_cookie_net_);
|
||||
EXPECT_EQ(1, data2_.cookie_js_ct_);
|
||||
EXPECT_EQ(0, data2_.cookie_net_ct_);
|
||||
} else {
|
||||
// All cookies sent.
|
||||
EXPECT_TRUE(data2_.got_cookie_js_);
|
||||
EXPECT_TRUE(data2_.got_cookie_net_);
|
||||
EXPECT_EQ(1, data2_.cookie_js_ct_);
|
||||
EXPECT_EQ(1, data2_.cookie_net_ct_);
|
||||
}
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
@@ -1747,11 +1745,11 @@ class CookieAccessTestHandler : public RoutingTestHandler,
|
||||
const std::string& url = frame->GetURL();
|
||||
const std::string& cookie_str = request.ToString();
|
||||
if (url == GetCookieAccessUrl1(scheme_, test_backend_ == SERVER)) {
|
||||
TestCookieString(cookie_str, got_cookie_js1_, got_cookie_net1_);
|
||||
TestCookieString(cookie_str, cookie_js1_ct_, cookie_net1_ct_);
|
||||
browser->GetMainFrame()->LoadURL(
|
||||
GetCookieAccessUrl2(scheme_, test_backend_ == SERVER));
|
||||
} else if (url == GetCookieAccessUrl2(scheme_, test_backend_ == SERVER)) {
|
||||
TestCookieString(cookie_str, got_cookie_js2_, got_cookie_net2_);
|
||||
TestCookieString(cookie_str, cookie_js2_ct_, cookie_net2_ct_);
|
||||
FinishTest();
|
||||
} else {
|
||||
ADD_FAILURE() << "Unexpected url: " << url;
|
||||
@@ -1873,9 +1871,9 @@ class CookieAccessTestHandler : public RoutingTestHandler,
|
||||
const std::string& name = CefString(&cookie.name);
|
||||
const std::string& value = CefString(&cookie.value);
|
||||
if (name == "name_js" && value == "value_js")
|
||||
handler_->got_cookie_js3_.yes();
|
||||
handler_->cookie_js3_ct_++;
|
||||
else if (name == "name_net" && value == "value_net")
|
||||
handler_->got_cookie_net3_.yes();
|
||||
handler_->cookie_net3_ct_++;
|
||||
|
||||
// Clean up the cookies.
|
||||
deleteCookie = true;
|
||||
@@ -1930,21 +1928,19 @@ class CookieAccessTestHandler : public RoutingTestHandler,
|
||||
CookieAccessData data1_;
|
||||
CookieAccessData data2_;
|
||||
|
||||
TrackCallback got_cookie_manager_;
|
||||
|
||||
// 1st request.
|
||||
int can_save_cookie1_ct_ = 0;
|
||||
TrackCallback got_cookie_js1_;
|
||||
TrackCallback got_cookie_net1_;
|
||||
int cookie_js1_ct_ = 0;
|
||||
int cookie_net1_ct_ = 0;
|
||||
|
||||
// 2nd request.
|
||||
int can_send_cookie2_ct_ = 0;
|
||||
TrackCallback got_cookie_js2_;
|
||||
TrackCallback got_cookie_net2_;
|
||||
int cookie_js2_ct_ = 0;
|
||||
int cookie_net2_ct_ = 0;
|
||||
|
||||
// From cookie manager.
|
||||
TrackCallback got_cookie_js3_;
|
||||
TrackCallback got_cookie_net3_;
|
||||
int cookie_js3_ct_ = 0;
|
||||
int cookie_net3_ct_ = 0;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CookieAccessTestHandler);
|
||||
IMPLEMENT_REFCOUNTING(CookieAccessTestHandler);
|
||||
@@ -2026,6 +2022,397 @@ ACCESS_TEST_ALLOWNOHANDLER_MODES(SchemeStandard, SCHEME_HANDLER, false)
|
||||
ACCESS_TEST_CUSTOM(Resource, RESOURCE_HANDLER)
|
||||
ACCESS_TEST_STANDARD(Resource, RESOURCE_HANDLER)
|
||||
|
||||
namespace {
|
||||
|
||||
// Tests the behavior of restarting of a network request that sets cookies and
|
||||
// a network request that includes cookies.
|
||||
// 1. Begin loading URL1, then restart the request in OnResourceResponse.
|
||||
// No cookies are saved.
|
||||
// 2. Load URL1 successfully. Network and JS cookies are saved.
|
||||
// 3. Begin loading URL2, then restart the request in OnResourceResponse.
|
||||
// Cookies are sent with the request/response.
|
||||
// 4. Load URL2 successfully. Cookies are sent with the request/response.
|
||||
class CookieRestartTestHandler : public RoutingTestHandler,
|
||||
public CefCookieAccessFilter {
|
||||
public:
|
||||
explicit CookieRestartTestHandler(bool use_global)
|
||||
: scheme_(kCookieAccessScheme), use_global_(use_global) {}
|
||||
|
||||
void RunTest() override {
|
||||
if (use_global_) {
|
||||
context_ = CefRequestContext::GetGlobalContext();
|
||||
} else {
|
||||
// Create the request context that will use an in-memory cache.
|
||||
CefRequestContextSettings settings;
|
||||
context_ = CefRequestContext::CreateContext(settings, NULL);
|
||||
}
|
||||
|
||||
cookie_manager_ = context_->GetCookieManager(nullptr);
|
||||
|
||||
SetTestTimeout();
|
||||
RunTestSetupContinue();
|
||||
}
|
||||
|
||||
void DestroyTest() override {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
CefPostTask(TID_UI,
|
||||
base::Bind(&CookieRestartTestHandler::DestroyTest, this));
|
||||
return;
|
||||
}
|
||||
|
||||
cookie_manager_ = NULL;
|
||||
context_ = NULL;
|
||||
|
||||
// Get 2 network requests for each URL.
|
||||
EXPECT_EQ(2, data1_.request_ct_);
|
||||
EXPECT_EQ(2, data2_.request_ct_);
|
||||
|
||||
// Get resource request callbacks for all requests (2 for each URL).
|
||||
EXPECT_EQ(4, before_resource_load_ct_);
|
||||
EXPECT_EQ(4, resource_response_ct_);
|
||||
|
||||
// Get JS query callbacks for the successful requests (1 for each URL).
|
||||
EXPECT_EQ(2, query_ct_);
|
||||
|
||||
// No cookies sent for the URL1 network requests because (a) we don't have
|
||||
// any cookies set initially and (b) we don't save cookies from the 1st URL1
|
||||
// request which is restarted.
|
||||
EXPECT_EQ(0, data1_.cookie_js_ct_);
|
||||
EXPECT_EQ(0, data1_.cookie_net_ct_);
|
||||
|
||||
// Net and JS cookies sent for both URL2 network requests.
|
||||
EXPECT_EQ(2, data2_.cookie_js_ct_);
|
||||
EXPECT_EQ(2, data2_.cookie_net_ct_);
|
||||
|
||||
// 1 call to CanSaveCookie for the net cookie returned by the successful
|
||||
// URL1 request.
|
||||
EXPECT_EQ(1, can_save_cookie_ct_);
|
||||
// 4 calls to CanSendCookie because both net and JS cookies are sent for
|
||||
// each URL2 request.
|
||||
EXPECT_EQ(4, can_send_cookie_ct_);
|
||||
|
||||
// Get the net and JS cookies from the JS query for the successful requests
|
||||
// (1 for each URL).
|
||||
EXPECT_EQ(1, cookie_js1_ct_);
|
||||
EXPECT_EQ(1, cookie_net1_ct_);
|
||||
EXPECT_EQ(1, cookie_js2_ct_);
|
||||
EXPECT_EQ(1, cookie_net2_ct_);
|
||||
|
||||
// Get the net and JS cookies from the cookie manager at the end.
|
||||
EXPECT_EQ(1, cookie_manager_js_ct_);
|
||||
EXPECT_EQ(1, cookie_manager_net_ct_);
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
}
|
||||
|
||||
CefRefPtr<CefCookieAccessFilter> GetCookieAccessFilter(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) override {
|
||||
EXPECT_IO_THREAD();
|
||||
return this;
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool is_navigation,
|
||||
bool is_download,
|
||||
const CefString& request_initiator,
|
||||
bool& disable_default_handling) override {
|
||||
return this;
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CanSendCookie(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
const CefCookie& cookie) override {
|
||||
EXPECT_IO_THREAD();
|
||||
can_send_cookie_ct_++;
|
||||
|
||||
// Called before the URL2 network requests.
|
||||
EXPECT_LE(2, before_resource_load_ct_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CanSaveCookie(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response,
|
||||
const CefCookie& cookie) override {
|
||||
EXPECT_IO_THREAD();
|
||||
can_save_cookie_ct_++;
|
||||
|
||||
// Called after the successful URL1 network request.
|
||||
EXPECT_EQ(2, before_resource_load_ct_);
|
||||
|
||||
// Expecting the network cookie only.
|
||||
EXPECT_STREQ("name_net", CefString(&cookie.name).ToString().c_str());
|
||||
EXPECT_STREQ("value_net", CefString(&cookie.value).ToString().c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
cef_return_value_t OnBeforeResourceLoad(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefRequestCallback> callback) override {
|
||||
EXPECT_IO_THREAD();
|
||||
before_resource_load_ct_++;
|
||||
|
||||
const std::string& url = request->GetURL();
|
||||
|
||||
if (before_resource_load_ct_ <= 2) {
|
||||
EXPECT_STREQ(GetCookieAccessUrl1(scheme_, true).c_str(), url.c_str());
|
||||
} else {
|
||||
EXPECT_STREQ(GetCookieAccessUrl2(scheme_, true).c_str(), url.c_str());
|
||||
}
|
||||
|
||||
const std::string& cookie_str = request->GetHeaderByName("Cookie");
|
||||
int cookie_js_ct = 0;
|
||||
int cookie_net_ct = 0;
|
||||
TestCookieString(cookie_str, cookie_js_ct, cookie_net_ct);
|
||||
|
||||
// Expect both cookies with the URL2 requests only.
|
||||
if (before_resource_load_ct_ >= 3) {
|
||||
EXPECT_EQ(1, cookie_js_ct);
|
||||
EXPECT_EQ(1, cookie_net_ct);
|
||||
} else {
|
||||
EXPECT_EQ(0, cookie_js_ct);
|
||||
EXPECT_EQ(0, cookie_net_ct);
|
||||
}
|
||||
|
||||
return RV_CONTINUE;
|
||||
}
|
||||
|
||||
bool OnResourceResponse(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response) override {
|
||||
EXPECT_IO_THREAD();
|
||||
resource_response_ct_++;
|
||||
|
||||
const std::string& url = request->GetURL();
|
||||
const std::string& set_cookie_str = response->GetHeader("Set-Cookie");
|
||||
|
||||
// Expect the network cookie with URL1 requests only.
|
||||
if (resource_response_ct_ <= 2) {
|
||||
EXPECT_STREQ(GetCookieAccessUrl1(scheme_, true).c_str(), url.c_str());
|
||||
EXPECT_STREQ("name_net=value_net", set_cookie_str.c_str());
|
||||
} else {
|
||||
EXPECT_STREQ(GetCookieAccessUrl2(scheme_, true).c_str(), url.c_str());
|
||||
EXPECT_TRUE(set_cookie_str.empty());
|
||||
}
|
||||
|
||||
if (resource_response_ct_ == 1 || resource_response_ct_ == 3) {
|
||||
// Restart the request loading this data.
|
||||
request->SetHeaderByName("X-Custom-Header", "value", false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int64 query_id,
|
||||
const CefString& request,
|
||||
bool persistent,
|
||||
CefRefPtr<Callback> callback) override {
|
||||
query_ct_++;
|
||||
|
||||
const std::string& url = frame->GetURL();
|
||||
const std::string& cookie_str = request.ToString();
|
||||
if (url == GetCookieAccessUrl1(scheme_, true)) {
|
||||
TestCookieString(cookie_str, cookie_js1_ct_, cookie_net1_ct_);
|
||||
browser->GetMainFrame()->LoadURL(GetCookieAccessUrl2(scheme_, true));
|
||||
} else if (url == GetCookieAccessUrl2(scheme_, true)) {
|
||||
TestCookieString(cookie_str, cookie_js2_ct_, cookie_net2_ct_);
|
||||
FinishTest();
|
||||
} else {
|
||||
ADD_FAILURE() << "Unexpected url: " << url;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void AddResponses(CookieAccessResponseHandler* handler) {
|
||||
// Sets a cookie via net response headers and JS, then retrieves the cookies
|
||||
// via JS.
|
||||
{
|
||||
data1_.response = CefResponse::Create();
|
||||
data1_.response->SetMimeType("text/html");
|
||||
data1_.response->SetStatus(200);
|
||||
data1_.response->SetStatusText("OK");
|
||||
|
||||
CefResponse::HeaderMap headerMap;
|
||||
data1_.response->GetHeaderMap(headerMap);
|
||||
headerMap.insert(std::make_pair("Set-Cookie", "name_net=value_net"));
|
||||
data1_.response->SetHeaderMap(headerMap);
|
||||
|
||||
data1_.response_data =
|
||||
"<html><head>"
|
||||
"<script>"
|
||||
"document.cookie='name_js=value_js';"
|
||||
"window.testQuery({request:document.cookie});"
|
||||
"</script>"
|
||||
"</head><body>COOKIE RESTART TEST1</body></html>";
|
||||
|
||||
handler->AddResponse(GetCookieAccessUrl1(scheme_, true), &data1_);
|
||||
}
|
||||
|
||||
// Retrieves the cookies via JS.
|
||||
{
|
||||
data2_.response = CefResponse::Create();
|
||||
data2_.response->SetMimeType("text/html");
|
||||
data2_.response->SetStatus(200);
|
||||
data2_.response->SetStatusText("OK");
|
||||
|
||||
data2_.response_data =
|
||||
"<html><head>"
|
||||
"<script>"
|
||||
"window.testQuery({request:document.cookie});"
|
||||
"</script>"
|
||||
"</head><body>COOKIE RESTART TEST2</body></html>";
|
||||
|
||||
handler->AddResponse(GetCookieAccessUrl2(scheme_, true), &data2_);
|
||||
}
|
||||
}
|
||||
|
||||
void RunTestSetupContinue() {
|
||||
CefPostTask(
|
||||
TID_UI,
|
||||
base::Bind(
|
||||
&CookieRestartTestHandler::StartServer, this,
|
||||
base::Bind(&CookieRestartTestHandler::RunTestContinue, this)));
|
||||
}
|
||||
|
||||
void StartServer(const base::Closure& complete_callback) {
|
||||
EXPECT_FALSE(server_handler_);
|
||||
|
||||
server_handler_ = new CookieAccessServerHandler();
|
||||
AddResponses(server_handler_.get());
|
||||
// 2 requests for each URL.
|
||||
server_handler_->SetExpectedRequestCount(4);
|
||||
server_handler_->CreateServer(complete_callback);
|
||||
}
|
||||
|
||||
void RunTestContinue() {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
CefPostTask(TID_UI,
|
||||
base::Bind(&CookieRestartTestHandler::RunTestContinue, this));
|
||||
return;
|
||||
}
|
||||
|
||||
CreateBrowser(GetCookieAccessUrl1(scheme_, true), context_);
|
||||
}
|
||||
|
||||
void FinishTest() {
|
||||
// Verify that cookies were set correctly.
|
||||
class TestVisitor : public CefCookieVisitor {
|
||||
public:
|
||||
explicit TestVisitor(CookieRestartTestHandler* handler)
|
||||
: handler_(handler) {}
|
||||
~TestVisitor() override {
|
||||
// Destroy the test.
|
||||
CefPostTask(
|
||||
TID_UI,
|
||||
base::Bind(
|
||||
&CookieRestartTestHandler::ShutdownServer, handler_,
|
||||
base::Bind(&CookieRestartTestHandler::DestroyTest, handler_)));
|
||||
}
|
||||
|
||||
bool Visit(const CefCookie& cookie,
|
||||
int count,
|
||||
int total,
|
||||
bool& deleteCookie) override {
|
||||
const std::string& name = CefString(&cookie.name);
|
||||
const std::string& value = CefString(&cookie.value);
|
||||
if (name == "name_js" && value == "value_js")
|
||||
handler_->cookie_manager_js_ct_++;
|
||||
else if (name == "name_net" && value == "value_net")
|
||||
handler_->cookie_manager_net_ct_++;
|
||||
|
||||
// Clean up the cookies.
|
||||
deleteCookie = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
CookieRestartTestHandler* handler_;
|
||||
IMPLEMENT_REFCOUNTING(TestVisitor);
|
||||
};
|
||||
|
||||
cookie_manager_->VisitAllCookies(new TestVisitor(this));
|
||||
}
|
||||
|
||||
void ShutdownServer(const base::Closure& complete_callback) {
|
||||
EXPECT_TRUE(server_handler_);
|
||||
|
||||
server_handler_->ShutdownServer(complete_callback);
|
||||
server_handler_ = nullptr;
|
||||
}
|
||||
|
||||
const std::string scheme_;
|
||||
const bool use_global_;
|
||||
CefRefPtr<CefRequestContext> context_;
|
||||
CefRefPtr<CefCookieManager> cookie_manager_;
|
||||
|
||||
CefRefPtr<CookieAccessServerHandler> server_handler_;
|
||||
|
||||
CookieAccessData data1_;
|
||||
CookieAccessData data2_;
|
||||
|
||||
int before_resource_load_ct_ = 0;
|
||||
int resource_response_ct_ = 0;
|
||||
int query_ct_ = 0;
|
||||
|
||||
// From network requests.
|
||||
int can_save_cookie_ct_ = 0;
|
||||
int can_send_cookie_ct_ = 0;
|
||||
int cookie_js1_ct_ = 0;
|
||||
int cookie_net1_ct_ = 0;
|
||||
int cookie_js2_ct_ = 0;
|
||||
int cookie_net2_ct_ = 0;
|
||||
|
||||
// From cookie manager.
|
||||
int cookie_manager_js_ct_ = 0;
|
||||
int cookie_manager_net_ct_ = 0;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CookieRestartTestHandler);
|
||||
IMPLEMENT_REFCOUNTING(CookieRestartTestHandler);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(CookieTest, RestartGlobal) {
|
||||
if (!IsNetworkServiceEnabled())
|
||||
return;
|
||||
CefRefPtr<CookieRestartTestHandler> handler =
|
||||
new CookieRestartTestHandler(true);
|
||||
handler->ExecuteTest();
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
||||
|
||||
TEST(CookieTest, RestartInMemory) {
|
||||
if (!IsNetworkServiceEnabled())
|
||||
return;
|
||||
CefRefPtr<CookieRestartTestHandler> handler =
|
||||
new CookieRestartTestHandler(false);
|
||||
handler->ExecuteTest();
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
||||
|
||||
// Entry point for registering custom schemes.
|
||||
// Called from client_app_delegates.cc.
|
||||
void RegisterCookieCustomSchemes(CefRawPtr<CefSchemeRegistrar> registrar,
|
||||
|
@@ -393,6 +393,11 @@ class FrameNavRendererTest : public ClientAppRenderer::Delegate,
|
||||
EXPECT_TRUE(args.get());
|
||||
EXPECT_TRUE(args->SetInt(0, nav_));
|
||||
EXPECT_TRUE(args->SetBool(1, result));
|
||||
|
||||
const int64 frame_id = frame->GetIdentifier();
|
||||
EXPECT_TRUE(args->SetInt(2, CefInt64GetLow(frame_id)));
|
||||
EXPECT_TRUE(args->SetInt(3, CefInt64GetHigh(frame_id)));
|
||||
|
||||
frame->SendProcessMessage(PID_BROWSER, return_msg);
|
||||
|
||||
nav_++;
|
||||
@@ -527,6 +532,11 @@ class FrameNavTestHandler : public TestHandler {
|
||||
EXPECT_TRUE(expectations_->OnRendererComplete(
|
||||
browser, frame, args->GetInt(0), args->GetBool(1)))
|
||||
<< "nav = " << nav_;
|
||||
|
||||
// Test that browser and render process frame IDs match.
|
||||
const int64 frame_id = CefInt64Set(args->GetInt(2), args->GetInt(3));
|
||||
EXPECT_EQ(frame->GetIdentifier(), frame_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -163,6 +163,14 @@ class BasicResponseTest : public TestHandler {
|
||||
// Normal load, nothing fancy.
|
||||
LOAD,
|
||||
|
||||
// Close the browser in OnAfterCreated to verify destruction handling of
|
||||
// uninitialized requests.
|
||||
ABORT_AFTER_CREATED,
|
||||
|
||||
// Close the browser in OnBeforeBrowse to verify destruction handling of
|
||||
// uninitialized requests.
|
||||
ABORT_BEFORE_BROWSE,
|
||||
|
||||
// Don't continue from OnBeforeResourceLoad, then close the browser to
|
||||
// verify destruction handling of in-progress requests.
|
||||
INCOMPLETE_BEFORE_RESOURCE_LOAD,
|
||||
@@ -207,6 +215,25 @@ class BasicResponseTest : public TestHandler {
|
||||
SetTestTimeout();
|
||||
}
|
||||
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
||||
EXPECT_UI_THREAD();
|
||||
TestHandler::OnAfterCreated(browser);
|
||||
|
||||
if (mode_ == ABORT_AFTER_CREATED) {
|
||||
SetSignalCompletionWhenAllBrowsersClose(false);
|
||||
CloseBrowser(browser, false);
|
||||
}
|
||||
}
|
||||
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override {
|
||||
EXPECT_UI_THREAD();
|
||||
TestHandler::OnBeforeClose(browser);
|
||||
|
||||
if (IsAborted()) {
|
||||
DestroyTest();
|
||||
}
|
||||
}
|
||||
|
||||
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
@@ -233,6 +260,11 @@ class BasicResponseTest : public TestHandler {
|
||||
|
||||
VerifyState(kOnBeforeBrowse, request, nullptr);
|
||||
|
||||
if (mode_ == ABORT_BEFORE_BROWSE) {
|
||||
SetSignalCompletionWhenAllBrowsersClose(false);
|
||||
CloseBrowser(browser, false);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -475,7 +507,7 @@ class BasicResponseTest : public TestHandler {
|
||||
|
||||
VerifyState(kOnResourceLoadComplete, request, response);
|
||||
|
||||
if (unhandled_ || IsIncomplete()) {
|
||||
if (unhandled_ || IsIncomplete() || IsAborted()) {
|
||||
EXPECT_EQ(UR_FAILED, status);
|
||||
EXPECT_EQ(0, received_content_length);
|
||||
} else {
|
||||
@@ -661,19 +693,36 @@ class BasicResponseTest : public TestHandler {
|
||||
EXPECT_EQ(0, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(0, on_resource_response_ct_);
|
||||
}
|
||||
} else if (IsAborted()) {
|
||||
EXPECT_EQ(1, on_before_browse_ct_);
|
||||
if (custom_scheme_) {
|
||||
EXPECT_EQ(0, get_resource_request_handler_ct_);
|
||||
EXPECT_EQ(0, get_cookie_access_filter_ct_);
|
||||
} else {
|
||||
// The callbacks executed for standard schemes may vary based on timing.
|
||||
}
|
||||
EXPECT_EQ(0, on_before_resource_load_ct_);
|
||||
EXPECT_EQ(0, get_resource_handler_ct_);
|
||||
EXPECT_EQ(0, on_resource_redirect_ct_);
|
||||
EXPECT_EQ(0, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(0, on_resource_response_ct_);
|
||||
} else {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
EXPECT_EQ(resource_handler_created_ct_, resource_handler_destroyed_ct_);
|
||||
EXPECT_EQ(1, on_resource_load_complete_ct_);
|
||||
|
||||
if (IsIncomplete())
|
||||
if (IsAborted())
|
||||
EXPECT_EQ(0, on_resource_load_complete_ct_);
|
||||
else
|
||||
EXPECT_EQ(1, on_resource_load_complete_ct_);
|
||||
|
||||
if (IsIncomplete() || IsAborted())
|
||||
EXPECT_EQ(0, on_load_end_ct_);
|
||||
else
|
||||
EXPECT_EQ(1, on_load_end_ct_);
|
||||
|
||||
if (custom_scheme_ && unhandled_ && !IsIncomplete())
|
||||
if (custom_scheme_ && unhandled_ && !(IsIncomplete() || IsAborted()))
|
||||
EXPECT_EQ(1, on_protocol_execution_ct_);
|
||||
else
|
||||
EXPECT_EQ(0, on_protocol_execution_ct_);
|
||||
@@ -715,7 +764,7 @@ class BasicResponseTest : public TestHandler {
|
||||
}
|
||||
|
||||
const char* GetStartupURL() const {
|
||||
if (IsLoad() || IsIncomplete()) {
|
||||
if (IsLoad() || IsIncomplete() || IsAborted()) {
|
||||
return GetURL(RESULT_HTML);
|
||||
} else if (mode_ == REDIRECT_RESOURCE_REDIRECT) {
|
||||
return GetURL(REDIRECT2_HTML);
|
||||
@@ -786,6 +835,10 @@ class BasicResponseTest : public TestHandler {
|
||||
IsIncompleteRequestHandler();
|
||||
}
|
||||
|
||||
bool IsAborted() const {
|
||||
return mode_ == ABORT_AFTER_CREATED || mode_ == ABORT_BEFORE_BROWSE;
|
||||
}
|
||||
|
||||
bool IsRedirect() const {
|
||||
return mode_ == REDIRECT_BEFORE_RESOURCE_LOAD ||
|
||||
mode_ == REDIRECT_REQUEST_HANDLER ||
|
||||
@@ -852,7 +905,7 @@ class BasicResponseTest : public TestHandler {
|
||||
EXPECT_EQ(request_id_, request->GetIdentifier()) << callback;
|
||||
}
|
||||
|
||||
if (IsLoad() || IsIncomplete()) {
|
||||
if (IsLoad() || IsIncomplete() || IsAborted()) {
|
||||
EXPECT_STREQ("GET", request->GetMethod().ToString().c_str()) << callback;
|
||||
EXPECT_STREQ(GetURL(RESULT_HTML), request->GetURL().ToString().c_str())
|
||||
<< callback;
|
||||
@@ -912,7 +965,8 @@ class BasicResponseTest : public TestHandler {
|
||||
// response.
|
||||
const bool incomplete_unhandled =
|
||||
(mode_ == INCOMPLETE_BEFORE_RESOURCE_LOAD ||
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST);
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST ||
|
||||
(IsAborted() && !custom_scheme_));
|
||||
|
||||
if ((unhandled_ && !override_unhandled) || incomplete_unhandled) {
|
||||
if (incomplete_unhandled) {
|
||||
@@ -927,7 +981,7 @@ class BasicResponseTest : public TestHandler {
|
||||
EXPECT_STREQ("", response->GetMimeType().ToString().c_str()) << callback;
|
||||
EXPECT_STREQ("", response->GetCharset().ToString().c_str()) << callback;
|
||||
} else {
|
||||
if (mode_ == INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE &&
|
||||
if ((mode_ == INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE || IsAborted()) &&
|
||||
callback == kOnResourceLoadComplete) {
|
||||
// We got a response, but we also got aborted.
|
||||
EXPECT_EQ(ERR_ABORTED, response->GetError()) << callback;
|
||||
@@ -1035,7 +1089,9 @@ bool IsTestSupported(BasicResponseTest::TestMode test_mode,
|
||||
// for custom schemes and unhandled requests.
|
||||
return false;
|
||||
}
|
||||
if (test_mode == BasicResponseTest::INCOMPLETE_BEFORE_RESOURCE_LOAD ||
|
||||
if (test_mode == BasicResponseTest::ABORT_AFTER_CREATED ||
|
||||
test_mode == BasicResponseTest::ABORT_BEFORE_BROWSE ||
|
||||
test_mode == BasicResponseTest::INCOMPLETE_BEFORE_RESOURCE_LOAD ||
|
||||
test_mode ==
|
||||
BasicResponseTest::INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST ||
|
||||
test_mode ==
|
||||
@@ -1063,6 +1119,8 @@ bool IsTestSupported(BasicResponseTest::TestMode test_mode,
|
||||
|
||||
#define BASIC_TEST_ALL_MODES(name, custom, unhandled) \
|
||||
BASIC_TEST(name##Load, LOAD, custom, unhandled) \
|
||||
BASIC_TEST(name##AbortAfterCreated, ABORT_AFTER_CREATED, custom, unhandled) \
|
||||
BASIC_TEST(name##AbortBeforeBrowse, ABORT_BEFORE_BROWSE, custom, unhandled) \
|
||||
BASIC_TEST(name##ModifyBeforeResourceLoad, MODIFY_BEFORE_RESOURCE_LOAD, \
|
||||
custom, unhandled) \
|
||||
BASIC_TEST(name##RedirectBeforeResourceLoad, REDIRECT_BEFORE_RESOURCE_LOAD, \
|
||||
|
@@ -450,6 +450,11 @@ void TestHandler::SetTestTimeout(int timeout_ms, bool treat_as_error) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (destroy_test_called_) {
|
||||
// No need to set the timeout if the test has already completed.
|
||||
return;
|
||||
}
|
||||
|
||||
if (treat_as_error && CefCommandLine::GetGlobalCommandLine()->HasSwitch(
|
||||
"disable-test-timeout")) {
|
||||
return;
|
||||
@@ -475,7 +480,7 @@ void TestHandler::TestComplete() {
|
||||
|
||||
TestHandler::UIThreadHelper* TestHandler::GetUIThreadHelper() {
|
||||
EXPECT_UI_THREAD();
|
||||
EXPECT_FALSE(destroy_test_called_);
|
||||
CHECK(!destroy_test_called_);
|
||||
|
||||
if (!ui_thread_helper_.get())
|
||||
ui_thread_helper_.reset(new UIThreadHelper());
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/cef_parser.h"
|
||||
#include "include/cef_request_context_handler.h"
|
||||
#include "include/cef_scheme.h"
|
||||
#include "include/cef_server.h"
|
||||
@@ -65,9 +66,12 @@ enum RequestTestMode {
|
||||
REQTEST_GET_REDIRECT_STOP,
|
||||
REQTEST_GET_REDIRECT_LOCATION,
|
||||
REQTEST_GET_REFERRER,
|
||||
REQTEST_GET_AUTH,
|
||||
REQTEST_POST,
|
||||
REQTEST_POST_FILE,
|
||||
REQTEST_POST_WITHPROGRESS,
|
||||
REQTEST_POST_REDIRECT,
|
||||
REQTEST_POST_REDIRECT_TOGET,
|
||||
REQTEST_HEAD,
|
||||
REQTEST_CACHE_WITH_CONTROL,
|
||||
REQTEST_CACHE_WITHOUT_CONTROL,
|
||||
@@ -142,6 +146,16 @@ struct RequestRunSettings {
|
||||
// If true the response cookie should be saved.
|
||||
bool expect_save_cookie = false;
|
||||
|
||||
// If true the test will begin by requiring Basic authentication and then
|
||||
// continue with the actual request. The UR_FLAG_ALLOW_STORED_CREDENTIALS
|
||||
// flag must be set on the request. When using the global request context
|
||||
// CefRequestContext::ClearHttpAuthCredentials should be called to avoid
|
||||
// leaking state across test runs. Authentication is only supported with
|
||||
// browser-initiated requests and the server backend.
|
||||
bool expect_authentication = false;
|
||||
std::string username;
|
||||
std::string password;
|
||||
|
||||
// If specified the test will begin with this redirect request and response.
|
||||
CefRefPtr<CefRequest> redirect_request;
|
||||
CefRefPtr<CefResponse> redirect_response;
|
||||
@@ -264,6 +278,24 @@ class RequestDataMap {
|
||||
RedirectDataMap redirect_data_map_;
|
||||
};
|
||||
|
||||
class TestCompletionCallback : public CefCompletionCallback {
|
||||
public:
|
||||
explicit TestCompletionCallback(const base::Closure& complete_callback)
|
||||
: complete_callback_(complete_callback) {
|
||||
EXPECT_FALSE(complete_callback_.is_null());
|
||||
}
|
||||
|
||||
void OnComplete() override {
|
||||
complete_callback_.Run();
|
||||
complete_callback_.Reset();
|
||||
}
|
||||
|
||||
private:
|
||||
base::Closure complete_callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(TestCompletionCallback);
|
||||
};
|
||||
|
||||
std::string GetRequestScheme(bool server_backend) {
|
||||
return server_backend ? kRequestSchemeServer : kRequestSchemeCustom;
|
||||
}
|
||||
@@ -470,6 +502,47 @@ void GetNormalResponse(const RequestRunSettings* settings,
|
||||
response->SetHeaderMap(headerMap);
|
||||
}
|
||||
|
||||
// Based on https://en.wikipedia.org/wiki/Basic_access_authentication#Protocol
|
||||
void GetAuthResponse(CefRefPtr<CefResponse> response) {
|
||||
response->SetStatus(401);
|
||||
response->SetStatusText("Unauthorized");
|
||||
response->SetMimeType("text/html");
|
||||
|
||||
CefResponse::HeaderMap headerMap;
|
||||
headerMap.insert(
|
||||
std::make_pair("WWW-Authenticate", "Basic realm=\"Test Realm\""));
|
||||
response->SetHeaderMap(headerMap);
|
||||
}
|
||||
|
||||
bool IsAuthorized(CefRefPtr<CefRequest> request,
|
||||
const std::string& username,
|
||||
const std::string& password) {
|
||||
const std::string& authHeader = request->GetHeaderByName("Authorization");
|
||||
if (authHeader.empty())
|
||||
return false;
|
||||
|
||||
if (authHeader.find("Basic ") == 0) {
|
||||
const std::string& base64 = authHeader.substr(6);
|
||||
CefRefPtr<CefBinaryValue> data = CefBase64Decode(base64);
|
||||
EXPECT_TRUE(data);
|
||||
if (!data) {
|
||||
LOG(ERROR) << "Failed to decode Authorization value: " << base64;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string decoded;
|
||||
decoded.resize(data->GetSize());
|
||||
data->GetData(&decoded[0], data->GetSize(), 0);
|
||||
|
||||
const std::string& expected = username + ":" + password;
|
||||
EXPECT_STREQ(expected.c_str(), decoded.c_str());
|
||||
return decoded == expected;
|
||||
}
|
||||
|
||||
LOG(ERROR) << "Unexpected Authorization value: " << authHeader;
|
||||
return false;
|
||||
}
|
||||
|
||||
// SCHEME HANDLER BACKEND
|
||||
|
||||
// Serves request responses.
|
||||
@@ -1007,6 +1080,14 @@ class RequestServerHandler : public CefServerHandler {
|
||||
CefRefPtr<CefRequest> request) {
|
||||
RequestDataMap::Entry entry = data_map_.Find(request->GetURL());
|
||||
if (entry.type == RequestDataMap::Entry::TYPE_NORMAL) {
|
||||
const bool needs_auth = entry.settings->expect_authentication &&
|
||||
!IsAuthorized(request, entry.settings->username,
|
||||
entry.settings->password);
|
||||
if (needs_auth) {
|
||||
HandleAuthRequest(server, connection_id, request);
|
||||
return;
|
||||
}
|
||||
|
||||
HandleNormalRequest(server, connection_id, request, entry.settings);
|
||||
} else if (entry.type == RequestDataMap::Entry::TYPE_REDIRECT) {
|
||||
HandleRedirectRequest(server, connection_id, request,
|
||||
@@ -1018,6 +1099,14 @@ class RequestServerHandler : public CefServerHandler {
|
||||
}
|
||||
}
|
||||
|
||||
void HandleAuthRequest(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
CefRefPtr<CefRequest> request) {
|
||||
CefRefPtr<CefResponse> response = CefResponse::Create();
|
||||
GetAuthResponse(response);
|
||||
SendResponse(server, connection_id, response, std::string());
|
||||
}
|
||||
|
||||
void HandleNormalRequest(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
CefRefPtr<CefRequest> request,
|
||||
@@ -1185,6 +1274,11 @@ class RequestClient : public CefURLRequestClient {
|
||||
const CefString& realm,
|
||||
const CefString& scheme,
|
||||
CefRefPtr<CefAuthCallback> callback) override {
|
||||
auth_credentials_ct_++;
|
||||
if (has_authentication_) {
|
||||
callback->Continue(username_, password_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1192,10 +1286,15 @@ class RequestClient : public CefURLRequestClient {
|
||||
const RequestCompleteCallback complete_callback_;
|
||||
|
||||
public:
|
||||
bool has_authentication_ = false;
|
||||
std::string username_;
|
||||
std::string password_;
|
||||
|
||||
int request_complete_ct_ = 0;
|
||||
int upload_progress_ct_ = 0;
|
||||
int download_progress_ct_ = 0;
|
||||
int download_data_ct_ = 0;
|
||||
int auth_credentials_ct_ = 0;
|
||||
|
||||
int64 upload_total_ = 0;
|
||||
int64 download_total_ = 0;
|
||||
@@ -1247,10 +1346,14 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||
REGISTER_TEST(REQTEST_GET_REDIRECT_LOCATION, SetupGetRedirectLocationTest,
|
||||
SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_GET_REFERRER, SetupGetReferrerTest, SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_GET_AUTH, SetupGetAuthTest, SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_POST, SetupPostTest, SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_POST_FILE, SetupPostFileTest, SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_POST_WITHPROGRESS, SetupPostWithProgressTest,
|
||||
SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_POST_REDIRECT, SetupPostRedirectTest, SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_POST_REDIRECT_TOGET, SetupPostRedirectToGetTest,
|
||||
SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_HEAD, SetupHeadTest, SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_CACHE_WITH_CONTROL, SetupCacheWithControlTest,
|
||||
MultipleRunTest);
|
||||
@@ -1523,6 +1626,28 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||
complete_callback.Run();
|
||||
}
|
||||
|
||||
void SetupGetAuthTest(const base::Closure& complete_callback) {
|
||||
// Start with the normal get test.
|
||||
SetupGetTestShared();
|
||||
|
||||
// Require Basic authentication.
|
||||
settings_.expect_authentication = true;
|
||||
settings_.username = "user";
|
||||
settings_.password = "pass";
|
||||
|
||||
// This flag is required to support credentials, which means we'll also get
|
||||
// the cookies.
|
||||
settings_.request->SetFlags(UR_FLAG_ALLOW_STORED_CREDENTIALS);
|
||||
settings_.expect_save_cookie = true;
|
||||
settings_.expect_send_cookie = true;
|
||||
|
||||
// The authentication request will come first, then the actual request.
|
||||
settings_.expected_receive_count = 2;
|
||||
settings_.expected_send_count = 2;
|
||||
|
||||
complete_callback.Run();
|
||||
}
|
||||
|
||||
void SetupPostTestShared() {
|
||||
settings_.request = CefRequest::Create();
|
||||
settings_.request->SetURL(GetTestURL("PostTest.html"));
|
||||
@@ -1589,6 +1714,58 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||
complete_callback.Run();
|
||||
}
|
||||
|
||||
void SetupPostRedirectTest(const base::Closure& complete_callback) {
|
||||
// Start with the normal post test.
|
||||
SetupPostTestShared();
|
||||
|
||||
// Add a redirect request.
|
||||
settings_.redirect_request = CefRequest::Create();
|
||||
settings_.redirect_request->SetURL(GetTestURL("redirect.html"));
|
||||
settings_.redirect_request->SetMethod("POST");
|
||||
SetUploadData(settings_.redirect_request, "the_post_data");
|
||||
|
||||
settings_.redirect_response = CefResponse::Create();
|
||||
settings_.redirect_response->SetMimeType("text/html");
|
||||
// Only 307 is supported for redirecting the same method and post data.
|
||||
settings_.redirect_response->SetStatus(307);
|
||||
settings_.redirect_response->SetStatusText("Found");
|
||||
|
||||
CefResponse::HeaderMap headerMap;
|
||||
headerMap.insert(std::make_pair("Location", settings_.request->GetURL()));
|
||||
settings_.redirect_response->SetHeaderMap(headerMap);
|
||||
|
||||
complete_callback.Run();
|
||||
}
|
||||
|
||||
void SetupPostRedirectToGetTest(const base::Closure& complete_callback) {
|
||||
// Start with the normal post test.
|
||||
SetupPostTestShared();
|
||||
|
||||
// The expected result after redirect is a GET request without POST data.
|
||||
settings_.request = CefRequest::Create();
|
||||
settings_.request->SetURL(GetTestURL("PostTest.html"));
|
||||
settings_.request->SetMethod("GET");
|
||||
|
||||
// Add a redirect request.
|
||||
settings_.redirect_request = CefRequest::Create();
|
||||
settings_.redirect_request->SetURL(GetTestURL("redirect.html"));
|
||||
settings_.redirect_request->SetMethod("POST");
|
||||
SetUploadData(settings_.redirect_request, "the_post_data");
|
||||
|
||||
settings_.redirect_response = CefResponse::Create();
|
||||
settings_.redirect_response->SetMimeType("text/html");
|
||||
// Redirect codes other than 307 will cause conversion to GET and removal
|
||||
// of POST data.
|
||||
settings_.redirect_response->SetStatus(302);
|
||||
settings_.redirect_response->SetStatusText("Found");
|
||||
|
||||
CefResponse::HeaderMap headerMap;
|
||||
headerMap.insert(std::make_pair("Location", settings_.request->GetURL()));
|
||||
settings_.redirect_response->SetHeaderMap(headerMap);
|
||||
|
||||
complete_callback.Run();
|
||||
}
|
||||
|
||||
void SetupHeadTest(const base::Closure& complete_callback) {
|
||||
settings_.request = CefRequest::Create();
|
||||
settings_.request->SetURL(GetTestURL("HeadTest.html"));
|
||||
@@ -1994,6 +2171,16 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||
EXPECT_TRUE(request.get());
|
||||
|
||||
CefRefPtr<RequestClient> client = new RequestClient(complete_callback);
|
||||
|
||||
// Delegation to CefRequestHandler::GetAuthCredentials is only supported
|
||||
// with NetworkService.
|
||||
if ((!IsNetworkServiceEnabled() || !use_frame_method_) &&
|
||||
settings_.expect_authentication) {
|
||||
client->has_authentication_ = true;
|
||||
client->username_ = settings_.username;
|
||||
client->password_ = settings_.password;
|
||||
}
|
||||
|
||||
if (use_frame_method_) {
|
||||
EXPECT_TRUE(frame_);
|
||||
frame_->CreateURLRequest(request, client.get());
|
||||
@@ -2064,6 +2251,12 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||
EXPECT_EQ(0, client->download_data_ct_);
|
||||
EXPECT_TRUE(client->download_data_.empty());
|
||||
}
|
||||
|
||||
if (settings_.expect_authentication) {
|
||||
EXPECT_EQ(1, client->auth_credentials_ct_);
|
||||
} else {
|
||||
EXPECT_EQ(0, client->auth_credentials_ct_);
|
||||
}
|
||||
}
|
||||
|
||||
// Run a test with a single request.
|
||||
@@ -2471,7 +2664,7 @@ class RequestTestHandler : public TestHandler {
|
||||
// Continue the test once supported schemes has been set.
|
||||
request_context->GetCookieManager(NULL)->SetSupportedSchemes(
|
||||
supported_schemes, true,
|
||||
new SupportedSchemesCompletionCallback(
|
||||
new TestCompletionCallback(
|
||||
base::Bind(&RequestTestHandler::PreSetupComplete, this)));
|
||||
} else {
|
||||
PreSetupComplete();
|
||||
@@ -2544,6 +2737,25 @@ class RequestTestHandler : public TestHandler {
|
||||
return TestHandler::OnBeforeResourceLoad(browser, frame, request, callback);
|
||||
}
|
||||
|
||||
bool GetAuthCredentials(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& origin_url,
|
||||
bool isProxy,
|
||||
const CefString& host,
|
||||
int port,
|
||||
const CefString& realm,
|
||||
const CefString& scheme,
|
||||
CefRefPtr<CefAuthCallback> callback) override {
|
||||
EXPECT_TRUE(test_in_browser_);
|
||||
EXPECT_TRUE(test_frame_method_);
|
||||
auth_credentials_ct_++;
|
||||
if (test_runner_->settings_.expect_authentication) {
|
||||
callback->Continue(test_runner_->settings_.username,
|
||||
test_runner_->settings_.password);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int httpStatusCode) override {
|
||||
@@ -2654,7 +2866,21 @@ class RequestTestHandler : public TestHandler {
|
||||
|
||||
// Shut down the browser side of the test.
|
||||
test_runner_->ShutdownTest(
|
||||
base::Bind(&RequestTestHandler::DestroyTest, this));
|
||||
base::Bind(&RequestTestHandler::MaybeClearAuthCredentials, this));
|
||||
}
|
||||
|
||||
void MaybeClearAuthCredentials() {
|
||||
if (test_runner_->settings_.expect_authentication &&
|
||||
context_mode_ == CONTEXT_GLOBAL) {
|
||||
// Clear the HTTP authentication cache to avoid leaking state between
|
||||
// test runs when using the global request context.
|
||||
test_runner_->GetRequestContext()->ClearHttpAuthCredentials(
|
||||
new TestCompletionCallback(
|
||||
base::Bind(&RequestTestHandler::DestroyTest, this)));
|
||||
return;
|
||||
}
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void DestroyTest() override {
|
||||
@@ -2671,6 +2897,16 @@ class RequestTestHandler : public TestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// CefRequestHandler::GetAuthCredentials should be called after
|
||||
// CefURLRequestClient::GetAuthCredentials when the request has an
|
||||
// associated frame.
|
||||
if (IsNetworkServiceEnabled() && test_in_browser_ && test_frame_method_ &&
|
||||
test_runner_->settings_.expect_authentication) {
|
||||
EXPECT_EQ(1, auth_credentials_ct_);
|
||||
} else {
|
||||
EXPECT_EQ(0, auth_credentials_ct_);
|
||||
}
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
|
||||
// For non-global contexts OnTestComplete() will be called when the
|
||||
@@ -2740,26 +2976,6 @@ class RequestTestHandler : public TestHandler {
|
||||
IMPLEMENT_REFCOUNTING(RequestContextHandler);
|
||||
};
|
||||
|
||||
// Continue the rest once supported schemes have been set.
|
||||
class SupportedSchemesCompletionCallback : public CefCompletionCallback {
|
||||
public:
|
||||
explicit SupportedSchemesCompletionCallback(
|
||||
const base::Closure& complete_callback)
|
||||
: complete_callback_(complete_callback) {
|
||||
EXPECT_FALSE(complete_callback_.is_null());
|
||||
}
|
||||
|
||||
void OnComplete() override {
|
||||
complete_callback_.Run();
|
||||
complete_callback_.Reset();
|
||||
}
|
||||
|
||||
private:
|
||||
base::Closure complete_callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(SupportedSchemesCompletionCallback);
|
||||
};
|
||||
|
||||
const RequestTestMode test_mode_;
|
||||
const ContextTestMode context_mode_;
|
||||
const bool test_in_browser_;
|
||||
@@ -2782,6 +2998,7 @@ class RequestTestHandler : public TestHandler {
|
||||
TrackCallback got_message_;
|
||||
TrackCallback got_success_;
|
||||
|
||||
int auth_credentials_ct_ = 0;
|
||||
TrackCallback got_on_test_complete_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(RequestTestHandler);
|
||||
@@ -2873,6 +3090,10 @@ void RegisterURLRequestCustomSchemes(
|
||||
test_server_backend, test_frame_method) \
|
||||
REQ_TEST(BrowserPOSTWithProgress##suffix, REQTEST_POST_WITHPROGRESS, \
|
||||
context_mode, true, test_server_backend, test_frame_method) \
|
||||
REQ_TEST(BrowserPOSTRedirect##suffix, REQTEST_POST_REDIRECT, context_mode, \
|
||||
true, test_server_backend, test_frame_method) \
|
||||
REQ_TEST(BrowserPOSTRedirectToGET##suffix, REQTEST_POST_REDIRECT_TOGET, \
|
||||
context_mode, true, test_server_backend, test_frame_method) \
|
||||
REQ_TEST(BrowserHEAD##suffix, REQTEST_HEAD, context_mode, true, \
|
||||
test_server_backend, test_frame_method) \
|
||||
REQ_TEST(RendererGET##suffix, REQTEST_GET, context_mode, false, \
|
||||
@@ -2893,6 +3114,10 @@ void RegisterURLRequestCustomSchemes(
|
||||
test_server_backend, test_frame_method) \
|
||||
REQ_TEST(RendererPOSTWithProgress##suffix, REQTEST_POST_WITHPROGRESS, \
|
||||
context_mode, false, test_server_backend, test_frame_method) \
|
||||
REQ_TEST(RendererPOSTRedirect##suffix, REQTEST_POST_REDIRECT, context_mode, \
|
||||
false, test_server_backend, test_frame_method) \
|
||||
REQ_TEST(RendererPOSTRedirectToGET##suffix, REQTEST_POST_REDIRECT_TOGET, \
|
||||
context_mode, false, test_server_backend, test_frame_method) \
|
||||
REQ_TEST(RendererHEAD##suffix, REQTEST_HEAD, context_mode, false, \
|
||||
test_server_backend, test_frame_method)
|
||||
|
||||
@@ -2940,7 +3165,7 @@ REQ_TEST_SET(WithFrame, true)
|
||||
|
||||
REQ_TEST_FRAME_SET()
|
||||
|
||||
// Cache tests can only be run with the server backend.
|
||||
// Cache and authentication tests can only be run with the server backend.
|
||||
#define REQ_TEST_CACHE_SET_EX(suffix, context_mode, test_frame_method) \
|
||||
REQ_TEST(BrowserGETCacheWithControl##suffix, REQTEST_CACHE_WITH_CONTROL, \
|
||||
context_mode, true, true, test_frame_method) \
|
||||
@@ -2972,6 +3197,8 @@ REQ_TEST_FRAME_SET()
|
||||
REQ_TEST(RendererGETCacheWithoutControl##suffix, \
|
||||
REQTEST_CACHE_WITHOUT_CONTROL, context_mode, false, true, \
|
||||
test_frame_method) \
|
||||
REQ_TEST(BrowserGETAuth##suffix, REQTEST_GET_AUTH, context_mode, true, true, \
|
||||
test_frame_method) \
|
||||
REQ_TEST(RendererGETCacheSkipFlag##suffix, REQTEST_CACHE_SKIP_FLAG, \
|
||||
context_mode, false, true, test_frame_method) \
|
||||
REQ_TEST(RendererGETCacheSkipHeader##suffix, REQTEST_CACHE_SKIP_HEADER, \
|
||||
|
@@ -36,7 +36,8 @@ def RunAction(dir, command):
|
||||
command[0] = sys.executable
|
||||
|
||||
try:
|
||||
gclient_utils.CheckCallAndFilterAndHeader(command, cwd=dir, always=True)
|
||||
gclient_utils.CheckCallAndFilter(
|
||||
command, cwd=dir, always_show_header=True, print_stdout=True)
|
||||
except gclient_utils.Error, e:
|
||||
# Use a discrete exit status code of 2 to indicate that a hook action
|
||||
# failed. Users of this script may wish to treat hook action failures
|
||||
|
@@ -440,13 +440,17 @@ def GetConfigArgsSandbox(platform, args, is_debug, cpu):
|
||||
'use_allocator_shim': False,
|
||||
|
||||
# Avoid /LTCG linker warnings and generate smaller lib files.
|
||||
'is_official_build': False
|
||||
'is_official_build': False,
|
||||
}
|
||||
|
||||
if is_debug:
|
||||
# Enable iterator debugging (_ITERATOR_DEBUG_LEVEL=2).
|
||||
add_args['enable_iterator_debugging'] = True
|
||||
|
||||
if platform == 'windows':
|
||||
# Avoid Debug build linker errors caused by custom libc++.
|
||||
add_args['use_custom_libcxx'] = False
|
||||
|
||||
result = MergeDicts(args, add_args, {
|
||||
'is_debug': is_debug,
|
||||
'target_cpu': cpu,
|
||||
|
Reference in New Issue
Block a user