Implement NetworkService request interception/handling (see issue #2622).

Implementation notes:
- Chromium change: CookieMonster::SetCookieableSchemes needs to be called
  immediately after the CookieMonster is created in NetworkContext::
  ApplyContextParamsToBuilder. Add a Profile::GetCookieableSchemes method and
  NetworkContextParams.cookieable_schemes member (set from
  ProfileNetworkContextService::CreateNetworkContextParams) to support that.
- Chromium change: Add a ContentBrowserClient::HandleExternalProtocol variant
  that exposes additional NetworkService request information.
- GetResourceResponseFilter is not yet implemented.

API changes:
- Resource-related callbacks have been moved from CefRequestHandler to a new
  CefResourceRequestHandler interface which is returned via the
  GetResourceRequestHandler method. If the CefRequestHandler declines to handle
  a resource it can optionally be handled by the CefRequestContextHandler, if
  any, associated with the loading context.
- The OnProtocolExecution callback has been moved from CefRequestHandler to
  CefResourceRequestHandler and will be called if a custom scheme request is
  unhandled.
- Cookie send/save permission callbacks have been moved from CefRequestHandler
  and CefResourceHandler to CefResourceRequestHandler.
- New methods added to CefResourceHandler that better match NetworkService
  execution sequence expectations. The old methods are now deprecated.
- New methods added to CefRequest and CefResponse.

Known behavior changes with the NetworkService implementation:
- Modifying the |new_url| parameter in OnResourceRedirect will no longer result
  in the method being called an additional time (likely a bug in the old
  implementation).
- Modifying the request URL in OnResourceResponse would previously cause a
  redirect. This behavior is now deprecated because the NetworkService does not
  support this functionality when using default network loaders. Temporary
  support has been added in combination with CefResourceHandler usage only.
- Other changes to the request object in OnResourceResponse will now cause the
  request to be restarted. This means that OnBeforeResourceLoad, etc, will be
  called an additional time with the new request information.
- CefResponse::GetMimeType will now be empty for non-200 responses.
- Requests using custom schemes can now be handled via CefResourceRequestHandler
  with the same callback behavior as builtin schemes.
- Redirects of custom scheme requests will now be followed as expected.
- Default handling of builtin schemes can now be disabled by setting
  |disable_default_handling| to true in GetResourceRequestHandler.
- Unhandled requests (custom scheme or builtin scheme with default handling
  disabled) will fail with an CefResponse::GetError value of
  ERR_UNKNOWN_URL_SCHEME.
- The CefSchemeHandlerFactory::Create callback will now include cookie headers.

To test:
- Run `cefclient --enable-network-service`. All resources should load
  successfully (this tests the transparent proxy capability).
- All tests pass with NetworkService disabled.
- The following tests pass with NetworkService enabled:
  - CookieTest.*
  - FrameTest.* (excluding .*Nav)
  - NavigationTest.* (excluding .Redirect*)
  - RequestHandlerTest.*
  - RequestContextTest.Basic*
  - RequestContextTest.Popup*
  - RequestTest.*
  - ResourceManagerTest.*
  - ResourceRequestHandlerTest.* (excluding .Filter*)
  - SchemeHandlerTest.*
  - StreamResourceHandlerTest.*
This commit is contained in:
Marshall Greenblatt
2019-04-24 02:50:25 +00:00
parent 019611c764
commit 8f240861e3
141 changed files with 12733 additions and 3927 deletions

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=706e3ebbdb4e3b01f3f3bb18eb85c1897c8b5ade$
// $hash=f94ec1ef3928002394720160d526ed157282cc7a$
//
#ifndef CEF_INCLUDE_CAPI_CEF_RESOURCE_HANDLER_CAPI_H_
@@ -51,9 +51,48 @@
extern "C" {
#endif
///
// Callback for asynchronous continuation of cef_resource_handler_t::skip().
///
typedef struct _cef_resource_skip_callback_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Callback for asynchronous continuation of skip(). If |bytes_skipped| > 0
// then either skip() will be called again until the requested number of bytes
// have been skipped or the request will proceed. If |bytes_skipped| <= 0 the
// request will fail with ERR_REQUEST_RANGE_NOT_SATISFIABLE.
///
void(CEF_CALLBACK* cont)(struct _cef_resource_skip_callback_t* self,
int64 bytes_skipped);
} cef_resource_skip_callback_t;
///
// Callback for asynchronous continuation of cef_resource_handler_t::read().
///
typedef struct _cef_resource_read_callback_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Callback for asynchronous continuation of read(). If |bytes_read| == 0 the
// response will be considered complete. If |bytes_read| > 0 then read() will
// be called again until the request is complete (based on either the result
// or the expected content length). If |bytes_read| < 0 then the request will
// fail and the |bytes_read| value will be treated as the error code.
///
void(CEF_CALLBACK* cont)(struct _cef_resource_read_callback_t* self,
int bytes_read);
} cef_resource_read_callback_t;
///
// Structure used to implement a custom request handler structure. The functions
// of this structure will always be called on the IO thread.
// of this structure will be called on the IO thread unless otherwise indicated.
///
typedef struct _cef_resource_handler_t {
///
@@ -61,12 +100,29 @@ typedef struct _cef_resource_handler_t {
///
cef_base_ref_counted_t base;
///
// Open the response stream. To handle the request immediately set
// |handle_request| to true (1) and return true (1). To decide at a later time
// set |handle_request| to false (0), return true (1), and execute |callback|
// to continue or cancel the request. To cancel the request immediately set
// |handle_request| to true (1) and return false (0). This function will be
// called in sequence but not from a dedicated thread. For backwards
// compatibility set |handle_request| to false (0) and return false (0) and
// the ProcessRequest function will be called.
///
int(CEF_CALLBACK* open)(struct _cef_resource_handler_t* self,
struct _cef_request_t* request,
int* handle_request,
struct _cef_callback_t* callback);
///
// Begin processing the request. To handle the request return true (1) and
// call cef_callback_t::cont() once the response header information is
// available (cef_callback_t::cont() can also be called from inside this
// function if header information is available immediately). To cancel the
// request return false (0).
//
// WARNING: This function is deprecated. Use Open instead.
///
int(CEF_CALLBACK* process_request)(struct _cef_resource_handler_t* self,
struct _cef_request_t* request,
@@ -92,12 +148,47 @@ typedef struct _cef_resource_handler_t {
int64* response_length,
cef_string_t* redirectUrl);
///
// Skip response data when requested by a Range header. Skip over and discard
// |bytes_to_skip| bytes of response data. If data is available immediately
// set |bytes_skipped| to the number of of bytes skipped and return true (1).
// To read the data at a later time set |bytes_skipped| to 0, return true (1)
// and execute |callback| when the data is available. To indicate failure set
// |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.
///
int(CEF_CALLBACK* skip)(struct _cef_resource_handler_t* self,
int64 bytes_to_skip,
int64* bytes_skipped,
struct _cef_resource_skip_callback_t* callback);
///
// Read response data. If data is available immediately copy up to
// |bytes_to_read| bytes into |data_out|, set |bytes_read| to the number of
// bytes copied, and return true (1). To read the data at a later time keep a
// pointer to |data_out|, set |bytes_read| to 0, return true (1) and execute
// |callback| when the data is available (|data_out| will remain valid until
// the callback is executed). To indicate response completion set |bytes_read|
// to 0 and return false (0). To indicate failure set |bytes_read| 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. For backwards compatibility
// set |bytes_read| to -1 and return false (0) and the ReadResponse function
// will be called.
///
int(CEF_CALLBACK* read)(struct _cef_resource_handler_t* self,
void* data_out,
int bytes_to_read,
int* bytes_read,
struct _cef_resource_read_callback_t* callback);
///
// Read response data. If data is available immediately copy up to
// |bytes_to_read| bytes into |data_out|, set |bytes_read| to the number of
// bytes copied, and return true (1). To read the data at a later time set
// |bytes_read| to 0, return true (1) and call cef_callback_t::cont() when the
// data is available. To indicate response completion return false (0).
//
// WARNING: This function is deprecated. Use Skip and Read instead.
///
int(CEF_CALLBACK* read_response)(struct _cef_resource_handler_t* self,
void* data_out,
@@ -105,21 +196,6 @@ typedef struct _cef_resource_handler_t {
int* bytes_read,
struct _cef_callback_t* callback);
///
// Return true (1) if the specified cookie can be sent with the request or
// false (0) otherwise. If false (0) is returned for any cookie then no
// cookies will be sent with the request.
///
int(CEF_CALLBACK* can_get_cookie)(struct _cef_resource_handler_t* self,
const struct _cef_cookie_t* cookie);
///
// Return true (1) if the specified cookie returned with the response can be
// set or false (0) otherwise.
///
int(CEF_CALLBACK* can_set_cookie)(struct _cef_resource_handler_t* self,
const struct _cef_cookie_t* cookie);
///
// Request processing has been canceled.
///