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

@ -401,8 +401,18 @@ static_library("libcef_static") {
"libcef/browser/net/url_request_manager.h",
"libcef/browser/net/url_request_user_data.cc",
"libcef/browser/net/url_request_user_data.h",
"libcef/browser/net_service/cookie_helper.cc",
"libcef/browser/net_service/cookie_helper.h",
"libcef/browser/net_service/cookie_manager_impl.cc",
"libcef/browser/net_service/cookie_manager_impl.h",
"libcef/browser/net_service/proxy_url_loader_factory.cc",
"libcef/browser/net_service/proxy_url_loader_factory.h",
"libcef/browser/net_service/resource_handler_wrapper.cc",
"libcef/browser/net_service/resource_handler_wrapper.h",
"libcef/browser/net_service/resource_request_handler_wrapper.cc",
"libcef/browser/net_service/resource_request_handler_wrapper.h",
"libcef/browser/net_service/stream_reader_url_loader.cc",
"libcef/browser/net_service/stream_reader_url_loader.h",
"libcef/browser/origin_whitelist_impl.cc",
"libcef/browser/origin_whitelist_impl.h",
"libcef/browser/osr/browser_platform_delegate_osr.cc",
@ -511,6 +521,8 @@ static_library("libcef_static") {
"libcef/common/net/upload_data.h",
"libcef/common/net/upload_element.cc",
"libcef/common/net/upload_element.h",
"libcef/common/net_service/net_service_util.cc",
"libcef/common/net_service/net_service_util.h",
"libcef/common/net_service/util.cc",
"libcef/common/net_service/util.h",
"libcef/common/parser_impl.cc",

View File

@ -8,7 +8,7 @@
# by hand. See the translator.README.txt file in the tools directory for
# more information.
#
# $hash=61795daa573f965b6b94dea5b8220eeca37f62a0$
# $hash=ce19444fe9b2ed5ae2a614f3d00ca3262d75ca98$
#
{
@ -57,12 +57,14 @@
'include/cef_render_handler.h',
'include/cef_render_process_handler.h',
'include/cef_request.h',
'include/cef_request_callback.h',
'include/cef_request_context.h',
'include/cef_request_context_handler.h',
'include/cef_request_handler.h',
'include/cef_resource_bundle.h',
'include/cef_resource_bundle_handler.h',
'include/cef_resource_handler.h',
'include/cef_resource_request_handler.h',
'include/cef_response.h',
'include/cef_response_filter.h',
'include/cef_scheme.h',
@ -149,12 +151,14 @@
'include/capi/cef_render_handler_capi.h',
'include/capi/cef_render_process_handler_capi.h',
'include/capi/cef_request_capi.h',
'include/capi/cef_request_callback_capi.h',
'include/capi/cef_request_context_capi.h',
'include/capi/cef_request_context_handler_capi.h',
'include/capi/cef_request_handler_capi.h',
'include/capi/cef_resource_bundle_capi.h',
'include/capi/cef_resource_bundle_handler_capi.h',
'include/capi/cef_resource_handler_capi.h',
'include/capi/cef_resource_request_handler_capi.h',
'include/capi/cef_response_capi.h',
'include/capi/cef_response_filter_capi.h',
'include/capi/cef_scheme_capi.h',
@ -366,6 +370,12 @@
'libcef_dll/ctocpp/resource_bundle_handler_ctocpp.h',
'libcef_dll/ctocpp/resource_handler_ctocpp.cc',
'libcef_dll/ctocpp/resource_handler_ctocpp.h',
'libcef_dll/cpptoc/resource_read_callback_cpptoc.cc',
'libcef_dll/cpptoc/resource_read_callback_cpptoc.h',
'libcef_dll/ctocpp/resource_request_handler_ctocpp.cc',
'libcef_dll/ctocpp/resource_request_handler_ctocpp.h',
'libcef_dll/cpptoc/resource_skip_callback_cpptoc.cc',
'libcef_dll/cpptoc/resource_skip_callback_cpptoc.h',
'libcef_dll/cpptoc/response_cpptoc.cc',
'libcef_dll/cpptoc/response_cpptoc.h',
'libcef_dll/ctocpp/response_filter_ctocpp.cc',
@ -650,6 +660,12 @@
'libcef_dll/cpptoc/resource_bundle_handler_cpptoc.h',
'libcef_dll/cpptoc/resource_handler_cpptoc.cc',
'libcef_dll/cpptoc/resource_handler_cpptoc.h',
'libcef_dll/ctocpp/resource_read_callback_ctocpp.cc',
'libcef_dll/ctocpp/resource_read_callback_ctocpp.h',
'libcef_dll/cpptoc/resource_request_handler_cpptoc.cc',
'libcef_dll/cpptoc/resource_request_handler_cpptoc.h',
'libcef_dll/ctocpp/resource_skip_callback_ctocpp.cc',
'libcef_dll/ctocpp/resource_skip_callback_ctocpp.h',
'libcef_dll/ctocpp/response_ctocpp.cc',
'libcef_dll/ctocpp/response_ctocpp.h',
'libcef_dll/cpptoc/response_filter_cpptoc.cc',

View File

@ -487,6 +487,7 @@
'tests/ceftests/request_unittest.cc',
'tests/ceftests/resource.h',
'tests/ceftests/resource_manager_unittest.cc',
'tests/ceftests/resource_request_handler_unittest.cc',
'tests/ceftests/routing_test_handler.cc',
'tests/ceftests/routing_test_handler.h',
'tests/ceftests/run_all_unittests.cc',

View File

@ -0,0 +1,74 @@
// Copyright (c) 2019 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=2602018f3322a2d983a02421cf55e0dc0a1357e9$
//
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_CALLBACK_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_REQUEST_CALLBACK_CAPI_H_
#pragma once
#include "include/capi/cef_base_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
///
// Callback structure used for asynchronous continuation of url requests.
///
typedef struct _cef_request_callback_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Continue the url request. If |allow| is true (1) the request will be
// continued. Otherwise, the request will be canceled.
///
void(CEF_CALLBACK* cont)(struct _cef_request_callback_t* self, int allow);
///
// Cancel the url request.
///
void(CEF_CALLBACK* cancel)(struct _cef_request_callback_t* self);
} cef_request_callback_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_REQUEST_CALLBACK_CAPI_H_

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=580e0e91bf4052f0e996dc42f63079ca1a6390cf$
// $hash=3a1ab8264989d7f68504dc60ad6dc52c31d323a4$
//
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_CAPI_H_
@ -136,6 +136,27 @@ typedef struct _cef_request_t {
void(CEF_CALLBACK* set_header_map)(struct _cef_request_t* self,
cef_string_multimap_t headerMap);
///
// Returns the first header value for |name| or an NULL string if not found.
// Will not return the Referer value if any. Use GetHeaderMap instead if
// |name| might have multiple values.
///
// The resulting string must be freed by calling cef_string_userfree_free().
cef_string_userfree_t(CEF_CALLBACK* get_header_by_name)(
struct _cef_request_t* self,
const cef_string_t* name);
///
// Set the header |name| to |value|. If |overwrite| is true (1) any existing
// values will be replaced with the new value. If |overwrite| is false (0) any
// existing values will not be overwritten. The Referer value cannot be set
// using this function.
///
void(CEF_CALLBACK* set_header_by_name)(struct _cef_request_t* self,
const cef_string_t* name,
const cef_string_t* value,
int overwrite);
///
// Set all values at one time.
///
@ -189,8 +210,8 @@ typedef struct _cef_request_t {
///
// Returns the globally unique identifier for this request or 0 if not
// specified. Can be used by cef_request_tHandler implementations in the
// browser process to track a single request across multiple callbacks.
// specified. Can be used by cef_resource_request_handler_t implementations in
// the browser process to track a single request across multiple callbacks.
///
uint64(CEF_CALLBACK* get_identifier)(struct _cef_request_t* self);
} cef_request_t;

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=1038c0c3db89ce0b829d66e166b063c96b15992d$
// $hash=59376c6298df4489ecc34f3509a8d0e77e9d97f7$
//
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_CONTEXT_CAPI_H_
@ -44,13 +44,13 @@
#include "include/capi/cef_cookie_capi.h"
#include "include/capi/cef_extension_capi.h"
#include "include/capi/cef_extension_handler_capi.h"
#include "include/capi/cef_request_context_handler_capi.h"
#include "include/capi/cef_values_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
struct _cef_request_context_handler_t;
struct _cef_scheme_handler_factory_t;
///

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=2bf745d270f474b3d5b36fc3fc2fca2b508ec16f$
// $hash=240893b4019b0bf8c69ffc1682ddabcacabcb3e4$
//
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_CONTEXT_HANDLER_CAPI_H_
@ -41,14 +41,16 @@
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_browser_capi.h"
#include "include/capi/cef_frame_capi.h"
#include "include/capi/cef_request_capi.h"
#include "include/capi/cef_resource_request_handler_capi.h"
#include "include/capi/cef_web_plugin_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
struct _cef_request_context_t;
///
// Implement this structure to provide handler implementations. The handler
// instance will not be released until all objects related to the context have
@ -95,6 +97,35 @@ typedef struct _cef_request_context_handler_t {
const cef_string_t* top_origin_url,
struct _cef_web_plugin_info_t* plugin_info,
cef_plugin_policy_t* plugin_policy);
///
// Called on the browser process IO thread before a resource request is
// initiated. The |browser| and |frame| values represent the source of the
// request, and may be NULL for requests originating from service workers.
// |request| represents the request contents and cannot be modified in this
// callback. |is_navigation| will be true (1) if the resource request is a
// navigation. |is_download| will be true (1) if the resource request is a
// download. |request_initiator| is the origin (scheme + domain) of the page
// that initiated the request. Set |disable_default_handling| to true (1) to
// disable default handling of the request, in which case it will need to be
// handled via cef_resource_request_handler_t::GetResourceHandler or it will
// be canceled. To allow the resource load to proceed with default handling
// return NULL. To specify a handler for the resource return a
// cef_resource_request_handler_t object. This function will not be called if
// the client associated with |browser| returns a non-NULL value from
// cef_request_tHandler::GetResourceRequestHandler for the same request
// (identified by cef_request_t::GetIdentifier).
///
struct _cef_resource_request_handler_t*(
CEF_CALLBACK* get_resource_request_handler)(
struct _cef_request_context_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
int is_navigation,
int is_download,
const cef_string_t* request_initiator,
int* disable_default_handling);
} cef_request_context_handler_t;
#ifdef __cplusplus

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=64631c0b1776a951da838f8b08a4c71ef33a15cc$
// $hash=fce8beb9d3e8709a512077681455cb4ef92ef76d$
//
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_HANDLER_CAPI_H_
@ -44,10 +44,9 @@
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_browser_capi.h"
#include "include/capi/cef_frame_capi.h"
#include "include/capi/cef_request_callback_capi.h"
#include "include/capi/cef_request_capi.h"
#include "include/capi/cef_resource_handler_capi.h"
#include "include/capi/cef_response_capi.h"
#include "include/capi/cef_response_filter_capi.h"
#include "include/capi/cef_resource_request_handler_capi.h"
#include "include/capi/cef_ssl_info_capi.h"
#include "include/capi/cef_x509_certificate_capi.h"
@ -55,27 +54,6 @@
extern "C" {
#endif
///
// Callback structure used for asynchronous continuation of url requests.
///
typedef struct _cef_request_callback_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Continue the url request. If |allow| is true (1) the request will be
// continued. Otherwise, the request will be canceled.
///
void(CEF_CALLBACK* cont)(struct _cef_request_callback_t* self, int allow);
///
// Cancel the url request.
///
void(CEF_CALLBACK* cancel)(struct _cef_request_callback_t* self);
} cef_request_callback_t;
///
// Callback structure used to select a client certificate for authentication.
///
@ -148,85 +126,31 @@ typedef struct _cef_request_handler_t {
int user_gesture);
///
// Called on the IO thread before a resource request is loaded. The |request|
// object may be modified. Return RV_CONTINUE to continue the request
// immediately. Return RV_CONTINUE_ASYNC and call cef_request_tCallback::
// cont() at a later time to continue or cancel the request asynchronously.
// Return RV_CANCEL to cancel the request immediately.
//
// Called on the browser process IO thread before a resource request is
// initiated. The |browser| and |frame| values represent the source of the
// request. |request| represents the request contents and cannot be modified
// in this callback. |is_navigation| will be true (1) if the resource request
// is a navigation. |is_download| will be true (1) if the resource request is
// a download. |request_initiator| is the origin (scheme + domain) of the page
// that initiated the request. Set |disable_default_handling| to true (1) to
// disable default handling of the request, in which case it will need to be
// handled via cef_resource_request_handler_t::GetResourceHandler or it will
// be canceled. To allow the resource load to proceed with default handling
// return NULL. To specify a handler for the resource return a
// cef_resource_request_handler_t object. If this callback returns NULL the
// same function will be called on the associated cef_request_tContextHandler,
// if any.
///
cef_return_value_t(CEF_CALLBACK* on_before_resource_load)(
struct _cef_resource_request_handler_t*(
CEF_CALLBACK* get_resource_request_handler)(
struct _cef_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
struct _cef_request_callback_t* callback);
///
// Called on the IO thread before a resource is loaded. To allow the resource
// to load normally return NULL. To specify a handler for the resource return
// a cef_resource_handler_t object. The |request| object should not be
// modified in this callback.
///
struct _cef_resource_handler_t*(CEF_CALLBACK* get_resource_handler)(
struct _cef_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request);
///
// Called on the IO thread when a resource load is redirected. The |request|
// parameter will contain the old URL and other request-related information.
// The |response| parameter will contain the response that resulted in the
// redirect. The |new_url| parameter will contain the new URL and can be
// changed if desired. The |request| object cannot be modified in this
// callback.
///
void(CEF_CALLBACK* on_resource_redirect)(struct _cef_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
struct _cef_response_t* response,
cef_string_t* new_url);
///
// Called on the IO thread when a resource response is received. To allow the
// resource to load normally return false (0). To redirect or retry the
// resource modify |request| (url, headers or post body) and return true (1).
// The |response| object cannot be modified in this callback.
///
int(CEF_CALLBACK* on_resource_response)(struct _cef_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
struct _cef_response_t* response);
///
// Called on the IO thread to optionally filter resource response content.
// |request| and |response| represent the request and response respectively
// and cannot be modified in this callback.
///
struct _cef_response_filter_t*(CEF_CALLBACK* get_resource_response_filter)(
struct _cef_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
struct _cef_response_t* response);
///
// Called on the IO thread when a resource load has completed. |request| and
// |response| represent the request and response respectively and cannot be
// modified in this callback. |status| indicates the load completion status.
// |received_content_length| is the number of response bytes actually read.
///
void(CEF_CALLBACK* on_resource_load_complete)(
struct _cef_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
struct _cef_response_t* response,
cef_urlrequest_status_t status,
int64 received_content_length);
int is_navigation,
int is_download,
const cef_string_t* request_initiator,
int* disable_default_handling);
///
// Called on the IO thread when the browser needs credentials from the user.
@ -250,29 +174,6 @@ typedef struct _cef_request_handler_t {
const cef_string_t* scheme,
struct _cef_auth_callback_t* callback);
///
// Called on the IO thread before sending a network request with a "Cookie"
// request header. Return true (1) to allow cookies to be included in the
// network request or false (0) to block cookies. The |request| object should
// not be modified in this callback.
///
int(CEF_CALLBACK* can_get_cookies)(struct _cef_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request);
///
// Called on the IO thread when receiving a network request with a "Set-
// Cookie" response header value represented by |cookie|. Return true (1) to
// allow the cookie to be stored or false (0) to block the cookie. The
// |request| object should not be modified in this callback.
///
int(CEF_CALLBACK* can_set_cookie)(struct _cef_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
const struct _cef_cookie_t* cookie);
///
// Called on the IO thread when JavaScript requests a specific storage quota
// size via the webkitStorageInfo.requestQuota function. |origin_url| is the
@ -288,18 +189,6 @@ typedef struct _cef_request_handler_t {
int64 new_size,
struct _cef_request_callback_t* callback);
///
// Called on the UI thread to handle requests for URLs with an unknown
// protocol component. Set |allow_os_execution| to true (1) to attempt
// execution via the registered OS protocol handler, if any. SECURITY WARNING:
// YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS BASED ON SCHEME, HOST OR
// OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION.
///
void(CEF_CALLBACK* on_protocol_execution)(struct _cef_request_handler_t* self,
struct _cef_browser_t* browser,
const cef_string_t* url,
int* allow_os_execution);
///
// Called on the UI thread to handle requests for URLs with an invalid SSL
// certificate. Return true (1) and call cef_request_tCallback::cont() either

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.
///

View File

@ -0,0 +1,215 @@
// Copyright (c) 2019 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=af361d45eb9009a2cbca2024d2ede6d43d8d440f$
//
#ifndef CEF_INCLUDE_CAPI_CEF_RESOURCE_REQUEST_HANDLER_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_RESOURCE_REQUEST_HANDLER_CAPI_H_
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_browser_capi.h"
#include "include/capi/cef_frame_capi.h"
#include "include/capi/cef_request_callback_capi.h"
#include "include/capi/cef_request_capi.h"
#include "include/capi/cef_resource_handler_capi.h"
#include "include/capi/cef_response_capi.h"
#include "include/capi/cef_response_filter_capi.h"
#include "include/internal/cef_types_wrappers.h"
#ifdef __cplusplus
extern "C" {
#endif
///
// Implement this structure to handle events related to browser requests. The
// functions of this structure will be called on the IO thread unless otherwise
// indicated.
///
typedef struct _cef_resource_request_handler_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Called on the IO thread before a resource request is loaded. The |browser|
// and |frame| values represent the source of the request, and may be NULL for
// requests originating from service workers. To redirect or change the
// resource load optionally modify |request|. Modification of the request URL
// will be treated as a redirect. Return RV_CONTINUE to continue the request
// immediately. Return RV_CONTINUE_ASYNC and call cef_request_tCallback::
// cont() at a later time to continue or cancel the request asynchronously.
// Return RV_CANCEL to cancel the request immediately.
//
///
cef_return_value_t(CEF_CALLBACK* on_before_resource_load)(
struct _cef_resource_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
struct _cef_request_callback_t* callback);
///
// Called on the IO thread before a resource is loaded. The |browser| and
// |frame| values represent the source of the request, and may be NULL for
// requests originating from service workers. To allow the resource to load
// using the default network loader return NULL. To specify a handler for the
// resource return a cef_resource_handler_t object. The |request| object
// should not be modified in this callback.
///
struct _cef_resource_handler_t*(CEF_CALLBACK* get_resource_handler)(
struct _cef_resource_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request);
///
// Called on the IO thread when a resource load is redirected. The |browser|
// and |frame| values represent the source of the request, and may be NULL for
// requests originating from service workers. The |request| parameter will
// contain the old URL and other request-related information. The |response|
// parameter will contain the response that resulted in the redirect. The
// |new_url| parameter will contain the new URL and can be changed if desired.
// The |request| and |response| objects cannot be modified in this callback.
///
void(CEF_CALLBACK* on_resource_redirect)(
struct _cef_resource_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
struct _cef_response_t* response,
cef_string_t* new_url);
///
// Called on the IO thread when a resource response is received. The |browser|
// and |frame| values represent the source of the request, and may be NULL for
// requests originating from service workers. To allow the resource load to
// proceed without modification return false (0). To redirect or retry the
// resource load optionally modify |request| and return true (1). Modification
// of the request URL will be treated as a redirect. Requests handled using
// the default network loader cannot be redirected in this callback. The
// |response| object cannot be modified in this callback.
//
// WARNING: Redirecting using this function is deprecated. Use
// OnBeforeResourceLoad or GetResourceHandler to perform redirects.
///
int(CEF_CALLBACK* on_resource_response)(
struct _cef_resource_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
struct _cef_response_t* response);
///
// Called on the IO thread to optionally filter resource response content. The
// |browser| and |frame| values represent the source of the request, and may
// be NULL for requests originating from service workers. |request| and
// |response| represent the request and response respectively and cannot be
// modified in this callback.
///
struct _cef_response_filter_t*(CEF_CALLBACK* get_resource_response_filter)(
struct _cef_resource_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
struct _cef_response_t* response);
///
// Called on the IO thread when a resource load has completed. The |browser|
// and |frame| values represent the source of the request, and may be NULL for
// requests originating from service workers. |request| and |response|
// represent the request and response respectively and cannot be modified in
// this callback. |status| indicates the load completion status.
// |received_content_length| is the number of response bytes actually read.
///
void(CEF_CALLBACK* on_resource_load_complete)(
struct _cef_resource_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
struct _cef_response_t* response,
cef_urlrequest_status_t status,
int64 received_content_length);
///
// Called on the IO thread to handle requests for URLs with an unknown
// protocol component. The |browser| and |frame| values represent the source
// of the request, and may be NULL for requests originating from service
// workers. |request| cannot be modified in this callback. Set
// |allow_os_execution| to true (1) to attempt execution via the registered OS
// protocol handler, if any. SECURITY WARNING: YOU SHOULD USE THIS METHOD TO
// ENFORCE RESTRICTIONS BASED ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE
// ALLOWING OS EXECUTION.
///
void(CEF_CALLBACK* on_protocol_execution)(
struct _cef_resource_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
int* allow_os_execution);
///
// Called on the IO thread before a resource request is sent. Return true (1)
// if the specified cookie can be sent with the request or false (0)
// otherwise.
///
int(CEF_CALLBACK* can_send_cookie)(
struct _cef_resource_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
const struct _cef_cookie_t* cookie);
///
// Called on the IO thread after a resource response is received. Return true
// (1) if the specified cookie returned with the response can be saved or
// false (0) otherwise.
///
int(CEF_CALLBACK* can_save_cookie)(
struct _cef_resource_request_handler_t* self,
struct _cef_browser_t* browser,
struct _cef_frame_t* frame,
struct _cef_request_t* request,
struct _cef_response_t* response,
const struct _cef_cookie_t* cookie);
} cef_resource_request_handler_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_RESOURCE_REQUEST_HANDLER_CAPI_H_

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=0c99415ddb1bf7d10135545c7b0ccfb7eec2264d$
// $hash=cc5ec5ca76adb568adb08c3b58fb3289a94b2ecd$
//
#ifndef CEF_INCLUDE_CAPI_CEF_RESPONSE_CAPI_H_
@ -109,6 +109,19 @@ typedef struct _cef_response_t {
void(CEF_CALLBACK* set_mime_type)(struct _cef_response_t* self,
const cef_string_t* mimeType);
///
// Get the response charset.
///
// The resulting string must be freed by calling cef_string_userfree_free().
cef_string_userfree_t(CEF_CALLBACK* get_charset)(
struct _cef_response_t* self);
///
// Set the response charset.
///
void(CEF_CALLBACK* set_charset)(struct _cef_response_t* self,
const cef_string_t* charset);
///
// Get the value for the specified response header field.
///

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=1d4a363735a7274fb957905f47841c63301507f0$
// $hash=bf5c2a51aa80e831382bfe08e8dd5ec6331f0fdc$
//
#ifndef CEF_INCLUDE_CAPI_CEF_SCHEME_CAPI_H_
@ -94,7 +94,7 @@ typedef struct _cef_scheme_handler_factory_t {
// will be the browser window and frame respectively that originated the
// request or NULL if the request did not originate from a browser window (for
// example, if the request came from cef_urlrequest_t). The |request| object
// passed to this function will not contain cookie data.
// passed to this function cannot be modified.
///
struct _cef_resource_handler_t*(CEF_CALLBACK* create)(
struct _cef_scheme_handler_factory_t* self,

View File

@ -34,7 +34,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=3a0c73e396fa3857e28d388def4fbd3029f22572$
// $hash=a16054629e5a769bd6a1fe5f49ca798dd945639c$
//
#ifndef CEF_INCLUDE_API_HASH_H_
@ -47,13 +47,13 @@
// way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash
// values will change only if that particular platform is affected.
#define CEF_API_HASH_UNIVERSAL "270f0270e88d272207bd83c60e36ceb45f4b690c"
#define CEF_API_HASH_UNIVERSAL "611213d46fd8a3299500c43cdea741eea7454a4f"
#if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "66d5f7568c90b1fcf60c4b8278b2465e94044426"
#define CEF_API_HASH_PLATFORM "6c42e6a3ed0cf99eca56ccfc46e0014c45bdd3fe"
#elif defined(OS_MACOSX)
#define CEF_API_HASH_PLATFORM "2eaac3385943011ba69f8c02ff81fcc779fa1d39"
#define CEF_API_HASH_PLATFORM "f8cd3ac6e74bfeb4466a4dd79b2dd19a63eddc8a"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "32502dcfde9333af005bae482dec534ce2e26d67"
#define CEF_API_HASH_PLATFORM "29fddb1f16808049dbfd747a2ddc91ee001dbcdf"
#endif
#ifdef __cplusplus

View File

@ -140,6 +140,25 @@ class CefRequest : public virtual CefBaseRefCounted {
/*--cef()--*/
virtual void SetHeaderMap(const HeaderMap& headerMap) = 0;
///
// Returns the first header value for |name| or an empty string if not found.
// Will not return the Referer value if any. Use GetHeaderMap instead if
// |name| might have multiple values.
///
/*--cef()--*/
virtual CefString GetHeaderByName(const CefString& name) = 0;
///
// Set the header |name| to |value|. If |overwrite| is true any existing
// values will be replaced with the new value. If |overwrite| is false any
// existing values will not be overwritten. The Referer value cannot be set
// using this method.
///
/*--cef()--*/
virtual void SetHeaderByName(const CefString& name,
const CefString& value,
bool overwrite) = 0;
///
// Set all values at one time.
///
@ -194,8 +213,8 @@ class CefRequest : public virtual CefBaseRefCounted {
///
// Returns the globally unique identifier for this request or 0 if not
// specified. Can be used by CefRequestHandler implementations in the browser
// process to track a single request across multiple callbacks.
// specified. Can be used by CefResourceRequestHandler implementations in the
// browser process to track a single request across multiple callbacks.
///
/*--cef()--*/
virtual uint64 GetIdentifier() = 0;

View File

@ -0,0 +1,63 @@
// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// The contents of this file must follow a specific format in order to
// support the CEF translator tool. See the translator.README.txt file in the
// tools directory for more information.
//
#ifndef CEF_INCLUDE_CEF_REQUEST_CALLBACK_H_
#define CEF_INCLUDE_CEF_REQUEST_CALLBACK_H_
#pragma once
#include "include/cef_base.h"
///
// Callback interface used for asynchronous continuation of url requests.
///
/*--cef(source=library)--*/
class CefRequestCallback : public virtual CefBaseRefCounted {
public:
///
// Continue the url request. If |allow| is true the request will be continued.
// Otherwise, the request will be canceled.
///
/*--cef(capi_name=cont)--*/
virtual void Continue(bool allow) = 0;
///
// Cancel the url request.
///
/*--cef()--*/
virtual void Cancel() = 0;
};
#endif // CEF_INCLUDE_CEF_REQUEST_CALLBACK_H_

View File

@ -44,9 +44,9 @@
#include "include/cef_cookie.h"
#include "include/cef_extension.h"
#include "include/cef_extension_handler.h"
#include "include/cef_request_context_handler.h"
#include "include/cef_values.h"
class CefRequestContextHandler;
class CefSchemeHandlerFactory;
///

View File

@ -39,10 +39,12 @@
#pragma once
#include "include/cef_base.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_request.h"
#include "include/cef_resource_request_handler.h"
#include "include/cef_web_plugin.h"
class CefRequestContext;
///
// Implement this interface to provide handler implementations. The handler
// instance will not be released until all objects related to the context have
@ -88,6 +90,37 @@ class CefRequestContextHandler : public virtual CefBaseRefCounted {
PluginPolicy* plugin_policy) {
return false;
}
///
// Called on the browser process IO thread before a resource request is
// initiated. The |browser| and |frame| values represent the source of the
// request, and may be NULL for requests originating from service workers.
// |request| represents the request contents and cannot be modified in this
// callback. |is_navigation| will be true if the resource request is a
// navigation. |is_download| will be true if the resource request is a
// download. |request_initiator| is the origin (scheme + domain) of the page
// that initiated the request. Set |disable_default_handling| to true to
// disable default handling of the request, in which case it will need to be
// handled via CefResourceRequestHandler::GetResourceHandler or it will be
// canceled. To allow the resource load to proceed with default handling
// return NULL. To specify a handler for the resource return a
// CefResourceRequestHandler object. This method will not be called if the
// client associated with |browser| returns a non-NULL value from
// CefRequestHandler::GetResourceRequestHandler for the same request
// (identified by CefRequest::GetIdentifier).
///
/*--cef(optional_param=browser,optional_param=frame,
optional_param=request_initiator)--*/
virtual 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) {
return NULL;
}
};
#endif // CEF_INCLUDE_CEF_REQUEST_CONTEXT_HANDLER_H_

View File

@ -45,32 +45,11 @@
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_request.h"
#include "include/cef_resource_handler.h"
#include "include/cef_response.h"
#include "include/cef_response_filter.h"
#include "include/cef_request_callback.h"
#include "include/cef_resource_request_handler.h"
#include "include/cef_ssl_info.h"
#include "include/cef_x509_certificate.h"
///
// Callback interface used for asynchronous continuation of url requests.
///
/*--cef(source=library)--*/
class CefRequestCallback : public virtual CefBaseRefCounted {
public:
///
// Continue the url request. If |allow| is true the request will be continued.
// Otherwise, the request will be canceled.
///
/*--cef(capi_name=cont)--*/
virtual void Continue(bool allow) = 0;
///
// Cancel the url request.
///
/*--cef()--*/
virtual void Cancel() = 0;
};
///
// Callback interface used to select a client certificate for authentication.
///
@ -92,9 +71,7 @@ class CefSelectClientCertificateCallback : public virtual CefBaseRefCounted {
/*--cef(source=client)--*/
class CefRequestHandler : public virtual CefBaseRefCounted {
public:
typedef cef_return_value_t ReturnValue;
typedef cef_termination_status_t TerminationStatus;
typedef cef_urlrequest_status_t URLRequestStatus;
typedef cef_window_open_disposition_t WindowOpenDisposition;
typedef std::vector<CefRefPtr<CefX509Certificate>> X509CertificateList;
@ -145,93 +122,32 @@ class CefRequestHandler : public virtual CefBaseRefCounted {
}
///
// Called on the IO thread before a resource request is loaded. The |request|
// object may be modified. Return RV_CONTINUE to continue the request
// immediately. Return RV_CONTINUE_ASYNC and call CefRequestCallback::
// Continue() at a later time to continue or cancel the request
// asynchronously. Return RV_CANCEL to cancel the request immediately.
//
// Called on the browser process IO thread before a resource request is
// initiated. The |browser| and |frame| values represent the source of the
// request. |request| represents the request contents and cannot be modified
// in this callback. |is_navigation| will be true if the resource request is a
// navigation. |is_download| will be true if the resource request is a
// download. |request_initiator| is the origin (scheme + domain) of the page
// that initiated the request. Set |disable_default_handling| to true to
// disable default handling of the request, in which case it will need to be
// handled via CefResourceRequestHandler::GetResourceHandler or it will be
// canceled. To allow the resource load to proceed with default handling
// return NULL. To specify a handler for the resource return a
// CefResourceRequestHandler object. If this callback returns NULL the same
// method will be called on the associated CefRequestContextHandler, if any.
///
/*--cef(default_retval=RV_CONTINUE)--*/
virtual ReturnValue OnBeforeResourceLoad(
/*--cef(optional_param=request_initiator)--*/
virtual CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefRequestCallback> callback) {
return RV_CONTINUE;
}
///
// Called on the IO thread before a resource is loaded. To allow the resource
// to load normally return NULL. To specify a handler for the resource return
// a CefResourceHandler object. The |request| object should not be modified in
// this callback.
///
/*--cef()--*/
virtual CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) {
bool is_navigation,
bool is_download,
const CefString& request_initiator,
bool& disable_default_handling) {
return NULL;
}
///
// Called on the IO thread when a resource load is redirected. The |request|
// parameter will contain the old URL and other request-related information.
// The |response| parameter will contain the response that resulted in the
// redirect. The |new_url| parameter will contain the new URL and can be
// changed if desired. The |request| object cannot be modified in this
// callback.
///
/*--cef()--*/
virtual void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
CefString& new_url) {}
///
// Called on the IO thread when a resource response is received. To allow the
// resource to load normally return false. To redirect or retry the resource
// modify |request| (url, headers or post body) and return true. The
// |response| object cannot be modified in this callback.
///
/*--cef()--*/
virtual bool OnResourceResponse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) {
return false;
}
///
// Called on the IO thread to optionally filter resource response content.
// |request| and |response| represent the request and response respectively
// and cannot be modified in this callback.
///
/*--cef()--*/
virtual CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) {
return NULL;
}
///
// Called on the IO thread when a resource load has completed. |request| and
// |response| represent the request and response respectively and cannot be
// modified in this callback. |status| indicates the load completion status.
// |received_content_length| is the number of response bytes actually read.
///
/*--cef()--*/
virtual void OnResourceLoadComplete(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
URLRequestStatus status,
int64 received_content_length) {}
///
// 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
@ -255,33 +171,6 @@ class CefRequestHandler : public virtual CefBaseRefCounted {
return false;
}
///
// Called on the IO thread before sending a network request with a "Cookie"
// request header. Return true to allow cookies to be included in the network
// request or false to block cookies. The |request| object should not be
// modified in this callback.
///
/*--cef()--*/
virtual bool CanGetCookies(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) {
return true;
}
///
// Called on the IO thread when receiving a network request with a
// "Set-Cookie" response header value represented by |cookie|. Return true to
// allow the cookie to be stored or false to block the cookie. The |request|
// object should not be modified in this callback.
///
/*--cef()--*/
virtual bool CanSetCookie(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
const CefCookie& cookie) {
return true;
}
///
// Called on the IO thread when JavaScript requests a specific storage quota
// size via the webkitStorageInfo.requestQuota function. |origin_url| is the
@ -298,18 +187,6 @@ class CefRequestHandler : public virtual CefBaseRefCounted {
return false;
}
///
// Called on the UI thread to handle requests for URLs with an unknown
// protocol component. Set |allow_os_execution| to true to attempt execution
// via the registered OS protocol handler, if any.
// SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS BASED
// ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION.
///
/*--cef()--*/
virtual void OnProtocolExecution(CefRefPtr<CefBrowser> browser,
const CefString& url,
bool& allow_os_execution) {}
///
// Called on the UI thread to handle requests for URLs with an invalid
// SSL certificate. Return true and call CefRequestCallback::Continue() either

View File

@ -45,23 +45,79 @@
#include "include/cef_request.h"
#include "include/cef_response.h"
///
// Callback for asynchronous continuation of CefResourceHandler::Skip().
///
/*--cef(source=library)--*/
class CefResourceSkipCallback : public virtual CefBaseRefCounted {
public:
///
// 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.
///
/*--cef(capi_name=cont)--*/
virtual void Continue(int64 bytes_skipped) = 0;
};
///
// Callback for asynchronous continuation of CefResourceHandler::Read().
///
/*--cef(source=library)--*/
class CefResourceReadCallback : public virtual CefBaseRefCounted {
public:
///
// 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.
///
/*--cef(capi_name=cont)--*/
virtual void Continue(int bytes_read) = 0;
};
///
// Class used to implement a custom request handler interface. The methods of
// this class will always be called on the IO thread.
// this class will be called on the IO thread unless otherwise indicated.
///
/*--cef(source=client)--*/
class CefResourceHandler : public virtual CefBaseRefCounted {
public:
///
// Open the response stream. To handle the request immediately set
// |handle_request| to true and return true. To decide at a later time set
// |handle_request| to false, return true, and execute |callback| to continue
// or cancel the request. To cancel the request immediately set
// |handle_request| to true and return false. This method will be called in
// sequence but not from a dedicated thread. For backwards compatibility set
// |handle_request| to false and return false and the ProcessRequest method
// will be called.
///
/*--cef()--*/
virtual bool Open(CefRefPtr<CefRequest> request,
bool& handle_request,
CefRefPtr<CefCallback> callback) {
handle_request = false;
return false;
}
///
// Begin processing the request. To handle the request return true and call
// CefCallback::Continue() once the response header information is available
// (CefCallback::Continue() can also be called from inside this method if
// header information is available immediately). To cancel the request return
// false.
//
// WARNING: This method is deprecated. Use Open instead.
///
/*--cef()--*/
virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback) = 0;
CefRefPtr<CefCallback> callback) {
return false;
}
///
// Retrieve response header information. If the response length is not known
@ -83,33 +139,62 @@ class CefResourceHandler : public virtual CefBaseRefCounted {
int64& response_length,
CefString& redirectUrl) = 0;
///
// Skip response data when requested by a Range header. Skip over and discard
// |bytes_to_skip| bytes of response data. If data is available immediately
// set |bytes_skipped| to the number of of bytes skipped and return true. To
// read the data at a later time set |bytes_skipped| to 0, return true and
// execute |callback| when the data is available. To indicate failure set
// |bytes_skipped| to < 0 (e.g. -2 for ERR_FAILED) and return false. This
// method will be called in sequence but not from a dedicated thread.
///
/*--cef()--*/
virtual bool Skip(int64 bytes_to_skip,
int64& bytes_skipped,
CefRefPtr<CefResourceSkipCallback> callback) {
bytes_skipped = -2;
return false;
}
///
// 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. To read the data at a later time keep a
// pointer to |data_out|, set |bytes_read| to 0, return true 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. To indicate failure set |bytes_read| to < 0 (e.g. -2
// for ERR_FAILED) and return false. This method will be called in sequence
// but not from a dedicated thread. For backwards compatibility set
// |bytes_read| to -1 and return false and the ReadResponse method will be
// called.
///
/*--cef()--*/
virtual bool Read(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefResourceReadCallback> callback) {
bytes_read = -1;
return false;
}
///
// 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. To read the data at a later time set
// |bytes_read| to 0, return true and call CefCallback::Continue() when the
// data is available. To indicate response completion return false.
//
// WARNING: This method is deprecated. Use Skip and Read instead.
///
/*--cef()--*/
virtual bool ReadResponse(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefCallback> callback) = 0;
///
// Return true if the specified cookie can be sent with the request or false
// otherwise. If false is returned for any cookie then no cookies will be sent
// with the request.
///
/*--cef()--*/
virtual bool CanGetCookie(const CefCookie& cookie) { return true; }
///
// Return true if the specified cookie returned with the response can be set
// or false otherwise.
///
/*--cef()--*/
virtual bool CanSetCookie(const CefCookie& cookie) { return true; }
CefRefPtr<CefCallback> callback) {
bytes_read = -2;
return false;
}
///
// Request processing has been canceled.

View File

@ -0,0 +1,211 @@
// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// The contents of this file must follow a specific format in order to
// support the CEF translator tool. See the translator.README.txt file in the
// tools directory for more information.
//
#ifndef CEF_INCLUDE_CEF_RESOURCE_REQUEST_HANDLER_H_
#define CEF_INCLUDE_CEF_RESOURCE_REQUEST_HANDLER_H_
#pragma once
#include "include/cef_base.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_request.h"
#include "include/cef_request_callback.h"
#include "include/cef_resource_handler.h"
#include "include/cef_response.h"
#include "include/cef_response_filter.h"
#include "include/internal/cef_types_wrappers.h"
///
// Implement this interface to handle events related to browser requests. The
// methods of this class will be called on the IO thread unless otherwise
// indicated.
///
/*--cef(source=client)--*/
class CefResourceRequestHandler : public virtual CefBaseRefCounted {
public:
typedef cef_return_value_t ReturnValue;
typedef cef_urlrequest_status_t URLRequestStatus;
///
// Called on the IO thread before a resource request is loaded. The |browser|
// and |frame| values represent the source of the request, and may be NULL for
// requests originating from service workers. To redirect or change the
// resource load optionally modify |request|. Modification of the request URL
// will be treated as a redirect. Return RV_CONTINUE to continue the request
// immediately. Return RV_CONTINUE_ASYNC and call CefRequestCallback::
// Continue() at a later time to continue or cancel the request
// asynchronously. Return RV_CANCEL to cancel the request immediately.
//
///
/*--cef(optional_param=browser,optional_param=frame,
default_retval=RV_CONTINUE)--*/
virtual ReturnValue OnBeforeResourceLoad(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefRequestCallback> callback) {
return RV_CONTINUE;
}
///
// Called on the IO thread before a resource is loaded. The |browser| and
// |frame| values represent the source of the request, and may be NULL for
// requests originating from service workers. To allow the resource to load
// using the default network loader return NULL. To specify a handler for the
// resource return a CefResourceHandler object. The |request| object should
// not be modified in this callback.
///
/*--cef(optional_param=browser,optional_param=frame)--*/
virtual CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) {
return NULL;
}
///
// Called on the IO thread when a resource load is redirected. The |browser|
// and |frame| values represent the source of the request, and may be NULL for
// requests originating from service workers. The |request| parameter will
// contain the old URL and other request-related information. The |response|
// parameter will contain the response that resulted in the redirect. The
// |new_url| parameter will contain the new URL and can be changed if desired.
// The |request| and |response| objects cannot be modified in this callback.
///
/*--cef(optional_param=browser,optional_param=frame)--*/
virtual void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
CefString& new_url) {}
///
// Called on the IO thread when a resource response is received. The |browser|
// and |frame| values represent the source of the request, and may be NULL for
// requests originating from service workers. To allow the resource load to
// proceed without modification return false. To redirect or retry the
// resource load optionally modify |request| and return true. Modification of
// the request URL will be treated as a redirect. Requests handled using the
// default network loader cannot be redirected in this callback. The
// |response| object cannot be modified in this callback.
//
// WARNING: Redirecting using this method is deprecated. Use
// OnBeforeResourceLoad or GetResourceHandler to perform redirects.
///
/*--cef(optional_param=browser,optional_param=frame)--*/
virtual bool OnResourceResponse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) {
return false;
}
///
// Called on the IO thread to optionally filter resource response content. The
// |browser| and |frame| values represent the source of the request, and may
// be NULL for requests originating from service workers. |request| and
// |response| represent the request and response respectively and cannot be
// modified in this callback.
///
/*--cef(optional_param=browser,optional_param=frame)--*/
virtual CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) {
return NULL;
}
///
// Called on the IO thread when a resource load has completed. The |browser|
// and |frame| values represent the source of the request, and may be NULL for
// requests originating from service workers. |request| and |response|
// represent the request and response respectively and cannot be modified in
// this callback. |status| indicates the load completion status.
// |received_content_length| is the number of response bytes actually read.
///
/*--cef(optional_param=browser,optional_param=frame)--*/
virtual void OnResourceLoadComplete(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
URLRequestStatus status,
int64 received_content_length) {}
///
// Called on the IO thread to handle requests for URLs with an unknown
// protocol component. The |browser| and |frame| values represent the source
// of the request, and may be NULL for requests originating from service
// workers. |request| cannot be modified in this callback. Set
// |allow_os_execution| to true to attempt execution via the registered OS
// protocol handler, if any.
// SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS BASED
// ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION.
///
/*--cef(optional_param=browser,optional_param=frame)--*/
virtual void OnProtocolExecution(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool& allow_os_execution) {}
///
// Called on the IO thread before a resource request is sent. Return true if
// the specified cookie can be sent with the request or false otherwise.
///
/*--cef(optional_param=browser,optional_param=frame)--*/
virtual bool CanSendCookie(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
const CefCookie& cookie) {
return true;
}
///
// Called on the IO thread after a resource response is received. Return true
// if the specified cookie returned with the response can be saved or false
// otherwise.
///
/*--cef(optional_param=browser,optional_param=frame)--*/
virtual bool CanSaveCookie(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
const CefCookie& cookie) {
return true;
}
};
#endif // CEF_INCLUDE_CEF_RESOURCE_REQUEST_HANDLER_H_

