Compare commits

...

31 Commits
4280 ... 3770

Author SHA1 Message Date
Riku Palomäki
16a67c4507 Fix gclient_util after depot_tools changes (fixes issue #2736) 2019-08-05 14:07:23 -04:00
Dmitry Azaraev
0ebdb473b1 Fix missing marshaling for CefSettings::root_cache_path member (fixes issue #2740) 2019-08-05 14:07:16 -04:00
Marshall Greenblatt
c81164e2ce Fix crash on DevTools remote debugging of WebWorkers (fixes issue #2605) 2019-07-26 09:49:58 -04:00
Marshall Greenblatt
e0be1d916d Fix missing cookie after redirect response with filter (fixes issue #2689, see issue #2622) 2019-07-25 17:02:24 -04:00
Marshall Greenblatt
d9915d728f Fix option for persisting session cookies (fixes issue #2720, see issue #2622) 2019-07-25 15:29:24 -04:00
Marshall Greenblatt
5656baa197 Fix C compile error due to unintentional C++ include (fixes issue #2728) 2019-07-25 13:42:31 -04:00
Marshall Greenblatt
fed0e1826a macOS: Fix alert dialog display (fixes issue #2726) 2019-07-25 12:36:50 -04:00
Dmitry Azaraev
a9c022bd11 Fix typo in documentation for CefResourceHandler::Skip 2019-07-25 12:36:42 -04:00
Marshall Greenblatt
84fed5dc0e Fix PDF load in <embed> and <object> tags (fixes issue #2727, see issue #2622) 2019-07-24 20:29:15 -04:00
Marshall Greenblatt
b34af23449 Fix crash on shutdown with PDF viewer and multi-threaded message loop (fixes issue #2709, see issue #2622)
Requests from the PDF viewer are not associated with a CefBrowser. Consequently,
the InterceptedRequestHandler for those requests will register as an observer of
CefContext destruction. When the browser is closed the InterceptedRequestHandler
is destroyed and an async task is posted to remove/delete the observer on the UI
thread. If CefShutdown is then called the task may execute after shutdown has
started, in which case CONTEXT_STATE_VALID() will return false. We still need to
remove the observer in this case to avoid a use-after-free in
FinishShutdownOnUIThread.
2019-07-23 15:29:46 -04:00
Dmitry Azaraev
94d09f80e7 Fix typo in documentation for cef_settings_t::cache_path. 2019-07-23 15:29:40 -04:00
Marshall Greenblatt
1c3d34bc32 Fix crash when extensions are disabled (fixes issue #2708, see issue #2622) 2019-07-23 12:22:46 -04:00
Riku Palomäki
4210896724 Fix dangling pointers in CefAudioMirrorDestination (fixes issue #2713). 2019-07-16 17:45:20 -04:00
Isaac Devine
1931b9c969 Fix race with multi-threaded message loop (fixes issue #2668).
Remove the local thread object in favor of setting the ui_thread_ field
directly. This avoids the race between ui_thread_.swap(thread) and
CefUIThread::InitializeBrowserRunner.
2019-07-16 17:45:10 -04:00
Alexander Guettler
fdd887b677 Fix dangling pointers in CefScopedArgArray (fixes issue #2704). 2019-07-16 17:44:59 -04:00
Masako Toda
849a6e64dc Fix redirect of requests with credentials mode 'include' (fixes issue #2699, see issue #2622).
Modifying the URL in OnBeforeResourceLoad causes an internal redirect response.
In cases where the request is cross-origin and credentials mode is 'include'
the redirect response must include the "Access-Control-Allow-Credentials"
header, otherwise the request will be blocked.
2019-07-16 21:42:04 +00:00
Marshall Greenblatt
5e9ca096e0 Add support for GetAuthCredentials (fixes issue #2718, see issue #2622).
When NetworkService is enabled requests created using CefFrame::CreateURLRequest
will call CefRequestHandler::GetAuthCredentials for the associated browser after
calling CefURLRequestClient::GetAuthCredentials if that call returns false.
2019-07-16 13:30:46 -04:00
Marshall Greenblatt
3b211d4bf5 Remove POST data after redirect to GET (see issue #2707, see issue #2622).
For 303 redirects all request methods except HEAD are converted to GET as per
the latest http draft. For historical reasons the draft also allows POST
requests to be converted to GETs when following 301/302 redirects. Most major
browsers do this and so shall we. When a request is converted to GET any POST
data should also be removed.

Use 307 redirects instead if you want the request to be repeated using the same
method and POST data.
2019-07-11 16:43:39 -04:00
Marshall Greenblatt
2c92fcd3cd Fix cross-origin redirect from OnBeforeResourceLoad (fixes issue #2695, see issue #2622).
Modifying the URL in OnBeforeResourceLoad causes an internal redirect response.
In cases where the request is cross-origin (containing a non-null "Origin"
header) the redirect response must include the "Access-Control-Allow-Origin"
header, otherwise the request will be blocked.

This change also fixes a problem where existing request headers would be
discarded if the request was modified in OnBeforeResourceLoad.
2019-06-25 16:56:45 -04:00
Marshall Greenblatt
d792e5fddf Fix loading of http(s) sub-resources from custom scheme initiator (fixes issue #2685, see issue #2622).
Determine external request status based on the current URL instead of the
request initiator.
2019-06-25 11:04:15 -04:00
Marshall Greenblatt
f50b3c2d43 Fix CefFrame::GetIdentifier value in the render process (fixes issue #2687, see issue #2498) 2019-06-19 16:57:17 +02:00
Marshall Greenblatt
6ad1dea9fa Fix crash if a pending request is continued after deletion (see issue #2622).
This is a speculative fix for a crash where the pending ResourceRequest appears
to be invalid after the request is continued from SetInitialized.
2019-06-19 16:01:58 +02:00
Marshall Greenblatt
542c867901 Update to Chromium version 75.0.3770.100 2019-06-19 14:06:11 +02:00
Marshall Greenblatt
5da93a11c8 Fix crashes when a request is aborted during initialization (see issue #2622).
Initialization of request objects requires asynchronous hops between the UI and
IO threads. In some cases the browser may be destroyed, the mojo connection may
be aborted, or the ProxyURLLoaderFactory object may be deleted while
initialization is still in progress. This change fixes crashes and adds unit
tests that try to reproduce these conditions.

To test: Run `ceftests --gtest_repeat=50
              --gtest_filter=ResourceRequestHandlerTest.Basic*Abort*`
2019-06-18 16:31:53 +02:00
Marshall Greenblatt
19229b6d38 Fix crash in ProxyURLLoaderFactory::MaybeDestroySelf (see issue #2622).
This is a speculative fix for a crash where |on_disconnect_| appears to be null
in ProxyURLLoaderFactory::MaybeDestroySelf. The hypothesis here is that
OnURLLoaderClientError is being called while the proxy object is still in-flight
to ResourceContextData::AddProxy (e.g. before SetDisconnectCallback has been
called for the proxy object). Additonally, this change protects against
MaybeDestroySelf attempting to execute |on_disconnect_| multiple times.
2019-06-14 19:01:10 +02:00
Marshall Greenblatt
90ecd35aff Fix inclusion of cookies with restarted requests (fixes issue #2672, see issue #2622) 2019-06-12 17:21:12 +02:00
Marshall Greenblatt
d3b54cbec7 macOS: Don't disable custom libc++ for cef_sandbox build (see issue #2677) 2019-06-12 12:00:50 +02:00
Marshall Greenblatt
3f2a3b1c67 Use FrameTreeNodeId to find delay loaded iframes for OnBeforeBrowse (fixes issue #2675, see issue #2498) 2019-06-12 11:53:14 +02:00
Marshall Greenblatt
699a922bd4 Windows: cmake: Add newer VS versions 2019-06-11 18:08:48 +02:00
Marshall Greenblatt
3b2e46543b Windows: Disable custom libc++ for cef_sandbox build (fixes issue #2677) 2019-06-11 18:08:26 +02:00
Marshall Greenblatt
b5e74dd297 Update to Chromium version 75.0.3770.80 2019-06-08 23:06:25 +02:00
83 changed files with 2081 additions and 484 deletions

View File

@@ -407,6 +407,8 @@ static_library("libcef_static") {
"libcef/browser/net_service/cookie_helper.h", "libcef/browser/net_service/cookie_helper.h",
"libcef/browser/net_service/cookie_manager_impl.cc", "libcef/browser/net_service/cookie_manager_impl.cc",
"libcef/browser/net_service/cookie_manager_impl.h", "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.cc",
"libcef/browser/net_service/proxy_url_loader_factory.h", "libcef/browser/net_service/proxy_url_loader_factory.h",
"libcef/browser/net_service/resource_handler_wrapper.cc", "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.cc",
"libcef/renderer/render_urlrequest_impl.h", "libcef/renderer/render_urlrequest_impl.h",
"libcef/renderer/thread_util.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.cc",
"libcef/renderer/v8_impl.h", "libcef/renderer/v8_impl.h",
"libcef/utility/content_utility_client.cc", "libcef/utility/content_utility_client.cc",

View File

@@ -7,5 +7,5 @@
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding # https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
{ {
'chromium_checkout': 'refs/tags/75.0.3770.0' 'chromium_checkout': 'refs/tags/75.0.3770.100'
} }

View File

@@ -374,6 +374,9 @@ if(OS_WINDOWS)
1913 # VS2017 version 15.6 1913 # VS2017 version 15.6
1914 # VS2017 version 15.7 1914 # VS2017 version 15.7
1915 # VS2017 version 15.8 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) list(FIND supported_msvc_versions ${MSVC_VERSION} _index)
if (${_index} EQUAL -1) if (${_index} EQUAL -1)

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=59376c6298df4489ecc34f3509a8d0e77e9d97f7$ // $hash=fdfce3e4e33a1d4e1170497d2a476f0837994060$
// //
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_CONTEXT_CAPI_H_ #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_request_context_t* self,
struct _cef_completion_callback_t* callback); 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 // 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 // only recommended if you have released all other CEF objects but don't yet

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=fce8beb9d3e8709a512077681455cb4ef92ef76d$ // $hash=d9c4e8591ee39bd9d8c1714c0ca2417a7d2a38ea$
// //
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_HANDLER_CAPI_H_ #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. // 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 // |origin_url| is the origin making this authentication request. |isProxy|
// hostname and |port| contains the port number. |realm| is the realm of the // indicates whether the host is a proxy server. |host| contains the hostname
// challenge and may be NULL. |scheme| is the authentication scheme used, such // and |port| contains the port number. |realm| is the realm of the challenge
// as "basic" or "digest", and will be NULL if the source of the request is an // 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 // 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 // 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 // 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)( int(CEF_CALLBACK* get_auth_credentials)(
struct _cef_request_handler_t* self, struct _cef_request_handler_t* self,
struct _cef_browser_t* browser, struct _cef_browser_t* browser,
struct _cef_frame_t* frame, const cef_string_t* origin_url,
int isProxy, int isProxy,
const cef_string_t* host, const cef_string_t* host,
int port, int port,

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=f94ec1ef3928002394720160d526ed157282cc7a$ // $hash=8c6ffeab9c9183cc5f77929839643767ce5c5c2f$
// //
#ifndef CEF_INCLUDE_CAPI_CEF_RESOURCE_HANDLER_CAPI_H_ #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 // 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 // |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). // set |bytes_skipped| to the number of bytes skipped and return true (1). To
// To read the data at a later time set |bytes_skipped| to 0, return true (1) // read the data at a later time set |bytes_skipped| to 0, return true (1) and
// and execute |callback| when the data is available. To indicate failure set // 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 // |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. // function will be called in sequence but not from a dedicated thread.
/// ///

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=af8ddd4d2d19e5b64d0a40778cb3c62fd5f1d8c9$ // $hash=adb3ca1e315a28efed7b2305c8aceb9c5eafdc66$
// //
#ifndef CEF_INCLUDE_CAPI_CEF_RESOURCE_REQUEST_HANDLER_CAPI_H_ #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_resource_handler_capi.h"
#include "include/capi/cef_response_capi.h" #include "include/capi/cef_response_capi.h"
#include "include/capi/cef_response_filter_capi.h" #include "include/capi/cef_response_filter_capi.h"
#include "include/internal/cef_types_wrappers.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=3d31b2d1bad50deeb68a5e6318344024c2f3f5be$ // $hash=77ac3a2aaea32b649185a58e4c2bbb13b7fe0540$
// //
#ifndef CEF_INCLUDE_CAPI_CEF_URLREQUEST_CAPI_H_ #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 // |isProxy| indicates whether the host is a proxy server. |host| contains the
// hostname and |port| contains the port number. Return true (1) to continue // hostname and |port| contains the port number. Return true (1) to continue
// the request and call cef_auth_callback_t::cont() when the authentication // the request and call cef_auth_callback_t::cont() when the authentication
// information is available. Return false (0) to cancel the request. This // information is available. If the request has an associated browser/frame
// function will only be called for requests initiated from the browser // then returning false (0) will result in a call to GetAuthCredentials on the
// process. // 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)( int(CEF_CALLBACK* get_auth_credentials)(
struct _cef_urlrequest_client_t* self, struct _cef_urlrequest_client_t* self,

View File

@@ -34,7 +34,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=0bc0d1faa22392b4245dc6eaf56337e7847a1900$ // $hash=467550bc7fb025b069edb9dc65988d8cb9c56fd2$
// //
#ifndef CEF_INCLUDE_API_HASH_H_ #ifndef CEF_INCLUDE_API_HASH_H_
@@ -47,13 +47,13 @@
// way that may cause binary incompatibility with other builds. The universal // way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash // hash value will change if any platform is affected whereas the platform hash
// values will change only if that particular platform is affected. // 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) #if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "afb8ea794d1bb0f56ba5ce1718a16e5dfd64229e" #define CEF_API_HASH_PLATFORM "37fc3765fe0ef3ef7542e6568e5689b3575968a8"
#elif defined(OS_MACOSX) #elif defined(OS_MACOSX)
#define CEF_API_HASH_PLATFORM "e3a279cf087095495c08fd9fa88daef5dbafff3a" #define CEF_API_HASH_PLATFORM "dc61db096a4b62365b16d450fe4f898a9552da6a"
#elif defined(OS_LINUX) #elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "d25833941c670d82cff0aa0ccf47b557d6813634" #define CEF_API_HASH_PLATFORM "059d7243ae34aa5503c96a21ce24a673dddf4e64"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -249,6 +249,15 @@ class CefRequestContext : public virtual CefBaseRefCounted {
virtual void ClearCertificateExceptions( virtual void ClearCertificateExceptions(
CefRefPtr<CefCompletionCallback> callback) = 0; 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. // Clears all active and idle connections that Chromium currently has.
// This is only recommended if you have released all other CEF objects but // This is only recommended if you have released all other CEF objects but

View File

@@ -150,18 +150,19 @@ class CefRequestHandler : public virtual CefBaseRefCounted {
/// ///
// Called on the IO thread when the browser needs credentials from the user. // 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 // |origin_url| is the origin making this authentication request. |isProxy|
// hostname and |port| contains the port number. |realm| is the realm of the // indicates whether the host is a proxy server. |host| contains the hostname
// challenge and may be empty. |scheme| is the authentication scheme used, // and |port| contains the port number. |realm| is the realm of the challenge
// such as "basic" or "digest", and will be empty if the source of the request // and may be empty. |scheme| is the authentication scheme used, such as
// is an FTP server. Return true to continue the request and call // "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 // CefAuthCallback::Continue() either in this method or at a later time when
// the authentication information is available. Return false to cancel the // the authentication information is available. Return false to cancel the
// request immediately. // request immediately.
/// ///
/*--cef(optional_param=realm,optional_param=scheme)--*/ /*--cef(optional_param=realm,optional_param=scheme)--*/
virtual bool GetAuthCredentials(CefRefPtr<CefBrowser> browser, virtual bool GetAuthCredentials(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, const CefString& origin_url,
bool isProxy, bool isProxy,
const CefString& host, const CefString& host,
int port, int port,

View File

@@ -142,7 +142,7 @@ class CefResourceHandler : public virtual CefBaseRefCounted {
/// ///
// Skip response data when requested by a Range header. Skip over and discard // 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 // |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 // 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 // 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 // |bytes_skipped| to < 0 (e.g. -2 for ERR_FAILED) and return false. This

View File

@@ -46,7 +46,6 @@
#include "include/cef_resource_handler.h" #include "include/cef_resource_handler.h"
#include "include/cef_response.h" #include "include/cef_response.h"
#include "include/cef_response_filter.h" #include "include/cef_response_filter.h"
#include "include/internal/cef_types_wrappers.h"
class CefCookieAccessFilter; class CefCookieAccessFilter;

View File

@@ -186,8 +186,11 @@ class CefURLRequestClient : public virtual CefBaseRefCounted {
// |isProxy| indicates whether the host is a proxy server. |host| contains the // |isProxy| indicates whether the host is a proxy server. |host| contains the
// hostname and |port| contains the port number. Return true to continue the // hostname and |port| contains the port number. Return true to continue the
// request and call CefAuthCallback::Continue() when the authentication // request and call CefAuthCallback::Continue() when the authentication
// information is available. Return false to cancel the request. This method // information is available. If the request has an associated browser/frame
// will only be called for requests initiated from the browser process. // 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)--*/ /*--cef(optional_param=realm)--*/
virtual bool GetAuthCredentials(bool isProxy, virtual bool GetAuthCredentials(bool isProxy,

View File

@@ -220,7 +220,7 @@ typedef struct _cef_settings_t {
/// ///
// The location where data for the global browser cache will be stored on // 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 // 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 // "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 // persisted to disk. HTML5 databases such as localStorage will only persist

View File

@@ -544,6 +544,7 @@ struct CefSettingsTraits {
cef_string_clear(&s->browser_subprocess_path); cef_string_clear(&s->browser_subprocess_path);
cef_string_clear(&s->framework_dir_path); cef_string_clear(&s->framework_dir_path);
cef_string_clear(&s->cache_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_data_path);
cef_string_clear(&s->user_agent); cef_string_clear(&s->user_agent);
cef_string_clear(&s->product_version); cef_string_clear(&s->product_version);
@@ -572,6 +573,8 @@ struct CefSettingsTraits {
cef_string_set(src->cache_path.str, src->cache_path.length, cef_string_set(src->cache_path.str, src->cache_path.length,
&target->cache_path, copy); &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, cef_string_set(src->user_data_path.str, src->user_data_path.length,
&target->user_data_path, copy); &target->user_data_path, copy);
target->persist_session_cookies = src->persist_session_cookies; target->persist_session_cookies = src->persist_session_cookies;

View File

@@ -97,8 +97,9 @@ class CefScopedArgArray {
CefScopedArgArray(int argc, char* argv[]) { CefScopedArgArray(int argc, char* argv[]) {
// argv should have (argc + 1) elements, the last one always being NULL. // argv should have (argc + 1) elements, the last one always being NULL.
array_ = new char*[argc + 1]; array_ = new char*[argc + 1];
values_.resize(argc);
for (int i = 0; i < argc; ++i) { 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_[i] = const_cast<char*>(values_[i].c_str());
} }
array_[argc] = NULL; array_[argc] = NULL;

View File

@@ -29,7 +29,7 @@ void CefAudioMirrorDestination::Start() {
FROM_HERE, {content::BrowserThread::IO}, FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&content::AudioMirroringManager::StartMirroring, base::BindOnce(&content::AudioMirroringManager::StartMirroring,
base::Unretained(mirroring_manager_), base::Unretained(mirroring_manager_),
base::Unretained(this))); base::RetainedRef(this)));
} }
void CefAudioMirrorDestination::Stop() { void CefAudioMirrorDestination::Stop() {
@@ -39,7 +39,7 @@ void CefAudioMirrorDestination::Stop() {
FROM_HERE, {content::BrowserThread::IO}, FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&content::AudioMirroringManager::StopMirroring, base::BindOnce(&content::AudioMirroringManager::StopMirroring,
base::Unretained(mirroring_manager_), base::Unretained(mirroring_manager_),
base::Unretained(this))); base::RetainedRef(this)));
} }
// Asynchronously query whether this MirroringDestination wants to consume // Asynchronously query whether this MirroringDestination wants to consume
@@ -56,7 +56,7 @@ void CefAudioMirrorDestination::QueryForMatches(
base::PostTaskWithTraits( base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI}, FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&CefAudioMirrorDestination::QueryForMatchesOnUIThread, base::BindOnce(&CefAudioMirrorDestination::QueryForMatchesOnUIThread,
base::Unretained(this), candidates, base::RetainedRef(this), candidates,
media::BindToCurrentLoop(std::move(results_callback)))); media::BindToCurrentLoop(std::move(results_callback))));
} }
@@ -99,7 +99,7 @@ media::AudioPushSink* CefAudioMirrorDestination::AddPushInput(
return new CefAudioPushSink( return new CefAudioPushSink(
params, browser_, cef_audio_handler_, params, browser_, cef_audio_handler_,
base::Bind(&CefAudioMirrorDestination::ReleasePushInput, base::Bind(&CefAudioMirrorDestination::ReleasePushInput,
base::Unretained(this))); base::RetainedRef(this)));
} }
void CefAudioMirrorDestination::ReleasePushInput(CefAudioPushSink* sink) { void CefAudioMirrorDestination::ReleasePushInput(CefAudioPushSink* sink) {

View File

@@ -22,14 +22,13 @@ class CefAudioPushSink;
class CefBrowserHostImpl; class CefBrowserHostImpl;
class CefAudioMirrorDestination class CefAudioMirrorDestination
: public content::AudioMirroringManager::MirroringDestination { : public base::RefCountedThreadSafe<CefAudioMirrorDestination>,
public content::AudioMirroringManager::MirroringDestination {
public: public:
CefAudioMirrorDestination(CefRefPtr<CefBrowserHostImpl> browser, CefAudioMirrorDestination(CefRefPtr<CefBrowserHostImpl> browser,
CefRefPtr<CefAudioHandler> cef_audio_handler, CefRefPtr<CefAudioHandler> cef_audio_handler,
content::AudioMirroringManager* mirroring_manager); content::AudioMirroringManager* mirroring_manager);
virtual ~CefAudioMirrorDestination() = default;
// Start mirroring. This needs to be triggered on the IO thread. // Start mirroring. This needs to be triggered on the IO thread.
void Start(); void Start();
@@ -65,6 +64,10 @@ class CefAudioMirrorDestination
const media::AudioParameters& params) override; const media::AudioParameters& params) override;
private: private:
friend class base::RefCountedThreadSafe<CefAudioMirrorDestination>;
~CefAudioMirrorDestination() override = default;
void QueryForMatchesOnUIThread( void QueryForMatchesOnUIThread(
const std::set<content::GlobalFrameRoutingId>& candidates, const std::set<content::GlobalFrameRoutingId>& candidates,
MatchesCallback results_callback); MatchesCallback results_callback);

View File

@@ -287,6 +287,10 @@ void CefBrowserContext::Initialize() {
CefString(&context->settings().accept_language_list); CefString(&context->settings().accept_language_list);
} }
if (!!settings_.persist_session_cookies) {
set_should_persist_session_cookies(true);
}
key_ = std::make_unique<ProfileKey>(GetPath()); key_ = std::make_unique<ProfileKey>(GetPath());
SimpleKeyMap::GetInstance()->Associate(this, key_.get()); SimpleKeyMap::GetInstance()->Associate(this, key_.get());

View File

@@ -183,6 +183,9 @@ class CefBrowserContext : public ChromeProfileStub,
// Values checked in ProfileNetworkContextService::CreateNetworkContextParams // Values checked in ProfileNetworkContextService::CreateNetworkContextParams
// when creating the NetworkContext. // when creating the NetworkContext.
bool ShouldRestoreOldSessionCookies() override {
return should_persist_session_cookies_;
}
bool ShouldPersistSessionCookies() override { bool ShouldPersistSessionCookies() override {
return should_persist_session_cookies_; return should_persist_session_cookies_;
} }

View File

@@ -1576,6 +1576,11 @@ CefRefPtr<CefFrame> CefBrowserHostImpl::GetFrameForHost(
return browser_info_->GetFrameForHost(host); 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, void CefBrowserHostImpl::LoadMainFrameURL(const std::string& url,
const content::Referrer& referrer, const content::Referrer& referrer,
ui::PageTransition transition, ui::PageTransition transition,
@@ -2736,8 +2741,8 @@ bool CefBrowserHostImpl::StartAudioMirroring() {
if (client_.get()) { if (client_.get()) {
CefRefPtr<CefAudioHandler> audio_handler = client_->GetAudioHandler(); CefRefPtr<CefAudioHandler> audio_handler = client_->GetAudioHandler();
if (audio_handler.get()) { if (audio_handler.get()) {
audio_mirror_destination_.reset(new CefAudioMirrorDestination( audio_mirror_destination_ = new CefAudioMirrorDestination(
this, audio_handler, content::AudioMirroringManager::GetInstance())); this, audio_handler, content::AudioMirroringManager::GetInstance());
audio_mirror_destination_->Start(); audio_mirror_destination_->Start();
return true; return true;
} }

View File

@@ -299,6 +299,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
// Returns the frame associated with the specified RenderFrameHost. // Returns the frame associated with the specified RenderFrameHost.
CefRefPtr<CefFrame> GetFrameForHost(const content::RenderFrameHost* host); 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. // Load the specified URL in the main frame.
void LoadMainFrameURL(const std::string& url, void LoadMainFrameURL(const std::string& url,
const content::Referrer& referrer, const content::Referrer& referrer,
@@ -663,7 +666,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
bool is_background_host_ = false; bool is_background_host_ = false;
// Used to mirror audio streams // Used to mirror audio streams
std::unique_ptr<CefAudioMirrorDestination> audio_mirror_destination_; scoped_refptr<CefAudioMirrorDestination> audio_mirror_destination_;
// Used with auto-resize. // Used with auto-resize.
bool auto_resize_enabled_ = false; bool auto_resize_enabled_ = false;

View File

@@ -22,6 +22,7 @@
#include "libcef/browser/media_capture_devices_dispatcher.h" #include "libcef/browser/media_capture_devices_dispatcher.h"
#include "libcef/browser/net/chrome_scheme_handler.h" #include "libcef/browser/net/chrome_scheme_handler.h"
#include "libcef/browser/net/net_util.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/proxy_url_loader_factory.h"
#include "libcef/browser/net_service/resource_request_handler_wrapper.h" #include "libcef/browser/net_service/resource_request_handler_wrapper.h"
#include "libcef/browser/plugins/plugin_service_filter.h" #include "libcef/browser/plugins/plugin_service_filter.h"
@@ -108,6 +109,7 @@
#include "extensions/browser/io_thread_extension_message_filter.h" #include "extensions/browser/io_thread_extension_message_filter.h"
#include "extensions/common/constants.h" #include "extensions/common/constants.h"
#include "extensions/common/switches.h" #include "extensions/common/switches.h"
#include "net/base/auth.h"
#include "net/ssl/ssl_cert_request_info.h" #include "net/ssl/ssl_cert_request_info.h"
#include "ppapi/host/ppapi_host.h" #include "ppapi/host/ppapi_host.h"
#include "services/network/public/cpp/network_switches.h" #include "services/network/public/cpp/network_switches.h"
@@ -429,6 +431,7 @@ bool NavigationOnUIThread(
bool is_main_frame, bool is_main_frame,
int64_t frame_id, int64_t frame_id,
int64_t parent_frame_id, int64_t parent_frame_id,
int frame_tree_node_id,
content::WebContents* source, content::WebContents* source,
const navigation_interception::NavigationParams& params) { const navigation_interception::NavigationParams& params) {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
@@ -447,7 +450,9 @@ bool NavigationOnUIThread(
frame = browser->GetMainFrame(); frame = browser->GetMainFrame();
} else if (frame_id >= 0) { } else if (frame_id >= 0) {
frame = browser->GetFrame(frame_id); frame = browser->GetFrame(frame_id);
DCHECK(frame); }
if (!frame && frame_tree_node_id >= 0) {
frame = browser->GetFrameForFrameTreeNode(frame_tree_node_id);
} }
if (!frame) { if (!frame) {
// Create a temporary frame object for navigation of sub-frames that // Create a temporary frame object for navigation of sub-frames that
@@ -1115,7 +1120,7 @@ CefContentBrowserClient::CreateThrottlesForNavigation(
std::make_unique<navigation_interception::InterceptNavigationThrottle>( std::make_unique<navigation_interception::InterceptNavigationThrottle>(
navigation_handle, navigation_handle,
base::Bind(&NavigationOnUIThread, is_main_frame, frame_id, base::Bind(&NavigationOnUIThread, is_main_frame, frame_id,
parent_frame_id), parent_frame_id, navigation_handle->GetFrameTreeNodeId()),
navigation_interception::SynchronyMode::kSync); navigation_interception::SynchronyMode::kSync);
throttles.push_back(std::move(throttle)); throttles.push_back(std::move(throttle));
@@ -1195,6 +1200,21 @@ CefContentBrowserClient::CreateClientCertStore(
->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( void CefContentBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
int frame_tree_node_id, int frame_tree_node_id,
NonNetworkURLLoaderFactoryMap* factories) { NonNetworkURLLoaderFactoryMap* factories) {

View File

@@ -150,10 +150,17 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
service_manager::BinderRegistry* registry, service_manager::BinderRegistry* registry,
blink::AssociatedInterfaceRegistry* associated_registry, blink::AssociatedInterfaceRegistry* associated_registry,
content::RenderProcessHost* render_process_host) override; content::RenderProcessHost* render_process_host) override;
std::unique_ptr<net::ClientCertStore> CreateClientCertStore( std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
content::ResourceContext* resource_context) override; 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( void RegisterNonNetworkNavigationURLLoaderFactories(
int frame_tree_node_id, int frame_tree_node_id,
NonNetworkURLLoaderFactoryMap* factories) override; NonNetworkURLLoaderFactoryMap* factories) override;

View File

@@ -199,7 +199,7 @@ void CefExtensionSystem::Init() {
// mime_handler_private.idl), and returns the unique View ID via the // mime_handler_private.idl), and returns the unique View ID via the
// |payload| argument. // |payload| argument.
// 5. The unique View ID arrives in the renderer process via // 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 // DOMImplementation::createDocument indirectly calls
// RendererBlinkPlatformImpl::getPluginList to retrieve the list of // RendererBlinkPlatformImpl::getPluginList to retrieve the list of
// supported plugins from the browser process. If a plugin supports the // supported plugins from the browser process. If a plugin supports the

View File

@@ -26,8 +26,9 @@
(CefJavaScriptDialogRunner::DialogClosedCallback)callback; (CefJavaScriptDialogRunner::DialogClosedCallback)callback;
- (NSAlert*)alert; - (NSAlert*)alert;
- (NSTextField*)textField; - (NSTextField*)textField;
- (void)alertDidEndWithResult:(NSModalResponse)returnCode - (void)alertDidEnd:(NSAlert*)alert
dialog:(CefJavaScriptDialogRunnerMac*)dialog; returnCode:(int)returnCode
contextInfo:(void*)contextInfo;
- (void)cancel; - (void)cancel;
@end @end
@@ -57,8 +58,9 @@
return textField_; return textField_;
} }
- (void)alertDidEndWithResult:(NSModalResponse)returnCode - (void)alertDidEnd:(NSAlert*)alert
dialog:(CefJavaScriptDialogRunnerMac*)dialog { returnCode:(int)returnCode
contextInfo:(void*)contextInfo {
if (returnCode == NSModalResponseStop) if (returnCode == NSModalResponseStop)
return; return;
@@ -139,11 +141,16 @@ void CefJavaScriptDialogRunnerMac::Run(
// around the "callee requires a non-null argument" error that occurs when // 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 // building with the 10.11 SDK. See http://crbug.com/383820 for related
// discussion. // 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; id nilArg = nil;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[alert beginSheetModalForWindow:nilArg // nil here makes it app-modal [alert beginSheetModalForWindow:nilArg // nil here makes it app-modal
completionHandler:^void(NSModalResponse returnCode) { modalDelegate:helper_
[helper_ alertDidEndWithResult:returnCode dialog:this]; didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
}]; contextInfo:this];
#pragma clang diagnostic pop
if ([alert accessoryView]) if ([alert accessoryView])
[[alert window] makeFirstResponder:[alert accessoryView]]; [[alert window] makeFirstResponder:[alert accessoryView]];

View File

@@ -395,13 +395,10 @@ net::NetworkDelegate::AuthRequiredResponse CefNetworkDelegate::OnAuthRequired(
if (client.get()) { if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler(); CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) { if (handler.get()) {
CefRefPtr<CefFrame> frame =
net_util::GetFrameForRequest(browser->browser_info(), request);
CefRefPtr<CefAuthCallbackImpl> callbackPtr( CefRefPtr<CefAuthCallbackImpl> callbackPtr(
new CefAuthCallbackImpl(std::move(callback), credentials)); new CefAuthCallbackImpl(std::move(callback), credentials));
if (handler->GetAuthCredentials( 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.challenger.host(), auth_info.challenger.port(),
auth_info.realm, auth_info.scheme, callbackPtr.get())) { auth_info.realm, auth_info.scheme, callbackPtr.get())) {
request->SetUserData( request->SetUserData(

View File

@@ -22,12 +22,88 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/strings/string_util.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/base/net_errors.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "services/network/public/cpp/shared_url_loader_factory.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.h"
#include "services/network/public/cpp/simple_url_loader_stream_consumer.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 ---------------------------------------------- // CefBrowserURLRequest::Context ----------------------------------------------
class CefBrowserURLRequest::Context class CefBrowserURLRequest::Context
@@ -113,6 +189,7 @@ class CefBrowserURLRequest::Context
request_context_impl->GetBrowserContext(); request_context_impl->GetBrowserContext();
DCHECK(browser_context); DCHECK(browser_context);
int render_frame_id = MSG_ROUTING_NONE;
scoped_refptr<net_service::URLLoaderFactoryGetter> loader_factory_getter; scoped_refptr<net_service::URLLoaderFactoryGetter> loader_factory_getter;
if (frame) { if (frame) {
// The request will be associated with this frame/browser if it's valid, // The request will be associated with this frame/browser if it's valid,
@@ -120,6 +197,14 @@ class CefBrowserURLRequest::Context
content::RenderFrameHost* rfh = content::RenderFrameHost* rfh =
static_cast<CefFrameHostImpl*>(frame.get())->GetRenderFrameHost(); static_cast<CefFrameHostImpl*>(frame.get())->GetRenderFrameHost();
if (rfh) { 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 = loader_factory_getter =
net_service::URLLoaderFactoryGetter::Create(rfh, browser_context); net_service::URLLoaderFactoryGetter::Create(rfh, browser_context);
} }
@@ -132,10 +217,12 @@ class CefBrowserURLRequest::Context
FROM_HERE, FROM_HERE,
base::BindOnce( base::BindOnce(
&CefBrowserURLRequest::Context::ContinueOnOriginatingThread, self, &CefBrowserURLRequest::Context::ContinueOnOriginatingThread, self,
loader_factory_getter)); render_frame_id, MakeRequestID(), loader_factory_getter));
} }
void ContinueOnOriginatingThread( void ContinueOnOriginatingThread(
int render_frame_id,
int32_t request_id,
scoped_refptr<net_service::URLLoaderFactoryGetter> scoped_refptr<net_service::URLLoaderFactoryGetter>
loader_factory_getter) { loader_factory_getter) {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
@@ -163,6 +250,8 @@ class CefBrowserURLRequest::Context
static_cast<CefRequestImpl*>(request_.get()) static_cast<CefRequestImpl*>(request_.get())
->Get(resource_request.get(), false); ->Get(resource_request.get(), false);
resource_request->render_frame_id = render_frame_id;
// SimpleURLLoader is picky about the body contents. Try to populate them // SimpleURLLoader is picky about the body contents. Try to populate them
// correctly below. // correctly below.
auto request_body = resource_request->request_body; auto request_body = resource_request->request_body;
@@ -187,6 +276,11 @@ class CefBrowserURLRequest::Context
loader_ = network::SimpleURLLoader::Create(std::move(resource_request), loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
NO_TRAFFIC_ANNOTATION_YET); 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) {
if (request_body->elements()->size() == 1) { if (request_body->elements()->size() == 1) {
const auto& element = (*request_body->elements())[0]; const auto& element = (*request_body->elements())[0];
@@ -294,6 +388,7 @@ class CefBrowserURLRequest::Context
DCHECK(request_->GetFlags() | UR_FLAG_STOP_ON_REDIRECT); DCHECK(request_->GetFlags() | UR_FLAG_STOP_ON_REDIRECT);
response_->SetReadOnly(false); response_->SetReadOnly(false);
response_->SetURL(redirect_info.new_url.spec());
response_->SetResponseHeaders(*response_head.headers); response_->SetResponseHeaders(*response_head.headers);
response_->SetReadOnly(true); response_->SetReadOnly(true);
@@ -403,6 +498,8 @@ class CefBrowserURLRequest::Context
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
DCHECK(url_request_); DCHECK(url_request_);
g_manager.Get().Remove(request_id_);
client_ = nullptr; client_ = nullptr;
request_context_ = nullptr; request_context_ = nullptr;
@@ -439,6 +536,8 @@ class CefBrowserURLRequest::Context
scoped_refptr<net_service::URLLoaderFactoryGetter> loader_factory_getter_; scoped_refptr<net_service::URLLoaderFactoryGetter> loader_factory_getter_;
std::unique_ptr<network::SimpleURLLoader> loader_; std::unique_ptr<network::SimpleURLLoader> loader_;
int32_t request_id_ = 0;
CefURLRequest::Status status_ = UR_IO_PENDING; CefURLRequest::Status status_ = UR_IO_PENDING;
CefRefPtr<CefResponseImpl> response_; CefRefPtr<CefResponseImpl> response_;
bool response_was_cached_ = false; bool response_was_cached_ = false;
@@ -453,6 +552,22 @@ class CefBrowserURLRequest::Context
// CefBrowserURLRequest ------------------------------------------------------- // 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( CefBrowserURLRequest::CefBrowserURLRequest(
CefRefPtr<CefFrame> frame, CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request, CefRefPtr<CefRequest> request,

View File

@@ -9,10 +9,28 @@
#include "include/cef_urlrequest.h" #include "include/cef_urlrequest.h"
#include "base/optional.h"
namespace content {
struct GlobalRequestID;
}
class CefBrowserURLRequest : public CefURLRequest { class CefBrowserURLRequest : public CefURLRequest {
public: public:
class Context; 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 // If |frame| is nullptr requests can still be intercepted but no
// browser/frame will be associated with them. // browser/frame will be associated with them.
CefBrowserURLRequest(CefRefPtr<CefFrame> frame, CefBrowserURLRequest(CefRefPtr<CefFrame> frame,

View 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

View 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_

View File

@@ -17,6 +17,7 @@
#include "content/public/browser/resource_context.h" #include "content/public/browser/resource_context.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "net/http/http_status_code.h" #include "net/http/http_status_code.h"
#include "services/network/public/cpp/cors/cors.h"
namespace net_service { namespace net_service {
@@ -40,7 +41,14 @@ class ResourceContextData : public base::SupportsUserData::Data {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
content::WebContents* web_contents = web_contents_getter.Run(); 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 = content::BrowserContext* browser_context =
web_contents->GetBrowserContext(); web_contents->GetBrowserContext();
@@ -59,6 +67,12 @@ class ResourceContextData : public base::SupportsUserData::Data {
content::ResourceContext* resource_context) { content::ResourceContext* resource_context) {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
// Maybe the proxy was destroyed while AddProxyOnUIThread was pending.
if (proxy->destroyed_) {
delete proxy;
return;
}
auto* self = static_cast<ResourceContextData*>( auto* self = static_cast<ResourceContextData*>(
resource_context->GetUserData(kResourceContextUserDataKey)); resource_context->GetUserData(kResourceContextUserDataKey));
if (!self) { if (!self) {
@@ -595,12 +609,6 @@ void InterceptedRequest::BeforeRequestReceived(const GURL& original_url,
// Equivalent to no interception. // Equivalent to no interception.
InterceptResponseReceived(original_url, nullptr); InterceptResponseReceived(original_url, nullptr);
} else { } 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 // TODO(network): Verify the case when WebContents::RenderFrameDeleted is
// called before network request is intercepted (i.e. if that's possible // called before network request is intercepted (i.e. if that's possible
// and whether it can result in any issues). // 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.encoded_data_length = head.headers->raw_headers().length();
head.content_length = head.encoded_body_length = 0; 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; current_response_ = head;
const net::RedirectInfo& redirect_info = const net::RedirectInfo& redirect_info =
MakeRedirectInfo(request_, head.headers.get(), request_.url, 0); 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_.site_for_cookies = redirect_info.new_site_for_cookies;
request_.referrer = GURL(redirect_info.new_referrer); request_.referrer = GURL(redirect_info.new_referrer);
request_.referrer_policy = redirect_info.new_referrer_policy; 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) { void InterceptedRequest::ContinueToResponseStarted(int error_code) {
@@ -862,6 +889,9 @@ void InterceptedRequest::ContinueToResponseStarted(int error_code) {
} }
void InterceptedRequest::OnDestroy() { void InterceptedRequest::OnDestroy() {
// We don't want any callbacks after this point.
weak_factory_.InvalidateWeakPtrs();
factory_->request_handler_->OnRequestComplete(id_, request_, status_); factory_->request_handler_->OnRequestComplete(id_, request_, status_);
// Destroys |this|. // Destroys |this|.
@@ -1027,7 +1057,9 @@ ProxyURLLoaderFactory::ProxyURLLoaderFactory(
url_loader_header_client_binding_.Bind(std::move(header_client_request)); url_loader_header_client_binding_.Bind(std::move(header_client_request));
} }
ProxyURLLoaderFactory::~ProxyURLLoaderFactory() {} ProxyURLLoaderFactory::~ProxyURLLoaderFactory() {
CEF_REQUIRE_IOT();
}
// static // static
void ProxyURLLoaderFactory::CreateOnIOThread( void ProxyURLLoaderFactory::CreateOnIOThread(
@@ -1046,6 +1078,7 @@ void ProxyURLLoaderFactory::CreateOnIOThread(
void ProxyURLLoaderFactory::SetDisconnectCallback( void ProxyURLLoaderFactory::SetDisconnectCallback(
DisconnectCallback on_disconnect) { DisconnectCallback on_disconnect) {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
DCHECK(!destroyed_);
DCHECK(!on_disconnect_); DCHECK(!on_disconnect_);
on_disconnect_ = std::move(on_disconnect); on_disconnect_ = std::move(on_disconnect);
} }
@@ -1179,8 +1212,14 @@ void ProxyURLLoaderFactory::MaybeDestroySelf() {
if (target_factory_.is_bound() || !requests_.empty()) if (target_factory_.is_bound() || !requests_.empty())
return; return;
// Deletes |this|. CHECK(!destroyed_);
std::move(on_disconnect_).Run(this); 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 } // namespace net_service

View File

@@ -195,6 +195,7 @@ class ProxyURLLoaderFactory
std::unique_ptr<InterceptedRequestHandler> request_handler_; std::unique_ptr<InterceptedRequestHandler> request_handler_;
bool destroyed_ = false;
DisconnectCallback on_disconnect_; DisconnectCallback on_disconnect_;
// Map of request ID to request object. // Map of request ID to request object.

View File

@@ -36,6 +36,9 @@ namespace net_service {
namespace { namespace {
const int kLoadNoCookiesFlags =
net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
class RequestCallbackWrapper : public CefRequestCallback { class RequestCallbackWrapper : public CefRequestCallback {
public: public:
using Callback = base::OnceCallback<void(bool /* allow */)>; using Callback = base::OnceCallback<void(bool /* allow */)>;
@@ -163,7 +166,32 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
class DestructionObserver : public CefBrowserHostImpl::Observer, class DestructionObserver : public CefBrowserHostImpl::Observer,
public CefContext::Observer { public CefContext::Observer {
public: 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) { void SetWrapper(base::WeakPtr<InterceptedRequestHandlerWrapper> wrapper) {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
@@ -173,121 +201,190 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
void OnBrowserDestroyed(CefBrowserHostImpl* browser) override { void OnBrowserDestroyed(CefBrowserHostImpl* browser) override {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
browser->RemoveObserver(this); browser->RemoveObserver(this);
registered_ = false;
browser_info_ = nullptr;
NotifyOnDestroyed(); NotifyOnDestroyed();
} }
void OnContextDestroyed() override { void OnContextDestroyed() override {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
CefContext::Get()->RemoveObserver(this); CefContext::Get()->RemoveObserver(this);
registered_ = false;
NotifyOnDestroyed(); NotifyOnDestroyed();
} }
private: private:
void NotifyOnDestroyed() { void NotifyOnDestroyed() {
// It's not safe to test the WeakPtr on the UI thread, so we'll just post if (wrapper_.MaybeValid()) {
// a task which will be ignored if the WeakPtr is invalid. // This will be a no-op if the WeakPtr is invalid.
CEF_POST_TASK(CEF_IOT, base::BindOnce( CEF_POST_TASK(
&InterceptedRequestHandlerWrapper::OnDestroyed, CEF_IOT,
wrapper_)); base::BindOnce(&InterceptedRequestHandlerWrapper::OnDestroyed,
wrapper_));
}
} }
scoped_refptr<CefBrowserInfo> browser_info_;
bool registered_ = true;
base::WeakPtr<InterceptedRequestHandlerWrapper> wrapper_; base::WeakPtr<InterceptedRequestHandlerWrapper> wrapper_;
DISALLOW_COPY_AND_ASSIGN(DestructionObserver); 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 { ~InitState() {
// There should be no pending or in-progress requests during destruction. if (destruction_observer_) {
DCHECK(pending_requests_.empty()); if (initialized_) {
DCHECK(request_map_.empty()); // Clear the reference added in
// InterceptedRequestHandlerWrapper::SetInitialized().
destruction_observer_->SetWrapper(nullptr);
}
DeleteDestructionObserver();
}
}
if (destruction_observer_) { void Initialize(content::BrowserContext* browser_context,
destruction_observer_->SetWrapper(nullptr); 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_POST_TASK(
CEF_UIT, base::BindOnce(&InterceptedRequestHandlerWrapper:: CEF_UIT,
RemoveDestructionObserverOnUIThread, base::BindOnce(&InitState::DeleteDestructionObserverOnUIThread,
browser_ ? browser_->browser_info() : nullptr, std::move(destruction_observer_)));
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());
} }
render_process_id_ = render_process_id; static void DeleteDestructionObserverOnUIThread(
render_frame_id_ = render_frame_id; std::unique_ptr<DestructionObserver> observer) {}
frame_tree_node_id_ = frame_tree_node_id;
is_navigation_ = is_navigation; // Only accessed on the UI thread.
is_download_ = is_download; content::BrowserContext* browser_context_ = nullptr;
request_initiator_ = request_initiator.Serialize();
is_external_ = is_external; 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. // Default values for standard headers.
accept_language_ = ComputeAcceptLanguageFromPref( std::string accept_language_;
GetAcceptLanguageList(browser_context, browser)); std::string user_agent_;
DCHECK(!accept_language_.empty());
user_agent_ = CefContentClient::Get()->browser()->GetUserAgent();
DCHECK(!user_agent_.empty());
CEF_POST_TASK( // Used to receive destruction notification.
CEF_IOT, std::unique_ptr<DestructionObserver> destruction_observer_;
base::BindOnce(&InterceptedRequestHandlerWrapper::SetInitialized, };
weak_ptr_factory_.GetWeakPtr()));
// 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(); 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 // Check that the CEF context or associated browser was not destroyed
// between the calls to Initialize and SetInitialized, in which case // between the calls to Initialize and SetInitialized, in which case
// we won't get an OnDestroyed callback from DestructionObserver. // we won't get an OnDestroyed callback from DestructionObserver.
if (browser_) { if (init_state_->browser_) {
if (!browser_->browser_info()->browser()) { if (!init_state_->browser_->browser_info()->browser()) {
OnDestroyed(); OnDestroyed();
return; return;
} }
@@ -296,7 +393,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
return; 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. // Continue any pending requests.
if (!pending_requests_.empty()) { if (!pending_requests_.empty()) {
@@ -320,7 +419,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
return; return;
} }
if (!initialized_) { if (!init_state_) {
// Queue requests until we're initialized. // Queue requests until we're initialized.
pending_requests_.push_back(std::make_unique<PendingRequest>( pending_requests_.push_back(std::make_unique<PendingRequest>(
id, request, request_was_redirected, std::move(callback), id, request, request_was_redirected, std::move(callback),
@@ -333,19 +432,22 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
// Add standard headers, if currently unspecified. // Add standard headers, if currently unspecified.
request->headers.SetHeaderIfMissing( request->headers.SetHeaderIfMissing(
net::HttpRequestHeaders::kAcceptLanguage, accept_language_); net::HttpRequestHeaders::kAcceptLanguage,
init_state_->accept_language_);
request->headers.SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent, 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. // External requests will not have a default handler.
bool intercept_only = is_external_; bool intercept_only = is_external;
CefRefPtr<CefRequestImpl> requestPtr; CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefResourceRequestHandler> handler = CefRefPtr<CefResourceRequestHandler> handler =
GetHandler(id, request, &intercept_only, requestPtr); GetHandler(id, request, &intercept_only, requestPtr);
CefRefPtr<CefSchemeHandlerFactory> scheme_factory = CefRefPtr<CefSchemeHandlerFactory> scheme_factory =
resource_context_->GetSchemeHandlerFactory(request->url); init_state_->resource_context_->GetSchemeHandlerFactory(request->url);
if (scheme_factory && !requestPtr) { if (scheme_factory && !requestPtr) {
requestPtr = MakeRequest(request, id.hash(), true); requestPtr = MakeRequest(request, id.hash(), true);
} }
@@ -360,13 +462,13 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
std::move(cancel_callback)); std::move(cancel_callback));
if (handler) { if (handler) {
state->cookie_filter_ = state->cookie_filter_ = handler->GetCookieAccessFilter(
handler->GetCookieAccessFilter(browser_, frame_, requestPtr.get()); init_state_->browser_, init_state_->frame_, requestPtr.get());
} }
auto exec_callback = auto exec_callback =
base::BindOnce(std::move(callback), maybe_intercept_request, base::BindOnce(std::move(callback), maybe_intercept_request,
is_external_ ? true : intercept_only); is_external ? true : intercept_only);
if (!maybe_intercept_request) { if (!maybe_intercept_request) {
// Cookies will be handled by the NetworkService. // Cookies will be handled by the NetworkService.
@@ -395,7 +497,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
auto done_cookie_callback = base::BindOnce( auto done_cookie_callback = base::BindOnce(
&InterceptedRequestHandlerWrapper::ContinueWithLoadedCookies, &InterceptedRequestHandlerWrapper::ContinueWithLoadedCookies,
weak_ptr_factory_.GetWeakPtr(), id, request, std::move(callback)); 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)); std::move(done_cookie_callback));
} }
@@ -421,7 +524,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
CefCookie cef_cookie; CefCookie cef_cookie;
if (net_service::MakeCefCookie(cookie, cef_cookie)) { if (net_service::MakeCefCookie(cookie, cef_cookie)) {
*allow = state->cookie_filter_->CanSendCookie( *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 // 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 // so that we can filter them. This will be a no-op for custom-handled
// requests. // requests.
request->load_flags |= request->load_flags |= kLoadNoCookiesFlags;
net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
} }
if (!allowed_cookies.empty()) { if (!allowed_cookies.empty()) {
@@ -490,7 +593,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
base::Passed(std::move(callback)))); base::Passed(std::move(callback))));
cef_return_value_t retval = state->handler_->OnBeforeResourceLoad( 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) { if (retval != RV_CONTINUE_ASYNC) {
// Continue or cancel the request immediately. // Continue or cancel the request immediately.
callbackPtr->Continue(retval == RV_CONTINUE); callbackPtr->Continue(retval == RV_CONTINUE);
@@ -555,12 +659,13 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
if (state->handler_) { if (state->handler_) {
// Does the client want to handle the request? // Does the client want to handle the request?
resource_handler = state->handler_->GetResourceHandler( 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_) { if (!resource_handler && state->scheme_factory_) {
// Does the scheme factory want to handle the request? // Does the scheme factory want to handle the request?
resource_handler = state->scheme_factory_->Create( resource_handler = state->scheme_factory_->Create(
browser_, frame_, request->url.scheme(), init_state_->browser_, init_state_->frame_, request->url.scheme(),
state->pending_request_.get()); state->pending_request_.get());
} }
@@ -615,6 +720,11 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
return; return;
} }
if (state->cookie_filter_) {
// Remove the flags that were added in ContinueWithLoadedCookies.
request->load_flags &= ~kLoadNoCookiesFlags;
}
if (!state->handler_) { if (!state->handler_) {
// Cookies may come from a scheme handler. // Cookies may come from a scheme handler.
MaybeSaveCookies( MaybeSaveCookies(
@@ -646,9 +756,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
CefString newUrl = redirect_info.new_url.spec(); CefString newUrl = redirect_info.new_url.spec();
CefString oldUrl = newUrl; CefString oldUrl = newUrl;
bool url_changed = false; bool url_changed = false;
state->handler_->OnResourceRedirect(browser_, frame_, state->handler_->OnResourceRedirect(
state->pending_request_.get(), init_state_->browser_, init_state_->frame_,
state->pending_response_.get(), newUrl); state->pending_request_.get(), state->pending_response_.get(), newUrl);
if (newUrl != oldUrl) { if (newUrl != oldUrl) {
// Also support relative URLs. // Also support relative URLs.
const GURL& url = redirect_info.new_url.Resolve(newUrl.ToString()); const GURL& url = redirect_info.new_url.Resolve(newUrl.ToString());
@@ -684,9 +794,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
auto response_mode = ResponseMode::CONTINUE; auto response_mode = ResponseMode::CONTINUE;
GURL new_url; GURL new_url;
if (state->handler_->OnResourceResponse(browser_, frame_, if (state->handler_->OnResourceResponse(
state->pending_request_.get(), init_state_->browser_, init_state_->frame_,
state->pending_response_.get())) { state->pending_request_.get(), state->pending_response_.get())) {
// The request may have been modified. // The request may have been modified.
const auto changes = state->pending_request_->GetChanges(); const auto changes = state->pending_request_->GetChanges();
if (changes) { if (changes) {
@@ -746,7 +856,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
auto done_cookie_callback = base::BindOnce( auto done_cookie_callback = base::BindOnce(
&InterceptedRequestHandlerWrapper::ContinueWithSavedCookies, &InterceptedRequestHandlerWrapper::ContinueWithSavedCookies,
weak_ptr_factory_.GetWeakPtr(), id, std::move(callback)); 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, allow_cookie_callback,
std::move(done_cookie_callback)); std::move(done_cookie_callback));
} }
@@ -768,8 +878,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
CefCookie cef_cookie; CefCookie cef_cookie;
if (net_service::MakeCefCookie(cookie, cef_cookie)) { if (net_service::MakeCefCookie(cookie, cef_cookie)) {
*allow = state->cookie_filter_->CanSaveCookie( *allow = state->cookie_filter_->CanSaveCookie(
browser_, frame_, state->pending_request_.get(), init_state_->browser_, init_state_->frame_,
state->pending_response_.get(), cef_cookie); state->pending_request_.get(), state->pending_response_.get(),
cef_cookie);
} }
} }
@@ -795,8 +906,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
if (state->handler_) { if (state->handler_) {
auto filter = state->handler_->GetResourceResponseFilter( auto filter = state->handler_->GetResourceResponseFilter(
browser_, frame_, state->pending_request_.get(), init_state_->browser_, init_state_->frame_,
state->pending_response_.get()); state->pending_request_.get(), state->pending_response_.get());
if (filter) { if (filter) {
return CreateResponseFilterHandler( return CreateResponseFilterHandler(
filter, std::move(body), filter, std::move(body),
@@ -831,14 +942,28 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
RequestState* state = GetState(id); RequestState* state = GetState(id);
if (!state) { 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; return;
} }
const bool is_external = IsExternalRequest(&request);
// Redirection of standard custom schemes is handled with a restart, so we // Redirection of standard custom schemes is handled with a restart, so we
// get completion notifications for both the original (redirected) request // get completion notifications for both the original (redirected) request
// and the final request. Don't report completion of the 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 && status.error_code == net::ERR_ABORTED &&
state->pending_response_.get() && state->pending_response_.get() &&
net::HttpResponseHeaders::IsRedirectResponseCode( net::HttpResponseHeaders::IsRedirectResponseCode(
@@ -849,11 +974,11 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
CallHandlerOnComplete(state, status); CallHandlerOnComplete(state, status);
if (status.error_code != 0 && is_external_) { if (status.error_code != 0 && is_external) {
bool allow_os_execution = false; bool allow_os_execution = false;
state->handler_->OnProtocolExecution(browser_, frame_, state->handler_->OnProtocolExecution(
state->pending_request_.get(), init_state_->browser_, init_state_->frame_,
allow_os_execution); state->pending_request_.get(), allow_os_execution);
if (allow_os_execution) { if (allow_os_execution) {
CefBrowserPlatformDelegate::HandleExternalProtocol(request.url); CefBrowserPlatformDelegate::HandleExternalProtocol(request.url);
} }
@@ -886,8 +1011,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
state->pending_response_->SetReadOnly(true); state->pending_response_->SetReadOnly(true);
state->handler_->OnResourceLoadComplete( state->handler_->OnResourceLoadComplete(
browser_, frame_, state->pending_request_.get(), init_state_->browser_, init_state_->frame_,
state->pending_response_.get(), state->pending_request_.get(), state->pending_response_.get(),
status.error_code == 0 ? UR_SUCCESS : UR_FAILED, status.error_code == 0 ? UR_SUCCESS : UR_FAILED,
status.encoded_body_length); status.encoded_body_length);
} }
@@ -902,9 +1027,10 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
const int64 request_id = id.hash(); const int64 request_id = id.hash();
if (browser_) { if (init_state_->browser_) {
// Maybe the browser's client wants to handle it? // 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) { if (client) {
CefRefPtr<CefRequestHandler> request_handler = CefRefPtr<CefRequestHandler> request_handler =
client->GetRequestHandler(); client->GetRequestHandler();
@@ -912,8 +1038,9 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
requestPtr = MakeRequest(request, request_id, true); requestPtr = MakeRequest(request, request_id, true);
handler = request_handler->GetResourceRequestHandler( handler = request_handler->GetResourceRequestHandler(
browser_, frame_, requestPtr.get(), is_navigation_, is_download_, init_state_->browser_, init_state_->frame_, requestPtr.get(),
request_initiator_, *intercept_only); init_state_->is_navigation_, init_state_->is_download_,
init_state_->request_initiator_, *intercept_only);
} }
} }
} }
@@ -921,16 +1048,17 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
if (!handler) { if (!handler) {
// Maybe the request context wants to handle it? // Maybe the request context wants to handle it?
CefRefPtr<CefRequestContextHandler> context_handler = CefRefPtr<CefRequestContextHandler> context_handler =
resource_context_->GetHandler(render_process_id_, init_state_->resource_context_->GetHandler(
request->render_frame_id, init_state_->render_process_id_, request->render_frame_id,
frame_tree_node_id_, false); init_state_->frame_tree_node_id_, false);
if (context_handler) { if (context_handler) {
if (!requestPtr) if (!requestPtr)
requestPtr = MakeRequest(request, request_id, true); requestPtr = MakeRequest(request, request_id, true);
handler = context_handler->GetResourceRequestHandler( handler = context_handler->GetResourceRequestHandler(
browser_, frame_, requestPtr.get(), is_navigation_, is_download_, init_state_->browser_, init_state_->frame_, requestPtr.get(),
request_initiator_, *intercept_only); 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. // CEF context or associated browser is destroyed.
void OnDestroyed() { void OnDestroyed() {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
DCHECK(initialized_); DCHECK(init_state_);
DCHECK(destruction_observer_); init_state_->DeleteDestructionObserver();
destruction_observer_.reset();
// Stop accepting new requests. // Stop accepting new requests.
shutting_down_ = true; shutting_down_ = true;
@@ -990,10 +1117,10 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
network::URLLoaderCompletionStatus(net::ERR_ABORTED)); network::URLLoaderCompletionStatus(net::ERR_ABORTED));
} }
if (browser_) { if (init_state_->browser_) {
// Clear objects that reference the browser. // Clear objects that reference the browser.
browser_ = nullptr; init_state_->browser_ = nullptr;
frame_ = nullptr; init_state_->frame_ = nullptr;
} }
// Execute cancel callbacks and delete pending and in-progress requests. // Execute cancel callbacks and delete pending and in-progress requests.
@@ -1023,43 +1150,29 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
return requestPtr; 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; 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>>; using RequestMap = std::map<RequestId, std::unique_ptr<RequestState>>;
RequestMap request_map_; RequestMap request_map_;
using PendingRequests = std::vector<std::unique_ptr<PendingRequest>>; using PendingRequests = std::vector<std::unique_ptr<PendingRequest>>;
PendingRequests pending_requests_; PendingRequests pending_requests_;
// Used to receive destruction notification.
std::unique_ptr<DestructionObserver> destruction_observer_;
base::WeakPtrFactory<InterceptedRequestHandlerWrapper> weak_ptr_factory_; base::WeakPtrFactory<InterceptedRequestHandlerWrapper> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(InterceptedRequestHandlerWrapper); DISALLOW_COPY_AND_ASSIGN(InterceptedRequestHandlerWrapper);
}; };
void InitOnUIThread( void InitOnUIThread(
InterceptedRequestHandlerWrapper* wrapper, scoped_refptr<InterceptedRequestHandlerWrapper::InitHelper> init_helper,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter, content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
int frame_tree_node_id, int frame_tree_node_id,
const network::ResourceRequest& request) { const network::ResourceRequest& request) {
@@ -1116,6 +1229,7 @@ void InitOnUIThread(
} }
#endif #endif
// May return nullptr for requests originating from guest views.
browserPtr = CefBrowserHostImpl::GetBrowserForHost(frame); browserPtr = CefBrowserHostImpl::GetBrowserForHost(frame);
if (browserPtr) { if (browserPtr) {
framePtr = browserPtr->GetFrameForHost(frame); framePtr = browserPtr->GetFrameForHost(frame);
@@ -1133,10 +1247,14 @@ void InitOnUIThread(
if (request.request_initiator.has_value()) if (request.request_initiator.has_value())
request_initiator = *request.request_initiator; request_initiator = *request.request_initiator;
wrapper->Initialize(browser_context, browserPtr, framePtr, render_process_id, auto init_state =
request.render_frame_id, frame_tree_node_id, std::make_unique<InterceptedRequestHandlerWrapper::InitState>();
is_navigation, is_download, request_initiator, init_state->Initialize(browser_context, browserPtr, framePtr,
true /* is_external */); 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 } // namespace
@@ -1149,8 +1267,6 @@ std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
bool is_download, bool is_download,
const url::Origin& request_initiator) { const url::Origin& request_initiator) {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
auto wrapper = std::make_unique<InterceptedRequestHandlerWrapper>();
CefRefPtr<CefBrowserHostImpl> browserPtr; CefRefPtr<CefBrowserHostImpl> browserPtr;
CefRefPtr<CefFrame> framePtr; CefRefPtr<CefFrame> framePtr;
int render_frame_id = -1; int render_frame_id = -1;
@@ -1160,6 +1276,8 @@ std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
if (frame) { if (frame) {
render_frame_id = frame->GetRoutingID(); render_frame_id = frame->GetRoutingID();
frame_tree_node_id = frame->GetFrameTreeNodeId(); frame_tree_node_id = frame->GetFrameTreeNodeId();
// May return nullptr for requests originating from guest views.
browserPtr = CefBrowserHostImpl::GetBrowserForHost(frame); browserPtr = CefBrowserHostImpl::GetBrowserForHost(frame);
if (browserPtr) { if (browserPtr) {
framePtr = browserPtr->GetFrameForHost(frame); framePtr = browserPtr->GetFrameForHost(frame);
@@ -1167,14 +1285,15 @@ std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
} }
} }
// Flag subresource loads of custom schemes. auto init_state =
const bool is_external = std::make_unique<InterceptedRequestHandlerWrapper::InitState>();
!is_navigation && !is_download && !request_initiator.scheme().empty() && init_state->Initialize(browser_context, browserPtr, framePtr,
!scheme::IsInternalHandledScheme(request_initiator.scheme()); 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; return wrapper;
} }
@@ -1184,9 +1303,9 @@ std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
const network::ResourceRequest& request) { const network::ResourceRequest& request) {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
auto wrapper = std::make_unique<InterceptedRequestHandlerWrapper>(); auto wrapper = std::make_unique<InterceptedRequestHandlerWrapper>();
CEF_POST_TASK(CEF_UIT, base::BindOnce( CEF_POST_TASK(CEF_UIT, base::BindOnce(InitOnUIThread, wrapper->init_helper(),
InitOnUIThread, base::Unretained(wrapper.get()), web_contents_getter, frame_tree_node_id,
web_contents_getter, frame_tree_node_id, request)); request));
return wrapper; return wrapper;
} }

View File

@@ -546,6 +546,21 @@ void CefRequestContextImpl::ClearCertificateExceptions(
this, callback)); 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( void CefRequestContextImpl::CloseAllConnections(
CefRefPtr<CefCompletionCallback> callback) { CefRefPtr<CefCompletionCallback> callback) {
if (net_service::IsEnabled()) { 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( void CefRequestContextImpl::CloseAllConnectionsInternal(
CefRefPtr<CefCompletionCallback> callback, CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext* browser_context) { CefBrowserContext* browser_context) {

View File

@@ -73,6 +73,8 @@ class CefRequestContextImpl : public CefRequestContext {
CefString& error) override; CefString& error) override;
void ClearCertificateExceptions( void ClearCertificateExceptions(
CefRefPtr<CefCompletionCallback> callback) override; CefRefPtr<CefCompletionCallback> callback) override;
void ClearHttpAuthCredentials(
CefRefPtr<CefCompletionCallback> callback) override;
void CloseAllConnections(CefRefPtr<CefCompletionCallback> callback) override; void CloseAllConnections(CefRefPtr<CefCompletionCallback> callback) override;
void ResolveHost(const CefString& origin, void ResolveHost(const CefString& origin,
CefRefPtr<CefResolveCallback> callback) override; CefRefPtr<CefResolveCallback> callback) override;
@@ -157,6 +159,12 @@ class CefRequestContextImpl : public CefRequestContext {
void ClearCertificateExceptionsInternal( void ClearCertificateExceptionsInternal(
CefRefPtr<CefCompletionCallback> callback, CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext* browser_context); 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, void CloseAllConnectionsInternal(CefRefPtr<CefCompletionCallback> callback,
CefBrowserContext* browser_context); CefBrowserContext* browser_context);
void CloseAllConnectionsInternalOld( void CloseAllConnectionsInternalOld(

View File

@@ -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()) { if (!disable_features.empty()) {
DCHECK(!base::FeatureList::GetInstance()); DCHECK(!base::FeatureList::GetInstance());
std::string disable_features_str = std::string disable_features_str =
@@ -725,11 +732,9 @@ int CefMainDelegate::RunProcess(
bool CefMainDelegate::CreateUIThread(base::OnceClosure setup_callback) { bool CefMainDelegate::CreateUIThread(base::OnceClosure setup_callback) {
DCHECK(!ui_thread_); DCHECK(!ui_thread_);
std::unique_ptr<CefUIThread> thread; ui_thread_.reset(new CefUIThread(std::move(setup_callback)));
thread.reset(new CefUIThread(std::move(setup_callback))); ui_thread_->Start();
thread->Start(); ui_thread_->WaitUntilThreadStarted();
thread->WaitUntilThreadStarted();
ui_thread_.swap(thread);
InitMessagePumpFactoryForUI(); InitMessagePumpFactoryForUI();
return true; return true;

View File

@@ -1133,9 +1133,10 @@ void CefRequestImpl::Changed(uint8_t changes) {
} }
if ((changes & kChangedHeaderMap) && if ((changes & kChangedHeaderMap) &&
!(backup_->backups_ & kChangedHeaderMap)) { !(backup_->backups_ & kChangedHeaderMap)) {
if (!backup_->headermap_) backup_->headermap_.reset(new HeaderMap());
backup_->headermap_.reset(new HeaderMap()); if (!headermap_.empty()) {
backup_->headermap_->swap(headermap_); backup_->headermap_->insert(headermap_.begin(), headermap_.end());
}
backup_->backups_ |= kChangedHeaderMap; backup_->backups_ |= kChangedHeaderMap;
} }
if ((changes & kChangedFlags) && !(backup_->backups_ & kChangedFlags)) { if ((changes & kChangedFlags) && !(backup_->backups_ & kChangedFlags)) {

View File

@@ -37,6 +37,7 @@
#include "libcef/renderer/render_message_filter.h" #include "libcef/renderer/render_message_filter.h"
#include "libcef/renderer/render_thread_observer.h" #include "libcef/renderer/render_thread_observer.h"
#include "libcef/renderer/thread_util.h" #include "libcef/renderer/thread_util.h"
#include "libcef/renderer/url_loader_throttle_provider_impl.h"
#include "libcef/renderer/v8_impl.h" #include "libcef/renderer/v8_impl.h"
#include "base/command_line.h" #include "base/command_line.h"
@@ -603,12 +604,28 @@ void CefContentRendererClient::RunScriptsAtDocumentIdle(
} }
void CefContentRendererClient::DevToolsAgentAttached() { 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_; ++devtools_agent_count_;
} }
void CefContentRendererClient::DevToolsAgentDetached() { 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_; --devtools_agent_count_;
if (devtools_agent_count_ == 0 && uncaught_exception_stack_size_ > 0) { if (devtools_agent_count_ == 0 && uncaught_exception_stack_size_ > 0) {
// When the last DevToolsAgent is detached the stack size is set to 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)); 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( void CefContentRendererClient::OnBindInterface(
const service_manager::BindSourceInfo& remote_info, const service_manager::BindSourceInfo& remote_info,
const std::string& name, const std::string& name,

View File

@@ -138,6 +138,9 @@ class CefContentRendererClient
void DevToolsAgentDetached() override; void DevToolsAgentDetached() override;
void CreateRendererService( void CreateRendererService(
service_manager::mojom::ServiceRequest service_request) override; service_manager::mojom::ServiceRequest service_request) override;
std::unique_ptr<content::URLLoaderThrottleProvider>
CreateURLLoaderThrottleProvider(
content::URLLoaderThrottleProviderType provider_type) override;
// service_manager::Service implementation. // service_manager::Service implementation.
void OnBindInterface(const service_manager::BindSourceInfo& remote_info, void OnBindInterface(const service_manager::BindSourceInfo& remote_info,

View File

@@ -9,6 +9,7 @@
#include "libcef/renderer/blink_glue.h" #include "libcef/renderer/blink_glue.h"
#include "base/logging.h" #include "base/logging.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view.h"
#include "content/renderer/render_frame_impl.h" #include "content/renderer/render_frame_impl.h"
#include "third_party/blink/public/web/web_local_frame.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. // routing IDs are unique within a given renderer process.
content::RenderFrame* render_frame = content::RenderFrame* render_frame =
content::RenderFrame::FromWebFrame(frame); content::RenderFrame::FromWebFrame(frame);
return frame_util::MakeFrameId(render_frame->GetRenderView()->GetRoutingID(), return frame_util::MakeFrameId(content::RenderThread::Get()->GetClientId(),
render_frame->GetRoutingID()); render_frame->GetRoutingID());
} }

View 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) {}

View 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_

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=29ac900a92c4ec966cc115aae96c49b545bc9db9$ // $hash=95cc8d1445764e1d1610b2047844b138e60542e6$
// //
#include "libcef_dll/cpptoc/request_context_cpptoc.h" #include "libcef_dll/cpptoc/request_context_cpptoc.h"
@@ -373,6 +373,21 @@ void CEF_CALLBACK request_context_clear_certificate_exceptions(
CefCompletionCallbackCToCpp::Wrap(callback)); 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 void CEF_CALLBACK
request_context_close_all_connections(struct _cef_request_context_t* self, request_context_close_all_connections(struct _cef_request_context_t* self,
cef_completion_callback_t* callback) { cef_completion_callback_t* callback) {
@@ -549,6 +564,8 @@ CefRequestContextCppToC::CefRequestContextCppToC() {
GetStruct()->set_preference = request_context_set_preference; GetStruct()->set_preference = request_context_set_preference;
GetStruct()->clear_certificate_exceptions = GetStruct()->clear_certificate_exceptions =
request_context_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()->close_all_connections = request_context_close_all_connections;
GetStruct()->resolve_host = request_context_resolve_host; GetStruct()->resolve_host = request_context_resolve_host;
GetStruct()->load_extension = request_context_load_extension; GetStruct()->load_extension = request_context_load_extension;

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=370a54c21bec2aff5cf62b5897f5d43401e1ec31$ // $hash=ab373b720fe3c700867f86ad29ffc8b3e518a92c$
// //
#include "libcef_dll/cpptoc/request_handler_cpptoc.h" #include "libcef_dll/cpptoc/request_handler_cpptoc.h"
@@ -159,7 +159,7 @@ request_handler_get_resource_request_handler(
int CEF_CALLBACK int CEF_CALLBACK
request_handler_get_auth_credentials(struct _cef_request_handler_t* self, request_handler_get_auth_credentials(struct _cef_request_handler_t* self,
cef_browser_t* browser, cef_browser_t* browser,
cef_frame_t* frame, const cef_string_t* origin_url,
int isProxy, int isProxy,
const cef_string_t* host, const cef_string_t* host,
int port, int port,
@@ -177,9 +177,9 @@ request_handler_get_auth_credentials(struct _cef_request_handler_t* self,
DCHECK(browser); DCHECK(browser);
if (!browser) if (!browser)
return 0; return 0;
// Verify param: frame; type: refptr_diff // Verify param: origin_url; type: string_byref_const
DCHECK(frame); DCHECK(origin_url);
if (!frame) if (!origin_url)
return 0; return 0;
// Verify param: host; type: string_byref_const // Verify param: host; type: string_byref_const
DCHECK(host); DCHECK(host);
@@ -193,7 +193,7 @@ request_handler_get_auth_credentials(struct _cef_request_handler_t* self,
// Execute // Execute
bool _retval = CefRequestHandlerCppToC::Get(self)->GetAuthCredentials( 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), isProxy ? true : false, CefString(host), port, CefString(realm),
CefString(scheme), CefAuthCallbackCToCpp::Wrap(callback)); CefString(scheme), CefAuthCallbackCToCpp::Wrap(callback));

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=8155639f093ff697fd30a9e330ae3470108251e5$ // $hash=5036c24365fa0fdb3d7efc54670f3123a7104fa0$
// //
#include "libcef_dll/ctocpp/request_context_ctocpp.h" #include "libcef_dll/ctocpp/request_context_ctocpp.h"
@@ -355,6 +355,22 @@ void CefRequestContextCToCpp::ClearCertificateExceptions(
_struct, CefCompletionCallbackCppToC::Wrap(callback)); _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") NO_SANITIZE("cfi-icall")
void CefRequestContextCToCpp::CloseAllConnections( void CefRequestContextCToCpp::CloseAllConnections(
CefRefPtr<CefCompletionCallback> callback) { CefRefPtr<CefCompletionCallback> callback) {

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=00889895e17ac49f55668e395aa98a5f8312ee31$ // $hash=dd07d0157b7e9128b240ed2b059f2358ebf9fc09$
// //
#ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_CONTEXT_CTOCPP_H_ #ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_CONTEXT_CTOCPP_H_
@@ -63,6 +63,8 @@ class CefRequestContextCToCpp
CefString& error) OVERRIDE; CefString& error) OVERRIDE;
void ClearCertificateExceptions( void ClearCertificateExceptions(
CefRefPtr<CefCompletionCallback> callback) OVERRIDE; CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
void ClearHttpAuthCredentials(
CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
void CloseAllConnections(CefRefPtr<CefCompletionCallback> callback) OVERRIDE; void CloseAllConnections(CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
void ResolveHost(const CefString& origin, void ResolveHost(const CefString& origin,
CefRefPtr<CefResolveCallback> callback) OVERRIDE; CefRefPtr<CefResolveCallback> callback) OVERRIDE;

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=f286ec7520ee6b589b3ecafa409eb3f71c081e27$ // $hash=ad2fb4fa8e7c8e265de6e03e2c8c8d3d28a7fd39$
// //
#include "libcef_dll/ctocpp/request_handler_ctocpp.h" #include "libcef_dll/ctocpp/request_handler_ctocpp.h"
@@ -151,7 +151,7 @@ CefRequestHandlerCToCpp::GetResourceRequestHandler(
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
bool CefRequestHandlerCToCpp::GetAuthCredentials( bool CefRequestHandlerCToCpp::GetAuthCredentials(
CefRefPtr<CefBrowser> browser, CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, const CefString& origin_url,
bool isProxy, bool isProxy,
const CefString& host, const CefString& host,
int port, int port,
@@ -170,9 +170,9 @@ bool CefRequestHandlerCToCpp::GetAuthCredentials(
DCHECK(browser.get()); DCHECK(browser.get());
if (!browser.get()) if (!browser.get())
return false; return false;
// Verify param: frame; type: refptr_diff // Verify param: origin_url; type: string_byref_const
DCHECK(frame.get()); DCHECK(!origin_url.empty());
if (!frame.get()) if (origin_url.empty())
return false; return false;
// Verify param: host; type: string_byref_const // Verify param: host; type: string_byref_const
DCHECK(!host.empty()); DCHECK(!host.empty());
@@ -186,8 +186,8 @@ bool CefRequestHandlerCToCpp::GetAuthCredentials(
// Execute // Execute
int _retval = _struct->get_auth_credentials( int _retval = _struct->get_auth_credentials(
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame), _struct, CefBrowserCppToC::Wrap(browser), origin_url.GetStruct(), isProxy,
isProxy, host.GetStruct(), port, realm.GetStruct(), scheme.GetStruct(), host.GetStruct(), port, realm.GetStruct(), scheme.GetStruct(),
CefAuthCallbackCppToC::Wrap(callback)); CefAuthCallbackCppToC::Wrap(callback));
// Return type: bool // Return type: bool

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=1e21398533e04c0dbd4143a3847b44fb43c64bc5$ // $hash=dab1901a0bbeda97ef1efc8e5852964c318775f6$
// //
#ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_HANDLER_CTOCPP_H_ #ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_HANDLER_CTOCPP_H_
@@ -54,7 +54,7 @@ class CefRequestHandlerCToCpp
const CefString& request_initiator, const CefString& request_initiator,
bool& disable_default_handling) override; bool& disable_default_handling) override;
bool GetAuthCredentials(CefRefPtr<CefBrowser> browser, bool GetAuthCredentials(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, const CefString& origin_url,
bool isProxy, bool isProxy,
const CefString& host, const CefString& host,
int port, int port,

View File

@@ -368,9 +368,6 @@ patches = [
{ {
# macOS: Fix undesirable switch to discrete GPU during startup. # macOS: Fix undesirable switch to discrete GPU during startup.
# https://bitbucket.org/chromiumembedded/cef/issues/2398 # 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', 'name': 'mac_gpu',
}, },
{ {
@@ -423,6 +420,14 @@ patches = [
# https://bitbucket.org/chromiumembedded/cef/issues/2622 # https://bitbucket.org/chromiumembedded/cef/issues/2622
'name': 'services_network_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 # Windows: Remove the base::Value is_standard_layout assert which will fail
# for the cef_sandbox build, and which is no longer required. # for the cef_sandbox build, and which is no longer required.
@@ -445,10 +450,5 @@ patches = [
# unique_ptr types. # unique_ptr types.
# https://chromium-review.googlesource.com/c/chromium/src/+/1584292 # https://chromium-review.googlesource.com/c/chromium/src/+/1584292
'name': 'compositor_frame_reporting_controller_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',
} }
] ]

View File

@@ -1,5 +1,5 @@
diff --git chrome/browser/BUILD.gn chrome/browser/BUILD.gn 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
+++ chrome/browser/BUILD.gn +++ chrome/browser/BUILD.gn
@@ -8,6 +8,7 @@ import("//build/config/features.gni") @@ -8,6 +8,7 @@ import("//build/config/features.gni")
@@ -29,7 +29,7 @@ index 987b36217aad..832eab3ee56a 100644
if (is_android) { if (is_android) {
sources += [ sources += [
"after_startup_task_utils_android.cc", "after_startup_task_utils_android.cc",
@@ -3916,7 +3922,7 @@ jumbo_split_static_library("browser") { @@ -3917,7 +3923,7 @@ jumbo_split_static_library("browser") {
] ]
} }

View File

@@ -51,7 +51,7 @@ index 6c8e21f6f5fe..4496c5579265 100644
override; override;
network::NetworkQualityTracker* network_quality_tracker() override; network::NetworkQualityTracker* network_quality_tracker() override;
diff --git chrome/browser/ui/BUILD.gn chrome/browser/ui/BUILD.gn 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
+++ chrome/browser/ui/BUILD.gn +++ chrome/browser/ui/BUILD.gn
@@ -9,6 +9,7 @@ import("//build/config/features.gni") @@ -9,6 +9,7 @@ import("//build/config/features.gni")

View File

@@ -1,8 +1,8 @@
diff --git chrome/browser/chrome_content_browser_client.cc chrome/browser/chrome_content_browser_client.cc 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
+++ 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(); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kUserAgent)) { if (command_line->HasSwitch(switches::kUserAgent)) {
diff --git chrome/browser/chrome_content_browser_client.h chrome/browser/chrome_content_browser_client.h 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
+++ chrome/browser/chrome_content_browser_client.h +++ chrome/browser/chrome_content_browser_client.h
@@ -77,7 +77,8 @@ class Origin; @@ -77,7 +77,8 @@ class Origin;

View File

@@ -125,7 +125,7 @@ index daf826ece047..615200c4b41c 100644
// If we broke out of the loop, we have found an enabled plugin. // If we broke out of the loop, we have found an enabled plugin.
bool enabled = i < matching_plugins.size(); bool enabled = i < matching_plugins.size();
diff --git chrome/browser/plugins/plugin_utils.cc chrome/browser/plugins/plugin_utils.cc 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
+++ chrome/browser/plugins/plugin_utils.cc +++ chrome/browser/plugins/plugin_utils.cc
@@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
@@ -148,12 +148,15 @@ index 01ea0ba7f0cb..2828896bbcad 100644
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/browser/info_map.h" #include "extensions/browser/info_map.h"
#include "extensions/common/constants.h" #include "extensions/common/constants.h"
@@ -180,10 +186,23 @@ PluginUtils::GetMimeTypeToExtensionIdMap( @@ -180,10 +186,26 @@ PluginUtils::GetMimeTypeToExtensionIdMap(
content::ResourceContext* resource_context) { content::ResourceContext* resource_context) {
base::flat_map<std::string, std::string> mime_type_to_extension_id_map; base::flat_map<std::string, std::string> mime_type_to_extension_id_map;
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
+ +
+#if BUILDFLAG(ENABLE_CEF) +#if BUILDFLAG(ENABLE_CEF)
+ if (!extensions::ExtensionsEnabled())
+ return mime_type_to_extension_id_map;
+
+ CefResourceContext* context = + CefResourceContext* context =
+ static_cast<CefResourceContext*>(resource_context); + static_cast<CefResourceContext*>(resource_context);
+ bool profile_is_off_the_record = context->IsOffTheRecord(); + bool profile_is_off_the_record = context->IsOffTheRecord();
@@ -172,7 +175,7 @@ index 01ea0ba7f0cb..2828896bbcad 100644
std::vector<std::string> whitelist = MimeTypesHandler::GetMIMETypeWhitelist(); std::vector<std::string> whitelist = MimeTypesHandler::GetMIMETypeWhitelist();
// Go through the white-listed extensions and try to use them to intercept // Go through the white-listed extensions and try to use them to intercept
// the URL request. // the URL request.
@@ -198,7 +217,7 @@ PluginUtils::GetMimeTypeToExtensionIdMap( @@ -198,7 +220,7 @@ PluginUtils::GetMimeTypeToExtensionIdMap(
} }
if (extension_id == extension_misc::kPdfExtensionId && if (extension_id == extension_misc::kPdfExtensionId &&

View File

@@ -262,10 +262,10 @@ index 3009401dac6b..b4c5a9e2db50 100644
}; };
diff --git content/common/frame_messages.h content/common/frame_messages.h 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
+++ 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. // type. If there is no matching plugin, |found| is false.
// |actual_mime_type| is the actual mime type supported by the // |actual_mime_type| is the actual mime type supported by the
// found plugin. // found plugin.
@@ -278,10 +278,10 @@ index 8673d65844ea..7d13c72dca9b 100644
std::string /* mime_type */, std::string /* mime_type */,
bool /* found */, bool /* found */,
diff --git content/public/browser/content_browser_client.h content/public/browser/content_browser_client.h 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
+++ 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::URLLoaderFactoryRequest* factory_request,
network::mojom::URLLoaderFactory*& out_factory); 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 // 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 // will house the content shown when in Picture-in-Picture mode. This will
// return a new OverlayWindow. // 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. // Used as part of the user agent string.
virtual std::string GetProduct() const; virtual std::string GetProduct() const;
@@ -372,10 +372,10 @@ index 8935697155f5..179b6ebf1360 100644
virtual void FocusedNodeChanged(const blink::WebNode& node) {} virtual void FocusedNodeChanged(const blink::WebNode& node) {}
diff --git content/renderer/render_frame_impl.cc content/renderer/render_frame_impl.cc 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
+++ 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; std::string mime_type;
bool found = false; bool found = false;
Send(new FrameHostMsg_GetPluginInfo( Send(new FrameHostMsg_GetPluginInfo(
@@ -385,7 +385,7 @@ index c75b6177f066..860bbe9e1c14 100644
params.mime_type.Utf8(), &found, &info, &mime_type)); params.mime_type.Utf8(), &found, &info, &mime_type));
if (!found) if (!found)
return nullptr; return nullptr;
@@ -4422,6 +4423,8 @@ void RenderFrameImpl::FrameDetached(DetachType type) { @@ -4473,6 +4474,8 @@ void RenderFrameImpl::FrameDetached(DetachType type) {
void RenderFrameImpl::FrameFocused() { void RenderFrameImpl::FrameFocused() {
Send(new FrameHostMsg_FrameFocused(routing_id_)); Send(new FrameHostMsg_FrameFocused(routing_id_));

View File

@@ -68,10 +68,10 @@ index c3511e3e6a66..3500f4a2b005 100644
void ChromeBrowserMainExtraPartsViewsLinux::ToolkitInitialized() { void ChromeBrowserMainExtraPartsViewsLinux::ToolkitInitialized() {
diff --git chrome/test/BUILD.gn chrome/test/BUILD.gn 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
+++ 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", "../browser/ui/input_method/input_method_engine_unittest.cc",
] ]
} }
@@ -80,7 +80,7 @@ index 5406779a17c2..b1ed0f2c970b 100644
sources += sources +=
[ "../browser/ui/libgtkui/select_file_dialog_impl_gtk_unittest.cc" ] [ "../browser/ui/libgtkui/select_file_dialog_impl_gtk_unittest.cc" ]
deps += [ "//build/config/linux/gtk" ] deps += [ "//build/config/linux/gtk" ]
@@ -4180,7 +4180,7 @@ test("unit_tests") { @@ -4191,7 +4191,7 @@ test("unit_tests") {
if (use_gio) { if (use_gio) {
configs += [ "//build/linux:gio_config" ] configs += [ "//build/linux:gio_config" ]
} }
@@ -89,7 +89,7 @@ index 5406779a17c2..b1ed0f2c970b 100644
deps += [ "//chrome/browser/ui/libgtkui" ] 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. # suites, it seems like one or another starts timing out too.
"../browser/ui/views/keyboard_access_browsertest.cc", "../browser/ui/views/keyboard_access_browsertest.cc",
] ]

View File

@@ -1,5 +1,5 @@
diff --git base/files/file_path_watcher_linux.cc base/files/file_path_watcher_linux.cc 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
+++ base/files/file_path_watcher_linux.cc +++ base/files/file_path_watcher_linux.cc
@@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
@@ -15,10 +15,10 @@ index 22732f2864ef..7d5caef5c3b0 100644
#include <algorithm> #include <algorithm>
+#include <array> +#include <array>
#include <fstream>
#include <map> #include <map>
#include <memory> #include <memory>
#include <set> @@ -263,22 +265,15 @@ void InotifyReaderThreadDelegate::ThreadMain() {
@@ -220,22 +222,15 @@ void InotifyReaderThreadDelegate::ThreadMain() {
PlatformThread::SetName("inotify_reader"); PlatformThread::SetName("inotify_reader");
// Make sure the file descriptors are good for use with select(). // Make sure the file descriptors are good for use with select().

View File

@@ -1,5 +1,5 @@
diff --git ui/gl/init/gl_initializer_mac.cc ui/gl/init/gl_initializer_mac.cc 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
+++ ui/gl/init/gl_initializer_mac.cc +++ ui/gl/init/gl_initializer_mac.cc
@@ -46,11 +46,8 @@ bool InitializeOneOffForSandbox() { @@ -46,11 +46,8 @@ bool InitializeOneOffForSandbox() {
@@ -16,14 +16,3 @@ index 85cab0eaef3e..37b2d42a34f5 100644
if (GetGLImplementation() == kGLImplementationAppleGL) { if (GetGLImplementation() == kGLImplementationAppleGL) {
attribs.push_back(kCGLPFARendererID); attribs.push_back(kCGLPFARendererID);
attribs.push_back( 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.";

View File

@@ -1,5 +1,5 @@
diff --git content/public/common/common_param_traits_macros.h content/public/common/common_param_traits_macros.h 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
+++ 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) @@ -189,6 +189,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences)
@@ -35,7 +35,7 @@ index a83015f3629a..fe79480e9af7 100644
bool record_whole_document; bool record_whole_document;
diff --git content/renderer/render_view_impl.cc content/renderer/render_view_impl.cc 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
+++ content/renderer/render_view_impl.cc +++ content/renderer/render_view_impl.cc
@@ -1026,6 +1026,8 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs, @@ -1026,6 +1026,8 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,

View File

@@ -1,5 +1,5 @@
diff --git chrome/browser/renderer_preferences_util.cc chrome/browser/renderer_preferences_util.cc 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
+++ chrome/browser/renderer_preferences_util.cc +++ chrome/browser/renderer_preferences_util.cc
@@ -29,7 +29,8 @@ @@ -29,7 +29,8 @@

View File

@@ -35,7 +35,7 @@ index 2b24d1ac1b5b..6577495d87a9 100644
base_cache_path.Append(chrome::kCacheDirname); base_cache_path.Append(chrome::kCacheDirname);
network_context_params->http_cache_max_size = network_context_params->http_cache_max_size =
diff --git chrome/browser/profiles/profile.h chrome/browser/profiles/profile.h 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
+++ chrome/browser/profiles/profile.h +++ chrome/browser/profiles/profile.h
@@ -321,6 +321,11 @@ class Profile : public content::BrowserContext { @@ -321,6 +321,11 @@ class Profile : public content::BrowserContext {
@@ -132,10 +132,10 @@ index 8be1b9dea5f7..30f23449ac51 100644
void CookieManager::SetForceKeepSessionState() { void CookieManager::SetForceKeepSessionState() {
diff --git services/network/network_context.cc services/network/network_context.cc 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
+++ 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; scoped_refptr<SessionCleanupCookieStore> session_cleanup_cookie_store;
@@ -143,7 +143,7 @@ index 9d6f7b930e11..c16e5ca90c14 100644
if (params_->cookie_path) { if (params_->cookie_path) {
scoped_refptr<base::SequencedTaskRunner> client_task_runner = scoped_refptr<base::SequencedTaskRunner> client_task_runner =
base::MessageLoopCurrent::Get()->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 = session_cleanup_cookie_store =
base::MakeRefCounted<SessionCleanupCookieStore>(sqlite_store); base::MakeRefCounted<SessionCleanupCookieStore>(sqlite_store);

View 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;

View File

@@ -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;

View File

@@ -52,7 +52,7 @@ index b2b3920da3b0..686afc464b42 100644
std::move(stats_db), BrowserFeatureProvider::GetFactoryCB()); std::move(stats_db), BrowserFeatureProvider::GetFactoryCB());
decode_history = new_decode_history.get(); 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 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
+++ 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() { @@ -2203,6 +2203,9 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {

View File

@@ -39,7 +39,7 @@ index cce16a111356..9f0a8b73adb5 100644
virtual void MenuWillShow() {} virtual void MenuWillShow() {}
diff --git ui/gfx/render_text.cc ui/gfx/render_text.cc 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
+++ ui/gfx/render_text.cc +++ ui/gfx/render_text.cc
@@ -514,6 +514,14 @@ void RenderText::SetElideBehavior(ElideBehavior elide_behavior) { @@ -514,6 +514,14 @@ void RenderText::SetElideBehavior(ElideBehavior elide_behavior) {
@@ -240,7 +240,7 @@ index 9df5c850d12d..e7007ffbb762 100644
std::unique_ptr<SelectionController> selection_controller_; std::unique_ptr<SelectionController> selection_controller_;
diff --git ui/views/controls/menu/menu_controller.cc ui/views/controls/menu/menu_controller.cc 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
+++ ui/views/controls/menu/menu_controller.cc +++ ui/views/controls/menu/menu_controller.cc
@@ -2570,8 +2570,13 @@ MenuItemView* MenuController::FindNextSelectableMenuItem( @@ -2570,8 +2570,13 @@ MenuItemView* MenuController::FindNextSelectableMenuItem(

View File

@@ -411,7 +411,7 @@ index 5bcb8d8b9bae..020fa85573aa 100644
if (native_widget_delegate->IsDialogBox()) { if (native_widget_delegate->IsDialogBox()) {
*style |= DS_MODALFRAME; *style |= DS_MODALFRAME;
diff --git ui/views/win/hwnd_message_handler.cc ui/views/win/hwnd_message_handler.cc 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
+++ ui/views/win/hwnd_message_handler.cc +++ ui/views/win/hwnd_message_handler.cc
@@ -2918,10 +2918,13 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message, @@ -2918,10 +2918,13 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,

View File

@@ -1,8 +1,8 @@
diff --git content/browser/web_contents/web_contents_impl.cc content/browser/web_contents/web_contents_impl.cc 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
+++ 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; std::string unique_name;
frame_tree_.root()->SetFrameName(params.main_frame_name, 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(render_view_host_delegate_view_);
CHECK(view_.get()); CHECK(view_.get());
@@ -2781,6 +2790,15 @@ void WebContentsImpl::CreateNewWindow( @@ -2783,6 +2792,15 @@ void WebContentsImpl::CreateNewWindow(
create_params.renderer_initiated_creation = create_params.renderer_initiated_creation =
main_frame_route_id != MSG_ROUTING_NONE; main_frame_route_id != MSG_ROUTING_NONE;
@@ -61,7 +61,7 @@ index 1491bf580c59..ab2c83357303 100644
std::unique_ptr<WebContents> new_contents; std::unique_ptr<WebContents> new_contents;
if (!is_guest) { if (!is_guest) {
create_params.context = view_->GetNativeView(); 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 // 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. // newly created object and give it one of its own member variables.
new_view->CreateViewForWidget( new_view->CreateViewForWidget(
@@ -70,7 +70,7 @@ index 1491bf580c59..ab2c83357303 100644
} }
// Save the created window associated with the route so we can show it // Save the created window associated with the route so we can show it
// later. // later.
@@ -6372,7 +6390,7 @@ InterstitialPageImpl* WebContentsImpl::GetInterstitialForRenderManager() { @@ -6382,7 +6400,7 @@ InterstitialPageImpl* WebContentsImpl::GetInterstitialForRenderManager() {
void WebContentsImpl::CreateRenderWidgetHostViewForRenderManager( void WebContentsImpl::CreateRenderWidgetHostViewForRenderManager(
RenderViewHost* render_view_host) { RenderViewHost* render_view_host) {
RenderWidgetHostViewBase* rwh_view = RenderWidgetHostViewBase* rwh_view =

View File

@@ -44,7 +44,7 @@ index a616fafed51f..dae131dad5de 100644
.Top() .Top()
.GetSecurityContext() .GetSecurityContext()
diff --git third_party/blink/renderer/core/frame/local_frame.cc third_party/blink/renderer/core/frame/local_frame.cc 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
+++ 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() { @@ -1257,7 +1257,7 @@ FrameResourceCoordinator* LocalFrame::GetFrameResourceCoordinator() {
@@ -85,10 +85,10 @@ index 6435384652b7..79bd103df30d 100644
void DevToolsSession::FlushProtocolNotifications() { void DevToolsSession::FlushProtocolNotifications() {
diff --git third_party/blink/renderer/core/page/page.cc third_party/blink/renderer/core/page/page.cc 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
+++ 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(), MakeGarbageCollected<OverscrollController>(GetVisualViewport(),
GetChromeClient())), GetChromeClient())),
link_highlights_(MakeGarbageCollected<LinkHighlights>(*this)), link_highlights_(MakeGarbageCollected<LinkHighlights>(*this)),
@@ -98,7 +98,7 @@ index 5480f0e29789..3bf2f35c9741 100644
// TODO(pdr): Initialize |validation_message_client_| lazily. // TODO(pdr): Initialize |validation_message_client_| lazily.
validation_message_client_( validation_message_client_(
MakeGarbageCollected<ValidationMessageClientImpl>(*this)), 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(); 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(link_highlights_);
visitor->Trace(spatial_navigation_controller_); visitor->Trace(spatial_navigation_controller_);
visitor->Trace(main_frame_); visitor->Trace(main_frame_);
@@ -159,7 +159,7 @@ index 5480f0e29789..3bf2f35c9741 100644
visitor->Trace(plugins_changed_observers_); visitor->Trace(plugins_changed_observers_);
visitor->Trace(next_related_page_); visitor->Trace(next_related_page_);
diff --git third_party/blink/renderer/core/page/page.h third_party/blink/renderer/core/page/page.h 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
+++ 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>, @@ -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 // Resets the plugin data for all pages in the renderer process and notifies
// PluginsChangedObservers. // 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_; const Member<LinkHighlights> link_highlights_;
Member<SpatialNavigationController> spatial_navigation_controller_; Member<SpatialNavigationController> spatial_navigation_controller_;

View File

@@ -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 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
+++ 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) { for (auto pointer_event : canceled_pointer_events) {
// If we are sending a pointercancel we have sent the pointerevent to some // If we are sending a pointercancel we have sent the pointerevent to some
// target before. // target before.

View File

@@ -11,7 +11,7 @@ index f831c084e1d3..80dd4ea3a154 100644
// Cancels and hides the current popup (datetime, select...) if any. // Cancels and hides the current popup (datetime, select...) if any.
virtual void CancelPagePopup() = 0; 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 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
+++ 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) { @@ -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)) { fullscreen_controller_(std::make_unique<FullscreenController>(this)) {
if (!AsView().client) { 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 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
+++ 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, @@ -105,7 +105,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,

View File

@@ -1,8 +1,8 @@
diff --git chrome/app/generated_resources.grd chrome/app/generated_resources.grd 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
+++ 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> </message>
</if> </if>
<message name="IDS_PLUGIN_BLOCKED_BY_POLICY" desc="The placeholder text for a plugin blocked by enterprise policy."> <message name="IDS_PLUGIN_BLOCKED_BY_POLICY" desc="The placeholder text for a plugin blocked by enterprise policy.">

View File

@@ -702,6 +702,32 @@ CefRefPtr<CefResourceRequestHandler> ClientHandler::GetResourceRequestHandler(
return this; 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, bool ClientHandler::OnQuotaRequest(CefRefPtr<CefBrowser> browser,
const CefString& origin_url, const CefString& origin_url,
int64 new_size, int64 new_size,

View File

@@ -229,6 +229,14 @@ class ClientHandler : public CefClient,
bool is_download, bool is_download,
const CefString& request_initiator, const CefString& request_initiator,
bool& disable_default_handling) OVERRIDE; 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, bool OnQuotaRequest(CefRefPtr<CefBrowser> browser,
const CefString& origin_url, const CefString& origin_url,
int64 new_size, int64 new_size,

View File

@@ -126,9 +126,10 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
const RequestClient::Callback& request_callback = const RequestClient::Callback& request_callback =
base::Bind(&Handler::OnRequestComplete, base::Unretained(this)); base::Bind(&Handler::OnRequestComplete, base::Unretained(this));
// Create and start the new CefURLRequest. // Create and start a new CefURLRequest associated with the frame, so
urlrequest_ = CefURLRequest::Create( // that it shares authentication with ClientHandler::GetAuthCredentials.
cef_request, new RequestClient(request_callback), NULL); urlrequest_ = frame->CreateURLRequest(
cef_request, new RequestClient(request_callback));
return true; return true;
} }

View File

@@ -7,11 +7,13 @@
<ul> <ul>
<li><a href="http://mudcu.be/labs/JS1k/BreathingGalaxies.html">Accelerated 2D Canvas</a></li> <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="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="http://html5advent2011.digitpaint.nl/3/index.html">Cursors</a></li>
<li><a href="dialogs">Dialogs</a></li> <li><a href="dialogs">Dialogs</a></li>
<li><a href="http://html5demos.com/drag">Drag & Drop</a></li> <li><a href="http://html5demos.com/drag">Drag & Drop</a></li>
<li><a href="draggable">Draggable Regions</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.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://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> <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="urlrequest">CefURLRequest</a></li>
<li><a href="xmlhttprequest">XMLHttpRequest</a></li> <li><a href="xmlhttprequest">XMLHttpRequest</a></li>
<li><a href="javascript:window.print();">Print this page with &quot;javascript:window.print();&quot;</a></li> <li><a href="javascript:window.print();">Print this page with &quot;javascript:window.print();&quot;</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> </ul>
</body> </body>
</html> </html>

View File

@@ -1067,13 +1067,13 @@ std::string GetCookieAccessUrl2(const std::string& scheme,
} }
void TestCookieString(const std::string& cookie_str, void TestCookieString(const std::string& cookie_str,
TrackCallback& got_cookie_js, int& cookie_js_ct,
TrackCallback& got_cookie_net) { int& cookie_net_ct) {
if (cookie_str.find("name_js=value_js") != std::string::npos) { 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) { 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; CefRefPtr<CefResponse> response;
std::string response_data; std::string response_data;
TrackCallback got_request_; int request_ct_ = 0;
TrackCallback got_cookie_js_; int cookie_js_ct_ = 0;
TrackCallback got_cookie_net_; int cookie_net_ct_ = 0;
}; };
class CookieAccessResponseHandler { class CookieAccessResponseHandler {
@@ -1116,7 +1116,7 @@ class CookieAccessSchemeHandler : public CefResourceHandler {
CefRequest::HeaderMap headerMap; CefRequest::HeaderMap headerMap;
request->GetHeaderMap(headerMap); request->GetHeaderMap(headerMap);
const std::string& cookie_str = GetHeaderValue(headerMap, "Cookie"); 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. // Continue immediately.
callback->Continue(); callback->Continue();
@@ -1203,7 +1203,7 @@ class CookieAccessSchemeHandlerFactory : public CefSchemeHandlerFactory,
const std::string& url = request->GetURL(); const std::string& url = request->GetURL();
ResponseDataMap::const_iterator it = data_map_.find(url); ResponseDataMap::const_iterator it = data_map_.find(url);
if (it != data_map_.end()) { if (it != data_map_.end()) {
it->second->got_request_.yes(); it->second->request_ct_++;
return new CookieAccessSchemeHandler(it->second); return new CookieAccessSchemeHandler(it->second);
} }
@@ -1425,13 +1425,13 @@ class CookieAccessServerHandler : public CefServerHandler,
const std::string& url = request->GetURL(); const std::string& url = request->GetURL();
ResponseDataMap::const_iterator it = data_map_.find(url); ResponseDataMap::const_iterator it = data_map_.find(url);
if (it != data_map_.end()) { if (it != data_map_.end()) {
it->second->got_request_.yes(); it->second->request_ct_++;
CefRequest::HeaderMap headerMap; CefRequest::HeaderMap headerMap;
request->GetHeaderMap(headerMap); request->GetHeaderMap(headerMap);
const std::string& cookie_str = GetHeaderValue(headerMap, "cookie"); const std::string& cookie_str = GetHeaderValue(headerMap, "cookie");
TestCookieString(cookie_str, it->second->got_cookie_js_, TestCookieString(cookie_str, it->second->cookie_js_ct_,
it->second->got_cookie_net_); it->second->cookie_net_ct_);
SendResponse(server, connection_id, it->second->response, SendResponse(server, connection_id, it->second->response,
it->second->response_data); it->second->response_data);
@@ -1593,10 +1593,8 @@ class CookieAccessTestHandler : public RoutingTestHandler,
context_ = NULL; context_ = NULL;
// Got both network requests. // Got both network requests.
EXPECT_TRUE(data1_.got_request_); EXPECT_EQ(1, data1_.request_ct_);
EXPECT_TRUE(data2_.got_request_); EXPECT_EQ(1, data2_.request_ct_);
EXPECT_FALSE(got_cookie_manager_);
if (test_mode_ == ALLOW_NO_FILTER || test_mode_ == ALLOW_NO_HANDLER) { if (test_mode_ == ALLOW_NO_FILTER || test_mode_ == ALLOW_NO_HANDLER) {
EXPECT_EQ(0, can_save_cookie1_ct_); EXPECT_EQ(0, can_save_cookie1_ct_);
@@ -1621,44 +1619,44 @@ class CookieAccessTestHandler : public RoutingTestHandler,
if (test_mode_ == BLOCK_ALL_COOKIES) { if (test_mode_ == BLOCK_ALL_COOKIES) {
// Never get the JS cookie via JS. // Never get the JS cookie via JS.
EXPECT_FALSE(got_cookie_js1_); EXPECT_EQ(0, cookie_js1_ct_);
EXPECT_FALSE(got_cookie_js2_); EXPECT_EQ(0, cookie_js2_ct_);
EXPECT_FALSE(got_cookie_js3_); EXPECT_EQ(0, cookie_js3_ct_);
} else { } else {
// Always get the JS cookie via JS. // Always get the JS cookie via JS.
EXPECT_TRUE(got_cookie_js1_); EXPECT_EQ(1, cookie_js1_ct_);
EXPECT_TRUE(got_cookie_js2_); EXPECT_EQ(1, cookie_js2_ct_);
EXPECT_TRUE(got_cookie_js3_); EXPECT_EQ(1, cookie_js3_ct_);
} }
// Only get the net cookie via JS if cookie write was allowed. // Only get the net cookie via JS if cookie write was allowed.
if ((test_mode_ & BLOCK_WRITE) || test_mode_ == BLOCK_ALL_COOKIES) { if ((test_mode_ & BLOCK_WRITE) || test_mode_ == BLOCK_ALL_COOKIES) {
EXPECT_FALSE(got_cookie_net1_); EXPECT_EQ(0, cookie_net1_ct_);
EXPECT_FALSE(got_cookie_net2_); EXPECT_EQ(0, cookie_net2_ct_);
EXPECT_FALSE(got_cookie_net3_); EXPECT_EQ(0, cookie_net3_ct_);
} else { } else {
EXPECT_TRUE(got_cookie_net1_); EXPECT_EQ(1, cookie_net1_ct_);
EXPECT_TRUE(got_cookie_net2_); EXPECT_EQ(1, cookie_net2_ct_);
EXPECT_TRUE(got_cookie_net3_); EXPECT_EQ(1, cookie_net3_ct_);
} }
// No cookies sent for the 1st network request. // No cookies sent for the 1st network request.
EXPECT_FALSE(data1_.got_cookie_js_); EXPECT_EQ(0, data1_.cookie_js_ct_);
EXPECT_FALSE(data1_.got_cookie_net_); EXPECT_EQ(0, data1_.cookie_net_ct_);
// 2nd network request... // 2nd network request...
if ((test_mode_ & BLOCK_READ) || test_mode_ == BLOCK_ALL_COOKIES) { if ((test_mode_ & BLOCK_READ) || test_mode_ == BLOCK_ALL_COOKIES) {
// No cookies sent if reading was blocked. // No cookies sent if reading was blocked.
EXPECT_FALSE(data2_.got_cookie_js_); EXPECT_EQ(0, data2_.cookie_js_ct_);
EXPECT_FALSE(data2_.got_cookie_net_); EXPECT_EQ(0, data2_.cookie_net_ct_);
} else if (test_mode_ & BLOCK_WRITE) { } else if (test_mode_ & BLOCK_WRITE) {
// Only JS cookie sent if writing was blocked. // Only JS cookie sent if writing was blocked.
EXPECT_TRUE(data2_.got_cookie_js_); EXPECT_EQ(1, data2_.cookie_js_ct_);
EXPECT_FALSE(data2_.got_cookie_net_); EXPECT_EQ(0, data2_.cookie_net_ct_);
} else { } else {
// All cookies sent. // All cookies sent.
EXPECT_TRUE(data2_.got_cookie_js_); EXPECT_EQ(1, data2_.cookie_js_ct_);
EXPECT_TRUE(data2_.got_cookie_net_); EXPECT_EQ(1, data2_.cookie_net_ct_);
} }
TestHandler::DestroyTest(); TestHandler::DestroyTest();
@@ -1747,11 +1745,11 @@ class CookieAccessTestHandler : public RoutingTestHandler,
const std::string& url = frame->GetURL(); const std::string& url = frame->GetURL();
const std::string& cookie_str = request.ToString(); const std::string& cookie_str = request.ToString();
if (url == GetCookieAccessUrl1(scheme_, test_backend_ == SERVER)) { 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( browser->GetMainFrame()->LoadURL(
GetCookieAccessUrl2(scheme_, test_backend_ == SERVER)); GetCookieAccessUrl2(scheme_, test_backend_ == SERVER));
} else if (url == 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(); FinishTest();
} else { } else {
ADD_FAILURE() << "Unexpected url: " << url; ADD_FAILURE() << "Unexpected url: " << url;
@@ -1873,9 +1871,9 @@ class CookieAccessTestHandler : public RoutingTestHandler,
const std::string& name = CefString(&cookie.name); const std::string& name = CefString(&cookie.name);
const std::string& value = CefString(&cookie.value); const std::string& value = CefString(&cookie.value);
if (name == "name_js" && value == "value_js") if (name == "name_js" && value == "value_js")
handler_->got_cookie_js3_.yes(); handler_->cookie_js3_ct_++;
else if (name == "name_net" && value == "value_net") else if (name == "name_net" && value == "value_net")
handler_->got_cookie_net3_.yes(); handler_->cookie_net3_ct_++;
// Clean up the cookies. // Clean up the cookies.
deleteCookie = true; deleteCookie = true;
@@ -1930,21 +1928,19 @@ class CookieAccessTestHandler : public RoutingTestHandler,
CookieAccessData data1_; CookieAccessData data1_;
CookieAccessData data2_; CookieAccessData data2_;
TrackCallback got_cookie_manager_;
// 1st request. // 1st request.
int can_save_cookie1_ct_ = 0; int can_save_cookie1_ct_ = 0;
TrackCallback got_cookie_js1_; int cookie_js1_ct_ = 0;
TrackCallback got_cookie_net1_; int cookie_net1_ct_ = 0;
// 2nd request. // 2nd request.
int can_send_cookie2_ct_ = 0; int can_send_cookie2_ct_ = 0;
TrackCallback got_cookie_js2_; int cookie_js2_ct_ = 0;
TrackCallback got_cookie_net2_; int cookie_net2_ct_ = 0;
// From cookie manager. // From cookie manager.
TrackCallback got_cookie_js3_; int cookie_js3_ct_ = 0;
TrackCallback got_cookie_net3_; int cookie_net3_ct_ = 0;
DISALLOW_COPY_AND_ASSIGN(CookieAccessTestHandler); DISALLOW_COPY_AND_ASSIGN(CookieAccessTestHandler);
IMPLEMENT_REFCOUNTING(CookieAccessTestHandler); IMPLEMENT_REFCOUNTING(CookieAccessTestHandler);
@@ -2026,6 +2022,397 @@ ACCESS_TEST_ALLOWNOHANDLER_MODES(SchemeStandard, SCHEME_HANDLER, false)
ACCESS_TEST_CUSTOM(Resource, RESOURCE_HANDLER) ACCESS_TEST_CUSTOM(Resource, RESOURCE_HANDLER)
ACCESS_TEST_STANDARD(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. // Entry point for registering custom schemes.
// Called from client_app_delegates.cc. // Called from client_app_delegates.cc.
void RegisterCookieCustomSchemes(CefRawPtr<CefSchemeRegistrar> registrar, void RegisterCookieCustomSchemes(CefRawPtr<CefSchemeRegistrar> registrar,

View File

@@ -393,6 +393,11 @@ class FrameNavRendererTest : public ClientAppRenderer::Delegate,
EXPECT_TRUE(args.get()); EXPECT_TRUE(args.get());
EXPECT_TRUE(args->SetInt(0, nav_)); EXPECT_TRUE(args->SetInt(0, nav_));
EXPECT_TRUE(args->SetBool(1, result)); 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); frame->SendProcessMessage(PID_BROWSER, return_msg);
nav_++; nav_++;
@@ -527,6 +532,11 @@ class FrameNavTestHandler : public TestHandler {
EXPECT_TRUE(expectations_->OnRendererComplete( EXPECT_TRUE(expectations_->OnRendererComplete(
browser, frame, args->GetInt(0), args->GetBool(1))) browser, frame, args->GetInt(0), args->GetBool(1)))
<< "nav = " << nav_; << "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; return true;
} }

View File

@@ -163,6 +163,14 @@ class BasicResponseTest : public TestHandler {
// Normal load, nothing fancy. // Normal load, nothing fancy.
LOAD, 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 // Don't continue from OnBeforeResourceLoad, then close the browser to
// verify destruction handling of in-progress requests. // verify destruction handling of in-progress requests.
INCOMPLETE_BEFORE_RESOURCE_LOAD, INCOMPLETE_BEFORE_RESOURCE_LOAD,
@@ -207,6 +215,25 @@ class BasicResponseTest : public TestHandler {
SetTestTimeout(); 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, bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request, CefRefPtr<CefRequest> request,
@@ -233,6 +260,11 @@ class BasicResponseTest : public TestHandler {
VerifyState(kOnBeforeBrowse, request, nullptr); VerifyState(kOnBeforeBrowse, request, nullptr);
if (mode_ == ABORT_BEFORE_BROWSE) {
SetSignalCompletionWhenAllBrowsersClose(false);
CloseBrowser(browser, false);
}
return false; return false;
} }
@@ -475,7 +507,7 @@ class BasicResponseTest : public TestHandler {
VerifyState(kOnResourceLoadComplete, request, response); VerifyState(kOnResourceLoadComplete, request, response);
if (unhandled_ || IsIncomplete()) { if (unhandled_ || IsIncomplete() || IsAborted()) {
EXPECT_EQ(UR_FAILED, status); EXPECT_EQ(UR_FAILED, status);
EXPECT_EQ(0, received_content_length); EXPECT_EQ(0, received_content_length);
} else { } else {
@@ -661,19 +693,36 @@ class BasicResponseTest : public TestHandler {
EXPECT_EQ(0, get_resource_response_filter_ct_); EXPECT_EQ(0, get_resource_response_filter_ct_);
EXPECT_EQ(0, on_resource_response_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 { } else {
NOTREACHED(); NOTREACHED();
} }
EXPECT_EQ(resource_handler_created_ct_, resource_handler_destroyed_ct_); 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_); EXPECT_EQ(0, on_load_end_ct_);
else else
EXPECT_EQ(1, on_load_end_ct_); 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_); EXPECT_EQ(1, on_protocol_execution_ct_);
else else
EXPECT_EQ(0, on_protocol_execution_ct_); EXPECT_EQ(0, on_protocol_execution_ct_);
@@ -715,7 +764,7 @@ class BasicResponseTest : public TestHandler {
} }
const char* GetStartupURL() const { const char* GetStartupURL() const {
if (IsLoad() || IsIncomplete()) { if (IsLoad() || IsIncomplete() || IsAborted()) {
return GetURL(RESULT_HTML); return GetURL(RESULT_HTML);
} else if (mode_ == REDIRECT_RESOURCE_REDIRECT) { } else if (mode_ == REDIRECT_RESOURCE_REDIRECT) {
return GetURL(REDIRECT2_HTML); return GetURL(REDIRECT2_HTML);
@@ -786,6 +835,10 @@ class BasicResponseTest : public TestHandler {
IsIncompleteRequestHandler(); IsIncompleteRequestHandler();
} }
bool IsAborted() const {
return mode_ == ABORT_AFTER_CREATED || mode_ == ABORT_BEFORE_BROWSE;
}
bool IsRedirect() const { bool IsRedirect() const {
return mode_ == REDIRECT_BEFORE_RESOURCE_LOAD || return mode_ == REDIRECT_BEFORE_RESOURCE_LOAD ||
mode_ == REDIRECT_REQUEST_HANDLER || mode_ == REDIRECT_REQUEST_HANDLER ||
@@ -852,7 +905,7 @@ class BasicResponseTest : public TestHandler {
EXPECT_EQ(request_id_, request->GetIdentifier()) << callback; 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("GET", request->GetMethod().ToString().c_str()) << callback;
EXPECT_STREQ(GetURL(RESULT_HTML), request->GetURL().ToString().c_str()) EXPECT_STREQ(GetURL(RESULT_HTML), request->GetURL().ToString().c_str())
<< callback; << callback;
@@ -912,7 +965,8 @@ class BasicResponseTest : public TestHandler {
// response. // response.
const bool incomplete_unhandled = const bool incomplete_unhandled =
(mode_ == INCOMPLETE_BEFORE_RESOURCE_LOAD || (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 ((unhandled_ && !override_unhandled) || incomplete_unhandled) {
if (incomplete_unhandled) { if (incomplete_unhandled) {
@@ -927,7 +981,7 @@ class BasicResponseTest : public TestHandler {
EXPECT_STREQ("", response->GetMimeType().ToString().c_str()) << callback; EXPECT_STREQ("", response->GetMimeType().ToString().c_str()) << callback;
EXPECT_STREQ("", response->GetCharset().ToString().c_str()) << callback; EXPECT_STREQ("", response->GetCharset().ToString().c_str()) << callback;
} else { } else {
if (mode_ == INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE && if ((mode_ == INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE || IsAborted()) &&
callback == kOnResourceLoadComplete) { callback == kOnResourceLoadComplete) {
// We got a response, but we also got aborted. // We got a response, but we also got aborted.
EXPECT_EQ(ERR_ABORTED, response->GetError()) << callback; EXPECT_EQ(ERR_ABORTED, response->GetError()) << callback;
@@ -1035,7 +1089,9 @@ bool IsTestSupported(BasicResponseTest::TestMode test_mode,
// for custom schemes and unhandled requests. // for custom schemes and unhandled requests.
return false; 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 == test_mode ==
BasicResponseTest::INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST || BasicResponseTest::INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST ||
test_mode == test_mode ==
@@ -1063,6 +1119,8 @@ bool IsTestSupported(BasicResponseTest::TestMode test_mode,
#define BASIC_TEST_ALL_MODES(name, custom, unhandled) \ #define BASIC_TEST_ALL_MODES(name, custom, unhandled) \
BASIC_TEST(name##Load, LOAD, 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, \ BASIC_TEST(name##ModifyBeforeResourceLoad, MODIFY_BEFORE_RESOURCE_LOAD, \
custom, unhandled) \ custom, unhandled) \
BASIC_TEST(name##RedirectBeforeResourceLoad, REDIRECT_BEFORE_RESOURCE_LOAD, \ BASIC_TEST(name##RedirectBeforeResourceLoad, REDIRECT_BEFORE_RESOURCE_LOAD, \

View File

@@ -450,6 +450,11 @@ void TestHandler::SetTestTimeout(int timeout_ms, bool treat_as_error) {
return; 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( if (treat_as_error && CefCommandLine::GetGlobalCommandLine()->HasSwitch(
"disable-test-timeout")) { "disable-test-timeout")) {
return; return;
@@ -475,7 +480,7 @@ void TestHandler::TestComplete() {
TestHandler::UIThreadHelper* TestHandler::GetUIThreadHelper() { TestHandler::UIThreadHelper* TestHandler::GetUIThreadHelper() {
EXPECT_UI_THREAD(); EXPECT_UI_THREAD();
EXPECT_FALSE(destroy_test_called_); CHECK(!destroy_test_called_);
if (!ui_thread_helper_.get()) if (!ui_thread_helper_.get())
ui_thread_helper_.reset(new UIThreadHelper()); ui_thread_helper_.reset(new UIThreadHelper());

View File

@@ -7,6 +7,7 @@
#include <sstream> #include <sstream>
#include "include/base/cef_bind.h" #include "include/base/cef_bind.h"
#include "include/cef_parser.h"
#include "include/cef_request_context_handler.h" #include "include/cef_request_context_handler.h"
#include "include/cef_scheme.h" #include "include/cef_scheme.h"
#include "include/cef_server.h" #include "include/cef_server.h"
@@ -65,9 +66,12 @@ enum RequestTestMode {
REQTEST_GET_REDIRECT_STOP, REQTEST_GET_REDIRECT_STOP,
REQTEST_GET_REDIRECT_LOCATION, REQTEST_GET_REDIRECT_LOCATION,
REQTEST_GET_REFERRER, REQTEST_GET_REFERRER,
REQTEST_GET_AUTH,
REQTEST_POST, REQTEST_POST,
REQTEST_POST_FILE, REQTEST_POST_FILE,
REQTEST_POST_WITHPROGRESS, REQTEST_POST_WITHPROGRESS,
REQTEST_POST_REDIRECT,
REQTEST_POST_REDIRECT_TOGET,
REQTEST_HEAD, REQTEST_HEAD,
REQTEST_CACHE_WITH_CONTROL, REQTEST_CACHE_WITH_CONTROL,
REQTEST_CACHE_WITHOUT_CONTROL, REQTEST_CACHE_WITHOUT_CONTROL,
@@ -142,6 +146,16 @@ struct RequestRunSettings {
// If true the response cookie should be saved. // If true the response cookie should be saved.
bool expect_save_cookie = false; 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. // If specified the test will begin with this redirect request and response.
CefRefPtr<CefRequest> redirect_request; CefRefPtr<CefRequest> redirect_request;
CefRefPtr<CefResponse> redirect_response; CefRefPtr<CefResponse> redirect_response;
@@ -264,6 +278,24 @@ class RequestDataMap {
RedirectDataMap redirect_data_map_; 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) { std::string GetRequestScheme(bool server_backend) {
return server_backend ? kRequestSchemeServer : kRequestSchemeCustom; return server_backend ? kRequestSchemeServer : kRequestSchemeCustom;
} }
@@ -470,6 +502,47 @@ void GetNormalResponse(const RequestRunSettings* settings,
response->SetHeaderMap(headerMap); 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 // SCHEME HANDLER BACKEND
// Serves request responses. // Serves request responses.
@@ -1007,6 +1080,14 @@ class RequestServerHandler : public CefServerHandler {
CefRefPtr<CefRequest> request) { CefRefPtr<CefRequest> request) {
RequestDataMap::Entry entry = data_map_.Find(request->GetURL()); RequestDataMap::Entry entry = data_map_.Find(request->GetURL());
if (entry.type == RequestDataMap::Entry::TYPE_NORMAL) { 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); HandleNormalRequest(server, connection_id, request, entry.settings);
} else if (entry.type == RequestDataMap::Entry::TYPE_REDIRECT) { } else if (entry.type == RequestDataMap::Entry::TYPE_REDIRECT) {
HandleRedirectRequest(server, connection_id, request, 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, void HandleNormalRequest(CefRefPtr<CefServer> server,
int connection_id, int connection_id,
CefRefPtr<CefRequest> request, CefRefPtr<CefRequest> request,
@@ -1185,6 +1274,11 @@ class RequestClient : public CefURLRequestClient {
const CefString& realm, const CefString& realm,
const CefString& scheme, const CefString& scheme,
CefRefPtr<CefAuthCallback> callback) override { CefRefPtr<CefAuthCallback> callback) override {
auth_credentials_ct_++;
if (has_authentication_) {
callback->Continue(username_, password_);
return true;
}
return false; return false;
} }
@@ -1192,10 +1286,15 @@ class RequestClient : public CefURLRequestClient {
const RequestCompleteCallback complete_callback_; const RequestCompleteCallback complete_callback_;
public: public:
bool has_authentication_ = false;
std::string username_;
std::string password_;
int request_complete_ct_ = 0; int request_complete_ct_ = 0;
int upload_progress_ct_ = 0; int upload_progress_ct_ = 0;
int download_progress_ct_ = 0; int download_progress_ct_ = 0;
int download_data_ct_ = 0; int download_data_ct_ = 0;
int auth_credentials_ct_ = 0;
int64 upload_total_ = 0; int64 upload_total_ = 0;
int64 download_total_ = 0; int64 download_total_ = 0;
@@ -1247,10 +1346,14 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
REGISTER_TEST(REQTEST_GET_REDIRECT_LOCATION, SetupGetRedirectLocationTest, REGISTER_TEST(REQTEST_GET_REDIRECT_LOCATION, SetupGetRedirectLocationTest,
SingleRunTest); SingleRunTest);
REGISTER_TEST(REQTEST_GET_REFERRER, SetupGetReferrerTest, 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, SetupPostTest, SingleRunTest);
REGISTER_TEST(REQTEST_POST_FILE, SetupPostFileTest, SingleRunTest); REGISTER_TEST(REQTEST_POST_FILE, SetupPostFileTest, SingleRunTest);
REGISTER_TEST(REQTEST_POST_WITHPROGRESS, SetupPostWithProgressTest, REGISTER_TEST(REQTEST_POST_WITHPROGRESS, SetupPostWithProgressTest,
SingleRunTest); 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_HEAD, SetupHeadTest, SingleRunTest);
REGISTER_TEST(REQTEST_CACHE_WITH_CONTROL, SetupCacheWithControlTest, REGISTER_TEST(REQTEST_CACHE_WITH_CONTROL, SetupCacheWithControlTest,
MultipleRunTest); MultipleRunTest);
@@ -1523,6 +1626,28 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
complete_callback.Run(); 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() { void SetupPostTestShared() {
settings_.request = CefRequest::Create(); settings_.request = CefRequest::Create();
settings_.request->SetURL(GetTestURL("PostTest.html")); settings_.request->SetURL(GetTestURL("PostTest.html"));
@@ -1589,6 +1714,58 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
complete_callback.Run(); 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) { void SetupHeadTest(const base::Closure& complete_callback) {
settings_.request = CefRequest::Create(); settings_.request = CefRequest::Create();
settings_.request->SetURL(GetTestURL("HeadTest.html")); settings_.request->SetURL(GetTestURL("HeadTest.html"));
@@ -1994,6 +2171,16 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
EXPECT_TRUE(request.get()); EXPECT_TRUE(request.get());
CefRefPtr<RequestClient> client = new RequestClient(complete_callback); 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_) { if (use_frame_method_) {
EXPECT_TRUE(frame_); EXPECT_TRUE(frame_);
frame_->CreateURLRequest(request, client.get()); frame_->CreateURLRequest(request, client.get());
@@ -2064,6 +2251,12 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
EXPECT_EQ(0, client->download_data_ct_); EXPECT_EQ(0, client->download_data_ct_);
EXPECT_TRUE(client->download_data_.empty()); 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. // Run a test with a single request.
@@ -2471,7 +2664,7 @@ class RequestTestHandler : public TestHandler {
// Continue the test once supported schemes has been set. // Continue the test once supported schemes has been set.
request_context->GetCookieManager(NULL)->SetSupportedSchemes( request_context->GetCookieManager(NULL)->SetSupportedSchemes(
supported_schemes, true, supported_schemes, true,
new SupportedSchemesCompletionCallback( new TestCompletionCallback(
base::Bind(&RequestTestHandler::PreSetupComplete, this))); base::Bind(&RequestTestHandler::PreSetupComplete, this)));
} else { } else {
PreSetupComplete(); PreSetupComplete();
@@ -2544,6 +2737,25 @@ class RequestTestHandler : public TestHandler {
return TestHandler::OnBeforeResourceLoad(browser, frame, request, callback); 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, void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, CefRefPtr<CefFrame> frame,
int httpStatusCode) override { int httpStatusCode) override {
@@ -2654,7 +2866,21 @@ class RequestTestHandler : public TestHandler {
// Shut down the browser side of the test. // Shut down the browser side of the test.
test_runner_->ShutdownTest( 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 { 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(); TestHandler::DestroyTest();
// For non-global contexts OnTestComplete() will be called when the // For non-global contexts OnTestComplete() will be called when the
@@ -2740,26 +2976,6 @@ class RequestTestHandler : public TestHandler {
IMPLEMENT_REFCOUNTING(RequestContextHandler); 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 RequestTestMode test_mode_;
const ContextTestMode context_mode_; const ContextTestMode context_mode_;
const bool test_in_browser_; const bool test_in_browser_;
@@ -2782,6 +2998,7 @@ class RequestTestHandler : public TestHandler {
TrackCallback got_message_; TrackCallback got_message_;
TrackCallback got_success_; TrackCallback got_success_;
int auth_credentials_ct_ = 0;
TrackCallback got_on_test_complete_; TrackCallback got_on_test_complete_;
IMPLEMENT_REFCOUNTING(RequestTestHandler); IMPLEMENT_REFCOUNTING(RequestTestHandler);
@@ -2873,6 +3090,10 @@ void RegisterURLRequestCustomSchemes(
test_server_backend, test_frame_method) \ test_server_backend, test_frame_method) \
REQ_TEST(BrowserPOSTWithProgress##suffix, REQTEST_POST_WITHPROGRESS, \ REQ_TEST(BrowserPOSTWithProgress##suffix, REQTEST_POST_WITHPROGRESS, \
context_mode, true, test_server_backend, test_frame_method) \ 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, \ REQ_TEST(BrowserHEAD##suffix, REQTEST_HEAD, context_mode, true, \
test_server_backend, test_frame_method) \ test_server_backend, test_frame_method) \
REQ_TEST(RendererGET##suffix, REQTEST_GET, context_mode, false, \ REQ_TEST(RendererGET##suffix, REQTEST_GET, context_mode, false, \
@@ -2893,6 +3114,10 @@ void RegisterURLRequestCustomSchemes(
test_server_backend, test_frame_method) \ test_server_backend, test_frame_method) \
REQ_TEST(RendererPOSTWithProgress##suffix, REQTEST_POST_WITHPROGRESS, \ REQ_TEST(RendererPOSTWithProgress##suffix, REQTEST_POST_WITHPROGRESS, \
context_mode, false, test_server_backend, test_frame_method) \ 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, \ REQ_TEST(RendererHEAD##suffix, REQTEST_HEAD, context_mode, false, \
test_server_backend, test_frame_method) test_server_backend, test_frame_method)
@@ -2940,7 +3165,7 @@ REQ_TEST_SET(WithFrame, true)
REQ_TEST_FRAME_SET() 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) \ #define REQ_TEST_CACHE_SET_EX(suffix, context_mode, test_frame_method) \
REQ_TEST(BrowserGETCacheWithControl##suffix, REQTEST_CACHE_WITH_CONTROL, \ REQ_TEST(BrowserGETCacheWithControl##suffix, REQTEST_CACHE_WITH_CONTROL, \
context_mode, true, true, test_frame_method) \ context_mode, true, true, test_frame_method) \
@@ -2972,6 +3197,8 @@ REQ_TEST_FRAME_SET()
REQ_TEST(RendererGETCacheWithoutControl##suffix, \ REQ_TEST(RendererGETCacheWithoutControl##suffix, \
REQTEST_CACHE_WITHOUT_CONTROL, context_mode, false, true, \ REQTEST_CACHE_WITHOUT_CONTROL, context_mode, false, true, \
test_frame_method) \ 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, \ REQ_TEST(RendererGETCacheSkipFlag##suffix, REQTEST_CACHE_SKIP_FLAG, \
context_mode, false, true, test_frame_method) \ context_mode, false, true, test_frame_method) \
REQ_TEST(RendererGETCacheSkipHeader##suffix, REQTEST_CACHE_SKIP_HEADER, \ REQ_TEST(RendererGETCacheSkipHeader##suffix, REQTEST_CACHE_SKIP_HEADER, \

View File

@@ -36,7 +36,8 @@ def RunAction(dir, command):
command[0] = sys.executable command[0] = sys.executable
try: 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: except gclient_utils.Error, e:
# Use a discrete exit status code of 2 to indicate that a hook action # 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 # failed. Users of this script may wish to treat hook action failures

View File

@@ -440,13 +440,17 @@ def GetConfigArgsSandbox(platform, args, is_debug, cpu):
'use_allocator_shim': False, 'use_allocator_shim': False,
# Avoid /LTCG linker warnings and generate smaller lib files. # Avoid /LTCG linker warnings and generate smaller lib files.
'is_official_build': False 'is_official_build': False,
} }
if is_debug: if is_debug:
# Enable iterator debugging (_ITERATOR_DEBUG_LEVEL=2). # Enable iterator debugging (_ITERATOR_DEBUG_LEVEL=2).
add_args['enable_iterator_debugging'] = True 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, { result = MergeDicts(args, add_args, {
'is_debug': is_debug, 'is_debug': is_debug,
'target_cpu': cpu, 'target_cpu': cpu,