diff --git a/cef.gyp b/cef.gyp index bd74c17d2..e5a57fec7 100644 --- a/cef.gyp +++ b/cef.gyp @@ -187,6 +187,7 @@ 'libcef_dll_wrapper', ], 'sources': [ + 'tests/unittests/cookie_unittest.cc', 'tests/unittests/dom_unittest.cc', 'tests/unittests/request_unittest.cc', 'tests/unittests/run_all_unittests.cc', @@ -308,6 +309,7 @@ 'include/cef_string_types.h', 'include/cef_string_wrappers.h', 'include/cef_types.h', + 'include/cef_types_wrappers.h', 'libcef_dll/cef_logging.h', 'libcef_dll/cpptoc/browser_cpptoc.cc', 'libcef_dll/cpptoc/browser_cpptoc.h', @@ -342,6 +344,8 @@ 'libcef_dll/cpptoc/xml_reader_cpptoc.h', 'libcef_dll/cpptoc/zip_reader_cpptoc.cc', 'libcef_dll/cpptoc/zip_reader_cpptoc.h', + 'libcef_dll/ctocpp/cookie_visitor_ctocpp.cc', + 'libcef_dll/ctocpp/cookie_visitor_ctocpp.h', 'libcef_dll/ctocpp/ctocpp.h', 'libcef_dll/ctocpp/domevent_listener_ctocpp.cc', 'libcef_dll/ctocpp/domevent_listener_ctocpp.h', @@ -415,6 +419,8 @@ 'sources': [ 'include/cef_wrapper.h', 'libcef_dll/cef_logging.h', + 'libcef_dll/cpptoc/cookie_visitor_cpptoc.cc', + 'libcef_dll/cpptoc/cookie_visitor_cpptoc.h', 'libcef_dll/cpptoc/cpptoc.h', 'libcef_dll/cpptoc/domevent_listener_cpptoc.cc', 'libcef_dll/cpptoc/domevent_listener_cpptoc.h', @@ -540,6 +546,7 @@ 'include/cef_string_types.h', 'include/cef_string_wrappers.h', 'include/cef_types.h', + 'include/cef_types_wrappers.h', 'libcef/browser_appcache_system.cc', 'libcef/browser_appcache_system.h', 'libcef/browser_database_system.cc', diff --git a/include/cef.h b/include/cef.h index bcc8ac4c8..34786351f 100644 --- a/include/cef.h +++ b/include/cef.h @@ -42,10 +42,10 @@ #include #include #include "cef_ptr.h" -#include "cef_types.h" +#include "cef_types_wrappers.h" class CefBrowser; -class CefBrowserSettings; +class CefCookieVisitor; class CefDOMDocument; class CefDOMEvent; class CefDOMEventListener; @@ -54,18 +54,15 @@ class CefDOMVisitor; class CefDownloadHandler; class CefFrame; class CefHandler; -class CefPopupFeatures; class CefPostData; class CefPostDataElement; class CefRequest; class CefResponse; class CefSchemeHandler; class CefSchemeHandlerFactory; -class CefSettings; class CefStreamReader; class CefStreamWriter; class CefTask; -class CefURLParts; class CefV8Context; class CefV8Handler; class CefV8Value; @@ -236,6 +233,39 @@ bool CefParseURL(const CefString& url, bool CefCreateURL(const CefURLParts& parts, CefString& url); +// Visit all cookies. The returned cookies are ordered by longest path, then by +// earliest creation date. Returns false if cookies cannot be accessed. +/*--cef()--*/ +bool CefVisitAllCookies(CefRefPtr visitor); + +// 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. +/*--cef()--*/ +bool CefVisitUrlCookies(const CefString& url, bool includeHttpOnly, + CefRefPtr visitor); + +// 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. +/*--cef()--*/ +bool CefSetCookie(const CefString& url, const CefCookie& cookie); + +// Delete all cookies that match the specified parameters. If both |url| and +// |cookie_name| are specified all host and domain cookies matching both values +// 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. +/*--cef()--*/ +bool CefDeleteCookies(const CefString& url, const CefString& cookie_name); + + // Interface defining the the reference count implementation methods. All // framework classes must implement the CefBase class. class CefBase @@ -347,49 +377,6 @@ protected: }; -// Class representing a rectangle. -class CefRect : public cef_rect_t -{ -public: - CefRect() - { - x = y = width = height = 0; - } - CefRect(int x, int y, int width, int height) - { - set(x, y, width, height); - } - - CefRect(const cef_rect_t& r) - { - set(r.x, r.y, r.width, r.height); - } - CefRect& operator=(const cef_rect_t& r) - { - x = r.x; - y = r.y; - width = r.width; - height = r.height; - return *this; - } - - bool isEmpty() const { return width <= 0 || height <= 0; } - void set(int x, int y, int width, int height) - { - this->x = x, this->y = y, this->width = width, this->height = height; - } -}; - -inline bool operator==(const CefRect& a, const CefRect& b) -{ - return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height; -} - -inline bool operator!=(const CefRect& a, const CefRect& b) -{ - return !(a == b); -} - // Implement this interface for task execution. The methods of this class may // be called on any thread. /*--cef(source=client)--*/ @@ -402,6 +389,23 @@ public: }; +// Interface to implement for visiting cookie values. The methods of this class +// will always be called on the IO thread. +/*--cef(source=client)--*/ +class CefCookieVisitor : public CefBase +{ +public: + // Method that will be called once for each cookie. |count| is the 0-based + // index for the current cookie. |total| is the total number of cookies. + // Set |deleteCookie| to true to delete the cookie currently being visited. + // Return false to stop visiting cookies. This method may never be called if + // no cookies are found. + /*--cef()--*/ + virtual bool Visit(const CefCookie& cookie, int count, int total, + bool& deleteCookie) =0; +}; + + // Class used to represent a browser window. The methods of this class may be // called on any thread unless otherwise indicated in the comments. /*--cef(source=library)--*/ @@ -829,7 +833,7 @@ public: /*--cef()--*/ virtual RetVal HandleProtocolExecution(CefRefPtr browser, const CefString& url, - bool* allow_os_execution) =0; + bool& allow_os_execution) =0; // Called on the UI thread when a server indicates via the // 'Content-Disposition' header that a response represents a file to download. @@ -2232,386 +2236,4 @@ public: virtual void HandleEvent(CefRefPtr event) =0; }; - -// Class representing popup window features. -class CefPopupFeatures : public cef_popup_features_t -{ -public: - CefPopupFeatures() - { - Init(); - } - virtual ~CefPopupFeatures() - { - Reset(); - } - - CefPopupFeatures(const CefPopupFeatures& r) - { - Init(); - *this = r; - } - CefPopupFeatures(const cef_popup_features_t& r) - { - Init(); - *this = r; - } - - void Reset() - { - if(additionalFeatures) - cef_string_list_free(additionalFeatures); - } - - void Attach(const cef_popup_features_t& r) - { - Reset(); - *static_cast(this) = r; - } - - void Detach() - { - Init(); - } - - CefPopupFeatures& operator=(const CefPopupFeatures& r) - { - return operator=(static_cast(r)); - } - - CefPopupFeatures& operator=(const cef_popup_features_t& r) - { - if(additionalFeatures) - cef_string_list_free(additionalFeatures); - additionalFeatures = r.additionalFeatures ? - cef_string_list_copy(r.additionalFeatures) : NULL; - - x = r.x; - xSet = r.xSet; - y = r.y; - ySet = r.ySet; - width = r.width; - widthSet = r.widthSet; - height = r.height; - heightSet = r.heightSet; - menuBarVisible = r.menuBarVisible; - statusBarVisible = r.statusBarVisible; - toolBarVisible = r.toolBarVisible; - locationBarVisible = r.locationBarVisible; - scrollbarsVisible = r.scrollbarsVisible; - resizable = r.resizable; - fullscreen = r.fullscreen; - dialog = r.dialog; - return *this; - } - -protected: - void Init() - { - x = 0; - xSet = false; - y = 0; - ySet = false; - width = 0; - widthSet = false; - height = 0; - heightSet = false; - - menuBarVisible = true; - statusBarVisible = true; - toolBarVisible = true; - locationBarVisible = true; - scrollbarsVisible = true; - resizable = true; - - fullscreen = false; - dialog = false; - additionalFeatures = NULL; - } -}; - - -// Class representing initialization settings. -class CefSettings : public cef_settings_t -{ -public: - CefSettings() - { - Init(); - } - virtual ~CefSettings() - { - Reset(); - } - - CefSettings(const CefSettings& r) - { - Init(); - *this = r; - } - CefSettings(const cef_settings_t& r) - { - Init(); - *this = r; - } - - void Reset() - { - cef_string_clear(&cache_path); - cef_string_clear(&user_agent); - cef_string_clear(&product_version); - cef_string_clear(&locale); - if(extra_plugin_paths) - cef_string_list_free(extra_plugin_paths); - cef_string_clear(&log_file); - Init(); - } - - void Attach(const cef_settings_t& r) - { - Reset(); - *static_cast(this) = r; - } - - void Detach() - { - Init(); - } - - CefSettings& operator=(const CefSettings& r) - { - return operator=(static_cast(r)); - } - - CefSettings& operator=(const cef_settings_t& r) - { - multi_threaded_message_loop = r.multi_threaded_message_loop; - - cef_string_copy(r.cache_path.str, r.cache_path.length, &cache_path); - cef_string_copy(r.user_agent.str, r.user_agent.length, &user_agent); - cef_string_copy(r.product_version.str, r.product_version.length, - &product_version); - cef_string_copy(r.locale.str, r.locale.length, &locale); - - if(extra_plugin_paths) - cef_string_list_free(extra_plugin_paths); - extra_plugin_paths = r.extra_plugin_paths ? - cef_string_list_copy(r.extra_plugin_paths) : NULL; - - cef_string_copy(r.log_file.str, r.log_file.length, &log_file); - log_severity = r.log_severity; - - return *this; - } - -protected: - void Init() - { - memset(static_cast(this), 0, sizeof(cef_settings_t)); - size = sizeof(cef_settings_t); - } -}; - - -// Class representing browser initialization settings. -class CefBrowserSettings : public cef_browser_settings_t -{ -public: - CefBrowserSettings() - { - Init(); - } - virtual ~CefBrowserSettings() - { - Reset(); - } - - CefBrowserSettings(const CefBrowserSettings& r) - { - Init(); - *this = r; - } - CefBrowserSettings(const cef_browser_settings_t& r) - { - Init(); - *this = r; - } - - void Reset() - { - cef_string_clear(&standard_font_family); - cef_string_clear(&fixed_font_family); - cef_string_clear(&serif_font_family); - cef_string_clear(&sans_serif_font_family); - cef_string_clear(&cursive_font_family); - cef_string_clear(&fantasy_font_family); - cef_string_clear(&default_encoding); - cef_string_clear(&user_style_sheet_location); - Init(); - } - - void Attach(const cef_browser_settings_t& r) - { - Reset(); - *static_cast(this) = r; - } - - void Detach() - { - Init(); - } - - CefBrowserSettings& operator=(const CefBrowserSettings& r) - { - return operator=(static_cast(r)); - } - - CefBrowserSettings& operator=(const cef_browser_settings_t& r) - { - drag_drop_disabled = r.drag_drop_disabled; - - cef_string_copy(r.standard_font_family.str, r.standard_font_family.length, - &standard_font_family); - cef_string_copy(r.fixed_font_family.str, r.fixed_font_family.length, - &fixed_font_family); - cef_string_copy(r.serif_font_family.str, r.serif_font_family.length, - &serif_font_family); - cef_string_copy(r.sans_serif_font_family.str, - r.sans_serif_font_family.length, &sans_serif_font_family); - cef_string_copy(r.cursive_font_family.str, r.cursive_font_family.length, - &cursive_font_family); - cef_string_copy(r.fantasy_font_family.str, r.fantasy_font_family.length, - &fantasy_font_family); - - default_font_size = r.default_font_size; - default_fixed_font_size = r.default_fixed_font_size; - minimum_font_size = r.minimum_font_size; - minimum_logical_font_size = r.minimum_logical_font_size; - remote_fonts_disabled = r.remote_fonts_disabled; - - cef_string_copy(r.default_encoding.str, r.default_encoding.length, - &default_encoding); - - encoding_detector_enabled = r.encoding_detector_enabled; - javascript_disabled = r.javascript_disabled; - javascript_open_windows_disallowed = r.javascript_open_windows_disallowed; - javascript_close_windows_disallowed = r.javascript_close_windows_disallowed; - javascript_access_clipboard_disallowed = - r.javascript_access_clipboard_disallowed; - dom_paste_disabled = r.dom_paste_disabled; - caret_browsing_enabled = r.caret_browsing_enabled; - java_disabled = r.java_disabled; - plugins_disabled = r.plugins_disabled; - universal_access_from_file_urls_allowed = - r.universal_access_from_file_urls_allowed; - file_access_from_file_urls_allowed = r.file_access_from_file_urls_allowed; - web_security_disabled = r.web_security_disabled; - xss_auditor_enabled = r.xss_auditor_enabled; - image_load_disabled = r.image_load_disabled; - shrink_standalone_images_to_fit = r.shrink_standalone_images_to_fit; - site_specific_quirks_disabled = r.site_specific_quirks_disabled; - text_area_resize_disabled = r.text_area_resize_disabled; - page_cache_disabled = r.page_cache_disabled; - tab_to_links_disabled = r.tab_to_links_disabled; - hyperlink_auditing_disabled = r.hyperlink_auditing_disabled; - user_style_sheet_enabled = r.user_style_sheet_enabled; - - cef_string_copy(r.user_style_sheet_location.str, - r.user_style_sheet_location.length, &user_style_sheet_location); - - author_and_user_styles_disabled = r.author_and_user_styles_disabled; - local_storage_disabled = r.local_storage_disabled; - databases_disabled = r.databases_disabled; - application_cache_disabled = r.application_cache_disabled; - webgl_disabled = r.webgl_disabled; - accelerated_compositing_disabled = r.accelerated_compositing_disabled; - accelerated_layers_disabled = r.accelerated_layers_disabled; - accelerated_2d_canvas_disabled = r.accelerated_2d_canvas_disabled; - developer_tools_disabled = r.developer_tools_disabled; - - return *this; - } - -protected: - void Init() - { - memset(static_cast(this), 0, - sizeof(cef_browser_settings_t)); - size = sizeof(cef_browser_settings_t); - } -}; - -// Class used to represent a URL's component parts. -class CefURLParts : public cef_urlparts_t -{ -public: - CefURLParts() - { - Init(); - } - virtual ~CefURLParts() - { - Reset(); - } - - CefURLParts(const CefURLParts& r) - { - Init(); - *this = r; - } - CefURLParts(const cef_urlparts_t& r) - { - Init(); - *this = r; - } - - void Reset() - { - cef_string_clear(&spec); - cef_string_clear(&scheme); - cef_string_clear(&username); - cef_string_clear(&password); - cef_string_clear(&host); - cef_string_clear(&port); - cef_string_clear(&path); - cef_string_clear(&query); - Init(); - } - - void Attach(const cef_urlparts_t& r) - { - Reset(); - *static_cast(this) = r; - } - - void Detach() - { - Init(); - } - - CefURLParts& operator=(const CefURLParts& r) - { - return operator=(static_cast(r)); - } - - CefURLParts& operator=(const cef_urlparts_t& r) - { - cef_string_copy(r.spec.str, r.spec.length, &spec); - cef_string_copy(r.scheme.str, r.scheme.length, &scheme); - cef_string_copy(r.username.str, r.username.length, &username); - cef_string_copy(r.password.str, r.password.length, &password); - cef_string_copy(r.host.str, r.host.length, &host); - cef_string_copy(r.port.str, r.port.length, &port); - cef_string_copy(r.path.str, r.path.length, &path); - cef_string_copy(r.query.str, r.query.length, &query); - return *this; - } - -protected: - void Init() - { - memset(static_cast(this), 0, sizeof(cef_urlparts_t)); - } -}; - #endif // _CEF_H diff --git a/include/cef_capi.h b/include/cef_capi.h index 72e2217a2..ae13c2099 100644 --- a/include/cef_capi.h +++ b/include/cef_capi.h @@ -197,6 +197,36 @@ CEF_EXPORT int cef_parse_url(const cef_string_t* url, CEF_EXPORT int cef_create_url(const struct _cef_urlparts_t* parts, cef_string_t* url); +// Visit all cookies. The returned cookies are ordered by longest path, then by +// earliest creation date. Returns false (0) if cookies cannot be accessed. +CEF_EXPORT int cef_visit_all_cookies(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. +CEF_EXPORT int cef_visit_url_cookies(const cef_string_t* url, + int includeHttpOnly, struct _cef_cookie_visitor_t* visitor); + +// 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. +CEF_EXPORT int cef_set_cookie(const cef_string_t* url, + const struct _cef_cookie_t* cookie); + +// Delete all cookies that match the specified parameters. If both |url| and +// |cookie_name| are specified all host and domain cookies matching both values +// 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. +CEF_EXPORT int cef_delete_cookies(const cef_string_t* url, + const cef_string_t* cookie_name); + typedef struct _cef_base_t { // Size of the data structure. @@ -235,6 +265,25 @@ typedef struct _cef_task_t } cef_task_t; +// Structure to implement for visiting cookie values. The functions of this +// structure will always be called on the IO thread. +typedef struct _cef_cookie_visitor_t +{ + // Base structure. + cef_base_t base; + + // Method that will be called once for each cookie. |count| is the 0-based + // index for the current cookie. |total| is the total number of cookies. Set + // |deleteCookie| to true (1) to delete the cookie currently being visited. + // Return false (0) to stop visiting cookies. This function may never be + // called if no cookies are found. + int (CEF_CALLBACK *visit)(struct _cef_cookie_visitor_t* self, + const struct _cef_cookie_t* cookie, int count, int total, + int* deleteCookie); + +} cef_cookie_visitor_t; + + // Structure used to represent a browser window. The functions of this structure // may be called on any thread unless otherwise indicated in the comments. typedef struct _cef_browser_t diff --git a/include/cef_linux.h b/include/cef_linux.h index bf55927fc..a8aea79f9 100644 --- a/include/cef_linux.h +++ b/include/cef_linux.h @@ -34,6 +34,7 @@ #if defined(__linux__) #include #include "cef_types_linux.h" +#include "cef_types_wrappers.h" // Atomic increment and decrement. inline long CefAtomicIncrement(long volatile *pDest) @@ -77,108 +78,49 @@ public: #define CefWindowHandle cef_window_handle_t #define CefCursorHandle cef_cursor_handle_t +struct CefWindowInfoTraits { + typedef cef_window_info_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, bool copy) + { + target->m_Widget = src->m_Widget; + target->m_ParentWidget = src->m_ParentWidget; + } +}; + // Class representing window information. -class CefWindowInfo : public cef_window_info_t +class CefWindowInfo : public CefStructBase { public: - CefWindowInfo() - { - Init(); - } - virtual ~CefWindowInfo() - { - Reset(); - } - - CefWindowInfo(const CefWindowInfo& r) - { - Init(); - *this = r; - } - CefWindowInfo(const cef_window_info_t& r) - { - Init(); - *this = r; - } - - void Reset() - { - Init(); - } - - void Attach(const cef_window_info_t& r) - { - Reset(); - *static_cast(this) = r; - } - - void Detach() - { - Init(); - } + typedef CefStructBase parent; + CefWindowInfo() : parent() {} + CefWindowInfo(const cef_window_info_t& r) : parent(r) {} + CefWindowInfo(const CefWindowInfo& r) : parent(r) {} + void SetAsChild(CefWindowHandle ParentWidget) { m_ParentWidget = ParentWidget; } +}; - CefWindowInfo& operator=(const CefWindowInfo& r) - { - return operator=(static_cast(r)); - } - CefWindowInfo& operator=(const cef_window_info_t& r) - { - m_Widget = r.m_Widget; - m_ParentWidget = r.m_ParentWidget; - return *this; - } +struct CefPrintInfoTraits { + typedef cef_print_info_t struct_type; -protected: - void Init() + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, bool copy) { - memset(static_cast(this), 0, sizeof(cef_window_info_t)); + target->m_Scale = src->m_Scale; } }; // Class representing print context information. -class CefPrintInfo : public cef_print_info_t -{ -public: - CefPrintInfo() - { - Init(); - } - virtual ~CefPrintInfo() - { - } - - CefPrintInfo(const CefPrintInfo& r) - { - Init(); - *this = r; - } - CefPrintInfo(const cef_print_info_t& r) - { - Init(); - *this = r; - } - - CefPrintInfo& operator=(const CefPrintInfo& r) - { - return operator=(static_cast(r)); - } - CefPrintInfo& operator=(const cef_print_info_t& r) - { - m_Scale = r.m_Scale; - return *this; - } - -protected: - void Init() - { - m_Scale = 0; - } -}; +typedef CefStructBase CefPrintInfo; #endif // defined(__linux__) diff --git a/include/cef_mac.h b/include/cef_mac.h index f42275f92..b3393738e 100644 --- a/include/cef_mac.h +++ b/include/cef_mac.h @@ -34,6 +34,7 @@ #if defined(__APPLE__) #include #include "cef_types_mac.h" +#include "cef_types_wrappers.h" // Atomic increment and decrement. inline long CefAtomicIncrement(long volatile *pDest) @@ -77,47 +78,40 @@ public: pthread_mutexattr_t attr_; }; +struct CefWindowInfoTraits { + typedef cef_window_info_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) + { + cef_string_clear(&s->m_windowName); + } + + static inline void set(const struct_type* src, struct_type* target, bool copy) + { + target->m_View = src->m_View; + target->m_ParentView = src->m_ParentView; + cef_string_set(src->m_windowName.str, src->m_windowName.length, + &target->m_windowName, copy); + target->m_x = src->m_x; + target->m_y = src->m_y; + target->m_nWidth = src->m_nWidth; + target->m_nHeight = src->m_nHeight; + target->m_bHidden = src->m_bHidden; + } +}; + // Class representing window information. -class CefWindowInfo : public cef_window_info_t +class CefWindowInfo : public CefStructBase { public: - CefWindowInfo() - { - Init(); - } - virtual ~CefWindowInfo() - { - Reset(); - } - - CefWindowInfo(const CefWindowInfo& r) - { - Init(); - *this = r; - } - CefWindowInfo(const cef_window_info_t& r) - { - Init(); - *this = r; - } - - void Reset() - { - cef_string_clear(&m_windowName); - Init(); - } - - void Attach(const cef_window_info_t& r) - { - Reset(); - *static_cast(this) = r; - } - - void Detach() - { - Init(); - } + typedef CefStructBase parent; + CefWindowInfo() : parent() {} + CefWindowInfo(const cef_window_info_t& r) : parent(r) {} + CefWindowInfo(const CefWindowInfo& r) : parent(r) {} + void SetAsChild(CefWindowHandle ParentView, int x, int y, int width, int height) { @@ -128,70 +122,22 @@ public: m_nHeight = height; m_bHidden = false; } +}; - CefWindowInfo& operator=(const CefWindowInfo& r) - { - return operator=(static_cast(r)); - } - CefWindowInfo& operator=(const cef_window_info_t& r) - { - m_View = r.m_View; - m_ParentView = r.m_ParentView; - cef_string_copy(r.m_windowName.str, r.m_windowName.length, &m_windowName); - m_x = r.m_x; - m_y = r.m_y; - m_nWidth = r.m_nWidth; - m_nHeight = r.m_nHeight; - m_bHidden = r.m_bHidden; - return *this; - } +struct CefPrintInfoTraits { + typedef cef_print_info_t struct_type; -protected: - void Init() + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, bool copy) { - memset(static_cast(this), 0, sizeof(cef_window_info_t)); + target->m_Scale = src->m_Scale; } }; // Class representing print context information. -class CefPrintInfo : public cef_print_info_t -{ -public: - CefPrintInfo() - { - Init(); - } - virtual ~CefPrintInfo() - { - } - - CefPrintInfo(const CefPrintInfo& r) - { - Init(); - *this = r; - } - CefPrintInfo(const cef_print_info_t& r) - { - Init(); - *this = r; - } - - CefPrintInfo& operator=(const CefPrintInfo& r) - { - return operator=(static_cast(r)); - } - CefPrintInfo& operator=(const cef_print_info_t& r) - { - m_Scale = r.m_Scale; - return *this; - } - -protected: - void Init() - { - m_Scale = 0; - } -}; +typedef CefStructBase CefPrintInfo; #endif // defined(__APPLE__) diff --git a/include/cef_types.h b/include/cef_types.h index 97c9a670b..22fe4f58f 100644 --- a/include/cef_types.h +++ b/include/cef_types.h @@ -269,6 +269,57 @@ typedef struct _cef_urlparts_t cef_string_t query; } cef_urlparts_t; +// Time information. Values should always be in UTC. +typedef struct _cef_time_t +{ + int year; // Four digit year "2007" + int month; // 1-based month (values 1 = January, etc.) + int day_of_week; // 0-based day of week (0 = Sunday, etc.) + int day_of_month; // 1-based day of month (1-31) + int hour; // Hour within the current day (0-23) + int minute; // Minute within the current hour (0-59) + int second; // Second within the current minute (0-59 plus leap + // seconds which may take it up to 60). + int millisecond; // Milliseconds within the current second (0-999) +} cef_time_t; + +// Cookie information. +typedef struct _cef_cookie_t +{ + // The cookie name. + cef_string_t name; + + // The cookie value. + cef_string_t value; + + // If |domain| is empty a host cookie will be created instead of a domain + // cookie. Domain cookies are stored with a leading "." and are visible to + // sub-domains whereas host cookies are not. + cef_string_t domain; + + // If |path| is non-empty only URLs at or below the path will get the cookie + // value. + cef_string_t path; + + // If |secure| is true the cookie will only be sent for HTTPS requests. + bool secure; + + // If |httponly| is true the cookie will only be sent for HTTP requests. + bool httponly; + + // The cookie creation date. This is automatically populated by the system on + // cookie creation. + cef_time_t creation; + + // The cookie last access date. This is automatically populated by the system + // on access. + cef_time_t last_access; + + // The cookie expiration date is only valid if |has_expires| is true. + bool has_expires; + cef_time_t expires; +} cef_cookie_t; + // Mouse button types. enum cef_mouse_button_type_t { diff --git a/include/cef_types_wrappers.h b/include/cef_types_wrappers.h new file mode 100644 index 000000000..b25da46f5 --- /dev/null +++ b/include/cef_types_wrappers.h @@ -0,0 +1,442 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef _CEF_TYPES_WRAPPERS_H +#define _CEF_TYPES_WRAPPERS_H + +#include "cef_types.h" + +// Template class that provides common functionality for CEF structure wrapping. +template +class CefStructBase : public traits::struct_type { +public: + typedef typename traits::struct_type struct_type; + + CefStructBase() : attached_to_(NULL) + { + Init(); + } + virtual ~CefStructBase() + { + // Only clear this object's data if it isn't currently attached to a + // structure. + if (!attached_to_) + Clear(this); + } + + CefStructBase(const CefStructBase& r) + { + Init(); + *this = r; + } + CefStructBase(const struct_type& r) + { + Init(); + *this = r; + } + + // Clear this object's values. + void Reset() + { + Clear(this); + Init(); + } + + // Attach to the source structure's existing values. DetachTo() can be called + // to insert the values back into the existing structure. + void AttachTo(struct_type& source) + { + // Only clear this object's data if it isn't currently attached to a + // structure. + if (!attached_to_) + Clear(this); + + // This object is now attached to the new structure. + attached_to_ = &source; + + // Transfer ownership of the values from the source structure. + memcpy(static_cast(this), &source, sizeof(struct_type)); + } + + // Relinquish ownership of values to the target structure. + void DetachTo(struct_type& target) + { + if (attached_to_ != &target) { + // Clear the target structure's values only if we are not currently + // attached to that structure. + Clear(&target); + } + + // Transfer ownership of the values to the target structure. + memcpy(&target, static_cast(this), sizeof(struct_type)); + + // Remove the references from this object. + Init(); + } + + // Set this object's values. If |copy| is true the source structure's values + // will be copied instead of referenced. + void Set(const struct_type& source, bool copy) + { + traits::set(&source, this, copy); + } + + CefStructBase& operator=(const CefStructBase& s) + { + return operator=(static_cast(s)); + } + + CefStructBase& operator=(const struct_type& s) + { + Set(s, true); + return *this; + } + +protected: + void Init() + { + memset(static_cast(this), 0, sizeof(struct_type)); + attached_to_ = NULL; + traits::init(this); + } + + static void Clear(struct_type* s) { traits::clear(s); } + + struct_type* attached_to_; +}; + + +struct CefRectTraits { + typedef cef_rect_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, bool copy) + { + target->x = src->x; + target->y = src->y; + target->width = src->width; + target->height = src->height; + } +}; + +// Class representing a rectangle. +class CefRect : public CefStructBase +{ +public: + typedef CefStructBase parent; + + CefRect() : parent() {} + CefRect(const cef_rect_t& r) : parent(r) {} + CefRect(const CefRect& r) : parent(r) {} + CefRect(int x, int y, int width, int height) : parent() + { + Set(x, y, width, height); + } + + bool IsEmpty() const { return width <= 0 || height <= 0; } + void Set(int x, int y, int width, int height) + { + this->x = x, this->y = y, this->width = width, this->height = height; + } +}; + +inline bool operator==(const CefRect& a, const CefRect& b) +{ + return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height; +} + +inline bool operator!=(const CefRect& a, const CefRect& b) +{ + return !(a == b); +} + + +struct CefPopupFeaturesTraits { + typedef cef_popup_features_t struct_type; + + static inline void init(struct_type* s) + { + s->menuBarVisible = true; + s->statusBarVisible = true; + s->toolBarVisible = true; + s->locationBarVisible = true; + s->scrollbarsVisible = true; + s->resizable = true; + } + + static inline void clear(struct_type* s) + { + if(s->additionalFeatures) + cef_string_list_free(s->additionalFeatures); + } + + static inline void set(const struct_type* src, struct_type* target, bool copy) + { + if(target->additionalFeatures) + cef_string_list_free(target->additionalFeatures); + target->additionalFeatures = src->additionalFeatures ? + cef_string_list_copy(src->additionalFeatures) : NULL; + + target->x = src->x; + target->xSet = src->xSet; + target->y = src->y; + target->ySet = src->ySet; + target->width = src->width; + target->widthSet = src->widthSet; + target->height = src->height; + target->heightSet = src->heightSet; + target->menuBarVisible = src->menuBarVisible; + target->statusBarVisible = src->statusBarVisible; + target->toolBarVisible = src->toolBarVisible; + target->locationBarVisible = src->locationBarVisible; + target->scrollbarsVisible = src->scrollbarsVisible; + target->resizable = src->resizable; + target->fullscreen = src->fullscreen; + target->dialog = src->dialog; + } +}; + +// Class representing popup window features. +typedef CefStructBase CefPopupFeatures; + + +struct CefSettingsTraits { + typedef cef_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->user_agent); + cef_string_clear(&s->product_version); + cef_string_clear(&s->locale); + if(s->extra_plugin_paths) + cef_string_list_free(s->extra_plugin_paths); + cef_string_clear(&s->log_file); + } + + static inline void set(const struct_type* src, struct_type* target, bool copy) + { + target->multi_threaded_message_loop = src->multi_threaded_message_loop; + + cef_string_set(src->cache_path.str, src->cache_path.length, + &target->cache_path, copy); + cef_string_set(src->user_agent.str, src->user_agent.length, + &target->user_agent, copy); + cef_string_set(src->product_version.str, src->product_version.length, + &target->product_version, copy); + cef_string_set(src->locale.str, src->locale.length, &target->locale, copy); + + if(target->extra_plugin_paths) + cef_string_list_free(target->extra_plugin_paths); + target->extra_plugin_paths = src->extra_plugin_paths ? + cef_string_list_copy(src->extra_plugin_paths) : NULL; + + cef_string_set(src->log_file.str, src->log_file.length, &target->log_file, + copy); + target->log_severity = src->log_severity; + } +}; + +// Class representing initialization settings. +typedef CefStructBase CefSettings; + + +struct CefBrowserSettingsTraits { + typedef cef_browser_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->standard_font_family); + cef_string_clear(&s->fixed_font_family); + cef_string_clear(&s->serif_font_family); + cef_string_clear(&s->sans_serif_font_family); + cef_string_clear(&s->cursive_font_family); + cef_string_clear(&s->fantasy_font_family); + cef_string_clear(&s->default_encoding); + cef_string_clear(&s->user_style_sheet_location); + } + + static inline void set(const struct_type* src, struct_type* target, bool copy) + { + target->drag_drop_disabled = src->drag_drop_disabled; + + cef_string_set(src->standard_font_family.str, + src->standard_font_family.length, &target->standard_font_family, copy); + cef_string_set(src->fixed_font_family.str, src->fixed_font_family.length, + &target->fixed_font_family, copy); + cef_string_set(src->serif_font_family.str, src->serif_font_family.length, + &target->serif_font_family, copy); + cef_string_set(src->sans_serif_font_family.str, + src->sans_serif_font_family.length, &target->sans_serif_font_family, + copy); + cef_string_set(src->cursive_font_family.str, + src->cursive_font_family.length, &target->cursive_font_family, copy); + cef_string_set(src->fantasy_font_family.str, + src->fantasy_font_family.length, &target->fantasy_font_family, copy); + + target->default_font_size = src->default_font_size; + target->default_fixed_font_size = src->default_fixed_font_size; + target->minimum_font_size = src->minimum_font_size; + target->minimum_logical_font_size = src->minimum_logical_font_size; + target->remote_fonts_disabled = src->remote_fonts_disabled; + + cef_string_set(src->default_encoding.str, src->default_encoding.length, + &target->default_encoding, copy); + + target->encoding_detector_enabled = src->encoding_detector_enabled; + target->javascript_disabled = src->javascript_disabled; + target->javascript_open_windows_disallowed = + src->javascript_open_windows_disallowed; + target->javascript_close_windows_disallowed = + src->javascript_close_windows_disallowed; + target->javascript_access_clipboard_disallowed = + src->javascript_access_clipboard_disallowed; + target->dom_paste_disabled = src->dom_paste_disabled; + target->caret_browsing_enabled = src->caret_browsing_enabled; + target->java_disabled = src->java_disabled; + target->plugins_disabled = src->plugins_disabled; + target->universal_access_from_file_urls_allowed = + src->universal_access_from_file_urls_allowed; + target->file_access_from_file_urls_allowed = + src->file_access_from_file_urls_allowed; + target->web_security_disabled = src->web_security_disabled; + target->xss_auditor_enabled = src->xss_auditor_enabled; + target->image_load_disabled = src->image_load_disabled; + target->shrink_standalone_images_to_fit = + src->shrink_standalone_images_to_fit; + target->site_specific_quirks_disabled = src->site_specific_quirks_disabled; + target->text_area_resize_disabled = src->text_area_resize_disabled; + target->page_cache_disabled = src->page_cache_disabled; + target->tab_to_links_disabled = src->tab_to_links_disabled; + target->hyperlink_auditing_disabled = src->hyperlink_auditing_disabled; + target->user_style_sheet_enabled = src->user_style_sheet_enabled; + + cef_string_set(src->user_style_sheet_location.str, + src->user_style_sheet_location.length, + &target->user_style_sheet_location, copy); + + target->author_and_user_styles_disabled = + src->author_and_user_styles_disabled; + target->local_storage_disabled = src->local_storage_disabled; + target->databases_disabled = src->databases_disabled; + target->application_cache_disabled = src->application_cache_disabled; + target->webgl_disabled = src->webgl_disabled; + target->accelerated_compositing_disabled = + src->accelerated_compositing_disabled; + target->accelerated_layers_disabled = src->accelerated_layers_disabled; + target->accelerated_2d_canvas_disabled = + src->accelerated_2d_canvas_disabled; + target->developer_tools_disabled = src->developer_tools_disabled; + } +}; + +// Class representing browser initialization settings. +typedef CefStructBase CefBrowserSettings; + + +struct CefURLPartsTraits { + typedef cef_urlparts_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) + { + cef_string_clear(&s->spec); + cef_string_clear(&s->scheme); + cef_string_clear(&s->username); + cef_string_clear(&s->password); + cef_string_clear(&s->host); + cef_string_clear(&s->port); + cef_string_clear(&s->path); + cef_string_clear(&s->query); + } + + static inline void set(const struct_type* src, struct_type* target, bool copy) + { + cef_string_set(src->spec.str, src->spec.length, &target->spec, copy); + cef_string_set(src->scheme.str, src->scheme.length, &target->scheme, copy); + cef_string_set(src->username.str, src->username.length, &target->username, + copy); + cef_string_set(src->password.str, src->password.length, &target->password, + copy); + cef_string_set(src->host.str, src->host.length, &target->host, copy); + cef_string_set(src->port.str, src->port.length, &target->port, copy); + cef_string_set(src->path.str, src->path.length, &target->path, copy); + cef_string_set(src->query.str, src->query.length, &target->query, copy); + } +}; + +// Class representing a URL's component parts. +typedef CefStructBase CefURLParts; + + +struct CefCookieTraits { + typedef cef_cookie_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) + { + cef_string_clear(&s->name); + cef_string_clear(&s->value); + cef_string_clear(&s->domain); + cef_string_clear(&s->path); + } + + static inline void set(const struct_type* src, struct_type* target, bool copy) + { + cef_string_set(src->name.str, src->name.length, &target->name, copy); + cef_string_set(src->value.str, src->value.length, &target->value, copy); + cef_string_set(src->domain.str, src->domain.length, &target->domain, copy); + cef_string_set(src->path.str, src->path.length, &target->path, copy); + target->secure = src->secure; + target->httponly = src->httponly; + target->creation = src->creation; + target->last_access = src->last_access; + target->has_expires = src->has_expires; + target->expires = src->expires; + } +}; + +// Class representing a cookie. +typedef CefStructBase CefCookie; + +#endif // _CEF_TYPES_WRAPPERS_H diff --git a/include/cef_win.h b/include/cef_win.h index af479e989..66e8a2349 100644 --- a/include/cef_win.h +++ b/include/cef_win.h @@ -34,6 +34,7 @@ #ifdef _WIN32 #include #include "cef_types_win.h" +#include "cef_types_wrappers.h" // Atomic increment and decrement. #define CefAtomicIncrement(p) InterlockedIncrement(p) @@ -68,67 +69,44 @@ public: #define CefWindowHandle cef_window_handle_t #define CefCursorHandle cef_cursor_handle_t + +struct CefWindowInfoTraits { + typedef cef_window_info_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) + { + cef_string_clear(&s->m_windowName); + } + + static inline void set(const struct_type* src, struct_type* target, bool copy) + { + target->m_dwExStyle = src->m_dwExStyle; + cef_string_set(src->m_windowName.str, src->m_windowName.length, + &target->m_windowName, copy); + target->m_dwStyle = src->m_dwStyle; + target->m_x = src->m_x; + target->m_y = src->m_y; + target->m_nWidth = src->m_nWidth; + target->m_nHeight = src->m_nHeight; + target->m_hWndParent = src->m_hWndParent; + target->m_hMenu = src->m_hMenu; + target->m_bWindowRenderingDisabled = src->m_bWindowRenderingDisabled; + target->m_hWnd = src->m_hWnd; + } +}; + // Class representing window information. -class CefWindowInfo : public cef_window_info_t +class CefWindowInfo : public CefStructBase { public: - CefWindowInfo() - { - Init(); - } - virtual ~CefWindowInfo() - { - Reset(); - } - - CefWindowInfo(const CefWindowInfo& r) - { - Init(); - *this = r; - } - CefWindowInfo(const cef_window_info_t& r) - { - Init(); - *this = r; - } - - void Reset() - { - cef_string_clear(&m_windowName); - Init(); - } - - void Attach(const cef_window_info_t& r) - { - Reset(); - *static_cast(this) = r; - } - - void Detach() - { - Init(); - } - - CefWindowInfo& operator=(const CefWindowInfo& r) - { - return operator=(static_cast(r)); - } - CefWindowInfo& operator=(const cef_window_info_t& r) - { - m_dwExStyle = r.m_dwExStyle; - cef_string_copy(r.m_windowName.str, r.m_windowName.length, &m_windowName); - m_dwStyle = r.m_dwStyle; - m_x = r.m_x; - m_y = r.m_y; - m_nWidth = r.m_nWidth; - m_nHeight = r.m_nHeight; - m_hWndParent = r.m_hWndParent; - m_hMenu = r.m_hMenu; - m_bWindowRenderingDisabled = r.m_bWindowRenderingDisabled; - m_hWnd = r.m_hWnd; - return *this; - } + typedef CefStructBase parent; + CefWindowInfo() : parent() {} + CefWindowInfo(const cef_window_info_t& r) : parent(r) {} + CefWindowInfo(const CefWindowInfo& r) : parent(r) {} + void SetAsChild(HWND hWndParent, RECT windowRect) { m_dwStyle = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP | @@ -158,59 +136,25 @@ public: m_bWindowRenderingDisabled = TRUE; m_hWndParent = hWndParent; } +}; -protected: - void Init() + +struct CefPrintInfoTraits { + typedef cef_print_info_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, bool copy) { - memset(static_cast(this), 0, sizeof(cef_window_info_t)); + target->m_hDC = src->m_hDC; + target->m_Rect = src->m_Rect; + target->m_Scale = src->m_Scale; } }; // Class representing print context information. -class CefPrintInfo : public cef_print_info_t -{ -public: - CefPrintInfo() - { - Init(); - } - virtual ~CefPrintInfo() - { - } - - CefPrintInfo(const CefPrintInfo& r) - { - Init(); - *this = r; - } - CefPrintInfo(const cef_print_info_t& r) - { - Init(); - *this = r; - } - - void Init() - { - m_hDC = NULL; - m_Rect.left = m_Rect.right = m_Rect.top = m_Rect.bottom = 0; - m_Scale = 0; - } - - CefPrintInfo& operator=(const CefPrintInfo& r) - { - return operator=(static_cast(r)); - } - CefPrintInfo& operator=(const cef_print_info_t& r) - { - m_hDC = r.m_hDC; - m_Rect.left = r.m_Rect.left; - m_Rect.right = r.m_Rect.right; - m_Rect.top = r.m_Rect.top; - m_Rect.bottom = r.m_Rect.bottom; - m_Scale = r.m_Scale; - return *this; - } -}; +typedef CefStructBase CefPrintInfo; #endif // _WIN32 diff --git a/libcef/browser_resource_loader_bridge.cc b/libcef/browser_resource_loader_bridge.cc index c3862ed26..35f9bdd77 100644 --- a/libcef/browser_resource_loader_bridge.cc +++ b/libcef/browser_resource_loader_bridge.cc @@ -383,9 +383,9 @@ class RequestProxy : public net::URLRequest::Delegate, !net::URLRequest::IsHandledProtocol(params->url.scheme())) { bool allow_os_execution = false; CefHandler::RetVal rv = handler->HandleProtocolExecution(browser_, - params->url.spec(), &allow_os_execution); - if(rv == RV_CONTINUE && allow_os_execution && - ExternalProtocolHandler::HandleExternalProtocol(params->url)) { + params->url.spec(), allow_os_execution); + if (rv == RV_CONTINUE && allow_os_execution && + ExternalProtocolHandler::HandleExternalProtocol(params->url)) { handled = true; } else if(rv == RV_HANDLED) { handled = true; @@ -885,7 +885,10 @@ class CookieSetter : public base::RefCountedThreadSafe { public: void Set(const GURL& url, const std::string& cookie) { REQUIRE_IOT(); - _Context->request_context()->cookie_store()->SetCookie(url, cookie); + net::CookieStore* cookie_store = + _Context->request_context()->cookie_store(); + if (cookie_store) + cookie_store->SetCookie(url, cookie); } private: @@ -900,7 +903,10 @@ class CookieGetter : public base::RefCountedThreadSafe { } void Get(const GURL& url) { - result_ = _Context->request_context()->cookie_store()->GetCookies(url); + net::CookieStore* cookie_store = + _Context->request_context()->cookie_store(); + if (cookie_store) + result_ = cookie_store->GetCookies(url); event_.Signal(); } @@ -959,10 +965,9 @@ bool FindProxyForUrl(const GURL& url, std::string* proxy_list) { // static void BrowserResourceLoaderBridge::SetCookie(const GURL& url, - const GURL& first_party_for_cookies, - const std::string& cookie) { + const GURL& first_party_for_cookies, + const std::string& cookie) { // Proxy to IO thread to synchronize w/ network loading. - scoped_refptr cookie_setter = new CookieSetter(); CefThread::PostTask(CefThread::IO, FROM_HERE, NewRunnableMethod( cookie_setter.get(), &CookieSetter::Set, url, cookie)); @@ -971,19 +976,18 @@ void BrowserResourceLoaderBridge::SetCookie(const GURL& url, // static std::string BrowserResourceLoaderBridge::GetCookies( const GURL& url, const GURL& first_party_for_cookies) { - // Proxy to IO thread to synchronize w/ network loading - - scoped_refptr getter = new CookieGetter(); - + // Proxy to IO thread to synchronize w/ network loading. + scoped_refptr cookie_getter = new CookieGetter(); CefThread::PostTask(CefThread::IO, FROM_HERE, NewRunnableMethod( - getter.get(), &CookieGetter::Get, url)); + cookie_getter.get(), &CookieGetter::Get, url)); - return getter->GetResult(); + // Blocks until the result is available. + return cookie_getter->GetResult(); } // static void BrowserResourceLoaderBridge::SetAcceptAllCookies(bool accept_all_cookies) { - // Proxy to IO thread to synchronize w/ network loading + // Proxy to IO thread to synchronize w/ network loading. CefThread::PostTask(CefThread::IO, FROM_HERE, NewRunnableMethod( _Context->request_context().get(), &BrowserRequestContext::SetAcceptAllCookies, accept_all_cookies)); diff --git a/libcef/browser_settings.h b/libcef/browser_settings.h index fce1304e3..47001e1a8 100644 --- a/libcef/browser_settings.h +++ b/libcef/browser_settings.h @@ -5,7 +5,7 @@ #ifndef _CEF_BROWSER_SETTINGS_H #define _CEF_BROWSER_SETTINGS_H -class CefBrowserSettings; +#include "include/cef_types_wrappers.h" struct WebPreferences; void BrowserToWebSettings(const CefBrowserSettings& cef, WebPreferences& web); diff --git a/libcef/cef_context.cc b/libcef/cef_context.cc index 2c378605b..87dfd209b 100644 --- a/libcef/cef_context.cc +++ b/libcef/cef_context.cc @@ -13,6 +13,8 @@ #if defined(OS_MACOSX) || defined(OS_WIN) #include "base/nss_util.h" #endif +#include "base/stringprintf.h" +#include "net/base/cookie_monster.h" #include "webkit/plugins/npapi/plugin_list.h" // Both the CefContext constuctor and the CefContext::RemoveBrowser method need @@ -22,6 +24,138 @@ const int kNextBrowserIdReset = 1; // Global CefContext pointer CefRefPtr _Context; +namespace { + +void UIT_RegisterPlugin(CefPluginInfo* plugin_info) +{ + REQUIRE_UIT(); + + webkit::npapi::WebPluginInfo info; + + FilePath filename = FilePath(CefString(&plugin_info->unique_name)); + std::string name = CefString(&plugin_info->display_name); + std::string description = CefString(&plugin_info->description); + std::string mime_type = CefString(&plugin_info->mime_type); + + webkit::npapi::PluginEntryPoints entry_points; +#if !defined(OS_POSIX) || defined(OS_MACOSX) + entry_points.np_getentrypoints = plugin_info->np_getentrypoints; +#endif + entry_points.np_initialize = plugin_info->np_initialize; + entry_points.np_shutdown = plugin_info->np_shutdown; + + webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(filename, + name, description, mime_type, entry_points); + + delete plugin_info; +} + +int GetThreadId(CefThreadId threadId) +{ + switch(threadId) { + case TID_UI: return CefThread::UI; + case TID_IO: return CefThread::IO; + case TID_FILE: return CefThread::FILE; + }; + NOTREACHED(); + return -1; +} + +void SetCefTime(cef_time_t& cef_time, const base::Time& base_time) +{ + base::Time::Exploded exploded; + base_time.UTCExplode(&exploded); + cef_time.year = exploded.year; + cef_time.month = exploded.month; + cef_time.day_of_week = exploded.day_of_week; + cef_time.day_of_month = exploded.day_of_month; + cef_time.hour = exploded.hour; + cef_time.minute = exploded.minute; + cef_time.second = exploded.second; + cef_time.millisecond = exploded.millisecond; +} + +void SetBaseTime(base::Time& base_time, const cef_time_t& cef_time) +{ + base::Time::Exploded exploded; + exploded.year = cef_time.year; + exploded.month = cef_time.month; + exploded.day_of_week = cef_time.day_of_week; + exploded.day_of_month = cef_time.day_of_month; + exploded.hour = cef_time.hour; + exploded.minute = cef_time.minute; + exploded.second = cef_time.second; + exploded.millisecond = cef_time.millisecond; + base_time = base::Time::FromUTCExploded(exploded); +} + +void IOT_VisitCookies(net::CookieMonster* cookie_monster, + const net::CookieList& list, + CefRefPtr visitor) +{ + int total = list.size(), count = 0; + + net::CookieList::const_iterator it = list.begin(); + for (; it != list.end(); ++it, ++count) { + CefCookie cookie; + const net::CookieMonster::CanonicalCookie& cc = *(it); + + CefString(&cookie.name).FromString(cc.Name()); + CefString(&cookie.value).FromString(cc.Value()); + CefString(&cookie.domain).FromString(cc.Domain()); + CefString(&cookie.path).FromString(cc.Path()); + cookie.secure = cc.IsSecure(); + cookie.httponly = cc.IsHttpOnly(); + SetCefTime(cookie.creation, cc.CreationDate()); + SetCefTime(cookie.last_access, cc.LastAccessDate()); + cookie.has_expires = cc.DoesExpire(); + if (cookie.has_expires) + SetCefTime(cookie.expires, cc.ExpiryDate()); + + bool deleteCookie = false; + bool keepLooping = visitor->Visit(cookie, count, total, deleteCookie); + if (deleteCookie) + cookie_monster->DeleteCanonicalCookie(cc); + if (!keepLooping) + break; + } +} + +void IOT_VisitAllCookies(CefRefPtr visitor) +{ + REQUIRE_IOT(); + + net::CookieMonster* cookie_monster = static_cast( + _Context->request_context()->cookie_store()); + if (!cookie_monster) + return; + + net::CookieList list = cookie_monster->GetAllCookies(); + if (!list.empty()) + IOT_VisitCookies(cookie_monster, list, visitor); +} + +void IOT_VisitUrlCookies(const GURL& url, bool includeHttpOnly, + CefRefPtr visitor) +{ + REQUIRE_IOT(); + + net::CookieMonster* cookie_monster = static_cast( + _Context->request_context()->cookie_store()); + if (!cookie_monster) + return; + + net::CookieOptions options; + if (includeHttpOnly) + options.set_include_httponly(); + net::CookieList list = + cookie_monster->GetAllCookiesForURLWithOptions(url, options); + if (!list.empty()) + IOT_VisitCookies(cookie_monster, list, visitor); +} + +} // anonymous + bool CefInitialize(const CefSettings& settings, const CefBrowserSettings& browser_defaults) { @@ -97,30 +231,6 @@ void CefRunMessageLoop() _Context->process()->RunMessageLoop(); } -static void UIT_RegisterPlugin(CefPluginInfo* plugin_info) -{ - REQUIRE_UIT(); - - webkit::npapi::WebPluginInfo info; - - FilePath filename = FilePath(CefString(&plugin_info->unique_name)); - std::string name = CefString(&plugin_info->display_name); - std::string description = CefString(&plugin_info->description); - std::string mime_type = CefString(&plugin_info->mime_type); - - webkit::npapi::PluginEntryPoints entry_points; -#if !defined(OS_POSIX) || defined(OS_MACOSX) - entry_points.np_getentrypoints = plugin_info->np_getentrypoints; -#endif - entry_points.np_initialize = plugin_info->np_initialize; - entry_points.np_shutdown = plugin_info->np_shutdown; - - webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(filename, - name, description, mime_type, entry_points); - - delete plugin_info; -} - bool CefRegisterPlugin(const CefPluginInfo& plugin_info) { // Verify that the context is in a valid state. @@ -135,17 +245,6 @@ bool CefRegisterPlugin(const CefPluginInfo& plugin_info) return true; } -static int GetThreadId(CefThreadId threadId) -{ - switch(threadId) { - case TID_UI: return CefThread::UI; - case TID_IO: return CefThread::IO; - case TID_FILE: return CefThread::FILE; - }; - NOTREACHED(); - return -1; -} - bool CefCurrentlyOn(CefThreadId threadId) { int id = GetThreadId(threadId); @@ -251,6 +350,114 @@ bool CefCreateURL(const CefURLParts& parts, return false; } +bool CefVisitAllCookies(CefRefPtr visitor) +{ + // Verify that the context is in a valid state. + if (!CONTEXT_STATE_VALID()) { + NOTREACHED(); + return false; + } + + return CefThread::PostTask(CefThread::IO, FROM_HERE, + NewRunnableFunction(IOT_VisitAllCookies, visitor)); +} + +bool CefVisitUrlCookies(const CefString& url, bool includeHttpOnly, + CefRefPtr visitor) +{ + // Verify that the context is in a valid state. + if (!CONTEXT_STATE_VALID()) { + NOTREACHED(); + return false; + } + + std::string urlStr = url; + GURL gurl = GURL(urlStr); + if (!gurl.is_valid()) + return false; + + return CefThread::PostTask(CefThread::IO, FROM_HERE, + NewRunnableFunction(IOT_VisitUrlCookies, gurl, includeHttpOnly, visitor)); +} + +bool CefSetCookie(const CefString& url, const CefCookie& cookie) +{ + // Verify that the context is in a valid state. + if (!CONTEXT_STATE_VALID()) { + NOTREACHED(); + return false; + } + + // Verify that this function is being called on the IO thread. + if (!CefThread::CurrentlyOn(CefThread::IO)) { + NOTREACHED(); + return false; + } + + net::CookieMonster* cookie_monster = static_cast( + _Context->request_context()->cookie_store()); + if (!cookie_monster) + return false; + + std::string urlStr = url; + GURL gurl = GURL(urlStr); + 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) + SetBaseTime(expiration_time, cookie.expires); + + return cookie_monster->SetCookieWithDetails(gurl, name, value, domain, path, + expiration_time, cookie.secure, + cookie.httponly); +} + +bool CefDeleteCookies(const CefString& url, const CefString& cookie_name) +{ + // Verify that the context is in a valid state. + if (!CONTEXT_STATE_VALID()) { + NOTREACHED(); + return false; + } + + // Verify that this function is being called on the IO thread. + if (!CefThread::CurrentlyOn(CefThread::IO)) { + NOTREACHED(); + return false; + } + + net::CookieMonster* cookie_monster = static_cast( + _Context->request_context()->cookie_store()); + if (!cookie_monster) + return false; + + if (url.empty()) { + // Delete all cookies. + cookie_monster->DeleteAll(true); + return true; + } + + std::string urlStr = url; + GURL gurl = GURL(urlStr); + if (!gurl.is_valid()) + return false; + + if (cookie_name.empty()) { + // Delete all matching host cookies. + cookie_monster->DeleteAllForHost(gurl); + } else { + // Delete all matching host and domain cookies. + cookie_monster->DeleteCookie(gurl, cookie_name); + } + return true; +} + // CefContext diff --git a/libcef_dll/cpptoc/cookie_visitor_cpptoc.cc b/libcef_dll/cpptoc/cookie_visitor_cpptoc.cc new file mode 100644 index 000000000..43f7bd001 --- /dev/null +++ b/libcef_dll/cpptoc/cookie_visitor_cpptoc.cc @@ -0,0 +1,53 @@ +// Copyright (c) 2010 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. +// +// --------------------------------------------------------------------------- +// +// A portion of this file was generated by the CEF translator tool. When +// making changes by hand only do so within the body of existing function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#include "libcef_dll/cpptoc/cookie_visitor_cpptoc.h" + + +// MEMBER FUNCTIONS - Body may be edited by hand. + +int CEF_CALLBACK cookie_visitor_visit(struct _cef_cookie_visitor_t* self, + const struct _cef_cookie_t* cookie, int count, int total, + int* deleteCookie) +{ + DCHECK(self); + DCHECK(cookie); + if(!self || !cookie) + return 0; + + // Reference the existing values without copying. + CefCookie cookieObj; + cookieObj.Set(*cookie, false); + + bool delVal = (*deleteCookie)?true:false; + bool retVal = CefCookieVisitorCppToC::Get(self)->Visit(cookieObj, count, + total, delVal); + *deleteCookie = delVal; + + return retVal; +} + + +// CONSTRUCTOR - Do not edit by hand. + +CefCookieVisitorCppToC::CefCookieVisitorCppToC(CefCookieVisitor* cls) + : CefCppToC( + cls) +{ + struct_.struct_.visit = cookie_visitor_visit; +} + +#ifdef _DEBUG +template<> long CefCppToC::DebugObjCt = 0; +#endif + diff --git a/libcef_dll/cpptoc/cookie_visitor_cpptoc.h b/libcef_dll/cpptoc/cookie_visitor_cpptoc.h new file mode 100644 index 000000000..5ad07cb44 --- /dev/null +++ b/libcef_dll/cpptoc/cookie_visitor_cpptoc.h @@ -0,0 +1,35 @@ +// Copyright (c) 2010 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 and should not edited +// by hand. See the translator.README.txt file in the tools directory for +// more information. +// +#ifndef _COOKIEVISITOR_CPPTOC_H +#define _COOKIEVISITOR_CPPTOC_H + +#ifndef USING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed wrapper-side only") +#else // USING_CEF_SHARED + +#include "include/cef.h" +#include "include/cef_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 CefCookieVisitorCppToC + : public CefCppToC +{ +public: + CefCookieVisitorCppToC(CefCookieVisitor* cls); + virtual ~CefCookieVisitorCppToC() {} +}; + +#endif // USING_CEF_SHARED +#endif // _COOKIEVISITOR_CPPTOC_H + diff --git a/libcef_dll/cpptoc/handler_cpptoc.cc b/libcef_dll/cpptoc/handler_cpptoc.cc index 4708063ab..de8901c56 100644 --- a/libcef_dll/cpptoc/handler_cpptoc.cc +++ b/libcef_dll/cpptoc/handler_cpptoc.cc @@ -39,10 +39,12 @@ enum cef_retval_t CEF_CALLBACK handler_handle_before_created( CefBrowserSettings browserSettings; CefPopupFeatures features; - // Take ownership of the pointers instead of copying. - wndInfo.Attach(*windowInfo); - browserSettings.Attach(*settings); - features.Attach(*popupFeatures); + // Take ownership of the values. + wndInfo.AttachTo(*windowInfo); + browserSettings.AttachTo(*settings); + + // Reference the existing values instead of copying. + features.Set(*popupFeatures, false); // |newHandler| will start off pointing to the current handler. CefRefPtr handlerPtr = CefHandlerCppToC::Unwrap(*handler); @@ -63,16 +65,9 @@ enum cef_retval_t CEF_CALLBACK handler_handle_before_created( *handler = CefHandlerCppToC::Wrap(handlerPtr); } - // Window info may or may not have changed. - *windowInfo = wndInfo; - - // Browser settings may or may not have changed. - *settings = browserSettings; - - // Don't free the pointers. - features.Detach(); - wndInfo.Detach(); - browserSettings.Detach(); + // Return the values to the structures. + wndInfo.DetachTo(*windowInfo); + browserSettings.DetachTo(*settings); return rv; } @@ -239,8 +234,8 @@ enum cef_retval_t CEF_CALLBACK handler_handle_protocol_execution( bool allowExec = *allow_os_execution?true:false; enum cef_retval_t rv = CefHandlerCppToC::Get(self)->HandleProtocolExecution( - CefBrowserCToCpp::Wrap(browser), CefString(url), &allowExec); - *allow_os_execution = allowExec?true:false; + CefBrowserCToCpp::Wrap(browser), CefString(url), allowExec); + *allow_os_execution = allowExec; return rv; } diff --git a/libcef_dll/ctocpp/cookie_visitor_ctocpp.cc b/libcef_dll/ctocpp/cookie_visitor_ctocpp.cc new file mode 100644 index 000000000..6b6816271 --- /dev/null +++ b/libcef_dll/ctocpp/cookie_visitor_ctocpp.cc @@ -0,0 +1,37 @@ +// Copyright (c) 2010 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. +// +// --------------------------------------------------------------------------- +// +// A portion of this file was generated by the CEF translator tool. When +// making changes by hand only do so within the body of existing static and +// virtual method implementations. See the translator.README.txt file in the +// tools directory for more information. +// + +#include "libcef_dll/ctocpp/cookie_visitor_ctocpp.h" + + +// VIRTUAL METHODS - Body may be edited by hand. + +bool CefCookieVisitorCToCpp::Visit(const CefCookie& cookie, int count, + int total, bool& deleteCookie) +{ + if(CEF_MEMBER_MISSING(struct_, visit)) + return false; + + int delVal = deleteCookie; + bool retVal = struct_->visit(struct_, &cookie, count, total, &delVal) ? + true : false; + deleteCookie = delVal?true:false; + + return retVal; +} + + +#ifdef _DEBUG +template<> long CefCToCpp::DebugObjCt = 0; +#endif + diff --git a/libcef_dll/ctocpp/cookie_visitor_ctocpp.h b/libcef_dll/ctocpp/cookie_visitor_ctocpp.h new file mode 100644 index 000000000..d74620bf7 --- /dev/null +++ b/libcef_dll/ctocpp/cookie_visitor_ctocpp.h @@ -0,0 +1,42 @@ +// Copyright (c) 2010 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 and should not edited +// by hand. See the translator.README.txt file in the tools directory for +// more information. +// + +#ifndef _COOKIEVISITOR_CTOCPP_H +#define _COOKIEVISITOR_CTOCPP_H + +#ifndef BUILDING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed DLL-side only") +#else // BUILDING_CEF_SHARED + +#include "include/cef.h" +#include "include/cef_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 CefCookieVisitorCToCpp + : public CefCToCpp +{ +public: + CefCookieVisitorCToCpp(cef_cookie_visitor_t* str) + : CefCToCpp(str) {} + virtual ~CefCookieVisitorCToCpp() {} + + // CefCookieVisitor methods + virtual bool Visit(const CefCookie& cookie, int count, int total, + bool& deleteCookie); +}; + +#endif // BUILDING_CEF_SHARED +#endif // _COOKIEVISITOR_CTOCPP_H + diff --git a/libcef_dll/ctocpp/handler_ctocpp.cc b/libcef_dll/ctocpp/handler_ctocpp.cc index 0c53dc893..a4996becf 100644 --- a/libcef_dll/ctocpp/handler_ctocpp.cc +++ b/libcef_dll/ctocpp/handler_ctocpp.cc @@ -171,15 +171,15 @@ CefHandler::RetVal CefHandlerCToCpp::HandleBeforeResourceLoad( CefHandler::RetVal CefHandlerCToCpp::HandleProtocolExecution( CefRefPtr browser, const CefString& url, - bool* allow_os_execution) + bool& allow_os_execution) { if(CEF_MEMBER_MISSING(struct_, handle_protocol_execution)) return RV_CONTINUE; - int allowExec = *allow_os_execution?1:0; + int allowExec = allow_os_execution; cef_retval_t rv = struct_->handle_protocol_execution(struct_, CefBrowserCppToC::Wrap(browser), url.GetStruct(), &allowExec); - *allow_os_execution = allowExec?true:false; + allow_os_execution = allowExec?true:false; return rv; } diff --git a/libcef_dll/ctocpp/handler_ctocpp.h b/libcef_dll/ctocpp/handler_ctocpp.h index d0f2a1cb2..243f0cf60 100644 --- a/libcef_dll/ctocpp/handler_ctocpp.h +++ b/libcef_dll/ctocpp/handler_ctocpp.h @@ -57,7 +57,7 @@ public: CefRefPtr& resourceStream, CefString& mimeType, int loadFlags); virtual RetVal HandleProtocolExecution(CefRefPtr browser, - const CefString& url, bool* allow_os_execution); + const CefString& url, bool& allow_os_execution); virtual RetVal HandleDownloadResponse(CefRefPtr browser, const CefString& mimeType, const CefString& fileName, int64 contentLength, CefRefPtr& handler); diff --git a/libcef_dll/libcef_dll.cc b/libcef_dll/libcef_dll.cc index 276f80fe9..94d1e090e 100644 --- a/libcef_dll/libcef_dll.cc +++ b/libcef_dll/libcef_dll.cc @@ -21,6 +21,7 @@ #include "cpptoc/web_urlrequest_cpptoc.h" #include "cpptoc/xml_reader_cpptoc.h" #include "cpptoc/zip_reader_cpptoc.h" +#include "ctocpp/cookie_visitor_ctocpp.h" #include "ctocpp/domevent_listener_ctocpp.h" #include "ctocpp/domvisitor_ctocpp.h" #include "ctocpp/download_handler_ctocpp.h" @@ -42,18 +43,14 @@ CEF_EXPORT int cef_initialize(const struct _cef_settings_t* settings, CefSettings settingsObj; CefBrowserSettings browserDefaultsObj; - // Take ownership of the pointers instead of copying. + // Reference the values instead of copying. if (settings) - settingsObj.Attach(*settings); + settingsObj.Set(*settings, false); if (browser_defaults) - browserDefaultsObj.Attach(*browser_defaults); + browserDefaultsObj.Set(*browser_defaults, false); int ret = CefInitialize(settingsObj, browserDefaultsObj); - // Don't free the pointers. - settingsObj.Detach(); - browserDefaultsObj.Detach(); - return ret; } @@ -77,6 +74,7 @@ CEF_EXPORT void cef_shutdown() DCHECK(CefWebURLRequestCppToC::DebugObjCt == 0); DCHECK(CefXmlReaderCppToC::DebugObjCt == 0); DCHECK(CefZipReaderCppToC::DebugObjCt == 0); + DCHECK(CefCookieVisitorCToCpp::DebugObjCt == 0); DCHECK(CefDOMEventListenerCToCpp::DebugObjCt == 0); DCHECK(CefDOMVisitorCToCpp::DebugObjCt == 0); DCHECK(CefDownloadHandlerCToCpp::DebugObjCt == 0); @@ -176,20 +174,7 @@ CEF_EXPORT int cef_parse_url(const cef_string_t* url, CefURLParts urlParts; bool ret = CefParseURL(CefString(url), urlParts); - // Clear the current structure values, if any. - cef_string_clear(&parts->spec); - cef_string_clear(&parts->scheme); - cef_string_clear(&parts->username); - cef_string_clear(&parts->password); - cef_string_clear(&parts->host); - cef_string_clear(&parts->port); - cef_string_clear(&parts->path); - cef_string_clear(&parts->query); - - // Transfer ownership of the values from |urlParts| to the structure. - memcpy(parts, static_cast(&urlParts), - sizeof(cef_urlparts_t)); - urlParts.Detach(); + urlParts.DetachTo(*parts); return ret; } @@ -201,21 +186,59 @@ CEF_EXPORT int cef_create_url(const struct _cef_urlparts_t* parts, if(!parts || !url) return 0; + // Reference the existing values without copying. CefURLParts urlParts; - - // Reference the existing structure values without copying. - cef_string_set(parts->spec.str, parts->spec.length, &urlParts.spec, false); - cef_string_set(parts->scheme.str, parts->scheme.length, &urlParts.scheme, - false); - cef_string_set(parts->username.str, parts->username.length, - &urlParts.username, false); - cef_string_set(parts->password.str, parts->password.length, - &urlParts.password, false); - cef_string_set(parts->host.str, parts->host.length, &urlParts.host, false); - cef_string_set(parts->port.str, parts->port.length, &urlParts.port, false); - cef_string_set(parts->path.str, parts->path.length, &urlParts.path, false); - cef_string_set(parts->query.str, parts->query.length, &urlParts.query, false); + urlParts.Set(*parts, false); CefString urlStr(url); return CefCreateURL(urlParts, urlStr); } + +CEF_EXPORT int cef_visit_all_cookies(struct _cef_cookie_visitor_t* visitor) +{ + DCHECK(visitor); + if (!visitor) + return 0; + + return CefVisitAllCookies(CefCookieVisitorCToCpp::Wrap(visitor)); +} + +CEF_EXPORT int cef_visit_url_cookies(const cef_string_t* url, + int includeHttpOnly, struct _cef_cookie_visitor_t* visitor) +{ + DCHECK(url); + DCHECK(visitor); + if (!url || !visitor) + return 0; + + return CefVisitUrlCookies(CefString(url), includeHttpOnly?true:false, + CefCookieVisitorCToCpp::Wrap(visitor)); +} + +CEF_EXPORT int cef_set_cookie(const cef_string_t* url, + const struct _cef_cookie_t* cookie) +{ + DCHECK(url); + DCHECK(cookie); + if (!url || !cookie) + return 0; + + // Reference the existing values without copying. + CefCookie cookieObj; + cookieObj.Set(*cookie, false); + + return CefSetCookie(CefString(url), cookieObj); +} + +CEF_EXPORT int cef_delete_cookies(const cef_string_t* url, + const cef_string_t* cookie_name) +{ + CefString urlStr, cookieNameStr; + + if(url) + urlStr = url; + if(cookie_name) + cookieNameStr = cookie_name; + + return CefDeleteCookies(urlStr, cookieNameStr); +} diff --git a/libcef_dll/wrapper/libcef_dll_wrapper.cc b/libcef_dll/wrapper/libcef_dll_wrapper.cc index 37b97eaf7..4f7126072 100644 --- a/libcef_dll/wrapper/libcef_dll_wrapper.cc +++ b/libcef_dll/wrapper/libcef_dll_wrapper.cc @@ -6,6 +6,7 @@ #include "include/cef_capi.h" #include "include/cef_nplugin.h" #include "include/cef_nplugin_capi.h" +#include "libcef_dll/cpptoc/cookie_visitor_cpptoc.h" #include "libcef_dll/cpptoc/domevent_listener_cpptoc.h" #include "libcef_dll/cpptoc/domvisitor_cpptoc.h" #include "libcef_dll/cpptoc/download_handler_cpptoc.h" @@ -46,6 +47,7 @@ void CefShutdown() #ifdef _DEBUG // Check that all wrapper objects have been destroyed + DCHECK(CefCookieVisitorCppToC::DebugObjCt == 0); DCHECK(CefDOMEventListenerCppToC::DebugObjCt == 0); DCHECK(CefDOMVisitorCppToC::DebugObjCt == 0); DCHECK(CefDownloadHandlerCppToC::DebugObjCt == 0); @@ -139,3 +141,27 @@ bool CefCreateURL(const CefURLParts& parts, { return cef_create_url(&parts, url.GetWritableStruct()) ? true : false; } + +bool CefVisitAllCookies(CefRefPtr visitor) +{ + return cef_visit_all_cookies(CefCookieVisitorCppToC::Wrap(visitor)) ? + true : false; +} + +bool CefVisitUrlCookies(const CefString& url, bool includeHttpOnly, + CefRefPtr visitor) +{ + return cef_visit_url_cookies(url.GetStruct(), includeHttpOnly, + CefCookieVisitorCppToC::Wrap(visitor)) ? true : false; +} + +bool CefSetCookie(const CefString& url, const CefCookie& cookie) +{ + return cef_set_cookie(url.GetStruct(), &cookie) ? true : false; +} + +bool CefDeleteCookies(const CefString& url, const CefString& cookie_name) +{ + return cef_delete_cookies(url.GetStruct(), cookie_name.GetStruct()) ? + true : false; +} diff --git a/tests/cefclient/cefclient.h b/tests/cefclient/cefclient.h index 9da6d5cbb..739465ce2 100644 --- a/tests/cefclient/cefclient.h +++ b/tests/cefclient/cefclient.h @@ -142,7 +142,7 @@ public: // ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION. virtual RetVal HandleProtocolExecution(CefRefPtr browser, const CefString& url, - bool* allow_os_execution) + bool& allow_os_execution) { REQUIRE_IO_THREAD(); return RV_CONTINUE; diff --git a/tests/cefclient/osrplugin.cpp b/tests/cefclient/osrplugin.cpp index 0207297d9..06e307b29 100644 --- a/tests/cefclient/osrplugin.cpp +++ b/tests/cefclient/osrplugin.cpp @@ -158,7 +158,7 @@ public: popup_rect_ = rect; } else if(!show) { // Clear the popup buffer. - popup_rect_.set(0,0,0,0); + popup_rect_.Set(0,0,0,0); if (popup_buffer_) { delete [] popup_buffer_; popup_buffer_ = NULL; diff --git a/tests/unittests/cookie_unittest.cc b/tests/unittests/cookie_unittest.cc new file mode 100644 index 000000000..b12167c4c --- /dev/null +++ b/tests/unittests/cookie_unittest.cc @@ -0,0 +1,375 @@ +// Copyright (c) 2011 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 "include/cef.h" +#include "include/cef_runnable.h" +#include "base/synchronization/waitable_event.h" +#include "testing/gtest/include/gtest/gtest.h" +#include + +namespace { + +const char* kTestUrl = "http://www.test.com/path/to/cookietest/foo.html"; +const char* kTestDomain = "www.test.com"; +const char* kTestPath = "/path/to/cookietest"; + +typedef std::vector CookieVector; + +void IOT_Set(const CefString& url, CookieVector* cookies, + base::WaitableEvent* event) +{ + CookieVector::const_iterator it = cookies->begin(); + for (; it != cookies->end(); ++it) + EXPECT_TRUE(CefSetCookie(url, *it)); + event->Signal(); +} + +void IOT_Delete(const CefString& url, const CefString& cookie_name, + base::WaitableEvent* event) +{ + EXPECT_TRUE(CefDeleteCookies(url, cookie_name)); + event->Signal(); +} + +class TestVisitor : public CefThreadSafeBase +{ +public: + TestVisitor(CookieVector* cookies, bool deleteCookies, + base::WaitableEvent* event) + : cookies_(cookies), delete_cookies_(deleteCookies), event_(event) + { + } + virtual ~TestVisitor() + { + event_->Signal(); + } + + virtual bool Visit(const CefCookie& cookie, int count, int total, + bool& deleteCookie) + { + cookies_->push_back(cookie); + if (delete_cookies_) + deleteCookie = true; + return true; + } + + CookieVector* cookies_; + bool delete_cookies_; + base::WaitableEvent* event_; +}; + +} // anonymous + +// Test creation of a domain cookie. +TEST(CookieTest, DomainCookie) +{ + base::WaitableEvent event(false, false); + + CefCookie cookie; + CefString(&cookie.name).FromASCII("my_cookie"); + CefString(&cookie.value).FromASCII("My Value"); + CefString(&cookie.domain).FromASCII(kTestDomain); + CefString(&cookie.path).FromASCII(kTestPath); + cookie.has_expires = true; + cookie.expires.year = 2011; + cookie.expires.month = 4; + cookie.expires.day_of_week = 1; + cookie.expires.day_of_month = 11; + + CookieVector cookies; + cookies.push_back(cookie); + + // Set the cookie. + CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Set, kTestUrl, &cookies, + &event)); + event.Wait(); + cookies.clear(); + + // Get the cookie and delete it. + EXPECT_TRUE(CefVisitUrlCookies(kTestUrl, false, + new TestVisitor(&cookies, true, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)1, cookies.size()); + + const CefCookie& cookie_read = cookies[0]; + EXPECT_EQ(CefString(&cookie_read.name), "my_cookie"); + EXPECT_EQ(CefString(&cookie_read.value), "My Value"); + EXPECT_EQ(CefString(&cookie_read.domain), ".www.test.com"); + EXPECT_EQ(CefString(&cookie_read.path), kTestPath); + EXPECT_TRUE(cookie_read.has_expires); + EXPECT_EQ(cookie.expires.year, cookie_read.expires.year); + EXPECT_EQ(cookie.expires.month, cookie_read.expires.month); + EXPECT_EQ(cookie.expires.day_of_week, cookie_read.expires.day_of_week); + EXPECT_EQ(cookie.expires.day_of_month, cookie_read.expires.day_of_month); + EXPECT_EQ(cookie.expires.hour, cookie_read.expires.hour); + EXPECT_EQ(cookie.expires.minute, cookie_read.expires.minute); + EXPECT_EQ(cookie.expires.second, cookie_read.expires.second); + EXPECT_EQ(cookie.expires.millisecond, cookie_read.expires.millisecond); + + cookies.clear(); + + // Verify that the cookie has been deleted. + EXPECT_TRUE(CefVisitUrlCookies(kTestUrl, false, + new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)0, cookies.size()); +} + +// Test creation of a host cookie. +TEST(CookieTest, HostCookie) +{ + base::WaitableEvent event(false, false); + + // Create a host cookie. + CefCookie cookie; + CefString(&cookie.name).FromASCII("my_cookie"); + CefString(&cookie.value).FromASCII("My Value"); + CefString(&cookie.path).FromASCII(kTestPath); + cookie.has_expires = true; + cookie.expires.year = 2011; + cookie.expires.month = 4; + cookie.expires.day_of_week = 1; + cookie.expires.day_of_month = 11; + + CookieVector cookies; + cookies.push_back(cookie); + + // Set the cookie. + CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Set, kTestUrl, &cookies, + &event)); + event.Wait(); + cookies.clear(); + + // Get the cookie. + EXPECT_TRUE(CefVisitUrlCookies(kTestUrl, false, + new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)1, cookies.size()); + + const CefCookie& cookie_read = cookies[0]; + EXPECT_EQ(CefString(&cookie_read.name), "my_cookie"); + EXPECT_EQ(CefString(&cookie_read.value), "My Value"); + EXPECT_EQ(CefString(&cookie_read.domain), kTestDomain); + EXPECT_EQ(CefString(&cookie_read.path), kTestPath); + EXPECT_TRUE(cookie_read.has_expires); + EXPECT_EQ(cookie.expires.year, cookie_read.expires.year); + EXPECT_EQ(cookie.expires.month, cookie_read.expires.month); + EXPECT_EQ(cookie.expires.day_of_week, cookie_read.expires.day_of_week); + EXPECT_EQ(cookie.expires.day_of_month, cookie_read.expires.day_of_month); + EXPECT_EQ(cookie.expires.hour, cookie_read.expires.hour); + EXPECT_EQ(cookie.expires.minute, cookie_read.expires.minute); + EXPECT_EQ(cookie.expires.second, cookie_read.expires.second); + EXPECT_EQ(cookie.expires.millisecond, cookie_read.expires.millisecond); + + cookies.clear(); + + // Delete the cookie. + CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Delete, kTestUrl, + CefString("my_cookie"), &event)); + event.Wait(); + + // Verify that the cookie has been deleted. + EXPECT_TRUE(CefVisitUrlCookies(kTestUrl, false, + new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)0, cookies.size()); +} + +// Test creation of multiple cookies. +TEST(CookieTest, MultipleCookies) +{ + base::WaitableEvent event(false, false); + std::stringstream ss; + int i; + + CookieVector cookies; + + const int kNumCookies = 4; + + // Create the cookies. + for(i = 0; i < kNumCookies; i++) { + CefCookie cookie; + + ss << "my_cookie" << i; + CefString(&cookie.name).FromASCII(ss.str().c_str()); + ss.str(""); + ss << "My Value " << i; + CefString(&cookie.value).FromASCII(ss.str().c_str()); + ss.str(""); + + cookies.push_back(cookie); + } + + // Set the cookies. + CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Set, kTestUrl, &cookies, + &event)); + event.Wait(); + cookies.clear(); + + // Get the cookies without deleting them. + EXPECT_TRUE(CefVisitUrlCookies(kTestUrl, false, + new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)kNumCookies, cookies.size()); + + CookieVector::const_iterator it = cookies.begin(); + for(i = 0; it != cookies.end(); ++it, ++i) { + const CefCookie& cookie = *it; + + ss << "my_cookie" << i; + EXPECT_EQ(CefString(&cookie.name), ss.str()); + ss.str(""); + ss << "My Value " << i; + EXPECT_EQ(CefString(&cookie.value), ss.str()); + ss.str(""); + } + + cookies.clear(); + + // Delete the 2nd cookie. + CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Delete, kTestUrl, + CefString("my_cookie1"), &event)); + event.Wait(); + + // Verify that the cookie has been deleted. + EXPECT_TRUE(CefVisitUrlCookies(kTestUrl, false, + new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)3, cookies.size()); + EXPECT_EQ(CefString(&cookies[0].name), "my_cookie0"); + EXPECT_EQ(CefString(&cookies[1].name), "my_cookie2"); + EXPECT_EQ(CefString(&cookies[2].name), "my_cookie3"); + + cookies.clear(); + + // Delete the rest of the cookies. + CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Delete, kTestUrl, + CefString(), &event)); + event.Wait(); + + // Verify that the cookies have been deleted. + EXPECT_TRUE(CefVisitUrlCookies(kTestUrl, false, + new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)0, cookies.size()); + + // Create the cookies. + for(i = 0; i < kNumCookies; i++) { + CefCookie cookie; + + ss << "my_cookie" << i; + CefString(&cookie.name).FromASCII(ss.str().c_str()); + ss.str(""); + ss << "My Value " << i; + CefString(&cookie.value).FromASCII(ss.str().c_str()); + ss.str(""); + + cookies.push_back(cookie); + } + + // Delete all of the cookies using the visitor. + EXPECT_TRUE(CefVisitUrlCookies(kTestUrl, false, + new TestVisitor(&cookies, true, &event))); + event.Wait(); + + cookies.clear(); + + // Verify that the cookies have been deleted. + EXPECT_TRUE(CefVisitUrlCookies(kTestUrl, false, + new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)0, cookies.size()); +} + +TEST(CookieTest, AllCookies) +{ + base::WaitableEvent event(false, false); + CookieVector cookies; + + // Delete all system cookies just in case something is left over from a + // different test. + CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Delete, CefString(), + CefString(), &event)); + event.Wait(); + + // Verify that all system cookies have been deleted. + EXPECT_TRUE(CefVisitAllCookies(new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)0, cookies.size()); + + // Create cookies with 2 separate hosts. + CefCookie cookie1; + const char* kUrl1 = "http://www.foo.com"; + CefString(&cookie1.name).FromASCII("my_cookie1"); + CefString(&cookie1.value).FromASCII("My Value 1"); + + cookies.push_back(cookie1); + CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Set, kUrl1, &cookies, &event)); + event.Wait(); + cookies.clear(); + + CefCookie cookie2; + const char* kUrl2 = "http://www.bar.com"; + CefString(&cookie2.name).FromASCII("my_cookie2"); + CefString(&cookie2.value).FromASCII("My Value 2"); + + cookies.push_back(cookie2); + CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Set, kUrl2, &cookies, &event)); + event.Wait(); + cookies.clear(); + + // Verify that all system cookies can be retrieved. + EXPECT_TRUE(CefVisitAllCookies(new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)2, cookies.size()); + 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"); + EXPECT_EQ(CefString(&cookies[1].name), "my_cookie2"); + EXPECT_EQ(CefString(&cookies[1].value), "My Value 2"); + EXPECT_EQ(CefString(&cookies[1].domain), "www.bar.com"); + cookies.clear(); + + // Verify that the cookies can be retrieved separately. + EXPECT_TRUE(CefVisitUrlCookies(kUrl1, false, + new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)1, cookies.size()); + 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"); + cookies.clear(); + + EXPECT_TRUE(CefVisitUrlCookies(kUrl2, false, + new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)1, cookies.size()); + 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"); + cookies.clear(); + + // Delete all of the system cookies. + CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Delete, CefString(), + CefString(), &event)); + event.Wait(); + + // Verify that all system cookies have been deleted. + EXPECT_TRUE(CefVisitAllCookies(new TestVisitor(&cookies, false, &event))); + event.Wait(); + + EXPECT_EQ((CookieVector::size_type)0, cookies.size()); +} diff --git a/tests/unittests/test_handler.h b/tests/unittests/test_handler.h index 4ad2206bb..6892711a0 100644 --- a/tests/unittests/test_handler.h +++ b/tests/unittests/test_handler.h @@ -132,7 +132,7 @@ public: virtual RetVal HandleProtocolExecution(CefRefPtr browser, const CefString& url, - bool* allow_os_execution) + bool& allow_os_execution) { return RV_CONTINUE; }