View File

@ -111,6 +111,18 @@ class CefResponse : public virtual CefBaseRefCounted {
/*--cef()--*/
virtual void SetMimeType(const CefString& mimeType) = 0;
///
// Get the response charset.
///
/*--cef()--*/
virtual CefString GetCharset() = 0;
///
// Set the response charset.
///
/*--cef()--*/
virtual void SetCharset(const CefString& charset) = 0;
///
// Get the value for the specified response header field.
///

View File

@ -109,7 +109,7 @@ class CefSchemeHandlerFactory : public virtual CefBaseRefCounted {
// will be the browser window and frame respectively that originated the
// request or NULL if the request did not originate from a browser window
// (for example, if the request came from CefURLRequest). The |request| object
// passed to this method will not contain cookie data.
// passed to this method cannot be modified.
///
/*--cef(optional_param=browser,optional_param=frame)--*/
virtual CefRefPtr<CefResourceHandler> Create(

View File

@ -558,10 +558,6 @@ const CefRequestContextSettings& CefBrowserContext::GetSettings() const {
return settings_;
}
CefRefPtr<CefRequestContextHandler> CefBrowserContext::GetHandler() const {
return NULL;
}
HostContentSettingsMap* CefBrowserContext::GetHostContentSettingsMap() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!host_content_settings_map_.get()) {
@ -607,19 +603,24 @@ void CefBrowserContext::OnRenderFrameCreated(
CefRequestContextImpl* request_context,
int render_process_id,
int render_frame_id,
int frame_tree_node_id,
bool is_main_frame,
bool is_guest_view) {
CEF_REQUIRE_UIT();
DCHECK_GE(render_process_id, 0);
DCHECK_GE(render_frame_id, 0);
DCHECK_GE(frame_tree_node_id, 0);
CefRefPtr<CefRequestContextHandler> handler = request_context->GetHandler();
if (handler && resource_context_) {
DCHECK_GE(render_process_id, 0);
// Using base::Unretained() is safe because both this callback and possible
// deletion of |resource_context_| will execute on the IO thread, and this
// callback will be executed first.
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefResourceContext::AddHandler,
base::Unretained(resource_context_.get()),
render_process_id, render_frame_id, handler));
CEF_POST_TASK(CEF_IOT, base::Bind(&CefResourceContext::AddHandler,
base::Unretained(resource_context_.get()),
render_process_id, render_frame_id,
frame_tree_node_id, handler));
}
}
@ -627,9 +628,14 @@ void CefBrowserContext::OnRenderFrameDeleted(
CefRequestContextImpl* request_context,
int render_process_id,
int render_frame_id,
int frame_tree_node_id,
bool is_main_frame,
bool is_guest_view) {
CEF_REQUIRE_UIT();
DCHECK_GE(render_process_id, 0);
DCHECK_GE(render_frame_id, 0);
DCHECK_GE(frame_tree_node_id, 0);
CefRefPtr<CefRequestContextHandler> handler = request_context->GetHandler();
if (handler && resource_context_) {
DCHECK_GE(render_process_id, 0);
@ -638,7 +644,8 @@ void CefBrowserContext::OnRenderFrameDeleted(
// callback will be executed first.
CEF_POST_TASK(CEF_IOT, base::Bind(&CefResourceContext::RemoveHandler,
base::Unretained(resource_context_.get()),
render_process_id, render_frame_id));
render_process_id, render_frame_id,
frame_tree_node_id));
}
if (resource_context_ && is_main_frame) {
@ -664,3 +671,29 @@ void CefBrowserContext::OnPurgePluginListCache() {
base::Unretained(resource_context_.get()), -1));
}
}
void CefBrowserContext::RegisterSchemeHandlerFactory(
const std::string& scheme_name,
const std::string& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) {
if (resource_context_) {
// Using base::Unretained() is safe because both this callback and possible
// deletion of |resource_context_| will execute on the IO thread, and this
// callback will be executed first.
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefResourceContext::RegisterSchemeHandlerFactory,
base::Unretained(resource_context_.get()),
scheme_name, domain_name, factory));
}
}
void CefBrowserContext::ClearSchemeHandlerFactories() {
if (resource_context_) {
// Using base::Unretained() is safe because both this callback and possible
// deletion of |resource_context_| will execute on the IO thread, and this
// callback will be executed first.
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefResourceContext::ClearSchemeHandlerFactories,
base::Unretained(resource_context_.get())));
}
}

View File

@ -181,6 +181,15 @@ class CefBrowserContext : public ChromeProfileStub,
const PrefService* GetPrefs() const override;
SimpleFactoryKey* GetSimpleFactoryKey() const override;
// Values checked in ProfileNetworkContextService::CreateNetworkContextParams
// when creating the NetworkContext.
bool ShouldPersistSessionCookies() override {
return should_persist_session_cookies_;
}
std::vector<std::string> GetCookieableSchemes() override {
return cookieable_schemes_;
}
// visitedlink::VisitedLinkDelegate methods.
void RebuildTable(const scoped_refptr<URLEnumerator>& enumerator) override;
@ -188,10 +197,6 @@ class CefBrowserContext : public ChromeProfileStub,
// thread.
const CefRequestContextSettings& GetSettings() const;
// Returns the handler associated with this object. Safe to call from any
// thread.
CefRefPtr<CefRequestContextHandler> GetHandler() const;
// Settings for plugins and extensions.
HostContentSettingsMap* GetHostContentSettingsMap();
@ -203,6 +208,7 @@ class CefBrowserContext : public ChromeProfileStub,
void OnRenderFrameCreated(CefRequestContextImpl* request_context,
int render_process_id,
int render_frame_id,
int frame_tree_node_id,
bool is_main_frame,
bool is_guest_view);
@ -210,6 +216,7 @@ class CefBrowserContext : public ChromeProfileStub,
void OnRenderFrameDeleted(CefRequestContextImpl* request_context,
int render_process_id,
int render_frame_id,
int frame_tree_node_id,
bool is_main_frame,
bool is_guest_view);
@ -217,6 +224,19 @@ class CefBrowserContext : public ChromeProfileStub,
// plugin list cache should be purged.
void OnPurgePluginListCache();
// Called from CefRequestContextImpl methods of the same name.
void RegisterSchemeHandlerFactory(const std::string& scheme_name,
const std::string& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory);
void ClearSchemeHandlerFactories();
void set_should_persist_session_cookies(bool value) {
should_persist_session_cookies_ = value;
}
void set_cookieable_schemes(const std::vector<std::string>& schemes) {
cookieable_schemes_ = schemes;
}
CefResourceContext* resource_context() const {
return resource_context_.get();
}
@ -252,6 +272,8 @@ class CefBrowserContext : public ChromeProfileStub,
std::unique_ptr<visitedlink::VisitedLinkMaster> visitedlink_master_;
// |visitedlink_listener_| is owned by visitedlink_master_.
CefVisitedLinkListener* visitedlink_listener_;
bool should_persist_session_cookies_ = false;
std::vector<std::string> cookieable_schemes_;
std::unique_ptr<CefResourceContext> resource_context_;

View File

