Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044).

- CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext.
- Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods.
- Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method.
- CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only).
- The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed.
- When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk.
- Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk.
- Add asynchronous callbacks for all CefCookieManager methods.
- Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath.
- cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2015-03-02 20:25:14 +00:00
parent 031f192e5a
commit ca0e381681
91 changed files with 3816 additions and 1347 deletions

View File

@ -994,7 +994,6 @@
'libcef/browser/scheme_handler.cc',
'libcef/browser/scheme_handler.h',
'libcef/browser/scheme_impl.cc',
'libcef/browser/scheme_impl.h',
'libcef/browser/software_output_device_osr.cc',
'libcef/browser/software_output_device_osr.h',
'libcef/browser/speech_recognition_manager_delegate.cc',
@ -1021,6 +1020,8 @@
'libcef/browser/url_request_context_impl.h',
'libcef/browser/url_request_context_proxy.cc',
'libcef/browser/url_request_context_proxy.h',
'libcef/browser/url_request_manager.cc',
'libcef/browser/url_request_manager.h',
'libcef/browser/url_request_interceptor.cc',
'libcef/browser/url_request_interceptor.h',
'libcef/browser/url_request_user_data.cc',

View File

@ -164,6 +164,8 @@
'libcef_dll/cpptoc/domnode_cpptoc.h',
'libcef_dll/ctocpp/domvisitor_ctocpp.cc',
'libcef_dll/ctocpp/domvisitor_ctocpp.h',
'libcef_dll/ctocpp/delete_cookies_callback_ctocpp.cc',
'libcef_dll/ctocpp/delete_cookies_callback_ctocpp.h',
'libcef_dll/ctocpp/dialog_handler_ctocpp.cc',
'libcef_dll/ctocpp/dialog_handler_ctocpp.h',
'libcef_dll/cpptoc/dictionary_value_cpptoc.cc',
@ -260,6 +262,8 @@
'libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h',
'libcef_dll/cpptoc/scheme_registrar_cpptoc.cc',
'libcef_dll/cpptoc/scheme_registrar_cpptoc.h',
'libcef_dll/ctocpp/set_cookie_callback_ctocpp.cc',
'libcef_dll/ctocpp/set_cookie_callback_ctocpp.h',
'libcef_dll/cpptoc/stream_reader_cpptoc.cc',
'libcef_dll/cpptoc/stream_reader_cpptoc.h',
'libcef_dll/cpptoc/stream_writer_cpptoc.cc',
@ -340,6 +344,8 @@
'libcef_dll/ctocpp/domnode_ctocpp.h',
'libcef_dll/cpptoc/domvisitor_cpptoc.cc',
'libcef_dll/cpptoc/domvisitor_cpptoc.h',
'libcef_dll/cpptoc/delete_cookies_callback_cpptoc.cc',
'libcef_dll/cpptoc/delete_cookies_callback_cpptoc.h',
'libcef_dll/cpptoc/dialog_handler_cpptoc.cc',
'libcef_dll/cpptoc/dialog_handler_cpptoc.h',
'libcef_dll/ctocpp/dictionary_value_ctocpp.cc',
@ -436,6 +442,8 @@
'libcef_dll/cpptoc/scheme_handler_factory_cpptoc.h',
'libcef_dll/ctocpp/scheme_registrar_ctocpp.cc',
'libcef_dll/ctocpp/scheme_registrar_ctocpp.h',
'libcef_dll/cpptoc/set_cookie_callback_cpptoc.cc',
'libcef_dll/cpptoc/set_cookie_callback_cpptoc.h',
'libcef_dll/ctocpp/stream_reader_ctocpp.cc',
'libcef_dll/ctocpp/stream_reader_ctocpp.h',
'libcef_dll/ctocpp/stream_writer_ctocpp.cc',

View File

@ -46,6 +46,8 @@ extern "C" {
#endif
struct _cef_cookie_visitor_t;
struct _cef_delete_cookies_callback_t;
struct _cef_set_cookie_callback_t;
///
// Structure used for managing cookies. The functions of this structure may be
@ -59,25 +61,27 @@ typedef struct _cef_cookie_manager_t {
///
// Set the schemes supported by this manager. By default only "http" and
// "https" schemes are supported. Must be called before any cookies are
// accessed.
// "https" schemes are supported. If |callback| is non-NULL it will be
// executed asnychronously on the IO thread after the change has been applied.
// Must be called before any cookies are accessed.
///
void (CEF_CALLBACK *set_supported_schemes)(struct _cef_cookie_manager_t* self,
cef_string_list_t schemes);
cef_string_list_t schemes, struct _cef_completion_callback_t* callback);
///
// Visit all cookies. The returned cookies are ordered by longest path, then
// by earliest creation date. Returns false (0) if cookies cannot be accessed.
// Visit all cookies on the IO thread. The returned cookies are ordered by
// longest path, then by earliest creation date. Returns false (0) if cookies
// cannot be accessed.
///
int (CEF_CALLBACK *visit_all_cookies)(struct _cef_cookie_manager_t* self,
struct _cef_cookie_visitor_t* visitor);
///
// Visit a subset of cookies. The results are filtered by the given url
// scheme, host, domain and path. If |includeHttpOnly| is true (1) HTTP-only
// cookies will also be included in the results. The returned cookies are
// ordered by longest path, then by earliest creation date. Returns false (0)
// if cookies cannot be accessed.
// Visit a subset of cookies on the IO thread. The results are filtered by the
// given url scheme, host, domain and path. If |includeHttpOnly| is true (1)
// HTTP-only cookies will also be included in the results. The returned
// cookies are ordered by longest path, then by earliest creation date.
// Returns false (0) if cookies cannot be accessed.
///
int (CEF_CALLBACK *visit_url_cookies)(struct _cef_cookie_manager_t* self,
const cef_string_t* url, int includeHttpOnly,
@ -87,24 +91,29 @@ typedef struct _cef_cookie_manager_t {
// Sets a cookie given a valid URL and explicit user-provided cookie
// attributes. This function expects each attribute to be well-formed. It will
// check for disallowed characters (e.g. the ';' character is disallowed
// within the cookie value attribute) and will return false (0) without
// setting the cookie if such characters are found. This function must be
// called on the IO thread.
// within the cookie value attribute) and fail without setting the cookie if
// such characters are found. If |callback| is non-NULL it will be executed
// asnychronously on the IO thread after the cookie has been set. Returns
// false (0) if an invalid URL is specified or if cookies cannot be accessed.
///
int (CEF_CALLBACK *set_cookie)(struct _cef_cookie_manager_t* self,
const cef_string_t* url, const struct _cef_cookie_t* cookie);
const cef_string_t* url, const struct _cef_cookie_t* cookie,
struct _cef_set_cookie_callback_t* callback);
///
// Delete all cookies that match the specified parameters. If both |url| and
// values |cookie_name| are specified all host and domain cookies matching
// |cookie_name| values are specified all host and domain cookies matching
// both will be deleted. If only |url| is specified all host cookies (but not
// domain cookies) irrespective of path will be deleted. If |url| is NULL all
// cookies for all hosts and domains will be deleted. Returns false (0) if a
// non- NULL invalid URL is specified or if cookies cannot be accessed. This
// function must be called on the IO thread.
// cookies for all hosts and domains will be deleted. If |callback| is non-
// NULL it will be executed asnychronously on the IO thread after the cookies
// have been deleted. Returns false (0) if a non-NULL invalid URL is specified
// or if cookies cannot be accessed. Cookies can alternately be deleted using
// the Visit*Cookies() functions.
///
int (CEF_CALLBACK *delete_cookies)(struct _cef_cookie_manager_t* self,
const cef_string_t* url, const cef_string_t* cookie_name);
const cef_string_t* url, const cef_string_t* cookie_name,
struct _cef_delete_cookies_callback_t* callback);
///
// Sets the directory path that will be used for storing cookie data. If
@ -112,16 +121,18 @@ typedef struct _cef_cookie_manager_t {
// stored at the specified |path|. To persist session cookies (cookies without
// an expiry date or validity interval) set |persist_session_cookies| to true
// (1). Session cookies are generally intended to be transient and most Web
// browsers do not persist them. Returns false (0) if cookies cannot be
// accessed.
// browsers do not persist them. If |callback| is non-NULL it will be executed
// asnychronously on the IO thread after the manager's storage has been
// initialized. Returns false (0) if cookies cannot be accessed.
///
int (CEF_CALLBACK *set_storage_path)(struct _cef_cookie_manager_t* self,
const cef_string_t* path, int persist_session_cookies);
const cef_string_t* path, int persist_session_cookies,
struct _cef_completion_callback_t* callback);
///
// Flush the backing store (if any) to disk and execute the specified
// |callback| on the IO thread when done. Returns false (0) if cookies cannot
// be accessed.
// Flush the backing store (if any) to disk. If |callback| is non-NULL it will
// be executed asnychronously on the IO thread after the flush is complete.
// Returns false (0) if cookies cannot be accessed.
///
int (CEF_CALLBACK *flush_store)(struct _cef_cookie_manager_t* self,
struct _cef_completion_callback_t* callback);
@ -130,20 +141,27 @@ typedef struct _cef_cookie_manager_t {
///
// Returns the global cookie manager. By default data will be stored at
// CefSettings.cache_path if specified or in memory otherwise.
// CefSettings.cache_path if specified or in memory otherwise. If |callback| is
// non-NULL it will be executed asnychronously on the IO thread after the
// manager's storage has been initialized. Using this function is equivalent to
// calling cef_request_tContext::cef_request_context_get_global_context()->get_d
// efault_cookie_manager().
///
CEF_EXPORT cef_cookie_manager_t* cef_cookie_manager_get_global_manager();
CEF_EXPORT cef_cookie_manager_t* cef_cookie_manager_get_global_manager(
struct _cef_completion_callback_t* callback);
///
// Creates a new cookie manager. If |path| is NULL data will be stored in memory
// only. Otherwise, data will be stored at the specified |path|. To persist
// session cookies (cookies without an expiry date or validity interval) set
// |persist_session_cookies| to true (1). Session cookies are generally intended
// to be transient and most Web browsers do not persist them. Returns NULL if
// creation fails.
// to be transient and most Web browsers do not persist them. If |callback| is
// non-NULL it will be executed asnychronously on the IO thread after the
// manager's storage has been initialized.
///
CEF_EXPORT cef_cookie_manager_t* cef_cookie_manager_create_manager(
const cef_string_t* path, int persist_session_cookies);
const cef_string_t* path, int persist_session_cookies,
struct _cef_completion_callback_t* callback);
///
@ -169,6 +187,44 @@ typedef struct _cef_cookie_visitor_t {
} cef_cookie_visitor_t;
///
// Structure to implement to be notified of asynchronous completion via
// cef_cookie_manager_t::set_cookie().
///
typedef struct _cef_set_cookie_callback_t {
///
// Base structure.
///
cef_base_t base;
///
// Method that will be called upon completion. |success| will be true (1) if
// the cookie was set successfully.
///
void (CEF_CALLBACK *on_complete)(struct _cef_set_cookie_callback_t* self,
int success);
} cef_set_cookie_callback_t;
///
// Structure to implement to be notified of asynchronous completion via
// cef_cookie_manager_t::delete_cookies().
///
typedef struct _cef_delete_cookies_callback_t {
///
// Base structure.
///
cef_base_t base;
///
// Method that will be called upon completion. |num_deleted| will be the
// number of cookies that were deleted or -1 if unknown.
///
void (CEF_CALLBACK *on_complete)(struct _cef_delete_cookies_callback_t* self,
int num_deleted);
} cef_delete_cookies_callback_t;
#ifdef __cplusplus
}
#endif

View File