@ -1636,6 +1636,29 @@ void CefBrowserHostImpl::CancelContextMenu() {
menu_manager_->CancelContextMenu();
}
CefRefPtr<CefFrame> CefBrowserHostImpl::GetFrameForHost(
const content::RenderFrameHost* host_const) {
CEF_REQUIRE_UIT();
if (!host_const)
return nullptr;
content::RenderFrameHost* host =
const_cast<content::RenderFrameHost*>(host_const);
content::RenderFrameHost* parent = host->GetParent();
return GetOrCreateFrame(
host->GetRoutingID(), host->GetFrameTreeNodeId(),
parent ? parent->GetRoutingID() : CefFrameHostImpl::kUnspecifiedFrameId,
parent == nullptr /* is_main_frame */,
false /* is_main_frame_state_flaky */, base::string16(), GURL());
}
CefRefPtr<CefFrame> CefBrowserHostImpl::GetFrameForHostRoutingId(
int render_frame_id) {
return GetOrCreateFrame(
render_frame_id, kUnspecifiedFrameTreeNodeId,
CefFrameHostImpl::kUnspecifiedFrameId, false /* is_main_frame */,
true /* is_main_frame_state_flaky */, base::string16(), GURL());
}
CefRefPtr<CefFrame> CefBrowserHostImpl::GetFrameForRequest(
const net::URLRequest* request) {
CEF_REQUIRE_IOT();
@ -1878,25 +1901,6 @@ void CefBrowserHostImpl::ViewText(const std::string& text) {
platform_delegate_->ViewText(text);
}
void CefBrowserHostImpl::HandleExternalProtocol(const GURL& url) {
if (CEF_CURRENTLY_ON_UIT()) {
bool allow_os_execution = false;
if (client_.get()) {
CefRefPtr<CefRequestHandler> handler = client_->GetRequestHandler();
if (handler.get())
handler->OnProtocolExecution(this, url.spec(), allow_os_execution);
}
if (allow_os_execution && platform_delegate_)
platform_delegate_->HandleExternalProtocol(url);
} else {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&CefBrowserHostImpl::HandleExternalProtocol, this, url));
}
}
SkColor CefBrowserHostImpl::GetBackgroundColor() const {
// Don't use |platform_delegate_| because it's not thread-safe.
return CefContext::Get()->GetBackgroundColor(
@ -2723,7 +2727,8 @@ void CefBrowserHostImpl::RenderFrameCreated(
const bool is_main_frame = (render_frame_host->GetParent() == nullptr);
request_context_->OnRenderFrameCreated(render_process_id, render_routing_id,
is_main_frame, false);
frame_tree_node_id, is_main_frame,
false);
}
void CefBrowserHostImpl::RenderFrameHostChanged(
@ -2747,7 +2752,8 @@ void CefBrowserHostImpl::FrameDeleted(
const bool is_main_frame = (render_frame_host->GetParent() == nullptr);
request_context_->OnRenderFrameDeleted(render_process_id, render_routing_id,
is_main_frame, false);
frame_tree_node_id, is_main_frame,
false);
base::AutoLock lock_scope(state_lock_);

View File

@ -309,6 +309,12 @@ class CefBrowserHostImpl : public CefBrowserHost,
CefRefPtr<CefBrowserView> GetBrowserView() const;
#endif
// Returns the frame associated with the specified RenderFrameHost.
CefRefPtr<CefFrame> GetFrameForHost(const content::RenderFrameHost* host);
// Returns the frame associated with the specified RenderFrameHost routing ID.
CefRefPtr<CefFrame> GetFrameForHostRoutingId(int render_frame_id);
// Returns the frame associated with the specified URLRequest.
CefRefPtr<CefFrame> GetFrameForRequest(const net::URLRequest* request);
@ -349,9 +355,6 @@ class CefBrowserHostImpl : public CefBrowserHost,
// Open the specified text in the default text editor.
void ViewText(const std::string& text);
// Handler for URLs involving external protocols.
void HandleExternalProtocol(const GURL& url);
// Convert from view coordinates to screen coordinates. Potential display
// scaling will be applied to the result.
gfx::Point GetScreenPoint(const gfx::Point& view) const;

View File

@ -184,7 +184,7 @@ class CefBrowserPlatformDelegate {
const content::NativeWebKeyboardEvent& event) = 0;
// Invoke platform specific handling for the external protocol.
virtual void HandleExternalProtocol(const GURL& url) = 0;
static void HandleExternalProtocol(const GURL& url);
// Translate CEF events to Chromium/Blink events.
virtual void TranslateKeyEvent(content::NativeWebKeyboardEvent& result,

View File

@ -81,7 +81,7 @@ void ChromeBrowserProcessStub::Shutdown() {
profile_manager_.reset();
event_router_forwarder_ = nullptr;
if (net_service::IsEnabled()) {
if (net_service::IsEnabled() && SystemNetworkContextManager::GetInstance()) {
SystemNetworkContextManager::DeleteInstance();
}

View File

@ -20,6 +20,9 @@
#include "libcef/browser/extensions/extension_system.h"
#include "libcef/browser/media_capture_devices_dispatcher.h"
#include "libcef/browser/net/chrome_scheme_handler.h"
#include "libcef/browser/net/net_util.h"
#include "libcef/browser/net_service/proxy_url_loader_factory.h"
#include "libcef/browser/net_service/resource_request_handler_wrapper.h"
#include "libcef/browser/plugins/plugin_service_filter.h"
#include "libcef/browser/prefs/renderer_prefs.h"
#include "libcef/browser/printing/printing_message_filter.h"
@ -1176,7 +1179,17 @@ bool CefContentBrowserClient::WillCreateURLLoaderFactory(
network::mojom::URLLoaderFactoryRequest* factory_request,
network::mojom::TrustedURLLoaderHeaderClientPtrInfo* header_client,
bool* bypass_redirect_checks) {
return false;
if (!net_service::IsEnabled())
return false;
auto request_handler = net_service::CreateInterceptedRequestHandler(
browser_context, frame, render_process_id, is_navigation, is_download,
request_initiator);
net_service::ProxyURLLoaderFactory::CreateProxy(
browser_context, factory_request, header_client,
std::move(request_handler));
return true;
}
void CefContentBrowserClient::OnNetworkServiceCreated(
@ -1243,15 +1256,38 @@ bool CefContentBrowserClient::HandleExternalProtocol(
const net::HttpRequestHeaders& headers,
network::mojom::URLLoaderFactoryRequest* factory_request,
network::mojom::URLLoaderFactory*& out_factory) {
CEF_POST_TASK(
CEF_UIT,
base::Bind(
base::IgnoreResult(
&CefContentBrowserClient::HandleExternalProtocolOnUIThread),
url, web_contents_getter));
if (net_service::IsEnabled()) {
// Call the other HandleExternalProtocol variant.
return false;
}
CefRefPtr<CefRequestImpl> requestPtr = new CefRequestImpl();
requestPtr->SetURL(url.spec());
requestPtr->SetMethod(method);
requestPtr->Set(headers);
requestPtr->SetReadOnly(true);
net_util::HandleExternalProtocol(requestPtr, web_contents_getter);
return false;
}
bool CefContentBrowserClient::HandleExternalProtocol(
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
int frame_tree_node_id,
content::NavigationUIData* navigation_data,
const network::ResourceRequest& request,
network::mojom::URLLoaderFactoryRequest* factory_request,
network::mojom::URLLoaderFactory*& out_factory) {
DCHECK(net_service::IsEnabled());
// CefBrowserPlatformDelegate::HandleExternalProtocol may be called if
// nothing handles the request.
auto request_handler = net_service::CreateInterceptedRequestHandler(
web_contents_getter, frame_tree_node_id, request);
out_factory = net_service::ProxyURLLoaderFactory::CreateProxy(
web_contents_getter, factory_request, std::move(request_handler));
return true;
}
std::string CefContentBrowserClient::GetProduct() const {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
@ -1333,18 +1369,3 @@ const extensions::Extension* CefContentBrowserClient::GetExtension(
return registry->enabled_extensions().GetExtensionOrAppByURL(
site_instance->GetSiteURL());
}
// static
void CefContentBrowserClient::HandleExternalProtocolOnUIThread(
const GURL& url,
const content::ResourceRequestInfo::WebContentsGetter&
web_contents_getter) {
CEF_REQUIRE_UIT();
content::WebContents* web_contents = web_contents_getter.Run();
if (web_contents) {
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForContents(web_contents);
if (browser.get())
browser->HandleExternalProtocol(url);
}
}

View File

@ -174,6 +174,13 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
const net::HttpRequestHeaders& headers,
network::mojom::URLLoaderFactoryRequest* factory_request,
network::mojom::URLLoaderFactory*& out_factory) override;
bool HandleExternalProtocol(
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
int frame_tree_node_id,
content::NavigationUIData* navigation_data,
const network::ResourceRequest& request,
network::mojom::URLLoaderFactoryRequest* factory_request,
network::mojom::URLLoaderFactory*& out_factory) override;
std::string GetProduct() const override;
std::string GetChromeProduct() const override;
std::string GetUserAgent() const override;
@ -194,11 +201,6 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
const extensions::Extension* GetExtension(
content::SiteInstance* site_instance);
static void HandleExternalProtocolOnUIThread(
const GURL& url,
const content::ResourceRequestInfo::WebContentsGetter&
web_contents_getter);
CefBrowserMainParts* browser_main_parts_;
std::unique_ptr<content::PluginServiceFilter> plugin_service_filter_;

View File

@ -91,11 +91,6 @@ bool CefBrowserPlatformDelegateBackground::HandleKeyboardEvent(
return false;
}
void CefBrowserPlatformDelegateBackground::HandleExternalProtocol(
const GURL& url) {
native_delegate_->HandleExternalProtocol(url);
}
void CefBrowserPlatformDelegateBackground::TranslateKeyEvent(
content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) const {

View File

@ -34,7 +34,6 @@ class CefBrowserPlatformDelegateBackground
void ViewText(const std::string& text) override;
bool HandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) override;
void HandleExternalProtocol(const GURL& url) override;
void TranslateKeyEvent(content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) const override;
void TranslateClickEvent(blink::WebMouseEvent& result,

View File

@ -71,7 +71,8 @@ void CefMimeHandlerViewGuestDelegate::OnGuestAttached(
const bool is_main_frame = (main_frame_host->GetParent() == nullptr);
owner_browser->request_context()->OnRenderFrameCreated(
render_process_id, render_frame_id, is_main_frame, true);
render_process_id, render_frame_id, frame_tree_node_id, is_main_frame,
true);
}
void CefMimeHandlerViewGuestDelegate::OnGuestDetached(
@ -96,7 +97,8 @@ void CefMimeHandlerViewGuestDelegate::OnGuestDetached(
const bool is_main_frame = (main_frame_host->GetParent() == nullptr);
owner_browser->request_context()->OnRenderFrameDeleted(
render_process_id, render_frame_id, is_main_frame, true);
render_process_id, render_frame_id, frame_tree_node_id, is_main_frame,
true);
}
bool CefMimeHandlerViewGuestDelegate::HandleContextMenu(

View File

@ -16,6 +16,7 @@
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/render_view_host.h"
#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h"
@ -23,7 +24,6 @@
#include "ui/events/keycodes/keysym_to_unicode.h"
#include "ui/gfx/font_render_params.h"
#include "ui/views/widget/widget.h"
#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
#if defined(USE_X11)
#include "libcef/browser/native/window_x11.h"
@ -78,8 +78,9 @@ bool CefBrowserPlatformDelegateNativeLinux::CreateHostWindow() {
DCHECK(!window_x11_);
// Create a new window object. It will delete itself when the associated X11
// window is destroyed.
window_x11_ = new CefWindowX11(browser_, window_info_.parent_window, rect,
CefString(&window_info_.window_name).ToString());
window_x11_ =
new CefWindowX11(browser_, window_info_.parent_window, rect,
CefString(&window_info_.window_name).ToString());
window_info_.window = window_x11_->xwindow();
host_window_created_ = true;
@ -251,8 +252,8 @@ bool CefBrowserPlatformDelegateNativeLinux::HandleKeyboardEvent(
return false;
}
void CefBrowserPlatformDelegateNativeLinux::HandleExternalProtocol(
const GURL& url) {}
// static
void CefBrowserPlatformDelegate::HandleExternalProtocol(const GURL& url) {}
void CefBrowserPlatformDelegateNativeLinux::TranslateKeyEvent(
content::NativeWebKeyboardEvent& result,

View File

@ -32,7 +32,6 @@ class CefBrowserPlatformDelegateNativeLinux
void ViewText(const std::string& text) override;
bool HandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) override;
void HandleExternalProtocol(const GURL& url) override;
void TranslateKeyEvent(content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) const override;
void TranslateClickEvent(blink::WebMouseEvent& result,

View File

@ -24,7 +24,6 @@ class CefBrowserPlatformDelegateNativeMac
void ViewText(const std::string& text) override;
bool HandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) override;
void HandleExternalProtocol(const GURL& url) override;
void TranslateKeyEvent(content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) const override;
void TranslateClickEvent(blink::WebMouseEvent& result,

View File

@ -301,8 +301,8 @@ bool CefBrowserPlatformDelegateNativeMac::HandleKeyboardEvent(
return false;
}
void CefBrowserPlatformDelegateNativeMac::HandleExternalProtocol(
const GURL& url) {}
// static
void CefBrowserPlatformDelegate::HandleExternalProtocol(const GURL& url) {}
void CefBrowserPlatformDelegateNativeMac::TranslateKeyEvent(
content::NativeWebKeyboardEvent& result,

View File

@ -399,8 +399,8 @@ bool CefBrowserPlatformDelegateNativeWin::HandleKeyboardEvent(
}
}
void CefBrowserPlatformDelegateNativeWin::HandleExternalProtocol(
const GURL& url) {
// static
void CefBrowserPlatformDelegate::HandleExternalProtocol(const GURL& url) {
CEF_POST_USER_VISIBLE_TASK(base::Bind(ExecuteExternalProtocol, url));
}

View File

@ -31,7 +31,6 @@ class CefBrowserPlatformDelegateNativeWin
void ViewText(const std::string& text) override;
bool HandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) override;
void HandleExternalProtocol(const GURL& url) override;
void TranslateKeyEvent(content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) const override;
void TranslateClickEvent(blink::WebMouseEvent& result,

View File

@ -11,6 +11,7 @@
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/net/network_delegate.h"
#include "libcef/common/net_service/net_service_util.h"
#include "libcef/common/task_runner_impl.h"
#include "libcef/common/time_util.h"
@ -22,8 +23,6 @@
#include "components/net_log/chrome_net_log.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "net/cookies/cookie_util.h"
#include "net/cookies/parsed_cookie.h"
#include "net/url_request/url_request_context.h"
#include "url/gurl.h"
@ -54,7 +53,7 @@ class VisitCookiesCallback
for (; it != list.end(); ++it, ++count) {
CefCookie cookie;
const net::CanonicalCookie& cc = *(it);
CefCookieManagerOldImpl::GetCefCookie(cc, cookie);
net_service::MakeCefCookie(cc, cookie);
bool deleteCookie = false;
bool keepLooping = visitor_->Visit(cookie, count, total, deleteCookie);
@ -85,19 +84,6 @@ class VisitCookiesCallback
CefRefPtr<CefCookieVisitor> visitor_;
};
// Methods extracted from net/cookies/cookie_store.cc
// Determine the cookie domain to use for setting the specified cookie.
bool GetCookieDomain(const GURL& url,
const net::ParsedCookie& pc,
std::string* result) {
std::string domain_string;
if (pc.HasDomain())
domain_string = pc.Domain();
return net::cookie_util::GetCookieDomainWithString(url, domain_string,
result);
}
// Always execute the callback asynchronously.
void RunAsyncCompletionOnUIThread(CefRefPtr<CefCompletionCallback> callback) {
if (!callback.get())
@ -254,61 +240,6 @@ bool CefCookieManagerOldImpl::FlushStore(
return true;
}
// static
bool CefCookieManagerOldImpl::GetCefCookie(const net::CanonicalCookie& cc,
CefCookie& cookie) {
CefString(&cookie.name).FromString(cc.Name());
CefString(&cookie.value).FromString(cc.Value());
CefString(&cookie.domain).FromString(cc.Domain());
CefString(&cookie.path).FromString(cc.Path());
cookie.secure = cc.IsSecure();
cookie.httponly = cc.IsHttpOnly();
cef_time_from_basetime(cc.CreationDate(), cookie.creation);
cef_time_from_basetime(cc.LastAccessDate(), cookie.last_access);
cookie.has_expires = cc.IsPersistent();
if (cookie.has_expires)
cef_time_from_basetime(cc.ExpiryDate(), cookie.expires);
return true;
}
// static
bool CefCookieManagerOldImpl::GetCefCookie(const GURL& url,
const std::string& cookie_line,
CefCookie& cookie) {
// Parse the cookie.
net::ParsedCookie pc(cookie_line);
if (!pc.IsValid())
return false;
std::string cookie_domain;
if (!GetCookieDomain(url, pc, &cookie_domain))
return false;
std::string path_string;
if (pc.HasPath())
path_string = pc.Path();
std::string cookie_path =
net::CanonicalCookie::CanonPathWithString(url, path_string);
base::Time creation_time = base::Time::Now();
base::Time cookie_expires =
net::CanonicalCookie::CanonExpiration(pc, creation_time, creation_time);
CefString(&cookie.name).FromString(pc.Name());
CefString(&cookie.value).FromString(pc.Value());
CefString(&cookie.domain).FromString(cookie_domain);
CefString(&cookie.path).FromString(cookie_path);
cookie.secure = pc.IsSecure();
cookie.httponly = pc.IsHttpOnly();
cef_time_from_basetime(creation_time, cookie.creation);
cef_time_from_basetime(creation_time, cookie.last_access);
cookie.has_expires = !cookie_expires.is_null();
if (cookie.has_expires)
cef_time_from_basetime(cookie_expires, cookie.expires);
return true;
}
// static
void CefCookieManagerOldImpl::SetCookieMonsterSchemes(
net::CookieMonster* cookie_monster,

View File

@ -56,11 +56,6 @@ class CefCookieManagerOldImpl : public CefCookieManager {
CefRefPtr<CefDeleteCookiesCallback> callback) override;
bool FlushStore(CefRefPtr<CefCompletionCallback> callback) override;
static bool GetCefCookie(const net::CanonicalCookie& cc, CefCookie& cookie);
static bool GetCefCookie(const GURL& url,
const std::string& cookie_line,
CefCookie& cookie);
// Set the schemes supported by |cookie_monster|. Default schemes will always
// be supported.
static void SetCookieMonsterSchemes(net::CookieMonster* cookie_monster,

View File

@ -4,11 +4,117 @@
#include "libcef/browser/net/net_util.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/resource_context.h"
#include "libcef/common/net/scheme_registration.h"
#include "base/optional.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/resource_request_info.h"
#include "net/url_request/url_request.h"
#include "url/origin.h"
#include "url/url_constants.h"
namespace net_util {
namespace {
CefString SerializeRequestInitiator(
base::Optional<url::Origin> request_initiator) {
if (request_initiator.has_value())
return request_initiator->Serialize();
return "null";
}
CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
CefResourceContext* resource_context,
int render_process_id,
int render_frame_id,
int frame_tree_node_id,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool is_navigation,
bool is_download,
base::Optional<url::Origin> request_initiator) {
CEF_REQUIRE_IOT();
DCHECK(resource_context);
DCHECK(request);
CefRefPtr<CefResourceRequestHandler> resource_request_handler;
const CefString& request_initiator_str =
SerializeRequestInitiator(request_initiator);
const bool is_custom_scheme =
!GURL(request->GetURL().ToString()).SchemeIsHTTPOrHTTPS();
// Not supported by the old network implementation, but keep the value
// consistent with the NetworkService implementation.
bool disable_default_handling = is_custom_scheme;
// Give the browser handler a chance first.
if (browser) {
DCHECK(frame);
CefRefPtr<CefClient> client = browser->GetHost()->GetClient();
if (client) {
CefRefPtr<CefRequestHandler> request_handler =
client->GetRequestHandler();
if (request_handler) {
resource_request_handler = request_handler->GetResourceRequestHandler(
browser, frame, request, is_navigation, is_download,
request_initiator_str, disable_default_handling);
}
}
}
// Give the request context handler a chance.
if (!resource_request_handler) {
CefRefPtr<CefRequestContextHandler> request_context_handler =
resource_context->GetHandler(render_process_id, render_frame_id,
frame_tree_node_id, false);
if (request_context_handler) {
resource_request_handler =
request_context_handler->GetResourceRequestHandler(
browser, frame, request, is_navigation, is_download,
request_initiator_str, disable_default_handling);
}
}
return resource_request_handler;
}
void HandleExternalProtocolOnIOThread(CefResourceContext* resource_context,
int render_process_id,
CefRefPtr<CefBrowserHostImpl> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequestImpl> request) {
CEF_REQUIRE_IOT();
CefRefPtr<CefResourceRequestHandler> request_handler =
GetResourceRequestHandler(
resource_context, render_process_id, -1, -1, browser.get(), frame,
request.get(), true /* is_navigation */, false /* is_download */,
base::Optional<url::Origin>());
if (!request_handler)
return;
bool allow_os_execution = false;
request_handler->OnProtocolExecution(browser, frame, request.get(),
allow_os_execution);
if (allow_os_execution) {
const GURL& url = GURL(request->GetURL().ToString());
CefBrowserPlatformDelegate::HandleExternalProtocol(url);
}
}
} // namespace
bool IsInternalRequest(const net::URLRequest* request) {
// With PlzNavigate we now receive blob URLs. Ignore these URLs.
// See https://crbug.com/776884 for details.
@ -19,4 +125,134 @@ bool IsInternalRequest(const net::URLRequest* request) {
return false;
}
CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
const net::URLRequest* request,
CefRefPtr<CefRequestImpl>& cef_request,
CefRefPtr<CefBrowser>& cef_browser,
CefRefPtr<CefFrame>& cef_frame) {
CEF_REQUIRE_IOT();
content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
if (!info)
return nullptr;
// Initiator will be non-null for subresource loads.
const bool is_navigation =
ui::PageTransitionIsNewNavigation(info->GetPageTransition()) &&
!request->initiator().has_value();
const bool is_download = info->IsDownload();
const CefString& request_initiator =
SerializeRequestInitiator(request->initiator());
const bool is_custom_scheme =
!scheme::IsInternalHandledScheme(request->url().scheme());
// Not supported by the old network implementation, but keep the value
// consistent with the NetworkService implementation.
bool disable_default_handling = is_custom_scheme;
CefRefPtr<CefResourceRequestHandler> resource_request_handler;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
CefRefPtr<CefFrame> frame;
CefRefPtr<CefRequestImpl> requestPtr;
// Give the browser handler a chance first.
if (browser) {
// A frame should always exist, or be created.
frame = browser->GetFrameForRequest(request);
DCHECK(frame);
CefRefPtr<CefClient> client = browser->GetClient();
if (client) {
CefRefPtr<CefRequestHandler> request_handler =
client->GetRequestHandler();
if (request_handler) {
requestPtr = new CefRequestImpl();
requestPtr->Set(request);
requestPtr->SetReadOnly(true);
resource_request_handler = request_handler->GetResourceRequestHandler(
browser.get(), frame, requestPtr.get(), is_navigation, is_download,
request_initiator, disable_default_handling);
}
}
}
// Give the request context handler a chance.
if (!resource_request_handler) {
CefResourceContext* resource_context =
static_cast<CefResourceContext*>(info->GetContext());
if (!resource_context)
return nullptr;
const int render_process_id = info->GetChildID();
const int render_frame_id = info->GetRenderFrameID();
const int frame_tree_node_id = info->GetFrameTreeNodeId();
CefRefPtr<CefRequestContextHandler> request_context_handler =
resource_context->GetHandler(render_process_id, render_frame_id,
frame_tree_node_id, false);
if (request_context_handler) {
if (!requestPtr) {
requestPtr = new CefRequestImpl();
requestPtr->Set(request);
requestPtr->SetReadOnly(true);
}
resource_request_handler =
request_context_handler->GetResourceRequestHandler(
browser.get(), frame, requestPtr.get(), is_navigation,
is_download, request_initiator, disable_default_handling);
}
}
if (resource_request_handler) {
// Success! Return all the objects that were discovered/created.
cef_request = requestPtr;
cef_browser = browser.get();
cef_frame = frame;
}
return resource_request_handler;
}
void HandleExternalProtocol(
CefRefPtr<CefRequestImpl> request,
const content::ResourceRequestInfo::WebContentsGetter&
web_contents_getter) {
DCHECK(request);
DCHECK(request->IsReadOnly());
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(HandleExternalProtocol, request,
web_contents_getter));
return;
}
content::WebContents* web_contents = web_contents_getter.Run();
if (!web_contents)
return;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForContents(web_contents);
if (!browser)
return;
content::BrowserContext* browser_context = web_contents->GetBrowserContext();
DCHECK(browser_context);
CefResourceContext* resource_context =
static_cast<CefResourceContext*>(browser_context->GetResourceContext());
DCHECK(resource_context);
const int render_process_id =
web_contents->GetRenderViewHost()->GetProcess()->GetID();
CEF_POST_TASK(
CEF_IOT, base::Bind(HandleExternalProtocolOnIOThread,
base::Unretained(resource_context), render_process_id,
browser, browser->GetMainFrame(), request));
}
} // namespace net_util

View File

@ -6,16 +6,39 @@
#define CEF_LIBCEF_BROWSER_NET_NET_UTIL_H_
#pragma once
#include "include/cef_resource_request_handler.h"
#include "libcef/common/request_impl.h"
#include "content/public/browser/resource_request_info.h"
namespace net {
class URLRequest;
}
class GURL;
namespace net_util {
// Returns true if |request| is handled internally and should not be exposed via
// the CEF API.
bool IsInternalRequest(const net::URLRequest* request);
// Returns the appropriate CefResourceRequestHandler as determined by the
// associated CefBrowser/CefRequestHandler and/or CefRequestContextHandler, if
// any. The out-params will be nullptr if no handler is returned. Otherwise,
// the |cef_request| parameter will be set based on the contents of |request|
// (read-only by default), and the |cef_browser| and |cef_frame| parameters
// will be set if the request is associated with a browser.
CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
const net::URLRequest* request,
CefRefPtr<CefRequestImpl>& cef_request,
CefRefPtr<CefBrowser>& cef_browser,
CefRefPtr<CefFrame>& cef_frame);
void HandleExternalProtocol(
CefRefPtr<CefRequestImpl> request,
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter);
} // namespace net_util
#endif // CEF_LIBCEF_BROWSER_NET_NET_UTIL_H_

View File

@ -14,6 +14,7 @@
#include "libcef/browser/net/source_stream.h"
#include "libcef/browser/net/url_request_user_data.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net_service/net_service_util.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/response_impl.h"
@ -251,34 +252,24 @@ std::unique_ptr<net::SourceStream> CefNetworkDelegate::CreateSourceStream(
if (net_util::IsInternalRequest(request))
return upstream;
CefRefPtr<CefResponseFilter> cef_filter;
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
if (handler) {
CefRefPtr<CefResponseImpl> responsePtr = new CefResponseImpl();
responsePtr->Set(request);
responsePtr->SetReadOnly(true);
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
CefRefPtr<CefRequestImpl> cefRequest = new CefRequestImpl();
cefRequest->Set(request);
cefRequest->SetReadOnly(true);
CefRefPtr<CefResponseImpl> cefResponse = new CefResponseImpl();
cefResponse->Set(request);
cefResponse->SetReadOnly(true);
cef_filter = handler->GetResourceResponseFilter(
browser.get(), frame, cefRequest.get(), cefResponse.get());
}
CefRefPtr<CefResponseFilter> cef_filter =
handler->GetResourceResponseFilter(browser, frame, requestPtr.get(),
responsePtr.get());
if (cef_filter && cef_filter->InitFilter()) {
return std::make_unique<CefSourceStream>(cef_filter, std::move(upstream));
}
}
if (cef_filter && cef_filter->InitFilter())
return std::make_unique<CefSourceStream>(cef_filter, std::move(upstream));
return upstream;
}
@ -291,48 +282,51 @@ int CefNetworkDelegate::OnBeforeURLRequest(net::URLRequest* request,
const bool force_google_safesearch =
(force_google_safesearch_ && force_google_safesearch_->GetValue());
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (browser.get()) {
const CefBrowserSettings& browser_settings = browser->settings();
if (browser_settings.accept_language_list.length > 0) {
const std::string& accept_language =
net::HttpUtil::GenerateAcceptLanguageHeader(
CefString(&browser_settings.accept_language_list));
request->SetExtraRequestHeaderByName(
net::HttpRequestHeaders::kAcceptLanguage, accept_language, false);
}
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
// Populate the request data.
CefRefPtr<CefRequestImpl> requestPtr(new CefRequestImpl());
requestPtr->Set(request);
requestPtr->SetTrackChanges(true);
if (handler) {
// The following callback allows modification of the request object.
requestPtr->SetReadOnly(false);
CefRefPtr<CefBeforeResourceLoadCallbackImpl> callbackImpl(
new CefBeforeResourceLoadCallbackImpl(requestPtr, new_url, request,
force_google_safesearch,
std::move(callback)));
// Give the client an opportunity to evaluate the request.
cef_return_value_t retval = handler->OnBeforeResourceLoad(
browser.get(), frame, requestPtr.get(), callbackImpl.get());
if (retval == RV_CANCEL) {
// Cancel the request.
callbackImpl->Continue(false);
} else if (retval == RV_CONTINUE) {
// Continue the request.
callbackImpl->Continue(true);
}
// Continue or cancel the request asynchronously.
return net::ERR_IO_PENDING;
CefBrowserHostImpl* browser_impl =
static_cast<CefBrowserHostImpl*>(browser.get());
if (browser_impl) {
const CefBrowserSettings& browser_settings = browser_impl->settings();
if (browser_settings.accept_language_list.length > 0) {
const std::string& accept_language =
net::HttpUtil::GenerateAcceptLanguageHeader(
CefString(&browser_settings.accept_language_list));
request->SetExtraRequestHeaderByName(
net::HttpRequestHeaders::kAcceptLanguage, accept_language, false);
requestPtr->SetHeaderByName(net::HttpRequestHeaders::kAcceptLanguage,
accept_language, false);
}
}
requestPtr->SetTrackChanges(true);
CefRefPtr<CefBeforeResourceLoadCallbackImpl> callbackImpl(
new CefBeforeResourceLoadCallbackImpl(requestPtr, new_url, request,
force_google_safesearch,
std::move(callback)));
// Give the client an opportunity to evaluate the request.
cef_return_value_t retval = handler->OnBeforeResourceLoad(
browser, frame, requestPtr.get(), callbackImpl.get());
if (retval == RV_CANCEL) {
// Cancel the request.
callbackImpl->Continue(false);
} else if (retval == RV_CONTINUE) {
// Continue the request.
callbackImpl->Continue(true);
}
// Continue or cancel the request asynchronously.
return net::ERR_IO_PENDING;
}
if (force_google_safesearch && new_url->is_empty())
@ -351,47 +345,39 @@ void CefNetworkDelegate::OnCompleted(net::URLRequest* request,
if (!started)
return;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
if (!handler)
return;
CefRefPtr<CefRequestImpl> cefRequest = new CefRequestImpl();
cefRequest->Set(request);
cefRequest->SetReadOnly(true);
CefRefPtr<CefResponseImpl> responsePtr = new CefResponseImpl();
responsePtr->Set(request);
responsePtr->SetReadOnly(true);
CefRefPtr<CefResponseImpl> cefResponse = new CefResponseImpl();
cefResponse->Set(request);
cefResponse->SetReadOnly(true);
cef_urlrequest_status_t status = UR_UNKNOWN;
switch (request->status().status()) {
case net::URLRequestStatus::SUCCESS:
status = UR_SUCCESS;
break;
case net::URLRequestStatus::CANCELED:
status = UR_CANCELED;
break;
case net::URLRequestStatus::FAILED:
status = UR_FAILED;
break;
default:
NOTREACHED();
break;
}
const int64 received_content_length =
request->received_response_content_length();
handler->OnResourceLoadComplete(browser.get(), frame, cefRequest.get(),
cefResponse.get(), status,
received_content_length);
}
}
cef_urlrequest_status_t status = UR_UNKNOWN;
switch (request->status().status()) {
case net::URLRequestStatus::SUCCESS:
status = UR_SUCCESS;
break;
case net::URLRequestStatus::CANCELED:
status = UR_CANCELED;
break;
case net::URLRequestStatus::FAILED:
status = UR_FAILED;
break;
default:
NOTREACHED();
break;
}
const int64 received_content_length =
request->received_response_content_length();
handler->OnResourceLoadComplete(browser, frame, requestPtr.get(),
responsePtr.get(), status,
received_content_length);
}
net::NetworkDelegate::AuthRequiredResponse CefNetworkDelegate::OnAuthRequired(
@ -460,25 +446,27 @@ bool CefNetworkDelegate::OnCanGetCookies(const net::URLRequest& request,
if (net_util::IsInternalRequest(&request))
return true;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(&request);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(&request);
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(&request, requestPtr, browser, frame);
if (!handler)
return true;
CefRefPtr<CefRequestImpl> cefRequest = new CefRequestImpl();
cefRequest->Set(&request);
cefRequest->SetReadOnly(true);
bool cookie_blocked = false;
return handler->CanGetCookies(browser.get(), frame, cefRequest.get());
}
for (const auto& cookie : cookie_list) {
CefCookie cef_cookie;
if (!net_service::MakeCefCookie(cookie, cef_cookie))
continue;
if (!handler->CanSendCookie(browser, frame, requestPtr.get(), cef_cookie)) {
if (!cookie_blocked)
cookie_blocked = true;
}
}
return true;
return !cookie_blocked;
}
bool CefNetworkDelegate::OnCanSetCookie(const net::URLRequest& request,
@ -490,30 +478,24 @@ bool CefNetworkDelegate::OnCanSetCookie(const net::URLRequest& request,
if (net_util::IsInternalRequest(&request))
return true;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(&request);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(&request);
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(&request, requestPtr, browser, frame);
if (!handler)
return true;
CefRefPtr<CefRequestImpl> cefRequest = new CefRequestImpl();
cefRequest->Set(&request);
cefRequest->SetReadOnly(true);
CefCookie cef_cookie;
if (!net_service::MakeCefCookie(cookie, cef_cookie))
return true;
CefCookie cefCookie;
if (!CefCookieManagerOldImpl::GetCefCookie(cookie, cefCookie))
return true;
CefRefPtr<CefResponseImpl> responsePtr = new CefResponseImpl();
responsePtr->Set(&request);
responsePtr->SetReadOnly(true);
return handler->CanSetCookie(browser.get(), frame, cefRequest.get(),
cefCookie);
}
}
}
return true;
return handler->CanSaveCookie(browser, frame, requestPtr.get(),
responsePtr.get(), cef_cookie);
}
bool CefNetworkDelegate::OnCanAccessFile(

View File

@ -12,6 +12,7 @@
#include "include/cef_parser.h"
#include "libcef/browser/net/cookie_manager_old_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net_service/net_service_util.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/response_impl.h"
@ -337,8 +338,7 @@ bool CefResourceRequestJob::IsRedirectResponse(
// Set the correct response status. This avoids a DCHECK in
// RedirectInfo::ComputeRedirectInfo.
request_->response_headers()->ReplaceStatusLine(
*http_status_code == 302 ? "HTTP/1.1 302 Found"
: "HTTP/1.1 303 See Other");
net_service::MakeStatusLine(*http_status_code, std::string(), true));
}
return redirect;
@ -452,19 +452,8 @@ void CefResourceRequestJob::DoLoadCookies() {
void CefResourceRequestJob::CheckCookiePolicyAndLoad(
const net::CookieList& cookie_list,
const net::CookieStatusList& excluded_list) {
bool can_get_cookies = !cookie_list.empty() && CanGetCookies(cookie_list);
if (can_get_cookies) {
net::CookieList::const_iterator it = cookie_list.begin();
for (; it != cookie_list.end(); ++it) {
CefCookie cookie;
if (!CefCookieManagerOldImpl::GetCefCookie(*it, cookie) ||
!handler_->CanGetCookie(cookie)) {
can_get_cookies = false;
break;
}
}
}
const bool can_get_cookies =
!cookie_list.empty() && CanGetCookies(cookie_list);
if (can_get_cookies)
DoLoadCookies();
else
@ -553,17 +542,7 @@ void CefResourceRequestJob::SaveNextCookie() {
std::unique_ptr<net::CanonicalCookie> cookie = net::CanonicalCookie::Create(
request_->url(), cookie_line, base::Time::Now(), options);
bool can_set_cookie = cookie && CanSetCookie(*cookie, &options);
if (can_set_cookie) {
CefCookie cef_cookie;
if (CefCookieManagerOldImpl::GetCefCookie(request_->url(), cookie_line,
cef_cookie)) {
can_set_cookie = handler_->CanSetCookie(cef_cookie);
} else {
can_set_cookie = false;
}
}
const bool can_set_cookie = cookie && CanSetCookie(*cookie, &options);
if (can_set_cookie) {
request_->context()->cookie_store()->SetCanonicalCookieAsync(
std::move(cookie), request_->url().scheme(), options,

View File

@ -33,27 +33,18 @@ net::URLRequestJob* CefRequestInterceptor::MaybeInterceptRequest(
if (net_util::IsInternalRequest(request))
return nullptr;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
// Populate the request data.
CefRefPtr<CefRequest> req(CefRequest::Create());
static_cast<CefRequestImpl*>(req.get())->Set(request);
// Give the client an opportunity to replace the request.
CefRefPtr<CefResourceHandler> resourceHandler =
handler->GetResourceHandler(browser.get(), frame, req);
if (resourceHandler.get()) {
return new CefResourceRequestJob(request, network_delegate,
resourceHandler);
}
}
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
if (handler) {
// Give the client an opportunity to replace the request.
CefRefPtr<CefResourceHandler> resourceHandler =
handler->GetResourceHandler(browser, frame, requestPtr.get());
if (resourceHandler) {
return new CefResourceRequestJob(request, network_delegate,
resourceHandler);
}
}
@ -67,36 +58,27 @@ net::URLRequestJob* CefRequestInterceptor::MaybeInterceptRedirect(
if (net_util::IsInternalRequest(request))
return nullptr;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
if (handler) {
CefRefPtr<CefResponseImpl> responsePtr = new CefResponseImpl();
responsePtr->Set(request);
responsePtr->SetReadOnly(true);
CefRefPtr<CefRequest> cefRequest = new CefRequestImpl();
static_cast<CefRequestImpl*>(cefRequest.get())->Set(request);
static_cast<CefRequestImpl*>(cefRequest.get())->SetReadOnly(true);
CefRefPtr<CefResponse> cefResponse = new CefResponseImpl();
static_cast<CefResponseImpl*>(cefResponse.get())->Set(request);
static_cast<CefResponseImpl*>(cefResponse.get())->SetReadOnly(true);
// Give the client an opportunity to redirect the request.
CefString newUrlStr = location.spec();
handler->OnResourceRedirect(browser.get(), frame, cefRequest,
cefResponse, newUrlStr);
if (newUrlStr != location.spec()) {
const GURL new_url = GURL(newUrlStr.ToString());
if (!new_url.is_empty() && new_url.is_valid()) {
return new net::URLRequestRedirectJob(
request, network_delegate, new_url,
net::URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT,
"Resource Redirect");
}
}
// Give the client an opportunity to redirect the request.
CefString newUrlStr = location.spec();
handler->OnResourceRedirect(browser, frame, requestPtr.get(),
responsePtr.get(), newUrlStr);
if (newUrlStr != location.spec()) {
const GURL new_url = GURL(newUrlStr.ToString());
if (!new_url.is_empty() && new_url.is_valid()) {
return new net::URLRequestRedirectJob(
request, network_delegate, new_url,
net::URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT,
"Resource Redirect");
}
}
}
@ -110,32 +92,27 @@ net::URLRequestJob* CefRequestInterceptor::MaybeInterceptResponse(
if (net_util::IsInternalRequest(request))
return nullptr;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (!browser.get())
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefBrowser> browser;
CefRefPtr<CefFrame> frame;
CefRefPtr<CefResourceRequestHandler> handler =
net_util::GetResourceRequestHandler(request, requestPtr, browser, frame);
if (!handler)
return nullptr;
CefRefPtr<CefClient> client = browser->GetClient();
if (!client.get())
return nullptr;
// The below callback allows modification of the request object.
requestPtr->SetReadOnly(false);
requestPtr->SetTrackChanges(true);
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (!handler.get())
return nullptr;
CefRefPtr<CefResponseImpl> responsePtr = new CefResponseImpl();
responsePtr->Set(request);
responsePtr->SetReadOnly(true);
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
CefRefPtr<CefRequestImpl> cefRequest = new CefRequestImpl();
cefRequest->Set(request);
cefRequest->SetTrackChanges(true);
CefRefPtr<CefResponseImpl> cefResponse = new CefResponseImpl();
cefResponse->Set(request);
cefResponse->SetReadOnly(true);
const GURL old_url = request->url();
// Give the client an opportunity to retry or redirect the request.
if (!handler->OnResourceResponse(browser.get(), frame, cefRequest.get(),
cefResponse.get())) {
if (!handler->OnResourceResponse(browser, frame, requestPtr.get(),
responsePtr.get())) {
return nullptr;
}
@ -146,16 +123,17 @@ net::URLRequestJob* CefRequestInterceptor::MaybeInterceptResponse(
// Update the URLRequest with only the values that have been changed by the
// client.
cefRequest->Get(request, true);
requestPtr->Get(request, true);
// If the URL was changed then redirect the request.
if (!!(cefRequest->GetChanges() & CefRequestImpl::kChangedUrl)) {
const GURL url(cefRequest->GetURL().ToString());
DCHECK_NE(url, request->url());
return new net::URLRequestRedirectJob(
request, network_delegate, url,
net::URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT,
"Resource Redirect");
if (!!(requestPtr->GetChanges() & CefRequestImpl::kChangedUrl)) {
const GURL new_url = old_url.Resolve(requestPtr->GetURL().ToString());
if (new_url != old_url) {
return new net::URLRequestRedirectJob(
request, network_delegate, new_url,
net::URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT,
"Resource Redirect");
}
}
// Otherwise queue a new job.

View File

@ -32,11 +32,6 @@ using net::URLRequestStatus;
namespace {
bool IsStandardScheme(const std::string& scheme) {
url::Component scheme_comp(0, scheme.length());
return url::IsStandard(scheme.c_str(), scheme_comp);
}
// Copied from net/url_request/url_request_job_manager.cc.
struct SchemeToFactory {
const char* scheme;
@ -127,7 +122,7 @@ bool CefURLRequestManager::AddFactory(
std::string domain_lower = ToLower(domain);
// Hostname is only supported for standard schemes.
if (!IsStandardScheme(scheme_lower))
if (!scheme::IsStandardScheme(scheme_lower))
domain_lower.clear();
SetProtocolHandlerIfNecessary(scheme_lower, true);
@ -145,7 +140,7 @@ void CefURLRequestManager::RemoveFactory(const std::string& scheme,
std::string domain_lower = ToLower(domain);
// Hostname is only supported for standard schemes.
if (!IsStandardScheme(scheme_lower))
if (!scheme::IsStandardScheme(scheme_lower))
domain_lower.clear();
HandlerMap::iterator iter =
@ -223,7 +218,7 @@ CefRefPtr<CefSchemeHandlerFactory> CefURLRequestManager::GetHandlerFactory(
const std::string& scheme) {
CefRefPtr<CefSchemeHandlerFactory> factory;
if (request->url().is_valid() && IsStandardScheme(scheme)) {
if (request->url().is_valid() && scheme::IsStandardScheme(scheme)) {
// Check for a match with a domain first.
const std::string& domain = request->url().host();

View File

@ -0,0 +1,227 @@
// 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/cookie_helper.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net_service/net_service_util.h"
#include "base/bind.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
#include "net/base/load_flags.h"
#include "net/cookies/cookie_options.h"
#include "net/cookies/cookie_util.h"
#include "services/network/cookie_manager.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/resource_response.h"
namespace net_service {
namespace {
// Do not keep a reference to the CookieManager returned by this method.
network::mojom::CookieManager* GetCookieManager(
content::BrowserContext* browser_context) {
CEF_REQUIRE_UIT();
return content::BrowserContext::GetDefaultStoragePartition(browser_context)
->GetCookieManagerForBrowserProcess();
}
//
// LOADING COOKIES.
//
void ContinueWithLoadedCookies(const AllowCookieCallback& allow_cookie_callback,
DoneCookieCallback done_callback,
const net::CookieList& cookies) {
CEF_REQUIRE_IOT();
net::CookieList allowed_cookies;
for (const auto& cookie : cookies) {
bool allow = false;
allow_cookie_callback.Run(cookie, &allow);
if (allow)
allowed_cookies.push_back(cookie);
}
std::move(done_callback).Run(cookies.size(), std::move(allowed_cookies));
}
void GetCookieListCallback(const AllowCookieCallback& allow_cookie_callback,
DoneCookieCallback done_callback,
const net::CookieList& cookies) {
CEF_REQUIRE_UIT();
CEF_POST_TASK(CEF_IOT,
base::BindOnce(ContinueWithLoadedCookies, allow_cookie_callback,
std::move(done_callback), cookies));
}
void LoadCookiesOnUIThread(content::BrowserContext* browser_context,
const GURL& url,
const net::CookieOptions& options,
const AllowCookieCallback& allow_cookie_callback,
DoneCookieCallback done_callback) {
CEF_REQUIRE_UIT();
GetCookieManager(browser_context)
->GetCookieList(
url, options,
base::BindOnce(GetCookieListCallback, allow_cookie_callback,
std::move(done_callback)));
}
//
// SAVING COOKIES.
//
struct SaveCookiesProgress {
DoneCookieCallback done_callback_;
int total_count_;
net::CookieList allowed_cookies_;
int num_cookie_lines_left_;
};
void SetCanonicalCookieCallback(SaveCookiesProgress* progress,
const net::CanonicalCookie& cookie,
bool success) {
CEF_REQUIRE_UIT();
progress->num_cookie_lines_left_--;
if (success)
progress->allowed_cookies_.push_back(cookie);
// If all the cookie lines have been handled the request can be continued.
if (progress->num_cookie_lines_left_ == 0) {
CEF_POST_TASK(CEF_IOT,
base::BindOnce(std::move(progress->done_callback_),
progress->total_count_,
std::move(progress->allowed_cookies_)));
delete progress;
}
}
void SaveCookiesOnUIThread(content::BrowserContext* browser_context,
const GURL& url,
const net::CookieOptions& options,
int total_count,
net::CookieList cookies,
DoneCookieCallback done_callback) {
CEF_REQUIRE_UIT();
DCHECK(!cookies.empty());
network::mojom::CookieManager* cookie_manager =
GetCookieManager(browser_context);
// |done_callback| needs to be executed once and only once after the list has
// been fully processed. |num_cookie_lines_left_| keeps track of how many
// async callbacks are currently pending.
auto progress = new SaveCookiesProgress;
progress->done_callback_ = std::move(done_callback);
progress->total_count_ = total_count;
// Make sure to wait for the loop to complete.
progress->num_cookie_lines_left_ = 1;
for (const auto& cookie : cookies) {
progress->num_cookie_lines_left_++;
cookie_manager->SetCanonicalCookie(
cookie, url.scheme(), options,
base::BindOnce(&SetCanonicalCookieCallback, base::Unretained(progress),
cookie));
}
SetCanonicalCookieCallback(progress, net::CanonicalCookie(), false);
}
} // namespace
void LoadCookies(content::BrowserContext* browser_context,
const network::ResourceRequest& request,
const AllowCookieCallback& allow_cookie_callback,
DoneCookieCallback done_callback) {
CEF_REQUIRE_IOT();
if ((request.load_flags & net::LOAD_DO_NOT_SEND_COOKIES) ||
!request.allow_credentials) {
// Continue immediately without loading cookies.
std::move(done_callback).Run(0, {});
return;
}
// Match the logic in URLRequestHttpJob::AddCookieHeaderAndStart.
net::CookieOptions options;
options.set_include_httponly();
options.set_same_site_cookie_context(
net::cookie_util::ComputeSameSiteContextForRequest(
request.method, request.url, request.site_for_cookies,
request.request_initiator, request.attach_same_site_cookies));
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(LoadCookiesOnUIThread, browser_context, request.url,
options, allow_cookie_callback, std::move(done_callback)));
}
void SaveCookies(content::BrowserContext* browser_context,
const network::ResourceRequest& request,
const network::ResourceResponseHead& head,
const AllowCookieCallback& allow_cookie_callback,
DoneCookieCallback done_callback) {
CEF_REQUIRE_IOT();
if (!request.allow_credentials ||
!head.headers->HasHeader(net_service::kHTTPSetCookieHeaderName)) {
// Continue immediately without saving cookies.
std::move(done_callback).Run(0, {});
return;
}
// Match the logic in
// URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete.
base::Time response_date;
if (!head.headers->GetDateValue(&response_date))
response_date = base::Time();
net::CookieOptions options;
options.set_include_httponly();
options.set_server_time(response_date);
options.set_same_site_cookie_context(
net::cookie_util::ComputeSameSiteContextForRequest(
request.method, request.url, request.site_for_cookies,
request.request_initiator, request.attach_same_site_cookies));
const base::StringPiece name(net_service::kHTTPSetCookieHeaderName);
std::string cookie_string;
size_t iter = 0;
net::CookieList allowed_cookies;
int total_count = 0;
while (head.headers->EnumerateHeader(&iter, name, &cookie_string)) {
total_count++;
net::CanonicalCookie::CookieInclusionStatus returned_status;
std::unique_ptr<net::CanonicalCookie> cookie = net::CanonicalCookie::Create(
request.url, cookie_string, base::Time::Now(), options,
&returned_status);
if (returned_status !=
net::CanonicalCookie::CookieInclusionStatus::INCLUDE) {
continue;
}
bool allow = false;
allow_cookie_callback.Run(*cookie, &allow);
if (allow)
allowed_cookies.push_back(*cookie);
}
if (!allowed_cookies.empty()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(SaveCookiesOnUIThread, browser_context, request.url,
options, total_count, std::move(allowed_cookies),
std::move(done_callback)));
} else {
std::move(done_callback).Run(total_count, std::move(allowed_cookies));
}
}
} // namespace net_service

View File

@ -0,0 +1,54 @@
// 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_COOKIE_HELPER_H_
#define CEF_LIBCEF_BROWSER_NET_SERVICE_COOKIE_HELPER_H_
#include "base/callback_forward.h"
#include "net/cookies/canonical_cookie.h"
namespace content {
class BrowserContext;
}
namespace network {
struct ResourceRequest;
struct ResourceResponseHead;
} // namespace network
namespace net_service {
using AllowCookieCallback =
base::Callback<void(const net::CanonicalCookie&, bool* /* allow */)>;
using DoneCookieCallback =
base::OnceCallback<void(int /* total_count */,
net::CookieList /* allowed_cookies */)>;
// Load cookies for |request|. |allow_cookie_callback| will be executed for each
// cookie and should return true to allow it. |done_callback| will be executed
// on completion with |total_count| representing the total number of cookies
// retrieved, and |allowed_cookies| representing the list of cookies that were
// both retrieved and allowed by |allow_cookie_callback|. The loaded cookies
// will not be set on |request|; that should be done in |done_callback|. Must be
// called on the IO thread.
void LoadCookies(content::BrowserContext* browser_context,
const network::ResourceRequest& request,
const AllowCookieCallback& allow_cookie_callback,
DoneCookieCallback done_callback);
// Save cookies from |head|. |allow_cookie_callback| will be executed for each
// cookie and should return true to allow it. |done_callback| will be executed
// on completion with |total_count| representing the total number of cookies
// retrieved, and |allowed_cookies| representing the list of cookies that were
// both allowed by |allow_cookie_callback| an successfully saved. Must be called
// on the IO thread.
void SaveCookies(content::BrowserContext* browser_context,
const network::ResourceRequest& request,
const network::ResourceResponseHead& head,
const AllowCookieCallback& allow_cookie_callback,
DoneCookieCallback done_callback);
} // namespace net_service
#endif // CEF_LIBCEF_BROWSER_NET_SERVICE_COOKIE_HELPER_H_

View File

@ -4,6 +4,7 @@
#include "libcef/browser/net_service/cookie_manager_impl.h"
#include "libcef/common/net_service/net_service_util.h"
#include "libcef/common/time_util.h"
#include "base/bind.h"
@ -50,20 +51,6 @@ void DeleteCookiesCallbackImpl(CefRefPtr<CefDeleteCookiesCallback> callback,
callback.get(), num_deleted));
}
void GetCefCookie(const net::CanonicalCookie& cc, CefCookie& cookie) {
CefString(&cookie.name).FromString(cc.Name());
CefString(&cookie.value).FromString(cc.Value());
CefString(&cookie.domain).FromString(cc.Domain());
CefString(&cookie.path).FromString(cc.Path());
cookie.secure = cc.IsSecure();
cookie.httponly = cc.IsHttpOnly();
cef_time_from_basetime(cc.CreationDate(), cookie.creation);
cef_time_from_basetime(cc.LastAccessDate(), cookie.last_access);
cookie.has_expires = cc.IsPersistent();
if (cookie.has_expires)
cef_time_from_basetime(cc.ExpiryDate(), cookie.expires);
}
void ExecuteVisitor(CefRefPtr<CefCookieVisitor> visitor,
CefRefPtr<CefRequestContextImpl> request_context,
const std::vector<net::CanonicalCookie>& cookies) {
@ -74,7 +61,7 @@ void ExecuteVisitor(CefRefPtr<CefCookieVisitor> visitor,
int total = cookies.size(), count = 0;
for (const auto& cc : cookies) {
CefCookie cookie;
GetCefCookie(cc, cookie);
net_service::MakeCefCookie(cc, cookie);
bool deleteCookie = false;
bool keepLooping = visitor->Visit(cookie, count, total, deleteCookie);
@ -119,9 +106,20 @@ void CefCookieManagerImpl::SetSupportedSchemes(
return;
}
// TODO(network): Figure out how to route this to
// CookieMonster::SetCookieableSchemes via the NetworkService.
NOTIMPLEMENTED();
std::vector<std::string> all_schemes;
for (const auto& scheme : schemes)
all_schemes.push_back(scheme);
// This list should match CookieMonster::kDefaultCookieableSchemes.
all_schemes.push_back("http");
all_schemes.push_back("https");
all_schemes.push_back("ws");
all_schemes.push_back("wss");
// This will be forwarded to the CookieMonster that lives in the
// NetworkService process when the NetworkContext is created via
// CefContentBrowserClient::CreateNetworkContext.
request_context_->GetBrowserContext()->set_cookieable_schemes(all_schemes);
RunAsyncCompletionOnUIThread(callback);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,203 @@
// Copyright (c) 2019 The Chromium Embedded Framework Authors. Portions
// Copyright (c) 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_BROWSER_NET_SERVICE_PROXY_URL_LOADER_FACTORY_H_
#define CEF_LIBCEF_BROWSER_NET_SERVICE_PROXY_URL_LOADER_FACTORY_H_
#include "libcef/browser/net_service/stream_reader_url_loader.h"
#include "base/callback.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/hash.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/resource_request_info.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace net_service {
class InterceptedRequest;
class ResourceContextData;
// Implement this interface to to evaluate requests. All methods are called on
// the IO thread.
class InterceptedRequestHandler {
public:
InterceptedRequestHandler();
virtual ~InterceptedRequestHandler();
// Optionally modify |request| and return true to proceed. Set
// |intercept_request| to false if the request will not be intercepted.
// Set |intercept_only| to true if the loader should not proceed unless
// the request is intercepted. Return false to abort the request with
// net::ERR_ACCESS_DENIED.
using OnBeforeRequestResultCallback =
base::OnceCallback<void(bool /* intercept_request */,
bool /* intercept_only */)>;
virtual void OnBeforeRequest(const RequestId& id,
network::ResourceRequest* request,
bool request_was_redirected,
OnBeforeRequestResultCallback callback);
// Optionally modify |request| and execute |callback| on the IO thread after
// determining if the request hould be intercepted.
using ShouldInterceptRequestResultCallback =
base::OnceCallback<void(std::unique_ptr<ResourceResponse>,
bool /* cancel_request */)>;
virtual void ShouldInterceptRequest(
const RequestId& id,
network::ResourceRequest* request,
ShouldInterceptRequestResultCallback callback);
// Called to evaluate and optionally modify request headers. |request| is the
// current request information. |redirect_url| will be non-empty if this
// method is called in response to a redirect. The |modified_headers| and
// |removed_headers| may be modified. If non-empty the |modified_headers|
// values will be merged first, and then any |removed_headers| values will be
// removed. This comparison is case sensitive.
virtual void ProcessRequestHeaders(
const RequestId& id,
const network::ResourceRequest& request,
const GURL& redirect_url,
net::HttpRequestHeaders* modified_headers,
std::vector<std::string>* removed_headers) {}
// Called to evaluate and optionally modify response headers. |request| is the
// current request information. |redirect_url| will be non-empty if this
// method is called in response to a redirect. Even though |head| is const the
// |head.headers| value is non-const and any changes will be passed to the
// client.
virtual void ProcessResponseHeaders(
const RequestId& id,
const network::ResourceRequest& request,
const GURL& redirect_url,
const network::ResourceResponseHead& head) {}
enum class ResponseMode {
// Continue the request.
CONTINUE,
// Restart the request.
RESTART,
// Cancel the request.
CANCEL
};
// Called on response. |request| is the current request information.
// |redirect_info| will be non-empty for redirect responses.
// Optionally modify |request| and execute the callback as appropriate.
using OnRequestResponseResultCallback = base::OnceCallback<void(
ResponseMode /* response_mode */,
scoped_refptr<net::HttpResponseHeaders> /* override_headers */,
const GURL& /* redirect_url */)>;
virtual void OnRequestResponse(
const RequestId& id,
network::ResourceRequest* request,
const network::ResourceResponseHead& head,
base::Optional<net::RedirectInfo> redirect_info,
OnRequestResponseResultCallback callback);
// Called on completion notification from the loader (successful or not).
virtual void OnRequestComplete(
const RequestId& id,
const network::ResourceRequest& request,
const network::URLLoaderCompletionStatus& status) {}
// Called on error.
virtual void OnRequestError(const RequestId& id,
const network::ResourceRequest& request,
int error_code,
bool safebrowsing_hit) {}
private:
DISALLOW_COPY_AND_ASSIGN(InterceptedRequestHandler);
};
// URL Loader Factory that supports request/response interception, processing
// and callback invocation.
// Based on android_webview/browser/network_service/
// aw_proxying_url_loader_factory.cc
class ProxyURLLoaderFactory
: public network::mojom::URLLoaderFactory,
public network::mojom::TrustedURLLoaderHeaderClient {
public:
~ProxyURLLoaderFactory() override;
// Create a proxy object on the UI thread.
static void CreateProxy(
content::BrowserContext* browser_context,
network::mojom::URLLoaderFactoryRequest* factory_request,
network::mojom::TrustedURLLoaderHeaderClientPtrInfo* header_client,
std::unique_ptr<InterceptedRequestHandler> request_handler);
// Create a proxy object on the IO thread.
static ProxyURLLoaderFactory* CreateProxy(
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
network::mojom::URLLoaderFactoryRequest* factory_request,
std::unique_ptr<InterceptedRequestHandler> request_handler);
// mojom::URLLoaderFactory methods:
void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader,
int32_t routing_id,
int32_t request_id,
uint32_t options,
const network::ResourceRequest& request,
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag&
traffic_annotation) override;
void Clone(network::mojom::URLLoaderFactoryRequest loader_request) override;
// network::mojom::TrustedURLLoaderHeaderClient:
void OnLoaderCreated(
int32_t request_id,
network::mojom::TrustedHeaderClientRequest request) override;
private:
friend class InterceptedRequest;
friend class ResourceContextData;
ProxyURLLoaderFactory(
network::mojom::URLLoaderFactoryRequest loader_request,
network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
network::mojom::TrustedURLLoaderHeaderClientRequest header_client_request,
std::unique_ptr<InterceptedRequestHandler> request_handler);
static void CreateOnIOThread(
network::mojom::URLLoaderFactoryRequest loader_request,
network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
network::mojom::TrustedURLLoaderHeaderClientRequest header_client_request,
content::ResourceContext* resource_context,
std::unique_ptr<InterceptedRequestHandler> request_handler);
using DisconnectCallback = base::OnceCallback<void(ProxyURLLoaderFactory*)>;
void SetDisconnectCallback(DisconnectCallback on_disconnect);
void OnTargetFactoryError();
void OnProxyBindingError();
void RemoveRequest(InterceptedRequest* request);
void MaybeDestroySelf();
mojo::BindingSet<network::mojom::URLLoaderFactory> proxy_bindings_;
network::mojom::URLLoaderFactoryPtr target_factory_;
mojo::Binding<network::mojom::TrustedURLLoaderHeaderClient>
url_loader_header_client_binding_;
std::unique_ptr<InterceptedRequestHandler> request_handler_;
DisconnectCallback on_disconnect_;
// Map of request ID to request object.
std::map<int32_t, std::unique_ptr<InterceptedRequest>> requests_;
base::WeakPtrFactory<ProxyURLLoaderFactory> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ProxyURLLoaderFactory);
};
} // namespace net_service
#endif // CEF_LIBCEF_BROWSER_NET_SERVICE_PROXY_URL_LOADER_FACTORY_H_

View File

@ -0,0 +1,406 @@
// 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/resource_handler_wrapper.h"
#include "libcef/browser/net_service/proxy_url_loader_factory.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net_service/net_service_util.h"
#include "libcef/common/request_impl.h"
#include "base/strings/string_number_conversions.h"
#include "net/http/http_status_code.h"
namespace net_service {
namespace {
class SkipCallbackWrapper : public CefResourceSkipCallback {
public:
explicit SkipCallbackWrapper(InputStream::SkipCallback callback)
: callback_(std::move(callback)),
work_thread_task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
~SkipCallbackWrapper() override {
if (!callback_.is_null()) {
std::move(callback_).Run(net::ERR_FAILED);
}
}
void Continue(int64 bytes_skipped) override {
if (!work_thread_task_runner_->RunsTasksInCurrentSequence()) {
work_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&SkipCallbackWrapper::Continue, this, bytes_skipped));
return;
}
if (!callback_.is_null()) {
std::move(callback_).Run(bytes_skipped);
}
}
void Disconnect() { callback_.Reset(); }
private:
InputStream::SkipCallback callback_;
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner_;
IMPLEMENT_REFCOUNTING(SkipCallbackWrapper);
DISALLOW_COPY_AND_ASSIGN(SkipCallbackWrapper);
};
class ReadCallbackWrapper : public CefResourceReadCallback {
public:
explicit ReadCallbackWrapper(InputStream::ReadCallback callback)
: callback_(std::move(callback)),
work_thread_task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
~ReadCallbackWrapper() override {
if (!callback_.is_null()) {
std::move(callback_).Run(net::ERR_FAILED);
}
}
void Continue(int bytes_read) override {
if (!work_thread_task_runner_->RunsTasksInCurrentSequence()) {
work_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&ReadCallbackWrapper::Continue, this, bytes_read));
return;
}
if (!callback_.is_null()) {
std::move(callback_).Run(bytes_read);
}
}
void Disconnect() { callback_.Reset(); }
private:
InputStream::ReadCallback callback_;
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner_;
IMPLEMENT_REFCOUNTING(ReadCallbackWrapper);
DISALLOW_COPY_AND_ASSIGN(ReadCallbackWrapper);
};
class ReadResponseCallbackWrapper : public CefCallback {
public:
~ReadResponseCallbackWrapper() override {
if (callback_) {
callback_->Continue(net::ERR_FAILED);
}
}
void Continue() override {
CEF_POST_TASK(CEF_IOT,
base::Bind(&ReadResponseCallbackWrapper::DoRead, this));
}
void Cancel() override {
CEF_POST_TASK(CEF_IOT,
base::Bind(&ReadResponseCallbackWrapper::DoCancel, this));
}
static void ReadResponse(CefRefPtr<CefResourceHandler> handler,
net::IOBuffer* dest,
int length,
CefRefPtr<ReadCallbackWrapper> callback) {
CEF_POST_TASK(
CEF_IOT, base::Bind(ReadResponseCallbackWrapper::ReadResponseOnIOThread,
handler, base::Unretained(dest), length, callback));
}
private:
ReadResponseCallbackWrapper(CefRefPtr<CefResourceHandler> handler,
net::IOBuffer* dest,
int length,
CefRefPtr<ReadCallbackWrapper> callback)
: handler_(handler), dest_(dest), length_(length), callback_(callback) {}
static void ReadResponseOnIOThread(CefRefPtr<CefResourceHandler> handler,
net::IOBuffer* dest,
int length,
CefRefPtr<ReadCallbackWrapper> callback) {
CEF_REQUIRE_IOT();
CefRefPtr<ReadResponseCallbackWrapper> callbackWrapper =
new ReadResponseCallbackWrapper(handler, dest, length, callback);
callbackWrapper->DoRead();
}
void DoRead() {
CEF_REQUIRE_IOT();
if (!callback_)
return;
int bytes_read = 0;
bool result =
handler_->ReadResponse(dest_->data(), length_, bytes_read, this);
if (result) {
if (bytes_read > 0) {
// Continue immediately.
callback_->Continue(bytes_read);
callback_ = nullptr;
}
return;
}
// Signal response completion immediately.
callback_->Continue(0);
callback_ = nullptr;
}
void DoCancel() {
CEF_REQUIRE_IOT();
if (callback_) {
callback_->Continue(net::ERR_FAILED);
callback_ = nullptr;
}
}
CefRefPtr<CefResourceHandler> handler_;
net::IOBuffer* const dest_;
int length_;
CefRefPtr<ReadCallbackWrapper> callback_;
IMPLEMENT_REFCOUNTING(ReadResponseCallbackWrapper);
DISALLOW_COPY_AND_ASSIGN(ReadResponseCallbackWrapper);
};
class InputStreamWrapper : public InputStream {
public:
explicit InputStreamWrapper(CefRefPtr<CefResourceHandler> handler)
: handler_(handler) {}
~InputStreamWrapper() override {}
// InputStream methods:
bool Skip(int64_t n, int64_t* bytes_skipped, SkipCallback callback) override {
CefRefPtr<SkipCallbackWrapper> callbackWrapper =
new SkipCallbackWrapper(std::move(callback));
bool result = handler_->Skip(n, *bytes_skipped, callbackWrapper.get());
if (result) {
if (*bytes_skipped > 0) {
// Continue immediately.
callbackWrapper->Disconnect();
}
return true;
}
// Cancel immediately.
return false;
}
bool Read(net::IOBuffer* dest,
int length,
int* bytes_read,
ReadCallback callback) override {
CefRefPtr<ReadCallbackWrapper> callbackWrapper =
new ReadCallbackWrapper(std::move(callback));
bool result = handler_->Read(dest->data(), length, *bytes_read,
callbackWrapper.get());
if (result) {
if (*bytes_read > 0) {
// Continue immediately.
callbackWrapper->Disconnect();
}
return true;
}
if (*bytes_read == -1) {
// Call ReadResponse on the IO thread.
ReadResponseCallbackWrapper::ReadResponse(handler_, dest, length,
callbackWrapper);
*bytes_read = 0;
return true;
}
// Complete or cancel immediately.
return false;
}
private:
CefRefPtr<CefResourceHandler> handler_;
DISALLOW_COPY_AND_ASSIGN(InputStreamWrapper);
};
class OpenCallbackWrapper : public CefCallback {
public:
OpenCallbackWrapper(ResourceResponse::OpenCallback callback,
std::unique_ptr<InputStreamWrapper> stream)
: callback_(std::move(callback)),
stream_(std::move(stream)),
work_thread_task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
~OpenCallbackWrapper() override {
if (!callback_.is_null()) {
Execute(std::move(callback_), std::move(stream_), false);
}
}
void Continue() override {
if (!work_thread_task_runner_->RunsTasksInCurrentSequence()) {
work_thread_task_runner_->PostTask(
FROM_HERE, base::Bind(&OpenCallbackWrapper::Continue, this));
return;
}
if (!callback_.is_null()) {
Execute(std::move(callback_), std::move(stream_), true);
}
}
void Cancel() override {
if (!work_thread_task_runner_->RunsTasksInCurrentSequence()) {
work_thread_task_runner_->PostTask(
FROM_HERE, base::Bind(&OpenCallbackWrapper::Cancel, this));
return;
}
if (!callback_.is_null()) {
Execute(std::move(callback_), std::move(stream_), false);
}
}
private:
static void Execute(ResourceResponse::OpenCallback callback,
std::unique_ptr<InputStreamWrapper> stream,
bool cont) {
std::move(callback).Run(cont ? std::move(stream) : nullptr);
}
ResourceResponse::OpenCallback callback_;
std::unique_ptr<InputStreamWrapper> stream_;
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner_;
IMPLEMENT_REFCOUNTING(OpenCallbackWrapper);
DISALLOW_COPY_AND_ASSIGN(OpenCallbackWrapper);
};
void CallProcessRequestOnIOThread(
CefRefPtr<CefResourceHandler> handler,
CefRefPtr<CefRequestImpl> request,
CefRefPtr<OpenCallbackWrapper> callbackWrapper) {
CEF_REQUIRE_IOT();
if (!handler->ProcessRequest(request.get(), callbackWrapper.get())) {
callbackWrapper->Cancel();
}
}
class ResourceResponseWrapper : public ResourceResponse {
public:
ResourceResponseWrapper(const RequestId request_id,
CefRefPtr<CefResourceHandler> handler)
: request_id_(request_id), handler_(handler) {
DCHECK(handler_);
}
~ResourceResponseWrapper() override {}
// ResourceResponse methods:
bool OpenInputStream(const RequestId& request_id,
const network::ResourceRequest& request,
OpenCallback callback) override {
DCHECK_EQ(request_id, request_id_);
// May be recreated on redirect.
request_ = new CefRequestImpl();
request_->Set(&request, request_id.hash());
request_->SetReadOnly(true);
CefRefPtr<OpenCallbackWrapper> callbackWrapper = new OpenCallbackWrapper(
std::move(callback), std::make_unique<InputStreamWrapper>(handler_));
bool handle_request = false;
bool result =
handler_->Open(request_.get(), handle_request, callbackWrapper.get());
if (result) {
if (handle_request) {
// Continue immediately.
callbackWrapper->Continue();
}
return true;
}
if (handle_request) {
// Cancel immediately.
callbackWrapper->Cancel();
return true;
}
// Call ProcessRequest on the IO thread.
CEF_POST_TASK(CEF_IOT, base::Bind(CallProcessRequestOnIOThread, handler_,
request_, callbackWrapper));
return true;
}
void GetResponseHeaders(const RequestId& request_id,
int* status_code,
std::string* reason_phrase,
std::string* mime_type,
std::string* charset,
int64_t* content_length,
HeaderMap* extra_headers) override {
DCHECK_EQ(request_id, request_id_);
CEF_REQUIRE_IOT();
CefRefPtr<CefResponse> response = CefResponse::Create();
int64_t response_length = -1;
CefString redirect_url;
handler_->GetResponseHeaders(response, response_length, redirect_url);
const auto error_code = response->GetError();
if (error_code != ERR_NONE) {
// Early exit if the handler reported an error.
*status_code = error_code;
return;
}
if (!redirect_url.empty()) {
// Perform a redirect.
*status_code = net::HTTP_TEMPORARY_REDIRECT;
*reason_phrase = std::string();
extra_headers->insert(
std::make_pair(kHTTPLocationHeaderName, redirect_url));
} else {
*status_code = response->GetStatus();
*reason_phrase = response->GetStatusText();
}
if (reason_phrase->empty() && *status_code > 0) {
*reason_phrase = net::GetHttpReasonPhrase(
static_cast<net::HttpStatusCode>(*status_code));
}
*mime_type = response->GetMimeType();
*charset = response->GetCharset();
// A |content_length| value may already be specified if the request included
// a Range header.
if (response_length >= 0 && *content_length == -1)
*content_length = response_length;
CefResponse::HeaderMap headerMap;
response->GetHeaderMap(headerMap);
for (const auto& value : headerMap) {
extra_headers->insert(std::make_pair(value.first, value.second));
}
}
private:
const RequestId request_id_;
CefRefPtr<CefRequestImpl> request_;
CefRefPtr<CefResourceHandler> handler_;
DISALLOW_COPY_AND_ASSIGN(ResourceResponseWrapper);
};
} // namespace
std::unique_ptr<ResourceResponse> CreateResourceResponse(
const RequestId& request_id,
CefRefPtr<CefResourceHandler> handler) {
return std::make_unique<ResourceResponseWrapper>(request_id, handler);
}
} // namespace net_service

View File

@ -0,0 +1,25 @@
// 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_RESOURCE_HANDLER_WRAPPER_H_
#define CEF_LIBCEF_BROWSER_NET_SERVICE_RESOURCE_HANDLER_WRAPPER_H_
#include "include/cef_request.h"
#include "include/cef_resource_handler.h"
namespace net_service {
class RequestId;
class ResourceResponse;
// Create a ResourceResponse that delegates to |handler|.
// The resulting object should be passed to
// InterceptedRequestHandler::ShouldInterceptRequestResultCallback.
std::unique_ptr<ResourceResponse> CreateResourceResponse(
const RequestId& request_id,
CefRefPtr<CefResourceHandler> handler);
} // namespace net_service
#endif // CEF_LIBCEF_BROWSER_NET_SERVICE_RESOURCE_HANDLER_WRAPPER_H_

View File

@ -0,0 +1,863 @@
// 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/resource_request_handler_wrapper.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/net_service/cookie_helper.h"
#include "libcef/browser/net_service/proxy_url_loader_factory.h"
#include "libcef/browser/net_service/resource_handler_wrapper.h"
#include "libcef/browser/resource_context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/content_client.h"
#include "libcef/common/net/scheme_registration.h"
#include "libcef/common/net_service/net_service_util.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/response_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "net/http/http_status_code.h"
#include "ui/base/page_transition_types.h"
#include "url/origin.h"
namespace net_service {
namespace {
class RequestCallbackWrapper : public CefRequestCallback {
public:
using Callback = base::OnceCallback<void(bool /* allow */)>;
explicit RequestCallbackWrapper(Callback callback)
: callback_(std::move(callback)),
work_thread_task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
~RequestCallbackWrapper() override {
if (!callback_.is_null()) {
// Make sure it executes on the correct thread.
work_thread_task_runner_->PostTask(
FROM_HERE, base::BindOnce(std::move(callback_), true));
}
}
void Continue(bool allow) override {
if (!work_thread_task_runner_->RunsTasksInCurrentSequence()) {
work_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&RequestCallbackWrapper::Continue, this, allow));
return;
}
if (!callback_.is_null()) {
std::move(callback_).Run(allow);
}
}
void Cancel() override { Continue(false); }
private:
Callback callback_;
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner_;
IMPLEMENT_REFCOUNTING(RequestCallbackWrapper);
DISALLOW_COPY_AND_ASSIGN(RequestCallbackWrapper);
};
std::string GetAcceptLanguageList(content::BrowserContext* browser_context,
CefRefPtr<CefBrowserHostImpl> browser) {
if (browser) {
const CefBrowserSettings& browser_settings = browser->settings();
if (browser_settings.accept_language_list.length > 0) {
return CefString(&browser_settings.accept_language_list);
}
}
const CefRequestContextSettings& context_settings =
static_cast<CefBrowserContext*>(browser_context)->GetSettings();
if (context_settings.accept_language_list.length > 0) {
return CefString(&context_settings.accept_language_list);
}
return "en-US,en";
}
class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
public:
struct RequestState {
RequestState() {}
void Reset(CefRefPtr<CefResourceRequestHandler> handler,
CefRefPtr<CefSchemeHandlerFactory> scheme_factory,
CefRefPtr<CefRequestImpl> request,
bool request_was_redirected) {
handler_ = handler;
scheme_factory_ = scheme_factory;
pending_request_ = request;
pending_response_ = nullptr;
request_was_redirected_ = request_was_redirected;
}
CefRefPtr<CefResourceRequestHandler> handler_;
CefRefPtr<CefSchemeHandlerFactory> scheme_factory_;
CefRefPtr<CefRequestImpl> pending_request_;
CefRefPtr<CefResponseImpl> pending_response_;
bool request_was_redirected_ = false;
};
struct PendingRequest {
PendingRequest(const RequestId& id,
network::ResourceRequest* request,
bool request_was_redirected,
OnBeforeRequestResultCallback callback)
: id_(id),
request_(request),
request_was_redirected_(request_was_redirected),
callback_(std::move(callback)) {}
void Run(InterceptedRequestHandlerWrapper* self) {
self->OnBeforeRequest(id_, request_, request_was_redirected_,
std::move(callback_));
}
const RequestId id_;
network::ResourceRequest* const request_;
const bool request_was_redirected_;
OnBeforeRequestResultCallback callback_;
};
InterceptedRequestHandlerWrapper() : weak_ptr_factory_(this) {}
~InterceptedRequestHandlerWrapper() override {}
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_);
// Don't hold a RefPtr to the CefBrowserHostImpl.
if (browser)
browser_info_ = browser->browser_info();
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();
is_external_ = is_external;
// Default values for standard headers.
accept_language_ = net::HttpUtil::GenerateAcceptLanguageHeader(
GetAcceptLanguageList(browser_context, browser));
user_agent_ = CefContentClient::Get()->browser()->GetUserAgent();
CEF_POST_TASK(
CEF_IOT,
base::BindOnce(&InterceptedRequestHandlerWrapper::SetInitialized,
weak_ptr_factory_.GetWeakPtr()));
}
void SetInitialized() {
CEF_REQUIRE_IOT();
initialized_ = true;
// Continue any pending requests.
if (!pending_requests_.empty()) {
for (const auto& request : pending_requests_)
request->Run(this);
pending_requests_.clear();
}
}
// InterceptedRequestHandler methods:
void OnBeforeRequest(const RequestId& id,
network::ResourceRequest* request,
bool request_was_redirected,
OnBeforeRequestResultCallback callback) override {
CEF_REQUIRE_IOT();
if (!initialized_) {
// Queue requests until we're initialized.
pending_requests_.push_back(std::make_unique<PendingRequest>(
id, request, request_was_redirected, std::move(callback)));
return;
}
// State may already exist for restarted requests.
RequestState* state = GetOrCreateState(id);
// Add standard headers, if currently unspecified.
request->headers.SetHeaderIfMissing(
net::HttpRequestHeaders::kAcceptLanguage, accept_language_);
request->headers.SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent,
user_agent_);
// External requests will not have a default handler.
bool intercept_only = is_external_;
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefResourceRequestHandler> handler =
GetHandler(id, request, &intercept_only, requestPtr);
CefRefPtr<CefSchemeHandlerFactory> scheme_factory =
resource_context_->GetSchemeHandlerFactory(request->url);
// May have a handler and/or scheme factory.
state->Reset(handler, scheme_factory, requestPtr, request_was_redirected);
auto exec_callback = base::BindOnce(
std::move(callback), handler || scheme_factory /* intercept_request */,
is_external_ ? true : intercept_only);
MaybeLoadCookies(state, request, std::move(exec_callback));
}
void MaybeLoadCookies(RequestState* state,
network::ResourceRequest* request,
base::OnceClosure callback) {
CEF_REQUIRE_IOT();
auto allow_cookie_callback =
base::BindRepeating(&InterceptedRequestHandlerWrapper::AllowCookieLoad,
weak_ptr_factory_.GetWeakPtr(), state);
auto done_cookie_callback = base::BindOnce(
&InterceptedRequestHandlerWrapper::ContinueWithLoadedCookies,
weak_ptr_factory_.GetWeakPtr(), state, request, std::move(callback));
net_service::LoadCookies(browser_context_, *request, allow_cookie_callback,
std::move(done_cookie_callback));
}
void AllowCookieLoad(RequestState* state,
const net::CanonicalCookie& cookie,
bool* allow) {
CEF_REQUIRE_IOT();
CefCookie cef_cookie;
if (net_service::MakeCefCookie(cookie, cef_cookie)) {
*allow = state->handler_->CanSendCookie(
GetBrowser(), frame_, state->pending_request_.get(), cef_cookie);
}
}
void ContinueWithLoadedCookies(RequestState* state,
network::ResourceRequest* request,
base::OnceClosure callback,
int total_count,
net::CookieList allowed_cookies) {
CEF_REQUIRE_IOT();
if (state->handler_) {
// Add the Cookie header ourselves instead of letting the NetworkService
// do it.
request->load_flags |= net::LOAD_DO_NOT_SEND_COOKIES;
if (!allowed_cookies.empty()) {
const std::string& cookie_line =
net::CanonicalCookie::BuildCookieLine(allowed_cookies);
request->headers.SetHeader(net::HttpRequestHeaders::kCookie,
cookie_line);
state->pending_request_->SetReadOnly(false);
state->pending_request_->SetHeaderByName(
net::HttpRequestHeaders::kCookie, cookie_line, true);
state->pending_request_->SetReadOnly(true);
}
// Save cookies ourselves instead of letting the NetworkService do it.
request->load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES;
}
std::move(callback).Run();
}
void ShouldInterceptRequest(
const RequestId& id,
network::ResourceRequest* request,
ShouldInterceptRequestResultCallback callback) override {
CEF_REQUIRE_IOT();
RequestState* state = GetState(id);
DCHECK(state);
// Must have a handler and/or scheme factory.
DCHECK(state->handler_ || state->scheme_factory_);
DCHECK(state->pending_request_);
if (state->handler_) {
// The client may modify |pending_request_| before executing the callback.
state->pending_request_->SetReadOnly(false);
state->pending_request_->SetTrackChanges(true,
true /* backup_on_change */);
CefRefPtr<RequestCallbackWrapper> callbackPtr =
new RequestCallbackWrapper(base::BindOnce(
&InterceptedRequestHandlerWrapper::ContinueShouldInterceptRequest,
weak_ptr_factory_.GetWeakPtr(), id, base::Unretained(request),
base::Passed(std::move(callback))));
cef_return_value_t retval = state->handler_->OnBeforeResourceLoad(
GetBrowser(), frame_, state->pending_request_.get(),
callbackPtr.get());
if (retval != RV_CONTINUE_ASYNC) {
// Continue or cancel the request immediately.
callbackPtr->Continue(retval == RV_CONTINUE);
}
} else {
// The scheme factory may choose to handle it.
ContinueShouldInterceptRequest(id, request, std::move(callback), true);
}
}
void ContinueShouldInterceptRequest(
const RequestId& id,
network::ResourceRequest* request,
ShouldInterceptRequestResultCallback callback,
bool allow) {
CEF_REQUIRE_IOT();
RequestState* state = GetState(id);
DCHECK(state);
// Must have a handler and/or scheme factory.
DCHECK(state->handler_ || state->scheme_factory_);
DCHECK(state->pending_request_);
if (state->handler_) {
if (allow) {
// Apply any |requestPtr| changes to |request|.
state->pending_request_->Get(request, true /* changed_only */);
}
const bool redirect =
(state->pending_request_->GetChanges() & CefRequestImpl::kChangedUrl);
if (redirect) {
// Revert any changes for now. We'll get them back after the redirect.
state->pending_request_->RevertChanges();
}
state->pending_request_->SetReadOnly(true);
state->pending_request_->SetTrackChanges(false);
if (!allow) {
// Cancel the request.
std::move(callback).Run(nullptr, true /* cancel_request */);
return;
}
if (redirect) {
// Performing a redirect.
std::move(callback).Run(nullptr, false /* cancel_request */);
return;
}
}
CefRefPtr<CefResourceHandler> resource_handler;
CefRefPtr<CefBrowser> browser = GetBrowser();
if (state->handler_) {
// Does the client want to handle the request?
resource_handler = state->handler_->GetResourceHandler(
browser, frame_, state->pending_request_.get());
}
if (!resource_handler && state->scheme_factory_) {
// Does the scheme factory want to handle the request?
resource_handler =
state->scheme_factory_->Create(browser, frame_, request->url.scheme(),
state->pending_request_.get());
}
std::unique_ptr<ResourceResponse> resource_response;
if (resource_handler) {
resource_response = CreateResourceResponse(id, resource_handler);
}
// Continue the request.
std::move(callback).Run(std::move(resource_response),
false /* cancel_request */);
}
void ProcessResponseHeaders(
const RequestId& id,
const network::ResourceRequest& request,
const GURL& redirect_url,
const network::ResourceResponseHead& head) override {
CEF_REQUIRE_IOT();
RequestState* state = GetState(id);
DCHECK(state);
if (!state->handler_)
return;
if (!state->pending_response_)
state->pending_response_ = new CefResponseImpl();
else
state->pending_response_->SetReadOnly(false);
if (head.headers)
state->pending_response_->SetResponseHeaders(*head.headers);
state->pending_response_->SetReadOnly(true);
}
void OnRequestResponse(const RequestId& id,
network::ResourceRequest* request,
const network::ResourceResponseHead& head,
base::Optional<net::RedirectInfo> redirect_info,
OnRequestResponseResultCallback callback) override {
CEF_REQUIRE_IOT();
RequestState* state = GetState(id);
DCHECK(state);
if (!state->handler_)
return;
DCHECK(state->pending_request_);
DCHECK(state->pending_response_);
// This flag should always be set.
DCHECK(request->load_flags | net::LOAD_DO_NOT_SAVE_COOKIES);
if (redirect_info.has_value()) {
HandleRedirect(state, *redirect_info, std::move(callback));
} else {
HandleResponse(state, request, head, std::move(callback));
}
}
void HandleRedirect(RequestState* state,
const net::RedirectInfo& redirect_info,
OnRequestResponseResultCallback callback) {
GURL new_url = redirect_info.new_url;
CefString newUrl = redirect_info.new_url.spec();
CefString oldUrl = newUrl;
bool url_changed = false;
state->handler_->OnResourceRedirect(GetBrowser(), frame_,
state->pending_request_.get(),
state->pending_response_.get(), newUrl);
if (newUrl != oldUrl) {
// Also support relative URLs.
const GURL& url = redirect_info.new_url.Resolve(newUrl.ToString());
if (url.is_valid()) {
url_changed = true;
new_url = url;
}
}
// Update the |pending_request_| object with the new info.
state->pending_request_->SetReadOnly(false);
state->pending_request_->Set(redirect_info);
if (url_changed) {
state->pending_request_->SetURL(new_url.spec());
}
state->pending_request_->SetReadOnly(true);
std::move(callback).Run(ResponseMode::CONTINUE, nullptr, new_url);
}
void HandleResponse(RequestState* state,
network::ResourceRequest* request,
const network::ResourceResponseHead& head,
OnRequestResponseResultCallback callback) {
// The client may modify |pending_request_| in OnResourceResponse.
state->pending_request_->SetReadOnly(false);
state->pending_request_->SetTrackChanges(true, true /* backup_on_change */);
auto response_mode = ResponseMode::CONTINUE;
GURL new_url;
if (state->handler_->OnResourceResponse(GetBrowser(), frame_,
state->pending_request_.get(),
state->pending_response_.get())) {
// The request may have been modified.
const auto changes = state->pending_request_->GetChanges();
if (changes) {
state->pending_request_->Get(request, true /* changed_only */);
if (changes & CefRequestImpl::kChangedUrl) {
// Redirect to the new URL.
new_url = GURL(state->pending_request_->GetURL().ToString());
} else {
// Restart the request.
response_mode = ResponseMode::RESTART;
}
}
}
// Revert any changes for now. We'll get them back after the redirect or
// restart.
state->pending_request_->RevertChanges();
state->pending_request_->SetReadOnly(true);
state->pending_request_->SetTrackChanges(false);
auto exec_callback =
base::BindOnce(std::move(callback), response_mode, nullptr, new_url);
if (response_mode == ResponseMode::RESTART) {
// Continue without saving cookies. We'll get them after the restart.
std::move(exec_callback).Run();
return;
}
MaybeSaveCookies(state, request, head, std::move(exec_callback));
}
void MaybeSaveCookies(RequestState* state,
network::ResourceRequest* request,
const network::ResourceResponseHead& head,
base::OnceClosure callback) {
CEF_REQUIRE_IOT();
auto allow_cookie_callback =
base::BindRepeating(&InterceptedRequestHandlerWrapper::AllowCookieSave,
weak_ptr_factory_.GetWeakPtr(), state);
auto done_cookie_callback = base::BindOnce(
&InterceptedRequestHandlerWrapper::ContinueWithSavedCookies,
weak_ptr_factory_.GetWeakPtr(), state, std::move(callback));
net_service::SaveCookies(browser_context_, *request, head,
allow_cookie_callback,
std::move(done_cookie_callback));
}
void AllowCookieSave(RequestState* state,
const net::CanonicalCookie& cookie,
bool* allow) {
CEF_REQUIRE_IOT();
CefCookie cef_cookie;
if (net_service::MakeCefCookie(cookie, cef_cookie)) {
*allow = state->handler_->CanSaveCookie(
GetBrowser(), frame_, state->pending_request_.get(),
state->pending_response_.get(), cef_cookie);
}
}
void ContinueWithSavedCookies(RequestState* state,
base::OnceClosure callback,
int total_count,
net::CookieList allowed_cookies) {
CEF_REQUIRE_IOT();
std::move(callback).Run();
}
void OnRequestComplete(
const RequestId& id,
const network::ResourceRequest& request,
const network::URLLoaderCompletionStatus& status) override {
CEF_REQUIRE_IOT();
RequestState* state = GetState(id);
DCHECK(state);
// Redirection of standard custom schemes is handled with a restart, so we
// get completion notifications for both the original (redirected) request
// and the final request. Don't report completion of the redirected request.
const bool ignore_result = is_external_ && request.url.IsStandard() &&
status.error_code == net::ERR_ABORTED &&
state->pending_response_.get() &&
net::HttpResponseHeaders::IsRedirectResponseCode(
state->pending_response_->GetStatus());
if (state->handler_ && !ignore_result) {
DCHECK(state->pending_request_);
if (!state->pending_response_) {
// If the request failed there may not be a response object yet.
state->pending_response_ = new CefResponseImpl();
} else {
state->pending_response_->SetReadOnly(false);
}
state->pending_response_->SetError(
static_cast<cef_errorcode_t>(status.error_code));
state->pending_response_->SetReadOnly(true);
CefRefPtr<CefBrowser> browser = GetBrowser();
state->handler_->OnResourceLoadComplete(
browser, frame_, state->pending_request_.get(),
state->pending_response_.get(),
status.error_code == 0 ? UR_SUCCESS : UR_FAILED,
status.encoded_body_length);
if (status.error_code != 0 && is_external_) {
bool allow_os_execution = false;
state->handler_->OnProtocolExecution(
browser, frame_, state->pending_request_.get(), allow_os_execution);
if (allow_os_execution) {
CefBrowserPlatformDelegate::HandleExternalProtocol(request.url);
}
}
}
RemoveState(id);
}
private:
// Returns the handler, if any, that should be used for this request.
CefRefPtr<CefResourceRequestHandler> GetHandler(
const RequestId& id,
network::ResourceRequest* request,
bool* intercept_only,
CefRefPtr<CefRequestImpl>& requestPtr) const {
CefRefPtr<CefResourceRequestHandler> handler;
const int64 request_id = id.hash();
CefRefPtr<CefBrowser> browser = GetBrowser();
if (browser) {
// Maybe the browser's client wants to handle it?
CefRefPtr<CefClient> client = browser->GetHost()->GetClient();
if (client) {
CefRefPtr<CefRequestHandler> request_handler =
client->GetRequestHandler();
if (request_handler) {
requestPtr = MakeRequest(request, request_id, true);
handler = request_handler->GetResourceRequestHandler(
browser, frame_, requestPtr.get(), is_navigation_, is_download_,
request_initiator_, *intercept_only);
}
}
}
if (!handler) {
// Maybe the request context wants to handle it?
CefRefPtr<CefRequestContextHandler> context_handler =
resource_context_->GetHandler(render_process_id_,
request->render_frame_id,
frame_tree_node_id_, false);
if (context_handler) {
if (!requestPtr)
requestPtr = MakeRequest(request, request_id, true);
handler = context_handler->GetResourceRequestHandler(
browser, frame_, requestPtr.get(), is_navigation_, is_download_,
request_initiator_, *intercept_only);
}
}
return handler;
}
RequestState* GetOrCreateState(const RequestId& id) {
RequestState* state = GetState(id);
if (!state) {
state = new RequestState();
request_map_.insert(std::make_pair(id, base::WrapUnique(state)));
}
return state;
}
RequestState* GetState(const RequestId& id) const {
RequestMap::const_iterator it = request_map_.find(id);
if (it != request_map_.end())
return it->second.get();
return nullptr;
}
void RemoveState(const RequestId& id) {
RequestMap::iterator it = request_map_.find(id);
DCHECK(it != request_map_.end());
if (it != request_map_.end())
request_map_.erase(it);
}
CefRefPtr<CefBrowser> GetBrowser() const {
if (browser_info_)
return browser_info_->browser().get();
return nullptr;
}
static CefRefPtr<CefRequestImpl> MakeRequest(
const network::ResourceRequest* request,
int64 request_id,
bool read_only) {
CefRefPtr<CefRequestImpl> requestPtr = new CefRequestImpl();
requestPtr->Set(request, request_id);
if (read_only)
requestPtr->SetReadOnly(true);
else
requestPtr->SetTrackChanges(true);
return requestPtr;
}
bool initialized_ = false;
// Only accessed on the UI thread.
content::BrowserContext* browser_context_ = nullptr;
scoped_refptr<CefBrowserInfo> browser_info_;
CefRefPtr<CefFrame> frame_;
CefResourceContext* resource_context_ = nullptr;
int render_process_id_ = 0;
int render_frame_id_ = -1;
int frame_tree_node_id_ = -1;
bool is_navigation_ = true;
bool is_download_ = false;
CefString request_initiator_;
bool is_external_ = false;
// Default values for standard headers.
std::string accept_language_;
std::string user_agent_;
using RequestMap = std::map<RequestId, std::unique_ptr<RequestState>>;
RequestMap request_map_;
using PendingRequests = std::vector<std::unique_ptr<PendingRequest>>;
PendingRequests pending_requests_;
base::WeakPtrFactory<InterceptedRequestHandlerWrapper> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(InterceptedRequestHandlerWrapper);
};
void InitOnUIThread(
InterceptedRequestHandlerWrapper* wrapper,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
int frame_tree_node_id,
const network::ResourceRequest& request) {
CEF_REQUIRE_UIT();
content::WebContents* web_contents = web_contents_getter.Run();
DCHECK(web_contents);
content::BrowserContext* browser_context = web_contents->GetBrowserContext();
DCHECK(browser_context);
const int render_process_id =
web_contents->GetRenderViewHost()->GetProcess()->GetID();
content::RenderFrameHost* frame = nullptr;
bool get_frame_by_route = false;
if (request.render_frame_id >= 0) {
// TODO(network): Are these main frame checks equivalent?
if (request.is_main_frame ||
request.resource_type == content::RESOURCE_TYPE_MAIN_FRAME) {
frame = web_contents->GetMainFrame();
DCHECK(frame);
} else {
// May return null for newly created iframes.
frame = content::RenderFrameHost::FromID(render_process_id,
request.render_frame_id);
if (!frame && frame_tree_node_id >= 0) {
// May return null for frames in inner WebContents.
frame = web_contents->FindFrameByFrameTreeNodeId(frame_tree_node_id,
render_process_id);
}
if (!frame) {
// Use the main frame for the CefBrowserHost, but choose a more
// appropriate CefFrame for the route.
frame = web_contents->GetMainFrame();
DCHECK(frame);
get_frame_by_route = true;
}
}
}
CefRefPtr<CefBrowserHostImpl> browserPtr;
CefRefPtr<CefFrame> framePtr;
// |frame| may be null for service worker requests.
if (frame) {
#if DCHECK_IS_ON()
if (frame_tree_node_id >= 0 && !get_frame_by_route) {
// Sanity check that we ended up with the expected frame.
DCHECK_EQ(frame_tree_node_id, frame->GetFrameTreeNodeId());
}
#endif
browserPtr = CefBrowserHostImpl::GetBrowserForHost(frame);
if (browserPtr) {
if (get_frame_by_route) {
framePtr =
browserPtr->GetFrameForHostRoutingId(request.render_frame_id);
frame_tree_node_id = -1;
} else {
framePtr = browserPtr->GetFrameForHost(frame);
if (frame_tree_node_id < 0)
frame_tree_node_id = frame->GetFrameTreeNodeId();
}
DCHECK(framePtr);
}
}
const bool is_navigation = ui::PageTransitionIsNewNavigation(
static_cast<ui::PageTransition>(request.transition_type));
// TODO(navigation): Can we determine the |is_download| value?
const bool is_download = false;
url::Origin request_initiator;
if (request.request_initiator.has_value())
request_initiator = *request.request_initiator;
wrapper->Initialize(browser_context, browserPtr, framePtr, render_process_id,
request.render_frame_id, frame_tree_node_id,
is_navigation, is_download, request_initiator,
true /* is_external */);
}
} // namespace
std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
content::BrowserContext* browser_context,
content::RenderFrameHost* frame,
int render_process_id,
bool is_navigation,
bool is_download,
const url::Origin& request_initiator) {
CEF_REQUIRE_UIT();
auto wrapper = std::make_unique<InterceptedRequestHandlerWrapper>();
CefRefPtr<CefBrowserHostImpl> browserPtr;
CefRefPtr<CefFrame> framePtr;
int render_frame_id = -1;
int frame_tree_node_id = -1;
// |frame| may be null for service worker requests.
if (frame) {
render_frame_id = frame->GetRoutingID();
frame_tree_node_id = frame->GetFrameTreeNodeId();
browserPtr = CefBrowserHostImpl::GetBrowserForHost(frame);
if (browserPtr) {
framePtr = browserPtr->GetFrameForHost(frame);
DCHECK(framePtr);
}
}
// Flag subresource loads of custom schemes.
const bool is_external = !is_navigation && !scheme::IsInternalHandledScheme(
request_initiator.scheme());
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;
}
std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
int frame_tree_node_id,
const network::ResourceRequest& request) {
CEF_REQUIRE_IOT();
auto wrapper = std::make_unique<InterceptedRequestHandlerWrapper>();
CEF_POST_TASK(CEF_UIT, base::BindOnce(
InitOnUIThread, base::Unretained(wrapper.get()),
web_contents_getter, frame_tree_node_id, request));
return wrapper;
}
} // namespace net_service

View File

@ -0,0 +1,48 @@
// 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_RESOURCE_REQUEST_HANDLER_WRAPPER_H_
#define CEF_LIBCEF_BROWSER_NET_SERVICE_RESOURCE_REQUEST_HANDLER_WRAPPER_H_
#include "content/public/browser/resource_request_info.h"
namespace content {
class BrowserContext;
class RenderFrameHost;
} // namespace content
namespace network {
struct ResourceRequest;
}
namespace url {
class Origin;
}
namespace net_service {
class InterceptedRequestHandler;
// Create an InterceptedRequestHandler that will delegate to a
// CefResourceRequestHandler. The resulting object should be passed to
// ProxyURLLoaderFactory::CreateProxy. Called on the UI thread only.
std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
content::BrowserContext* browser_context,
content::RenderFrameHost* frame,
int render_process_id,
bool is_navigation,
bool is_download,
const url::Origin& request_initiator);
// Create an InterceptedRequestHandler that will delegate to a
// CefResourceRequestHandler. The resulting object should be passed to
// ProxyURLLoaderFactory::CreateProxy. Called on the IO thread only.
std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
int frame_tree_node_id,
const network::ResourceRequest& request);
} // namespace net_service
#endif // CEF_LIBCEF_BROWSER_NET_SERVICE_RESOURCE_REQUEST_HANDLER_WRAPPER_H_

View File

@ -0,0 +1,825 @@
// Copyright (c) 2019 The Chromium Embedded Framework Authors. Portions
// Copyright (c) 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/browser/net_service/stream_reader_url_loader.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net_service/net_service_util.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
namespace net_service {
namespace {
using OnInputStreamOpenedCallback =
base::OnceCallback<void(std::unique_ptr<StreamReaderURLLoader::Delegate>,
std::unique_ptr<InputStream>)>;
// Helper for executing the OnInputStreamOpenedCallback.
class OpenInputStreamWrapper
: public base::RefCountedThreadSafe<OpenInputStreamWrapper> {
public:
static void Open(
std::unique_ptr<StreamReaderURLLoader::Delegate> delegate,
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner,
const RequestId& request_id,
const network::ResourceRequest& request,
OnInputStreamOpenedCallback callback) {
work_thread_task_runner->PostTask(
FROM_HERE,
base::BindOnce(OpenInputStreamWrapper::OpenOnWorkThread,
// This is intentional - the loader could be deleted
// while the callback is executing on the background
// thread. The delegate will be "returned" to the loader
// once the InputStream open attempt is completed.
std::move(delegate), base::ThreadTaskRunnerHandle::Get(),
request_id, request, std::move(callback)));
}
private:
friend class base::RefCountedThreadSafe<OpenInputStreamWrapper>;
OpenInputStreamWrapper(
std::unique_ptr<StreamReaderURLLoader::Delegate> delegate,
scoped_refptr<base::SingleThreadTaskRunner> job_thread_task_runner,
OnInputStreamOpenedCallback callback)
: delegate_(std::move(delegate)),
job_thread_task_runner_(job_thread_task_runner),
callback_(std::move(callback)) {}
virtual ~OpenInputStreamWrapper() {}
static void OpenOnWorkThread(
std::unique_ptr<StreamReaderURLLoader::Delegate> delegate,
scoped_refptr<base::SingleThreadTaskRunner> job_thread_task_runner,
const RequestId& request_id,
const network::ResourceRequest& request,
OnInputStreamOpenedCallback callback) {
DCHECK(!CEF_CURRENTLY_ON_IOT());
DCHECK(!CEF_CURRENTLY_ON_UIT());
scoped_refptr<OpenInputStreamWrapper> wrapper = new OpenInputStreamWrapper(
std::move(delegate), job_thread_task_runner, std::move(callback));
wrapper->Open(request_id, request);
}
void Open(const RequestId& request_id,
const network::ResourceRequest& request) {
if (!delegate_->OpenInputStream(
request_id, request,
base::BindOnce(&OpenInputStreamWrapper::OnCallback,
base::WrapRefCounted(this)))) {
OnCallback(nullptr);
}
}
void OnCallback(std::unique_ptr<InputStream> input_stream) {
if (!job_thread_task_runner_->RunsTasksInCurrentSequence()) {
job_thread_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&OpenInputStreamWrapper::OnCallback,
base::WrapRefCounted(this), std::move(input_stream)));
return;
}
DCHECK(!callback_.is_null());
if (callback_.is_null())
return;
std::move(callback_).Run(std::move(delegate_), std::move(input_stream));
}
std::unique_ptr<StreamReaderURLLoader::Delegate> delegate_;
scoped_refptr<base::SingleThreadTaskRunner> job_thread_task_runner_;
OnInputStreamOpenedCallback callback_;
DISALLOW_COPY_AND_ASSIGN(OpenInputStreamWrapper);
};
} // namespace
//==============================
// InputStreamReader
//=============================
// Class responsible for reading from the InputStream.
class InputStreamReader : public base::RefCountedThreadSafe<InputStreamReader> {
public:
// The constructor is called on the IO thread, not on the worker thread.
// Callbacks will be executed on the IO thread.
InputStreamReader(
std::unique_ptr<InputStream> stream,
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner);
// Skip |skip_bytes| number of bytes from |stream_|. |callback| will be
// executed asynchronously on the IO thread. A negative value passed to
// |callback| will indicate an error code, a positive value will indicate the
// number of bytes skipped.
void Skip(int64_t skip_bytes, InputStream::SkipCallback callback);
// Read up to |dest_size| bytes from |stream_| into |dest|. |callback| will be
// executed asynchronously on the IO thread. A negative value passed to
// |callback| will indicate an error code, a positive value will indicate the
// number of bytes read.
void Read(scoped_refptr<net::IOBuffer> dest,
int dest_size,
InputStream::ReadCallback callback);
private:
friend class base::RefCountedThreadSafe<InputStreamReader>;
virtual ~InputStreamReader();
void SkipOnWorkThread(int64_t skip_bytes, InputStream::SkipCallback callback);
void ReadOnWorkThread(scoped_refptr<net::IOBuffer> buffer,
int buffer_size,
InputStream::ReadCallback callback);
void SkipToRequestedRange();
static void ContinueSkipCallback(
scoped_refptr<InputStreamReader> stream,
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner,
int callback_id,
int64_t bytes_skipped);
static void ContinueReadCallback(
scoped_refptr<InputStreamReader> stream,
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner,
int callback_id,
int bytes_read);
void ContinueSkipCallbackOnWorkThread(int callback_id, int64_t bytes_skipped);
void ContinueReadCallbackOnWorkThread(int callback_id, int bytes_read);
void RunSkipCallback(int64_t bytes_skipped);
void RunReadCallback(int bytes_read);
static void RunSkipCallbackOnJobThread(
int64_t bytes_skipped,
InputStream::SkipCallback skip_callback);
static void RunReadCallbackOnJobThread(
int bytes_read,
InputStream::ReadCallback read_callback);
std::unique_ptr<InputStream> stream_;
// All InputStream methods are called this task runner.
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner_;
// All callbacks are executed on this task runner.
scoped_refptr<base::SingleThreadTaskRunner> job_thread_task_runner_;
// The below members are only accessed on the work thread.
int64_t bytes_skipped_;
int64_t bytes_to_skip_;
InputStream::SkipCallback pending_skip_callback_;
scoped_refptr<net::IOBuffer> buffer_;
InputStream::ReadCallback pending_read_callback_;
int pending_callback_id_ = -1;
int next_callback_id_ = 0;
DISALLOW_COPY_AND_ASSIGN(InputStreamReader);
};
InputStreamReader::InputStreamReader(
std::unique_ptr<InputStream> stream,
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner)
: stream_(std::move(stream)),
work_thread_task_runner_(work_thread_task_runner),
job_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
CEF_REQUIRE_IOT();
DCHECK(stream_);
DCHECK(work_thread_task_runner_);
}
InputStreamReader::~InputStreamReader() {}
void InputStreamReader::Skip(int64_t skip_bytes,
InputStream::SkipCallback callback) {
work_thread_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&InputStreamReader::SkipOnWorkThread,
base::WrapRefCounted(this), skip_bytes,
std::move(callback)));
}
void InputStreamReader::Read(scoped_refptr<net::IOBuffer> dest,
int dest_size,
InputStream::ReadCallback callback) {
work_thread_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&InputStreamReader::ReadOnWorkThread,
base::WrapRefCounted(this), dest, dest_size,
std::move(callback)));
}
void InputStreamReader::SkipOnWorkThread(int64_t skip_bytes,
InputStream::SkipCallback callback) {
DCHECK(work_thread_task_runner_->RunsTasksInCurrentSequence());
// No callback should currently be pending.
DCHECK_EQ(pending_callback_id_, -1);
DCHECK(pending_skip_callback_.is_null());
pending_skip_callback_ = std::move(callback);
if (skip_bytes <= 0) {
RunSkipCallback(0);
return;
}
bytes_skipped_ = bytes_to_skip_ = skip_bytes;
SkipToRequestedRange();
}
void InputStreamReader::ReadOnWorkThread(scoped_refptr<net::IOBuffer> dest,
int dest_size,
InputStream::ReadCallback callback) {
DCHECK(work_thread_task_runner_->RunsTasksInCurrentSequence());
// No callback should currently be pending.
DCHECK_EQ(pending_callback_id_, -1);
DCHECK(pending_read_callback_.is_null());
pending_read_callback_ = std::move(callback);
if (!dest_size) {
RunReadCallback(0);
return;
}
DCHECK_GT(dest_size, 0);
buffer_ = dest;
pending_callback_id_ = ++next_callback_id_;
int bytes_read = 0;
bool result = stream_->Read(
buffer_.get(), dest_size, &bytes_read,
base::BindOnce(&InputStreamReader::ContinueReadCallback,
base::WrapRefCounted(this), work_thread_task_runner_,
pending_callback_id_));
// Check if the callback will execute asynchronously.
if (result && bytes_read == 0)
return;
RunReadCallback(result || bytes_read <= 0 ? bytes_read : net::ERR_FAILED);
}
void InputStreamReader::SkipToRequestedRange() {
DCHECK(work_thread_task_runner_->RunsTasksInCurrentSequence());
// Skip to the start of the requested data. This has to be done in a loop
// because the underlying InputStream is not guaranteed to skip the requested
// number of bytes.
do {
pending_callback_id_ = ++next_callback_id_;
int64_t skipped = 0;
bool result = stream_->Skip(
bytes_to_skip_, &skipped,
base::BindOnce(&InputStreamReader::ContinueSkipCallback,
base::WrapRefCounted(this), work_thread_task_runner_,
pending_callback_id_));
// Check if the callback will execute asynchronously.
if (result && skipped == 0)
return;
if (!result || skipped <= 0) {
RunSkipCallback(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE);
return;
}
DCHECK_LE(skipped, bytes_to_skip_);
bytes_to_skip_ -= skipped;
} while (bytes_to_skip_ > 0);
// All done, the requested number of bytes were skipped.
RunSkipCallback(bytes_skipped_);
}
// static
void InputStreamReader::ContinueSkipCallback(
scoped_refptr<InputStreamReader> stream,
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner,
int callback_id,
int64_t bytes_skipped) {
// Always execute asynchronously.
work_thread_task_runner->PostTask(
FROM_HERE,
base::BindOnce(&InputStreamReader::ContinueSkipCallbackOnWorkThread,
stream, callback_id, bytes_skipped));
}
// static
void InputStreamReader::ContinueReadCallback(
scoped_refptr<InputStreamReader> stream,
scoped_refptr<base::SequencedTaskRunner> work_thread_task_runner,
int callback_id,
int bytes_read) {
// Always execute asynchronously.
work_thread_task_runner->PostTask(
FROM_HERE,
base::BindOnce(&InputStreamReader::ContinueReadCallbackOnWorkThread,
stream, callback_id, bytes_read));
}
void InputStreamReader::ContinueSkipCallbackOnWorkThread(
int callback_id,
int64_t bytes_skipped) {
DCHECK(work_thread_task_runner_->RunsTasksInCurrentSequence());
// Check for out of order callbacks.
if (pending_callback_id_ != callback_id)
return;
DCHECK_LE(bytes_skipped, bytes_to_skip_);
if (bytes_to_skip_ > 0 && bytes_skipped > 0)
bytes_to_skip_ -= bytes_skipped;
if (bytes_skipped <= 0) {
RunSkipCallback(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE);
} else if (bytes_to_skip_ > 0) {
// Continue execution asynchronously.
work_thread_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&InputStreamReader::SkipToRequestedRange, this));
} else {
// All done, the requested number of bytes were skipped.
RunSkipCallback(bytes_skipped_);
}
}
void InputStreamReader::ContinueReadCallbackOnWorkThread(int callback_id,
int bytes_read) {
DCHECK(work_thread_task_runner_->RunsTasksInCurrentSequence());
// Check for out of order callbacks.
if (pending_callback_id_ != callback_id)
return;
RunReadCallback(bytes_read);
}
void InputStreamReader::RunSkipCallback(int64_t bytes_skipped) {
DCHECK(work_thread_task_runner_->RunsTasksInCurrentSequence());
DCHECK(!pending_skip_callback_.is_null());
job_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(InputStreamReader::RunSkipCallbackOnJobThread, bytes_skipped,
base::Passed(std::move(pending_skip_callback_))));
// Reset callback state.
pending_callback_id_ = -1;
bytes_skipped_ = bytes_to_skip_ = -1;
}
void InputStreamReader::RunReadCallback(int bytes_read) {
DCHECK(work_thread_task_runner_->RunsTasksInCurrentSequence());
DCHECK(!pending_read_callback_.is_null());
job_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(InputStreamReader::RunReadCallbackOnJobThread, bytes_read,
base::Passed(std::move(pending_read_callback_))));
// Reset callback state.
pending_callback_id_ = -1;
buffer_ = nullptr;
}
// static
void InputStreamReader::RunSkipCallbackOnJobThread(
int64_t bytes_skipped,
InputStream::SkipCallback skip_callback) {
std::move(skip_callback).Run(bytes_skipped);
}
// static
void InputStreamReader::RunReadCallbackOnJobThread(
int bytes_read,
InputStream::ReadCallback read_callback) {
std::move(read_callback).Run(bytes_read);
}
//==============================
// RequestId
//==============================
std::string RequestId::ToString() const {
return base::StringPrintf("RequestId(%u, %u)", request_id_, routing_id_);
}
std::string RequestId::ToString(base::StringPiece debug_label) const {
return base::StringPrintf("RequestId[%s](%u, %u)",
debug_label.as_string().c_str(), request_id_,
routing_id_);
}
std::ostream& operator<<(std::ostream& out, const RequestId& request_id) {
return out << request_id.ToString();
}
//==============================
// StreamReaderURLLoader
//=============================
StreamReaderURLLoader::StreamReaderURLLoader(
const RequestId& request_id,
const network::ResourceRequest& request,
network::mojom::URLLoaderClientPtr client,
network::mojom::TrustedHeaderClientPtr header_client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
std::unique_ptr<Delegate> response_delegate)
: request_id_(request_id),
request_(request),
client_(std::move(client)),
header_client_(std::move(header_client)),
traffic_annotation_(traffic_annotation),
response_delegate_(std::move(response_delegate)),
writable_handle_watcher_(FROM_HERE,
mojo::SimpleWatcher::ArmingPolicy::MANUAL,
base::SequencedTaskRunnerHandle::Get()),
weak_factory_(this) {
DCHECK(response_delegate_);
// If there is a client error, clean up the request.
client_.set_connection_error_handler(
base::BindOnce(&StreamReaderURLLoader::RequestComplete,
weak_factory_.GetWeakPtr(), net::ERR_ABORTED));
// All InputStream work will be performed on this task runner.
stream_work_task_runner_ =
base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()});
}
StreamReaderURLLoader::~StreamReaderURLLoader() {}
void StreamReaderURLLoader::Start() {
DCHECK(thread_checker_.CalledOnValidThread());
if (!ParseRange(request_.headers)) {
RequestComplete(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE);
return;
}
if (header_client_.is_bound()) {
header_client_->OnBeforeSendHeaders(
request_.headers,
base::BindOnce(&StreamReaderURLLoader::ContinueWithRequestHeaders,
weak_factory_.GetWeakPtr()));
} else {
ContinueWithRequestHeaders(net::OK, base::nullopt);
}
}
void StreamReaderURLLoader::ContinueWithRequestHeaders(
int32_t result,
const base::Optional<net::HttpRequestHeaders>& headers) {
if (result != net::OK) {
RequestComplete(result);
return;
}
if (headers) {
DCHECK(header_client_.is_bound());
request_.headers = *headers;
}
OpenInputStreamWrapper::Open(
// This is intentional - the loader could be deleted while
// the callback is executing on the background thread. The
// delegate will be "returned" to the loader once the
// InputStream open attempt is completed.
std::move(response_delegate_), stream_work_task_runner_, request_id_,
request_,
base::BindOnce(&StreamReaderURLLoader::OnInputStreamOpened,
weak_factory_.GetWeakPtr()));
}
void StreamReaderURLLoader::FollowRedirect(
const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const base::Optional<GURL>& new_url) {
NOTREACHED();
}
void StreamReaderURLLoader::ProceedWithResponse() {}
void StreamReaderURLLoader::SetPriority(net::RequestPriority priority,
int intra_priority_value) {}
void StreamReaderURLLoader::PauseReadingBodyFromNet() {}
void StreamReaderURLLoader::ResumeReadingBodyFromNet() {}
void StreamReaderURLLoader::OnInputStreamOpened(
std::unique_ptr<StreamReaderURLLoader::Delegate> returned_delegate,
std::unique_ptr<InputStream> input_stream) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(returned_delegate);
response_delegate_ = std::move(returned_delegate);
if (!input_stream) {
bool restarted = false;
response_delegate_->OnInputStreamOpenFailed(request_id_, &restarted);
if (restarted) {
// The request has been restarted with a new loader.
// |this| will be deleted.
CleanUp();
} else {
HeadersComplete(net::HTTP_NOT_FOUND, -1);
}
return;
}
input_stream_reader_ = base::MakeRefCounted<InputStreamReader>(
std::move(input_stream), stream_work_task_runner_);
if (!byte_range_valid()) {
OnReaderSkipCompleted(0);
} else {
input_stream_reader_->Skip(
byte_range_.first_byte_position(),
base::BindOnce(&StreamReaderURLLoader::OnReaderSkipCompleted,
weak_factory_.GetWeakPtr()));
}
}
void StreamReaderURLLoader::OnReaderSkipCompleted(int64_t bytes_skipped) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!byte_range_valid()) {
// Expected content length is unspecified.
HeadersComplete(net::HTTP_OK, -1);
} else if (bytes_skipped == byte_range_.first_byte_position()) {
// We skipped the expected number of bytes.
int64_t expected_content_length = byte_range_.last_byte_position() -
byte_range_.first_byte_position() + 1;
DCHECK_GE(expected_content_length, 0);
HeadersComplete(net::HTTP_OK, expected_content_length);
} else {
RequestComplete(bytes_skipped < 0 ? bytes_skipped : net::ERR_FAILED);
}
}
void StreamReaderURLLoader::HeadersComplete(int orig_status_code,
int64_t expected_content_length) {
DCHECK(thread_checker_.CalledOnValidThread());
int status_code = orig_status_code;
std::string status_text =
net::GetHttpReasonPhrase(static_cast<net::HttpStatusCode>(status_code));
std::string mime_type, charset;
int64_t content_length = expected_content_length;
ResourceResponse::HeaderMap extra_headers;
response_delegate_->GetResponseHeaders(request_id_, &status_code,
&status_text, &mime_type, &charset,
&content_length, &extra_headers);
if (status_code < 0) {
// Early exit if the handler reported an error.
RequestComplete(status_code);
return;
}
pending_response_.request_start = base::TimeTicks::Now();
pending_response_.response_start = base::TimeTicks::Now();
pending_response_.headers = MakeResponseHeaders(
status_code, status_text, mime_type, charset, content_length,
extra_headers, false /* allow_existing_header_override */);
if (content_length >= 0)
pending_response_.content_length = content_length;
if (!mime_type.empty()) {
pending_response_.mime_type = mime_type;
if (!charset.empty())
pending_response_.charset = charset;
}
if (header_client_.is_bound()) {
header_client_->OnHeadersReceived(
pending_response_.headers->raw_headers(),
base::BindOnce(&StreamReaderURLLoader::ContinueWithResponseHeaders,
weak_factory_.GetWeakPtr()));
} else {
ContinueWithResponseHeaders(net::OK, base::nullopt, GURL());
}
}
void StreamReaderURLLoader::ContinueWithResponseHeaders(
int32_t result,
const base::Optional<std::string>& headers,
const GURL& redirect_url) {
if (result != net::OK) {
RequestComplete(result);
return;
}
if (headers) {
DCHECK(header_client_.is_bound());
pending_response_.headers =
base::MakeRefCounted<net::HttpResponseHeaders>(*headers);
}
// What the length would be if we sent headers over the network. Used to
// calculate data length.
header_length_ = pending_response_.headers->raw_headers().length();
DCHECK(client_.is_bound());
std::string location;
if (!redirect_url.is_empty() ||
pending_response_.headers->IsRedirect(&location)) {
pending_response_.encoded_data_length = header_length_;
pending_response_.content_length = pending_response_.encoded_body_length =
0;
const GURL new_location =
redirect_url.is_empty() ? request_.url.Resolve(location) : redirect_url;
client_->OnReceiveRedirect(
MakeRedirectInfo(request_, pending_response_.headers.get(),
new_location,
pending_response_.headers->response_code()),
pending_response_);
// The client will restart the request with a new loader.
// |this| will be deleted.
CleanUp();
} else {
client_->OnReceiveResponse(pending_response_);
}
}
void StreamReaderURLLoader::ContinueResponse(bool was_redirected) {
DCHECK(thread_checker_.CalledOnValidThread());
if (was_redirected) {
// Special case where we allow the client to perform the redirect.
// The client will restart the request with a new loader.
// |this| will be deleted.
CleanUp();
} else {
SendBody();
}
}
void StreamReaderURLLoader::SendBody() {
DCHECK(thread_checker_.CalledOnValidThread());
mojo::ScopedDataPipeConsumerHandle consumer_handle;
if (CreateDataPipe(nullptr /*options*/, &producer_handle_,
&consumer_handle) != MOJO_RESULT_OK) {
RequestComplete(net::ERR_FAILED);
return;
}
writable_handle_watcher_.Watch(
producer_handle_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
base::BindRepeating(&StreamReaderURLLoader::OnDataPipeWritable,
base::Unretained(this)));
client_->OnStartLoadingResponseBody(std::move(consumer_handle));
ReadMore();
}
void StreamReaderURLLoader::ReadMore() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!pending_buffer_.get());
uint32_t num_bytes;
MojoResult mojo_result = network::NetToMojoPendingBuffer::BeginWrite(
&producer_handle_, &pending_buffer_, &num_bytes);
if (mojo_result == MOJO_RESULT_SHOULD_WAIT) {
// The pipe is full. We need to wait for it to have more space.
writable_handle_watcher_.ArmOrNotify();
return;
} else if (mojo_result == MOJO_RESULT_FAILED_PRECONDITION) {
// The data pipe consumer handle has been closed.
RequestComplete(net::ERR_ABORTED);
return;
} else if (mojo_result != MOJO_RESULT_OK) {
// The body stream is in a bad state. Bail out.
RequestComplete(net::ERR_UNEXPECTED);
return;
}
scoped_refptr<net::IOBuffer> buffer(
new network::NetToMojoIOBuffer(pending_buffer_.get()));
if (!input_stream_reader_.get()) {
// This will happen if opening the InputStream fails in which case the
// error is communicated by setting the HTTP response status header rather
// than failing the request during the header fetch phase.
OnReaderReadCompleted(0);
return;
}
input_stream_reader_->Read(
buffer, base::checked_cast<int>(num_bytes),
base::BindOnce(&StreamReaderURLLoader::OnReaderReadCompleted,
weak_factory_.GetWeakPtr()));
}
void StreamReaderURLLoader::OnDataPipeWritable(MojoResult result) {
if (result == MOJO_RESULT_FAILED_PRECONDITION) {
RequestComplete(net::ERR_ABORTED);
return;
}
DCHECK_EQ(result, MOJO_RESULT_OK) << result;
ReadMore();
}
void StreamReaderURLLoader::OnReaderReadCompleted(int bytes_read) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(pending_buffer_);
if (bytes_read < 0) {
// Error case.
RequestComplete(bytes_read);
return;
}
if (bytes_read == 0) {
// Eof, read completed.
pending_buffer_->Complete(0);
RequestComplete(net::OK);
return;
}
producer_handle_ = pending_buffer_->Complete(bytes_read);
pending_buffer_ = nullptr;
client_->OnTransferSizeUpdated(bytes_read);
total_bytes_read_ += bytes_read;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&StreamReaderURLLoader::ReadMore,
weak_factory_.GetWeakPtr()));
}
void StreamReaderURLLoader::RequestComplete(int status_code) {
DCHECK(thread_checker_.CalledOnValidThread());
auto status = network::URLLoaderCompletionStatus(status_code);
status.completion_time = base::TimeTicks::Now();
status.encoded_data_length = total_bytes_read_ + header_length_;
status.encoded_body_length = total_bytes_read_;
// We don't support decoders, so use the same value.
status.decoded_body_length = total_bytes_read_;
client_->OnComplete(status);
CleanUp();
}
void StreamReaderURLLoader::CleanUp() {
DCHECK(thread_checker_.CalledOnValidThread());
// Resets the watchers and pipes, so that we will never be called back.
writable_handle_watcher_.Cancel();
pending_buffer_ = nullptr;
producer_handle_.reset();
// Manages its own lifetime.
delete this;
}
bool StreamReaderURLLoader::ParseRange(const net::HttpRequestHeaders& headers) {
DCHECK(thread_checker_.CalledOnValidThread());
std::string range_header;
if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) {
// This loader only cares about the Range header so that we know how many
// bytes in the stream to skip and how many to read after that.
std::vector<net::HttpByteRange> ranges;
if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) {
// In case of multi-range request only use the first range.
// We don't support multirange requests.
if (ranges.size() == 1)
byte_range_ = ranges[0];
} else {
// This happens if the range header could not be parsed or is invalid.
return false;
}
}
return true;
}
bool StreamReaderURLLoader::byte_range_valid() const {
return byte_range_.IsValid() && byte_range_.first_byte_position() >= 0;
}
} // namespace net_service

View File

@ -0,0 +1,235 @@
// Copyright (c) 2019 The Chromium Embedded Framework Authors. Portions
// Copyright (c) 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_BROWSER_NET_SERVICE_STREAM_READER_URL_LOADER_H_
#define CEF_LIBCEF_BROWSER_NET_SERVICE_STREAM_READER_URL_LOADER_H_
#include <map>
#include "base/callback.h"
#include "base/threading/thread_checker.h"
#include "mojo/public/cpp/system/simple_watcher.h"
#include "net/http/http_byte_range.h"
#include "services/network/public/cpp/net_adapters.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/url_loader.mojom.h"
namespace net_service {
class InputStreamReader;
// Abstract class representing an input stream. All methods are called in
// sequence on a worker thread, but not necessarily on the same thread.
class InputStream {
public:
virtual ~InputStream() {}
// 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 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE.
using SkipCallback = base::OnceCallback<void(int64_t /* bytes_skipped */)>;
// Skip over and discard |n| bytes of data from this input stream. If data
// is available immediately set |bytes_skipped| to the number of of bytes
// skipped and return true. To read the data at a later time set
// |bytes_skipped| to 0, return true and execute |callback| when the data is
// available. To indicate failure set |bytes_skipped| to < 0 (e.g.
// net::ERR_FAILED) and return false.
virtual bool Skip(int64_t n,
int64_t* bytes_skipped,
SkipCallback callback) = 0;
// 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.
using ReadCallback = base::OnceCallback<void(int /* bytes_read */)>;
// Read response data. If data is available immediately copy up to |length|
// bytes into |dest|, set |bytes_read| to the number of bytes copied, and
// return true. To read the data at a later time set |bytes_read| to 0, return
// true and execute |callback| when the data is available. To indicate
// response completion set |bytes_read| to 0 and return false. To indicate
// failure set |bytes_read| to < 0 (e.g. net::ERR_FAILED) and return false.
virtual bool Read(net::IOBuffer* dest,
int length,
int* bytes_read,
ReadCallback callback) = 0;
};
// Unique identifier for RequestHandler callbacks.
// Based on components/viz/common/surfaces/frame_sink_id.h
class RequestId {
public:
constexpr RequestId() : request_id_(0), routing_id_(0) {}
constexpr RequestId(const RequestId& other)
: request_id_(other.request_id_), routing_id_(other.routing_id_) {}
constexpr RequestId(uint32_t request_id, uint32_t routing_id)
: request_id_(request_id), routing_id_(routing_id) {}
constexpr bool is_valid() const {
return request_id_ != 0 || routing_id_ != 0;
}
constexpr uint32_t request_id() const { return request_id_; }
constexpr uint32_t routing_id() const { return routing_id_; }
bool operator==(const RequestId& other) const {
return request_id_ == other.request_id_ && routing_id_ == other.routing_id_;
}
bool operator!=(const RequestId& other) const { return !(*this == other); }
bool operator<(const RequestId& other) const {
return std::tie(request_id_, routing_id_) <
std::tie(other.request_id_, other.routing_id_);
}
size_t hash() const { return base::HashInts(request_id_, routing_id_); }
std::string ToString() const;
std::string ToString(base::StringPiece debug_label) const;
private:
uint32_t request_id_;
uint32_t routing_id_;
};
std::ostream& operator<<(std::ostream& out, const RequestId& request_id);
struct RequestIdHash {
size_t operator()(const RequestId& key) const { return key.hash(); }
};
// Abstract class for handling intercepted resource responses. All methods are
// called on the IO thread unless otherwise indicated.
class ResourceResponse {
public:
virtual ~ResourceResponse() {}
// Callback for asynchronous continuation of Open(). If the InputStream is
// null the request will be canceled.
using OpenCallback = base::OnceCallback<void(std::unique_ptr<InputStream>)>;
// This method is called on a worker thread. Return true and execute
// |callback| to continue the request. Return false to cancel the request.
// |request| may be different from the request used to create the
// StreamReaderURLLoader if a redirect was followed.
virtual bool OpenInputStream(const RequestId& id,
const network::ResourceRequest& request,
OpenCallback callback) = 0;
// This method is called to populate the response headers.
using HeaderMap = std::multimap<std::string, std::string>;
virtual void GetResponseHeaders(const RequestId& id,
int* status_code,
std::string* reason_phrase,
std::string* mime_type,
std::string* charset,
int64_t* content_length,
HeaderMap* extra_headers) = 0;
};
// Custom URLLoader implementation for loading network responses from stream.
// Methods are called on the IO thread unless otherwise indicated.
// Based on android_webview/browser/network_service/
// android_stream_reader_url_loader.h
class StreamReaderURLLoader : public network::mojom::URLLoader {
public:
// Delegate abstraction for obtaining input streams. All methods are called
// on the IO thread unless otherwise indicated.
class Delegate : public ResourceResponse {
public:
// This method is called if the result of calling OpenInputStream was null.
// The |restarted| parameter is set to true if the request was restarted
// with a new loader.
virtual void OnInputStreamOpenFailed(const RequestId& id,
bool* restarted) = 0;
};
StreamReaderURLLoader(
const RequestId& request_id,
const network::ResourceRequest& request,
network::mojom::URLLoaderClientPtr client,
network::mojom::TrustedHeaderClientPtr header_client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
std::unique_ptr<Delegate> response_delegate);
~StreamReaderURLLoader() override;
void Start();
void ContinueResponse(bool was_redirected);
// network::mojom::URLLoader methods:
void FollowRedirect(const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const base::Optional<GURL>& new_url) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
int intra_priority_value) override;
void PauseReadingBodyFromNet() override;
void ResumeReadingBodyFromNet() override;
private:
void ContinueWithRequestHeaders(
int32_t result,
const base::Optional<net::HttpRequestHeaders>& headers);
void OnInputStreamOpened(std::unique_ptr<Delegate> returned_delegate,
std::unique_ptr<InputStream> input_stream);
void OnReaderSkipCompleted(int64_t bytes_skipped);
void HeadersComplete(int status_code, int64_t expected_content_length);
void ContinueWithResponseHeaders(int32_t result,
const base::Optional<std::string>& headers,
const GURL& redirect_url);
void SendBody();
void ReadMore();
void OnDataPipeWritable(MojoResult result);
void OnReaderReadCompleted(int bytes_read);
void RequestComplete(int status_code);
void CleanUp();
bool ParseRange(const net::HttpRequestHeaders& headers);
bool byte_range_valid() const;
const RequestId request_id_;
network::ResourceResponseHead pending_response_;
size_t header_length_ = 0;
int64_t total_bytes_read_ = 0;
net::HttpByteRange byte_range_;
network::ResourceRequest request_;
network::mojom::URLLoaderClientPtr client_;
network::mojom::TrustedHeaderClientPtr header_client_;
const net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
std::unique_ptr<Delegate> response_delegate_;
scoped_refptr<InputStreamReader> input_stream_reader_;
mojo::ScopedDataPipeProducerHandle producer_handle_;
scoped_refptr<network::NetToMojoPendingBuffer> pending_buffer_;
mojo::SimpleWatcher writable_handle_watcher_;
base::ThreadChecker thread_checker_;
scoped_refptr<base::SequencedTaskRunner> stream_work_task_runner_;
base::WeakPtrFactory<StreamReaderURLLoader> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(StreamReaderURLLoader);
};
} // namespace net_service
#endif // CEF_LIBCEF_BROWSER_NET_SERVICE_STREAM_READER_URL_LOADER_H_