@ -38,27 +38,30 @@
#define CEF_INCLUDE_CAPI_CEF_REQUEST_CONTEXT_CAPI_H_
#pragma once
#include "include/capi/cef_cookie_capi.h"
#include "include/capi/cef_request_context_handler_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
struct _cef_scheme_handler_factory_t;
///
// A request context provides request handling for a set of related browser
// objects. A request context is specified when creating a new browser object
// via the cef_browser_host_t static factory functions. Browser objects with
// different request contexts will never be hosted in the same render process.
// Browser objects with the same request context may or may not be hosted in the
// same render process depending on the process model. Browser objects created
// indirectly via the JavaScript window.open function or targeted links will
// share the same render process and the same request context as the source
// browser. When running in single-process mode there is only a single render
// process (the main process) and so all browsers created in single-process mode
// will share the same request context. This will be the first request context
// passed into a cef_browser_host_t static factory function and all other
// request context objects will be ignored.
// A request context provides request handling for a set of related browser or
// URL request objects. A request context can be specified when creating a new
// browser via the cef_browser_host_t static factory functions or when creating
// a new URL request via the cef_urlrequest_t static factory functions. Browser
// objects with different request contexts will never be hosted in the same
// render process. Browser objects with the same request context may or may not
// be hosted in the same render process depending on the process model. Browser
// objects created indirectly via the JavaScript window.open function or
// targeted links will share the same render process and the same request
// context as the source browser. When running in single-process mode there is
// only a single render process (the main process) and so all browsers created
// in single-process mode will share the same request context. This will be the
// first request context passed into a cef_browser_host_t static factory
// function and all other request context objects will be ignored.
///
typedef struct _cef_request_context_t {
///
@ -74,7 +77,16 @@ typedef struct _cef_request_context_t {
struct _cef_request_context_t* other);
///
// Returns true (1) if this object is the global context.
// Returns true (1) if this object is sharing the same storage as |that|
// object.
///
int (CEF_CALLBACK *is_sharing_with)(struct _cef_request_context_t* self,
struct _cef_request_context_t* other);
///
// Returns true (1) if this object is the global context. The global context
// is used by default when creating a browser or URL request with a NULL
// context argument.
///
int (CEF_CALLBACK *is_global)(struct _cef_request_context_t* self);
@ -83,6 +95,51 @@ typedef struct _cef_request_context_t {
///
struct _cef_request_context_handler_t* (CEF_CALLBACK *get_handler)(
struct _cef_request_context_t* self);
///
// Returns the cache path for this object. If NULL an "incognito mode" in-
// memory cache is being used.
///
// The resulting string must be freed by calling cef_string_userfree_free().
cef_string_userfree_t (CEF_CALLBACK *get_cache_path)(
struct _cef_request_context_t* self);
///
// Returns the default cookie manager for this object. This will be the global
// cookie manager if this object is the global request context. Otherwise,
// this will be the default cookie manager used when this request context does
// not receive a value via cef_request_tContextHandler::get_cookie_manager().
// If |callback| is non-NULL it will be executed asnychronously on the IO
// thread after the manager's storage has been initialized.
///
struct _cef_cookie_manager_t* (CEF_CALLBACK *get_default_cookie_manager)(
struct _cef_request_context_t* self,
struct _cef_completion_callback_t* callback);
///
// Register a scheme handler factory for the specified |scheme_name| and
// optional |domain_name|. An NULL |domain_name| value for a standard scheme
// will cause the factory to match all domain names. The |domain_name| value
// will be ignored for non-standard schemes. If |scheme_name| is a built-in
// scheme and no handler is returned by |factory| then the built-in scheme
// handler factory will be called. If |scheme_name| is a custom scheme then
// you must also implement the cef_app_t::on_register_custom_schemes()
// function in all processes. This function may be called multiple times to
// change or remove the factory that matches the specified |scheme_name| and
// optional |domain_name|. Returns false (0) if an error occurs. This function
// may be called on any thread in the browser process.
///
int (CEF_CALLBACK *register_scheme_handler_factory)(
struct _cef_request_context_t* self, const cef_string_t* scheme_name,
const cef_string_t* domain_name,
struct _cef_scheme_handler_factory_t* factory);
///
// Clear all registered scheme handler factories. Returns false (0) on error.
// This function may be called on any thread in the browser process.
///
int (CEF_CALLBACK *clear_scheme_handler_factories)(
struct _cef_request_context_t* self);
} cef_request_context_t;
@ -92,9 +149,19 @@ typedef struct _cef_request_context_t {
CEF_EXPORT cef_request_context_t* cef_request_context_get_global_context();
///
// Creates a new context object with the specified handler.
// Creates a new context object with the specified |settings| and optional
// |handler|.
///
CEF_EXPORT cef_request_context_t* cef_request_context_create_context(
const struct _cef_request_context_settings_t* settings,
struct _cef_request_context_handler_t* handler);
///
// Creates a new context object that shares storage with |other| and uses an
// optional |handler|.
///
CEF_EXPORT cef_request_context_t* create_context_shared(
cef_request_context_t* other,
struct _cef_request_context_handler_t* handler);

View File

@ -47,7 +47,9 @@ extern "C" {
///
// Implement this structure to provide handler implementations.
// Implement this structure to provide handler implementations. The handler
// instance will not be released until all objects related to the context have
// been destroyed.
///
typedef struct _cef_request_context_handler_t {
///
@ -56,8 +58,9 @@ typedef struct _cef_request_context_handler_t {
cef_base_t base;
///
// Called on the IO thread to retrieve the cookie manager. The global cookie
// manager will be used if this function returns NULL.
// Called on the IO thread to retrieve the cookie manager. If this function
// returns NULL the default cookie manager retrievable via
// cef_request_tContext::get_default_cookie_manager() will be used.
///
struct _cef_cookie_manager_t* (CEF_CALLBACK *get_cookie_manager)(
struct _cef_request_context_handler_t* self);

View File

@ -139,25 +139,30 @@ typedef struct _cef_scheme_handler_factory_t {
///
// Register a scheme handler factory for the specified |scheme_name| and
// optional |domain_name|. An NULL |domain_name| value for a standard scheme
// will cause the factory to match all domain names. The |domain_name| value
// will be ignored for non-standard schemes. If |scheme_name| is a built-in
// scheme and no handler is returned by |factory| then the built-in scheme
// handler factory will be called. If |scheme_name| is a custom scheme then also
// implement the cef_app_t::on_register_custom_schemes() function in all
// processes. This function may be called multiple times to change or remove the
// factory that matches the specified |scheme_name| and optional |domain_name|.
// Returns false (0) if an error occurs. This function may be called on any
// thread in the browser process.
// Register a scheme handler factory with the global request context. An NULL
// |domain_name| value for a standard scheme will cause the factory to match all
// domain names. The |domain_name| value will be ignored for non-standard
// schemes. If |scheme_name| is a built-in scheme and no handler is returned by
// |factory| then the built-in scheme handler factory will be called. If
// |scheme_name| is a custom scheme then you must also implement the
// cef_app_t::on_register_custom_schemes() function in all processes. This
// function may be called multiple times to change or remove the factory that
// matches the specified |scheme_name| and optional |domain_name|. Returns false
// (0) if an error occurs. This function may be called on any thread in the
// browser process. Using this function is equivalent to calling cef_request_tCo
// ntext::cef_request_context_get_global_context()->register_scheme_handler_fact
// ory().
///
CEF_EXPORT int cef_register_scheme_handler_factory(
const cef_string_t* scheme_name, const cef_string_t* domain_name,
cef_scheme_handler_factory_t* factory);
///
// Clear all registered scheme handler factories. Returns false (0) on error.
// This function may be called on any thread in the browser process.
// Clear all scheme handler factories registered with the global request
// context. Returns false (0) on error. This function may be called on any
// thread in the browser process. Using this function is equivalent to calling c
// ef_request_tContext::cef_request_context_get_global_context()->clear_scheme_h
// andler_factories().
///
CEF_EXPORT int cef_clear_scheme_handler_factories();

View File

@ -41,6 +41,7 @@
#include "include/capi/cef_auth_callback_capi.h"
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_request_capi.h"
#include "include/capi/cef_request_context_capi.h"
#include "include/capi/cef_response_capi.h"
#ifdef __cplusplus
@ -113,10 +114,14 @@ typedef struct _cef_urlrequest_t {
// not normally be rendered then the response may receive special handling
// inside the browser (for example, via the file download code path instead of
// the URL request code path). The |request| object will be marked as read-only
// after calling this function.
// after calling this function. In the browser process if |request_context| is
// NULL the global request context will be used. In the render process
// |request_context| must be NULL and the context associated with the current
// renderer process' browser will be used.
///
CEF_EXPORT cef_urlrequest_t* cef_urlrequest_create(
struct _cef_request_t* request, struct _cef_urlrequest_client_t* client);
struct _cef_request_t* request, struct _cef_urlrequest_client_t* client,
struct _cef_request_context_t* request_context);
///

View File

@ -43,7 +43,8 @@
#include <vector>
class CefCookieVisitor;
class CefSetCookieCallback;
class CefDeleteCookiesCallback;
///
// Class used for managing cookies. The methods of this class may be called on
@ -54,10 +55,14 @@ class CefCookieManager : public virtual CefBase {
public:
///
// Returns the global cookie manager. By default data will be stored at
// CefSettings.cache_path if specified or in memory otherwise.
// CefSettings.cache_path if specified or in memory otherwise. If |callback|
// is non-NULL it will be executed asnychronously on the IO thread after the
// manager's storage has been initialized. Using this method is equivalent to
// calling CefRequestContext::GetGlobalContext()->GetDefaultCookieManager().
///
/*--cef()--*/
static CefRefPtr<CefCookieManager> GetGlobalManager();
/*--cef(optional_param=callback)--*/
static CefRefPtr<CefCookieManager> GetGlobalManager(
CefRefPtr<CefCompletionCallback> callback);
///
// Creates a new cookie manager. If |path| is empty data will be stored in
@ -65,81 +70,98 @@ class CefCookieManager : public virtual CefBase {
// persist session cookies (cookies without an expiry date or validity
// interval) set |persist_session_cookies| to true. Session cookies are
// generally intended to be transient and most Web browsers do not persist
// them. Returns NULL if creation fails.
// them. If |callback| is non-NULL it will be executed asnychronously on the
// IO thread after the manager's storage has been initialized.
///
/*--cef(optional_param=path)--*/
/*--cef(optional_param=path,optional_param=callback)--*/
static CefRefPtr<CefCookieManager> CreateManager(
const CefString& path,
bool persist_session_cookies);
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback);
///
// Set the schemes supported by this manager. By default only "http" and
// "https" schemes are supported. Must be called before any cookies are
// accessed.
// "https" schemes are supported. If |callback| is non-NULL it will be
// executed asnychronously on the IO thread after the change has been applied.
// Must be called before any cookies are accessed.
///
/*--cef()--*/
virtual void SetSupportedSchemes(const std::vector<CefString>& schemes) =0;
/*--cef(optional_param=callback)--*/
virtual void SetSupportedSchemes(
const std::vector<CefString>& schemes,
CefRefPtr<CefCompletionCallback> callback) =0;
///
// Visit all cookies. The returned cookies are ordered by longest path, then
// by earliest creation date. Returns false if cookies cannot be accessed.
// Visit all cookies on the IO thread. The returned cookies are ordered by
// longest path, then by earliest creation date. Returns false if cookies
// cannot be accessed.
///
/*--cef()--*/
virtual bool VisitAllCookies(CefRefPtr<CefCookieVisitor> visitor) =0;
///
// Visit a subset of cookies. The results are filtered by the given url
// scheme, host, domain and path. If |includeHttpOnly| is true HTTP-only
// cookies will also be included in the results. The returned cookies are
// ordered by longest path, then by earliest creation date. Returns false if
// cookies cannot be accessed.
// Visit a subset of cookies on the IO thread. The results are filtered by the
// given url scheme, host, domain and path. If |includeHttpOnly| is true
// HTTP-only cookies will also be included in the results. The returned
// cookies are ordered by longest path, then by earliest creation date.
// Returns false if cookies cannot be accessed.
///
/*--cef()--*/
virtual bool VisitUrlCookies(const CefString& url, bool includeHttpOnly,
virtual bool VisitUrlCookies(const CefString& url,
bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor) =0;
///
// Sets a cookie given a valid URL and explicit user-provided cookie
// attributes. This function expects each attribute to be well-formed. It will
// check for disallowed characters (e.g. the ';' character is disallowed
// within the cookie value attribute) and will return false without setting
// the cookie if such characters are found. This method must be called on the
// IO thread.
// within the cookie value attribute) and fail without setting the cookie if
// such characters are found. If |callback| is non-NULL it will be executed
// asnychronously on the IO thread after the cookie has been set. Returns
// false if an invalid URL is specified or if cookies cannot be accessed.
///
/*--cef()--*/
virtual bool SetCookie(const CefString& url, const CefCookie& cookie) =0;
/*--cef(optional_param=callback)--*/
virtual bool SetCookie(const CefString& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback) =0;
///
// Delete all cookies that match the specified parameters. If both |url| and
// values |cookie_name| are specified all host and domain cookies matching
// |cookie_name| values are specified all host and domain cookies matching
// both will be deleted. If only |url| is specified all host cookies (but not
// domain cookies) irrespective of path will be deleted. If |url| is empty all
// cookies for all hosts and domains will be deleted. Returns false if a non-
// empty invalid URL is specified or if cookies cannot be accessed. This
// method must be called on the IO thread.
// cookies for all hosts and domains will be deleted. If |callback| is
// non-NULL it will be executed asnychronously on the IO thread after the
// cookies have been deleted. Returns false if a non-empty invalid URL is
// specified or if cookies cannot be accessed. Cookies can alternately be
// deleted using the Visit*Cookies() methods.
///
/*--cef(optional_param=url,optional_param=cookie_name)--*/
/*--cef(optional_param=url,optional_param=cookie_name,
optional_param=callback)--*/
virtual bool DeleteCookies(const CefString& url,
const CefString& cookie_name) =0;
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback) =0;
///
// Sets the directory path that will be used for storing cookie data. If
// |path| is empty data will be stored in memory only. Otherwise, data will be
// stored at the specified |path|. To persist session cookies (cookies without
// an expiry date or validity interval) set |persist_session_cookies| to true.
// Session cookies are generally intended to be transient and most Web browsers
// do not persist them. Returns false if cookies cannot be accessed.
// Session cookies are generally intended to be transient and most Web
// browsers do not persist them. If |callback| is non-NULL it will be executed
// asnychronously on the IO thread after the manager's storage has been
// initialized. Returns false if cookies cannot be accessed.
///
/*--cef(optional_param=path)--*/
/*--cef(optional_param=path,optional_param=callback)--*/
virtual bool SetStoragePath(const CefString& path,
bool persist_session_cookies) =0;
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback) =0;
///
// Flush the backing store (if any) to disk and execute the specified
// |callback| on the IO thread when done. Returns false if cookies cannot be
// accessed.
// Flush the backing store (if any) to disk. If |callback| is non-NULL it will
// be executed asnychronously on the IO thread after the flush is complete.
// Returns false if cookies cannot be accessed.
///
/*--cef(optional_param=handler)--*/
/*--cef(optional_param=callback)--*/
virtual bool FlushStore(CefRefPtr<CefCompletionCallback> callback) =0;
};
@ -163,4 +185,36 @@ class CefCookieVisitor : public virtual CefBase {
bool& deleteCookie) =0;
};
///
// Interface to implement to be notified of asynchronous completion via
// CefCookieManager::SetCookie().
///
/*--cef(source=client)--*/
class CefSetCookieCallback : public virtual CefBase {
public:
///
// Method that will be called upon completion. |success| will be true if the
// cookie was set successfully.
///
/*--cef()--*/
virtual void OnComplete(bool success) =0;
};
///
// Interface to implement to be notified of asynchronous completion via
// CefCookieManager::DeleteCookies().
///
/*--cef(source=client)--*/
class CefDeleteCookiesCallback : public virtual CefBase {
public:
///
// Method that will be called upon completion. |num_deleted| will be the
// number of cookies that were deleted or -1 if unknown.
///
/*--cef()--*/
virtual void OnComplete(int num_deleted) =0;
};
#endif // CEF_INCLUDE_CEF_COOKIE_H_

View File

@ -38,22 +38,26 @@
#define CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_
#pragma once
#include "include/cef_cookie.h"
#include "include/cef_request_context_handler.h"
class CefSchemeHandlerFactory;
///
// A request context provides request handling for a set of related browser
// objects. A request context is specified when creating a new browser object
// via the CefBrowserHost static factory methods. Browser objects with different
// request contexts will never be hosted in the same render process. Browser
// objects with the same request context may or may not be hosted in the same
// render process depending on the process model. Browser objects created
// indirectly via the JavaScript window.open function or targeted links will
// share the same render process and the same request context as the source
// browser. When running in single-process mode there is only a single render
// process (the main process) and so all browsers created in single-process mode
// will share the same request context. This will be the first request context
// passed into a CefBrowserHost static factory method and all other request
// context objects will be ignored.
// or URL request objects. A request context can be specified when creating a
// new browser via the CefBrowserHost static factory methods or when creating a
// new URL request via the CefURLRequest static factory methods. Browser objects
// with different request contexts will never be hosted in the same render
// process. Browser objects with the same request context may or may not be
// hosted in the same render process depending on the process model. Browser
// objects created indirectly via the JavaScript window.open function or
// targeted links will share the same render process and the same request
// context as the source browser. When running in single-process mode there is
// only a single render process (the main process) and so all browsers created
// in single-process mode will share the same request context. This will be the
// first request context passed into a CefBrowserHost static factory method and
// all other request context objects will be ignored.
///
/*--cef(source=library,no_debugct_check)--*/
class CefRequestContext : public virtual CefBase {
@ -65,10 +69,21 @@ class CefRequestContext : public virtual CefBase {
static CefRefPtr<CefRequestContext> GetGlobalContext();
///
// Creates a new context object with the specified handler.
// Creates a new context object with the specified |settings| and optional
// |handler|.
///
/*--cef(optional_param=handler)--*/
static CefRefPtr<CefRequestContext> CreateContext(
const CefRequestContextSettings& settings,
CefRefPtr<CefRequestContextHandler> handler);
///
// Creates a new context object that shares storage with |other| and uses an
// optional |handler|.
///
/*--cef(capi_name=create_context_shared,optional_param=handler)--*/
static CefRefPtr<CefRequestContext> CreateContext(
CefRefPtr<CefRequestContext> other,
CefRefPtr<CefRequestContextHandler> handler);
///
@ -79,7 +94,15 @@ class CefRequestContext : public virtual CefBase {
virtual bool IsSame(CefRefPtr<CefRequestContext> other) =0;
///
// Returns true if this object is the global context.
// Returns true if this object is sharing the same storage as |that| object.
///
/*--cef()--*/
virtual bool IsSharingWith(CefRefPtr<CefRequestContext> other) =0;
///
// Returns true if this object is the global context. The global context is
// used by default when creating a browser or URL request with a NULL context
// argument.
///
/*--cef()--*/
virtual bool IsGlobal() =0;
@ -89,6 +112,51 @@ class CefRequestContext : public virtual CefBase {
///
/*--cef()--*/
virtual CefRefPtr<CefRequestContextHandler> GetHandler() =0;
///
// Returns the cache path for this object. If empty an "incognito mode"
// in-memory cache is being used.
///
/*--cef()--*/
virtual CefString GetCachePath() =0;
///
// Returns the default cookie manager for this object. This will be the global
// cookie manager if this object is the global request context. Otherwise,
// this will be the default cookie manager used when this request context does
// not receive a value via CefRequestContextHandler::GetCookieManager(). If
// |callback| is non-NULL it will be executed asnychronously on the IO thread
// after the manager's storage has been initialized.
///
/*--cef(optional_param=callback)--*/
virtual CefRefPtr<CefCookieManager> GetDefaultCookieManager(
CefRefPtr<CefCompletionCallback> callback) =0;
///
// Register a scheme handler factory for the specified |scheme_name| and
// optional |domain_name|. An empty |domain_name| value for a standard scheme
// will cause the factory to match all domain names. The |domain_name| value
// will be ignored for non-standard schemes. If |scheme_name| is a built-in
// scheme and no handler is returned by |factory| then the built-in scheme
// handler factory will be called. If |scheme_name| is a custom scheme then
// you must also implement the CefApp::OnRegisterCustomSchemes() method in all
// processes. This function may be called multiple times to change or remove
// the factory that matches the specified |scheme_name| and optional
// |domain_name|. Returns false if an error occurs. This function may be
// called on any thread in the browser process.
///
/*--cef(optional_param=domain_name,optional_param=factory)--*/
virtual bool RegisterSchemeHandlerFactory(
const CefString& scheme_name,
const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) =0;
///
// Clear all registered scheme handler factories. Returns false on error. This
// function may be called on any thread in the browser process.
///
/*--cef()--*/
virtual bool ClearSchemeHandlerFactories() =0;
};
#endif // CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_

View File

@ -42,14 +42,17 @@
#include "include/cef_cookie.h"
///
// Implement this interface to provide handler implementations.
// Implement this interface to provide handler implementations. The handler
// instance will not be released until all objects related to the context have
// been destroyed.
///
/*--cef(source=client,no_debugct_check)--*/
class CefRequestContextHandler : public virtual CefBase {
public:
///
// Called on the IO thread to retrieve the cookie manager. The global cookie
// manager will be used if this method returns NULL.
// Called on the IO thread to retrieve the cookie manager. If this method
// returns NULL the default cookie manager retrievable via
// CefRequestContext::GetDefaultCookieManager() will be used.
///
/*--cef()--*/
virtual CefRefPtr<CefCookieManager> GetCookieManager() { return NULL; }

View File

@ -49,17 +49,18 @@ class CefSchemeHandlerFactory;
///
// Register a scheme handler factory for the specified |scheme_name| and
// optional |domain_name|. An empty |domain_name| value for a standard scheme
// will cause the factory to match all domain names. The |domain_name| value
// will be ignored for non-standard schemes. If |scheme_name| is a built-in
// scheme and no handler is returned by |factory| then the built-in scheme
// handler factory will be called. If |scheme_name| is a custom scheme then
// also implement the CefApp::OnRegisterCustomSchemes() method in all processes.
// This function may be called multiple times to change or remove the factory
// that matches the specified |scheme_name| and optional |domain_name|.
// Returns false if an error occurs. This function may be called on any thread
// in the browser process.
// Register a scheme handler factory with the global request context. An empty
// |domain_name| value for a standard scheme will cause the factory to match all
// domain names. The |domain_name| value will be ignored for non-standard
// schemes. If |scheme_name| is a built-in scheme and no handler is returned by
// |factory| then the built-in scheme handler factory will be called. If
// |scheme_name| is a custom scheme then you must also implement the
// CefApp::OnRegisterCustomSchemes() method in all processes. This function may
// be called multiple times to change or remove the factory that matches the
// specified |scheme_name| and optional |domain_name|. Returns false if an error
// occurs. This function may be called on any thread in the browser process.
// Using this function is equivalent to calling
// CefRequestContext::GetGlobalContext()->RegisterSchemeHandlerFactory().
///
/*--cef(optional_param=domain_name,optional_param=factory)--*/
bool CefRegisterSchemeHandlerFactory(
@ -68,8 +69,10 @@ bool CefRegisterSchemeHandlerFactory(
CefRefPtr<CefSchemeHandlerFactory> factory);
///
// Clear all registered scheme handler factories. Returns false on error. This
// function may be called on any thread in the browser process.
// Clear all scheme handler factories registered with the global request
// context. Returns false on error. This function may be called on any thread in
// the browser process. Using this function is equivalent to calling
// CefRequestContext::GetGlobalContext()->ClearSchemeHandlerFactories().
///
/*--cef()--*/
bool CefClearSchemeHandlerFactories();

View File

@ -41,6 +41,7 @@
#include "include/cef_auth_callback.h"
#include "include/cef_base.h"
#include "include/cef_request.h"
#include "include/cef_request_context.h"
#include "include/cef_response.h"
class CefURLRequestClient;
@ -68,12 +69,16 @@ class CefURLRequest : public virtual CefBase {
// would not normally be rendered then the response may receive special
// handling inside the browser (for example, via the file download code path
// instead of the URL request code path). The |request| object will be marked
// as read-only after calling this method.
// as read-only after calling this method. In the browser process if
// |request_context| is empty the global request context will be used. In the
// render process |request_context| must be empty and the context associated
// with the current renderer process' browser will be used.
///
/*--cef()--*/
/*--cef(optional_param=request_context)--*/
static CefRefPtr<CefURLRequest> Create(
CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client);
CefRefPtr<CefURLRequestClient> client,
CefRefPtr<CefRequestContext> request_context);
///
// Returns the request object used to create this URL request. The returned

View File

@ -234,20 +234,34 @@ typedef struct _cef_settings_t {
int command_line_args_disabled;
///
// The location where cache data will be stored on disk. If empty an in-memory
// cache will be used for some features and a temporary disk cache for others.
// HTML5 databases such as localStorage will only persist across sessions if a
// cache path is specified.
// The location where cache data will be stored on disk. If empty then
// browsers will be created in "incognito mode" where in-memory caches are
// used for storage and no data is persisted to disk. HTML5 databases such as
// localStorage will only persist across sessions if a cache path is
// specified. Can be overridden for individual CefRequestContext instances via
// the CefRequestContextSettings.cache_path value.
///
cef_string_t cache_path;
///
// The location where user data such as spell checking dictionary files will
// be stored on disk. If empty then the default platform-specific user data
// directory will be used ("~/.cef_user_data" directory on Linux,
// "~/Library/Application Support/CEF/User Data" directory on Mac OS X,
// "Local Settings\Application Data\CEF\User Data" directory under the user
// profile directory on Windows).
///
cef_string_t user_data_path;
///
// To persist session cookies (cookies without an expiry date or validity
// interval) by default when using the global cookie manager set this value to
// true. Session cookies are generally intended to be transient and most Web
// browsers do not persist them. A |cache_path| value must also be specified to
// enable this feature. Also configurable using the "persist-session-cookies"
// command-line switch.
// browsers do not persist them. A |cache_path| value must also be specified
// to enable this feature. Also configurable using the
// "persist-session-cookies" command-line switch. Can be overridden for
// individual CefRequestContext instances via the
// CefRequestContextSettings.persist_session_cookies value.
///
int persist_session_cookies;
@ -370,7 +384,9 @@ typedef struct _cef_settings_t {
// Enabling this setting can lead to potential security vulnerabilities like
// "man in the middle" attacks. Applications that load content from the
// internet should not enable this setting. Also configurable using the
// "ignore-certificate-errors" command-line switch.
// "ignore-certificate-errors" command-line switch. Can be overridden for
// individual CefRequestContext instances via the
// CefRequestContextSettings.ignore_certificate_errors value.
///
int ignore_certificate_errors;
@ -386,11 +402,64 @@ typedef struct _cef_settings_t {
// Comma delimited ordered list of language codes without any whitespace that
// will be used in the "Accept-Language" HTTP header. May be overridden on a
// per-browser basis using the CefBrowserSettings.accept_language_list value.
// If both values are empty then "en-US,en" will be used.
// If both values are empty then "en-US,en" will be used. Can be overridden
// for individual CefRequestContext instances via the
// CefRequestContextSettings.accept_language_list value.
///
cef_string_t accept_language_list;
} cef_settings_t;
///
// Request context initialization settings. Specify NULL or 0 to get the
// recommended default values.
///
typedef struct _cef_request_context_settings_t {
///
// Size of this structure.
///
size_t size;
///
// The location where cache data will be stored on disk. If empty then
// browsers will be created in "incognito mode" where in-memory caches are
// used for storage and no data is persisted to disk. HTML5 databases such as
// localStorage will only persist across sessions if a cache path is
// specified. To share the global browser cache and related configuration set
// this value to match the CefSettings.cache_path value.
///
cef_string_t cache_path;
///
// To persist session cookies (cookies without an expiry date or validity
// interval) by default when using the global cookie manager set this value to
// true. Session cookies are generally intended to be transient and most Web
// browsers do not persist them. Can be set globally using the
// CefSettings.persist_session_cookies value. This value will be ignored if
// |cache_path| is empty or if it matches the CefSettings.cache_path value.
///
int persist_session_cookies;
///
// Set to true (1) to ignore errors related to invalid SSL certificates.
// Enabling this setting can lead to potential security vulnerabilities like
// "man in the middle" attacks. Applications that load content from the
// internet should not enable this setting. Can be set globally using the
// CefSettings.ignore_certificate_errors value. This value will be ignored if
// |cache_path| matches the CefSettings.cache_path value.
///
int ignore_certificate_errors;
///
// Comma delimited ordered list of language codes without any whitespace that
// will be used in the "Accept-Language" HTTP header. Can be set globally
// using the CefSettings.accept_language_list value or overridden on a per-
// browser basis using the CefBrowserSettings.accept_language_list value. If
// all values are empty then "en-US,en" will be used. This value will be
// ignored if |cache_path| matches the CefSettings.cache_path value.
///
cef_string_t accept_language_list;
} cef_request_context_settings_t;
///
// Browser initialization settings. Specify NULL or 0 to get the recommended
// default values. The consequences of using custom values may not be well
@ -746,6 +815,18 @@ typedef enum {
// module).
///
PK_FILE_MODULE,
///
// "Local Settings\Application Data" directory under the user profile
// directory on Windows.
///
PK_LOCAL_APP_DATA,
///
// "Application Data" directory under the user profile directory on Windows
// and "~/Library/Application Support" directory on Mac OS X.
///
PK_USER_DATA,
} cef_path_key_t;
///

View File

@ -418,6 +418,7 @@ struct CefSettingsTraits {
static inline void clear(struct_type* s) {
cef_string_clear(&s->browser_subprocess_path);
cef_string_clear(&s->cache_path);
cef_string_clear(&s->user_data_path);
cef_string_clear(&s->user_agent);
cef_string_clear(&s->product_version);
cef_string_clear(&s->locale);
@ -441,6 +442,8 @@ struct CefSettingsTraits {
cef_string_set(src->cache_path.str, src->cache_path.length,
&target->cache_path, copy);
cef_string_set(src->user_data_path.str, src->user_data_path.length,
&target->user_data_path, copy);
target->persist_session_cookies = src->persist_session_cookies;
cef_string_set(src->user_agent.str, src->user_agent.length,
@ -477,6 +480,36 @@ struct CefSettingsTraits {
typedef CefStructBase<CefSettingsTraits> CefSettings;
struct CefRequestContextSettingsTraits {
typedef cef_request_context_settings_t struct_type;
static inline void init(struct_type* s) {
s->size = sizeof(struct_type);
}
static inline void clear(struct_type* s) {
cef_string_clear(&s->cache_path);
cef_string_clear(&s->accept_language_list);
}
static inline void set(const struct_type* src, struct_type* target,
bool copy) {
cef_string_set(src->cache_path.str, src->cache_path.length,
&target->cache_path, copy);
target->persist_session_cookies = src->persist_session_cookies;
target->ignore_certificate_errors = src->ignore_certificate_errors;
cef_string_set(src->accept_language_list.str,
src->accept_language_list.length, &target->accept_language_list, copy);
}
};
///
// Class representing request context initialization settings.
///
typedef CefStructBase<CefRequestContextSettingsTraits>
CefRequestContextSettings;
struct CefBrowserSettingsTraits {
typedef cef_browser_settings_t struct_type;

View File

@ -6,7 +6,9 @@
#define CEF_LIBCEF_BROWSER_BROWSER_CONTEXT_H_
#pragma once
#include "include/cef_request_context_handler.h"
#include "libcef/browser/resource_context.h"
#include "libcef/browser/url_request_context_getter_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@ -26,11 +28,12 @@
//
// RCI = CefRequestContextImpl
// Implements the CefRequestContext interface which is exposed to clients.
// References the global BCI or creates a new BCP.
// References the isolated BCI or creates a new BCP.
//
// BCI = CefBrowserContextImpl
// Entry point from WC when using the global RCI. Owns the RC and creates the
// URCGI. Life span controlled by RCI and CefBrowserMainParts.
// Entry point from WC when using an isolated RCI. Owns the RC and creates the
// URCGI. Life span controlled by RCI and (for the global context)
// CefBrowserMainParts.
//
// BCP = CefBrowserContextProxy
// Entry point from WC when using a custom RCI. Owns the RC and creates the
@ -42,14 +45,14 @@
// controlled by BCI/BCP.
//
// URCGI = CefURLRequestContextGetterImpl
// Creates and owns the URCI. Life span is controlled by RC and
// CefBrowserMainParts.
// Creates and owns the URCI. Life span is controlled by RC and (for the
// global context) CefBrowserMainParts.
//
// URCGP = CefURLRequestContextGetterProxy
// Creates and owns the URCP. Life span is controlled by RC.
//
// URCI = CefURLRequestContextImpl
// Owns various network-related objects including the global cookie manager.
// Owns various network-related objects including the isolated cookie manager.
// Owns URLRequest objects which must be destroyed first. Life span is
// controlled by URCGI.
//
@ -61,7 +64,7 @@
// CSP = CefCookieStoreProxy
// Gives the CefCookieManager instance retrieved via CefRequestContextHandler
// an opportunity to handle cookie requests. Otherwise forwards requests via
// URCI to the global cookie manager. Life span is controlled by URCP.
// URCI to the isolated cookie manager. Life span is controlled by URCP.
//
//
// Relationship diagram:
@ -69,7 +72,7 @@
// own = ownership (scoped_ptr)
// ptr = raw pointer
//
// CefBrowserMainParts global cookie manager, etc...
// CefBrowserMainParts isolated cookie manager, etc...
// | | ^
// ref ref ref/own
// v v |
@ -103,7 +106,7 @@
// Main entry point for configuring behavior on a per-browser basis. An instance
// of this class is passed to WebContents::Create in CefBrowserHostImpl::
// CreateInternal. Only accessed on the UI thread.
// CreateInternal. Only accessed on the UI thread unless otherwise indicated.
class CefBrowserContext
: public content::BrowserContext,
public base::RefCountedThreadSafe<
@ -114,6 +117,18 @@ class CefBrowserContext
// BrowserContext methods.
content::ResourceContext* GetResourceContext() override;
// Returns true if this is a CefBrowserContextProxy object. Safe to call from
// any thread.
virtual bool IsProxy() const = 0;
// Returns the settings associated with this object. Safe to call from any
// thread.
virtual const CefRequestContextSettings& GetSettings() const = 0;
// Returns the handler associated with this object. Safe to call from any
// thread.
virtual CefRefPtr<CefRequestContextHandler> GetHandler() const = 0;
// Called from CefContentBrowserClient to create the URLRequestContextGetter.
virtual net::URLRequestContextGetter* CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,

View File

@ -6,30 +6,129 @@
#include <map>
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/thread_util.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/net/proxy_service_factory.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "net/proxy/proxy_config_service.h"
using content::BrowserThread;
CefBrowserContextImpl::CefBrowserContextImpl() {
namespace {
// Manages the global mapping of cache path to Impl instance.
class ImplManager {
public:
ImplManager() {}
~ImplManager() {
DCHECK(map_.empty());
}
CefBrowserContextImpl* GetImpl(const base::FilePath& path) {
CEF_REQUIRE_UIT();
DCHECK(!path.empty());
PathMap::const_iterator it = map_.find(path);
if (it != map_.end())
return it->second;
return NULL;
}
void AddImpl(const base::FilePath& path, CefBrowserContextImpl* impl) {
CEF_REQUIRE_UIT();
DCHECK(!path.empty());
DCHECK(GetImpl(path) == NULL);
map_.insert(std::make_pair(path, impl));
}
void RemoveImpl(const base::FilePath& path) {
CEF_REQUIRE_UIT();
DCHECK(!path.empty());
PathMap::iterator it = map_.find(path);
DCHECK(it != map_.end());
if (it != map_.end())
map_.erase(it);
}
private:
typedef std::map<base::FilePath, CefBrowserContextImpl*> PathMap;
PathMap map_;
DISALLOW_COPY_AND_ASSIGN(ImplManager);
};
base::LazyInstance<ImplManager> g_manager = LAZY_INSTANCE_INITIALIZER;
} // namespace
CefBrowserContextImpl::CefBrowserContextImpl(
const CefRequestContextSettings& settings)
: settings_(settings) {
}
CefBrowserContextImpl::~CefBrowserContextImpl() {
pref_proxy_config_tracker_->DetachFromPrefService();
// Delete the download manager delegate here because otherwise we'll crash
// when it's accessed from the content::BrowserContext destructor.
if (download_manager_delegate_.get())
download_manager_delegate_.reset(NULL);
if (!cache_path_.empty())
g_manager.Get().RemoveImpl(cache_path_);
}
void CefBrowserContextImpl::Initialize() {
cache_path_ = base::FilePath(CefString(&settings_.cache_path));
if (!cache_path_.empty()) {
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (!base::DirectoryExists(cache_path_) &&
!base::CreateDirectory(cache_path_)) {
LOG(ERROR) << "The cache_path directory could not be created: " <<
cache_path_.value();
cache_path_ = base::FilePath();
CefString(&settings_.cache_path).clear();
}
}
if (!cache_path_.empty())
g_manager.Get().AddImpl(cache_path_, this);
if (settings_.accept_language_list.length == 0) {
// Use the global language list setting.
CefString(&settings_.accept_language_list) =
CefString(&CefContext::Get()->settings().accept_language_list);
}
// Initialize proxy configuration tracker.
pref_proxy_config_tracker_.reset(
ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
CefContentBrowserClient::Get()->pref_service()));
// Create the CefURLRequestContextGetterImpl via an indirect call to
// CreateRequestContext. Triggers a call to CefURLRequestContextGetterImpl::
// GetURLRequestContext() on the IO thread which creates the
// CefURLRequestContextImpl.
GetRequestContext();
DCHECK(url_request_getter_.get());
}
// static
scoped_refptr<CefBrowserContextImpl> CefBrowserContextImpl::GetForCachePath(
const base::FilePath& cache_path) {
return g_manager.Get().GetImpl(cache_path);
}
base::FilePath CefBrowserContextImpl::GetPath() const {
return CefContext::Get()->cache_path();
return cache_path_;
}
scoped_ptr<content::ZoomLevelDelegate>
@ -38,7 +137,7 @@ scoped_ptr<content::ZoomLevelDelegate>
}
bool CefBrowserContextImpl::IsOffTheRecord() const {
return false;
return cache_path_.empty();
}
content::DownloadManagerDelegate*
@ -98,14 +197,36 @@ content::SSLHostStateDelegate*
return NULL;
}
bool CefBrowserContextImpl::IsProxy() const {
return false;
}
const CefRequestContextSettings& CefBrowserContextImpl::GetSettings() const {
return settings_;
}
CefRefPtr<CefRequestContextHandler> CefBrowserContextImpl::GetHandler() const {
return NULL;
}
net::URLRequestContextGetter* CefBrowserContextImpl::CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
CEF_REQUIRE_UIT();
DCHECK(!url_request_getter_.get());
// Initialize the proxy configuration service.
scoped_ptr<net::ProxyConfigService> proxy_config_service;
proxy_config_service.reset(
ProxyServiceFactory::CreateProxyConfigService(
pref_proxy_config_tracker_.get()));
url_request_getter_ = new CefURLRequestContextGetterImpl(
settings_,
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
protocol_handlers,
proxy_config_service.Pass(),
request_interceptors.Pass());
resource_context()->set_url_request_context_getter(url_request_getter_.get());
return url_request_getter_.get();

View File

@ -13,6 +13,7 @@
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/net/pref_proxy_config_tracker.h"
namespace content {
class DownloadManagerDelegate;
@ -21,12 +22,21 @@ class SpeechRecognitionPreferences;
class CefDownloadManagerDelegate;
// Global BrowserContext implementation. Life span is controlled by
// CefRequestContextImpl and CefBrowserMainParts. Only accessed on the UI
// thread. See browser_context.h for an object relationship diagram.
// Isolated BrowserContext implementation. Life span is controlled by
// CefRequestContextImpl and (for the main context) CefBrowserMainParts. Only
// accessed on the UI thread unless otherwise indicated. See browser_context.h
// for an object relationship diagram.
class CefBrowserContextImpl : public CefBrowserContext {
public:
CefBrowserContextImpl();
explicit CefBrowserContextImpl(const CefRequestContextSettings& settings);
// Returns the existing instance, if any, associated with the specified
// |cache_path|.
static scoped_refptr<CefBrowserContextImpl> GetForCachePath(
const base::FilePath& cache_path);
// Must be called immediately after this object is created.
void Initialize();
// BrowserContext methods.
base::FilePath GetPath() const override;
@ -50,6 +60,9 @@ class CefBrowserContextImpl : public CefBrowserContext {
content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
// CefBrowserContext methods.
bool IsProxy() const override;
const CefRequestContextSettings& GetSettings() const override;
CefRefPtr<CefRequestContextHandler> GetHandler() const override;
net::URLRequestContextGetter* CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors)
@ -61,6 +74,11 @@ class CefBrowserContextImpl : public CefBrowserContext {
content::URLRequestInterceptorScopedVector request_interceptors)
override;
// Guaranteed to exist once this object has been initialized.
scoped_refptr<CefURLRequestContextGetterImpl> request_context() const {
return url_request_getter_;
}
private:
// Only allow deletion via scoped_refptr().
friend struct content::BrowserThread::DeleteOnThread<
@ -69,6 +87,12 @@ class CefBrowserContextImpl : public CefBrowserContext {
~CefBrowserContextImpl() override;
// Members initialized during construction are safe to access from any thread.
CefRequestContextSettings settings_;
base::FilePath cache_path_;
scoped_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;
scoped_ptr<CefDownloadManagerDelegate> download_manager_delegate_;
scoped_refptr<CefURLRequestContextGetterImpl> url_request_getter_;

View File

@ -17,6 +17,8 @@ CefBrowserContextProxy::CefBrowserContextProxy(
scoped_refptr<CefBrowserContextImpl> parent)
: handler_(handler),
parent_(parent) {
DCHECK(handler_.get());
DCHECK(parent_.get());
}
CefBrowserContextProxy::~CefBrowserContextProxy() {
@ -93,13 +95,25 @@ content::SSLHostStateDelegate*
return parent_->GetSSLHostStateDelegate();
}
bool CefBrowserContextProxy::IsProxy() const {
return true;
}
const CefRequestContextSettings& CefBrowserContextProxy::GetSettings() const {
return parent_->GetSettings();
}
CefRefPtr<CefRequestContextHandler> CefBrowserContextProxy::GetHandler() const {
return handler_;
}
net::URLRequestContextGetter* CefBrowserContextProxy::CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
CEF_REQUIRE_UIT();
DCHECK(!url_request_getter_.get());
url_request_getter_ =
new CefURLRequestContextGetterProxy(handler_,
CefContentBrowserClient::Get()->request_context().get());
new CefURLRequestContextGetterProxy(handler_, parent_->request_context());
resource_context()->set_url_request_context_getter(url_request_getter_.get());
return url_request_getter_.get();
}

View File

@ -6,7 +6,6 @@
#define CEF_LIBCEF_BROWSER_BROWSER_CONTEXT_PROXY_H_
#pragma once
#include "include/cef_request_context_handler.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_context_impl.h"
@ -52,6 +51,9 @@ class CefBrowserContextProxy : public CefBrowserContext {
content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
// CefBrowserContext methods.
bool IsProxy() const override;
const CefRequestContextSettings& GetSettings() const override;
CefRefPtr<CefRequestContextHandler> GetHandler() const override;
net::URLRequestContextGetter* CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors)
@ -63,7 +65,9 @@ class CefBrowserContextProxy : public CefBrowserContext {
content::URLRequestInterceptorScopedVector request_interceptors)
override;
CefRefPtr<CefRequestContextHandler> handler() const { return handler_; }
scoped_refptr<CefBrowserContextImpl> parent() const {
return parent_;
}
private:
// Only allow deletion via scoped_refptr().
@ -73,8 +77,10 @@ class CefBrowserContextProxy : public CefBrowserContext {
~CefBrowserContextProxy() override;
// Members initialized during construction are safe to access from any thread.
CefRefPtr<CefRequestContextHandler> handler_;
scoped_refptr<CefBrowserContextImpl> parent_;
scoped_ptr<CefDownloadManagerDelegate> download_manager_delegate_;
scoped_refptr<CefURLRequestContextGetterProxy> url_request_getter_;

View File

@ -397,15 +397,16 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::CreateInternal(
DCHECK(opener == kNullWindowHandle || browser_info->is_popup());
if (!web_contents) {
scoped_refptr<CefBrowserContext> browser_context = NULL;
if (request_context.get()) {
CefRequestContextImpl* request_context_impl =
static_cast<CefRequestContextImpl*>(request_context.get());
browser_context = request_context_impl->GetOrCreateBrowserContext();
} else {
browser_context = CefContentBrowserClient::Get()->browser_context();
}
DCHECK(browser_context);
// Get or create the request context and browser context.
CefRefPtr<CefRequestContextImpl> request_context_impl =
CefRequestContextImpl::GetForRequestContext(request_context);
DCHECK(request_context_impl.get());
scoped_refptr<CefBrowserContext> browser_context =
request_context_impl->GetBrowserContext();
DCHECK(browser_context.get());
if (!request_context.get())
request_context = request_context_impl.get();
content::WebContents::CreateParams create_params(
browser_context.get());
@ -424,7 +425,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::CreateInternal(
CefRefPtr<CefBrowserHostImpl> browser =
new CefBrowserHostImpl(window_info, settings, client, web_contents,
browser_info, opener);
browser_info, opener, request_context);
if (!browser->IsWindowless() && !browser->PlatformCreateWindow())
return NULL;
@ -2236,6 +2237,8 @@ void CefBrowserHostImpl::WebContentsCreated(
const base::string16& frame_name,
const GURL& target_url,
content::WebContents* new_contents) {
DCHECK(new_contents);
scoped_ptr<PendingPopupInfo> pending_popup_info;
{
base::AutoLock lock_scope(pending_popup_info_lock_);
@ -2261,11 +2264,19 @@ void CefBrowserHostImpl::WebContentsCreated(
DCHECK(!info->is_popup());
}
scoped_refptr<CefBrowserContext> browser_context =
static_cast<CefBrowserContext*>(new_contents->GetBrowserContext());
DCHECK(browser_context.get());
CefRefPtr<CefRequestContext> request_context =
CefRequestContextImpl::GetForBrowserContext(browser_context).get();
DCHECK(request_context.get());
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::CreateInternal(pending_popup_info->window_info,
pending_popup_info->settings,
pending_popup_info->client,
new_contents, info, opener, NULL);
new_contents, info, opener,
request_context);
}
void CefBrowserHostImpl::DidNavigateMainFramePostCommit(
@ -2725,13 +2736,15 @@ CefBrowserHostImpl::CefBrowserHostImpl(
CefRefPtr<CefClient> client,
content::WebContents* web_contents,
scoped_refptr<CefBrowserInfo> browser_info,
CefWindowHandle opener)
CefWindowHandle opener,
CefRefPtr<CefRequestContext> request_context)
: content::WebContentsObserver(web_contents),
window_info_(window_info),
settings_(settings),
client_(client),
browser_info_(browser_info),
opener_(opener),
request_context_(request_context),
is_loading_(false),
can_go_back_(false),
can_go_forward_(false),
@ -2753,16 +2766,14 @@ CefBrowserHostImpl::CefBrowserHostImpl(
window_x11_ = NULL;
#endif
DCHECK(request_context_.get());
DCHECK(!browser_info_->browser().get());
browser_info_->set_browser(this);
web_contents_.reset(web_contents);
web_contents->SetDelegate(this);
scoped_refptr<CefBrowserContext> browser_context =
static_cast<CefBrowserContext*>(web_contents->GetBrowserContext());
request_context_ = new CefRequestContextImpl(browser_context);
registrar_.reset(new content::NotificationRegistrar);
registrar_->Add(this, content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
content::Source<content::WebContents>(web_contents));

View File

@ -499,7 +499,8 @@ class CefBrowserHostImpl : public CefBrowserHost,
CefRefPtr<CefClient> client,
content::WebContents* web_contents,
scoped_refptr<CefBrowserInfo> browser_info,
CefWindowHandle opener);
CefWindowHandle opener,
CefRefPtr<CefRequestContext> request_context);
// Updates and returns an existing frame or creates a new frame. Pass
// CefFrameHostImpl::kUnspecifiedFrameId for |parent_frame_id| if unknown.

View File

@ -10,6 +10,7 @@
#include "libcef/browser/browser_context_proxy.h"
#include "libcef/browser/browser_message_loop.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/devtools_delegate.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/net_resource_provider.h"
@ -18,7 +19,6 @@
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/net/proxy_service_factory.h"
#include "content/browser/webui/content_web_ui_controller_factory.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/web_ui_controller_factory.h"
@ -118,31 +118,16 @@ int CefBrowserMainParts::PreCreateThreads() {
// Initialize the V8 proxy integration.
net::ProxyResolverV8::EnsureIsolateCreated();
// Initialize proxy configuration tracker.
pref_proxy_config_tracker_.reset(
ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
pref_service_.get()));
return 0;
}
void CefBrowserMainParts::PreMainMessageLoopRun() {
CefRequestContextSettings settings;
CefContext::Get()->PopulateRequestContextSettings(&settings);
// Create the global BrowserContext.
global_browser_context_ = new CefBrowserContextImpl();
// Initialize the proxy configuration service. This needs to occur before
// CefURLRequestContextGetter::GetURLRequestContext() is called for the
// first time.
proxy_config_service_.reset(
ProxyServiceFactory::CreateProxyConfigService(
pref_proxy_config_tracker_.get()));
// Create the global URLRequestContextGetter via an indirect call to
// CefBrowserContextImpl::CreateRequestContext. Triggers a call to
// CefURLRequestContextGetter::GetURLRequestContext() on the IO thread which
// creates the URLRequestContext.
global_request_context_ = static_cast<CefURLRequestContextGetterImpl*>(
global_browser_context_->GetRequestContext());
global_browser_context_ = new CefBrowserContextImpl(settings);
global_browser_context_->Initialize();
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
@ -164,9 +149,7 @@ void CefBrowserMainParts::PostMainMessageLoopRun() {
devtools_delegate_->Stop();
devtools_delegate_ = NULL;
}
pref_proxy_config_tracker_->DetachFromPrefService();
global_request_context_ = NULL;
global_browser_context_ = NULL;
#ifndef NDEBUG
@ -176,8 +159,6 @@ void CefBrowserMainParts::PostMainMessageLoopRun() {
}
void CefBrowserMainParts::PostDestroyThreads() {
pref_proxy_config_tracker_.reset(NULL);
#if defined(USE_AURA)
aura::Env::DeleteInstance();
delete views::ViewsDelegate::views_delegate;

View File

@ -15,9 +15,7 @@
#include "base/memory/scoped_vector.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_piece.h"
#include "chrome/browser/net/pref_proxy_config_tracker.h"
#include "content/public/browser/browser_main_parts.h"
#include "net/proxy/proxy_config_service.h"
#include "net/url_request/url_request_context_getter.h"
namespace base {
@ -48,27 +46,18 @@ class CefBrowserMainParts : public content::BrowserMainParts {
scoped_refptr<CefBrowserContextImpl> browser_context() const {
return global_browser_context_;
}
scoped_refptr<CefURLRequestContextGetterImpl> request_context() const {
return global_request_context_;
}
CefDevToolsDelegate* devtools_delegate() const {
return devtools_delegate_;
}
PrefService* pref_service() const { return pref_service_.get(); }
scoped_ptr<net::ProxyConfigService> proxy_config_service() {
return proxy_config_service_.Pass();
}
private:
void PlatformInitialize();
void PlatformCleanup();
scoped_refptr<CefBrowserContextImpl> global_browser_context_;
scoped_refptr<CefURLRequestContextGetterImpl> global_request_context_;
CefDevToolsDelegate* devtools_delegate_; // Deletes itself.
scoped_ptr<base::MessageLoop> message_loop_;
scoped_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;
scoped_ptr<net::ProxyConfigService> proxy_config_service_;
scoped_refptr<CefBrowserPrefStore> pref_store_;
scoped_ptr<PrefService> pref_service_;

View File

@ -8,6 +8,7 @@
#include "libcef/browser/browser_context.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/request_context_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_user_data.h"
#include "libcef/common/http_header_utils.h"
@ -17,6 +18,7 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/url_fetcher.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
@ -28,6 +30,7 @@
#include "net/url_request/url_fetcher_response_writer.h"
#include "net/url_request/url_request_status.h"
using content::BrowserThread;
namespace {
@ -128,10 +131,12 @@ class CefBrowserURLRequest::Context
public:
Context(CefRefPtr<CefBrowserURLRequest> url_request,
CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client)
CefRefPtr<CefURLRequestClient> client,
CefRefPtr<CefRequestContext> request_context)
: url_request_(url_request),
request_(request),
client_(client),
request_context_(request_context),
message_loop_proxy_(base::MessageLoop::current()->message_loop_proxy()),
status_(UR_IO_PENDING),
error_code_(ERR_NONE),
@ -169,13 +174,48 @@ class CefBrowserURLRequest::Context
return false;
}
BrowserThread::PostTaskAndReply(
BrowserThread::UI,
FROM_HERE,
base::Bind(&CefBrowserURLRequest::Context::GetRequestContextOnUIThread,
this),
base::Bind(&CefBrowserURLRequest::Context::ContinueOnOriginatingThread,
this, url, request_type));
return true;
}
void GetRequestContextOnUIThread() {
CEF_REQUIRE_UIT();
// Get or create the request context and browser context.
CefRefPtr<CefRequestContextImpl> request_context_impl =
CefRequestContextImpl::GetForRequestContext(request_context_);
DCHECK(request_context_impl.get());
scoped_refptr<CefBrowserContext> browser_context =
request_context_impl->GetBrowserContext();
DCHECK(browser_context.get());
if (!request_context_.get())
request_context_ = request_context_impl.get();
// The request context is created on the UI thread but accessed and
// destroyed on the IO thread.
url_request_getter_ = browser_context->GetRequestContext();
}
void ContinueOnOriginatingThread(const GURL& url,
net::URLFetcher::RequestType request_type) {
DCHECK(CalledOnValidThread());
fetcher_delegate_.reset(
new CefURLFetcherDelegate(this, request_->GetFlags()));
fetcher_.reset(net::URLFetcher::Create(url, request_type,
fetcher_delegate_.get()));
fetcher_->SetRequestContext(
CefContentBrowserClient::Get()->request_context().get());
DCHECK(url_request_getter_.get());
fetcher_->SetRequestContext(url_request_getter_.get());
CefRequest::HeaderMap headerMap;
request_->GetHeaderMap(headerMap);
@ -289,8 +329,6 @@ class CefBrowserURLRequest::Context
fetcher_->SaveResponseWithWriter(response_writer.Pass());
fetcher_->Start();
return true;
}
void Cancel() {
@ -424,6 +462,7 @@ class CefBrowserURLRequest::Context
CefRefPtr<CefBrowserURLRequest> url_request_;
CefRefPtr<CefRequest> request_;
CefRefPtr<CefURLRequestClient> client_;
CefRefPtr<CefRequestContext> request_context_;
scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
scoped_ptr<net::URLFetcher> fetcher_;
scoped_ptr<CefURLFetcherDelegate> fetcher_delegate_;
@ -432,6 +471,8 @@ class CefBrowserURLRequest::Context
CefRefPtr<CefResponse> response_;
int64 upload_data_size_;
bool got_upload_progress_complete_;
scoped_refptr<net::URLRequestContextGetter> url_request_getter_;
};
@ -476,8 +517,9 @@ void CefURLFetcherDelegate::OnURLFetchUploadProgress(
CefBrowserURLRequest::CefBrowserURLRequest(
CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client) {
context_ = new Context(this, request, client);
CefRefPtr<CefURLRequestClient> client,
CefRefPtr<CefRequestContext> request_context) {
context_ = new Context(this, request, client, request_context);
}
CefBrowserURLRequest::~CefBrowserURLRequest() {

View File

@ -13,7 +13,8 @@ class CefBrowserURLRequest : public CefURLRequest {
class Context;
CefBrowserURLRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client);
CefRefPtr<CefURLRequestClient> client,
CefRefPtr<CefRequestContext> request_context);
~CefBrowserURLRequest() override;
bool Start();

View File

@ -10,10 +10,9 @@
#include "include/cef_version.h"
#include "include/cef_web_plugin.h"
#include "libcef/browser/context.h"
#include "libcef/browser/frame_host_impl.h"
#include "libcef/browser/internal_scheme_handler.h"
#include "libcef/browser/scheme_impl.h"
#include "libcef/browser/url_request_manager.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/content_client.h"
@ -182,7 +181,8 @@ class Delegate : public InternalHandlerDelegate {
public:
Delegate() {}
bool OnRequest(CefRefPtr<CefRequest> request,
bool OnRequest(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
Action* action) override {
GURL url = GURL(request->GetURL().ToString());
std::string path = url.path();
@ -200,7 +200,7 @@ class Delegate : public InternalHandlerDelegate {
handled = OnLicense(action);
break;
case CHROME_VERSION:
handled = OnVersion(action);
handled = OnVersion(browser, action);
break;
default:
break;
@ -245,7 +245,8 @@ class Delegate : public InternalHandlerDelegate {
return true;
}
bool OnVersion(Action* action) {
bool OnVersion(CefRefPtr<CefBrowser> browser,
Action* action) {
base::StringPiece piece = CefContentClient::Get()->GetDataResource(
IDR_CEF_VERSION_HTML, ui::SCALE_FACTOR_NONE);
if (piece.empty()) {
@ -276,7 +277,8 @@ class Delegate : public InternalHandlerDelegate {
parser.Add("USERAGENT", CefContentClient::Get()->GetUserAgent());
parser.Add("COMMANDLINE", GetCommandLine());
parser.Add("MODULEPATH", GetModulePath());
parser.Add("CACHEPATH", CefString(CefContext::Get()->cache_path().value()));
parser.Add("CACHEPATH",
browser->GetHost()->GetRequestContext()->GetCachePath());
std::string tmpl = piece.as_string();
parser.Parse(&tmpl);
@ -328,15 +330,20 @@ void DidFinishChromeVersionLoad(CefRefPtr<CefFrame> frame) {
class ChromeProtocolHandlerWrapper :
public net::URLRequestJobFactory::ProtocolHandler {
public:
explicit ChromeProtocolHandlerWrapper(
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> chrome_protocol_handler)
: chrome_protocol_handler_(chrome_protocol_handler.Pass()) {
ChromeProtocolHandlerWrapper(
CefURLRequestManager* request_manager,
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
chrome_protocol_handler)
: request_manager_(request_manager),
chrome_protocol_handler_(chrome_protocol_handler.Pass()) {
DCHECK(request_manager_);
}
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
// Keep synchronized with the checks in ChromeProtocolHandler::MaybeCreateJob.
// Keep synchronized with the checks in
// ChromeProtocolHandler::MaybeCreateJob.
if (content::ViewHttpCacheJobFactory::IsSupportedURL(request->url()) ||
(request->url().SchemeIs(content::kChromeUIScheme) &&
request->url().host() == content::kChromeUIAppCacheInternalsHost) ||
@ -347,21 +354,24 @@ class ChromeProtocolHandlerWrapper :
#endif
(request->url().SchemeIs(content::kChromeUIScheme) &&
request->url().host() == content::kChromeUIHistogramHost)) {
return chrome_protocol_handler_->MaybeCreateJob(request, network_delegate);
return chrome_protocol_handler_->MaybeCreateJob(request,
network_delegate);
}
// Use the protocol handler registered with CEF.
return scheme::GetRequestJob(request, network_delegate);
return request_manager_->GetRequestJob(request, network_delegate);
}
private:
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> chrome_protocol_handler_;
CefURLRequestManager* request_manager_;
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
chrome_protocol_handler_;
};
} // namespace
void RegisterChromeHandler() {
CefRegisterSchemeHandlerFactory(
void RegisterChromeHandler(CefURLRequestManager* request_manager) {
request_manager->AddFactory(
content::kChromeUIScheme,
std::string(),
CreateInternalHandlerFactory(
@ -393,10 +403,12 @@ void DidFinishChromeLoad(CefRefPtr<CefFrame> frame,
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
WrapChromeProtocolHandler(
CefURLRequestManager* request_manager,
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
chrome_protocol_handler) {
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> ret(
new ChromeProtocolHandlerWrapper(chrome_protocol_handler.Pass()));
new ChromeProtocolHandlerWrapper(request_manager,
chrome_protocol_handler.Pass()));
return ret.Pass();
}

View File

@ -24,12 +24,14 @@ namespace content {
class BrowserContext;
}
class CefURLRequestManager;
namespace scheme {
extern const char kChromeURL[];
// Register the chrome scheme handler.
void RegisterChromeHandler();
void RegisterChromeHandler(CefURLRequestManager* request_manager);
// Used to redirect about: URLs to chrome: URLs.
bool WillHandleBrowserAboutURL(GURL* url,
@ -43,6 +45,7 @@ void DidFinishChromeLoad(CefRefPtr<CefFrame> frame,
// "chrome" protocol handler and forward the rest to CEF's handler.
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
WrapChromeProtocolHandler(
CefURLRequestManager* request_manager,
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
chrome_protocol_handler);

View File

@ -64,12 +64,14 @@ namespace {
// In-memory store for access tokens used by geolocation.
class CefAccessTokenStore : public content::AccessTokenStore {
public:
CefAccessTokenStore() {}
// |system_context| is used by NetworkLocationProvider to communicate with a
// remote geolocation service.
explicit CefAccessTokenStore(net::URLRequestContextGetter* system_context)
: system_context_(system_context) {}
void LoadAccessTokens(
const LoadAccessTokensCallbackType& callback) override {
callback.Run(access_token_set_,
CefContentBrowserClient::Get()->request_context().get());
callback.Run(access_token_set_, system_context_);
}
void SaveAccessToken(
@ -78,6 +80,7 @@ class CefAccessTokenStore : public content::AccessTokenStore {
}
private:
net::URLRequestContextGetter* system_context_;
AccessTokenSet access_token_set_;
DISALLOW_COPY_AND_ASSIGN(CefAccessTokenStore);
@ -754,7 +757,8 @@ void CefContentBrowserClient::AllowCertificateError(
}
content::AccessTokenStore* CefContentBrowserClient::CreateAccessTokenStore() {
return new CefAccessTokenStore;
return new CefAccessTokenStore(
browser_main_parts_->browser_context()->request_context().get());
}
void CefContentBrowserClient::RequestPermission(
@ -986,7 +990,7 @@ std::string CefContentBrowserClient::GetDefaultDownloadName() {
content::DevToolsManagerDelegate*
CefContentBrowserClient::GetDevToolsManagerDelegate() {
return new CefDevToolsManagerDelegate(browser_context().get());
return new CefDevToolsManagerDelegate();
}
#if defined(OS_POSIX) && !defined(OS_MACOSX)
@ -1041,11 +1045,6 @@ CefContentBrowserClient::browser_context() const {
return browser_main_parts_->browser_context();
}
scoped_refptr<CefURLRequestContextGetterImpl>
CefContentBrowserClient::request_context() const {
return browser_main_parts_->request_context();
}
CefDevToolsDelegate* CefContentBrowserClient::devtools_delegate() const {
return browser_main_parts_->devtools_delegate();
}
@ -1053,8 +1052,3 @@ CefDevToolsDelegate* CefContentBrowserClient::devtools_delegate() const {
PrefService* CefContentBrowserClient::pref_service() const {
return browser_main_parts_->pref_service();
}
scoped_ptr<net::ProxyConfigService>
CefContentBrowserClient::proxy_config_service() const {
return browser_main_parts_->proxy_config_service();
}

View File

@ -21,7 +21,6 @@
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "content/public/browser/content_browser_client.h"
#include "net/proxy/proxy_config_service.h"
#include "url/gurl.h"
class CefBrowserInfo;
@ -168,13 +167,9 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
void set_last_create_window_params(const LastCreateWindowParams& params);
scoped_refptr<CefBrowserContextImpl> browser_context() const;
scoped_refptr<CefURLRequestContextGetterImpl> request_context() const;
CefDevToolsDelegate* devtools_delegate() const;
PrefService* pref_service() const;
// Passes ownership.
scoped_ptr<net::ProxyConfigService> proxy_config_service() const;
private:
CefBrowserMainParts* browser_main_parts_;

View File

@ -10,9 +10,9 @@
#include "libcef/browser/browser_message_loop.h"
#include "libcef/browser/chrome_browser_process_stub.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/scheme_handler.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/trace_subscriber.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/main_delegate.h"
#include "libcef/renderer/content_renderer_client.h"
@ -232,22 +232,6 @@ bool CefContext::Initialize(const CefMainArgs& args,
init_thread_id_ = base::PlatformThread::CurrentId();
settings_ = settings;
cache_path_ = base::FilePath(CefString(&settings.cache_path));
if (!cache_path_.empty() &&
!base::DirectoryExists(cache_path_) &&
!base::CreateDirectory(cache_path_)) {
NOTREACHED() << "The cache_path directory could not be created";
cache_path_ = base::FilePath();
}
if (cache_path_.empty()) {
// Create and use a temporary directory.
if (cache_temp_dir_.CreateUniqueTempDir()) {
cache_path_ = cache_temp_dir_.path();
} else {
NOTREACHED() << "Failed to create temporary cache_path directory";
}
}
#if !defined(OS_WIN)
if (settings.multi_threaded_message_loop) {
NOTIMPLEMENTED() << "multi_threaded_message_loop is not supported.";
@ -346,12 +330,24 @@ CefTraceSubscriber* CefContext::GetTraceSubscriber() {
return trace_subscriber_.get();
}
void CefContext::PopulateRequestContextSettings(
CefRequestContextSettings* settings) {
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
CefString(&settings->cache_path) = CefString(&settings_.cache_path);
settings->persist_session_cookies =
settings_.persist_session_cookies ||
command_line->HasSwitch(switches::kPersistSessionCookies);
settings->ignore_certificate_errors =
settings_.ignore_certificate_errors ||
command_line->HasSwitch(switches::kIgnoreCertificateErrors);
CefString(&settings->accept_language_list) =
CefString(&settings_.accept_language_list);
}
void CefContext::OnContextInitialized() {
CEF_REQUIRE_UIT();
// Register internal scheme handlers.
scheme::RegisterInternalHandlers();
// Must be created after the NotificationService.
print_job_manager_.reset(new printing::PrintJobManager());

View File

@ -12,8 +12,6 @@
#include "include/cef_app.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/platform_thread.h"
@ -59,9 +57,6 @@ class CefContext {
// Returns true if the context is shutting down.
bool shutting_down() { return shutting_down_; }
// Retrieve the path at which cache data will be stored on disk.
const base::FilePath& cache_path() const { return cache_path_; }
const CefSettings& settings() const { return settings_; }
printing::PrintJobManager* print_job_manager() const {
@ -70,6 +65,10 @@ class CefContext {
CefTraceSubscriber* GetTraceSubscriber();
// Populate the request context settings based on CefSettings and command-
// line flags.
void PopulateRequestContextSettings(CefRequestContextSettings* settings);
private:
void OnContextInitialized();
@ -88,8 +87,6 @@ class CefContext {
base::PlatformThreadId init_thread_id_;
CefSettings settings_;
base::FilePath cache_path_;
base::ScopedTempDir cache_temp_dir_;
scoped_ptr<CefMainDelegate> main_delegate_;
scoped_ptr<content::ContentMainRunner> main_runner_;

View File

@ -8,11 +8,9 @@
#include <string>
#include <vector>
#include "libcef/browser/browser_context.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_getter.h"
#include "libcef/common/time_util.h"
#include "base/bind.h"
@ -34,8 +32,9 @@ namespace {
// Callback class for visiting cookies.
class VisitCookiesCallback : public base::RefCounted<VisitCookiesCallback> {
public:
explicit VisitCookiesCallback(net::CookieMonster* cookie_monster,
CefRefPtr<CefCookieVisitor> visitor)
explicit VisitCookiesCallback(
scoped_refptr<net::CookieMonster> cookie_monster,
CefRefPtr<CefCookieVisitor> visitor)
: cookie_monster_(cookie_monster),
visitor_(visitor) {
}
@ -85,291 +84,276 @@ bool GetCookieDomain(const GURL& url,
result);
}
void RunCompletionOnIOThread(CefRefPtr<CefCompletionCallback> callback) {
// Always execute the callback asynchronously.
void RunAsyncCompletionOnIOThread(CefRefPtr<CefCompletionCallback> callback) {
if (!callback.get())
return;
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefCompletionCallback::OnComplete, callback.get()));
}
// Always execute the callback asynchronously.
void DeleteCookiesCallbackImpl(CefRefPtr<CefDeleteCookiesCallback> callback,
int num_deleted) {
if (!callback.get())
return;
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefDeleteCookiesCallback::OnComplete, callback.get(),
num_deleted));
}
// Always execute the callback asynchronously.
void SetCookieCallbackImpl(CefRefPtr<CefSetCookieCallback> callback,
bool success) {
if (!callback.get())
return;
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefSetCookieCallback::OnComplete, callback.get(), success));
}
} // namespace
CefCookieManagerImpl::CefCookieManagerImpl(bool is_global)
: is_global_(is_global) {
CefCookieManagerImpl::CefCookieManagerImpl() {
}
CefCookieManagerImpl::~CefCookieManagerImpl() {
}
void CefCookieManagerImpl::Initialize(
CefRefPtr<CefRequestContextImpl> request_context,
const CefString& path,
bool persist_session_cookies) {
if (is_global_)
SetGlobal();
else
SetStoragePath(path, persist_session_cookies);
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback) {
if (request_context.get()) {
request_context_ = request_context;
request_context_->GetRequestContextImpl(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
base::Bind(&CefCookieManagerImpl::InitWithContext, this, callback));
} else {
SetStoragePath(path, persist_session_cookies, callback);
}
}
void CefCookieManagerImpl::GetCookieMonster(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const CookieMonsterCallback& callback) {
if (!task_runner.get())
task_runner = base::MessageLoop::current()->task_runner();
if (!CEF_CURRENTLY_ON_IOT()) {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefCookieManagerImpl::GetCookieMonster, this, task_runner,
callback));
return;
}
if (HasContext()) {
RunMethodWithContext(
base::Bind(&CefCookieManagerImpl::GetCookieMonsterWithContext, this,
task_runner, callback));
return;
}
DCHECK(cookie_monster_.get());
if (cookie_monster_.get()) {
if (task_runner->BelongsToCurrentThread()) {
// Execute the callback immediately.
callback.Run(cookie_monster_);
} else {
// Execute the callback on the target thread.
task_runner->PostTask(FROM_HERE, base::Bind(callback, cookie_monster_));
}
return;
}
}
scoped_refptr<net::CookieMonster>
CefCookieManagerImpl::GetExistingCookieMonster() {
CEF_REQUIRE_IOT();
if (cookie_monster_.get()) {
return cookie_monster_;
} else if (request_context_impl_.get()) {
scoped_refptr<net::CookieMonster> cookie_monster =
request_context_impl_->GetURLRequestContext()->cookie_store()->
GetCookieMonster();
DCHECK(cookie_monster.get());
return cookie_monster;
}
LOG(ERROR) << "Cookie manager backing store does not exist yet";
return NULL;
}
void CefCookieManagerImpl::SetSupportedSchemes(
const std::vector<CefString>& schemes) {
if (CEF_CURRENTLY_ON_IOT()) {
if (!cookie_monster_.get())
return;
if (is_global_) {
// Global changes are handled by the request context.
scoped_refptr<CefURLRequestContextGetterImpl> getter =
CefContentBrowserClient::Get()->request_context();
std::vector<std::string> scheme_vec;
std::vector<CefString>::const_iterator it = schemes.begin();
for (; it != schemes.end(); ++it)
scheme_vec.push_back(it->ToString());
getter->SetCookieSupportedSchemes(scheme_vec);
return;
}
supported_schemes_ = schemes;
if (supported_schemes_.empty()) {
supported_schemes_.push_back("http");
supported_schemes_.push_back("https");
}
std::set<std::string> scheme_set;
std::vector<CefString>::const_iterator it = supported_schemes_.begin();
for (; it != supported_schemes_.end(); ++it)
scheme_set.insert(*it);
const char** arr = new const char*[scheme_set.size()];
std::set<std::string>::const_iterator it2 = scheme_set.begin();
for (int i = 0; it2 != scheme_set.end(); ++it2, ++i)
arr[i] = it2->c_str();
cookie_monster_->SetCookieableSchemes(arr, scheme_set.size());
delete [] arr;
} else {
// Execute on the IO thread.
const std::vector<CefString>& schemes,
CefRefPtr<CefCompletionCallback> callback) {
if (!CEF_CURRENTLY_ON_IOT()) {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefCookieManagerImpl::SetSupportedSchemes,
this, schemes));
base::Bind(&CefCookieManagerImpl::SetSupportedSchemes, this, schemes,
callback));
return;
}
if (HasContext()) {
RunMethodWithContext(
base::Bind(&CefCookieManagerImpl::SetSupportedSchemesWithContext, this,
schemes, callback));
return;
}
DCHECK(cookie_monster_.get());
if (!cookie_monster_.get())
return;
supported_schemes_ = schemes;
if (supported_schemes_.empty()) {
supported_schemes_.push_back("http");
supported_schemes_.push_back("https");
}
std::set<std::string> scheme_set;
std::vector<CefString>::const_iterator it = supported_schemes_.begin();
for (; it != supported_schemes_.end(); ++it)
scheme_set.insert(*it);
const char** arr = new const char*[scheme_set.size()];
std::set<std::string>::const_iterator it2 = scheme_set.begin();
for (int i = 0; it2 != scheme_set.end(); ++it2, ++i)
arr[i] = it2->c_str();
cookie_monster_->SetCookieableSchemes(arr, scheme_set.size());
delete [] arr;
RunAsyncCompletionOnIOThread(callback);
}
bool CefCookieManagerImpl::VisitAllCookies(
CefRefPtr<CefCookieVisitor> visitor) {
if (CEF_CURRENTLY_ON_IOT()) {
if (!cookie_monster_.get())
return false;
scoped_refptr<VisitCookiesCallback> callback(
new VisitCookiesCallback(cookie_monster_.get(), visitor));
cookie_monster_->GetAllCookiesAsync(
base::Bind(&VisitCookiesCallback::Run, callback.get()));
} else {
// Execute on the IO thread.
CEF_POST_TASK(CEF_IOT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::VisitAllCookies),
this, visitor));
}
GetCookieMonster(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
base::Bind(&CefCookieManagerImpl::VisitAllCookiesInternal, this,
visitor));
return true;
}
bool CefCookieManagerImpl::VisitUrlCookies(
const CefString& url, bool includeHttpOnly,
const CefString& url,
bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor) {
if (CEF_CURRENTLY_ON_IOT()) {
if (!cookie_monster_.get())
return false;
net::CookieOptions options;
if (includeHttpOnly)
options.set_include_httponly();
scoped_refptr<VisitCookiesCallback> callback(
new VisitCookiesCallback(cookie_monster_.get(), visitor));
GURL gurl = GURL(url.ToString());
cookie_monster_->GetAllCookiesForURLWithOptionsAsync(gurl, options,
base::Bind(&VisitCookiesCallback::Run, callback.get()));
} else {
// Execute on the IO thread.
CEF_POST_TASK(CEF_IOT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::VisitUrlCookies),
this, url, includeHttpOnly, visitor));
}
GetCookieMonster(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
base::Bind(&CefCookieManagerImpl::VisitUrlCookiesInternal, this, url,
includeHttpOnly, visitor));
return true;
}
bool CefCookieManagerImpl::SetCookie(const CefString& url,
const CefCookie& cookie) {
CEF_REQUIRE_IOT_RETURN(false);
if (!cookie_monster_.get())
return false;
bool CefCookieManagerImpl::SetCookie(
const CefString& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback) {
GURL gurl = GURL(url.ToString());
if (!gurl.is_valid())
return false;
std::string name = CefString(&cookie.name).ToString();
std::string value = CefString(&cookie.value).ToString();
std::string domain = CefString(&cookie.domain).ToString();
std::string path = CefString(&cookie.path).ToString();
base::Time expiration_time;
if (cookie.has_expires)
cef_time_to_basetime(cookie.expires, expiration_time);
cookie_monster_->SetCookieWithDetailsAsync(
gurl, name, value, domain, path,
expiration_time,
cookie.secure ? true : false,
cookie.httponly ? true : false,
net::COOKIE_PRIORITY_DEFAULT,
net::CookieStore::SetCookiesCallback());
GetCookieMonster(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
base::Bind(&CefCookieManagerImpl::SetCookieInternal, this, gurl, cookie,
callback));
return true;
}
bool CefCookieManagerImpl::DeleteCookies(const CefString& url,
const CefString& cookie_name) {
CEF_REQUIRE_IOT_RETURN(false);
if (!cookie_monster_.get())
return false;
if (url.empty()) {
// Delete all cookies.
cookie_monster_->DeleteAllAsync(net::CookieMonster::DeleteCallback());
return true;
}
bool CefCookieManagerImpl::DeleteCookies(
const CefString& url,
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback) {
// Empty URLs are allowed but not invalid URLs.
GURL gurl = GURL(url.ToString());
if (!gurl.is_valid())
if (!gurl.is_empty() && !gurl.is_valid())
return false;
if (cookie_name.empty()) {
// Delete all matching host cookies.
cookie_monster_->DeleteAllForHostAsync(gurl,
net::CookieMonster::DeleteCallback());
} else {
// Delete all matching host and domain cookies.
cookie_monster_->DeleteCookieAsync(gurl, cookie_name, base::Closure());
}
GetCookieMonster(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
base::Bind(&CefCookieManagerImpl::DeleteCookiesInternal, this, gurl,
cookie_name, callback));
return true;
}
bool CefCookieManagerImpl::SetStoragePath(
const CefString& path,
bool persist_session_cookies) {
if (CEF_CURRENTLY_ON_IOT()) {
base::FilePath new_path;
if (!path.empty())
new_path = base::FilePath(path);
if (is_global_) {
// Global path changes are handled by the request context.
scoped_refptr<CefURLRequestContextGetterImpl> getter =
CefContentBrowserClient::Get()->request_context();
getter->SetCookieStoragePath(new_path, persist_session_cookies);
cookie_monster_ = getter->GetURLRequestContext()->cookie_store()->
GetCookieMonster();
return true;
}
if (cookie_monster_.get() && ((storage_path_.empty() && path.empty()) ||
storage_path_ == new_path)) {
// The path has not changed so don't do anything.
return true;
}
scoped_refptr<content::SQLitePersistentCookieStore> persistent_store;
if (!new_path.empty()) {
// TODO(cef): Move directory creation to the blocking pool instead of
// allowing file IO on this thread.
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (base::DirectoryExists(new_path) ||
base::CreateDirectory(new_path)) {
const base::FilePath& cookie_path = new_path.AppendASCII("Cookies");
persistent_store =
new content::SQLitePersistentCookieStore(
cookie_path,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
persist_session_cookies,
NULL,
NULL);
} else {
NOTREACHED() << "The cookie storage directory could not be created";
storage_path_.clear();
}
}
// Set the new cookie store that will be used for all new requests. The old
// cookie store, if any, will be automatically flushed and closed when no
// longer referenced.
cookie_monster_ = new net::CookieMonster(persistent_store.get(), NULL);
if (persistent_store.get() && persist_session_cookies)
cookie_monster_->SetPersistSessionCookies(true);
storage_path_ = new_path;
// Restore the previously supported schemes.
SetSupportedSchemes(supported_schemes_);
} else {
// Execute on the IO thread.
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback) {
if (!CEF_CURRENTLY_ON_IOT()) {
CEF_POST_TASK(CEF_IOT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::SetStoragePath),
this, path, persist_session_cookies));
this, path, persist_session_cookies, callback));
return true;
}
if (HasContext()) {
RunMethodWithContext(
base::Bind(&CefCookieManagerImpl::SetStoragePathWithContext, this, path,
persist_session_cookies, callback));
return true;
}
base::FilePath new_path;
if (!path.empty())
new_path = base::FilePath(path);
if (cookie_monster_.get() && ((storage_path_.empty() && path.empty()) ||
storage_path_ == new_path)) {
// The path has not changed so don't do anything.
RunAsyncCompletionOnIOThread(callback);
return true;
}
scoped_refptr<content::SQLitePersistentCookieStore> persistent_store;
if (!new_path.empty()) {
// TODO(cef): Move directory creation to the blocking pool instead of
// allowing file IO on this thread.
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (base::DirectoryExists(new_path) ||
base::CreateDirectory(new_path)) {
const base::FilePath& cookie_path = new_path.AppendASCII("Cookies");
persistent_store =
new content::SQLitePersistentCookieStore(
cookie_path,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
persist_session_cookies,
NULL,
NULL);
} else {
NOTREACHED() << "The cookie storage directory could not be created";
storage_path_.clear();
}
}
// Set the new cookie store that will be used for all new requests. The old
// cookie store, if any, will be automatically flushed and closed when no
// longer referenced.
cookie_monster_ = new net::CookieMonster(persistent_store.get(), NULL);
if (persistent_store.get() && persist_session_cookies)
cookie_monster_->SetPersistSessionCookies(true);
storage_path_ = new_path;
// Restore the previously supported schemes.
SetSupportedSchemes(supported_schemes_, callback);
return true;
}
bool CefCookieManagerImpl::FlushStore(
CefRefPtr<CefCompletionCallback> callback) {
if (CEF_CURRENTLY_ON_IOT()) {
if (!cookie_monster_.get()) {
if (callback.get())
RunCompletionOnIOThread(callback);
return true;
}
base::Closure flush_callback;
if (callback.get())
flush_callback = base::Bind(RunCompletionOnIOThread, callback);
else
flush_callback = base::Bind(&base::DoNothing);
cookie_monster_->FlushStore(flush_callback);
} else {
// Execute on the IO thread.
CEF_POST_TASK(CEF_IOT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::FlushStore),
this, callback));
}
GetCookieMonster(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
base::Bind(&CefCookieManagerImpl::FlushStoreInternal, this, callback));
return true;
}
void CefCookieManagerImpl::SetGlobal() {
if (CEF_CURRENTLY_ON_IOT()) {
scoped_refptr<CefURLRequestContextGetterImpl> getter =
CefContentBrowserClient::Get()->request_context();
if (getter.get()) {
cookie_monster_ =
getter->GetURLRequestContext()->cookie_store()->GetCookieMonster();
DCHECK(cookie_monster_.get());
}
} else {
// Execute on the IO thread.
CEF_POST_TASK(CEF_IOT, base::Bind(&CefCookieManagerImpl::SetGlobal, this));
}
}
// static
bool CefCookieManagerImpl::GetCefCookie(const net::CanonicalCookie& cc,
CefCookie& cookie) {
@ -421,33 +405,208 @@ bool CefCookieManagerImpl::GetCefCookie(const GURL& url,
return true;
}
bool CefCookieManagerImpl::HasContext() {
CEF_REQUIRE_IOT();
return (request_context_impl_.get() || request_context_.get());
}
void CefCookieManagerImpl::RunMethodWithContext(
const CefRequestContextImpl::RequestContextCallback& method) {
CEF_REQUIRE_IOT();
if (request_context_impl_.get()) {
method.Run(request_context_impl_);
} else if (request_context_.get()) {
// Try again after the request context is initialized.
request_context_->GetRequestContextImpl(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
method);
} else {
NOTREACHED();
}
}
void CefCookieManagerImpl::InitWithContext(
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefURLRequestContextGetterImpl> request_context) {
CEF_REQUIRE_IOT();
DCHECK(!request_context_impl_.get());
request_context_impl_ = request_context;
// Clear the CefRequestContextImpl reference here to avoid a potential
// reference loop between CefRequestContextImpl (which has a reference to
// CefRequestContextHandler), CefRequestContextHandler (which may keep a
// reference to this object) and this object.
request_context_ = NULL;
RunAsyncCompletionOnIOThread(callback);
}
void CefCookieManagerImpl::SetStoragePathWithContext(
const CefString& path,
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefURLRequestContextGetterImpl> request_context) {
CEF_REQUIRE_IOT();
base::FilePath new_path;
if (!path.empty())
new_path = base::FilePath(path);
request_context->SetCookieStoragePath(new_path, persist_session_cookies);
RunAsyncCompletionOnIOThread(callback);
}
void CefCookieManagerImpl::SetSupportedSchemesWithContext(
const std::vector<CefString>& schemes,
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefURLRequestContextGetterImpl> request_context) {
CEF_REQUIRE_IOT();
std::vector<std::string> scheme_vec;
std::vector<CefString>::const_iterator it = schemes.begin();
for (; it != schemes.end(); ++it)
scheme_vec.push_back(it->ToString());
request_context->SetCookieSupportedSchemes(scheme_vec);
RunAsyncCompletionOnIOThread(callback);
}
void CefCookieManagerImpl::GetCookieMonsterWithContext(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const CookieMonsterCallback& callback,
scoped_refptr<CefURLRequestContextGetterImpl> request_context) {
CEF_REQUIRE_IOT();
scoped_refptr<net::CookieMonster> cookie_monster =
request_context->GetURLRequestContext()->cookie_store()->
GetCookieMonster();
if (task_runner->BelongsToCurrentThread()) {
// Execute the callback immediately.
callback.Run(cookie_monster);
} else {
// Execute the callback on the target thread.
task_runner->PostTask(FROM_HERE, base::Bind(callback, cookie_monster));
}
}
void CefCookieManagerImpl::VisitAllCookiesInternal(
CefRefPtr<CefCookieVisitor> visitor,
scoped_refptr<net::CookieMonster> cookie_monster) {
CEF_REQUIRE_IOT();
scoped_refptr<VisitCookiesCallback> callback(
new VisitCookiesCallback(cookie_monster, visitor));
cookie_monster->GetAllCookiesAsync(
base::Bind(&VisitCookiesCallback::Run, callback.get()));
}
void CefCookieManagerImpl::VisitUrlCookiesInternal(
const CefString& url,
bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor,
scoped_refptr<net::CookieMonster> cookie_monster) {
CEF_REQUIRE_IOT();
net::CookieOptions options;
if (includeHttpOnly)
options.set_include_httponly();
scoped_refptr<VisitCookiesCallback> callback(
new VisitCookiesCallback(cookie_monster, visitor));
GURL gurl = GURL(url.ToString());
cookie_monster->GetAllCookiesForURLWithOptionsAsync(gurl, options,
base::Bind(&VisitCookiesCallback::Run, callback.get()));
}
void CefCookieManagerImpl::SetCookieInternal(
const GURL& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback,
scoped_refptr<net::CookieMonster> cookie_monster) {
CEF_REQUIRE_IOT();
std::string name = CefString(&cookie.name).ToString();
std::string value = CefString(&cookie.value).ToString();
std::string domain = CefString(&cookie.domain).ToString();
std::string path = CefString(&cookie.path).ToString();
base::Time expiration_time;
if (cookie.has_expires)
cef_time_to_basetime(cookie.expires, expiration_time);
cookie_monster->SetCookieWithDetailsAsync(
url, name, value, domain, path,
expiration_time,
cookie.secure ? true : false,
cookie.httponly ? true : false,
net::COOKIE_PRIORITY_DEFAULT,
base::Bind(SetCookieCallbackImpl, callback));
}
void CefCookieManagerImpl::DeleteCookiesInternal(
const GURL& url,
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback,
scoped_refptr<net::CookieMonster> cookie_monster) {
CEF_REQUIRE_IOT();
if (url.is_empty()) {
// Delete all cookies.
cookie_monster->DeleteAllAsync(
base::Bind(DeleteCookiesCallbackImpl, callback));
} else if (cookie_name.empty()) {
// Delete all matching host cookies.
cookie_monster->DeleteAllForHostAsync(url,
base::Bind(DeleteCookiesCallbackImpl, callback));
} else {
// Delete all matching host and domain cookies.
cookie_monster->DeleteCookieAsync(url, cookie_name,
base::Bind(DeleteCookiesCallbackImpl, callback, -1));
}
}
void CefCookieManagerImpl::FlushStoreInternal(
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<net::CookieMonster> cookie_monster) {
CEF_REQUIRE_IOT();
cookie_monster->FlushStore(
base::Bind(RunAsyncCompletionOnIOThread, callback));
}
// CefCookieManager methods ----------------------------------------------------
// static
CefRefPtr<CefCookieManager> CefCookieManager::GetGlobalManager() {
CefRefPtr<CefCookieManager> CefCookieManager::GetGlobalManager(
CefRefPtr<CefCompletionCallback> callback) {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return NULL;
}
CefRefPtr<CefCookieManagerImpl> manager(new CefCookieManagerImpl(true));
manager->Initialize(CefString(), false);
return manager.get();
return CefRequestContext::GetGlobalContext()->GetDefaultCookieManager(
callback);
}
// static
CefRefPtr<CefCookieManager> CefCookieManager::CreateManager(
const CefString& path,
bool persist_session_cookies) {
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback) {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return NULL;
}
CefRefPtr<CefCookieManagerImpl> manager(new CefCookieManagerImpl(false));
manager->Initialize(path, persist_session_cookies);
return manager.get();
CefRefPtr<CefCookieManagerImpl> cookie_manager = new CefCookieManagerImpl();
cookie_manager->Initialize(NULL, path, persist_session_cookies, callback);
return cookie_manager.get();
}

View File

@ -6,45 +6,113 @@
#define CEF_LIBCEF_BROWSER_COOKIE_MANAGER_IMPL_H_
#include "include/cef_cookie.h"
#include "libcef/browser/request_context_impl.h"
#include "base/files/file_path.h"
#include "net/cookies/cookie_monster.h"
// Implementation of the CefCookieManager interface.
class CefCookieManagerImpl : public CefCookieManager {
public:
CefCookieManagerImpl(bool is_global);
CefCookieManagerImpl();
~CefCookieManagerImpl() override;
// Initialize the cookie manager.
void Initialize(const CefString& path,
bool persist_session_cookies);
// Must be called immediately after this object is created.
void Initialize(CefRefPtr<CefRequestContextImpl> request_context,
const CefString& path,
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback);
// Executes |callback| either synchronously or asynchronously with the cookie
// monster object when it's available. If |task_runner| is NULL the callback
// will be executed on the originating thread. The resulting cookie monster
// object can only be accessed on the IO thread.
typedef base::Callback<void(scoped_refptr<net::CookieMonster>)>
CookieMonsterCallback;
void GetCookieMonster(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const CookieMonsterCallback& callback);
// Returns the existing cookie monster object. Logs an error if the cookie
// monster does not yet exist. Must be called on the IO thread.
scoped_refptr<net::CookieMonster> GetExistingCookieMonster();
// CefCookieManager methods.
void SetSupportedSchemes(const std::vector<CefString>& schemes) override;
void SetSupportedSchemes(const std::vector<CefString>& schemes,
CefRefPtr<CefCompletionCallback> callback) override;
bool VisitAllCookies(CefRefPtr<CefCookieVisitor> visitor) override;
bool VisitUrlCookies(const CefString& url, bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor) override;
bool SetCookie(const CefString& url,
const CefCookie& cookie) override;
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback) override;
bool DeleteCookies(const CefString& url,
const CefString& cookie_name) override;
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback) override;
bool SetStoragePath(const CefString& path,
bool persist_session_cookies) override;
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback) override;
bool FlushStore(CefRefPtr<CefCompletionCallback> callback) override;
net::CookieMonster* cookie_monster() { return cookie_monster_.get(); }
static bool GetCefCookie(const net::CanonicalCookie& cc, CefCookie& cookie);
static bool GetCefCookie(const GURL& url, const std::string& cookie_line,
CefCookie& cookie);
private:
void SetGlobal();
// Returns true if a context is or will be available.
bool HasContext();
scoped_refptr<net::CookieMonster> cookie_monster_;
bool is_global_;
// Execute |method| on the IO thread once the request context is available.
void RunMethodWithContext(
const CefRequestContextImpl::RequestContextCallback& method);
void InitWithContext(
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefURLRequestContextGetterImpl> request_context);
void SetStoragePathWithContext(
const CefString& path,
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefURLRequestContextGetterImpl> request_context);
void SetSupportedSchemesWithContext(
const std::vector<CefString>& schemes,
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefURLRequestContextGetterImpl> request_context);
void GetCookieMonsterWithContext(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const CookieMonsterCallback& callback,
scoped_refptr<CefURLRequestContextGetterImpl> request_context);
void VisitAllCookiesInternal(
CefRefPtr<CefCookieVisitor> visitor,
scoped_refptr<net::CookieMonster> cookie_monster);
void VisitUrlCookiesInternal(
const CefString& url,
bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor,
scoped_refptr<net::CookieMonster> cookie_monster);
void SetCookieInternal(
const GURL& url,
const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback,
scoped_refptr<net::CookieMonster> cookie_monster);
void DeleteCookiesInternal(
const GURL& url,
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback,
scoped_refptr<net::CookieMonster> cookie_monster);
void FlushStoreInternal(
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<net::CookieMonster> cookie_monster);
// Used for cookie monsters owned by the context.
CefRefPtr<CefRequestContextImpl> request_context_;
scoped_refptr<CefURLRequestContextGetterImpl> request_context_impl_;
// Used for cookie monsters owned by this object.
base::FilePath storage_path_;
std::vector<CefString> supported_schemes_;
scoped_refptr<net::CookieMonster> cookie_monster_;
IMPLEMENT_REFCOUNTING(CefCookieManagerImpl);
};

View File

@ -16,6 +16,8 @@ CefCookieStoreProxy::CefCookieStoreProxy(
: parent_(parent),
handler_(handler) {
CEF_REQUIRE_IOT();
DCHECK(parent_);
DCHECK(handler_.get());
}
CefCookieStoreProxy::~CefCookieStoreProxy() {
@ -117,20 +119,18 @@ net::CookieStore* CefCookieStoreProxy::GetCookieStore() {
scoped_refptr<net::CookieStore> cookie_store;
if (handler_.get()) {
// Get the manager from the handler.
CefRefPtr<CefCookieManager> manager = handler_->GetCookieManager();
if (manager.get()) {
cookie_store = reinterpret_cast<CefCookieManagerImpl*>(manager.get())->
cookie_monster();
DCHECK(cookie_store.get());
return cookie_store.get();
}
CefRefPtr<CefCookieManager> manager = handler_->GetCookieManager();
if (manager.get()) {
// Use the cookie store provided by the manager.
cookie_store = reinterpret_cast<CefCookieManagerImpl*>(manager.get())->
GetExistingCookieMonster();
DCHECK(cookie_store.get());
return cookie_store.get();
}
DCHECK(parent_);
if (parent_) {
// Use the global cookie store.
// Use the cookie store from the parent.
cookie_store = parent_->cookie_store();
DCHECK(cookie_store.get());
}

View File

@ -173,9 +173,7 @@ std::string CefDevToolsDelegate::GetChromeDevToolsURL() {
// CefDevToolsManagerDelegate
CefDevToolsManagerDelegate::CefDevToolsManagerDelegate(
content::BrowserContext* browser_context)
: browser_context_(browser_context) {
CefDevToolsManagerDelegate::CefDevToolsManagerDelegate() {
}
CefDevToolsManagerDelegate::~CefDevToolsManagerDelegate() {

View File

@ -45,8 +45,7 @@ class CefDevToolsDelegate : public content::DevToolsHttpHandlerDelegate {
class CefDevToolsManagerDelegate : public content::DevToolsManagerDelegate {
public:
explicit CefDevToolsManagerDelegate(
content::BrowserContext* browser_context);
CefDevToolsManagerDelegate();
~CefDevToolsManagerDelegate() override;
// DevToolsManagerDelegate implementation.
@ -63,8 +62,6 @@ class CefDevToolsManagerDelegate : public content::DevToolsManagerDelegate {
std::string GetPageThumbnailData(const GURL& url) override;
private:
content::BrowserContext* browser_context_;
DISALLOW_COPY_AND_ASSIGN(CefDevToolsManagerDelegate);
};

View File

@ -7,6 +7,7 @@
#include <string>
#include "libcef/browser/internal_scheme_handler.h"
#include "libcef/browser/url_request_manager.h"
#include "base/strings/string_util.h"
#include "content/public/common/url_constants.h"
@ -22,7 +23,8 @@ class Delegate : public InternalHandlerDelegate {
public:
Delegate() {}
bool OnRequest(CefRefPtr<CefRequest> request,
bool OnRequest(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
Action* action) override {
GURL url = GURL(request->GetURL().ToString());
std::string path = url.path();
@ -43,8 +45,8 @@ class Delegate : public InternalHandlerDelegate {
} // namespace
void RegisterChromeDevToolsHandler() {
CefRegisterSchemeHandlerFactory(
void RegisterChromeDevToolsHandler(CefURLRequestManager* request_manager) {
request_manager->AddFactory(
content::kChromeDevToolsScheme,
kChromeDevToolsHost,
CreateInternalHandlerFactory(

View File

@ -6,12 +6,14 @@
#define CEF_LIBCEF_BROWSER_DEVTOOLS_SCHEME_HANDLER_H_
#pragma once
class CefURLRequestManager;
namespace scheme {
extern const char kChromeDevToolsHost[];
// Register the chrome-devtools scheme handler.
void RegisterChromeDevToolsHandler();
void RegisterChromeDevToolsHandler(CefURLRequestManager* request_manager);
} // namespace scheme

View File

@ -125,7 +125,7 @@ class InternalHandlerFactory : public CefSchemeHandlerFactory {
GURL url = GURL(request->GetURL().ToString());
InternalHandlerDelegate::Action action;
if (delegate_->OnRequest(request, &action)) {
if (delegate_->OnRequest(browser, request, &action)) {
if (!action.redirect_url.is_empty() && action.redirect_url.is_valid())
return new RedirectHandler(action.redirect_url);

View File

@ -39,7 +39,8 @@ class InternalHandlerDelegate {
virtual ~InternalHandlerDelegate() {}
// Populate |action| and return true if the request was handled.
virtual bool OnRequest(CefRefPtr<CefRequest> request,
virtual bool OnRequest(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
Action* action) = 0;
};

View File

@ -7,6 +7,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"
bool CefGetPath(PathKey key, CefString& path) {
int pref_key = base::PATH_START;
@ -29,6 +30,14 @@ bool CefGetPath(PathKey key, CefString& path) {
case PK_FILE_MODULE:
pref_key = base::FILE_MODULE;
break;
#if defined(OS_WIN)
case PK_LOCAL_APP_DATA:
pref_key = base::DIR_LOCAL_APP_DATA;
break;
#endif
case PK_USER_DATA:
pref_key = chrome::DIR_USER_DATA;
break;
default:
NOTREACHED() << "invalid argument";
return false;

View File

@ -7,18 +7,29 @@
#include "libcef/browser/browser_context_proxy.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/cookie_manager_impl.h"
#include "libcef/browser/thread_util.h"
#include "base/atomic_sequence_num.h"
#include "base/logging.h"
using content::BrowserThread;
namespace {
base::StaticAtomicSequenceNumber g_next_id;
CefRefPtr<CefBrowserContextImpl> GetImpl(CefRefPtr<CefBrowserContext> context) {
if (context->IsProxy())
return static_cast<CefBrowserContextProxy*>(context.get())->parent();
return static_cast<CefBrowserContextImpl*>(context.get());
}
} // namespace
// Static functions
// CefBrowserContext
// static
CefRefPtr<CefRequestContext> CefRequestContext::GetGlobalContext() {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
@ -26,69 +37,213 @@ CefRefPtr<CefRequestContext> CefRequestContext::GetGlobalContext() {
return NULL;
}
return new CefRequestContextImpl(
CefContentBrowserClient::Get()->browser_context().get());
return CefRequestContextImpl::GetForBrowserContext(
CefContentBrowserClient::Get()->browser_context());
}
// static
CefRefPtr<CefRequestContext> CefRequestContext::CreateContext(
CefRefPtr<CefRequestContextHandler> handler) {
const CefRequestContextSettings& settings,
CefRefPtr<CefRequestContextHandler> handler) {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return NULL;
}
return new CefRequestContextImpl(handler);
return new CefRequestContextImpl(settings, handler);
}
// static
CefRefPtr<CefRequestContext> CefRequestContext::CreateContext(
CefRefPtr<CefRequestContext> other,
CefRefPtr<CefRequestContextHandler> handler) {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return NULL;
}
if (!other.get())
return NULL;
return new CefRequestContextImpl(
static_cast<CefRequestContextImpl*>(other.get()), handler);
}
// CefBrowserContextImpl
CefRequestContextImpl::CefRequestContextImpl(
scoped_refptr<CefBrowserContext> browser_context)
: browser_context_(browser_context),
unique_id_(0) {
DCHECK(browser_context.get());
if (!IsGlobal()) {
CEF_REQUIRE_UIT();
scoped_refptr<CefBrowserContextProxy> proxy =
static_cast<CefBrowserContextProxy*>(browser_context.get());
handler_ = proxy->handler();
}
}
CefRequestContextImpl::CefRequestContextImpl(
CefRefPtr<CefRequestContextHandler> handler)
: handler_(handler),
unique_id_(g_next_id.GetNext()) {
}
CefRequestContextImpl::~CefRequestContextImpl() {
}
scoped_refptr<CefBrowserContext>
CefRequestContextImpl::GetOrCreateBrowserContext() {
CEF_REQUIRE_UIT();
if (!browser_context_) {
browser_context_ = new CefBrowserContextProxy(
handler_, CefContentBrowserClient::Get()->browser_context());
// static
CefRefPtr<CefRequestContextImpl> CefRequestContextImpl::GetForRequestContext(
CefRefPtr<CefRequestContext> request_context) {
if (request_context.get()) {
// Use the context from the provided CefRequestContext.
return static_cast<CefRequestContextImpl*>(request_context.get());
}
// Use the global context.
scoped_refptr<CefBrowserContext> browser_context =
CefContentBrowserClient::Get()->browser_context();
return GetForBrowserContext(browser_context);
}
// static
CefRefPtr<CefRequestContextImpl> CefRequestContextImpl::GetForBrowserContext(
scoped_refptr<CefBrowserContext> browser_context) {
DCHECK(browser_context.get());
return new CefRequestContextImpl(browser_context);
}
scoped_refptr<CefBrowserContext> CefRequestContextImpl::GetBrowserContext() {
CEF_REQUIRE_UIT();
if (!browser_context_) {
scoped_refptr<CefBrowserContextImpl> parent;
if (other_.get()) {
// Share storage with |other_|.
parent = GetImpl(other_->GetBrowserContext());
}
if (!parent.get()) {
const base::FilePath& cache_path =
base::FilePath(CefString(&settings_.cache_path));
if (!cache_path.empty()) {
// Check if a CefBrowserContextImpl is already globally registered for
// the specified cache path. If so then use it.
parent = CefBrowserContextImpl::GetForCachePath(cache_path);
}
}
if (!parent.get()) {
// Create a new CefBrowserContextImpl instance. If the cache path is non-
// empty then this new instance will become the globally registered
// CefBrowserContextImpl for that path. Otherwise, this new instance will
// be a completely isolated "incongento mode" context.
parent = new CefBrowserContextImpl(settings_);
parent->Initialize();
}
// The parent's settings may be different. Force our settings to match the
// parent.
settings_ = parent->GetSettings();
if (handler_.get()) {
// Use a proxy that will execute handler callbacks where appropriate and
// otherwise forward all requests to the parent implementation.
browser_context_ = new CefBrowserContextProxy(handler_, parent);
} else {
// Use the parent implementation directly.
browser_context_ = parent;
}
request_context_impl_ = parent->request_context().get();
DCHECK(request_context_impl_);
if (handler_.get()) {
// Keep the handler alive until the associated request context is
// destroyed.
request_context_impl_->AddHandler(handler_);
}
}
if (!request_context_impl_) {
request_context_impl_ = GetImpl(browser_context_)->request_context().get();
DCHECK(request_context_impl_);
}
if (other_.get()) {
// Clear the reference to |other_| after setting |request_context_impl_|.
// This is the reverse order of checks in IsSharedWith().
other_ = NULL;
}
return browser_context_;
}
void CefRequestContextImpl::GetBrowserContext(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const BrowserContextCallback& callback) {
if (!task_runner.get())
task_runner = base::MessageLoop::current()->task_runner();
GetBrowserContextOnUIThread(task_runner, callback);
}
void CefRequestContextImpl::GetRequestContextImpl(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const RequestContextCallback& callback) {
if (!task_runner.get())
task_runner = base::MessageLoop::current()->task_runner();
if (request_context_impl_) {
// The browser context already exists.
DCHECK(browser_context_.get());
GetRequestContextImplOnIOThread(task_runner, callback, browser_context_);
} else {
// Need to initialize the browser context first.
GetBrowserContextOnUIThread(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
base::Bind(&CefRequestContextImpl::GetRequestContextImplOnIOThread,
this, task_runner, callback));
}
}
bool CefRequestContextImpl::IsSame(CefRefPtr<CefRequestContext> other) {
CefRequestContextImpl* impl =
CefRequestContextImpl* other_impl =
static_cast<CefRequestContextImpl*>(other.get());
if (!impl)
if (!other_impl)
return false;
// Compare CefBrowserContext points if one has been associated.
if (browser_context_ && impl->browser_context_)
return (browser_context_ == impl->browser_context_);
else if (browser_context_ || impl->browser_context_)
// Compare CefBrowserContext pointers if one has been associated.
if (browser_context_ && other_impl->browser_context_)
return (browser_context_ == other_impl->browser_context_);
else if (browser_context_ || other_impl->browser_context_)
return false;
// Otherwise compare unique IDs.
return (unique_id_ == impl->unique_id_);
return (unique_id_ == other_impl->unique_id_);
}
bool CefRequestContextImpl::IsSharingWith(CefRefPtr<CefRequestContext> other) {
CefRequestContextImpl* other_impl =
static_cast<CefRequestContextImpl*>(other.get());
if (!other_impl)
return false;
if (IsSame(other))
return true;
CefRefPtr<CefRequestContext> pending_other = other_;
if (pending_other.get()) {
// This object is not initialized but we know what context this object will
// share with. Compare to that other context instead.
return pending_other->IsSharingWith(other);
}
pending_other = other_impl->other_;
if (pending_other.get()) {
// The other object is not initialized but we know what context that object
// will share with. Compare to that other context instead.
return pending_other->IsSharingWith(this);
}
if (request_context_impl_ && other_impl->request_context_impl_) {
// Both objects are initialized. Compare the request context objects.
return (request_context_impl_ == other_impl->request_context_impl_);
}
// This or the other object is not initialized. Compare the cache path values.
// If both are non-empty and the same then they'll share the same storage.
if (settings_.cache_path.length > 0 &&
other_impl->settings_.cache_path.length > 0) {
return (base::FilePath(CefString(&settings_.cache_path)) ==
base::FilePath(CefString(&other_impl->settings_.cache_path)));
}
return false;
}
bool CefRequestContextImpl::IsGlobal() {
@ -99,3 +254,126 @@ bool CefRequestContextImpl::IsGlobal() {
CefRefPtr<CefRequestContextHandler> CefRequestContextImpl::GetHandler() {
return handler_;
}
CefString CefRequestContextImpl::GetCachePath() {
return CefString(&settings_.cache_path);
}
CefRefPtr<CefCookieManager> CefRequestContextImpl::GetDefaultCookieManager(
CefRefPtr<CefCompletionCallback> callback) {
CefRefPtr<CefCookieManagerImpl> cookie_manager = new CefCookieManagerImpl();
cookie_manager->Initialize(this, CefString(), false, callback);
return cookie_manager.get();
}
bool CefRequestContextImpl::RegisterSchemeHandlerFactory(
const CefString& scheme_name,
const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) {
GetRequestContextImpl(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
base::Bind(&CefRequestContextImpl::RegisterSchemeHandlerFactoryInternal,
this, scheme_name, domain_name, factory));
return true;
}
bool CefRequestContextImpl::ClearSchemeHandlerFactories() {
GetRequestContextImpl(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
base::Bind(&CefRequestContextImpl::ClearSchemeHandlerFactoriesInternal,
this));
return true;
}
CefRequestContextImpl::CefRequestContextImpl(
scoped_refptr<CefBrowserContext> browser_context)
: browser_context_(browser_context),
settings_(browser_context->GetSettings()),
handler_(browser_context->GetHandler()),
unique_id_(0),
request_context_impl_(NULL) {
}
CefRequestContextImpl::CefRequestContextImpl(
const CefRequestContextSettings& settings,
CefRefPtr<CefRequestContextHandler> handler)
: settings_(settings),
handler_(handler),
unique_id_(g_next_id.GetNext()),
request_context_impl_(NULL) {
}
CefRequestContextImpl::CefRequestContextImpl(
CefRefPtr<CefRequestContextImpl> other,
CefRefPtr<CefRequestContextHandler> handler)
: other_(other),
handler_(handler),
unique_id_(g_next_id.GetNext()),
request_context_impl_(NULL) {
}
void CefRequestContextImpl::GetBrowserContextOnUIThread(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const BrowserContextCallback& callback) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefRequestContextImpl::GetBrowserContextOnUIThread,
this, task_runner, callback));
return;
}
// Make sure the browser context exists.
GetBrowserContext();
DCHECK(browser_context_.get());
DCHECK(request_context_impl_);
if (task_runner->BelongsToCurrentThread()) {
// Execute the callback immediately.
callback.Run(browser_context_);
} else {
// Execute the callback on the target thread.
task_runner->PostTask(FROM_HERE, base::Bind(callback, browser_context_));
}
}
void CefRequestContextImpl::GetRequestContextImplOnIOThread(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const RequestContextCallback& callback,
scoped_refptr<CefBrowserContext> browser_context) {
if (!CEF_CURRENTLY_ON_IOT()) {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefRequestContextImpl::GetRequestContextImplOnIOThread,
this, task_runner, callback, browser_context));
return;
}
DCHECK(request_context_impl_);
// Make sure the request context exists.
request_context_impl_->GetURLRequestContext();
if (task_runner->BelongsToCurrentThread()) {
// Execute the callback immediately.
callback.Run(request_context_impl_);
} else {
// Execute the callback on the target thread.
task_runner->PostTask(FROM_HERE,
base::Bind(callback, make_scoped_refptr(request_context_impl_)));
}
}
void CefRequestContextImpl::RegisterSchemeHandlerFactoryInternal(
const CefString& scheme_name,
const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory,
scoped_refptr<CefURLRequestContextGetterImpl> request_context) {
CEF_REQUIRE_IOT();
request_context->request_manager()->AddFactory(scheme_name, domain_name,
factory);
}
void CefRequestContextImpl::ClearSchemeHandlerFactoriesInternal(
scoped_refptr<CefURLRequestContextGetterImpl> request_context) {
CEF_REQUIRE_IOT();
request_context->request_manager()->ClearFactories();
}

View File

@ -9,27 +9,98 @@
#include "include/cef_request_context.h"
#include "libcef/browser/browser_context.h"
// Implementation of the CefRequestContext interface. All methods are thread-
// safe unless otherwise indicated.
class CefRequestContextImpl : public CefRequestContext {
public:
explicit CefRequestContextImpl(
scoped_refptr<CefBrowserContext> browser_context);
explicit CefRequestContextImpl(CefRefPtr<CefRequestContextHandler> handler);
~CefRequestContextImpl() override;
scoped_refptr<CefBrowserContext> GetOrCreateBrowserContext();
// Returns a CefRequestContextImpl for the specified |request_context|.
// Will return the global context if |request_context| is NULL.
static CefRefPtr<CefRequestContextImpl> GetForRequestContext(
CefRefPtr<CefRequestContext> request_context);
// Returns a CefRequestContextImpl for the specified |browser_context|.
// |browser_context| must be non-NULL.
static CefRefPtr<CefRequestContextImpl> GetForBrowserContext(
scoped_refptr<CefBrowserContext> browser_context);
// Returns the browser context object. Can only be called on the UI thread.
scoped_refptr<CefBrowserContext> GetBrowserContext();
// Executes |callback| either synchronously or asynchronously with the browser
// context object when it's available. If |task_runner| is NULL the callback
// will be executed on the originating thread. The resulting context object
// can only be accessed on the UI thread.
typedef base::Callback<void(scoped_refptr<CefBrowserContext>)>
BrowserContextCallback;
void GetBrowserContext(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const BrowserContextCallback& callback);
// Executes |callback| either synchronously or asynchronously with the request
// context object when it's available. If |task_runner| is NULL the callback
// will be executed on the originating thread. The resulting context object
// can only be accessed on the IO thread.
typedef base::Callback<void(scoped_refptr<CefURLRequestContextGetterImpl>)>
RequestContextCallback;
void GetRequestContextImpl(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const RequestContextCallback& callback);
bool IsSame(CefRefPtr<CefRequestContext> other) override;
bool IsSharingWith(CefRefPtr<CefRequestContext> other) override;
bool IsGlobal() override;
CefRefPtr<CefRequestContextHandler> GetHandler() override;
CefString GetCachePath() override;
CefRefPtr<CefCookieManager> GetDefaultCookieManager(
CefRefPtr<CefCompletionCallback> callback) override;
bool RegisterSchemeHandlerFactory(
const CefString& scheme_name,
const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) override;
bool ClearSchemeHandlerFactories() override;
const CefRequestContextSettings& settings() const { return settings_; }
private:
friend class CefRequestContext;
explicit CefRequestContextImpl(
scoped_refptr<CefBrowserContext> browser_context);
CefRequestContextImpl(const CefRequestContextSettings& settings,
CefRefPtr<CefRequestContextHandler> handler);
CefRequestContextImpl(CefRefPtr<CefRequestContextImpl> other,
CefRefPtr<CefRequestContextHandler> handler);
void GetBrowserContextOnUIThread(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const BrowserContextCallback& callback);
void GetRequestContextImplOnIOThread(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const RequestContextCallback& callback,
scoped_refptr<CefBrowserContext> browser_context);
void RegisterSchemeHandlerFactoryInternal(
const CefString& scheme_name,
const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory,
scoped_refptr<CefURLRequestContextGetterImpl> request_context);
void ClearSchemeHandlerFactoriesInternal(
scoped_refptr<CefURLRequestContextGetterImpl> request_context);
protected:
scoped_refptr<CefBrowserContext> browser_context_;
CefRequestContextSettings settings_;
CefRefPtr<CefRequestContextImpl> other_;
CefRefPtr<CefRequestContextHandler> handler_;
// Used to uniquely identify CefRequestContext objects before an associated
// CefBrowserContext has been created.
int unique_id_;
// Owned by the CefBrowserContext.
CefURLRequestContextGetterImpl* request_context_impl_;
IMPLEMENT_REFCOUNTING(CefRequestContextImpl);
DISALLOW_COPY_AND_ASSIGN(CefRequestContextImpl);
};

View File

@ -23,6 +23,7 @@ namespace scheme {
void InstallInternalProtectedHandlers(
net::URLRequestJobFactoryImpl* job_factory,
CefURLRequestManager* request_manager,
content::ProtocolHandlerMap* protocol_handlers,
net::FtpTransactionFactory* ftp_transaction_factory) {
protocol_handlers->insert(
@ -58,6 +59,7 @@ void InstallInternalProtectedHandlers(
// not to interfere with CEF's "chrome" handler.
protocol_handler.reset(
scheme::WrapChromeProtocolHandler(
request_manager,
make_scoped_ptr(it->second.release())).release());
} else {
protocol_handler.reset(it->second.release());
@ -73,9 +75,9 @@ void InstallInternalProtectedHandlers(
}
}
void RegisterInternalHandlers() {
scheme::RegisterChromeHandler();
scheme::RegisterChromeDevToolsHandler();
void RegisterInternalHandlers(CefURLRequestManager* request_manager) {
scheme::RegisterChromeHandler(request_manager);
scheme::RegisterChromeDevToolsHandler(request_manager);
}
void DidFinishLoad(CefRefPtr<CefFrame> frame, const GURL& validated_url) {

View File

@ -16,17 +16,20 @@ class FtpTransactionFactory;
class URLRequestJobFactoryImpl;
}
class CefURLRequestManager;
namespace scheme {
// Install the internal scheme handlers provided by Chromium that cannot be
// overridden.
void InstallInternalProtectedHandlers(
net::URLRequestJobFactoryImpl* job_factory,
CefURLRequestManager* request_manager,
content::ProtocolHandlerMap* protocol_handlers,
net::FtpTransactionFactory* ftp_transaction_factory);
// Register the internal scheme handlers that can be overridden.
void RegisterInternalHandlers();
void RegisterInternalHandlers(CefURLRequestManager* request_manager);
// Used to fire any asynchronous content updates.
void DidFinishLoad(CefRefPtr<CefFrame> frame, const GURL& validated_url);

View File

@ -1,361 +1,33 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2009 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.
// Copyright (c) 2015 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 <map>
#include "include/cef_browser.h"
#include "include/cef_scheme.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/resource_request_job.h"
#include "libcef/browser/scheme_handler.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_getter.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/response_impl.h"
#include "libcef/common/scheme_registration.h"
#include "libcef/common/upload_data.h"
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "base/synchronization/lock.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_http_job.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "url/third_party/mozilla/url_parse.h"
#include "url/url_util.h"
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;
net::URLRequest::ProtocolFactory* factory;
};
static const SchemeToFactory kBuiltinFactories[] = {
{ "http", net::URLRequestHttpJob::Factory },
{ "https", net::URLRequestHttpJob::Factory },
};
bool IsBuiltinScheme(const std::string& scheme) {
for (size_t i = 0; i < arraysize(kBuiltinFactories); ++i)
if (LowerCaseEqualsASCII(scheme, kBuiltinFactories[i].scheme))
return true;
return false;
}
net::URLRequestJob* GetBuiltinSchemeRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& scheme) {
// See if the request should be handled by a built-in protocol factory.
for (size_t i = 0; i < arraysize(kBuiltinFactories); ++i) {
if (scheme == kBuiltinFactories[i].scheme) {
net::URLRequestJob* job =
(kBuiltinFactories[i].factory)(request, network_delegate, scheme);
DCHECK(job); // The built-in factories are not expected to fail!
return job;
}
}
return NULL;
}
std::string ToLower(const std::string& str) {
std::string str_lower = str;
std::transform(str_lower.begin(), str_lower.end(), str_lower.begin(),
towlower);
return str;
}
// Class that manages the CefSchemeHandlerFactory instances.
class CefUrlRequestManager {
protected:
// Class used for creating URLRequestJob instances. The lifespan of this
// object is managed by URLRequestJobFactory.
class ProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
public:
explicit ProtocolHandler(const std::string& scheme)
: scheme_(scheme) {}
// From net::URLRequestJobFactory::ProtocolHandler
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
CEF_REQUIRE_IOT();
return CefUrlRequestManager::GetInstance()->GetRequestJob(
request, network_delegate, scheme_);
}
private:
std::string scheme_;
};
public:
CefUrlRequestManager() {}
// Retrieve the singleton instance.
static CefUrlRequestManager* GetInstance();
bool AddFactory(const std::string& scheme,
const std::string& domain,
CefRefPtr<CefSchemeHandlerFactory> factory) {
if (!factory.get()) {
RemoveFactory(scheme, domain);
return true;
}
CEF_REQUIRE_IOT();
std::string scheme_lower = ToLower(scheme);
std::string domain_lower = ToLower(domain);
// Hostname is only supported for standard schemes.
if (!IsStandardScheme(scheme_lower))
domain_lower.clear();
SetProtocolHandlerIfNecessary(scheme_lower, true);
handler_map_[make_pair(scheme_lower, domain_lower)] = factory;
return true;
}
void RemoveFactory(const std::string& scheme,
const std::string& domain) {
CEF_REQUIRE_IOT();
std::string scheme_lower = ToLower(scheme);
std::string domain_lower = ToLower(domain);
// Hostname is only supported for standard schemes.
if (!IsStandardScheme(scheme_lower))
domain_lower.clear();
HandlerMap::iterator iter =
handler_map_.find(make_pair(scheme_lower, domain_lower));
if (iter != handler_map_.end()) {
handler_map_.erase(iter);
SetProtocolHandlerIfNecessary(scheme_lower, false);
}
}
// Clear all the existing URL handlers and unregister the ProtocolFactory.
void ClearFactories() {
CEF_REQUIRE_IOT();
net::URLRequestJobFactoryImpl* job_factory = GetJobFactoryImpl();
// Create a unique set of scheme names.
std::set<std::string> schemes;
for (HandlerMap::const_iterator i = handler_map_.begin();
i != handler_map_.end(); ++i) {
schemes.insert(i->first.first);
}
for (std::set<std::string>::const_iterator scheme = schemes.begin();
scheme != schemes.end(); ++scheme) {
const std::string& scheme_name = *scheme;
if (!scheme::IsInternalProtectedScheme(scheme_name)) {
bool set_protocol = job_factory->SetProtocolHandler(scheme_name, NULL);
DCHECK(set_protocol);
}
}
handler_map_.clear();
}
// Helper for chaining ProtocolHandler implementations.
net::URLRequestJob* GetRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate) {
CEF_REQUIRE_IOT();
return GetRequestJob(request, network_delegate, request->url().scheme());
}
private:
net::URLRequestJobFactoryImpl* GetJobFactoryImpl() {
return CefContentBrowserClient::Get()->request_context()->
job_factory_impl();
}
// Add or remove the protocol handler if necessary. |scheme| will already be
// in lower case.
void SetProtocolHandlerIfNecessary(const std::string& scheme, bool add) {
// Don't modify a protocol handler for internal protected schemes or if the
// protocol handler is still needed by other registered factories.
if (scheme::IsInternalProtectedScheme(scheme) || HasFactory(scheme))
return;
net::URLRequestJobFactoryImpl* job_factory = GetJobFactoryImpl();
bool set_protocol = job_factory->SetProtocolHandler(
scheme,
(add ? new ProtocolHandler(scheme) : NULL));
DCHECK(set_protocol);
}
// Returns true if any factory currently exists for |scheme|. |scheme| will
// already be in lower case.
bool HasFactory(const std::string& scheme) {
if (handler_map_.empty())
return false;
for (HandlerMap::const_iterator i = handler_map_.begin();
i != handler_map_.end(); ++i) {
if (scheme == i->first.first)
return true;
}
return false;
}
// Retrieve the matching handler factory, if any. |scheme| will already be in
// lower case.
CefRefPtr<CefSchemeHandlerFactory> GetHandlerFactory(
net::URLRequest* request, const std::string& scheme) {
CefRefPtr<CefSchemeHandlerFactory> factory;
if (request->url().is_valid() && IsStandardScheme(scheme)) {
// Check for a match with a domain first.
const std::string& domain = request->url().host();
HandlerMap::iterator i = handler_map_.find(make_pair(scheme, domain));
if (i != handler_map_.end())
factory = i->second;
}
if (!factory.get()) {
// Check for a match with no specified domain.
HandlerMap::iterator i =
handler_map_.find(make_pair(scheme, std::string()));
if (i != handler_map_.end())
factory = i->second;
}
return factory;
}
// Create the job that will handle the request. |scheme| will already be in
// lower case.
net::URLRequestJob* GetRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& scheme) {
net::URLRequestJob* job = NULL;
CefRefPtr<CefSchemeHandlerFactory> factory =
GetHandlerFactory(request, scheme);
if (factory.get()) {
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
CefRefPtr<CefFrame> frame;
if (browser.get())
frame = browser->GetFrameForRequest(request);
// Populate the request data.
CefRefPtr<CefRequestImpl> requestPtr(new CefRequestImpl());
requestPtr->Set(request);
// Call the handler factory to create the handler for the request.
CefRefPtr<CefResourceHandler> handler =
factory->Create(browser.get(), frame, scheme, requestPtr.get());
if (handler.get())
job = new CefResourceRequestJob(request, network_delegate, handler);
}
if (!job && IsBuiltinScheme(scheme)) {
// Give the built-in scheme handler a chance to handle the request.
job = GetBuiltinSchemeRequestJob(request, network_delegate, scheme);
}
#ifndef NDEBUG
if (job)
DLOG(INFO) << "CefUrlRequestManager hit for " << request->url().spec();
#endif
return job;
}
// Map (scheme, domain) to factories. Will only be accessed on the IO thread.
typedef std::map<std::pair<std::string, std::string>,
CefRefPtr<CefSchemeHandlerFactory> > HandlerMap;
HandlerMap handler_map_;
DISALLOW_EVIL_CONSTRUCTORS(CefUrlRequestManager);
};
base::LazyInstance<CefUrlRequestManager> g_manager = LAZY_INSTANCE_INITIALIZER;
CefUrlRequestManager* CefUrlRequestManager::GetInstance() {
return g_manager.Pointer();
}
} // namespace
bool CefRegisterSchemeHandlerFactory(
const CefString& scheme_name,
const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID())
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return false;
if (CEF_CURRENTLY_ON(CEF_IOT)) {
return CefUrlRequestManager::GetInstance()->AddFactory(scheme_name,
domain_name,
factory);
} else {
CEF_POST_TASK(CEF_IOT,
base::Bind(base::IgnoreResult(&CefRegisterSchemeHandlerFactory),
scheme_name, domain_name, factory));
return true;
}
return CefRequestContext::GetGlobalContext()->
RegisterSchemeHandlerFactory(scheme_name, domain_name, factory);
}
bool CefClearSchemeHandlerFactories() {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID())
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return false;
if (CEF_CURRENTLY_ON(CEF_IOT)) {
CefUrlRequestManager::GetInstance()->ClearFactories();
// Register internal scheme handlers.
scheme::RegisterInternalHandlers();
} else {
CEF_POST_TASK(CEF_IOT,
base::Bind(base::IgnoreResult(&CefClearSchemeHandlerFactories)));
}
return true;
return CefRequestContext::GetGlobalContext()->
ClearSchemeHandlerFactories();
}
namespace scheme {
net::URLRequestJob* GetRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate) {
return CefUrlRequestManager::GetInstance()->GetRequestJob(
request, network_delegate);
}
} // namespace scheme

View File

@ -1,24 +0,0 @@
// Copyright (c) 2013 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_SCHEME_IMPL_H_
#define CEF_LIBCEF_BROWSER_SCHEME_IMPL_H_
#pragma once
namespace net {
class NetworkDelegate;
class URLRequest;
class URLRequestJob;
}
namespace scheme {
// Helper for chaining net::URLRequestJobFactory::ProtocolHandler
// implementations.
net::URLRequestJob* GetRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate);
} // namespace scheme
#endif // CEF_LIBCEF_BROWSER_SCHEME_IMPL_H_

View File

@ -10,8 +10,6 @@
#include <string>
#include <vector>
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/scheme_handler.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_network_delegate.h"
@ -98,12 +96,16 @@ class CefHttpUserAgentSettings : public net::HttpUserAgentSettings {
} // namespace
CefURLRequestContextGetterImpl::CefURLRequestContextGetterImpl(
const CefRequestContextSettings& settings,
base::MessageLoop* io_loop,
base::MessageLoop* file_loop,
content::ProtocolHandlerMap* protocol_handlers,
scoped_ptr<net::ProxyConfigService> proxy_config_service,
content::URLRequestInterceptorScopedVector request_interceptors)
: io_loop_(io_loop),
: settings_(settings),
io_loop_(io_loop),
file_loop_(file_loop),
proxy_config_service_(proxy_config_service.Pass()),
request_interceptors_(request_interceptors.Pass()) {
// Must first be created on the UI thread.
CEF_REQUIRE_UIT();
@ -124,19 +126,19 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
CEF_REQUIRE_IOT();
if (!url_request_context_.get()) {
const base::FilePath& cache_path = CefContext::Get()->cache_path();
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
const CefSettings& settings = CefContext::Get()->settings();
base::FilePath cache_path;
if (settings_.cache_path.length > 0)
cache_path = base::FilePath(CefString(&settings_.cache_path));
url_request_context_.reset(new CefURLRequestContextImpl());
storage_.reset(
new net::URLRequestContextStorage(url_request_context_.get()));
bool persist_session_cookies =
(settings.persist_session_cookies ||
command_line->HasSwitch(switches::kPersistSessionCookies));
SetCookieStoragePath(cache_path, persist_session_cookies);
SetCookieStoragePath(cache_path,
settings_.persist_session_cookies ? true : false);
storage_->set_network_delegate(new CefNetworkDelegate);
@ -146,8 +148,8 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
base::WorkerPool::GetTaskRunner(true))));
const std::string& accept_language =
settings.accept_language_list.length > 0 ?
CefString(&settings.accept_language_list): "en-US,en";
settings_.accept_language_list.length > 0 ?
CefString(&settings_.accept_language_list): "en-US,en";
storage_->set_http_user_agent_settings(
new CefHttpUserAgentSettings(accept_language));
@ -161,7 +163,7 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
NULL,
url_request_context_.get(),
url_request_context_->network_delegate(),
CefContentBrowserClient::Get()->proxy_config_service().release(),
proxy_config_service_.release(),
*command_line,
true));
storage_->set_proxy_service(system_proxy_service.release());
@ -218,8 +220,7 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
network_session_params.http_server_properties =
url_request_context_->http_server_properties();
network_session_params.ignore_certificate_errors =
(settings.ignore_certificate_errors ||
command_line->HasSwitch(switches::kIgnoreCertificateErrors));
settings_.ignore_certificate_errors ? true : false;
net::HttpCache* main_cache = new net::HttpCache(network_session_params,
main_backend);
@ -232,13 +233,18 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
new net::URLRequestJobFactoryImpl());
job_factory_impl_ = job_factory.get();
url_request_manager_.reset(new CefURLRequestManager(job_factory.get()));
// Install internal scheme handlers that cannot be overridden.
scheme::InstallInternalProtectedHandlers(job_factory.get(),
url_request_manager_.get(),
&protocol_handlers_,
ftp_transaction_factory_.get());
protocol_handlers_.clear();
// Register internal scheme handlers that can be overridden.
scheme::RegisterInternalHandlers(url_request_manager_.get());
request_interceptors_.push_back(new CefRequestInterceptor());
// Set up interceptors in the reverse order.
@ -256,7 +262,12 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
storage_->set_job_factory(top_job_factory.release());
#if defined(USE_NSS)
net::SetURLRequestContextForNSSHttpIO(url_request_context_.get());
// Only do this for the first (global) request context.
static bool request_context_for_nss_set = false;
if (!request_context_for_nss_set) {
net::SetURLRequestContextForNSSHttpIO(url_request_context_.get());
request_context_for_nss_set = true;
}
#endif
}
@ -347,6 +358,16 @@ void CefURLRequestContextGetterImpl::SetCookieSupportedSchemes(
delete [] arr;
}
void CefURLRequestContextGetterImpl::AddHandler(
CefRefPtr<CefRequestContextHandler> handler) {
if (!CEF_CURRENTLY_ON_IOT()) {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefURLRequestContextGetterImpl::AddHandler, this, handler));
return;
}
handler_list_.push_back(handler);
}
void CefURLRequestContextGetterImpl::CreateProxyConfigService() {
if (proxy_config_service_.get())
return;

View File

@ -9,8 +9,10 @@
#include <string>
#include <vector>
#include "include/internal/cef_types_wrappers.h"
#include "libcef/browser/url_request_context_getter.h"
#include "libcef/browser/url_request_context_impl.h"
#include "libcef/browser/url_request_manager.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
@ -32,16 +34,18 @@ class URLRequestJobFactoryImpl;
class URLSecurityManager;
}
// Global URLRequestContextGetter implementation. Life span is primarily
// controlled by CefResourceContext and CefBrowserMainParts. Created on the UI
// thread but accessed and destroyed on the IO thread. See browser_context.h
// for an object relationship diagram.
// Isolated URLRequestContextGetter implementation. Life span is primarily
// controlled by CefResourceContext and (for the global context)
// CefBrowserMainParts. Created on the UI thread but accessed and destroyed on
// the IO thread. See browser_context.h for an object relationship diagram.
class CefURLRequestContextGetterImpl : public CefURLRequestContextGetter {
public:
CefURLRequestContextGetterImpl(
const CefRequestContextSettings& settings,
base::MessageLoop* io_loop,
base::MessageLoop* file_loop,
content::ProtocolHandlerMap* protocol_handlers,
scoped_ptr<net::ProxyConfigService> proxy_config_service,
content::URLRequestInterceptorScopedVector request_interceptors);
~CefURLRequestContextGetterImpl() override;
@ -53,32 +57,40 @@ class CefURLRequestContextGetterImpl : public CefURLRequestContextGetter {
// CefURLRequestContextGetter implementation.
net::HostResolver* GetHostResolver() const override;
net::URLRequestJobFactoryImpl* job_factory_impl() const {
return job_factory_impl_;
}
void SetCookieStoragePath(const base::FilePath& path,
bool persist_session_cookies);
void SetCookieSupportedSchemes(const std::vector<std::string>& schemes);
// Keep a reference to all handlers sharing this context so that they'll be
// kept alive until the context is destroyed.
void AddHandler(CefRefPtr<CefRequestContextHandler> handler);
CefURLRequestManager* request_manager() const {
return url_request_manager_.get();
}
private:
void CreateProxyConfigService();
const CefRequestContextSettings settings_;
base::MessageLoop* io_loop_;
base::MessageLoop* file_loop_;
scoped_ptr<net::ProxyConfigService> proxy_config_service_;
scoped_ptr<net::URLRequestContextStorage> storage_;
scoped_ptr<CefURLRequestContextImpl> url_request_context_;
scoped_ptr<CefURLRequestManager> url_request_manager_;
scoped_ptr<net::URLSecurityManager> url_security_manager_;
scoped_ptr<net::FtpTransactionFactory> ftp_transaction_factory_;
content::ProtocolHandlerMap protocol_handlers_;
content::URLRequestInterceptorScopedVector request_interceptors_;
net::URLRequestJobFactoryImpl* job_factory_impl_;
base::FilePath cookie_store_path_;
std::vector<std::string> cookie_supported_schemes_;
std::vector<CefRefPtr<CefRequestContextHandler> > handler_list_;
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextGetterImpl);
};

View File

@ -12,7 +12,8 @@ CefURLRequestContextGetterProxy::CefURLRequestContextGetterProxy(
scoped_refptr<CefURLRequestContextGetterImpl> parent)
: handler_(handler),
parent_(parent) {
DCHECK(parent);
DCHECK(handler_.get());
DCHECK(parent_.get());
}
CefURLRequestContextGetterProxy::~CefURLRequestContextGetterProxy() {

View File

@ -15,8 +15,9 @@
class CefURLRequestContextProxy;
// URLRequestContextGetter implementation for a particular CefRequestContext.
// Life span is primarily controlled by CefResourceContext. Only accessed on the
// IO thread. See browser_context.h for an object relationship diagram.
// Life span is primarily controlled by CefResourceContext. Created on the UI
// thread but accessed and destroyed on the IO thread. See browser_context.h for
// an object relationship diagram.
class CefURLRequestContextGetterProxy : public CefURLRequestContextGetter {
public:
CefURLRequestContextGetterProxy(

View File

@ -8,7 +8,7 @@
#include "libcef/browser/url_request_context.h"
// Global URLRequestContext implementation. Life span is controlled by
// Isolated URLRequestContext implementation. Life span is controlled by
// CefURLRequestContextGetterImpl. Only accessed on the IO thread. See
// browser_context.h for an object relationship diagram.
class CefURLRequestContextImpl : public CefURLRequestContext {

View File

@ -12,6 +12,8 @@ CefURLRequestContextProxy::CefURLRequestContextProxy(
CefURLRequestContextImpl* parent,
CefRefPtr<CefRequestContextHandler> handler) {
CEF_REQUIRE_IOT();
DCHECK(parent);
DCHECK(handler.get());
// Cookie store that proxies to the browser implementation.
cookie_store_proxy_ = new CefCookieStoreProxy(parent, handler);

View File

@ -0,0 +1,282 @@
// Copyright (c) 2015 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2009 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/url_request_manager.h"
#include "include/cef_browser.h"
#include "include/cef_scheme.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/resource_request_job.h"
#include "libcef/browser/scheme_handler.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/scheme_registration.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_http_job.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "url/third_party/mozilla/url_parse.h"
#include "url/url_util.h"
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;
net::URLRequest::ProtocolFactory* factory;
};
static const SchemeToFactory kBuiltinFactories[] = {
{ "http", net::URLRequestHttpJob::Factory },
{ "https", net::URLRequestHttpJob::Factory },
};
bool IsBuiltinScheme(const std::string& scheme) {
for (size_t i = 0; i < arraysize(kBuiltinFactories); ++i)
if (LowerCaseEqualsASCII(scheme, kBuiltinFactories[i].scheme))
return true;
return false;
}
net::URLRequestJob* GetBuiltinSchemeRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& scheme) {
// See if the request should be handled by a built-in protocol factory.
for (size_t i = 0; i < arraysize(kBuiltinFactories); ++i) {
if (scheme == kBuiltinFactories[i].scheme) {
net::URLRequestJob* job =
(kBuiltinFactories[i].factory)(request, network_delegate, scheme);
DCHECK(job); // The built-in factories are not expected to fail!
return job;
}
}
return NULL;
}
std::string ToLower(const std::string& str) {
std::string str_lower = str;
std::transform(str_lower.begin(), str_lower.end(), str_lower.begin(),
towlower);
return str;
}
} // namespace
// Class used for creating URLRequestJob instances. The lifespan of this object
// is managed by URLRequestJobFactory.
class CefProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
public:
CefProtocolHandler(CefURLRequestManager* request_manager,
const std::string& scheme)
: request_manager_(request_manager),
scheme_(scheme) {}
// From net::URLRequestJobFactory::ProtocolHandler
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
CEF_REQUIRE_IOT();
return request_manager_->GetRequestJob(request, network_delegate, scheme_);
}
private:
CefURLRequestManager* request_manager_;
std::string scheme_;
};
CefURLRequestManager::CefURLRequestManager(
net::URLRequestJobFactoryImpl* job_factory)
: job_factory_(job_factory) {
CEF_REQUIRE_IOT();
DCHECK(job_factory_);
}
CefURLRequestManager::~CefURLRequestManager() {
CEF_REQUIRE_IOT();
}
bool CefURLRequestManager::AddFactory(
const std::string& scheme,
const std::string& domain,
CefRefPtr<CefSchemeHandlerFactory> factory) {
if (!factory.get()) {
RemoveFactory(scheme, domain);
return true;
}
CEF_REQUIRE_IOT();
std::string scheme_lower = ToLower(scheme);
std::string domain_lower = ToLower(domain);
// Hostname is only supported for standard schemes.
if (!IsStandardScheme(scheme_lower))
domain_lower.clear();
SetProtocolHandlerIfNecessary(scheme_lower, true);
handler_map_[make_pair(scheme_lower, domain_lower)] = factory;
return true;
}
void CefURLRequestManager::RemoveFactory(const std::string& scheme,
const std::string& domain) {
CEF_REQUIRE_IOT();
std::string scheme_lower = ToLower(scheme);
std::string domain_lower = ToLower(domain);
// Hostname is only supported for standard schemes.
if (!IsStandardScheme(scheme_lower))
domain_lower.clear();
HandlerMap::iterator iter =
handler_map_.find(make_pair(scheme_lower, domain_lower));
if (iter != handler_map_.end()) {
handler_map_.erase(iter);
SetProtocolHandlerIfNecessary(scheme_lower, false);
}
}
// Clear all the existing URL handlers and unregister the ProtocolFactory.
void CefURLRequestManager::ClearFactories() {
CEF_REQUIRE_IOT();
// Create a unique set of scheme names.
std::set<std::string> schemes;
for (HandlerMap::const_iterator i = handler_map_.begin();
i != handler_map_.end(); ++i) {
schemes.insert(i->first.first);
}
for (std::set<std::string>::const_iterator scheme = schemes.begin();
scheme != schemes.end(); ++scheme) {
const std::string& scheme_name = *scheme;
if (!scheme::IsInternalProtectedScheme(scheme_name)) {
bool set_protocol = job_factory_->SetProtocolHandler(scheme_name, NULL);
DCHECK(set_protocol);
}
}
handler_map_.clear();
// Re-register internal scheme handlers that can be overridden.
scheme::RegisterInternalHandlers(this);
}
// Helper for chaining ProtocolHandler implementations.
net::URLRequestJob* CefURLRequestManager::GetRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) {
CEF_REQUIRE_IOT();
return GetRequestJob(request, network_delegate, request->url().scheme());
}
void CefURLRequestManager::SetProtocolHandlerIfNecessary(
const std::string& scheme,
bool add) {
// Don't modify a protocol handler for internal protected schemes or if the
// protocol handler is still needed by other registered factories.
if (scheme::IsInternalProtectedScheme(scheme) || HasFactory(scheme))
return;
bool set_protocol = job_factory_->SetProtocolHandler(
scheme,
(add ? new CefProtocolHandler(this, scheme) : NULL));
DCHECK(set_protocol);
}
bool CefURLRequestManager::HasFactory(const std::string& scheme) {
if (handler_map_.empty())
return false;
for (HandlerMap::const_iterator i = handler_map_.begin();
i != handler_map_.end(); ++i) {
if (scheme == i->first.first)
return true;
}
return false;
}
CefRefPtr<CefSchemeHandlerFactory> CefURLRequestManager::GetHandlerFactory(
net::URLRequest* request,
const std::string& scheme) {
CefRefPtr<CefSchemeHandlerFactory> factory;
if (request->url().is_valid() && IsStandardScheme(scheme)) {
// Check for a match with a domain first.
const std::string& domain = request->url().host();
HandlerMap::iterator i = handler_map_.find(make_pair(scheme, domain));
if (i != handler_map_.end())
factory = i->second;
}
if (!factory.get()) {
// Check for a match with no specified domain.
HandlerMap::iterator i =
handler_map_.find(make_pair(scheme, std::string()));
if (i != handler_map_.end())
factory = i->second;
}
return factory;
}
net::URLRequestJob* CefURLRequestManager::GetRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& scheme) {
net::URLRequestJob* job = NULL;
CefRefPtr<CefSchemeHandlerFactory> factory =
GetHandlerFactory(request, scheme);
if (factory.get()) {
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
CefRefPtr<CefFrame> frame;
if (browser.get())
frame = browser->GetFrameForRequest(request);
// Populate the request data.
CefRefPtr<CefRequestImpl> requestPtr(new CefRequestImpl());
requestPtr->Set(request);
// Call the handler factory to create the handler for the request.
CefRefPtr<CefResourceHandler> handler =
factory->Create(browser.get(), frame, scheme, requestPtr.get());
if (handler.get())
job = new CefResourceRequestJob(request, network_delegate, handler);
}
if (!job && IsBuiltinScheme(scheme)) {
// Give the built-in scheme handler a chance to handle the request.
job = GetBuiltinSchemeRequestJob(request, network_delegate, scheme);
}
#ifndef NDEBUG
if (job)
DLOG(INFO) << "CefURLRequestManager hit for " << request->url().spec();
#endif
return job;
}

View File

@ -0,0 +1,80 @@
// Copyright (c) 2015 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_URL_REQUEST_MANAGER_H_
#define CEF_LIBCEF_BROWSER_URL_REQUEST_MANAGER_H_
#pragma once
#include <map>
#include "include/cef_scheme.h"
namespace net {
class NetworkDelegate;
class URLRequest;
class URLRequestJob;
class URLRequestJobFactoryImpl;
}
class CefProtocolHandler;
// Class that manages CefSchemeHandlerFactory instances. Only accessed on the IO
// thread.
class CefURLRequestManager {
public:
explicit CefURLRequestManager(net::URLRequestJobFactoryImpl* job_factory);
~CefURLRequestManager();
// Add |factory| for the specified |scheme| and |domain|. See documentation on
// CefRequestContext::RegisterSchemeHandlerFactory() for usage.
bool AddFactory(const std::string& scheme,
const std::string& domain,
CefRefPtr<CefSchemeHandlerFactory> factory);
// Remove all factories associated with the specified |scheme| and |domain|.
void RemoveFactory(const std::string& scheme,
const std::string& domain);
// Clear all the existing URL handlers and unregister the ProtocolFactory.
void ClearFactories();
// Helper for chaining ProtocolHandler implementations.
net::URLRequestJob* GetRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate);
private:
friend class CefProtocolHandler;
// Add or remove the protocol handler if necessary. |scheme| will already be
// in lower case.
void SetProtocolHandlerIfNecessary(const std::string& scheme, bool add);
// Returns true if any factory currently exists for |scheme|. |scheme| will
// already be in lower case.
bool HasFactory(const std::string& scheme);
// Retrieve the matching handler factory, if any. |scheme| will already be in
// lower case.
CefRefPtr<CefSchemeHandlerFactory> GetHandlerFactory(
net::URLRequest* request, const std::string& scheme);
// Create the job that will handle the request. |scheme| will already be in
// lower case.
net::URLRequestJob* GetRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& scheme);
// Life span of |job_factory_| is guaranteed by
// CefURLRequestContextGetterImpl which also owns this object.
net::URLRequestJobFactoryImpl* job_factory_;
// Map (scheme, domain) to factories.
typedef std::map<std::pair<std::string, std::string>,
CefRefPtr<CefSchemeHandlerFactory> > HandlerMap;
HandlerMap handler_map_;
DISALLOW_COPY_AND_ASSIGN(CefURLRequestManager);
};
#endif // CEF_LIBCEF_BROWSER_URL_REQUEST_MANAGER_H_

View File

@ -49,6 +49,11 @@
#include "components/crash/app/breakpad_linux.h"
#endif
#if defined(OS_LINUX)
#include "base/environment.h"
#include "base/nix/xdg_util.h"
#endif
namespace {
base::LazyInstance<CefCrashReporterClient>::Leaky g_crash_reporter_client =
@ -117,6 +122,64 @@ base::FilePath GetLibrariesFilePath() {
#endif // !defined(OS_MACOSX)
#if defined(OS_LINUX)
// Based on chrome/common/chrome_paths_linux.cc.
// See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
// for a spec on where config files go. The net effect for most
// systems is we use ~/.config/chromium/ for Chromium and
// ~/.config/google-chrome/ for official builds.
// (This also helps us sidestep issues with other apps grabbing ~/.chromium .)
bool GetDefaultUserDataDirectory(base::FilePath* result) {
scoped_ptr<base::Environment> env(base::Environment::Create());
base::FilePath config_dir(
base::nix::GetXDGDirectory(env.get(),
base::nix::kXdgConfigHomeEnvVar,
base::nix::kDotConfigDir));
*result = config_dir.Append(FILE_PATH_LITERAL("cef_user_data"));
return true;
}
#elif defined(OS_MACOSX)
// Based on chrome/common/chrome_paths_mac.mm.
bool GetDefaultUserDataDirectory(base::FilePath* result) {
if (!PathService::Get(base::DIR_APP_DATA, result))
return false;
*result = result->Append(FILE_PATH_LITERAL("CEF"));
*result = result->Append(FILE_PATH_LITERAL("User Data"));
return true;
}
#elif defined(OS_WIN)
// Based on chrome/common/chrome_paths_win.cc.
bool GetDefaultUserDataDirectory(base::FilePath* result) {
if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result))
return false;
*result = result->Append(FILE_PATH_LITERAL("CEF"));
*result = result->Append(FILE_PATH_LITERAL("User Data"));
return true;
}
#endif
base::FilePath GetUserDataPath() {
const CefSettings& settings = CefContext::Get()->settings();
if (settings.user_data_path.length > 0)
return base::FilePath(CefString(&settings.user_data_path));
base::FilePath result;
if (GetDefaultUserDataDirectory(&result))
return result;
if (PathService::Get(base::DIR_TEMP, &result))
return result;
NOTREACHED();
return result;
}
// File name of the internal PDF plugin on different platforms.
const base::FilePath::CharType kInternalPDFPluginFileName[] =
#if defined(OS_WIN)
@ -417,14 +480,11 @@ void CefMainDelegate::PreSandboxStartup() {
#endif
// Paths used to locate spell checking dictionary files.
// TODO(cef): It may be better to use a persistent location for
// DIR_USER_DATA. See the implementation of GetDefaultUserDataDirectory in
// chrome/common/chrome_paths_*.
const base::FilePath& cache_path = CefContext::Get()->cache_path();
PathService::Override(chrome::DIR_USER_DATA, cache_path);
const base::FilePath& user_data_path = GetUserDataPath();
PathService::Override(chrome::DIR_USER_DATA, user_data_path);
PathService::OverrideAndCreateIfNeeded(
chrome::DIR_APP_DICTIONARIES,
cache_path.AppendASCII("Dictionaries"),
user_data_path.AppendASCII("Dictionaries"),
false, // May not be an absolute path.
true); // Create if necessary.
}

View File

@ -14,7 +14,8 @@
// static
CefRefPtr<CefURLRequest> CefURLRequest::Create(
CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client) {
CefRefPtr<CefURLRequestClient> client,
CefRefPtr<CefRequestContext> request_context) {
if (!request.get() || !client.get()) {
NOTREACHED() << "called with invalid parameters";
return NULL;
@ -28,7 +29,7 @@ CefRefPtr<CefURLRequest> CefURLRequest::Create(
if (CefContentClient::Get()->browser()) {
// In the browser process.
CefRefPtr<CefBrowserURLRequest> impl =
new CefBrowserURLRequest(request, client);
new CefBrowserURLRequest(request, client, request_context);
if (impl->Start())
return impl.get();
return NULL;

View File

@ -13,31 +13,39 @@
#include "libcef_dll/cpptoc/cookie_manager_cpptoc.h"
#include "libcef_dll/ctocpp/completion_callback_ctocpp.h"
#include "libcef_dll/ctocpp/cookie_visitor_ctocpp.h"
#include "libcef_dll/ctocpp/delete_cookies_callback_ctocpp.h"
#include "libcef_dll/ctocpp/set_cookie_callback_ctocpp.h"
#include "libcef_dll/transfer_util.h"
// GLOBAL FUNCTIONS - Body may be edited by hand.
CEF_EXPORT cef_cookie_manager_t* cef_cookie_manager_get_global_manager() {
CEF_EXPORT cef_cookie_manager_t* cef_cookie_manager_get_global_manager(
cef_completion_callback_t* callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: callback
// Execute
CefRefPtr<CefCookieManager> _retval = CefCookieManager::GetGlobalManager();
CefRefPtr<CefCookieManager> _retval = CefCookieManager::GetGlobalManager(
CefCompletionCallbackCToCpp::Wrap(callback));
// Return type: refptr_same
return CefCookieManagerCppToC::Wrap(_retval);
}
CEF_EXPORT cef_cookie_manager_t* cef_cookie_manager_create_manager(
const cef_string_t* path, int persist_session_cookies) {
const cef_string_t* path, int persist_session_cookies,
cef_completion_callback_t* callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: path
// Unverified params: path, callback
// Execute
CefRefPtr<CefCookieManager> _retval = CefCookieManager::CreateManager(
CefString(path),
persist_session_cookies?true:false);
persist_session_cookies?true:false,
CefCompletionCallbackCToCpp::Wrap(callback));
// Return type: refptr_same
return CefCookieManagerCppToC::Wrap(_retval);
@ -47,7 +55,8 @@ CEF_EXPORT cef_cookie_manager_t* cef_cookie_manager_create_manager(
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK cookie_manager_set_supported_schemes(
struct _cef_cookie_manager_t* self, cef_string_list_t schemes) {
struct _cef_cookie_manager_t* self, cef_string_list_t schemes,
cef_completion_callback_t* callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
@ -57,6 +66,7 @@ void CEF_CALLBACK cookie_manager_set_supported_schemes(
DCHECK(schemes);
if (!schemes)
return;
// Unverified params: callback
// Translate param: schemes; type: string_vec_byref_const
std::vector<CefString> schemesList;
@ -64,7 +74,8 @@ void CEF_CALLBACK cookie_manager_set_supported_schemes(
// Execute
CefCookieManagerCppToC::Get(self)->SetSupportedSchemes(
schemesList);
schemesList,
CefCompletionCallbackCToCpp::Wrap(callback));
}
int CEF_CALLBACK cookie_manager_visit_all_cookies(
@ -116,7 +127,8 @@ int CEF_CALLBACK cookie_manager_visit_url_cookies(
}
int CEF_CALLBACK cookie_manager_set_cookie(struct _cef_cookie_manager_t* self,
const cef_string_t* url, const struct _cef_cookie_t* cookie) {
const cef_string_t* url, const struct _cef_cookie_t* cookie,
struct _cef_set_cookie_callback_t* callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
@ -130,6 +142,7 @@ int CEF_CALLBACK cookie_manager_set_cookie(struct _cef_cookie_manager_t* self,
DCHECK(cookie);
if (!cookie)
return 0;
// Unverified params: callback
// Translate param: cookie; type: struct_byref_const
CefCookie cookieObj;
@ -139,7 +152,8 @@ int CEF_CALLBACK cookie_manager_set_cookie(struct _cef_cookie_manager_t* self,
// Execute
bool _retval = CefCookieManagerCppToC::Get(self)->SetCookie(
CefString(url),
cookieObj);
cookieObj,
CefSetCookieCallbackCToCpp::Wrap(callback));
// Return type: bool
return _retval;
@ -147,18 +161,20 @@ int CEF_CALLBACK cookie_manager_set_cookie(struct _cef_cookie_manager_t* self,
int CEF_CALLBACK cookie_manager_delete_cookies(
struct _cef_cookie_manager_t* self, const cef_string_t* url,
const cef_string_t* cookie_name) {
const cef_string_t* cookie_name,
struct _cef_delete_cookies_callback_t* callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Unverified params: url, cookie_name
// Unverified params: url, cookie_name, callback
// Execute
bool _retval = CefCookieManagerCppToC::Get(self)->DeleteCookies(
CefString(url),
CefString(cookie_name));
CefString(cookie_name),
CefDeleteCookiesCallbackCToCpp::Wrap(callback));
// Return type: bool
return _retval;
@ -166,18 +182,19 @@ int CEF_CALLBACK cookie_manager_delete_cookies(
int CEF_CALLBACK cookie_manager_set_storage_path(
struct _cef_cookie_manager_t* self, const cef_string_t* path,
int persist_session_cookies) {
int persist_session_cookies, cef_completion_callback_t* callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Unverified params: path
// Unverified params: path, callback
// Execute
bool _retval = CefCookieManagerCppToC::Get(self)->SetStoragePath(
CefString(path),
persist_session_cookies?true:false);
persist_session_cookies?true:false,
CefCompletionCallbackCToCpp::Wrap(callback));
// Return type: bool
return _retval;
@ -190,10 +207,7 @@ int CEF_CALLBACK cookie_manager_flush_store(struct _cef_cookie_manager_t* self,
DCHECK(self);
if (!self)
return 0;
// Verify param: callback; type: refptr_diff
DCHECK(callback);
if (!callback)
return 0;
// Unverified params: callback
// Execute
bool _retval = CefCookieManagerCppToC::Get(self)->FlushStore(

View File

@ -0,0 +1,45 @@
// Copyright (c) 2015 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.
//
#include "libcef_dll/cpptoc/delete_cookies_callback_cpptoc.h"
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK delete_cookies_callback_on_complete(
struct _cef_delete_cookies_callback_t* self, int num_deleted) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefDeleteCookiesCallbackCppToC::Get(self)->OnComplete(
num_deleted);
}
// CONSTRUCTOR - Do not edit by hand.
CefDeleteCookiesCallbackCppToC::CefDeleteCookiesCallbackCppToC(
CefDeleteCookiesCallback* cls)
: CefCppToC<CefDeleteCookiesCallbackCppToC, CefDeleteCookiesCallback,
cef_delete_cookies_callback_t>(cls) {
struct_.struct_.on_complete = delete_cookies_callback_on_complete;
}
#ifndef NDEBUG
template<> base::AtomicRefCount CefCppToC<CefDeleteCookiesCallbackCppToC,
CefDeleteCookiesCallback, cef_delete_cookies_callback_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,36 @@
// Copyright (c) 2015 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.
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_DELETE_COOKIES_CALLBACK_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_DELETE_COOKIES_CALLBACK_CPPTOC_H_
#pragma once
#ifndef USING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
#else // USING_CEF_SHARED
#include "include/cef_cookie.h"
#include "include/capi/cef_cookie_capi.h"
#include "libcef_dll/cpptoc/cpptoc.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed wrapper-side only.
class CefDeleteCookiesCallbackCppToC
: public CefCppToC<CefDeleteCookiesCallbackCppToC, CefDeleteCookiesCallback,
cef_delete_cookies_callback_t> {
public:
explicit CefDeleteCookiesCallbackCppToC(CefDeleteCookiesCallback* cls);
};
#endif // USING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CPPTOC_DELETE_COOKIES_CALLBACK_CPPTOC_H_

View File

@ -10,8 +10,11 @@
// for more information.
//
#include "libcef_dll/cpptoc/cookie_manager_cpptoc.h"
#include "libcef_dll/cpptoc/request_context_cpptoc.h"
#include "libcef_dll/ctocpp/completion_callback_ctocpp.h"
#include "libcef_dll/ctocpp/request_context_handler_ctocpp.h"
#include "libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h"
// GLOBAL FUNCTIONS - Body may be edited by hand.
@ -27,13 +30,44 @@ CEF_EXPORT cef_request_context_t* cef_request_context_get_global_context() {
}
CEF_EXPORT cef_request_context_t* cef_request_context_create_context(
const struct _cef_request_context_settings_t* settings,
struct _cef_request_context_handler_t* handler) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: settings; type: struct_byref_const
DCHECK(settings);
if (!settings)
return NULL;
// Unverified params: handler
// Translate param: settings; type: struct_byref_const
CefRequestContextSettings settingsObj;
if (settings)
settingsObj.Set(*settings, false);
// Execute
CefRefPtr<CefRequestContext> _retval = CefRequestContext::CreateContext(
settingsObj,
CefRequestContextHandlerCToCpp::Wrap(handler));
// Return type: refptr_same
return CefRequestContextCppToC::Wrap(_retval);
}
CEF_EXPORT cef_request_context_t* create_context_shared(
cef_request_context_t* other,
struct _cef_request_context_handler_t* handler) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: other; type: refptr_same
DCHECK(other);
if (!other)
return NULL;
// Unverified params: handler
// Execute
CefRefPtr<CefRequestContext> _retval = CefRequestContext::CreateContext(
CefRequestContextCppToC::Unwrap(other),
CefRequestContextHandlerCToCpp::Wrap(handler));
// Return type: refptr_same
@ -63,6 +97,27 @@ int CEF_CALLBACK request_context_is_same(struct _cef_request_context_t* self,
return _retval;
}
int CEF_CALLBACK request_context_is_sharing_with(
struct _cef_request_context_t* self,
struct _cef_request_context_t* other) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: other; type: refptr_same
DCHECK(other);
if (!other)
return 0;
// Execute
bool _retval = CefRequestContextCppToC::Get(self)->IsSharingWith(
CefRequestContextCppToC::Unwrap(other));
// Return type: bool
return _retval;
}
int CEF_CALLBACK request_context_is_global(
struct _cef_request_context_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -94,6 +149,81 @@ struct _cef_request_context_handler_t* CEF_CALLBACK request_context_get_handler(
return CefRequestContextHandlerCToCpp::Unwrap(_retval);
}
cef_string_userfree_t CEF_CALLBACK request_context_get_cache_path(
struct _cef_request_context_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefString _retval = CefRequestContextCppToC::Get(self)->GetCachePath();
// Return type: string
return _retval.DetachToUserFree();
}
cef_cookie_manager_t* CEF_CALLBACK request_context_get_default_cookie_manager(
struct _cef_request_context_t* self, cef_completion_callback_t* callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Unverified params: callback
// Execute
CefRefPtr<CefCookieManager> _retval = CefRequestContextCppToC::Get(
self)->GetDefaultCookieManager(
CefCompletionCallbackCToCpp::Wrap(callback));
// Return type: refptr_same
return CefCookieManagerCppToC::Wrap(_retval);
}
int CEF_CALLBACK request_context_register_scheme_handler_factory(
struct _cef_request_context_t* self, const cef_string_t* scheme_name,
const cef_string_t* domain_name,
struct _cef_scheme_handler_factory_t* factory) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: scheme_name; type: string_byref_const
DCHECK(scheme_name);
if (!scheme_name)
return 0;
// Unverified params: domain_name, factory
// Execute
bool _retval = CefRequestContextCppToC::Get(
self)->RegisterSchemeHandlerFactory(
CefString(scheme_name),
CefString(domain_name),
CefSchemeHandlerFactoryCToCpp::Wrap(factory));
// Return type: bool
return _retval;
}
int CEF_CALLBACK request_context_clear_scheme_handler_factories(
struct _cef_request_context_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefRequestContextCppToC::Get(
self)->ClearSchemeHandlerFactories();
// Return type: bool
return _retval;
}
// CONSTRUCTOR - Do not edit by hand.
@ -101,8 +231,16 @@ CefRequestContextCppToC::CefRequestContextCppToC(CefRequestContext* cls)
: CefCppToC<CefRequestContextCppToC, CefRequestContext,
cef_request_context_t>(cls) {
struct_.struct_.is_same = request_context_is_same;
struct_.struct_.is_sharing_with = request_context_is_sharing_with;
struct_.struct_.is_global = request_context_is_global;
struct_.struct_.get_handler = request_context_get_handler;
struct_.struct_.get_cache_path = request_context_get_cache_path;
struct_.struct_.get_default_cookie_manager =
request_context_get_default_cookie_manager;
struct_.struct_.register_scheme_handler_factory =
request_context_register_scheme_handler_factory;
struct_.struct_.clear_scheme_handler_factories =
request_context_clear_scheme_handler_factories;
}
#ifndef NDEBUG

View File

@ -20,6 +20,8 @@
#include "include/cef_request_context.h"
#include "include/capi/cef_request_context_capi.h"
#include "include/cef_scheme.h"
#include "include/capi/cef_scheme_capi.h"
#include "libcef_dll/cpptoc/cpptoc.h"
// Wrap a C++ class with a C structure.

View File

@ -0,0 +1,45 @@
// Copyright (c) 2015 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.
//
#include "libcef_dll/cpptoc/set_cookie_callback_cpptoc.h"
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK set_cookie_callback_on_complete(
struct _cef_set_cookie_callback_t* self, int success) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefSetCookieCallbackCppToC::Get(self)->OnComplete(
success?true:false);
}
// CONSTRUCTOR - Do not edit by hand.
CefSetCookieCallbackCppToC::CefSetCookieCallbackCppToC(
CefSetCookieCallback* cls)
: CefCppToC<CefSetCookieCallbackCppToC, CefSetCookieCallback,
cef_set_cookie_callback_t>(cls) {
struct_.struct_.on_complete = set_cookie_callback_on_complete;
}
#ifndef NDEBUG
template<> base::AtomicRefCount CefCppToC<CefSetCookieCallbackCppToC,
CefSetCookieCallback, cef_set_cookie_callback_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,36 @@
// Copyright (c) 2015 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.
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_SET_COOKIE_CALLBACK_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_SET_COOKIE_CALLBACK_CPPTOC_H_
#pragma once
#ifndef USING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
#else // USING_CEF_SHARED
#include "include/cef_cookie.h"
#include "include/capi/cef_cookie_capi.h"
#include "libcef_dll/cpptoc/cpptoc.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed wrapper-side only.
class CefSetCookieCallbackCppToC
: public CefCppToC<CefSetCookieCallbackCppToC, CefSetCookieCallback,
cef_set_cookie_callback_t> {
public:
explicit CefSetCookieCallbackCppToC(CefSetCookieCallback* cls);
};
#endif // USING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CPPTOC_SET_COOKIE_CALLBACK_CPPTOC_H_

View File

@ -11,6 +11,7 @@
//
#include "libcef_dll/cpptoc/request_cpptoc.h"
#include "libcef_dll/cpptoc/request_context_cpptoc.h"
#include "libcef_dll/cpptoc/response_cpptoc.h"
#include "libcef_dll/cpptoc/urlrequest_cpptoc.h"
#include "libcef_dll/ctocpp/urlrequest_client_ctocpp.h"
@ -19,7 +20,8 @@
// GLOBAL FUNCTIONS - Body may be edited by hand.
CEF_EXPORT cef_urlrequest_t* cef_urlrequest_create(cef_request_t* request,
struct _cef_urlrequest_client_t* client) {
struct _cef_urlrequest_client_t* client,
cef_request_context_t* request_context) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: request; type: refptr_same
@ -30,11 +32,13 @@ CEF_EXPORT cef_urlrequest_t* cef_urlrequest_create(cef_request_t* request,
DCHECK(client);
if (!client)
return NULL;
// Unverified params: request_context
// Execute
CefRefPtr<CefURLRequest> _retval = CefURLRequest::Create(
CefRequestCppToC::Unwrap(request),
CefURLRequestClientCToCpp::Wrap(client));
CefURLRequestClientCToCpp::Wrap(client),
CefRequestContextCppToC::Unwrap(request_context));
// Return type: refptr_same
return CefURLRequestCppToC::Wrap(_retval);

View File

@ -12,32 +12,40 @@
#include "libcef_dll/cpptoc/completion_callback_cpptoc.h"
#include "libcef_dll/cpptoc/cookie_visitor_cpptoc.h"
#include "libcef_dll/cpptoc/delete_cookies_callback_cpptoc.h"
#include "libcef_dll/cpptoc/set_cookie_callback_cpptoc.h"
#include "libcef_dll/ctocpp/cookie_manager_ctocpp.h"
#include "libcef_dll/transfer_util.h"
// STATIC METHODS - Body may be edited by hand.
CefRefPtr<CefCookieManager> CefCookieManager::GetGlobalManager() {
CefRefPtr<CefCookieManager> CefCookieManager::GetGlobalManager(
CefRefPtr<CefCompletionCallback> callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: callback
// Execute
cef_cookie_manager_t* _retval = cef_cookie_manager_get_global_manager();
cef_cookie_manager_t* _retval = cef_cookie_manager_get_global_manager(
CefCompletionCallbackCppToC::Wrap(callback));
// Return type: refptr_same
return CefCookieManagerCToCpp::Wrap(_retval);
}
CefRefPtr<CefCookieManager> CefCookieManager::CreateManager(
const CefString& path, bool persist_session_cookies) {
const CefString& path, bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: path
// Unverified params: path, callback
// Execute
cef_cookie_manager_t* _retval = cef_cookie_manager_create_manager(
path.GetStruct(),
persist_session_cookies);
persist_session_cookies,
CefCompletionCallbackCppToC::Wrap(callback));
// Return type: refptr_same
return CefCookieManagerCToCpp::Wrap(_retval);
@ -47,12 +55,15 @@ CefRefPtr<CefCookieManager> CefCookieManager::CreateManager(
// VIRTUAL METHODS - Body may be edited by hand.
void CefCookieManagerCToCpp::SetSupportedSchemes(
const std::vector<CefString>& schemes) {
const std::vector<CefString>& schemes,
CefRefPtr<CefCompletionCallback> callback) {
if (CEF_MEMBER_MISSING(struct_, set_supported_schemes))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: callback
// Translate param: schemes; type: string_vec_byref_const
cef_string_list_t schemesList = cef_string_list_alloc();
DCHECK(schemesList);
@ -61,7 +72,8 @@ void CefCookieManagerCToCpp::SetSupportedSchemes(
// Execute
struct_->set_supported_schemes(struct_,
schemesList);
schemesList,
CefCompletionCallbackCppToC::Wrap(callback));
// Restore param:schemes; type: string_vec_byref_const
if (schemesList)
@ -115,7 +127,7 @@ bool CefCookieManagerCToCpp::VisitUrlCookies(const CefString& url,
}
bool CefCookieManagerCToCpp::SetCookie(const CefString& url,
const CefCookie& cookie) {
const CefCookie& cookie, CefRefPtr<CefSetCookieCallback> callback) {
if (CEF_MEMBER_MISSING(struct_, set_cookie))
return false;
@ -125,47 +137,52 @@ bool CefCookieManagerCToCpp::SetCookie(const CefString& url,
DCHECK(!url.empty());
if (url.empty())
return false;
// Unverified params: callback
// Execute
int _retval = struct_->set_cookie(struct_,
url.GetStruct(),
&cookie);
&cookie,
CefSetCookieCallbackCppToC::Wrap(callback));
// Return type: bool
return _retval?true:false;
}
bool CefCookieManagerCToCpp::DeleteCookies(const CefString& url,
const CefString& cookie_name) {
const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback) {
if (CEF_MEMBER_MISSING(struct_, delete_cookies))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: url, cookie_name
// Unverified params: url, cookie_name, callback
// Execute
int _retval = struct_->delete_cookies(struct_,
url.GetStruct(),
cookie_name.GetStruct());
cookie_name.GetStruct(),
CefDeleteCookiesCallbackCppToC::Wrap(callback));
// Return type: bool
return _retval?true:false;
}
bool CefCookieManagerCToCpp::SetStoragePath(const CefString& path,
bool persist_session_cookies) {
bool persist_session_cookies, CefRefPtr<CefCompletionCallback> callback) {
if (CEF_MEMBER_MISSING(struct_, set_storage_path))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: path
// Unverified params: path, callback
// Execute
int _retval = struct_->set_storage_path(struct_,
path.GetStruct(),
persist_session_cookies);
persist_session_cookies,
CefCompletionCallbackCppToC::Wrap(callback));
// Return type: bool
return _retval?true:false;
@ -178,10 +195,7 @@ bool CefCookieManagerCToCpp::FlushStore(
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: callback; type: refptr_diff
DCHECK(callback.get());
if (!callback.get())
return false;
// Unverified params: callback
// Execute
int _retval = struct_->flush_store(struct_,

View File

@ -34,17 +34,18 @@ class CefCookieManagerCToCpp
cef_cookie_manager_t>(str) {}
// CefCookieManager methods
virtual void SetSupportedSchemes(
const std::vector<CefString>& schemes) OVERRIDE;
virtual void SetSupportedSchemes(const std::vector<CefString>& schemes,
CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
virtual bool VisitAllCookies(CefRefPtr<CefCookieVisitor> visitor) OVERRIDE;
virtual bool VisitUrlCookies(const CefString& url, bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor) OVERRIDE;
virtual bool SetCookie(const CefString& url,
const CefCookie& cookie) OVERRIDE;
virtual bool DeleteCookies(const CefString& url,
const CefString& cookie_name) OVERRIDE;
virtual bool SetCookie(const CefString& url, const CefCookie& cookie,
CefRefPtr<CefSetCookieCallback> callback) OVERRIDE;
virtual bool DeleteCookies(const CefString& url, const CefString& cookie_name,
CefRefPtr<CefDeleteCookiesCallback> callback) OVERRIDE;
virtual bool SetStoragePath(const CefString& path,
bool persist_session_cookies) OVERRIDE;
bool persist_session_cookies,
CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
virtual bool FlushStore(CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
};

View File

@ -0,0 +1,34 @@
// Copyright (c) 2015 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.
//
#include "libcef_dll/ctocpp/delete_cookies_callback_ctocpp.h"
// VIRTUAL METHODS - Body may be edited by hand.
void CefDeleteCookiesCallbackCToCpp::OnComplete(int num_deleted) {
if (CEF_MEMBER_MISSING(struct_, on_complete))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->on_complete(struct_,
num_deleted);
}
#ifndef NDEBUG
template<> base::AtomicRefCount CefCToCpp<CefDeleteCookiesCallbackCToCpp,
CefDeleteCookiesCallback, cef_delete_cookies_callback_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,41 @@
// Copyright (c) 2015 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.
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_DELETE_COOKIES_CALLBACK_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_DELETE_COOKIES_CALLBACK_CTOCPP_H_
#pragma once
#ifndef BUILDING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
#else // BUILDING_CEF_SHARED
#include "include/cef_cookie.h"
#include "include/capi/cef_cookie_capi.h"
#include "libcef_dll/ctocpp/ctocpp.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed DLL-side only.
class CefDeleteCookiesCallbackCToCpp
: public CefCToCpp<CefDeleteCookiesCallbackCToCpp, CefDeleteCookiesCallback,
cef_delete_cookies_callback_t> {
public:
explicit CefDeleteCookiesCallbackCToCpp(cef_delete_cookies_callback_t* str)
: CefCToCpp<CefDeleteCookiesCallbackCToCpp, CefDeleteCookiesCallback,
cef_delete_cookies_callback_t>(str) {}
// CefDeleteCookiesCallback methods
void OnComplete(int num_deleted) override;
};
#endif // BUILDING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CTOCPP_DELETE_COOKIES_CALLBACK_CTOCPP_H_

View File

@ -10,7 +10,10 @@
// for more information.
//
#include "libcef_dll/cpptoc/completion_callback_cpptoc.h"
#include "libcef_dll/cpptoc/request_context_handler_cpptoc.h"
#include "libcef_dll/cpptoc/scheme_handler_factory_cpptoc.h"
#include "libcef_dll/ctocpp/cookie_manager_ctocpp.h"
#include "libcef_dll/ctocpp/request_context_ctocpp.h"
@ -27,6 +30,7 @@ CefRefPtr<CefRequestContext> CefRequestContext::GetGlobalContext() {
}
CefRefPtr<CefRequestContext> CefRequestContext::CreateContext(
const CefRequestContextSettings& settings,
CefRefPtr<CefRequestContextHandler> handler) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -34,6 +38,27 @@ CefRefPtr<CefRequestContext> CefRequestContext::CreateContext(
// Execute
cef_request_context_t* _retval = cef_request_context_create_context(
&settings,
CefRequestContextHandlerCppToC::Wrap(handler));
// Return type: refptr_same
return CefRequestContextCToCpp::Wrap(_retval);
}
CefRefPtr<CefRequestContext> CefRequestContext::CreateContext(
CefRefPtr<CefRequestContext> other,
CefRefPtr<CefRequestContextHandler> handler) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: other; type: refptr_same
DCHECK(other.get());
if (!other.get())
return NULL;
// Unverified params: handler
// Execute
cef_request_context_t* _retval = create_context_shared(
CefRequestContextCToCpp::Unwrap(other),
CefRequestContextHandlerCppToC::Wrap(handler));
// Return type: refptr_same
@ -62,6 +87,26 @@ bool CefRequestContextCToCpp::IsSame(CefRefPtr<CefRequestContext> other) {
return _retval?true:false;
}
bool CefRequestContextCToCpp::IsSharingWith(
CefRefPtr<CefRequestContext> other) {
if (CEF_MEMBER_MISSING(struct_, is_sharing_with))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: other; type: refptr_same
DCHECK(other.get());
if (!other.get())
return false;
// Execute
int _retval = struct_->is_sharing_with(struct_,
CefRequestContextCToCpp::Unwrap(other));
// Return type: bool
return _retval?true:false;
}
bool CefRequestContextCToCpp::IsGlobal() {
if (CEF_MEMBER_MISSING(struct_, is_global))
return false;
@ -88,6 +133,75 @@ CefRefPtr<CefRequestContextHandler> CefRequestContextCToCpp::GetHandler() {
return CefRequestContextHandlerCppToC::Unwrap(_retval);
}
CefString CefRequestContextCToCpp::GetCachePath() {
if (CEF_MEMBER_MISSING(struct_, get_cache_path))
return CefString();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_string_userfree_t _retval = struct_->get_cache_path(struct_);
// Return type: string
CefString _retvalStr;
_retvalStr.AttachToUserFree(_retval);
return _retvalStr;
}
CefRefPtr<CefCookieManager> CefRequestContextCToCpp::GetDefaultCookieManager(
CefRefPtr<CefCompletionCallback> callback) {
if (CEF_MEMBER_MISSING(struct_, get_default_cookie_manager))
return NULL;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: callback
// Execute
cef_cookie_manager_t* _retval = struct_->get_default_cookie_manager(struct_,
CefCompletionCallbackCppToC::Wrap(callback));
// Return type: refptr_same
return CefCookieManagerCToCpp::Wrap(_retval);
}
bool CefRequestContextCToCpp::RegisterSchemeHandlerFactory(
const CefString& scheme_name, const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) {
if (CEF_MEMBER_MISSING(struct_, register_scheme_handler_factory))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: scheme_name; type: string_byref_const
DCHECK(!scheme_name.empty());
if (scheme_name.empty())
return false;
// Unverified params: domain_name, factory
// Execute
int _retval = struct_->register_scheme_handler_factory(struct_,
scheme_name.GetStruct(),
domain_name.GetStruct(),
CefSchemeHandlerFactoryCppToC::Wrap(factory));
// Return type: bool
return _retval?true:false;
}
bool CefRequestContextCToCpp::ClearSchemeHandlerFactories() {
if (CEF_MEMBER_MISSING(struct_, clear_scheme_handler_factories))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = struct_->clear_scheme_handler_factories(struct_);
// Return type: bool
return _retval?true:false;
}
#ifndef NDEBUG
template<> base::AtomicRefCount CefCToCpp<CefRequestContextCToCpp,

View File

@ -20,6 +20,8 @@
#include "include/cef_request_context.h"
#include "include/capi/cef_request_context_capi.h"
#include "include/cef_scheme.h"
#include "include/capi/cef_scheme_capi.h"
#include "libcef_dll/ctocpp/ctocpp.h"
// Wrap a C structure with a C++ class.
@ -34,8 +36,16 @@ class CefRequestContextCToCpp
// CefRequestContext methods
virtual bool IsSame(CefRefPtr<CefRequestContext> other) OVERRIDE;
virtual bool IsSharingWith(CefRefPtr<CefRequestContext> other) OVERRIDE;
virtual bool IsGlobal() OVERRIDE;
virtual CefRefPtr<CefRequestContextHandler> GetHandler() OVERRIDE;
virtual CefString GetCachePath() OVERRIDE;
virtual CefRefPtr<CefCookieManager> GetDefaultCookieManager(
CefRefPtr<CefCompletionCallback> callback) OVERRIDE;
virtual bool RegisterSchemeHandlerFactory(const CefString& scheme_name,
const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) OVERRIDE;
virtual bool ClearSchemeHandlerFactories() OVERRIDE;
};
#endif // USING_CEF_SHARED

View File

@ -0,0 +1,34 @@
// Copyright (c) 2015 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.
//
#include "libcef_dll/ctocpp/set_cookie_callback_ctocpp.h"
// VIRTUAL METHODS - Body may be edited by hand.
void CefSetCookieCallbackCToCpp::OnComplete(bool success) {
if (CEF_MEMBER_MISSING(struct_, on_complete))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->on_complete(struct_,
success);
}
#ifndef NDEBUG
template<> base::AtomicRefCount CefCToCpp<CefSetCookieCallbackCToCpp,
CefSetCookieCallback, cef_set_cookie_callback_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,41 @@
// Copyright (c) 2015 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.
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_SET_COOKIE_CALLBACK_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_SET_COOKIE_CALLBACK_CTOCPP_H_
#pragma once
#ifndef BUILDING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
#else // BUILDING_CEF_SHARED
#include "include/cef_cookie.h"
#include "include/capi/cef_cookie_capi.h"
#include "libcef_dll/ctocpp/ctocpp.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed DLL-side only.
class CefSetCookieCallbackCToCpp
: public CefCToCpp<CefSetCookieCallbackCToCpp, CefSetCookieCallback,
cef_set_cookie_callback_t> {
public:
explicit CefSetCookieCallbackCToCpp(cef_set_cookie_callback_t* str)
: CefCToCpp<CefSetCookieCallbackCToCpp, CefSetCookieCallback,
cef_set_cookie_callback_t>(str) {}
// CefSetCookieCallback methods
void OnComplete(bool success) override;
};
#endif // BUILDING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CTOCPP_SET_COOKIE_CALLBACK_CTOCPP_H_

View File

@ -12,6 +12,7 @@
#include "libcef_dll/cpptoc/urlrequest_client_cpptoc.h"
#include "libcef_dll/ctocpp/request_ctocpp.h"
#include "libcef_dll/ctocpp/request_context_ctocpp.h"
#include "libcef_dll/ctocpp/response_ctocpp.h"
#include "libcef_dll/ctocpp/urlrequest_ctocpp.h"
@ -19,7 +20,8 @@
// STATIC METHODS - Body may be edited by hand.
CefRefPtr<CefURLRequest> CefURLRequest::Create(CefRefPtr<CefRequest> request,
CefRefPtr<CefURLRequestClient> client) {
CefRefPtr<CefURLRequestClient> client,
CefRefPtr<CefRequestContext> request_context) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: request; type: refptr_same
@ -30,11 +32,13 @@ CefRefPtr<CefURLRequest> CefURLRequest::Create(CefRefPtr<CefRequest> request,
DCHECK(client.get());
if (!client.get())
return NULL;
// Unverified params: request_context
// Execute
cef_urlrequest_t* _retval = cef_urlrequest_create(
CefRequestCToCpp::Unwrap(request),
CefURLRequestClientCppToC::Wrap(client));
CefURLRequestClientCppToC::Wrap(client),
CefRequestContextCToCpp::Unwrap(request_context));
// Return type: refptr_same
return CefURLRequestCToCpp::Wrap(_retval);

View File

@ -80,6 +80,7 @@
#include "libcef_dll/ctocpp/context_menu_handler_ctocpp.h"
#include "libcef_dll/ctocpp/cookie_visitor_ctocpp.h"
#include "libcef_dll/ctocpp/domvisitor_ctocpp.h"
#include "libcef_dll/ctocpp/delete_cookies_callback_ctocpp.h"
#include "libcef_dll/ctocpp/dialog_handler_ctocpp.h"
#include "libcef_dll/ctocpp/display_handler_ctocpp.h"
#include "libcef_dll/ctocpp/download_handler_ctocpp.h"
@ -103,6 +104,7 @@
#include "libcef_dll/ctocpp/resource_handler_ctocpp.h"
#include "libcef_dll/ctocpp/run_file_dialog_callback_ctocpp.h"
#include "libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h"
#include "libcef_dll/ctocpp/set_cookie_callback_ctocpp.h"
#include "libcef_dll/ctocpp/string_visitor_ctocpp.h"
#include "libcef_dll/ctocpp/task_ctocpp.h"
#include "libcef_dll/ctocpp/urlrequest_client_ctocpp.h"
@ -202,6 +204,8 @@ CEF_EXPORT void cef_shutdown() {
DCHECK(base::AtomicRefCountIsZero(&CefDOMDocumentCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefDOMNodeCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefDOMVisitorCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(
&CefDeleteCookiesCallbackCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefDialogHandlerCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefDictionaryValueCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefDisplayHandlerCToCpp::DebugObjCt));
@ -251,6 +255,7 @@ CEF_EXPORT void cef_shutdown() {
DCHECK(base::AtomicRefCountIsZero(
&CefSchemeHandlerFactoryCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefSchemeRegistrarCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefSetCookieCallbackCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefStreamReaderCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefStreamWriterCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefStringVisitorCToCpp::DebugObjCt));

View File

@ -39,6 +39,7 @@
#include "libcef_dll/cpptoc/context_menu_handler_cpptoc.h"
#include "libcef_dll/cpptoc/cookie_visitor_cpptoc.h"
#include "libcef_dll/cpptoc/domvisitor_cpptoc.h"
#include "libcef_dll/cpptoc/delete_cookies_callback_cpptoc.h"
#include "libcef_dll/cpptoc/dialog_handler_cpptoc.h"
#include "libcef_dll/cpptoc/display_handler_cpptoc.h"
#include "libcef_dll/cpptoc/download_handler_cpptoc.h"
@ -62,6 +63,7 @@
#include "libcef_dll/cpptoc/resource_handler_cpptoc.h"
#include "libcef_dll/cpptoc/run_file_dialog_callback_cpptoc.h"
#include "libcef_dll/cpptoc/scheme_handler_factory_cpptoc.h"
#include "libcef_dll/cpptoc/set_cookie_callback_cpptoc.h"
#include "libcef_dll/cpptoc/string_visitor_cpptoc.h"
#include "libcef_dll/cpptoc/task_cpptoc.h"
#include "libcef_dll/cpptoc/urlrequest_client_cpptoc.h"
@ -194,6 +196,8 @@ CEF_GLOBAL void CefShutdown() {
DCHECK(base::AtomicRefCountIsZero(&CefDOMDocumentCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefDOMNodeCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefDOMVisitorCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(
&CefDeleteCookiesCallbackCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefDialogHandlerCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefDictionaryValueCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefDisplayHandlerCppToC::DebugObjCt));
@ -243,6 +247,7 @@ CEF_GLOBAL void CefShutdown() {
DCHECK(base::AtomicRefCountIsZero(
&CefSchemeHandlerFactoryCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefSchemeRegistrarCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefSetCookieCallbackCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefStreamReaderCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefStreamWriterCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefStringVisitorCppToC::DebugObjCt));

View File

@ -132,6 +132,13 @@ patches = [
'name': 'base_atomicops_455263',
'path': '../base/allocator/',
},
{
# Fix assertion on Linux when ProxyConfigServiceLinux is deleted on the IO
# thread.
# https://code.google.com/p/chromium/issues/detail?id=462624
'name': 'net_proxy_462624',
'path': '../net/proxy/',
},
{
# Disable scollbar bounce and overlay on OS X.
# http://code.google.com/p/chromiumembedded/issues/detail?id=364

View File

@ -0,0 +1,130 @@
diff --git proxy_config_service_linux.cc proxy_config_service_linux.cc
index e0a9372..be8068d 100644
--- proxy_config_service_linux.cc
+++ proxy_config_service_linux.cc
@@ -202,8 +202,11 @@ const int kDebounceTimeoutMilliseconds = 250;
class SettingGetterImplGConf : public ProxyConfigServiceLinux::SettingGetter {
public:
SettingGetterImplGConf()
- : client_(NULL), system_proxy_id_(0), system_http_proxy_id_(0),
- notify_delegate_(NULL) {
+ : client_(NULL),
+ system_proxy_id_(0),
+ system_http_proxy_id_(0),
+ notify_delegate_(NULL),
+ debounce_timer_(new base::OneShotTimer<SettingGetterImplGConf>()) {
}
~SettingGetterImplGConf() override {
@@ -287,6 +290,7 @@ class SettingGetterImplGConf : public ProxyConfigServiceLinux::SettingGetter {
client_ = NULL;
task_runner_ = NULL;
}
+ debounce_timer_.reset();
}
bool SetUpNotifications(
@@ -475,8 +479,8 @@ class SettingGetterImplGConf : public ProxyConfigServiceLinux::SettingGetter {
void OnChangeNotification() {
// We don't use Reset() because the timer may not yet be running.
// (In that case Stop() is a no-op.)
- debounce_timer_.Stop();
- debounce_timer_.Start(FROM_HERE,
+ debounce_timer_->Stop();
+ debounce_timer_->Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds),
this, &SettingGetterImplGConf::OnDebouncedNotification);
}
@@ -499,7 +503,7 @@ class SettingGetterImplGConf : public ProxyConfigServiceLinux::SettingGetter {
guint system_http_proxy_id_;
ProxyConfigServiceLinux::Delegate* notify_delegate_;
- base::OneShotTimer<SettingGetterImplGConf> debounce_timer_;
+ scoped_ptr<base::OneShotTimer<SettingGetterImplGConf> > debounce_timer_;
// Task runner for the thread that we make gconf calls on. It should
// be the UI thread and all our methods should be called on this
@@ -523,7 +527,8 @@ class SettingGetterImplGSettings
https_client_(NULL),
ftp_client_(NULL),
socks_client_(NULL),
- notify_delegate_(NULL) {
+ notify_delegate_(NULL),
+ debounce_timer_(new base::OneShotTimer<SettingGetterImplGSettings>()) {
}
~SettingGetterImplGSettings() override {
@@ -598,6 +603,7 @@ class SettingGetterImplGSettings
client_ = NULL;
task_runner_ = NULL;
}
+ debounce_timer_.reset();
}
bool SetUpNotifications(
@@ -746,8 +752,8 @@ class SettingGetterImplGSettings
void OnChangeNotification() {
// We don't use Reset() because the timer may not yet be running.
// (In that case Stop() is a no-op.)
- debounce_timer_.Stop();
- debounce_timer_.Start(FROM_HERE,
+ debounce_timer_->Stop();
+ debounce_timer_->Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds),
this, &SettingGetterImplGSettings::OnDebouncedNotification);
}
@@ -768,7 +774,7 @@ class SettingGetterImplGSettings
GSettings* ftp_client_;
GSettings* socks_client_;
ProxyConfigServiceLinux::Delegate* notify_delegate_;
- base::OneShotTimer<SettingGetterImplGSettings> debounce_timer_;
+ scoped_ptr<base::OneShotTimer<SettingGetterImplGSettings> > debounce_timer_;
// Task runner for the thread that we make gsettings calls on. It should
// be the UI thread and all our methods should be called on this
@@ -852,9 +858,14 @@ class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter,
public base::MessagePumpLibevent::Watcher {
public:
explicit SettingGetterImplKDE(base::Environment* env_var_getter)
- : inotify_fd_(-1), notify_delegate_(NULL), indirect_manual_(false),
- auto_no_pac_(false), reversed_bypass_list_(false),
- env_var_getter_(env_var_getter), file_task_runner_(NULL) {
+ : inotify_fd_(-1),
+ notify_delegate_(NULL),
+ debounce_timer_(new base::OneShotTimer<SettingGetterImplKDE>()),
+ indirect_manual_(false),
+ auto_no_pac_(false),
+ reversed_bypass_list_(false),
+ env_var_getter_(env_var_getter),
+ file_task_runner_(NULL) {
// This has to be called on the UI thread (http://crbug.com/69057).
base::ThreadRestrictions::ScopedAllowIO allow_io;
@@ -956,6 +967,7 @@ class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter,
close(inotify_fd_);
inotify_fd_ = -1;
}
+ debounce_timer_.reset();
}
bool SetUpNotifications(
@@ -1305,8 +1317,8 @@ class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter,
if (kioslaverc_touched) {
// We don't use Reset() because the timer may not yet be running.
// (In that case Stop() is a no-op.)
- debounce_timer_.Stop();
- debounce_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(
+ debounce_timer_->Stop();
+ debounce_timer_->Start(FROM_HERE, base::TimeDelta::FromMilliseconds(
kDebounceTimeoutMilliseconds), this,
&SettingGetterImplKDE::OnDebouncedNotification);
}
@@ -1319,7 +1331,7 @@ class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter,
int inotify_fd_;
base::MessagePumpLibevent::FileDescriptorWatcher inotify_watcher_;
ProxyConfigServiceLinux::Delegate* notify_delegate_;
- base::OneShotTimer<SettingGetterImplKDE> debounce_timer_;
+ scoped_ptr<base::OneShotTimer<SettingGetterImplKDE> > debounce_timer_;
base::FilePath kde_config_dir_;
bool indirect_manual_;
bool auto_no_pac_;

View File

@ -16,9 +16,10 @@ void ClientAppBrowser::OnContextInitialized() {
CreateDelegates(delegates_);
// Register cookieable schemes with the global cookie manager.
CefRefPtr<CefCookieManager> manager = CefCookieManager::GetGlobalManager();
CefRefPtr<CefCookieManager> manager =
CefCookieManager::GetGlobalManager(NULL);
DCHECK(manager.get());
manager->SetSupportedSchemes(cookieable_schemes_);
manager->SetSupportedSchemes(cookieable_schemes_, NULL);
print_handler_ = CreatePrintHandler();

View File

@ -29,15 +29,16 @@
#define ID_TESTS_GETTEXT 32701
#define ID_TESTS_OTHER_TESTS 32702
#define ID_TESTS_PLUGIN_INFO 32703
#define ID_TESTS_POPUP 32704
#define ID_TESTS_PRINT 32705
#define ID_TESTS_REQUEST 32706
#define ID_TESTS_TRACING_BEGIN 32707
#define ID_TESTS_TRACING_END 32708
#define ID_TESTS_ZOOM_IN 32709
#define ID_TESTS_ZOOM_OUT 32710
#define ID_TESTS_ZOOM_RESET 32711
#define ID_TESTS_LAST 32711
#define ID_TESTS_WINDOW_NEW 32704
#define ID_TESTS_WINDOW_POPUP 32705
#define ID_TESTS_PRINT 32706
#define ID_TESTS_REQUEST 32707
#define ID_TESTS_TRACING_BEGIN 32708
#define ID_TESTS_TRACING_END 32709
#define ID_TESTS_ZOOM_IN 32710
#define ID_TESTS_ZOOM_OUT 32711
#define ID_TESTS_ZOOM_RESET 32712
#define ID_TESTS_LAST 32712
#define IDC_STATIC -1
#define IDS_BINDING 1000
#define IDS_DIALOGS 1001

View File

@ -579,7 +579,8 @@ GtkWidget* RootWindowGtk::CreateMenuBar() {
GtkWidget* test_menu = CreateMenu(menu_bar, "Tests");
AddMenuEntry(test_menu, "Get Source", ID_TESTS_GETSOURCE);
AddMenuEntry(test_menu, "Get Text", ID_TESTS_GETTEXT);
AddMenuEntry(test_menu, "Popup Window", ID_TESTS_POPUP);
AddMenuEntry(test_menu, "New Window", ID_TESTS_WINDOW_NEW);
AddMenuEntry(test_menu, "Popup Window", ID_TESTS_WINDOW_POPUP);
AddMenuEntry(test_menu, "Request", ID_TESTS_REQUEST);
AddMenuEntry(test_menu, "Plugin Info", ID_TESTS_PLUGIN_INFO);
AddMenuEntry(test_menu, "Zoom In", ID_TESTS_ZOOM_IN);

View File

@ -4,6 +4,8 @@
#include "cefclient/browser/root_window_manager.h"
#include <sstream>
#include "include/base/cef_bind.h"
#include "include/base/cef_logging.h"
#include "include/wrapper/cef_helpers.h"
@ -113,7 +115,20 @@ CefRefPtr<CefRequestContext> RootWindowManager::GetRequestContext(
if (request_context_per_browser_) {
// Create a new request context for each browser.
return CefRequestContext::CreateContext(NULL);
CefRequestContextSettings settings;
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
if (command_line->HasSwitch(switches::kCachePath)) {
// If a global cache path value is specified then give each browser a
// unique cache path.
std::stringstream ss;
ss << command_line->GetSwitchValue(switches::kCachePath).ToString() <<
time(NULL);
CefString(&settings.cache_path) = ss.str();
}
return CefRequestContext::CreateContext(settings, NULL);
}
// All browsers will share the global request context.

View File

@ -18,6 +18,7 @@
#include "cefclient/browser/main_context.h"
#include "cefclient/browser/resource.h"
#include "cefclient/browser/resource_util.h"
#include "cefclient/browser/root_window_manager.h"
#include "cefclient/browser/scheme_test.h"
#include "cefclient/browser/urlrequest_test.h"
#include "cefclient/browser/window_test.h"
@ -112,7 +113,15 @@ void RunRequestTest(CefRefPtr<CefBrowser> browser) {
browser->GetMainFrame()->LoadRequest(request);
}
void RunPopupTest(CefRefPtr<CefBrowser> browser) {
void RunNewWindowTest(CefRefPtr<CefBrowser> browser) {
MainContext::Get()->GetRootWindowManager()->CreateRootWindow(
true, // Show controls.
browser->GetHost()->IsWindowRenderingDisabled(),
CefRect(), // Use default system size.
std::string()); // Use default URL.
}
void RunPopupWindowTest(CefRefPtr<CefBrowser> browser) {
browser->GetMainFrame()->ExecuteJavaScript(
"window.open('http://www.google.com');", "about:blank", 0);
}
@ -288,8 +297,11 @@ void RunTest(CefRefPtr<CefBrowser> browser, int id) {
case ID_TESTS_GETTEXT:
RunGetTextTest(browser);
break;
case ID_TESTS_POPUP:
RunPopupTest(browser);
case ID_TESTS_WINDOW_NEW:
RunNewWindowTest(browser);
break;
case ID_TESTS_WINDOW_POPUP:
RunPopupWindowTest(browser);
break;
case ID_TESTS_REQUEST:
RunRequestTest(browser);

View File

@ -131,7 +131,9 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
base::Bind(&Handler::OnRequestComplete, base::Unretained(this));
// Create and start the new CefURLRequest.
urlrequest_ = CefURLRequest::Create(request, new RequestClient(callback));
urlrequest_ = CefURLRequest::Create(request,
new RequestClient(callback),
NULL);
return true;
}

View File

@ -128,7 +128,8 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
NSMenu *testMenu = [[[NSMenu alloc] initWithTitle:@"Tests"] autorelease];
AddMenuItem(testMenu, @"Get Text", ID_TESTS_GETSOURCE);
AddMenuItem(testMenu, @"Get Source", ID_TESTS_GETTEXT);
AddMenuItem(testMenu, @"Popup Window", ID_TESTS_POPUP);
AddMenuItem(testMenu, @"New Window", ID_TESTS_WINDOW_NEW);
AddMenuItem(testMenu, @"Popup Window", ID_TESTS_WINDOW_POPUP);
AddMenuItem(testMenu, @"Request", ID_TESTS_REQUEST);
AddMenuItem(testMenu, @"Plugin Info", ID_TESTS_PLUGIN_INFO);
AddMenuItem(testMenu, @"Zoom In", ID_TESTS_ZOOM_IN);

View File

@ -73,7 +73,8 @@ BEGIN
BEGIN
MENUITEM "Get Source", ID_TESTS_GETSOURCE
MENUITEM "Get Text", ID_TESTS_GETTEXT
MENUITEM "Popup Window", ID_TESTS_POPUP
MENUITEM "New Window", ID_TESTS_WINDOW_NEW
MENUITEM "Popup Window", ID_TESTS_WINDOW_POPUP
MENUITEM "Request", ID_TESTS_REQUEST
MENUITEM "Plugin Info", ID_TESTS_PLUGIN_INFO
MENUITEM "Zoom In", ID_TESTS_ZOOM_IN

View File

@ -26,23 +26,66 @@ const char* kTestUrl = "http://www.test.com/path/to/cookietest/foo.html";
const char* kTestDomain = "www.test.com";
const char* kTestPath = "/path/to/cookietest";
const int kIgnoreNumDeleted = -2;
typedef std::vector<CefCookie> CookieVector;
void IOT_Set(CefRefPtr<CefCookieManager> manager,
const CefString& url, CookieVector* cookies,
base::WaitableEvent* event) {
CookieVector::const_iterator it = cookies->begin();
for (; it != cookies->end(); ++it)
EXPECT_TRUE(manager->SetCookie(url, *it));
event->Signal();
}
class TestCompletionCallback : public CefCompletionCallback {
public:
explicit TestCompletionCallback(base::WaitableEvent* event)
: event_(event) {}
void IOT_Delete(CefRefPtr<CefCookieManager> manager,
const CefString& url, const CefString& cookie_name,
base::WaitableEvent* event) {
EXPECT_TRUE(manager->DeleteCookies(url, cookie_name));
event->Signal();
}
void OnComplete() override {
event_->Signal();
}
private:
base::WaitableEvent* event_;
IMPLEMENT_REFCOUNTING(TestCompletionCallback);
DISALLOW_COPY_AND_ASSIGN(TestCompletionCallback);
};
class TestSetCookieCallback : public CefSetCookieCallback {
public:
TestSetCookieCallback(bool expected_success,
base::WaitableEvent* event)
: expected_success_(expected_success),
event_(event) {}
void OnComplete(bool success) override {
EXPECT_EQ(expected_success_, success);
event_->Signal();
}
private:
bool expected_success_;
base::WaitableEvent* event_;
IMPLEMENT_REFCOUNTING(TestSetCookieCallback);
DISALLOW_COPY_AND_ASSIGN(TestSetCookieCallback);
};
class TestDeleteCookiesCallback : public CefDeleteCookiesCallback {
public:
TestDeleteCookiesCallback(int expected_num_deleted,
base::WaitableEvent* event)
: expected_num_deleted_(expected_num_deleted),
event_(event) {}
void OnComplete(int num_deleted) override {
if (expected_num_deleted_ != kIgnoreNumDeleted)
EXPECT_EQ(expected_num_deleted_, num_deleted);
event_->Signal();
}
private:
int expected_num_deleted_;
base::WaitableEvent* event_;
IMPLEMENT_REFCOUNTING(TestDeleteCookiesCallback);
DISALLOW_COPY_AND_ASSIGN(TestDeleteCookiesCallback);
};
class TestVisitor : public CefCookieVisitor {
public:
@ -73,18 +116,25 @@ class TestVisitor : public CefCookieVisitor {
// Set the cookies.
void SetCookies(CefRefPtr<CefCookieManager> manager,
const CefString& url, CookieVector& cookies,
const CefString& url, const CookieVector& cookies,
bool expected_success,
base::WaitableEvent& event) {
CefPostTask(TID_IO, base::Bind(IOT_Set, manager, url, &cookies, &event));
event.Wait();
CookieVector::const_iterator it = cookies.begin();
for (; it != cookies.end(); ++it) {
EXPECT_TRUE(manager->SetCookie(
url, *it, new TestSetCookieCallback(expected_success, &event)));
event.Wait();
}
}
// Delete the cookie.
void DeleteCookies(CefRefPtr<CefCookieManager> manager,
const CefString& url, const CefString& cookie_name,
int expected_num_deleted,
base::WaitableEvent& event) {
CefPostTask(TID_IO,
base::Bind(IOT_Delete, manager, url, cookie_name, &event));
EXPECT_TRUE(manager->DeleteCookies(
url, cookie_name,
new TestDeleteCookiesCallback(expected_num_deleted, &event)));
event.Wait();
}
@ -110,7 +160,7 @@ void CreateCookie(CefRefPtr<CefCookieManager> manager,
CookieVector cookies;
cookies.push_back(cookie);
SetCookies(manager, kTestUrl, cookies, event);
SetCookies(manager, kTestUrl, cookies, true, event);
}
// Retrieve the test cookie. If |withDomain| is true check that the cookie
@ -126,7 +176,9 @@ void GetCookie(CefRefPtr<CefCookieManager> manager,
new TestVisitor(&cookies, deleteCookies, &event)));
event.Wait();
EXPECT_EQ((CookieVector::size_type)1, cookies.size());
EXPECT_EQ(1U, cookies.size());
if (cookies.size() != 1U)
return;
const CefCookie& cookie_read = cookies[0];
EXPECT_EQ(CefString(&cookie_read.name), "my_cookie");
@ -185,19 +237,17 @@ void VerifyNoCookies(CefRefPtr<CefCookieManager> manager,
}
event.Wait();
EXPECT_EQ((CookieVector::size_type)0, cookies.size());
EXPECT_EQ(0U, cookies.size());
}
// Delete all system cookies.
void DeleteAllCookies(CefRefPtr<CefCookieManager> manager,
base::WaitableEvent& event) {
CefPostTask(TID_IO,
base::Bind(IOT_Delete, manager, CefString(), CefString(), &event));
event.Wait();
DeleteCookies(manager, CefString(), CefString(), kIgnoreNumDeleted, event);
}
void TestDomainCookie(CefRefPtr<CefCookieManager> manager) {
base::WaitableEvent event(false, false);
void TestDomainCookie(CefRefPtr<CefCookieManager> manager,
base::WaitableEvent& event) {
CefCookie cookie;
// Create a domain cookie.
@ -210,8 +260,8 @@ void TestDomainCookie(CefRefPtr<CefCookieManager> manager) {
VerifyNoCookies(manager, event, true);
}
void TestHostCookie(CefRefPtr<CefCookieManager> manager) {
base::WaitableEvent event(false, false);
void TestHostCookie(CefRefPtr<CefCookieManager> manager,
base::WaitableEvent& event) {
CefCookie cookie;
// Create a host cookie.
@ -224,8 +274,8 @@ void TestHostCookie(CefRefPtr<CefCookieManager> manager) {
VerifyNoCookies(manager, event, true);
}
void TestMultipleCookies(CefRefPtr<CefCookieManager> manager) {
base::WaitableEvent event(false, false);
void TestMultipleCookies(CefRefPtr<CefCookieManager> manager,
base::WaitableEvent& event) {
std::stringstream ss;
int i;
@ -248,7 +298,7 @@ void TestMultipleCookies(CefRefPtr<CefCookieManager> manager) {
}
// Set the cookies.
SetCookies(manager, kTestUrl, cookies, event);
SetCookies(manager, kTestUrl, cookies, true, event);
cookies.clear();
// Get the cookies without deleting them.
@ -271,12 +321,15 @@ void TestMultipleCookies(CefRefPtr<CefCookieManager> manager) {
cookies.clear();
// Delete the 2nd cookie.
DeleteCookies(manager, kTestUrl, CefString("my_cookie1"), event);
DeleteCookies(manager, kTestUrl, CefString("my_cookie1"), -1, event);
// Verify that the cookie has been deleted.
VisitUrlCookies(manager, kTestUrl, false, cookies, false, event);
EXPECT_EQ((CookieVector::size_type)3, cookies.size());
EXPECT_EQ(3U, cookies.size());
if (cookies.size() != 3U)
return;
EXPECT_EQ(CefString(&cookies[0].name), "my_cookie0");
EXPECT_EQ(CefString(&cookies[1].name), "my_cookie2");
EXPECT_EQ(CefString(&cookies[2].name), "my_cookie3");
@ -284,12 +337,12 @@ void TestMultipleCookies(CefRefPtr<CefCookieManager> manager) {
cookies.clear();
// Delete the rest of the cookies.
DeleteCookies(manager, kTestUrl, CefString(), event);
DeleteCookies(manager, kTestUrl, CefString(), 3, event);
// Verify that the cookies have been deleted.
VisitUrlCookies(manager, kTestUrl, false, cookies, false, event);
EXPECT_EQ((CookieVector::size_type)0, cookies.size());
EXPECT_EQ(0U, cookies.size());
// Create the cookies.
for (i = 0; i < kNumCookies; i++) {
@ -313,21 +366,21 @@ void TestMultipleCookies(CefRefPtr<CefCookieManager> manager) {
// Verify that the cookies have been deleted.
VisitUrlCookies(manager, kTestUrl, false, cookies, false, event);
EXPECT_EQ((CookieVector::size_type)0, cookies.size());
EXPECT_EQ(0U, cookies.size());
}
void TestAllCookies(CefRefPtr<CefCookieManager> manager) {
base::WaitableEvent event(false, false);
void TestAllCookies(CefRefPtr<CefCookieManager> manager,
base::WaitableEvent& event) {
CookieVector cookies;
// Delete all system cookies just in case something is left over from a
// different test.
DeleteCookies(manager, CefString(), CefString(), event);
DeleteAllCookies(manager, event);
// Verify that all system cookies have been deleted.
VisitAllCookies(manager, cookies, false, event);
EXPECT_EQ((CookieVector::size_type)0, cookies.size());
EXPECT_EQ(0U, cookies.size());
// Create cookies with 2 separate hosts.
CefCookie cookie1;
@ -336,7 +389,7 @@ void TestAllCookies(CefRefPtr<CefCookieManager> manager) {
CefString(&cookie1.value).FromASCII("My Value 1");
cookies.push_back(cookie1);
SetCookies(manager, kUrl1, cookies, event);
SetCookies(manager, kUrl1, cookies, true, event);
cookies.clear();
CefCookie cookie2;
@ -345,13 +398,16 @@ void TestAllCookies(CefRefPtr<CefCookieManager> manager) {
CefString(&cookie2.value).FromASCII("My Value 2");
cookies.push_back(cookie2);
SetCookies(manager, kUrl2, cookies, event);
SetCookies(manager, kUrl2, cookies, true, event);
cookies.clear();
// Verify that all system cookies can be retrieved.
VisitAllCookies(manager, cookies, false, event);
EXPECT_EQ((CookieVector::size_type)2, cookies.size());
EXPECT_EQ(2U, cookies.size());
if (cookies.size() != 2U)
return;
EXPECT_EQ(CefString(&cookies[0].name), "my_cookie1");
EXPECT_EQ(CefString(&cookies[0].value), "My Value 1");
EXPECT_EQ(CefString(&cookies[0].domain), "www.foo.com");
@ -363,7 +419,10 @@ void TestAllCookies(CefRefPtr<CefCookieManager> manager) {
// Verify that the cookies can be retrieved separately.
VisitUrlCookies(manager, kUrl1, false, cookies, false, event);
EXPECT_EQ((CookieVector::size_type)1, cookies.size());
EXPECT_EQ(1U, cookies.size());
if (cookies.size() != 1U)
return;
EXPECT_EQ(CefString(&cookies[0].name), "my_cookie1");
EXPECT_EQ(CefString(&cookies[0].value), "My Value 1");
EXPECT_EQ(CefString(&cookies[0].domain), "www.foo.com");
@ -371,7 +430,10 @@ void TestAllCookies(CefRefPtr<CefCookieManager> manager) {
VisitUrlCookies(manager, kUrl2, false, cookies, false, event);
EXPECT_EQ((CookieVector::size_type)1, cookies.size());
EXPECT_EQ(1U, cookies.size());
if (cookies.size() != 1U)
return;
EXPECT_EQ(CefString(&cookies[0].name), "my_cookie2");
EXPECT_EQ(CefString(&cookies[0].value), "My Value 2");
EXPECT_EQ(CefString(&cookies[0].domain), "www.bar.com");
@ -385,8 +447,8 @@ void TestAllCookies(CefRefPtr<CefCookieManager> manager) {
}
void TestChangeDirectory(CefRefPtr<CefCookieManager> manager,
base::WaitableEvent& event,
const CefString& original_dir) {
base::WaitableEvent event(false, false);
CefCookie cookie;
base::ScopedTempDir temp_dir;
@ -398,7 +460,7 @@ void TestChangeDirectory(CefRefPtr<CefCookieManager> manager,
DeleteAllCookies(manager, event);
// Set the new temporary directory as the storage location.
EXPECT_TRUE(manager->SetStoragePath(temp_dir.path().value(), false));
EXPECT_TRUE(manager->SetStoragePath(temp_dir.path().value(), false, NULL));
// Wait for the storage location change to complete on the IO thread.
WaitForIOThread();
@ -413,7 +475,7 @@ void TestChangeDirectory(CefRefPtr<CefCookieManager> manager,
GetCookie(manager, cookie, true, event, false);
// Restore the original storage location.
EXPECT_TRUE(manager->SetStoragePath(original_dir, false));
EXPECT_TRUE(manager->SetStoragePath(original_dir, false, NULL));
// Wait for the storage location change to complete on the IO thread.
WaitForIOThread();
@ -422,7 +484,7 @@ void TestChangeDirectory(CefRefPtr<CefCookieManager> manager,
VerifyNoCookies(manager, event, true);
// Set the new temporary directory as the storage location.
EXPECT_TRUE(manager->SetStoragePath(temp_dir.path().value(), false));
EXPECT_TRUE(manager->SetStoragePath(temp_dir.path().value(), false, NULL));
// Wait for the storage location change to complete on the IO thread.
WaitForIOThread();
@ -431,7 +493,7 @@ void TestChangeDirectory(CefRefPtr<CefCookieManager> manager,
GetCookie(manager, cookie, true, event, false);
// Restore the original storage location.
EXPECT_TRUE(manager->SetStoragePath(original_dir, false));
EXPECT_TRUE(manager->SetStoragePath(original_dir, false, NULL));
// Wait for the storage location change to complete on the IO thread.
WaitForIOThread();
@ -441,19 +503,27 @@ void TestChangeDirectory(CefRefPtr<CefCookieManager> manager,
// Test creation of a domain cookie.
TEST(CookieTest, DomainCookieGlobal) {
CefRefPtr<CefCookieManager> manager = CefCookieManager::GetGlobalManager();
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::GetGlobalManager(new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestDomainCookie(manager);
TestDomainCookie(manager, event);
}
// Test creation of a domain cookie.
TEST(CookieTest, DomainCookieInMemory) {
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::CreateManager(CefString(), false);
CefCookieManager::CreateManager(CefString(), false,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestDomainCookie(manager);
TestDomainCookie(manager, event);
}
// Test creation of a domain cookie.
@ -463,28 +533,40 @@ TEST(CookieTest, DomainCookieOnDisk) {
// Create a new temporary directory.
EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::CreateManager(temp_dir.path().value(), false);
CefCookieManager::CreateManager(temp_dir.path().value(), false,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestDomainCookie(manager);
TestDomainCookie(manager, event);
}
// Test creation of a host cookie.
TEST(CookieTest, HostCookieGlobal) {
CefRefPtr<CefCookieManager> manager = CefCookieManager::GetGlobalManager();
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::GetGlobalManager(new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestHostCookie(manager);
TestHostCookie(manager, event);
}
// Test creation of a host cookie.
TEST(CookieTest, HostCookieInMemory) {
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::CreateManager(CefString(), false);
CefCookieManager::CreateManager(CefString(), false,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestHostCookie(manager);
TestHostCookie(manager, event);
}
// Test creation of a host cookie.
@ -494,28 +576,40 @@ TEST(CookieTest, HostCookieOnDisk) {
// Create a new temporary directory.
EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::CreateManager(temp_dir.path().value(), false);
CefCookieManager::CreateManager(temp_dir.path().value(), false,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestHostCookie(manager);
TestHostCookie(manager, event);
}
// Test creation of multiple cookies.
TEST(CookieTest, MultipleCookiesGlobal) {
CefRefPtr<CefCookieManager> manager = CefCookieManager::GetGlobalManager();
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::GetGlobalManager(new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestMultipleCookies(manager);
TestMultipleCookies(manager, event);
}
// Test creation of multiple cookies.
TEST(CookieTest, MultipleCookiesInMemory) {
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::CreateManager(CefString(), false);
CefCookieManager::CreateManager(CefString(), false,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestMultipleCookies(manager);
TestMultipleCookies(manager, event);
}
// Test creation of multiple cookies.
@ -525,26 +619,38 @@ TEST(CookieTest, MultipleCookiesOnDisk) {
// Create a new temporary directory.
EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::CreateManager(temp_dir.path().value(), false);
CefCookieManager::CreateManager(temp_dir.path().value(), false,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestMultipleCookies(manager);
TestMultipleCookies(manager, event);
}
TEST(CookieTest, AllCookiesGlobal) {
CefRefPtr<CefCookieManager> manager = CefCookieManager::GetGlobalManager();
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::GetGlobalManager(new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestAllCookies(manager);
TestAllCookies(manager, event);
}
TEST(CookieTest, AllCookiesInMemory) {
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::CreateManager(CefString(), false);
CefCookieManager::CreateManager(CefString(), false,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestAllCookies(manager);
TestAllCookies(manager, event);
}
TEST(CookieTest, AllCookiesOnDisk) {
@ -553,51 +659,43 @@ TEST(CookieTest, AllCookiesOnDisk) {
// Create a new temporary directory.
EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::CreateManager(temp_dir.path().value(), false);
CefCookieManager::CreateManager(temp_dir.path().value(), false,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestAllCookies(manager);
TestAllCookies(manager, event);
}
TEST(CookieTest, ChangeDirectoryGlobal) {
CefRefPtr<CefCookieManager> manager = CefCookieManager::GetGlobalManager();
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::GetGlobalManager(new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
std::string cache_path;
CefTestSuite::GetCachePath(cache_path);
TestChangeDirectory(manager, cache_path);
TestChangeDirectory(manager, event, cache_path);
}
TEST(CookieTest, ChangeDirectoryCreated) {
base::WaitableEvent event(false, false);
CefRefPtr<CefCookieManager> manager =
CefCookieManager::CreateManager(CefString(), false);
CefCookieManager::CreateManager(CefString(), false,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
TestChangeDirectory(manager, CefString());
TestChangeDirectory(manager, event, CefString());
}
namespace {
class TestCompletionCallback : public CefCompletionCallback {
public:
explicit TestCompletionCallback(base::WaitableEvent* event)
: event_(event) {}
void OnComplete() override {
event_->Signal();
}
private:
base::WaitableEvent* event_;
IMPLEMENT_REFCOUNTING(TestCompletionCallback);
};
} // namespace
TEST(CookieTest, SessionCookieNoPersist) {
base::ScopedTempDir temp_dir;
base::WaitableEvent event(false, false);
@ -607,7 +705,9 @@ TEST(CookieTest, SessionCookieNoPersist) {
EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
CefRefPtr<CefCookieManager> manager =
CefCookieManager::CreateManager(temp_dir.path().value(), false);
CefCookieManager::CreateManager(temp_dir.path().value(), false,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
// Create a session cookie.
@ -619,10 +719,12 @@ TEST(CookieTest, SessionCookieNoPersist) {
// Flush the cookie store to disk.
manager->FlushStore(new TestCompletionCallback(&event));
event.Wait();
// Create a new manager to read the same cookie store.
manager =
CefCookieManager::CreateManager(temp_dir.path().value(), false);
manager = CefCookieManager::CreateManager(temp_dir.path().value(), false,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
// Verify that the cookie doesn't exist.
VerifyNoCookies(manager, event, true);
@ -637,7 +739,9 @@ TEST(CookieTest, SessionCookieWillPersist) {
EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
CefRefPtr<CefCookieManager> manager =
CefCookieManager::CreateManager(temp_dir.path().value(), true);
CefCookieManager::CreateManager(temp_dir.path().value(), true,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
// Create a session cookie.
@ -651,8 +755,10 @@ TEST(CookieTest, SessionCookieWillPersist) {
event.Wait();
// Create a new manager to read the same cookie store.
manager =
CefCookieManager::CreateManager(temp_dir.path().value(), true);
manager = CefCookieManager::CreateManager(temp_dir.path().value(), true,
new TestCompletionCallback(&event));
event.Wait();
EXPECT_TRUE(manager.get());
// Verify that the cookie exists.
GetCookie(manager, cookie, true, event, false);
@ -704,9 +810,9 @@ class CookieTestJSHandler : public TestHandler {
CookieTestJSHandler() {}
void RunTest() override {
// Create =new in-memory managers.
manager1_ = CefCookieManager::CreateManager(CefString(), false);
manager2_ = CefCookieManager::CreateManager(CefString(), false);
// Create new in-memory managers.
manager1_ = CefCookieManager::CreateManager(CefString(), false, NULL);
manager2_ = CefCookieManager::CreateManager(CefString(), false, NULL);
std::string page =
"<html><head>"
@ -727,9 +833,13 @@ class CookieTestJSHandler : public TestHandler {
context_handler_ = new RequestContextHandler(this);
context_handler_->SetURL(kCookieJSUrl1);
// Create the browser
CreateBrowser(kCookieJSUrl1,
CefRequestContext::CreateContext(context_handler_.get()));
// Create the request context that will use an in-memory cache.
CefRequestContextSettings settings;
CefRefPtr<CefRequestContext> request_context =
CefRequestContext::CreateContext(settings, context_handler_.get());
// Create the browser.
CreateBrowser(kCookieJSUrl1, request_context);
// Time out the test after a reasonable period of time.
SetTestTimeout();
@ -773,7 +883,7 @@ class CookieTestJSHandler : public TestHandler {
// Get the cookie.
VisitUrlCookies(manager, url, false, cookies, false, event);
if (cookies.size() == 1 && CefString(&cookies[0].name) == name &&
if (cookies.size() == 1U && CefString(&cookies[0].name) == name &&
CefString(&cookies[0].value) == value) {
callback.yes();
}
@ -968,8 +1078,8 @@ class CookieTestSchemeHandler : public TestHandler {
void RunTest() override {
// Create new in-memory managers.
manager1_ = CefCookieManager::CreateManager(CefString(), false);
manager2_ = CefCookieManager::CreateManager(CefString(), false);
manager1_ = CefCookieManager::CreateManager(CefString(), false, NULL);
manager2_ = CefCookieManager::CreateManager(CefString(), false, NULL);
if (scheme_ != "http") {
std::vector<CefString> schemes;
@ -977,20 +1087,24 @@ class CookieTestSchemeHandler : public TestHandler {
schemes.push_back("https");
schemes.push_back(scheme_);
manager1_->SetSupportedSchemes(schemes);
manager2_->SetSupportedSchemes(schemes);
manager1_->SetSupportedSchemes(schemes, NULL);
manager2_->SetSupportedSchemes(schemes, NULL);
}
// Register the scheme handler.
CefRegisterSchemeHandlerFactory(scheme_, "cookie-tests",
new SchemeHandlerFactory(this));
context_handler_ = new RequestContextHandler(this);
context_handler_->SetURL(url1_);
// Create the browser
CreateBrowser(url1_,
CefRequestContext::CreateContext(context_handler_.get()));
// Create the request context that will use an in-memory cache.
CefRequestContextSettings settings;
CefRefPtr<CefRequestContext> request_context =
CefRequestContext::CreateContext(settings, context_handler_.get());
// Register the scheme handler.
request_context->RegisterSchemeHandlerFactory(scheme_, "cookie-tests",
new SchemeHandlerFactory(this));
// Create the browser.
CreateBrowser(url1_, request_context);
// Time out the test after a reasonable period of time.
SetTestTimeout();
@ -1019,7 +1133,8 @@ class CookieTestSchemeHandler : public TestHandler {
VerifyCookie(manager2_, url, "name2", "value2", got_cookie3_);
// Unregister the scheme handler.
CefRegisterSchemeHandlerFactory(scheme_, "cookie-tests", NULL);
browser->GetHost()->GetRequestContext()->RegisterSchemeHandlerFactory(
scheme_, "cookie-tests", NULL);
DestroyTest();
}
@ -1044,7 +1159,7 @@ class CookieTestSchemeHandler : public TestHandler {
// Get the cookie.
VisitUrlCookies(manager, url, false, cookies, false, event);
if (cookies.size() == 1 && CefString(&cookies[0].name) == name &&
if (cookies.size() == 1U && CefString(&cookies[0].name) == name &&
CefString(&cookies[0].value) == value) {
callback.yes();
}

View File

@ -6,6 +6,7 @@
#include "tests/unittests/chromium_includes.h"
#include "include/base/cef_bind.h"
#include "base/files/scoped_temp_dir.h"
#include "include/cef_request_context.h"
#include "include/cef_request_context_handler.h"
#include "include/wrapper/cef_closure_task.h"
@ -18,15 +19,19 @@ TEST(RequestContextTest, GetGlobalContext) {
EXPECT_TRUE(context1.get());
EXPECT_TRUE(context1->IsGlobal());
EXPECT_TRUE(context1->IsSame(context1));
EXPECT_TRUE(context1->IsSharingWith(context1));
CefRefPtr<CefRequestContext> context2 =
CefRequestContext::GetGlobalContext();
EXPECT_TRUE(context2.get());
EXPECT_TRUE(context2->IsGlobal());
EXPECT_TRUE(context2->IsSame(context2));
EXPECT_TRUE(context2->IsSharingWith(context2));
EXPECT_TRUE(context1->IsSame(context2));
EXPECT_TRUE(context2->IsSame(context1));
EXPECT_TRUE(context1->IsSharingWith(context2));
EXPECT_TRUE(context2->IsSharingWith(context1));
}
TEST(RequestContextTest, CreateContext) {
@ -40,57 +45,193 @@ TEST(RequestContextTest, CreateContext) {
CefRefPtr<CefRequestContextHandler> handler = new Handler();
CefRequestContextSettings settings;
CefRefPtr<CefRequestContext> context1 =
CefRequestContext::CreateContext(handler.get());
CefRequestContext::CreateContext(settings, handler.get());
EXPECT_TRUE(context1.get());
EXPECT_FALSE(context1->IsGlobal());
EXPECT_TRUE(context1->IsSame(context1));
EXPECT_TRUE(context1->IsSharingWith(context1));
EXPECT_EQ(context1->GetHandler().get(), handler.get());
CefRefPtr<CefRequestContext> context2 =
CefRequestContext::CreateContext(handler.get());
CefRequestContext::CreateContext(settings, handler.get());
EXPECT_TRUE(context2.get());
EXPECT_FALSE(context2->IsGlobal());
EXPECT_TRUE(context2->IsSame(context2));
EXPECT_TRUE(context2->IsSharingWith(context2));
EXPECT_EQ(context2->GetHandler().get(), handler.get());
EXPECT_FALSE(context1->IsSame(context2));
EXPECT_FALSE(context1->IsSharingWith(context2));
EXPECT_FALSE(context2->IsSame(context1));
EXPECT_FALSE(context2->IsSharingWith(context1));
CefRefPtr<CefRequestContext> context3 =
CefRequestContext::GetGlobalContext();
EXPECT_TRUE(context3.get());
EXPECT_FALSE(context3->IsSame(context1));
EXPECT_FALSE(context3->IsSharingWith(context1));
EXPECT_FALSE(context3->IsSame(context2));
EXPECT_FALSE(context3->IsSharingWith(context2));
EXPECT_FALSE(context1->IsSame(context3));
EXPECT_FALSE(context1->IsSharingWith(context3));
EXPECT_FALSE(context2->IsSame(context3));
EXPECT_FALSE(context2->IsSharingWith(context3));
}
TEST(RequestContextTest, CreateContextNoHandler) {
CefRequestContextSettings settings;
CefRefPtr<CefRequestContext> context1 =
CefRequestContext::CreateContext(NULL);
CefRequestContext::CreateContext(settings, NULL);
EXPECT_TRUE(context1.get());
EXPECT_FALSE(context1->IsGlobal());
EXPECT_TRUE(context1->IsSame(context1));
EXPECT_TRUE(context1->IsSharingWith(context1));
EXPECT_FALSE(context1->GetHandler().get());
CefRefPtr<CefRequestContext> context2 =
CefRequestContext::CreateContext(NULL);
CefRequestContext::CreateContext(settings, NULL);
EXPECT_TRUE(context2.get());
EXPECT_FALSE(context2->IsGlobal());
EXPECT_TRUE(context2->IsSame(context2));
EXPECT_TRUE(context2->IsSharingWith(context2));
EXPECT_FALSE(context2->GetHandler().get());
EXPECT_FALSE(context1->IsSame(context2));
EXPECT_FALSE(context1->IsSharingWith(context2));
EXPECT_FALSE(context2->IsSame(context1));
EXPECT_FALSE(context2->IsSharingWith(context1));
CefRefPtr<CefRequestContext> context3 =
CefRequestContext::GetGlobalContext();
EXPECT_TRUE(context3.get());
EXPECT_FALSE(context3->IsSame(context1));
EXPECT_FALSE(context3->IsSharingWith(context1));
EXPECT_FALSE(context3->IsSame(context2));
EXPECT_FALSE(context3->IsSharingWith(context2));
EXPECT_FALSE(context1->IsSame(context3));
EXPECT_FALSE(context1->IsSharingWith(context3));
EXPECT_FALSE(context2->IsSame(context3));
EXPECT_FALSE(context2->IsSharingWith(context3));
}
TEST(RequestContextTest, CreateContextSharedGlobal) {
CefRequestContextSettings settings;
CefRefPtr<CefRequestContext> context1 =
CefRequestContext::GetGlobalContext();
EXPECT_TRUE(context1.get());
EXPECT_TRUE(context1->IsGlobal());
EXPECT_TRUE(context1->IsSame(context1));
EXPECT_TRUE(context1->IsSharingWith(context1));
CefRefPtr<CefRequestContext> context2 =
CefRequestContext::CreateContext(context1, NULL);
EXPECT_TRUE(context2.get());
EXPECT_FALSE(context2->IsGlobal());
EXPECT_TRUE(context2->IsSame(context2));
EXPECT_FALSE(context2->IsSame(context1));
EXPECT_FALSE(context1->IsSame(context2));
EXPECT_TRUE(context2->IsSharingWith(context2));
EXPECT_TRUE(context2->IsSharingWith(context1));
EXPECT_TRUE(context1->IsSharingWith(context2));
CefRefPtr<CefRequestContext> context3 =
CefRequestContext::CreateContext(context2, NULL);
EXPECT_TRUE(context3.get());
EXPECT_FALSE(context3->IsGlobal());
EXPECT_TRUE(context3->IsSame(context3));
EXPECT_FALSE(context3->IsSame(context2));
EXPECT_FALSE(context3->IsSame(context1));
EXPECT_FALSE(context1->IsSame(context3));
EXPECT_FALSE(context2->IsSame(context3));
EXPECT_TRUE(context3->IsSharingWith(context3));
EXPECT_TRUE(context3->IsSharingWith(context2));
EXPECT_TRUE(context3->IsSharingWith(context1));
EXPECT_TRUE(context1->IsSharingWith(context3));
EXPECT_TRUE(context2->IsSharingWith(context3));
CefRefPtr<CefRequestContext> context4 =
CefRequestContext::CreateContext(context1, NULL);
EXPECT_TRUE(context4.get());
EXPECT_FALSE(context4->IsGlobal());
EXPECT_TRUE(context4->IsSame(context4));
EXPECT_FALSE(context4->IsSame(context3));
EXPECT_FALSE(context4->IsSame(context2));
EXPECT_FALSE(context4->IsSame(context1));
EXPECT_FALSE(context1->IsSame(context4));
EXPECT_FALSE(context2->IsSame(context4));
EXPECT_FALSE(context3->IsSame(context4));
EXPECT_TRUE(context4->IsSharingWith(context4));
EXPECT_TRUE(context4->IsSharingWith(context3));
EXPECT_TRUE(context4->IsSharingWith(context2));
EXPECT_TRUE(context4->IsSharingWith(context1));
EXPECT_TRUE(context1->IsSharingWith(context4));
EXPECT_TRUE(context2->IsSharingWith(context4));
EXPECT_TRUE(context3->IsSharingWith(context4));
}
TEST(RequestContextTest, CreateContextSharedOnDisk) {
base::ScopedTempDir tempdir;
EXPECT_TRUE(tempdir.CreateUniqueTempDir());
CefRequestContextSettings settings;
CefString(&settings.cache_path) = tempdir.path().value();
CefRefPtr<CefRequestContext> context1 =
CefRequestContext::CreateContext(settings, NULL);
EXPECT_TRUE(context1.get());
EXPECT_FALSE(context1->IsGlobal());
EXPECT_TRUE(context1->IsSame(context1));
EXPECT_TRUE(context1->IsSharingWith(context1));
CefRefPtr<CefRequestContext> context2 =
CefRequestContext::CreateContext(context1, NULL);
EXPECT_TRUE(context2.get());
EXPECT_FALSE(context2->IsGlobal());
EXPECT_TRUE(context2->IsSame(context2));
EXPECT_FALSE(context2->IsSame(context1));
EXPECT_FALSE(context1->IsSame(context2));
EXPECT_TRUE(context2->IsSharingWith(context2));
EXPECT_TRUE(context2->IsSharingWith(context1));
EXPECT_TRUE(context1->IsSharingWith(context2));
CefRefPtr<CefRequestContext> context3 =
CefRequestContext::CreateContext(context2, NULL);
EXPECT_TRUE(context3.get());
EXPECT_FALSE(context3->IsGlobal());
EXPECT_TRUE(context3->IsSame(context3));
EXPECT_FALSE(context3->IsSame(context2));
EXPECT_FALSE(context3->IsSame(context1));
EXPECT_FALSE(context1->IsSame(context3));
EXPECT_FALSE(context2->IsSame(context3));
EXPECT_TRUE(context3->IsSharingWith(context3));
EXPECT_TRUE(context3->IsSharingWith(context2));
EXPECT_TRUE(context3->IsSharingWith(context1));
EXPECT_TRUE(context1->IsSharingWith(context3));
EXPECT_TRUE(context2->IsSharingWith(context3));
CefRefPtr<CefRequestContext> context4 =
CefRequestContext::CreateContext(context1, NULL);
EXPECT_TRUE(context4.get());
EXPECT_FALSE(context4->IsGlobal());
EXPECT_TRUE(context4->IsSame(context4));
EXPECT_FALSE(context4->IsSame(context3));
EXPECT_FALSE(context4->IsSame(context2));
EXPECT_FALSE(context4->IsSame(context1));
EXPECT_FALSE(context1->IsSame(context4));
EXPECT_FALSE(context2->IsSame(context4));
EXPECT_FALSE(context3->IsSame(context4));
EXPECT_TRUE(context4->IsSharingWith(context4));
EXPECT_TRUE(context4->IsSharingWith(context3));
EXPECT_TRUE(context4->IsSharingWith(context2));
EXPECT_TRUE(context4->IsSharingWith(context1));
EXPECT_TRUE(context1->IsSharingWith(context4));
EXPECT_TRUE(context2->IsSharingWith(context4));
EXPECT_TRUE(context3->IsSharingWith(context4));
}
namespace {
@ -128,9 +269,12 @@ class CookieTestHandler : public TestHandler {
"<body>Nav1</body>"
"</html>", "text/html");
CefRequestContextSettings settings;
context_handler_ = new RequestContextHandler(this);
context_ = CefRequestContext::CreateContext(context_handler_.get());
cookie_manager_ = CefCookieManager::CreateManager(CefString(), true);
context_ =
CefRequestContext::CreateContext(settings, context_handler_.get());
cookie_manager_ = CefCookieManager::CreateManager(CefString(), true, NULL);
// Create browser that loads the 1st URL.
CreateBrowser(url_, context_);
@ -142,7 +286,8 @@ class CookieTestHandler : public TestHandler {
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) override {
CefRefPtr<CefRequestContext> context = browser->GetHost()->GetRequestContext();
CefRefPtr<CefRequestContext> context =
browser->GetHost()->GetRequestContext();
EXPECT_TRUE(context.get());
EXPECT_TRUE(context->IsSame(context_));
EXPECT_FALSE(context->IsGlobal());
@ -287,10 +432,13 @@ class PopupTestHandler : public TestHandler {
"<body>Nav1</body>"
"</html>", "text/html");
CefRequestContextSettings settings;
context_handler_ = new RequestContextHandler(this);
context_handler_->SetURL(url_);
context_ = CefRequestContext::CreateContext(context_handler_.get());
cookie_manager_ = CefCookieManager::CreateManager(CefString(), true);
context_ =
CefRequestContext::CreateContext(settings, context_handler_.get());
cookie_manager_ = CefCookieManager::CreateManager(CefString(), true, NULL);
// Create browser that loads the 1st URL.
CreateBrowser(url_, context_);
@ -302,7 +450,8 @@ class PopupTestHandler : public TestHandler {
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) override {
CefRefPtr<CefRequestContext> context = browser->GetHost()->GetRequestContext();
CefRefPtr<CefRequestContext> context =
browser->GetHost()->GetRequestContext();
EXPECT_TRUE(context.get());
EXPECT_TRUE(context->IsSame(context_));
EXPECT_FALSE(context->IsGlobal());

View File

@ -102,7 +102,7 @@ class NetNotifyTestHandler : public TestHandler {
url2_ = base::StringPrintf("%snav2.html?t=%d",
same_origin_ ? kNetNotifyOrigin1 : kNetNotifyOrigin2, test_type_);
cookie_manager_ = CefCookieManager::CreateManager(CefString(), true);
cookie_manager_ = CefCookieManager::CreateManager(CefString(), true, NULL);
AddResource(url1_,
"<html>"
@ -118,9 +118,13 @@ class NetNotifyTestHandler : public TestHandler {
context_handler_ = new RequestContextHandler(this);
context_handler_->SetURL(url1_);
// Create the request context that will use an in-memory cache.
CefRequestContextSettings settings;
CefRefPtr<CefRequestContext> request_context =
CefRequestContext::CreateContext(settings, context_handler_.get());
// Create browser that loads the 1st URL.
CreateBrowser(url1_,
CefRequestContext::CreateContext(context_handler_.get()));
CreateBrowser(url1_, request_context);
}
void RunTest() override {

View File

@ -32,9 +32,11 @@ TestHandler::CompletionState::CompletionState(int total)
void TestHandler::CompletionState::TestComplete() {
if (++count_ == total_) {
// Signal that the test is now complete.
event_.Signal();
count_ = 0;
// Signal that the test is now complete. Do not access any object members
// after this call because |this| might be deleted.
event_.Signal();
}
}

View File

@ -55,6 +55,12 @@ enum RequestTestMode {
REQTEST_HEAD,
};
enum ContextTestMode {
CONTEXT_GLOBAL,
CONTEXT_INMEMORY,
CONTEXT_ONDISK,
};
struct RequestRunSettings {
RequestRunSettings()
: expect_upload_progress(false),
@ -140,9 +146,43 @@ void GetUploadData(CefRefPtr<CefRequest> request,
EXPECT_EQ(size, element->GetBytes(size, const_cast<char*>(data.c_str())));
}
// Set a cookie so that we can test if it's sent with the request.
void SetTestCookie(CefRefPtr<CefRequestContext> request_context,
base::WaitableEvent* event) {
class Callback : public CefSetCookieCallback {
public:
explicit Callback(base::WaitableEvent* event)
: event_(event) {}
void OnComplete(bool success) override {
EXPECT_TRUE(success);
event_->Signal();
}
private:
base::WaitableEvent* event_;
IMPLEMENT_REFCOUNTING(Callback);
};
CefCookie cookie;
CefString(&cookie.name) = kRequestSendCookieName;
CefString(&cookie.value) = "send-cookie-value";
CefString(&cookie.domain) = kRequestHost;
CefString(&cookie.path) = "/";
cookie.has_expires = false;
EXPECT_TRUE(request_context->GetDefaultCookieManager(NULL)->SetCookie(
kRequestOrigin, cookie, new Callback(event)));
// Wait for the Callback.
event->Wait();
}
// Tests if the save cookie has been set. If set, it will be deleted at the same
// time.
void TestSaveCookie(base::WaitableEvent* event, bool* cookie_exists) {
void GetTestCookie(CefRefPtr<CefRequestContext> request_context,
base::WaitableEvent* event,
bool* cookie_exists) {
class Visitor : public CefCookieVisitor {
public:
Visitor(base::WaitableEvent* event, bool* cookie_exists)
@ -172,10 +212,11 @@ void TestSaveCookie(base::WaitableEvent* event, bool* cookie_exists) {
};
CefRefPtr<CefCookieManager> cookie_manager =
CefCookieManager::GetGlobalManager();
EXPECT_TRUE(cookie_manager.get());
cookie_manager->VisitUrlCookies(kRequestOrigin, true,
new Visitor(event, cookie_exists));
request_context->GetDefaultCookieManager(NULL);
cookie_manager->VisitUrlCookies(
kRequestOrigin, true, new Visitor(event, cookie_exists));
// Wait for the Visitor.
event->Wait();
}
@ -431,11 +472,14 @@ class RequestClient : public CefURLRequestClient {
virtual ~Delegate() {}
};
static CefRefPtr<RequestClient> Create(Delegate* delegate,
CefRefPtr<CefRequest> request) {
CefRefPtr<RequestClient> client = new RequestClient(delegate);
CefURLRequest::Create(request, client.get());
return client;
explicit RequestClient(Delegate* delegate)
: delegate_(delegate),
request_complete_ct_(0),
upload_progress_ct_(0),
download_progress_ct_(0),
download_data_ct_(0),
upload_total_(0),
download_total_(0) {
}
void OnRequestComplete(CefRefPtr<CefURLRequest> request) override {
@ -489,16 +533,6 @@ class RequestClient : public CefURLRequestClient {
}
private:
explicit RequestClient(Delegate* delegate)
: delegate_(delegate),
request_complete_ct_(0),
upload_progress_ct_(0),
download_progress_ct_(0),
download_data_ct_(0),
upload_total_(0),
download_total_(0) {
}
Delegate* delegate_;
public:
@ -521,7 +555,7 @@ class RequestClient : public CefURLRequestClient {
// Executes the tests.
class RequestTestRunner {
class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
public:
typedef base::Callback<void(void)> TestCallback;
@ -533,16 +567,15 @@ class RequestTestRunner {
virtual ~Delegate() {}
};
RequestTestRunner(Delegate* delegate, bool is_browser_process)
RequestTestRunner(Delegate* delegate,
bool is_browser_process)
: delegate_(delegate),
is_browser_process_(is_browser_process) {
// Helper macro for registering test callbacks.
#define REGISTER_TEST(test_mode, setup_method, run_method) \
RegisterTest(test_mode, \
base::Bind(&RequestTestRunner::setup_method, \
base::Unretained(this)), \
base::Bind(&RequestTestRunner::run_method, \
base::Unretained(this)));
base::Bind(&RequestTestRunner::setup_method, this), \
base::Bind(&RequestTestRunner::run_method, this));
// Register the test callbacks.
REGISTER_TEST(REQTEST_GET, SetupGetTest, GenericRunTest);
@ -557,6 +590,15 @@ class RequestTestRunner {
REGISTER_TEST(REQTEST_HEAD, SetupHeadTest, GenericRunTest);
}
// Called in the browser process to set the request context that will be used
// when creating the URL request.
void SetRequestContext(CefRefPtr<CefRequestContext> request_context) {
request_context_ = request_context;
}
CefRefPtr<CefRequestContext> GetRequestContext() const {
return request_context_;
}
// Called in both the browser and render process to setup the test.
void SetupTest(RequestTestMode test_mode) {
TestMap::const_iterator it = test_map_.find(test_mode);
@ -701,7 +743,8 @@ class RequestTestRunner {
void GenericRunTest() {
class Test : public RequestClient::Delegate {
public:
Test(RequestTestRunner* runner, const RequestRunSettings& settings)
Test(scoped_refptr<RequestTestRunner> runner,
const RequestRunSettings& settings)
: runner_(runner),
settings_(settings) {
}
@ -765,7 +808,7 @@ class RequestTestRunner {
}
private:
RequestTestRunner* runner_;
scoped_refptr<RequestTestRunner> runner_;
RequestRunSettings settings_;
};
@ -776,7 +819,10 @@ class RequestTestRunner {
request = settings_.request;
EXPECT_TRUE(request.get());
RequestClient::Create(new Test(this, settings_), request);
CefRefPtr<RequestClient> client =
new RequestClient(new Test(this, settings_));
CefURLRequest::Create(request, client.get(), request_context_);
}
// Register a test. Called in the constructor.
@ -791,7 +837,8 @@ class RequestTestRunner {
void DestroyTest() {
if (scheme_factory_.get()) {
// Remove the factory registration.
CefRegisterSchemeHandlerFactory(kRequestScheme, kRequestHost, NULL);
request_context_->RegisterSchemeHandlerFactory(
kRequestScheme, kRequestHost, NULL);
scheme_factory_ = NULL;
}
@ -815,8 +862,8 @@ class RequestTestRunner {
if (!scheme_factory_.get()) {
// Add the factory registration.
scheme_factory_ = new RequestSchemeHandlerFactory();
CefRegisterSchemeHandlerFactory(kRequestScheme, kRequestHost,
scheme_factory_.get());
request_context_->RegisterSchemeHandlerFactory(
kRequestScheme, kRequestHost, scheme_factory_.get());
}
EXPECT_TRUE(settings_.request.get());
@ -832,6 +879,7 @@ class RequestTestRunner {
Delegate* delegate_;
bool is_browser_process_;
CefRefPtr<CefRequestContext> request_context_;
struct TestEntry {
TestCallback setup;
@ -854,7 +902,7 @@ class RequestRendererTest : public ClientAppRenderer::Delegate,
public RequestTestRunner::Delegate {
public:
RequestRendererTest()
: test_runner_(this, false) {
: test_runner_(new RequestTestRunner(this, false)) {
}
bool OnProcessMessageReceived(
@ -871,10 +919,10 @@ class RequestRendererTest : public ClientAppRenderer::Delegate,
// Setup the test. This will create the objects that we test against but
// not register any scheme handlers (because we're in the render process).
test_runner_.SetupTest(test_mode);
test_runner_->SetupTest(test_mode);
// Run the test.
test_runner_.RunTest(test_mode);
test_runner_->RunTest(test_mode);
return true;
}
@ -901,7 +949,7 @@ class RequestRendererTest : public ClientAppRenderer::Delegate,
CefRefPtr<ClientAppRenderer> app_;
CefRefPtr<CefBrowser> browser_;
RequestTestRunner test_runner_;
scoped_refptr<RequestTestRunner> test_runner_;
IMPLEMENT_REFCOUNTING(RequestRendererTest);
};
@ -914,51 +962,97 @@ class RequestTestHandler : public TestHandler,
using TestHandler::DestroyTest;
RequestTestHandler(RequestTestMode test_mode,
ContextTestMode context_mode,
bool test_in_browser,
const char* test_url)
: test_mode_(test_mode),
context_mode_(context_mode),
test_in_browser_(test_in_browser),
test_url_(test_url),
test_runner_(this, true) {
test_runner_(new RequestTestRunner(this, true)) {
}
void RunTest() override {
EXPECT_TRUE(test_url_ != NULL);
AddResource(test_url_, "<html><body>TEST</body></html>", "text/html");
// Get or create the request context.
if (context_mode_ == CONTEXT_GLOBAL) {
CefRefPtr<CefRequestContext> request_context =
CefRequestContext::GetGlobalContext();
EXPECT_TRUE(request_context.get());
test_runner_->SetRequestContext(request_context);
base::WaitableEvent event(false, false);
SetTestCookie(&event);
event.Wait();
// Continue the test now.
RunTestContinue();
} else {
// Don't end the test until the temporary request context has been
// destroyed.
SetSignalCompletionWhenAllBrowsersClose(false);
CefRequestContextSettings settings;
if (context_mode_ == CONTEXT_ONDISK) {
EXPECT_TRUE(context_tmpdir_.CreateUniqueTempDir());
CefString(&settings.cache_path) = context_tmpdir_.path().value();
}
// Create a new temporary request context.
CefRefPtr<CefRequestContext> request_context =
CefRequestContext::CreateContext(settings,
new RequestContextHandler(this));
EXPECT_TRUE(request_context.get());
test_runner_->SetRequestContext(request_context);
// Set the schemes that are allowed to store cookies.
std::vector<CefString> supported_schemes;
supported_schemes.push_back("http");
supported_schemes.push_back("https");
supported_schemes.push_back(kRequestScheme);
// Continue the test once supported schemes has been set.
request_context->GetDefaultCookieManager(NULL)->SetSupportedSchemes(
supported_schemes, new SupportedSchemesCompletionCallback(this));
}
}
void RunTestContinue() {
if (!CefCurrentlyOn(TID_UI)) {
CefPostTask(TID_UI,
base::Bind(&RequestTestHandler::RunTestContinue, this));
return;
}
// Setup the test. This will create the objects that we test against and
// register any scheme handlers.
test_runner_.SetupTest(test_mode_);
test_runner_->SetupTest(test_mode_);
CreateBrowser(test_url_);
base::WaitableEvent event(false, false);
SetTestCookie(test_runner_->GetRequestContext(), &event);
if (test_in_browser_) {
// Run the test now.
test_runner_->RunTest(test_mode_);
} else {
EXPECT_TRUE(test_url_ != NULL);
AddResource(test_url_, "<html><body>TEST</body></html>", "text/html");
// Create a browser to run the test in the renderer process.
CreateBrowser(test_url_, test_runner_->GetRequestContext());
}
// Time out the test after a reasonable period of time.
SetTestTimeout();
}
CefRefPtr<CefProcessMessage> CreateTestMessage() {
CefRefPtr<CefProcessMessage> msg =
CefProcessMessage::Create(kRequestTestMsg);
EXPECT_TRUE(msg->GetArgumentList()->SetInt(0, test_mode_));
return msg;
}
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) override {
EXPECT_FALSE(test_in_browser_);
if (frame->IsMain()) {
if (test_in_browser_) {
// Run the test in the browser process.
test_runner_.RunTest(test_mode_);
} else {
// Send a message to the renderer process to run the test.
EXPECT_TRUE(browser->SendProcessMessage(PID_RENDERER,
CreateTestMessage()));
}
CefRefPtr<CefProcessMessage> test_message =
CefProcessMessage::Create(kRequestTestMsg);
EXPECT_TRUE(test_message->GetArgumentList()->SetInt(0, test_mode_));
// Send a message to the renderer process to run the test.
EXPECT_TRUE(browser->SendProcessMessage(PID_RENDERER, test_message));
}
}
@ -970,6 +1064,7 @@ class RequestTestHandler : public TestHandler,
EXPECT_EQ(PID_RENDERER, source_process);
EXPECT_TRUE(message.get());
EXPECT_TRUE(message->IsReadOnly());
EXPECT_FALSE(test_in_browser_);
got_message_.yes();
@ -977,7 +1072,7 @@ class RequestTestHandler : public TestHandler,
got_success_.yes();
// Test is complete.
DestroyTest(test_runner_.settings_);
DestroyTest(test_runner_->settings_);
return true;
}
@ -986,62 +1081,69 @@ class RequestTestHandler : public TestHandler,
base::WaitableEvent event(false, false);
bool has_save_cookie = false;
TestSaveCookie(&event, &has_save_cookie);
if (settings.expect_save_cookie)
EXPECT_TRUE(has_save_cookie);
else
EXPECT_FALSE(has_save_cookie);
ClearTestCookie(&event);
event.Wait();
GetTestCookie(test_runner_->GetRequestContext(), &event, &has_save_cookie);
EXPECT_EQ(settings.expect_save_cookie, has_save_cookie);
TestHandler::DestroyTest();
// Need to call TestComplete() explicitly if testing in the browser and
// using the global context. Otherwise, TestComplete() will be called when
// the browser is destroyed (for render test + global context) or when the
// temporary context is destroyed.
const bool call_test_complete =
(test_in_browser_ && context_mode_ == CONTEXT_GLOBAL);
// Release our reference to the context. Do not access any object members
// after this call because |this| might be deleted.
test_runner_->SetRequestContext(NULL);
if (call_test_complete)
TestComplete();
}
protected:
// Set a cookie so that we can test if it's sent with the request.
void SetTestCookie(base::WaitableEvent* event) {
if (CefCurrentlyOn(TID_IO)) {
CefRefPtr<CefCookieManager> cookie_manager =
CefCookieManager::GetGlobalManager();
EXPECT_TRUE(cookie_manager.get());
CefCookie cookie;
CefString(&cookie.name) = kRequestSendCookieName;
CefString(&cookie.value) = "send-cookie-value";
CefString(&cookie.domain) = kRequestHost;
CefString(&cookie.path) = "/";
cookie.has_expires = false;
EXPECT_TRUE(cookie_manager->SetCookie(kRequestOrigin, cookie));
event->Signal();
} else {
// Execute on the IO thread.
CefPostTask(TID_IO,
base::Bind(&RequestTestHandler::SetTestCookie, this, event));
private:
// Used with temporary request contexts to signal test completion once the
// temporary context has been destroyed.
class RequestContextHandler : public CefRequestContextHandler {
public:
explicit RequestContextHandler(CefRefPtr<RequestTestHandler> test_handler)
: test_handler_(test_handler) {
}
}
// Remove the cookie that we set above.
void ClearTestCookie(base::WaitableEvent* event) {
if (CefCurrentlyOn(TID_IO)) {
CefRefPtr<CefCookieManager> cookie_manager =
CefCookieManager::GetGlobalManager();
EXPECT_TRUE(cookie_manager.get());
EXPECT_TRUE(cookie_manager->DeleteCookies(kRequestOrigin,
kRequestSendCookieName));
event->Signal();
} else {
// Execute on the IO thread.
CefPostTask(TID_IO,
base::Bind(&RequestTestHandler::ClearTestCookie, this, event));
~RequestContextHandler() override {
test_handler_->TestComplete();
}
}
private:
CefRefPtr<RequestTestHandler> test_handler_;
IMPLEMENT_REFCOUNTING(RequestContextHandler);
};
// Continue the rest once supported schemes have been set.
class SupportedSchemesCompletionCallback : public CefCompletionCallback {
public:
explicit SupportedSchemesCompletionCallback(
CefRefPtr<RequestTestHandler> test_handler)
: test_handler_(test_handler) {
}
void OnComplete() override {
test_handler_->RunTestContinue();
}
private:
CefRefPtr<RequestTestHandler> test_handler_;
IMPLEMENT_REFCOUNTING(SupportedSchemesCompletionCallback);
};
RequestTestMode test_mode_;
ContextTestMode context_mode_;
bool test_in_browser_;
const char* test_url_;
RequestTestRunner test_runner_;
scoped_refptr<RequestTestRunner> test_runner_;
base::ScopedTempDir context_tmpdir_;
public:
// Only used when the test runs in the render process.
@ -1069,10 +1171,11 @@ void RegisterURLRequestCustomSchemes(
// Helpers for defining URLRequest tests.
#define REQ_TEST_EX(name, test_mode, test_in_browser, test_url) \
#define REQ_TEST_EX(name, test_mode, context_mode, test_in_browser, test_url) \
TEST(URLRequestTest, name) { \
CefRefPtr<RequestTestHandler> handler = \
new RequestTestHandler(test_mode, test_in_browser, test_url); \
new RequestTestHandler(test_mode, context_mode, test_in_browser, \
test_url); \
handler->ExecuteTest(); \
if (!test_in_browser) { \
EXPECT_TRUE(handler->got_message_); \
@ -1081,28 +1184,38 @@ void RegisterURLRequestCustomSchemes(
ReleaseAndWaitForDestructor(handler); \
}
#define REQ_TEST(name, test_mode, test_in_browser) \
REQ_TEST_EX(name, test_mode, test_in_browser, kRequestTestUrl)
#define REQ_TEST(name, test_mode, context_mode, test_in_browser) \
REQ_TEST_EX(name, test_mode, context_mode, test_in_browser, kRequestTestUrl)
// Define the tests.
REQ_TEST(BrowserGET, REQTEST_GET, true);
REQ_TEST(BrowserGETNoData, REQTEST_GET_NODATA, true);
REQ_TEST(BrowserGETAllowCookies, REQTEST_GET_ALLOWCOOKIES, true);
REQ_TEST(BrowserGETRedirect, REQTEST_GET_REDIRECT, true);
REQ_TEST(BrowserPOST, REQTEST_POST, true);
REQ_TEST(BrowserPOSTFile, REQTEST_POST_FILE, true);
REQ_TEST(BrowserPOSTWithProgress, REQTEST_POST_WITHPROGRESS, true);
REQ_TEST(BrowserHEAD, REQTEST_HEAD, true);
REQ_TEST(RendererGET, REQTEST_GET, false);
REQ_TEST(RendererGETNoData, REQTEST_GET_NODATA, false);
REQ_TEST(RendererGETAllowCookies, REQTEST_GET_ALLOWCOOKIES, false);
REQ_TEST(RendererGETRedirect, REQTEST_GET_REDIRECT, false);
REQ_TEST(RendererPOST, REQTEST_POST, false);
REQ_TEST(RendererPOSTWithProgress, REQTEST_POST_WITHPROGRESS, false);
REQ_TEST(RendererHEAD, REQTEST_HEAD, false);
#define REQ_TEST_SET(suffix, context_mode) \
REQ_TEST(BrowserGET##suffix, REQTEST_GET, context_mode, true); \
REQ_TEST(BrowserGETNoData##suffix, REQTEST_GET_NODATA, context_mode, true); \
REQ_TEST(BrowserGETAllowCookies##suffix, \
REQTEST_GET_ALLOWCOOKIES, context_mode, true); \
REQ_TEST(BrowserGETRedirect##suffix, \
REQTEST_GET_REDIRECT, context_mode, true); \
REQ_TEST(BrowserPOST##suffix, REQTEST_POST, context_mode, true); \
REQ_TEST(BrowserPOSTFile##suffix, REQTEST_POST_FILE, context_mode, true); \
REQ_TEST(BrowserPOSTWithProgress##suffix, \
REQTEST_POST_WITHPROGRESS, context_mode, true); \
REQ_TEST(BrowserHEAD##suffix, REQTEST_HEAD, context_mode, true); \
REQ_TEST(RendererGET##suffix, REQTEST_GET, context_mode, false); \
REQ_TEST(RendererGETNoData##suffix, \
REQTEST_GET_NODATA, context_mode, false); \
REQ_TEST(RendererGETAllowCookies##suffix, \
REQTEST_GET_ALLOWCOOKIES, context_mode, false); \
REQ_TEST(RendererGETRedirect##suffix, \
REQTEST_GET_REDIRECT, context_mode, false); \
REQ_TEST(RendererPOST##suffix, REQTEST_POST, context_mode, false); \
REQ_TEST(RendererPOSTWithProgress##suffix, \
REQTEST_POST_WITHPROGRESS, context_mode, false); \
REQ_TEST(RendererHEAD##suffix, REQTEST_HEAD, context_mode, false)
REQ_TEST_SET(ContextGlobal, CONTEXT_GLOBAL);
REQ_TEST_SET(ContextInMemory, CONTEXT_INMEMORY);
REQ_TEST_SET(ContextOnDisk, CONTEXT_ONDISK);
namespace {
@ -1163,7 +1276,7 @@ class InvalidURLTestClient : public CefURLRequestClient {
request->SetMethod("GET");
request->SetURL("foo://invalidurl");
CefURLRequest::Create(request, this);
CefURLRequest::Create(request, this, NULL);
}
void CompleteOnUIThread() {