View File

@ -144,10 +144,6 @@ bool CefBrowserPlatformDelegateOsr::HandleKeyboardEvent(
return native_delegate_->HandleKeyboardEvent(event);
}
void CefBrowserPlatformDelegateOsr::HandleExternalProtocol(const GURL& url) {
native_delegate_->HandleExternalProtocol(url);
}
void CefBrowserPlatformDelegateOsr::TranslateKeyEvent(
content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) const {

View File

@ -41,7 +41,6 @@ class CefBrowserPlatformDelegateOsr
void ViewText(const std::string& text) override;
bool HandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) override;
void HandleExternalProtocol(const GURL& url) override;
void TranslateKeyEvent(content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) const override;
void TranslateClickEvent(blink::WebMouseEvent& result,

View File

@ -96,8 +96,8 @@ bool CefPluginServiceFilter::IsPluginAvailable(
// The |render_frame_id| value may not be valid, so allow matches with any
// handler that shares the same |render_process_id| value.
CefRefPtr<CefRequestContextHandler> handler =
resource_context->GetHandler(render_process_id, render_frame_id, false);
CefRefPtr<CefRequestContextHandler> handler = resource_context->GetHandler(
render_process_id, render_frame_id, -1, false);
if (!handler) {
// No handler so go with the default plugin load decision.
return *status != chrome::mojom::PluginStatus::kDisabled;

View File

@ -300,26 +300,53 @@ bool CefRequestContextImpl::RegisterSchemeHandlerFactory(
const CefString& scheme_name,
const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) {
if (net_service::IsEnabled()) {
NOTIMPLEMENTED();
return false;
if (!net_service::IsEnabled()) {
GetRequestContextImpl(
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
base::Bind(&CefRequestContextImpl::RegisterSchemeHandlerFactoryInternal,
this, scheme_name, domain_name, factory));
return true;
}
GetRequestContextImpl(
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
base::Bind(&CefRequestContextImpl::RegisterSchemeHandlerFactoryInternal,
this, scheme_name, domain_name, factory));
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(
base::IgnoreResult(
&CefRequestContextImpl::RegisterSchemeHandlerFactory),
this, scheme_name, domain_name, factory));
return true;
}
// Make sure the browser context exists.
EnsureBrowserContext();
browser_context()->RegisterSchemeHandlerFactory(scheme_name, domain_name,
factory);
return true;
}
bool CefRequestContextImpl::ClearSchemeHandlerFactories() {
if (net_service::IsEnabled()) {
NOTIMPLEMENTED();
return false;
if (!net_service::IsEnabled()) {
GetRequestContextImpl(
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
base::Bind(&CefRequestContextImpl::ClearSchemeHandlerFactoriesInternal,
this));
return true;
}
GetRequestContextImpl(
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
base::Bind(&CefRequestContextImpl::ClearSchemeHandlerFactoriesInternal,
this));
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(base::IgnoreResult(
&CefRequestContextImpl::ClearSchemeHandlerFactories),
this));
return true;
}
// Make sure the browser context exists.
EnsureBrowserContext();
browser_context()->ClearSchemeHandlerFactories();
return true;
}
@ -555,18 +582,22 @@ CefRefPtr<CefExtension> CefRequestContextImpl::GetExtension(
void CefRequestContextImpl::OnRenderFrameCreated(int render_process_id,
int render_frame_id,
int frame_tree_node_id,
bool is_main_frame,
bool is_guest_view) {
browser_context_->OnRenderFrameCreated(
this, render_process_id, render_frame_id, is_main_frame, is_guest_view);
browser_context_->OnRenderFrameCreated(this, render_process_id,
render_frame_id, frame_tree_node_id,
is_main_frame, is_guest_view);
}
void CefRequestContextImpl::OnRenderFrameDeleted(int render_process_id,
int render_frame_id,
int frame_tree_node_id,
bool is_main_frame,
bool is_guest_view) {
browser_context_->OnRenderFrameDeleted(
this, render_process_id, render_frame_id, is_main_frame, is_guest_view);
browser_context_->OnRenderFrameDeleted(this, render_process_id,
render_frame_id, frame_tree_node_id,
is_main_frame, is_guest_view);
}
// static

View File

@ -91,6 +91,7 @@ class CefRequestContextImpl : public CefRequestContext {
// created.
void OnRenderFrameCreated(int render_process_id,
int render_frame_id,
int frame_tree_node_id,
bool is_main_frame,
bool is_guest_view);
@ -99,6 +100,7 @@ class CefRequestContextImpl : public CefRequestContext {
// deleted.
void OnRenderFrameDeleted(int render_process_id,
int render_frame_id,
int frame_tree_node_id,
bool is_main_frame,
bool is_guest_view);

View File

@ -6,8 +6,13 @@
#include "libcef/browser/net/url_request_context_getter.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net/scheme_registration.h"
#include "base/i18n/case_conversion.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/resource_context_impl.h"
#include "content/public/browser/browser_thread.h"
@ -26,7 +31,14 @@
CefResourceContext::CefResourceContext(bool is_off_the_record)
: is_off_the_record_(is_off_the_record) {}
CefResourceContext::~CefResourceContext() {}
CefResourceContext::~CefResourceContext() {
// This is normally called in the parent ResourceContext destructor, but we
// want to call it here so that this CefResourceContext object is still
// valid when CefNetworkDelegate::OnCompleted is called via the URLRequest
// destructor.
if (content::ResourceDispatcherHostImpl::Get())
content::ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(this);
}
std::unique_ptr<net::ClientCertStore>
CefResourceContext::CreateClientCertStore() {
@ -56,41 +68,60 @@ void CefResourceContext::set_extensions_info_map(
void CefResourceContext::AddHandler(
int render_process_id,
int render_frame_id,
int frame_tree_node_id,
CefRefPtr<CefRequestContextHandler> handler) {
CEF_REQUIRE_IOT();
DCHECK_GE(render_process_id, 0);
DCHECK_GE(render_frame_id, 0);
DCHECK_GE(frame_tree_node_id, 0);
DCHECK(handler);
handler_map_.insert(std::make_pair(
render_id_handler_map_.insert(std::make_pair(
std::make_pair(render_process_id, render_frame_id), handler));
node_id_handler_map_.insert(std::make_pair(frame_tree_node_id, handler));
}
void CefResourceContext::RemoveHandler(int render_process_id,
int render_frame_id) {
int render_frame_id,
int frame_tree_node_id) {
CEF_REQUIRE_IOT();
DCHECK_GE(render_process_id, 0);
DCHECK_GE(render_frame_id, 0);
DCHECK_GE(frame_tree_node_id, 0);
HandlerMap::iterator it =
handler_map_.find(std::make_pair(render_process_id, render_frame_id));
if (it != handler_map_.end())
handler_map_.erase(it);
auto it1 = render_id_handler_map_.find(
std::make_pair(render_process_id, render_frame_id));
if (it1 != render_id_handler_map_.end())
render_id_handler_map_.erase(it1);
auto it2 = node_id_handler_map_.find(frame_tree_node_id);
if (it2 != node_id_handler_map_.end())
node_id_handler_map_.erase(it2);
}
CefRefPtr<CefRequestContextHandler> CefResourceContext::GetHandler(
int render_process_id,
int render_frame_id,
int frame_tree_node_id,
bool require_frame_match) {
CEF_REQUIRE_IOT();
DCHECK_GE(render_process_id, 0);
HandlerMap::const_iterator it =
handler_map_.find(std::make_pair(render_process_id, render_frame_id));
if (it != handler_map_.end())
return it->second;
if (render_process_id >= 0 && render_frame_id >= 0) {
const auto it1 = render_id_handler_map_.find(
std::make_pair(render_process_id, render_frame_id));
if (it1 != render_id_handler_map_.end())
return it1->second;
}
if (!require_frame_match) {
if (frame_tree_node_id >= 0) {
const auto it2 = node_id_handler_map_.find(frame_tree_node_id);
if (it2 != node_id_handler_map_.end())
return it2->second;
}
if (render_process_id >= 0 && !require_frame_match) {
// Choose an arbitrary handler for the same process.
for (auto& kv : handler_map_) {
for (auto& kv : render_id_handler_map_) {
if (kv.first.first == render_process_id)
return kv.second;
}
@ -150,3 +181,68 @@ void CefResourceContext::ClearPluginLoadDecision(int render_process_id) {
}
}
}
void CefResourceContext::RegisterSchemeHandlerFactory(
const std::string& scheme_name,
const std::string& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) {
CEF_REQUIRE_IOT();
const std::string& scheme_lower = base::ToLowerASCII(scheme_name);
std::string domain_lower;
// Hostname is only supported for standard schemes.
if (scheme::IsStandardScheme(scheme_lower)) {
// Hostname might contain Unicode characters.
domain_lower =
base::UTF16ToUTF8(base::i18n::ToLower(base::UTF8ToUTF16(domain_name)));
}
const auto key = std::make_pair(scheme_lower, domain_lower);
if (factory) {
// Add or replace the factory.
scheme_handler_factory_map_[key] = factory;
} else {
// Remove the existing factory, if any.
auto it = scheme_handler_factory_map_.find(key);
if (it != scheme_handler_factory_map_.end())
scheme_handler_factory_map_.erase(it);
}
}
void CefResourceContext::ClearSchemeHandlerFactories() {
CEF_REQUIRE_IOT();
scheme_handler_factory_map_.clear();
}
CefRefPtr<CefSchemeHandlerFactory> CefResourceContext::GetSchemeHandlerFactory(
const GURL& url) {
CEF_REQUIRE_IOT();
if (scheme_handler_factory_map_.empty())
return nullptr;
const std::string& scheme_lower = url.scheme();
const std::string& domain_lower =
url.IsStandard() ? url.host() : std::string();
if (!domain_lower.empty()) {
// Sanity check.
DCHECK(scheme::IsStandardScheme(scheme_lower)) << scheme_lower;
// Try for a match with hostname first.
const auto it = scheme_handler_factory_map_.find(
std::make_pair(scheme_lower, domain_lower));
if (it != scheme_handler_factory_map_.end())
return it->second;
}
// Try for a match with no specified hostname.
const auto it = scheme_handler_factory_map_.find(
std::make_pair(scheme_lower, std::string()));
if (it != scheme_handler_factory_map_.end())
return it->second;
return nullptr;
}

View File

@ -41,10 +41,20 @@ class CefResourceContext : public content::ResourceContext {
// CefRequestContextImpl and CefBrowserContext.
void AddHandler(int render_process_id,
int render_frame_id,
int frame_tree_node_id,
CefRefPtr<CefRequestContextHandler> handler);
void RemoveHandler(int render_process_id, int render_frame_id);
void RemoveHandler(int render_process_id,
int render_frame_id,
int frame_tree_node_id);
// Returns the handler that matches the specified IDs. Pass -1 for unknown
// values. If |require_frame_match| is true only exact matches will be
// returned. If |require_frame_match| is false, and there is not an exact
// match, then the first handler for the same |render_process_id| will be
// returned.
CefRefPtr<CefRequestContextHandler> GetHandler(int render_process_id,
int render_frame_id,
int frame_tree_node_id,
bool require_frame_match);
// Remember the plugin load decision for plugin status requests that arrive
@ -64,6 +74,13 @@ class CefResourceContext : public content::ResourceContext {
// plugin load decisions if |render_process_id| is -1.
void ClearPluginLoadDecision(int render_process_id);
// Manage scheme handler factories associated with this context.
void RegisterSchemeHandlerFactory(const std::string& scheme_name,
const std::string& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory);
void ClearSchemeHandlerFactories();
CefRefPtr<CefSchemeHandlerFactory> GetSchemeHandlerFactory(const GURL& url);
// State transferred from the BrowserContext for use on the IO thread.
bool IsOffTheRecord() const { return is_off_the_record_; }
const extensions::InfoMap* GetExtensionInfoMap() const {
@ -77,8 +94,15 @@ class CefResourceContext : public content::ResourceContext {
// Map of (render_process_id, render_frame_id) to handler.
typedef std::map<std::pair<int, int>, CefRefPtr<CefRequestContextHandler>>
HandlerMap;
HandlerMap handler_map_;
RenderIdHandlerMap;
RenderIdHandlerMap render_id_handler_map_;
// Map of frame_tree_node_id to handler. Keeping this map is necessary
// because, when navigating the main frame, a new (pre-commit) URLRequest
// will be created before the RenderFrameHost. Consequently we can't rely
// on valid render IDs. See https://crbug.com/776884 for background.
typedef std::map<int, CefRefPtr<CefRequestContextHandler>> NodeIdHandlerMap;
NodeIdHandlerMap node_id_handler_map_;
// Map (render_process_id, plugin_path, is_main_frame, main_frame_origin) to
// plugin load decision.
@ -88,6 +112,12 @@ class CefResourceContext : public content::ResourceContext {
PluginLoadDecisionMap;
PluginLoadDecisionMap plugin_load_decision_map_;
// Map (scheme, domain) to factories.
typedef std::map<std::pair<std::string, std::string>,
CefRefPtr<CefSchemeHandlerFactory>>
SchemeHandlerFactoryMap;
SchemeHandlerFactoryMap scheme_handler_factory_map_;
DISALLOW_COPY_AND_ASSIGN(CefResourceContext);
};

View File

@ -33,11 +33,6 @@ class CefResourceDispatcherHostDelegate
network::ResourceResponse* response) override;
private:
void HandleExternalProtocolOnUIThread(
const GURL& url,
const content::ResourceRequestInfo::WebContentsGetter&
web_contents_getter);
struct StreamTargetInfo {
std::string extension_id;
std::string view_id;

View File

@ -234,10 +234,6 @@ bool CefBrowserPlatformDelegateViews::HandleKeyboardEvent(
return browser_view_->HandleKeyboardEvent(event);
}
void CefBrowserPlatformDelegateViews::HandleExternalProtocol(const GURL& url) {
native_delegate_->HandleExternalProtocol(url);
}
void CefBrowserPlatformDelegateViews::TranslateKeyEvent(
content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) const {

View File

@ -54,7 +54,6 @@ class CefBrowserPlatformDelegateViews
void ViewText(const std::string& text) override;
bool HandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) override;
void HandleExternalProtocol(const GURL& url) override;
void TranslateKeyEvent(content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) const override;
void TranslateClickEvent(blink::WebMouseEvent& result,

View File

@ -10,6 +10,7 @@
#include "extensions/common/constants.h"
#include "net/net_buildflags.h"
#include "url/url_constants.h"
#include "url/url_util.h"
namespace scheme {
@ -50,16 +51,22 @@ void AddInternalSchemes(content::ContentClient::Schemes* schemes) {
bool IsInternalHandledScheme(const std::string& scheme) {
static const char* schemes[] = {
url::kAboutScheme,
url::kBlobScheme,
content::kChromeDevToolsScheme,
content::kChromeUIScheme,
extensions::kExtensionScheme,
url::kDataScheme,
extensions::kExtensionScheme,
url::kFileScheme,
url::kFileSystemScheme,
#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
url::kFtpScheme,
#endif
url::kHttpScheme,
url::kHttpsScheme,
url::kJavaScriptScheme,
url::kWsScheme,
url::kWssScheme,
};
for (size_t i = 0; i < sizeof(schemes) / sizeof(schemes[0]); ++i) {
@ -77,13 +84,14 @@ bool IsInternalProtectedScheme(const std::string& scheme) {
static const char* schemes[] = {
url::kBlobScheme,
content::kChromeUIScheme,
extensions::kExtensionScheme,
url::kDataScheme,
extensions::kExtensionScheme,
url::kFileScheme,
url::kFileSystemScheme,
#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
url::kFtpScheme,
#endif
url::kJavaScriptScheme,
};
for (size_t i = 0; i < sizeof(schemes) / sizeof(schemes[0]); ++i) {
@ -94,4 +102,9 @@ bool IsInternalProtectedScheme(const std::string& scheme) {
return false;
}
bool IsStandardScheme(const std::string& scheme) {
url::Component scheme_comp(0, scheme.length());
return url::IsStandard(scheme.c_str(), scheme_comp);
}
} // namespace scheme

View File

@ -26,6 +26,9 @@ bool IsInternalHandledScheme(const std::string& scheme);
// always be a lower-case string.
bool IsInternalProtectedScheme(const std::string& scheme);
// Returns true if the specified |scheme| is a registered standard scheme.
bool IsStandardScheme(const std::string& scheme);
} // namespace scheme
#endif // CEF_LIBCEF_COMMON_NET_SCHEME_REGISTRATION_H_

View File

@ -0,0 +1,229 @@
// Copyright (c) 2019 The Chromium Embedded Framework Authors. Portions
// Copyright (c) 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/common/net_service/net_service_util.h"
#include "libcef/common/time_util.h"
#include <set>
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_util.h"
#include "net/cookies/parsed_cookie.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/redirect_util.h"
#include "net/url_request/url_request.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/resource_response.h"
namespace net_service {
namespace {
// Determine the cookie domain to use for setting the specified cookie.
// From net/cookies/cookie_store.cc.
bool GetCookieDomain(const GURL& url,
const net::ParsedCookie& pc,
std::string* result) {
std::string domain_string;
if (pc.HasDomain())
domain_string = pc.Domain();
return net::cookie_util::GetCookieDomainWithString(url, domain_string,
result);
}
} // namespace
const char kHTTPLocationHeaderName[] = "Location";
const char kHTTPSetCookieHeaderName[] = "Set-Cookie";
const char kHTTPHeaderSep[] = ": ";
std::string MakeHeader(const std::string& name, const std::string& value) {
std::string header(name);
header.append(kHTTPHeaderSep);
header.append(value);
return header;
}
std::string MakeStatusLine(int status_code,
const std::string& status_text,
bool for_replacement) {
std::string status("HTTP/1.1 ");
status.append(base::NumberToString(status_code));
status.append(" ");
if (status_text.empty()) {
const std::string& text =
net::GetHttpReasonPhrase(static_cast<net::HttpStatusCode>(status_code));
DCHECK(!text.empty());
status.append(text);
} else {
status.append(status_text);
}
if (!for_replacement) {
// The HttpResponseHeaders constructor expects its input string to be
// terminated by two NULs.
status.append("\0\0", 2);
}
return status;
}
std::string MakeContentTypeValue(const std::string& mime_type,
const std::string& charset) {
DCHECK(!mime_type.empty());
std::string value = mime_type;
if (!charset.empty()) {
value.append("; charset=");
value.append(charset);
}
return value;
}
net::HttpResponseHeaders* MakeResponseHeaders(
int status_code,
const std::string& status_text,
const std::string& mime_type,
const std::string& charset,
int64_t content_length,
const std::multimap<std::string, std::string>& extra_headers,
bool allow_existing_header_override) {
if (status_code <= 0)
status_code = 200;
auto headers = new net::HttpResponseHeaders(
MakeStatusLine(status_code, status_text, false));
// Track the headers that have already been set. Perform all comparisons in
// lowercase.
std::set<std::string> set_headers_lowercase;
if (status_code == net::HTTP_OK) {
if (!mime_type.empty()) {
headers->AddHeader(MakeHeader(net::HttpRequestHeaders::kContentType,
MakeContentTypeValue(mime_type, charset)));
set_headers_lowercase.insert(
base::ToLowerASCII(net::HttpRequestHeaders::kContentType));
}
if (content_length >= 0) {
headers->AddHeader(MakeHeader(net::HttpRequestHeaders::kContentLength,
base::NumberToString(content_length)));
set_headers_lowercase.insert(
base::ToLowerASCII(net::HttpRequestHeaders::kContentLength));
}
}
for (const auto& pair : extra_headers) {
if (!set_headers_lowercase.empty()) {
// Check if the header has already been set.
const std::string& name_lowercase = base::ToLowerASCII(pair.first);
if (set_headers_lowercase.find(name_lowercase) !=
set_headers_lowercase.end()) {
if (allow_existing_header_override)
headers->RemoveHeader(pair.first);
else
continue;
}
}
headers->AddHeader(MakeHeader(pair.first, pair.second));
}
return headers;
}
net::RedirectInfo MakeRedirectInfo(const network::ResourceRequest& request,
const net::HttpResponseHeaders* headers,
const GURL& new_location,
int status_code) {
bool insecure_scheme_was_upgraded = false;
GURL location = new_location;
if (status_code == 0)
status_code = net::HTTP_TEMPORARY_REDIRECT;
// If this a redirect to HTTP of a request that had the
// 'upgrade-insecure-requests' policy set, upgrade it to HTTPS.
if (request.upgrade_if_insecure) {
if (location.SchemeIs("http")) {
insecure_scheme_was_upgraded = true;
GURL::Replacements replacements;
replacements.SetSchemeStr("https");
location = location.ReplaceComponents(replacements);
}
}
net::URLRequest::FirstPartyURLPolicy first_party_url_policy =
request.update_first_party_url_on_redirect
? net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT
: net::URLRequest::NEVER_CHANGE_FIRST_PARTY_URL;
return net::RedirectInfo::ComputeRedirectInfo(
request.method, request.url, request.site_for_cookies,
request.top_frame_origin, first_party_url_policy, request.referrer_policy,
request.referrer.spec(), status_code, location,
net::RedirectUtil::GetReferrerPolicyHeader(headers),
insecure_scheme_was_upgraded);
}
bool MakeCefCookie(const net::CanonicalCookie& cc, CefCookie& cookie) {
CefString(&cookie.name).FromString(cc.Name());
CefString(&cookie.value).FromString(cc.Value());
CefString(&cookie.domain).FromString(cc.Domain());
CefString(&cookie.path).FromString(cc.Path());
cookie.secure = cc.IsSecure();
cookie.httponly = cc.IsHttpOnly();
cef_time_from_basetime(cc.CreationDate(), cookie.creation);
cef_time_from_basetime(cc.LastAccessDate(), cookie.last_access);
cookie.has_expires = cc.IsPersistent();
if (cookie.has_expires)
cef_time_from_basetime(cc.ExpiryDate(), cookie.expires);
return true;
}
bool MakeCefCookie(const GURL& url,
const std::string& cookie_line,
CefCookie& cookie) {
// Parse the cookie.
net::ParsedCookie pc(cookie_line);
if (!pc.IsValid())
return false;
std::string cookie_domain;
if (!GetCookieDomain(url, pc, &cookie_domain))
return false;
std::string path_string;
if (pc.HasPath())
path_string = pc.Path();
std::string cookie_path =
net::CanonicalCookie::CanonPathWithString(url, path_string);
base::Time creation_time = base::Time::Now();
base::Time cookie_expires =
net::CanonicalCookie::CanonExpiration(pc, creation_time, creation_time);
CefString(&cookie.name).FromString(pc.Name());
CefString(&cookie.value).FromString(pc.Value());
CefString(&cookie.domain).FromString(cookie_domain);
CefString(&cookie.path).FromString(cookie_path);
cookie.secure = pc.IsSecure();
cookie.httponly = pc.IsHttpOnly();
cef_time_from_basetime(creation_time, cookie.creation);
cef_time_from_basetime(creation_time, cookie.last_access);
cookie.has_expires = !cookie_expires.is_null();
if (cookie.has_expires)
cef_time_from_basetime(cookie_expires, cookie.expires);
return true;
}
} // namespace net_service

View File

@ -0,0 +1,71 @@
// 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_COMMON_NET_SERVICE_NET_SERVICE_UTIL_H_
#define CEF_LIBCEF_COMMON_NET_SERVICE_NET_SERVICE_UTIL_H_
#include <map>
#include <string>
#include "include/internal/cef_types_wrappers.h"
namespace net {
class CanonicalCookie;
class HttpResponseHeaders;
struct RedirectInfo;
} // namespace net
namespace network {
struct ResourceRequest;
struct ResourceResponseHead;
} // namespace network
class GURL;
namespace net_service {
// HTTP header names.
extern const char kHTTPLocationHeaderName[];
extern const char kHTTPSetCookieHeaderName[];
// Make a header name/value pair.
std::string MakeHeader(const std::string& name, const std::string& value);
// Make an HTTP response status line.
// Set |for_replacement| to true if the result will be passed to
// HttpResponseHeaders::ReplaceStatusLine and false if the result will
// be passed to the HttpResponseHeaders constructor.
std::string MakeStatusLine(int status_code,
const std::string& status_text,
bool for_replacement);
// Make an HTTP Content-Type response header value.
std::string MakeContentTypeValue(const std::string& mime_type,
const std::string& charset);
// Make a new HttpResponseHeaders object.
net::HttpResponseHeaders* MakeResponseHeaders(
int status_code,
const std::string& status_text,
const std::string& mime_type,
const std::string& charset,
int64_t content_length,
const std::multimap<std::string, std::string>& extra_headers,
bool allow_existing_header_override);
// Make a RedirectInfo structure.
net::RedirectInfo MakeRedirectInfo(const network::ResourceRequest& request,
const net::HttpResponseHeaders* headers,
const GURL& new_location,
int status_code);
// Populate |cookie|. Returns true on success.
bool MakeCefCookie(const net::CanonicalCookie& cc, CefCookie& cookie);
bool MakeCefCookie(const GURL& url,
const std::string& cookie_line,
CefCookie& cookie);
} // namespace net_service
#endif // CEF_LIBCEF_COMMON_NET_SERVICE_NET_SERVICE_UTIL_H_

View File

@ -32,9 +32,13 @@
#include "net/base/upload_file_element_reader.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_util.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request.h"
#include "services/network/public/cpp/data_element.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
@ -110,6 +114,10 @@ std::string GetURLRequestReferrer(const GURL& referrer_url) {
return referrer_url.spec();
}
void MakeASCIILower(std::string* str) {
std::transform(str->begin(), str->end(), str->begin(), ::tolower);
}
// Returns the cef_urlrequest_flags_t policy specified by the Cache-Control
// request header directives, if any. The directives are case-insensitive and
// some have an optional argument. Multiple directives are comma-separated.
@ -133,7 +141,7 @@ int GetCacheControlHeaderPolicy(CefRequest::HeaderMap headerMap) {
int flags = 0;
if (!line.empty()) {
std::transform(line.begin(), line.end(), line.begin(), ::tolower);
MakeASCIILower(&line);
std::vector<base::StringPiece> pieces = base::SplitStringPiece(
line, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
@ -224,6 +232,18 @@ void SetHeaderMap(const CefRequest::HeaderMap& map,
}
}
// Finds the first instance of |nameLower| (already lower-case) in |map| with
// case-insensitive comparison.
CefRequest::HeaderMap::iterator FindHeaderInMap(const std::string& nameLower,
CefRequest::HeaderMap& map) {
for (auto it = map.begin(); it != map.end(); ++it) {
if (base::EqualsCaseInsensitiveASCII(it->first.ToString(), nameLower))
return it;
}
return map.end();
}
// Type used in UploadDataStream.
typedef std::vector<std::unique_ptr<net::UploadElementReader>>
UploadElementReaders;
@ -255,7 +275,7 @@ CefRefPtr<CefRequest> CefRequest::Create() {
// CefRequestImpl -------------------------------------------------------------
CefRequestImpl::CefRequestImpl() : read_only_(false), track_changes_(false) {
CefRequestImpl::CefRequestImpl() {
// Verify that our enum matches Chromium's values.
static_assert(static_cast<int>(REFERRER_POLICY_LAST_VALUE) ==
static_cast<int>(net::URLRequest::MAX_REFERRER_POLICY),
@ -280,8 +300,8 @@ void CefRequestImpl::SetURL(const CefString& url) {
CHECK_READONLY_RETURN_VOID();
const GURL& new_url = GURL(url.ToString());
if (url_ != new_url) {
url_ = new_url;
Changed(kChangedUrl);
url_ = new_url;
}
}
@ -295,8 +315,8 @@ void CefRequestImpl::SetMethod(const CefString& method) {
CHECK_READONLY_RETURN_VOID();
const std::string& new_method = method;
if (method_ != new_method) {
method_ = new_method;
Changed(kChangedMethod);
method_ = new_method;
}
}
@ -309,9 +329,9 @@ void CefRequestImpl::SetReferrer(const CefString& referrer_url,
// applied by URLRequest::SetReferrer().
const GURL& new_referrer_url = GURL(referrer_url.ToString()).GetAsReferrer();
if (referrer_url_ != new_referrer_url || referrer_policy_ != policy) {
Changed(kChangedReferrer);
referrer_url_ = new_referrer_url;
referrer_policy_ = policy;
Changed(kChangedReferrer);
}
}
@ -333,8 +353,8 @@ CefRefPtr<CefPostData> CefRequestImpl::GetPostData() {
void CefRequestImpl::SetPostData(CefRefPtr<CefPostData> postData) {
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
postdata_ = postData;
Changed(kChangedPostData);
postdata_ = postData;
}
void CefRequestImpl::GetHeaderMap(HeaderMap& headerMap) {
@ -345,8 +365,50 @@ void CefRequestImpl::GetHeaderMap(HeaderMap& headerMap) {
void CefRequestImpl::SetHeaderMap(const HeaderMap& headerMap) {
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
::GetHeaderMap(headerMap, headermap_);
Changed(kChangedHeaderMap);
::GetHeaderMap(headerMap, headermap_);
}
CefString CefRequestImpl::GetHeaderByName(const CefString& name) {
base::AutoLock lock_scope(lock_);
std::string nameLower = name;
MakeASCIILower(&nameLower);
auto it = FindHeaderInMap(nameLower, headermap_);
if (it != headermap_.end())
return it->second;
return CefString();
}
void CefRequestImpl::SetHeaderByName(const CefString& name,
const CefString& value,
bool overwrite) {
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
std::string nameLower = name;
MakeASCIILower(&nameLower);
// Do not include Referer in the header map.
if (nameLower == kReferrerLowerCase)
return;
Changed(kChangedHeaderMap);
// There may be multiple values, so remove any first.
for (auto it = headermap_.begin(); it != headermap_.end();) {
if (base::EqualsCaseInsensitiveASCII(it->first.ToString(), nameLower)) {
if (!overwrite)
return;
it = headermap_.erase(it);
} else {
++it;
}
}
headermap_.insert(std::make_pair(name, value));
}
void CefRequestImpl::Set(const CefString& url,
@ -357,17 +419,20 @@ void CefRequestImpl::Set(const CefString& url,
CHECK_READONLY_RETURN_VOID();
const GURL& new_url = GURL(url.ToString());
if (url_ != new_url) {
url_ = new_url;
Changed(kChangedUrl);
url_ = new_url;
}
const std::string& new_method = method;
if (method_ != new_method) {
method_ = new_method;
Changed(kChangedMethod);
method_ = new_method;
}
postdata_ = postData;
if (postdata_ != postData) {
Changed(kChangedPostData);
postdata_ = postData;
}
Changed(kChangedHeaderMap);
::GetHeaderMap(headerMap, headermap_);
Changed(kChangedPostData | kChangedHeaderMap);
}
int CefRequestImpl::GetFlags() {
@ -379,23 +444,23 @@ void CefRequestImpl::SetFlags(int flags) {
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
if (flags_ != flags) {
flags_ = flags;
Changed(kChangedFlags);
flags_ = flags;
}
}
CefString CefRequestImpl::GetFirstPartyForCookies() {
base::AutoLock lock_scope(lock_);
return site_for_cookies_.spec();
return first_party_for_cookies_.spec();
}
void CefRequestImpl::SetFirstPartyForCookies(const CefString& url) {
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
const GURL& new_url = GURL(url.ToString());
if (site_for_cookies_ != new_url) {
site_for_cookies_ = new_url;
if (first_party_for_cookies_ != new_url) {
Changed(kChangedFirstPartyForCookies);
first_party_for_cookies_ = new_url;
}
}
@ -414,6 +479,97 @@ uint64 CefRequestImpl::GetIdentifier() {
return identifier_;
}
void CefRequestImpl::Set(const network::ResourceRequest* request,
uint64 identifier) {
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
Reset();
url_ = request->url;
method_ = request->method;
identifier_ = identifier;
// Our consumer should have made sure that this is a safe referrer. See for
// instance WebCore::FrameLoader::HideReferrer.
if (request->referrer.is_valid()) {
referrer_url_ = request->referrer;
referrer_policy_ =
static_cast<cef_referrer_policy_t>(request->referrer_policy);
}
// Transfer request headers.
::GetHeaderMap(request->headers, headermap_);
// Transfer post data, if any.
if (request->request_body) {
postdata_ = CefPostData::Create();
static_cast<CefPostDataImpl*>(postdata_.get())->Set(*request->request_body);
}
first_party_for_cookies_ = request->site_for_cookies;
resource_type_ = static_cast<cef_resource_type_t>(request->resource_type);
transition_type_ =
static_cast<cef_transition_type_t>(request->transition_type);
}
void CefRequestImpl::Get(network::ResourceRequest* request,
bool changed_only) const {
base::AutoLock lock_scope(lock_);
if (ShouldSet(kChangedUrl, changed_only))
request->url = url_;
if (ShouldSet(kChangedMethod, changed_only))
request->method = method_;
if (ShouldSet(kChangedReferrer, changed_only)) {
request->referrer = referrer_url_;
request->referrer_policy =
static_cast<net::URLRequest::ReferrerPolicy>(referrer_policy_);
}
if (ShouldSet(kChangedHeaderMap, changed_only)) {
net::HttpRequestHeaders headers;
headers.AddHeadersFromString(HttpHeaderUtils::GenerateHeaders(headermap_));
request->headers.Swap(&headers);
}
if (ShouldSet(kChangedPostData, changed_only)) {
if (postdata_.get()) {
request->request_body =
static_cast<CefPostDataImpl*>(postdata_.get())->GetBody();
} else if (request->request_body) {
request->request_body = nullptr;
}
}
if (!first_party_for_cookies_.is_empty() &&
ShouldSet(kChangedFirstPartyForCookies, changed_only)) {
request->site_for_cookies = first_party_for_cookies_;
}
}
void CefRequestImpl::Set(const net::RedirectInfo& redirect_info) {
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
url_ = redirect_info.new_url;
method_ = redirect_info.new_method;
first_party_for_cookies_ = redirect_info.new_site_for_cookies;
referrer_url_ = GURL(redirect_info.new_referrer);
referrer_policy_ =
static_cast<cef_referrer_policy_t>(redirect_info.new_referrer_policy);
}
void CefRequestImpl::Set(const net::HttpRequestHeaders& headers) {
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
::GetHeaderMap(headers, headermap_);
}
void CefRequestImpl::Set(const net::URLRequest* request) {
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
@ -446,7 +602,7 @@ void CefRequestImpl::Set(const net::URLRequest* request) {
static_cast<CefPostDataImpl*>(postdata_.get())->Set(*data);
}
site_for_cookies_ = request->site_for_cookies();
first_party_for_cookies_ = request->site_for_cookies();
content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
@ -484,9 +640,9 @@ void CefRequestImpl::Get(net::URLRequest* request, bool changed_only) const {
}
}
if (!site_for_cookies_.is_empty() &&
if (!first_party_for_cookies_.is_empty() &&
ShouldSet(kChangedFirstPartyForCookies, changed_only)) {
request->set_site_for_cookies(site_for_cookies_);
request->set_site_for_cookies(first_party_for_cookies_);
}
}
@ -551,8 +707,8 @@ void CefRequestImpl::Get(blink::WebURLRequest& request,
::SetHeaderMap(headermap_, request);
if (!site_for_cookies_.is_empty())
request.SetSiteForCookies(site_for_cookies_);
if (!first_party_for_cookies_.is_empty())
request.SetSiteForCookies(first_party_for_cookies_);
int flags = flags_;
if (!(flags & kURCachePolicyMask)) {
@ -674,7 +830,7 @@ void CefRequestImpl::Get(CefNavigateParams& params) const {
impl->Get(*params.upload_data.get());
}
params.site_for_cookies = site_for_cookies_;
params.site_for_cookies = first_party_for_cookies_;
params.load_flags = flags_;
}
@ -743,8 +899,8 @@ void CefRequestImpl::Get(net::URLFetcher& fetcher,
}
}
if (!site_for_cookies_.is_empty())
fetcher.SetInitiator(url::Origin::Create(site_for_cookies_));
if (!first_party_for_cookies_.is_empty())
fetcher.SetInitiator(url::Origin::Create(first_party_for_cookies_));
int flags = flags_;
if (!(flags & kURCachePolicyMask)) {
@ -789,12 +945,17 @@ void CefRequestImpl::SetReadOnly(bool read_only) {
static_cast<CefPostDataImpl*>(postdata_.get())->SetReadOnly(read_only);
}
void CefRequestImpl::SetTrackChanges(bool track_changes) {
void CefRequestImpl::SetTrackChanges(bool track_changes,
bool backup_on_change) {
base::AutoLock lock_scope(lock_);
if (track_changes_ == track_changes)
return;
if (!track_changes && backup_on_change_)
backup_.reset();
track_changes_ = track_changes;
backup_on_change_ = track_changes ? backup_on_change : false;
changes_ = kChangedNone;
if (postdata_.get()) {
@ -803,6 +964,44 @@ void CefRequestImpl::SetTrackChanges(bool track_changes) {
}
}
void CefRequestImpl::RevertChanges() {
base::AutoLock lock_scope(lock_);
DCHECK(!read_only_);
DCHECK(track_changes_);
DCHECK(backup_on_change_);
if (!backup_)
return;
// Restore the original values if a backup exists.
if (backup_->backups_ & kChangedUrl)
url_ = backup_->url_;
if (backup_->backups_ & kChangedMethod)
method_ = backup_->method_;
if (backup_->backups_ & kChangedReferrer) {
referrer_url_ = backup_->referrer_url_;
referrer_policy_ = backup_->referrer_policy_;
}
if (backup_->backups_ & kChangedPostData)
postdata_ = backup_->postdata_;
if (backup_->backups_ & kChangedHeaderMap) {
DCHECK(backup_->headermap_);
headermap_.swap(*backup_->headermap_);
}
if (backup_->backups_ & kChangedFlags)
flags_ = backup_->flags_;
if (backup_->backups_ & kChangedFirstPartyForCookies)
first_party_for_cookies_ = backup_->first_party_for_cookies_;
backup_.reset();
}
void CefRequestImpl::DiscardChanges() {
base::AutoLock lock_scope(lock_);
DCHECK(track_changes_);
DCHECK(backup_on_change_);
backup_.reset();
}
uint8_t CefRequestImpl::GetChanges() const {
base::AutoLock lock_scope(lock_);
@ -872,8 +1071,52 @@ cef_referrer_policy_t CefRequestImpl::BlinkReferrerPolicyToNetReferrerPolicy(
void CefRequestImpl::Changed(uint8_t changes) {
lock_.AssertAcquired();
if (track_changes_)
changes_ |= changes;
if (!track_changes_)
return;
if (backup_on_change_) {
if (!backup_)
backup_.reset(new Backup());
// Set the backup values if not already set.
if ((changes & kChangedUrl) && !(backup_->backups_ & kChangedUrl)) {
backup_->url_ = url_;
backup_->backups_ |= kChangedUrl;
}
if ((changes & kChangedMethod) && !(backup_->backups_ & kChangedMethod)) {
backup_->method_ = method_;
backup_->backups_ |= kChangedMethod;
}
if ((changes & kChangedReferrer) &&
!(backup_->backups_ & kChangedReferrer)) {
backup_->referrer_url_ = referrer_url_;
backup_->referrer_policy_ = referrer_policy_;
backup_->backups_ |= kChangedReferrer;
}
if ((changes & kChangedPostData) &&
!(backup_->backups_ & kChangedPostData)) {
backup_->postdata_ = postdata_;
backup_->backups_ |= kChangedPostData;
}
if ((changes & kChangedHeaderMap) &&
!(backup_->backups_ & kChangedHeaderMap)) {
if (!backup_->headermap_)
backup_->headermap_.reset(new HeaderMap());
backup_->headermap_->swap(headermap_);
backup_->backups_ |= kChangedHeaderMap;
}
if ((changes & kChangedFlags) && !(backup_->backups_ & kChangedFlags)) {
backup_->flags_ = flags_;
backup_->backups_ |= kChangedFlags;
}
if ((changes & kChangedFirstPartyForCookies) &&
!(backup_->backups_ & kChangedFirstPartyForCookies)) {
backup_->first_party_for_cookies_ = first_party_for_cookies_;
backup_->backups_ |= kChangedFirstPartyForCookies;
}
}
changes_ |= changes;
}
bool CefRequestImpl::ShouldSet(uint8_t changes, bool changed_only) const {
@ -916,7 +1159,7 @@ void CefRequestImpl::Reset() {
transition_type_ = TT_EXPLICIT;
identifier_ = 0U;
flags_ = UR_FLAG_NONE;
site_for_cookies_ = GURL();
first_party_for_cookies_ = GURL();
changes_ = kChangedNone;
}
@ -1003,6 +1246,32 @@ void CefPostDataImpl::RemoveElements() {
Changed();
}
void CefPostDataImpl::Set(const network::ResourceRequestBody& body) {
{
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
}
CefRefPtr<CefPostDataElement> postelem;
for (const auto& element : *body.elements()) {
postelem = CefPostDataElement::Create();
static_cast<CefPostDataElementImpl*>(postelem.get())->Set(element);
AddElement(postelem);
}
}
scoped_refptr<network::ResourceRequestBody> CefPostDataImpl::GetBody() const {
base::AutoLock lock_scope(lock_);
scoped_refptr<network::ResourceRequestBody> body =
new network::ResourceRequestBody();
for (const auto& element : elements_) {
static_cast<CefPostDataElementImpl*>(element.get())->Get(*body);
}
return body;
}
void CefPostDataImpl::Set(const net::UploadData& data) {
{
base::AutoLock lock_scope(lock_);
@ -1255,6 +1524,35 @@ size_t CefPostDataElementImpl::GetBytes(size_t size, void* bytes) {
return rv;
}
void CefPostDataElementImpl::Set(const network::DataElement& element) {
{
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
}
if (element.type() == network::mojom::DataElementType::kBytes) {
SetToBytes(element.length(), element.bytes());
} else if (element.type() == network::mojom::DataElementType::kFile) {
SetToFile(element.path().value());
} else {
NOTREACHED();
}
}
void CefPostDataElementImpl::Get(network::ResourceRequestBody& body) const {
base::AutoLock lock_scope(lock_);
if (type_ == PDE_TYPE_BYTES) {
body.AppendBytes(static_cast<char*>(data_.bytes.bytes), data_.bytes.size);
} else if (type_ == PDE_TYPE_FILE) {
base::FilePath path = base::FilePath(CefString(&data_.filename));
body.AppendFileRange(path, 0, std::numeric_limits<uint64_t>::max(),
base::Time());
} else {
NOTREACHED();
}
}
void CefPostDataElementImpl::Set(const net::UploadElement& element) {
{
base::AutoLock lock_scope(lock_);

View File

@ -17,12 +17,17 @@
#include "third_party/blink/public/platform/web_http_body.h"
#include "url/gurl.h"
namespace blink {
class WebURLRequest;
} // namespace blink
namespace navigation_interception {
class NavigationParams;
}
namespace net {
class HttpRequestHeaders;
struct RedirectInfo;
class UploadData;
class UploadDataStream;
class UploadElement;
@ -31,9 +36,11 @@ class URLFetcher;
class URLRequest;
} // namespace net
namespace blink {
class WebURLRequest;
} // namespace blink
namespace network {
class DataElement;
struct ResourceRequest;
class ResourceRequestBody;
} // namespace network
struct CefMsg_LoadRequest_Params;
struct CefNavigateParams;
@ -67,6 +74,10 @@ class CefRequestImpl : public CefRequest {
void SetPostData(CefRefPtr<CefPostData> postData) override;
void GetHeaderMap(HeaderMap& headerMap) override;
void SetHeaderMap(const HeaderMap& headerMap) override;
CefString GetHeaderByName(const CefString& name) override;
void SetHeaderByName(const CefString& name,
const CefString& value,
bool overwrite) override;
void Set(const CefString& url,
const CefString& method,
CefRefPtr<CefPostData> postData,
@ -79,6 +90,19 @@ class CefRequestImpl : public CefRequest {
TransitionType GetTransitionType() override;
uint64 GetIdentifier() override;
// Populate this object from the ResourceRequest object.
void Set(const network::ResourceRequest* request, uint64 identifier);
// Populate the URLRequest object from this object.
// If |changed_only| is true then only the changed fields will be updated.
void Get(network::ResourceRequest* request, bool changed_only) const;
// Populate this object from the RedirectInfo object.
void Set(const net::RedirectInfo& redirect_info);
// Populate this object from teh HttpRequestHeaders object.
void Set(const net::HttpRequestHeaders& headers);
// Populate this object from the URLRequest object.
void Set(const net::URLRequest* request);
@ -112,7 +136,14 @@ class CefRequestImpl : public CefRequest {
void SetReadOnly(bool read_only);
void SetTrackChanges(bool track_changes);
// Enable or disable tracking of changes. If |track_changes| is true the
// status of changes will be tracked, and retrievable via GetChanges(). If
// |backup_on_change| is true the original value will be backed up before the
// first change. The original values can later be restored by calling
// RevertChanges() before calling SetTrackChanges(false).
void SetTrackChanges(bool track_changes, bool backup_on_change = false);
void RevertChanges();
void DiscardChanges();
uint8_t GetChanges() const;
static network::mojom::ReferrerPolicy NetReferrerPolicyToBlinkReferrerPolicy(
@ -121,7 +152,13 @@ class CefRequestImpl : public CefRequest {
network::mojom::ReferrerPolicy blink_policy);
private:
// Mark values as changed. Must be called before the new values are assigned.
void Changed(uint8_t changes);
// Used with the Set() methods that export data to other object types. Returns
// true if the values should be set on the export object. If |changed_only| is
// true then only return true if the value has been changed in combination
// with track changes.
bool ShouldSet(uint8_t changes, bool changed_only) const;
void Reset();
@ -138,16 +175,35 @@ class CefRequestImpl : public CefRequest {
// The below members are used by CefURLRequest.
int flags_;
GURL site_for_cookies_;
GURL first_party_for_cookies_;
// Stores backup of values for use with track changes.
struct Backup {
// Bitmask of values that have been backed up.
uint8_t backups_ = kChangedNone;
GURL url_;
std::string method_;
GURL referrer_url_;
ReferrerPolicy referrer_policy_;
CefRefPtr<CefPostData> postdata_;
std::unique_ptr<HeaderMap> headermap_;
int flags_;
GURL first_party_for_cookies_;
};
std::unique_ptr<Backup> backup_;
// True if this object is read-only.
bool read_only_;
bool read_only_ = false;
// True if this object should track changes.
bool track_changes_;
bool track_changes_ = false;
// True if original values should be backed up when |track_changes_| is true.
bool backup_on_change_ = false;
// Bitmask of |Changes| values which indicate which fields have changed.
uint8_t changes_;
uint8_t changes_ = kChangedNone;
mutable base::Lock lock_;
@ -167,6 +223,8 @@ class CefPostDataImpl : public CefPostData {
bool AddElement(CefRefPtr<CefPostDataElement> element) override;
void RemoveElements() override;
void Set(const network::ResourceRequestBody& body);
scoped_refptr<network::ResourceRequestBody> GetBody() const;
void Set(const net::UploadData& data);
void Set(const net::UploadDataStream& data_stream);
void Get(net::UploadData& data) const;
@ -218,6 +276,8 @@ class CefPostDataElementImpl : public CefPostDataElement {
void* GetBytes() { return data_.bytes.bytes; }
void Set(const network::DataElement& element);
void Get(network::ResourceRequestBody& body) const;
void Set(const net::UploadElement& element);
void Set(const net::UploadElementReader& element_reader);
void Get(net::UploadElement& element) const;

View File

@ -6,8 +6,10 @@
#include <string>
#include "libcef/common/net_service/net_service_util.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "base/strings/string_util.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
@ -84,6 +86,17 @@ void CefResponseImpl::SetMimeType(const CefString& mimeType) {
mime_type_ = mimeType;
}
CefString CefResponseImpl::GetCharset() {
base::AutoLock lock_scope(lock_);
return charset_;
}
void CefResponseImpl::SetCharset(const CefString& charset) {
base::AutoLock lock_scope(lock_);
CHECK_READONLY_RETURN_VOID();
charset_ = charset;
}
CefString CefResponseImpl::GetHeader(const CefString& name) {
base::AutoLock lock_scope(lock_);
@ -121,51 +134,17 @@ void CefResponseImpl::SetHeaderMap(const HeaderMap& headerMap) {
net::HttpResponseHeaders* CefResponseImpl::GetResponseHeaders() {
base::AutoLock lock_scope(lock_);
std::string response;
std::string status_text;
bool has_content_type_header = false;
std::string mime_type = mime_type_;
if (mime_type.empty())
mime_type = "text/html";
if (!status_text_.empty())
status_text = status_text_;
else
status_text = (status_code_ == 200) ? "OK" : "ERROR";
std::multimap<std::string, std::string> extra_headers;
for (const auto& pair : header_map_)
extra_headers.insert(std::make_pair(pair.first, pair.second));
base::SStringPrintf(&response, "HTTP/1.1 %d %s", status_code_,
status_text.c_str());
if (header_map_.size() > 0) {
for (HeaderMap::const_iterator header = header_map_.begin();
header != header_map_.end(); ++header) {
const CefString& key = header->first;
const CefString& value = header->second;
if (!key.empty()) {
// Delimit with "\0" as required by net::HttpResponseHeaders.
std::string key_str(key);
std::string value_str(value);
base::StringAppendF(&response, "%c%s: %s", '\0', key_str.c_str(),
value_str.c_str());
if (!has_content_type_header &&
key_str == net::HttpRequestHeaders::kContentType) {
has_content_type_header = true;
}
}
}
}
if (!has_content_type_header) {
std::string mime_type;
if (!mime_type_.empty())
mime_type = mime_type_;
else
mime_type = "text/html";
base::StringAppendF(&response, "%c%s: %s", '\0',
net::HttpRequestHeaders::kContentType,
mime_type.c_str());
}
return new net::HttpResponseHeaders(response);
return net_service::MakeResponseHeaders(
status_code_, status_text_, mime_type, charset_, -1, extra_headers,
true /* allow_existing_header_override */);
}
void CefResponseImpl::SetResponseHeaders(
@ -183,11 +162,10 @@ void CefResponseImpl::SetResponseHeaders(
status_code_ = headers.response_code();
status_text_ = headers.GetStatusText();
std::string mime_type;
if (headers.GetMimeType(&mime_type))
mime_type_ = mime_type;
else
mime_type_.clear();
std::string mime_type, charset;
headers.GetMimeTypeAndCharset(&mime_type, &charset);
mime_type_ = mime_type;
charset_ = charset;
}
void CefResponseImpl::Set(const blink::WebURLResponse& response) {

View File

@ -34,6 +34,8 @@ class CefResponseImpl : public CefResponse {
void SetStatusText(const CefString& statusText) override;
CefString GetMimeType() override;
void SetMimeType(const CefString& mimeType) override;
CefString GetCharset() override;
void SetCharset(const CefString& charset) override;
CefString GetHeader(const CefString& name) override;
void GetHeaderMap(HeaderMap& headerMap) override;
void SetHeaderMap(const HeaderMap& headerMap) override;
@ -53,6 +55,7 @@ class CefResponseImpl : public CefResponse {
int status_code_;
CefString status_text_;
CefString mime_type_;
CefString charset_;
CefString url_;
HeaderMap header_map_;
bool read_only_;

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=95fec7879b0944afdcf9cd04b3b5d5bab1b9c134$
// $hash=1cbeca6be574f17e0e0fa563b98f95506941ecf2$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_REQUEST_CALLBACK_CPPTOC_H_
@ -20,8 +20,8 @@
#error This file can be included DLL-side only
#endif
#include "include/capi/cef_request_handler_capi.h"
#include "include/cef_request_handler.h"
#include "include/capi/cef_request_callback_capi.h"
#include "include/cef_request_callback.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=e3a4e0ec89854791f0f84a88af6161d51c98a274$
// $hash=8a1bcfce1784b99aa054c80eea510730c7b6c704$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_REQUEST_CONTEXT_CPPTOC_H_
@ -21,8 +21,10 @@
#endif
#include "include/capi/cef_request_context_capi.h"
#include "include/capi/cef_request_context_handler_capi.h"
#include "include/capi/cef_scheme_capi.h"
#include "include/cef_request_context.h"
#include "include/cef_request_context_handler.h"
#include "include/cef_scheme.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"

View File

@ -9,11 +9,15 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=b98ed34333ccd44a004c88c0ca496f7821f49e18$
// $hash=16c737f9006a13e5a445d2402c04bc833d68961a$
//
#include "libcef_dll/cpptoc/request_context_handler_cpptoc.h"
#include "libcef_dll/cpptoc/resource_request_handler_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/frame_ctocpp.h"
#include "libcef_dll/ctocpp/request_context_ctocpp.h"
#include "libcef_dll/ctocpp/request_ctocpp.h"
#include "libcef_dll/ctocpp/web_plugin_info_ctocpp.h"
namespace {
@ -75,6 +79,51 @@ int CEF_CALLBACK request_context_handler_on_before_plugin_load(
return _retval;
}
struct _cef_resource_request_handler_t* CEF_CALLBACK
request_context_handler_get_resource_request_handler(
struct _cef_request_context_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
int is_navigation,
int is_download,
const cef_string_t* request_initiator,
int* disable_default_handling) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return NULL;
// Verify param: disable_default_handling; type: bool_byref
DCHECK(disable_default_handling);
if (!disable_default_handling)
return NULL;
// Unverified params: browser, frame, request_initiator
// Translate param: disable_default_handling; type: bool_byref
bool disable_default_handlingBool =
(disable_default_handling && *disable_default_handling) ? true : false;
// Execute
CefRefPtr<CefResourceRequestHandler> _retval =
CefRequestContextHandlerCppToC::Get(self)->GetResourceRequestHandler(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), is_navigation ? true : false,
is_download ? true : false, CefString(request_initiator),
disable_default_handlingBool);
// Restore param: disable_default_handling; type: bool_byref
if (disable_default_handling)
*disable_default_handling = disable_default_handlingBool ? true : false;
// Return type: refptr_same
return CefResourceRequestHandlerCppToC::Wrap(_retval);
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
@ -84,6 +133,8 @@ CefRequestContextHandlerCppToC::CefRequestContextHandlerCppToC() {
request_context_handler_on_request_context_initialized;
GetStruct()->on_before_plugin_load =
request_context_handler_on_before_plugin_load;
GetStruct()->get_resource_request_handler =
request_context_handler_get_resource_request_handler;
}
// DESTRUCTOR - Do not edit by hand.

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=ba55d3f626c344b38261bdabd7a3fd8d8b7814f9$
// $hash=7eda7522edc12bf229307a92fbf463194fea8a3f$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_REQUEST_CONTEXT_HANDLER_CPPTOC_H_
@ -20,9 +20,7 @@
#error This file can be included wrapper-side only
#endif
#include "include/capi/cef_request_context_capi.h"
#include "include/capi/cef_request_context_handler_capi.h"
#include "include/cef_request_context.h"
#include "include/cef_request_context_handler.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=ce5154d248eed30bca03ae2eb2b21b5cecd3dc0a$
// $hash=fc10026d8f3e77868d19807ea625f9449678da60$
//
#include "libcef_dll/cpptoc/request_cpptoc.h"
@ -231,6 +231,50 @@ void CEF_CALLBACK request_set_header_map(struct _cef_request_t* self,
CefRequestCppToC::Get(self)->SetHeaderMap(headerMapMultimap);
}
cef_string_userfree_t CEF_CALLBACK
request_get_header_by_name(struct _cef_request_t* self,
const cef_string_t* name) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Verify param: name; type: string_byref_const
DCHECK(name);
if (!name)
return NULL;
// Execute
CefString _retval =
CefRequestCppToC::Get(self)->GetHeaderByName(CefString(name));
// Return type: string
return _retval.DetachToUserFree();
}
void CEF_CALLBACK request_set_header_by_name(struct _cef_request_t* self,
const cef_string_t* name,
const cef_string_t* value,
int overwrite) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: name; type: string_byref_const
DCHECK(name);
if (!name)
return;
// Verify param: value; type: string_byref_const
DCHECK(value);
if (!value)
return;
// Execute
CefRequestCppToC::Get(self)->SetHeaderByName(
CefString(name), CefString(value), overwrite ? true : false);
}
void CEF_CALLBACK request_set(struct _cef_request_t* self,
const cef_string_t* url,
const cef_string_t* method,
@ -384,6 +428,8 @@ CefRequestCppToC::CefRequestCppToC() {
GetStruct()->set_post_data = request_set_post_data;
GetStruct()->get_header_map = request_get_header_map;
GetStruct()->set_header_map = request_set_header_map;
GetStruct()->get_header_by_name = request_get_header_by_name;
GetStruct()->set_header_by_name = request_set_header_by_name;
GetStruct()->set = request_set;
GetStruct()->get_flags = request_get_flags;
GetStruct()->set_flags = request_set_flags;

View File

@ -9,18 +9,16 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=9353ea1707598e400907e00b1338270ee90c97b0$
// $hash=370a54c21bec2aff5cf62b5897f5d43401e1ec31$
//
#include "libcef_dll/cpptoc/request_handler_cpptoc.h"
#include "libcef_dll/cpptoc/resource_handler_cpptoc.h"
#include "libcef_dll/cpptoc/response_filter_cpptoc.h"
#include "libcef_dll/cpptoc/resource_request_handler_cpptoc.h"
#include "libcef_dll/ctocpp/auth_callback_ctocpp.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/frame_ctocpp.h"
#include "libcef_dll/ctocpp/request_callback_ctocpp.h"
#include "libcef_dll/ctocpp/request_ctocpp.h"
#include "libcef_dll/ctocpp/response_ctocpp.h"
#include "libcef_dll/ctocpp/select_client_certificate_callback_ctocpp.h"
#include "libcef_dll/ctocpp/sslinfo_ctocpp.h"
#include "libcef_dll/ctocpp/x509certificate_ctocpp.h"
@ -103,173 +101,16 @@ int CEF_CALLBACK request_handler_on_open_urlfrom_tab(
return _retval;
}
cef_return_value_t CEF_CALLBACK
request_handler_on_before_resource_load(struct _cef_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
cef_request_callback_t* callback) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return RV_CONTINUE;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return RV_CONTINUE;
// Verify param: frame; type: refptr_diff
DCHECK(frame);
if (!frame)
return RV_CONTINUE;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return RV_CONTINUE;
// Verify param: callback; type: refptr_diff
DCHECK(callback);
if (!callback)
return RV_CONTINUE;
// Execute
cef_return_value_t _retval =
CefRequestHandlerCppToC::Get(self)->OnBeforeResourceLoad(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request),
CefRequestCallbackCToCpp::Wrap(callback));
// Return type: simple
return _retval;
}
struct _cef_resource_handler_t* CEF_CALLBACK
request_handler_get_resource_handler(struct _cef_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return NULL;
// Verify param: frame; type: refptr_diff
DCHECK(frame);
if (!frame)
return NULL;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return NULL;
// Execute
CefRefPtr<CefResourceHandler> _retval =
CefRequestHandlerCppToC::Get(self)->GetResourceHandler(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request));
// Return type: refptr_same
return CefResourceHandlerCppToC::Wrap(_retval);
}
void CEF_CALLBACK
request_handler_on_resource_redirect(struct _cef_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
struct _cef_response_t* response,
cef_string_t* new_url) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Verify param: frame; type: refptr_diff
DCHECK(frame);
if (!frame)
return;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return;
// Verify param: response; type: refptr_diff
DCHECK(response);
if (!response)
return;
// Verify param: new_url; type: string_byref
DCHECK(new_url);
if (!new_url)
return;
// Translate param: new_url; type: string_byref
CefString new_urlStr(new_url);
// Execute
CefRequestHandlerCppToC::Get(self)->OnResourceRedirect(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), CefResponseCToCpp::Wrap(response),
new_urlStr);
}
int CEF_CALLBACK
request_handler_on_resource_response(struct _cef_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
struct _cef_response_t* response) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: frame; type: refptr_diff
DCHECK(frame);
if (!frame)
return 0;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return 0;
// Verify param: response; type: refptr_diff
DCHECK(response);
if (!response)
return 0;
// Execute
bool _retval = CefRequestHandlerCppToC::Get(self)->OnResourceResponse(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), CefResponseCToCpp::Wrap(response));
// Return type: bool
return _retval;
}
struct _cef_response_filter_t* CEF_CALLBACK
request_handler_get_resource_response_filter(
struct _cef_resource_request_handler_t* CEF_CALLBACK
request_handler_get_resource_request_handler(
struct _cef_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
struct _cef_response_t* response) {
int is_navigation,
int is_download,
const cef_string_t* request_initiator,
int* disable_default_handling) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -289,58 +130,30 @@ request_handler_get_resource_response_filter(
DCHECK(request);
if (!request)
return NULL;
// Verify param: response; type: refptr_diff
DCHECK(response);
if (!response)
// Verify param: disable_default_handling; type: bool_byref
DCHECK(disable_default_handling);
if (!disable_default_handling)
return NULL;
// Unverified params: request_initiator
// Translate param: disable_default_handling; type: bool_byref
bool disable_default_handlingBool =
(disable_default_handling && *disable_default_handling) ? true : false;
// Execute
CefRefPtr<CefResponseFilter> _retval =
CefRequestHandlerCppToC::Get(self)->GetResourceResponseFilter(
CefRefPtr<CefResourceRequestHandler> _retval =
CefRequestHandlerCppToC::Get(self)->GetResourceRequestHandler(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), CefResponseCToCpp::Wrap(response));
CefRequestCToCpp::Wrap(request), is_navigation ? true : false,
is_download ? true : false, CefString(request_initiator),
disable_default_handlingBool);
// Restore param: disable_default_handling; type: bool_byref
if (disable_default_handling)
*disable_default_handling = disable_default_handlingBool ? true : false;
// Return type: refptr_same
return CefResponseFilterCppToC::Wrap(_retval);
}
void CEF_CALLBACK
request_handler_on_resource_load_complete(struct _cef_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
struct _cef_response_t* response,
cef_urlrequest_status_t status,
int64 received_content_length) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Verify param: frame; type: refptr_diff
DCHECK(frame);
if (!frame)
return;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return;
// Verify param: response; type: refptr_diff
DCHECK(response);
if (!response)
return;
// Execute
CefRequestHandlerCppToC::Get(self)->OnResourceLoadComplete(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), CefResponseCToCpp::Wrap(response),
status, received_content_length);
return CefResourceRequestHandlerCppToC::Wrap(_retval);
}
int CEF_CALLBACK
@ -388,84 +201,6 @@ request_handler_get_auth_credentials(struct _cef_request_handler_t* self,
return _retval;
}
int CEF_CALLBACK
request_handler_can_get_cookies(struct _cef_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: frame; type: refptr_diff
DCHECK(frame);
if (!frame)
return 0;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return 0;
// Execute
bool _retval = CefRequestHandlerCppToC::Get(self)->CanGetCookies(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request));
// Return type: bool
return _retval;
}
int CEF_CALLBACK
request_handler_can_set_cookie(struct _cef_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
const struct _cef_cookie_t* cookie) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: frame; type: refptr_diff
DCHECK(frame);
if (!frame)
return 0;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return 0;
// Verify param: cookie; type: struct_byref_const
DCHECK(cookie);
if (!cookie)
return 0;
// Translate param: cookie; type: struct_byref_const
CefCookie cookieObj;
if (cookie)
cookieObj.Set(*cookie, false);
// Execute
bool _retval = CefRequestHandlerCppToC::Get(self)->CanSetCookie(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), cookieObj);
// Return type: bool
return _retval;
}
int CEF_CALLBACK
request_handler_on_quota_request(struct _cef_request_handler_t* self,
cef_browser_t* browser,
@ -501,44 +236,6 @@ request_handler_on_quota_request(struct _cef_request_handler_t* self,
return _retval;
}
void CEF_CALLBACK
request_handler_on_protocol_execution(struct _cef_request_handler_t* self,
cef_browser_t* browser,
const cef_string_t* url,
int* allow_os_execution) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Verify param: url; type: string_byref_const
DCHECK(url);
if (!url)
return;
// Verify param: allow_os_execution; type: bool_byref
DCHECK(allow_os_execution);
if (!allow_os_execution)
return;
// Translate param: allow_os_execution; type: bool_byref
bool allow_os_executionBool =
(allow_os_execution && *allow_os_execution) ? true : false;
// Execute
CefRequestHandlerCppToC::Get(self)->OnProtocolExecution(
CefBrowserCToCpp::Wrap(browser), CefString(url), allow_os_executionBool);
// Restore param: allow_os_execution; type: bool_byref
if (allow_os_execution)
*allow_os_execution = allow_os_executionBool ? true : false;
}
int CEF_CALLBACK
request_handler_on_certificate_error(struct _cef_request_handler_t* self,
cef_browser_t* browser,
@ -706,20 +403,10 @@ void CEF_CALLBACK request_handler_on_render_process_terminated(
CefRequestHandlerCppToC::CefRequestHandlerCppToC() {
GetStruct()->on_before_browse = request_handler_on_before_browse;
GetStruct()->on_open_urlfrom_tab = request_handler_on_open_urlfrom_tab;
GetStruct()->on_before_resource_load =
request_handler_on_before_resource_load;
GetStruct()->get_resource_handler = request_handler_get_resource_handler;
GetStruct()->on_resource_redirect = request_handler_on_resource_redirect;
GetStruct()->on_resource_response = request_handler_on_resource_response;
GetStruct()->get_resource_response_filter =
request_handler_get_resource_response_filter;
GetStruct()->on_resource_load_complete =
request_handler_on_resource_load_complete;
GetStruct()->get_resource_request_handler =
request_handler_get_resource_request_handler;
GetStruct()->get_auth_credentials = request_handler_get_auth_credentials;
GetStruct()->can_get_cookies = request_handler_can_get_cookies;
GetStruct()->can_set_cookie = request_handler_can_set_cookie;
GetStruct()->on_quota_request = request_handler_on_quota_request;
GetStruct()->on_protocol_execution = request_handler_on_protocol_execution;
GetStruct()->on_certificate_error = request_handler_on_certificate_error;
GetStruct()->on_select_client_certificate =
request_handler_on_select_client_certificate;

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=a3b2f47a5c8ea53d6eb4b4e35abb429c2736434c$
// $hash=ceedb00b43b104cb120d80d766029d28585d9b3a$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_RESOLVE_CALLBACK_CPPTOC_H_
@ -21,8 +21,10 @@
#endif
#include "include/capi/cef_request_context_capi.h"
#include "include/capi/cef_request_context_handler_capi.h"
#include "include/capi/cef_scheme_capi.h"
#include "include/cef_request_context.h"
#include "include/cef_request_context_handler.h"
#include "include/cef_scheme.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"

View File

@ -9,12 +9,14 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=9d3f948866d05cacdb33a2335422ff0f94825389$
// $hash=e95db24c85f1c1880048b6319660133038f8b213$
//
#include "libcef_dll/cpptoc/resource_handler_cpptoc.h"
#include "libcef_dll/ctocpp/callback_ctocpp.h"
#include "libcef_dll/ctocpp/request_ctocpp.h"
#include "libcef_dll/ctocpp/resource_read_callback_ctocpp.h"
#include "libcef_dll/ctocpp/resource_skip_callback_ctocpp.h"
#include "libcef_dll/ctocpp/response_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
@ -22,6 +24,46 @@ namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
int CEF_CALLBACK resource_handler_open(struct _cef_resource_handler_t* self,
cef_request_t* request,
int* handle_request,
cef_callback_t* callback) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return 0;
// Verify param: handle_request; type: bool_byref
DCHECK(handle_request);
if (!handle_request)
return 0;
// Verify param: callback; type: refptr_diff
DCHECK(callback);
if (!callback)
return 0;
// Translate param: handle_request; type: bool_byref
bool handle_requestBool = (handle_request && *handle_request) ? true : false;
// Execute
bool _retval = CefResourceHandlerCppToC::Get(self)->Open(
CefRequestCToCpp::Wrap(request), handle_requestBool,
CefCallbackCToCpp::Wrap(callback));
// Restore param: handle_request; type: bool_byref
if (handle_request)
*handle_request = handle_requestBool ? true : false;
// Return type: bool
return _retval;
}
int CEF_CALLBACK
resource_handler_process_request(struct _cef_resource_handler_t* self,
cef_request_t* request,
@ -89,6 +131,83 @@ resource_handler_get_response_headers(struct _cef_resource_handler_t* self,
*response_length = response_lengthVal;
}
int CEF_CALLBACK resource_handler_skip(struct _cef_resource_handler_t* self,
int64 bytes_to_skip,
int64* bytes_skipped,
cef_resource_skip_callback_t* callback) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: bytes_skipped; type: simple_byref
DCHECK(bytes_skipped);
if (!bytes_skipped)
return 0;
// Verify param: callback; type: refptr_diff
DCHECK(callback);
if (!callback)
return 0;
// Translate param: bytes_skipped; type: simple_byref
int64 bytes_skippedVal = bytes_skipped ? *bytes_skipped : 0;
// Execute
bool _retval = CefResourceHandlerCppToC::Get(self)->Skip(
bytes_to_skip, bytes_skippedVal,
CefResourceSkipCallbackCToCpp::Wrap(callback));
// Restore param: bytes_skipped; type: simple_byref
if (bytes_skipped)
*bytes_skipped = bytes_skippedVal;
// Return type: bool
return _retval;
}
int CEF_CALLBACK resource_handler_read(struct _cef_resource_handler_t* self,
void* data_out,
int bytes_to_read,
int* bytes_read,
cef_resource_read_callback_t* callback) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: data_out; type: simple_byaddr
DCHECK(data_out);
if (!data_out)
return 0;
// Verify param: bytes_read; type: simple_byref
DCHECK(bytes_read);
if (!bytes_read)
return 0;
// Verify param: callback; type: refptr_diff
DCHECK(callback);
if (!callback)
return 0;
// Translate param: bytes_read; type: simple_byref
int bytes_readVal = bytes_read ? *bytes_read : 0;
// Execute
bool _retval = CefResourceHandlerCppToC::Get(self)->Read(
data_out, bytes_to_read, bytes_readVal,
CefResourceReadCallbackCToCpp::Wrap(callback));
// Restore param: bytes_read; type: simple_byref
if (bytes_read)
*bytes_read = bytes_readVal;
// Return type: bool
return _retval;
}
int CEF_CALLBACK
resource_handler_read_response(struct _cef_resource_handler_t* self,
void* data_out,
@ -131,60 +250,6 @@ resource_handler_read_response(struct _cef_resource_handler_t* self,
return _retval;
}
int CEF_CALLBACK
resource_handler_can_get_cookie(struct _cef_resource_handler_t* self,
const struct _cef_cookie_t* cookie) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: cookie; type: struct_byref_const
DCHECK(cookie);
if (!cookie)
return 0;
// Translate param: cookie; type: struct_byref_const
CefCookie cookieObj;
if (cookie)
cookieObj.Set(*cookie, false);
// Execute
bool _retval = CefResourceHandlerCppToC::Get(self)->CanGetCookie(cookieObj);
// Return type: bool
return _retval;
}
int CEF_CALLBACK
resource_handler_can_set_cookie(struct _cef_resource_handler_t* self,
const struct _cef_cookie_t* cookie) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: cookie; type: struct_byref_const
DCHECK(cookie);
if (!cookie)
return 0;
// Translate param: cookie; type: struct_byref_const
CefCookie cookieObj;
if (cookie)
cookieObj.Set(*cookie, false);
// Execute
bool _retval = CefResourceHandlerCppToC::Get(self)->CanSetCookie(cookieObj);
// Return type: bool
return _retval;
}
void CEF_CALLBACK
resource_handler_cancel(struct _cef_resource_handler_t* self) {
shutdown_checker::AssertNotShutdown();
@ -204,11 +269,12 @@ resource_handler_cancel(struct _cef_resource_handler_t* self) {
// CONSTRUCTOR - Do not edit by hand.
CefResourceHandlerCppToC::CefResourceHandlerCppToC() {
GetStruct()->open = resource_handler_open;
GetStruct()->process_request = resource_handler_process_request;
GetStruct()->get_response_headers = resource_handler_get_response_headers;
GetStruct()->skip = resource_handler_skip;
GetStruct()->read = resource_handler_read;
GetStruct()->read_response = resource_handler_read_response;
GetStruct()->can_get_cookie = resource_handler_can_get_cookie;
GetStruct()->can_set_cookie = resource_handler_can_set_cookie;
GetStruct()->cancel = resource_handler_cancel;
}

View File

@ -0,0 +1,66 @@
// 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=f13640047c8e0b866091e9da2ff114af0fab9e99$
//
#include "libcef_dll/cpptoc/resource_read_callback_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK
resource_read_callback_cont(struct _cef_resource_read_callback_t* self,
int bytes_read) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefResourceReadCallbackCppToC::Get(self)->Continue(bytes_read);
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefResourceReadCallbackCppToC::CefResourceReadCallbackCppToC() {
GetStruct()->cont = resource_read_callback_cont;
}
// DESTRUCTOR - Do not edit by hand.
CefResourceReadCallbackCppToC::~CefResourceReadCallbackCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefResourceReadCallback> CefCppToCRefCounted<
CefResourceReadCallbackCppToC,
CefResourceReadCallback,
cef_resource_read_callback_t>::UnwrapDerived(CefWrapperType type,
cef_resource_read_callback_t*
s) {
NOTREACHED() << "Unexpected class type: " << type;
return NULL;
}
template <>
CefWrapperType CefCppToCRefCounted<CefResourceReadCallbackCppToC,
CefResourceReadCallback,
cef_resource_read_callback_t>::kWrapperType =
WT_RESOURCE_READ_CALLBACK;

View File

@ -0,0 +1,38 @@
// 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=72fe4f2d3855abb8f6a830740e86332a43b87131$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_RESOURCE_READ_CALLBACK_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_RESOURCE_READ_CALLBACK_CPPTOC_H_
#pragma once
#if !defined(BUILDING_CEF_SHARED)
#error This file can be included DLL-side only
#endif
#include "include/capi/cef_resource_handler_capi.h"
#include "include/cef_resource_handler.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed DLL-side only.
class CefResourceReadCallbackCppToC
: public CefCppToCRefCounted<CefResourceReadCallbackCppToC,
CefResourceReadCallback,
cef_resource_read_callback_t> {
public:
CefResourceReadCallbackCppToC();
virtual ~CefResourceReadCallbackCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_RESOURCE_READ_CALLBACK_CPPTOC_H_

View File

@ -0,0 +1,390 @@
// 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=d923eabb6aa1e7a54966da940db39e308a71763f$
//
#include "libcef_dll/cpptoc/resource_request_handler_cpptoc.h"
#include "libcef_dll/cpptoc/resource_handler_cpptoc.h"
#include "libcef_dll/cpptoc/response_filter_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/frame_ctocpp.h"
#include "libcef_dll/ctocpp/request_callback_ctocpp.h"
#include "libcef_dll/ctocpp/request_ctocpp.h"
#include "libcef_dll/ctocpp/response_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
cef_return_value_t CEF_CALLBACK
resource_request_handler_on_before_resource_load(
struct _cef_resource_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
cef_request_callback_t* callback) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return RV_CONTINUE;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return RV_CONTINUE;
// Verify param: callback; type: refptr_diff
DCHECK(callback);
if (!callback)
return RV_CONTINUE;
// Unverified params: browser, frame
// Execute
cef_return_value_t _retval =
CefResourceRequestHandlerCppToC::Get(self)->OnBeforeResourceLoad(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request),
CefRequestCallbackCToCpp::Wrap(callback));
// Return type: simple
return _retval;
}
cef_resource_handler_t* CEF_CALLBACK
resource_request_handler_get_resource_handler(
struct _cef_resource_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return NULL;
// Unverified params: browser, frame
// Execute
CefRefPtr<CefResourceHandler> _retval =
CefResourceRequestHandlerCppToC::Get(self)->GetResourceHandler(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request));
// Return type: refptr_same
return CefResourceHandlerCppToC::Wrap(_retval);
}
void CEF_CALLBACK resource_request_handler_on_resource_redirect(
struct _cef_resource_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
struct _cef_response_t* response,
cef_string_t* new_url) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return;
// Verify param: response; type: refptr_diff
DCHECK(response);
if (!response)
return;
// Verify param: new_url; type: string_byref
DCHECK(new_url);
if (!new_url)
return;
// Unverified params: browser, frame
// Translate param: new_url; type: string_byref
CefString new_urlStr(new_url);
// Execute
CefResourceRequestHandlerCppToC::Get(self)->OnResourceRedirect(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), CefResponseCToCpp::Wrap(response),
new_urlStr);
}
int CEF_CALLBACK resource_request_handler_on_resource_response(
struct _cef_resource_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
struct _cef_response_t* response) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return 0;
// Verify param: response; type: refptr_diff
DCHECK(response);
if (!response)
return 0;
// Unverified params: browser, frame
// Execute
bool _retval = CefResourceRequestHandlerCppToC::Get(self)->OnResourceResponse(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), CefResponseCToCpp::Wrap(response));
// Return type: bool
return _retval;
}
struct _cef_response_filter_t* CEF_CALLBACK
resource_request_handler_get_resource_response_filter(
struct _cef_resource_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
struct _cef_response_t* response) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return NULL;
// Verify param: response; type: refptr_diff
DCHECK(response);
if (!response)
return NULL;
// Unverified params: browser, frame
// Execute
CefRefPtr<CefResponseFilter> _retval =
CefResourceRequestHandlerCppToC::Get(self)->GetResourceResponseFilter(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), CefResponseCToCpp::Wrap(response));
// Return type: refptr_same
return CefResponseFilterCppToC::Wrap(_retval);
}
void CEF_CALLBACK resource_request_handler_on_resource_load_complete(
struct _cef_resource_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
struct _cef_response_t* response,
cef_urlrequest_status_t status,
int64 received_content_length) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return;
// Verify param: response; type: refptr_diff
DCHECK(response);
if (!response)
return;
// Unverified params: browser, frame
// Execute
CefResourceRequestHandlerCppToC::Get(self)->OnResourceLoadComplete(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), CefResponseCToCpp::Wrap(response),
status, received_content_length);
}
void CEF_CALLBACK resource_request_handler_on_protocol_execution(
struct _cef_resource_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
int* allow_os_execution) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return;
// Verify param: allow_os_execution; type: bool_byref
DCHECK(allow_os_execution);
if (!allow_os_execution)
return;
// Unverified params: browser, frame
// Translate param: allow_os_execution; type: bool_byref
bool allow_os_executionBool =
(allow_os_execution && *allow_os_execution) ? true : false;
// Execute
CefResourceRequestHandlerCppToC::Get(self)->OnProtocolExecution(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), allow_os_executionBool);
// Restore param: allow_os_execution; type: bool_byref
if (allow_os_execution)
*allow_os_execution = allow_os_executionBool ? true : false;
}
int CEF_CALLBACK resource_request_handler_can_send_cookie(
struct _cef_resource_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
const struct _cef_cookie_t* cookie) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return 0;
// Verify param: cookie; type: struct_byref_const
DCHECK(cookie);
if (!cookie)
return 0;
// Unverified params: browser, frame
// Translate param: cookie; type: struct_byref_const
CefCookie cookieObj;
if (cookie)
cookieObj.Set(*cookie, false);
// Execute
bool _retval = CefResourceRequestHandlerCppToC::Get(self)->CanSendCookie(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), cookieObj);
// Return type: bool
return _retval;
}
int CEF_CALLBACK resource_request_handler_can_save_cookie(
struct _cef_resource_request_handler_t* self,
cef_browser_t* browser,
cef_frame_t* frame,
cef_request_t* request,
struct _cef_response_t* response,
const struct _cef_cookie_t* cookie) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: request; type: refptr_diff
DCHECK(request);
if (!request)
return 0;
// Verify param: response; type: refptr_diff
DCHECK(response);
if (!response)
return 0;
// Verify param: cookie; type: struct_byref_const
DCHECK(cookie);
if (!cookie)
return 0;
// Unverified params: browser, frame
// Translate param: cookie; type: struct_byref_const
CefCookie cookieObj;
if (cookie)
cookieObj.Set(*cookie, false);
// Execute
bool _retval = CefResourceRequestHandlerCppToC::Get(self)->CanSaveCookie(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefRequestCToCpp::Wrap(request), CefResponseCToCpp::Wrap(response),
cookieObj);
// Return type: bool
return _retval;
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefResourceRequestHandlerCppToC::CefResourceRequestHandlerCppToC() {
GetStruct()->on_before_resource_load =
resource_request_handler_on_before_resource_load;
GetStruct()->get_resource_handler =
resource_request_handler_get_resource_handler;
GetStruct()->on_resource_redirect =
resource_request_handler_on_resource_redirect;
GetStruct()->on_resource_response =
resource_request_handler_on_resource_response;
GetStruct()->get_resource_response_filter =
resource_request_handler_get_resource_response_filter;
GetStruct()->on_resource_load_complete =
resource_request_handler_on_resource_load_complete;
GetStruct()->on_protocol_execution =
resource_request_handler_on_protocol_execution;
GetStruct()->can_send_cookie = resource_request_handler_can_send_cookie;
GetStruct()->can_save_cookie = resource_request_handler_can_save_cookie;
}
// DESTRUCTOR - Do not edit by hand.
CefResourceRequestHandlerCppToC::~CefResourceRequestHandlerCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefResourceRequestHandler>
CefCppToCRefCounted<CefResourceRequestHandlerCppToC,
CefResourceRequestHandler,
cef_resource_request_handler_t>::
UnwrapDerived(CefWrapperType type, cef_resource_request_handler_t* s) {
NOTREACHED() << "Unexpected class type: " << type;
return NULL;
}
template <>
CefWrapperType
CefCppToCRefCounted<CefResourceRequestHandlerCppToC,
CefResourceRequestHandler,
cef_resource_request_handler_t>::kWrapperType =
WT_RESOURCE_REQUEST_HANDLER;

View File

@ -0,0 +1,38 @@
// 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=ee7eab38c1a75c054316c4fc1cb3166f7da875bf$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_RESOURCE_REQUEST_HANDLER_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_RESOURCE_REQUEST_HANDLER_CPPTOC_H_
#pragma once
#if !defined(WRAPPING_CEF_SHARED)
#error This file can be included wrapper-side only
#endif
#include "include/capi/cef_resource_request_handler_capi.h"
#include "include/cef_resource_request_handler.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed wrapper-side only.
class CefResourceRequestHandlerCppToC
: public CefCppToCRefCounted<CefResourceRequestHandlerCppToC,
CefResourceRequestHandler,
cef_resource_request_handler_t> {
public:
CefResourceRequestHandlerCppToC();
virtual ~CefResourceRequestHandlerCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_RESOURCE_REQUEST_HANDLER_CPPTOC_H_

View File

@ -0,0 +1,66 @@
// 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=d7446af3d06087c4c46768d965973cea23a6e537$
//
#include "libcef_dll/cpptoc/resource_skip_callback_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK
resource_skip_callback_cont(struct _cef_resource_skip_callback_t* self,
int64 bytes_skipped) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefResourceSkipCallbackCppToC::Get(self)->Continue(bytes_skipped);
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefResourceSkipCallbackCppToC::CefResourceSkipCallbackCppToC() {
GetStruct()->cont = resource_skip_callback_cont;
}
// DESTRUCTOR - Do not edit by hand.
CefResourceSkipCallbackCppToC::~CefResourceSkipCallbackCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefResourceSkipCallback> CefCppToCRefCounted<
CefResourceSkipCallbackCppToC,
CefResourceSkipCallback,
cef_resource_skip_callback_t>::UnwrapDerived(CefWrapperType type,
cef_resource_skip_callback_t*
s) {
NOTREACHED() << "Unexpected class type: " << type;
return NULL;
}
template <>
CefWrapperType CefCppToCRefCounted<CefResourceSkipCallbackCppToC,
CefResourceSkipCallback,
cef_resource_skip_callback_t>::kWrapperType =
WT_RESOURCE_SKIP_CALLBACK;

View File

@ -0,0 +1,38 @@
// 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=0d504faf7f9f4d313dd7382622cf4295a7d326b9$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_RESOURCE_SKIP_CALLBACK_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_RESOURCE_SKIP_CALLBACK_CPPTOC_H_
#pragma once
#if !defined(BUILDING_CEF_SHARED)
#error This file can be included DLL-side only
#endif
#include "include/capi/cef_resource_handler_capi.h"
#include "include/cef_resource_handler.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed DLL-side only.
class CefResourceSkipCallbackCppToC
: public CefCppToCRefCounted<CefResourceSkipCallbackCppToC,
CefResourceSkipCallback,
cef_resource_skip_callback_t> {
public:
CefResourceSkipCallbackCppToC();
virtual ~CefResourceSkipCallbackCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_RESOURCE_SKIP_CALLBACK_CPPTOC_H_

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=67d244b48d02049dcf75c7ae45b223c756d61aa7$
// $hash=4573a140180f11230e688f73e8c09503f9123c3d$
//
#include "libcef_dll/cpptoc/response_cpptoc.h"
@ -159,6 +159,37 @@ void CEF_CALLBACK response_set_mime_type(struct _cef_response_t* self,
CefResponseCppToC::Get(self)->SetMimeType(CefString(mimeType));
}
cef_string_userfree_t CEF_CALLBACK
response_get_charset(struct _cef_response_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefString _retval = CefResponseCppToC::Get(self)->GetCharset();
// Return type: string
return _retval.DetachToUserFree();
}
void CEF_CALLBACK response_set_charset(struct _cef_response_t* self,
const cef_string_t* charset) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: charset; type: string_byref_const
DCHECK(charset);
if (!charset)
return;
// Execute
CefResponseCppToC::Get(self)->SetCharset(CefString(charset));
}
cef_string_userfree_t CEF_CALLBACK
response_get_header(struct _cef_response_t* self, const cef_string_t* name) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -267,6 +298,8 @@ CefResponseCppToC::CefResponseCppToC() {
GetStruct()->set_status_text = response_set_status_text;
GetStruct()->get_mime_type = response_get_mime_type;
GetStruct()->set_mime_type = response_set_mime_type;
GetStruct()->get_charset = response_get_charset;
GetStruct()->set_charset = response_set_charset;
GetStruct()->get_header = response_get_header;
GetStruct()->get_header_map = response_get_header_map;
GetStruct()->set_header_map = response_set_header_map;

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=11c730dca41c86a9a29ba6f32a59f55040c177b6$
// $hash=114267cdef686a8176722db4397d6c684e2d1e1f$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_CALLBACK_CTOCPP_H_
@ -20,8 +20,8 @@
#error This file can be included wrapper-side only
#endif
#include "include/capi/cef_request_handler_capi.h"
#include "include/cef_request_handler.h"
#include "include/capi/cef_request_callback_capi.h"
#include "include/cef_request_callback.h"
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"
// Wrap a C structure with a C++ class.

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=73f229f21f0d9ce78f3897fd8a2ec94261a52f48$
// $hash=00889895e17ac49f55668e395aa98a5f8312ee31$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_CONTEXT_CTOCPP_H_
@ -22,8 +22,10 @@
#include <vector>
#include "include/capi/cef_request_context_capi.h"
#include "include/capi/cef_request_context_handler_capi.h"
#include "include/capi/cef_scheme_capi.h"
#include "include/cef_request_context.h"
#include "include/cef_request_context_handler.h"
#include "include/cef_scheme.h"
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"

View File

@ -9,12 +9,16 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=4b25ca3feb69361cc3b6525fdc0c3a56710b65ec$
// $hash=4427c3dce042fac34640c02c4b07fcf6b5902f34$
//
#include "libcef_dll/ctocpp/request_context_handler_ctocpp.h"
#include "libcef_dll/cpptoc/browser_cpptoc.h"
#include "libcef_dll/cpptoc/frame_cpptoc.h"
#include "libcef_dll/cpptoc/request_context_cpptoc.h"
#include "libcef_dll/cpptoc/request_cpptoc.h"
#include "libcef_dll/cpptoc/web_plugin_info_cpptoc.h"
#include "libcef_dll/ctocpp/resource_request_handler_ctocpp.h"
// VIRTUAL METHODS - Body may be edited by hand.
@ -75,6 +79,44 @@ bool CefRequestContextHandlerCToCpp::OnBeforePluginLoad(
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall")
CefRefPtr<CefResourceRequestHandler> CefRequestContextHandlerCToCpp::
GetResourceRequestHandler(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool is_navigation,
bool is_download,
const CefString& request_initiator,
bool& disable_default_handling) {
cef_request_context_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_resource_request_handler))
return NULL;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: request; type: refptr_diff
DCHECK(request.get());
if (!request.get())
return NULL;
// Unverified params: browser, frame, request_initiator
// Translate param: disable_default_handling; type: bool_byref
int disable_default_handlingInt = disable_default_handling;
// Execute
cef_resource_request_handler_t* _retval =
_struct->get_resource_request_handler(
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
CefRequestCppToC::Wrap(request), is_navigation, is_download,
request_initiator.GetStruct(), &disable_default_handlingInt);
// Restore param:disable_default_handling; type: bool_byref
disable_default_handling = disable_default_handlingInt ? true : false;
// Return type: refptr_same
return CefResourceRequestHandlerCToCpp::Wrap(_retval);
}
// CONSTRUCTOR - Do not edit by hand.
CefRequestContextHandlerCToCpp::CefRequestContextHandlerCToCpp() {}

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=3cf1dba9c137bc586d91149920ff4558bce74a58$
// $hash=be43dedb9d443b51103d1e38e144078afc631f76$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_CONTEXT_HANDLER_CTOCPP_H_
@ -20,9 +20,7 @@
#error This file can be included DLL-side only
#endif
#include "include/capi/cef_request_context_capi.h"
#include "include/capi/cef_request_context_handler_capi.h"
#include "include/cef_request_context.h"
#include "include/cef_request_context_handler.h"
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"
@ -45,6 +43,14 @@ class CefRequestContextHandlerCToCpp
const CefString& top_origin_url,
CefRefPtr<CefWebPluginInfo> plugin_info,
PluginPolicy* plugin_policy) override;
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;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_REQUEST_CONTEXT_HANDLER_CTOCPP_H_

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=d03733ad63f8893ab03663ea46aec6ae92354efd$
// $hash=8f57157cf8f05f46b5ae96335584b5e9df02b200$
//
#include "libcef_dll/ctocpp/request_ctocpp.h"
@ -237,6 +237,53 @@ void CefRequestCToCpp::SetHeaderMap(const HeaderMap& headerMap) {
cef_string_multimap_free(headerMapMultimap);
}
NO_SANITIZE("cfi-icall")
CefString CefRequestCToCpp::GetHeaderByName(const CefString& name) {
cef_request_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_header_by_name))
return CefString();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: name; type: string_byref_const
DCHECK(!name.empty());
if (name.empty())
return CefString();
// Execute
cef_string_userfree_t _retval =
_struct->get_header_by_name(_struct, name.GetStruct());
// Return type: string
CefString _retvalStr;
_retvalStr.AttachToUserFree(_retval);
return _retvalStr;
}
NO_SANITIZE("cfi-icall")
void CefRequestCToCpp::SetHeaderByName(const CefString& name,
const CefString& value,
bool overwrite) {
cef_request_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, set_header_by_name))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: name; type: string_byref_const
DCHECK(!name.empty());
if (name.empty())
return;
// Verify param: value; type: string_byref_const
DCHECK(!value.empty());
if (value.empty())
return;
// Execute
_struct->set_header_by_name(_struct, name.GetStruct(), value.GetStruct(),
overwrite);
}
NO_SANITIZE("cfi-icall")
void CefRequestCToCpp::Set(const CefString& url,
const CefString& method,

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=98cf46c3682e03594e72a7304dfa0ddd8b8cf3d8$
// $hash=509366756c3105887a659c6539b2b0483542193b$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_CTOCPP_H_
@ -46,6 +46,10 @@ class CefRequestCToCpp
void SetPostData(CefRefPtr<CefPostData> postData) OVERRIDE;
void GetHeaderMap(HeaderMap& headerMap) OVERRIDE;
void SetHeaderMap(const HeaderMap& headerMap) OVERRIDE;
CefString GetHeaderByName(const CefString& name) OVERRIDE;
void SetHeaderByName(const CefString& name,
const CefString& value,
bool overwrite) OVERRIDE;
void Set(const CefString& url,
const CefString& method,
CefRefPtr<CefPostData> postData,

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=b3f3b31db6c1497beb7fb90a0c31c8096a73cdc7$
// $hash=f286ec7520ee6b589b3ecafa409eb3f71c081e27$
//
#include "libcef_dll/ctocpp/request_handler_ctocpp.h"
@ -18,12 +18,10 @@
#include "libcef_dll/cpptoc/frame_cpptoc.h"
#include "libcef_dll/cpptoc/request_callback_cpptoc.h"
#include "libcef_dll/cpptoc/request_cpptoc.h"
#include "libcef_dll/cpptoc/response_cpptoc.h"
#include "libcef_dll/cpptoc/select_client_certificate_callback_cpptoc.h"
#include "libcef_dll/cpptoc/sslinfo_cpptoc.h"
#include "libcef_dll/cpptoc/x509certificate_cpptoc.h"
#include "libcef_dll/ctocpp/resource_handler_ctocpp.h"
#include "libcef_dll/ctocpp/response_filter_ctocpp.h"
#include "libcef_dll/ctocpp/resource_request_handler_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
// VIRTUAL METHODS - Body may be edited by hand.
@ -102,55 +100,19 @@ bool CefRequestHandlerCToCpp::OnOpenURLFromTab(
}
NO_SANITIZE("cfi-icall")
CefRequestHandler::ReturnValue CefRequestHandlerCToCpp::OnBeforeResourceLoad(
CefRefPtr<CefResourceRequestHandler>
CefRequestHandlerCToCpp::GetResourceRequestHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefRequestCallback> callback) {
bool is_navigation,
bool is_download,
const CefString& request_initiator,
bool& disable_default_handling) {
shutdown_checker::AssertNotShutdown();
cef_request_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_before_resource_load))
return RV_CONTINUE;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return RV_CONTINUE;
// Verify param: frame; type: refptr_diff
DCHECK(frame.get());
if (!frame.get())
return RV_CONTINUE;
// Verify param: request; type: refptr_diff
DCHECK(request.get());
if (!request.get())
return RV_CONTINUE;
// Verify param: callback; type: refptr_diff
DCHECK(callback.get());
if (!callback.get())
return RV_CONTINUE;
// Execute
cef_return_value_t _retval = _struct->on_before_resource_load(
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
CefRequestCppToC::Wrap(request),
CefRequestCallbackCppToC::Wrap(callback));
// Return type: simple
return _retval;
}
NO_SANITIZE("cfi-icall")
CefRefPtr<CefResourceHandler> CefRequestHandlerCToCpp::GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) {
shutdown_checker::AssertNotShutdown();
cef_request_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_resource_handler))
if (CEF_MEMBER_MISSING(_struct, get_resource_request_handler))
return NULL;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -167,173 +129,23 @@ CefRefPtr<CefResourceHandler> CefRequestHandlerCToCpp::GetResourceHandler(
DCHECK(request.get());
if (!request.get())
return NULL;
// Unverified params: request_initiator
// Translate param: disable_default_handling; type: bool_byref
int disable_default_handlingInt = disable_default_handling;
// Execute
cef_resource_handler_t* _retval = _struct->get_resource_handler(
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
CefRequestCppToC::Wrap(request));
cef_resource_request_handler_t* _retval =
_struct->get_resource_request_handler(
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
CefRequestCppToC::Wrap(request), is_navigation, is_download,
request_initiator.GetStruct(), &disable_default_handlingInt);
// Restore param:disable_default_handling; type: bool_byref
disable_default_handling = disable_default_handlingInt ? true : false;
// Return type: refptr_same
return CefResourceHandlerCToCpp::Wrap(_retval);
}
NO_SANITIZE("cfi-icall")
void CefRequestHandlerCToCpp::OnResourceRedirect(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
CefString& new_url) {
shutdown_checker::AssertNotShutdown();
cef_request_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_resource_redirect))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Verify param: frame; type: refptr_diff
DCHECK(frame.get());
if (!frame.get())
return;
// Verify param: request; type: refptr_diff
DCHECK(request.get());
if (!request.get())
return;
// Verify param: response; type: refptr_diff
DCHECK(response.get());
if (!response.get())
return;
// Execute
_struct->on_resource_redirect(
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
CefRequestCppToC::Wrap(request), CefResponseCppToC::Wrap(response),
new_url.GetWritableStruct());
}
NO_SANITIZE("cfi-icall")
bool CefRequestHandlerCToCpp::OnResourceResponse(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) {
shutdown_checker::AssertNotShutdown();
cef_request_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_resource_response))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Verify param: frame; type: refptr_diff
DCHECK(frame.get());
if (!frame.get())
return false;
// Verify param: request; type: refptr_diff
DCHECK(request.get());
if (!request.get())
return false;
// Verify param: response; type: refptr_diff
DCHECK(response.get());
if (!response.get())
return false;
// Execute
int _retval = _struct->on_resource_response(
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
CefRequestCppToC::Wrap(request), CefResponseCppToC::Wrap(response));
// Return type: bool
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall")
CefRefPtr<CefResponseFilter> CefRequestHandlerCToCpp::GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) {
shutdown_checker::AssertNotShutdown();
cef_request_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_resource_response_filter))
return NULL;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return NULL;
// Verify param: frame; type: refptr_diff
DCHECK(frame.get());
if (!frame.get())
return NULL;
// Verify param: request; type: refptr_diff
DCHECK(request.get());
if (!request.get())
return NULL;
// Verify param: response; type: refptr_diff
DCHECK(response.get());
if (!response.get())
return NULL;
// Execute
cef_response_filter_t* _retval = _struct->get_resource_response_filter(
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
CefRequestCppToC::Wrap(request), CefResponseCppToC::Wrap(response));
// Return type: refptr_same
return CefResponseFilterCToCpp::Wrap(_retval);
}
NO_SANITIZE("cfi-icall")
void CefRequestHandlerCToCpp::OnResourceLoadComplete(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
URLRequestStatus status,
int64 received_content_length) {
shutdown_checker::AssertNotShutdown();
cef_request_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_resource_load_complete))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Verify param: frame; type: refptr_diff
DCHECK(frame.get());
if (!frame.get())
return;
// Verify param: request; type: refptr_diff
DCHECK(request.get());
if (!request.get())
return;
// Verify param: response; type: refptr_diff
DCHECK(response.get());
if (!response.get())
return;
// Execute
_struct->on_resource_load_complete(
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
CefRequestCppToC::Wrap(request), CefResponseCppToC::Wrap(response),
status, received_content_length);
return CefResourceRequestHandlerCToCpp::Wrap(_retval);
}
NO_SANITIZE("cfi-icall")
@ -382,75 +194,6 @@ bool CefRequestHandlerCToCpp::GetAuthCredentials(
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall")
bool CefRequestHandlerCToCpp::CanGetCookies(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) {
shutdown_checker::AssertNotShutdown();
cef_request_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, can_get_cookies))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Verify param: frame; type: refptr_diff
DCHECK(frame.get());
if (!frame.get())
return false;
// Verify param: request; type: refptr_diff
DCHECK(request.get());
if (!request.get())
return false;
// Execute
int _retval = _struct->can_get_cookies(
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
CefRequestCppToC::Wrap(request));
// Return type: bool
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall")
bool CefRequestHandlerCToCpp::CanSetCookie(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
const CefCookie& cookie) {
shutdown_checker::AssertNotShutdown();
cef_request_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, can_set_cookie))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Verify param: frame; type: refptr_diff
DCHECK(frame.get());
if (!frame.get())
return false;
// Verify param: request; type: refptr_diff
DCHECK(request.get());
if (!request.get())
return false;
// Execute
int _retval = _struct->can_set_cookie(
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
CefRequestCppToC::Wrap(request), &cookie);
// Return type: bool
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall")
bool CefRequestHandlerCToCpp::OnQuotaRequest(
CefRefPtr<CefBrowser> browser,
@ -487,38 +230,6 @@ bool CefRequestHandlerCToCpp::OnQuotaRequest(
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall")
void CefRequestHandlerCToCpp::OnProtocolExecution(CefRefPtr<CefBrowser> browser,
const CefString& url,
bool& allow_os_execution) {
shutdown_checker::AssertNotShutdown();
cef_request_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_protocol_execution))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Verify param: url; type: string_byref_const
DCHECK(!url.empty());
if (url.empty())
return;
// Translate param: allow_os_execution; type: bool_byref
int allow_os_executionInt = allow_os_execution;
// Execute
_struct->on_protocol_execution(_struct, CefBrowserCppToC::Wrap(browser),
url.GetStruct(), &allow_os_executionInt);
// Restore param:allow_os_execution; type: bool_byref
allow_os_execution = allow_os_executionInt ? true : false;
}
NO_SANITIZE("cfi-icall")
bool CefRequestHandlerCToCpp::OnCertificateError(
CefRefPtr<CefBrowser> browser,

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=a1df4ee1e2349b84e3748b22558d0c61a353662c$
// $hash=1e21398533e04c0dbd4143a3847b44fb43c64bc5$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_HANDLER_CTOCPP_H_
@ -45,35 +45,14 @@ class CefRequestHandlerCToCpp
const CefString& target_url,
WindowOpenDisposition target_disposition,
bool user_gesture) override;
ReturnValue OnBeforeResourceLoad(
CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefRequestCallback> callback) override;
CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) override;
void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
CefString& new_url) override;
bool OnResourceResponse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) override;
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) override;
void OnResourceLoadComplete(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
URLRequestStatus status,
int64 received_content_length) override;
bool is_navigation,
bool is_download,
const CefString& request_initiator,
bool& disable_default_handling) override;
bool GetAuthCredentials(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
bool isProxy,
@ -82,20 +61,10 @@ class CefRequestHandlerCToCpp
const CefString& realm,
const CefString& scheme,
CefRefPtr<CefAuthCallback> callback) override;
bool CanGetCookies(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) override;
bool CanSetCookie(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
const CefCookie& cookie) override;
bool OnQuotaRequest(CefRefPtr<CefBrowser> browser,
const CefString& origin_url,
int64 new_size,
CefRefPtr<CefRequestCallback> callback) override;
void OnProtocolExecution(CefRefPtr<CefBrowser> browser,
const CefString& url,
bool& allow_os_execution) override;
bool OnCertificateError(CefRefPtr<CefBrowser> browser,
cef_errorcode_t cert_error,
const CefString& request_url,

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=ebbe4bdaf0b530c72bd81e4981d979d5f72bb959$
// $hash=06de6cb6999bd9437bbd5ce4a743f5f4c7371bc6$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_RESOLVE_CALLBACK_CTOCPP_H_
@ -22,8 +22,10 @@
#include <vector>
#include "include/capi/cef_request_context_capi.h"
#include "include/capi/cef_request_context_handler_capi.h"
#include "include/capi/cef_scheme_capi.h"
#include "include/cef_request_context.h"
#include "include/cef_request_context_handler.h"
#include "include/cef_scheme.h"
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"

Some files were not shown because too many files have changed in this diff Show More