diff --git a/cef.gyp b/cef.gyp index 428731490..a010cbf2e 100644 --- a/cef.gyp +++ b/cef.gyp @@ -244,6 +244,7 @@ 'tests/unittests/test_util.cc', 'tests/unittests/test_util.h', 'tests/unittests/url_unittest.cc', + 'tests/unittests/urlrequest_unittest.cc', 'tests/unittests/v8_unittest.cc', 'tests/unittests/values_unittest.cc', 'tests/unittests/xml_reader_unittest.cc', @@ -755,6 +756,8 @@ 'libcef/browser/browser_message_loop.h', 'libcef/browser/browser_settings.cc', 'libcef/browser/browser_settings.h', + 'libcef/browser/browser_urlrequest_impl.cc', + 'libcef/browser/browser_urlrequest_impl.h', 'libcef/browser/content_browser_client.cc', 'libcef/browser/content_browser_client.h', 'libcef/browser/context.cc', @@ -837,6 +840,7 @@ 'libcef/common/tracker.cc', 'libcef/common/tracker.h', 'libcef/common/url_impl.cc', + 'libcef/common/urlrequest_impl.cc', 'libcef/common/value_base.cc', 'libcef/common/value_base.h', 'libcef/common/values_impl.cc', @@ -857,6 +861,8 @@ 'libcef/renderer/frame_impl.h', 'libcef/renderer/render_process_observer.cc', 'libcef/renderer/render_process_observer.h', + 'libcef/renderer/render_urlrequest_impl.cc', + 'libcef/renderer/render_urlrequest_impl.h', 'libcef/renderer/thread_util.h', 'libcef/renderer/v8_impl.cc', 'libcef/renderer/v8_impl.h', @@ -1059,6 +1065,7 @@ 'tests/unittests/dom_unittest.cc', 'tests/unittests/process_message_unittest.cc', 'tests/unittests/scheme_handler_unittest.cc', + 'tests/unittests/urlrequest_unittest.cc', 'tests/unittests/test_handler.cc', 'tests/unittests/test_handler.h', 'tests/unittests/test_suite.cc', diff --git a/cef_paths.gypi b/cef_paths.gypi index a23b47bde..f3b724d92 100644 --- a/cef_paths.gypi +++ b/cef_paths.gypi @@ -14,6 +14,7 @@ 'autogen_cpp_includes': [ 'include/cef_app.h', 'include/cef_browser.h', + 'include/cef_browser_process_handler.h', 'include/cef_callback.h', 'include/cef_client.h', 'include/cef_command_line.h', @@ -43,6 +44,7 @@ 'include/cef_string_visitor.h', 'include/cef_task.h', 'include/cef_url.h', + 'include/cef_urlrequest.h', 'include/cef_v8.h', 'include/cef_values.h', 'include/cef_web_plugin.h', @@ -52,6 +54,7 @@ 'autogen_capi_includes': [ 'include/capi/cef_app_capi.h', 'include/capi/cef_browser_capi.h', + 'include/capi/cef_browser_process_handler_capi.h', 'include/capi/cef_callback_capi.h', 'include/capi/cef_client_capi.h', 'include/capi/cef_command_line_capi.h', @@ -81,6 +84,7 @@ 'include/capi/cef_string_visitor_capi.h', 'include/capi/cef_task_capi.h', 'include/capi/cef_url_capi.h', + 'include/capi/cef_urlrequest_capi.h', 'include/capi/cef_v8_capi.h', 'include/capi/cef_values_capi.h', 'include/capi/cef_web_plugin_capi.h', @@ -98,6 +102,8 @@ 'libcef_dll/cpptoc/browser_cpptoc.h', 'libcef_dll/cpptoc/browser_host_cpptoc.cc', 'libcef_dll/cpptoc/browser_host_cpptoc.h', + 'libcef_dll/ctocpp/browser_process_handler_ctocpp.cc', + 'libcef_dll/ctocpp/browser_process_handler_ctocpp.h', 'libcef_dll/cpptoc/callback_cpptoc.cc', 'libcef_dll/cpptoc/callback_cpptoc.h', 'libcef_dll/ctocpp/client_ctocpp.cc', @@ -182,6 +188,10 @@ 'libcef_dll/ctocpp/string_visitor_ctocpp.h', 'libcef_dll/ctocpp/task_ctocpp.cc', 'libcef_dll/ctocpp/task_ctocpp.h', + 'libcef_dll/cpptoc/urlrequest_cpptoc.cc', + 'libcef_dll/cpptoc/urlrequest_cpptoc.h', + 'libcef_dll/ctocpp/urlrequest_client_ctocpp.cc', + 'libcef_dll/ctocpp/urlrequest_client_ctocpp.h', 'libcef_dll/ctocpp/v8accessor_ctocpp.cc', 'libcef_dll/ctocpp/v8accessor_ctocpp.h', 'libcef_dll/cpptoc/v8context_cpptoc.cc', @@ -214,6 +224,8 @@ 'libcef_dll/ctocpp/browser_ctocpp.h', 'libcef_dll/ctocpp/browser_host_ctocpp.cc', 'libcef_dll/ctocpp/browser_host_ctocpp.h', + 'libcef_dll/cpptoc/browser_process_handler_cpptoc.cc', + 'libcef_dll/cpptoc/browser_process_handler_cpptoc.h', 'libcef_dll/ctocpp/callback_ctocpp.cc', 'libcef_dll/ctocpp/callback_ctocpp.h', 'libcef_dll/cpptoc/client_cpptoc.cc', @@ -298,6 +310,10 @@ 'libcef_dll/cpptoc/string_visitor_cpptoc.h', 'libcef_dll/cpptoc/task_cpptoc.cc', 'libcef_dll/cpptoc/task_cpptoc.h', + 'libcef_dll/ctocpp/urlrequest_ctocpp.cc', + 'libcef_dll/ctocpp/urlrequest_ctocpp.h', + 'libcef_dll/cpptoc/urlrequest_client_cpptoc.cc', + 'libcef_dll/cpptoc/urlrequest_client_cpptoc.h', 'libcef_dll/cpptoc/v8accessor_cpptoc.cc', 'libcef_dll/cpptoc/v8accessor_cpptoc.h', 'libcef_dll/ctocpp/v8context_ctocpp.cc', diff --git a/include/capi/cef_app_capi.h b/include/capi/cef_app_capi.h index 1930d046b..e698171d0 100644 --- a/include/capi/cef_app_capi.h +++ b/include/capi/cef_app_capi.h @@ -134,30 +134,28 @@ typedef struct _cef_app_t { void (CEF_CALLBACK *on_register_custom_schemes)(struct _cef_app_t* self, struct _cef_scheme_registrar_t* registrar); - /// - // Return the handler for render process events. This function is called by - // the render process main thread. - /// - struct _cef_render_process_handler_t* ( - CEF_CALLBACK *get_render_process_handler)(struct _cef_app_t* self); - /// // Return the handler for resource bundle events. If // CefSettings.pack_loading_disabled is true (1) a handler must be returned. // If no handler is returned resources will be loaded from pack files. This - // function is called by the browser and rendere processes on multiple - // threads. + // function is called by the browser and render processes on multiple threads. /// struct _cef_resource_bundle_handler_t* ( CEF_CALLBACK *get_resource_bundle_handler)(struct _cef_app_t* self); /// - // Return the handler for proxy events. If no handler is returned the default - // system handler will be used. This function is called by the browser process - // IO thread. + // Return the handler for functionality specific to the browser process. This + // function is called on multiple threads in the browser process. /// - struct _cef_proxy_handler_t* (CEF_CALLBACK *get_proxy_handler)( - struct _cef_app_t* self); + struct _cef_browser_process_handler_t* ( + CEF_CALLBACK *get_browser_process_handler)(struct _cef_app_t* self); + + /// + // Return the handler for functionality specific to the render process. This + // function is called on the render process main thread. + /// + struct _cef_render_process_handler_t* ( + CEF_CALLBACK *get_render_process_handler)(struct _cef_app_t* self); } cef_app_t; diff --git a/include/capi/cef_browser_process_handler_capi.h b/include/capi/cef_browser_process_handler_capi.h new file mode 100644 index 000000000..b07c9a90b --- /dev/null +++ b/include/capi/cef_browser_process_handler_capi.h @@ -0,0 +1,80 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool and should not edited +// by hand. See the translator.README.txt file in the tools directory for +// more information. +// + +#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_PROCESS_HANDLER_CAPI_H_ +#define CEF_INCLUDE_CAPI_CEF_BROWSER_PROCESS_HANDLER_CAPI_H_ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "include/capi/cef_base_capi.h" + + +/// +// Structure used to implement browser process callbacks. The functions of this +// structure will be called on the browser process main thread unless otherwise +// indicated. +/// +typedef struct _cef_browser_process_handler_t { + /// + // Base structure. + /// + cef_base_t base; + + /// + // Return the handler for proxy events. If no handler is returned the default + // system handler will be used. This function is called on the browser process + // IO thread. + /// + struct _cef_proxy_handler_t* (CEF_CALLBACK *get_proxy_handler)( + struct _cef_browser_process_handler_t* self); + + /// + // Called on the browser process UI thread immediately after the CEF context + // has been initialized. + /// + void (CEF_CALLBACK *on_context_initialized)( + struct _cef_browser_process_handler_t* self); +} cef_browser_process_handler_t; + + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_CAPI_CEF_BROWSER_PROCESS_HANDLER_CAPI_H_ diff --git a/include/capi/cef_load_handler_capi.h b/include/capi/cef_load_handler_capi.h index 6b4269e49..cac300563 100644 --- a/include/capi/cef_load_handler_capi.h +++ b/include/capi/cef_load_handler_capi.h @@ -86,7 +86,7 @@ typedef struct _cef_load_handler_t { /// void (CEF_CALLBACK *on_load_error)(struct _cef_load_handler_t* self, struct _cef_browser_t* browser, struct _cef_frame_t* frame, - enum cef_handler_errorcode_t errorCode, const cef_string_t* errorText, + enum cef_errorcode_t errorCode, const cef_string_t* errorText, const cef_string_t* failedUrl); } cef_load_handler_t; diff --git a/include/capi/cef_request_capi.h b/include/capi/cef_request_capi.h index 8ebd5d0ce..a28d4754d 100644 --- a/include/capi/cef_request_capi.h +++ b/include/capi/cef_request_capi.h @@ -55,6 +55,11 @@ typedef struct _cef_request_t { /// cef_base_t base; + /// + // Returns true (1) if this object is read-only. + /// + int (CEF_CALLBACK *is_read_only)(struct _cef_request_t* self); + /// // Get the fully qualified URL. /// @@ -112,20 +117,20 @@ typedef struct _cef_request_t { cef_string_multimap_t headerMap); /// - // Get the flags used in combination with CefWebURLRequest. + // Get the flags used in combination with cef_urlrequest_t. See + // cef_urlrequest_flags_t for supported values. /// - enum cef_weburlrequest_flags_t (CEF_CALLBACK *get_flags)( - struct _cef_request_t* self); + int (CEF_CALLBACK *get_flags)(struct _cef_request_t* self); /// - // Set the flags used in combination with CefWebURLRequest. + // Set the flags used in combination with cef_urlrequest_t. See + // cef_urlrequest_flags_t for supported values. /// - void (CEF_CALLBACK *set_flags)(struct _cef_request_t* self, - enum cef_weburlrequest_flags_t flags); + void (CEF_CALLBACK *set_flags)(struct _cef_request_t* self, int flags); /// // Set the URL to the first party for cookies used in combination with - // CefWebURLRequest. + // cef_urlrequest_t. /// // The resulting string must be freed by calling cef_string_userfree_free(). cef_string_userfree_t (CEF_CALLBACK *get_first_party_for_cookies)( @@ -133,7 +138,7 @@ typedef struct _cef_request_t { /// // Get the URL to the first party for cookies used in combination with - // CefWebURLRequest. + // cef_urlrequest_t. /// void (CEF_CALLBACK *set_first_party_for_cookies)(struct _cef_request_t* self, const cef_string_t* url); @@ -156,6 +161,11 @@ typedef struct _cef_post_data_t { /// cef_base_t base; + /// + // Returns true (1) if this object is read-only. + /// + int (CEF_CALLBACK *is_read_only)(struct _cef_post_data_t* self); + /// // Returns the number of existing post data elements. /// @@ -203,6 +213,11 @@ typedef struct _cef_post_data_element_t { /// cef_base_t base; + /// + // Returns true (1) if this object is read-only. + /// + int (CEF_CALLBACK *is_read_only)(struct _cef_post_data_element_t* self); + /// // Remove all contents from the post data element. /// diff --git a/include/capi/cef_resource_handler_capi.h b/include/capi/cef_resource_handler_capi.h index 58caa3376..b55c41202 100644 --- a/include/capi/cef_resource_handler_capi.h +++ b/include/capi/cef_resource_handler_capi.h @@ -90,6 +90,21 @@ typedef struct _cef_resource_handler_t { void* data_out, int bytes_to_read, int* bytes_read, struct _cef_callback_t* callback); + /// + // Return true (1) if the specified cookie can be sent with the request or + // false (0) otherwise. If false (0) is returned for any cookie then no + // cookies will be sent with the request. + /// + int (CEF_CALLBACK *can_get_cookie)(struct _cef_resource_handler_t* self, + const struct _cef_cookie_t* cookie); + + /// + // Return true (1) if the specified cookie returned with the response can be + // set or false (0) otherwise. + /// + int (CEF_CALLBACK *can_set_cookie)(struct _cef_resource_handler_t* self, + const struct _cef_cookie_t* cookie); + /// // Request processing has been canceled. /// diff --git a/include/capi/cef_response_capi.h b/include/capi/cef_response_capi.h index e58180711..5dd682ae4 100644 --- a/include/capi/cef_response_capi.h +++ b/include/capi/cef_response_capi.h @@ -55,6 +55,11 @@ typedef struct _cef_response_t { /// cef_base_t base; + /// + // Returns true (1) if this object is read-only. + /// + int (CEF_CALLBACK *is_read_only)(struct _cef_response_t* self); + /// // Get the response status code. /// @@ -112,6 +117,12 @@ typedef struct _cef_response_t { } cef_response_t; +/// +// Create a new cef_response_t object. +/// +CEF_EXPORT cef_response_t* cef_response_create(); + + #ifdef __cplusplus } #endif diff --git a/include/capi/cef_scheme_capi.h b/include/capi/cef_scheme_capi.h index b7fb63294..3e9622eb9 100644 --- a/include/capi/cef_scheme_capi.h +++ b/include/capi/cef_scheme_capi.h @@ -140,10 +140,11 @@ typedef struct _cef_scheme_handler_factory_t { cef_base_t base; /// - // Return a new resource handler instance to handle the request. |browser| - // will be the browser window that initiated the request. If the request was - // initiated using the CefWebURLRequest API |browser| will be NULL. The - // |request| object passed to this function will not contain cookie data. + // Return a new resource handler instance to handle the request. |browser| and + // |frame| will be the browser window and frame respectively that originated + // the request or NULL if the request did not originate from a browser window + // (for example, if the request came from cef_urlrequest_t). The |request| + // object passed to this function will not contain cookie data. /// struct _cef_resource_handler_t* (CEF_CALLBACK *create)( struct _cef_scheme_handler_factory_t* self, diff --git a/include/capi/cef_urlrequest_capi.h b/include/capi/cef_urlrequest_capi.h new file mode 100644 index 000000000..29e111e9b --- /dev/null +++ b/include/capi/cef_urlrequest_capi.h @@ -0,0 +1,164 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool and should not edited +// by hand. See the translator.README.txt file in the tools directory for +// more information. +// + +#ifndef CEF_INCLUDE_CAPI_CEF_URLREQUEST_CAPI_H_ +#define CEF_INCLUDE_CAPI_CEF_URLREQUEST_CAPI_H_ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "include/capi/cef_base_capi.h" + + +/// +// Structure used to make a URL request. URL requests are not associated with a +// browser instance so no cef_client_t callbacks will be executed. URL requests +// can be created on any valid CEF thread in either the browser or render +// process. Once created the functions of the URL request object must be +// accessed on the same thread that created it. +/// +typedef struct _cef_urlrequest_t { + /// + // Base structure. + /// + cef_base_t base; + + /// + // Returns the request object used to create this URL request. The returned + // object is read-only and should not be modified. + /// + struct _cef_request_t* (CEF_CALLBACK *get_request)( + struct _cef_urlrequest_t* self); + + /// + // Returns the client. + /// + struct _cef_urlrequest_client_t* (CEF_CALLBACK *get_client)( + struct _cef_urlrequest_t* self); + + /// + // Returns the request status. + /// + enum cef_urlrequest_status_t (CEF_CALLBACK *get_request_status)( + struct _cef_urlrequest_t* self); + + /// + // Returns the request error if status is UR_CANCELED or UR_FAILED, or 0 + // otherwise. + /// + enum cef_errorcode_t (CEF_CALLBACK *get_request_error)( + struct _cef_urlrequest_t* self); + + /// + // Returns the response, or NULL if no response information is available. + // Response information will only be available after the upload has completed. + // The returned object is read-only and should not be modified. + /// + struct _cef_response_t* (CEF_CALLBACK *get_response)( + struct _cef_urlrequest_t* self); + + /// + // Cancel the request. + /// + void (CEF_CALLBACK *cancel)(struct _cef_urlrequest_t* self); +} cef_urlrequest_t; + + +/// +// Create a new URL request. Only GET, POST, HEAD, DELETE and PUT request +// functions are supported. The |request| object will be marked as read-only +// after calling this function. +/// +CEF_EXPORT cef_urlrequest_t* cef_urlrequest_create( + struct _cef_request_t* request, struct _cef_urlrequest_client_t* client); + + +/// +// Structure that should be implemented by the cef_urlrequest_t client. The +// functions of this structure will be called on the same thread that created +// the request. +/// +typedef struct _cef_urlrequest_client_t { + /// + // Base structure. + /// + cef_base_t base; + + /// + // Notifies the client that the request has completed. Use the + // cef_urlrequest_t::GetRequestStatus function to determine if the request was + // successful or not. + /// + void (CEF_CALLBACK *on_request_complete)( + struct _cef_urlrequest_client_t* self, + struct _cef_urlrequest_t* request); + + /// + // Notifies the client of upload progress. |current| denotes the number of + // bytes sent so far and |total| is the total size of uploading data (or -1 if + // chunked upload is enabled). This function will only be called if the + // UR_FLAG_REPORT_UPLOAD_PROGRESS flag is set on the request. + /// + void (CEF_CALLBACK *on_upload_progress)(struct _cef_urlrequest_client_t* self, + struct _cef_urlrequest_t* request, uint64 current, uint64 total); + + /// + // Notifies the client of download progress. |current| denotes the number of + // bytes received up to the call and |total| is the expected total size of the + // response (or -1 if not determined). + /// + void (CEF_CALLBACK *on_download_progress)( + struct _cef_urlrequest_client_t* self, struct _cef_urlrequest_t* request, + uint64 current, uint64 total); + + /// + // Called when some part of the response is read. |data| contains the current + // bytes received since the last call. This function will not be called if the + // UR_FLAG_NO_DOWNLOAD_DATA flag is set on the request. + /// + void (CEF_CALLBACK *on_download_data)(struct _cef_urlrequest_client_t* self, + struct _cef_urlrequest_t* request, const void* data, + size_t data_length); +} cef_urlrequest_client_t; + + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_CAPI_CEF_URLREQUEST_CAPI_H_ diff --git a/include/cef_app.h b/include/cef_app.h index cecc06686..9d1aa321d 100644 --- a/include/cef_app.h +++ b/include/cef_app.h @@ -40,8 +40,8 @@ #pragma once #include "include/cef_base.h" +#include "include/cef_browser_process_handler.h" #include "include/cef_command_line.h" -#include "include/cef_proxy_handler.h" #include "include/cef_render_process_handler.h" #include "include/cef_resource_bundle_handler.h" #include "include/cef_scheme.h" @@ -142,20 +142,11 @@ class CefApp : public virtual CefBase { CefRefPtr registrar) { } - /// - // Return the handler for render process events. This method is called by the - // render process main thread. - /// - /*--cef()--*/ - virtual CefRefPtr GetRenderProcessHandler() { - return NULL; - } - /// // Return the handler for resource bundle events. If // CefSettings.pack_loading_disabled is true a handler must be returned. If no // handler is returned resources will be loaded from pack files. This method - // is called by the browser and rendere processes on multiple threads. + // is called by the browser and render processes on multiple threads. /// /*--cef()--*/ virtual CefRefPtr GetResourceBundleHandler() { @@ -163,12 +154,20 @@ class CefApp : public virtual CefBase { } /// - // Return the handler for proxy events. If no handler is returned the default - // system handler will be used. This method is called by the browser process - // IO thread. + // Return the handler for functionality specific to the browser process. This + // method is called on multiple threads in the browser process. /// /*--cef()--*/ - virtual CefRefPtr GetProxyHandler() { + virtual CefRefPtr GetBrowserProcessHandler() { + return NULL; + } + + /// + // Return the handler for functionality specific to the render process. This + // method is called on the render process main thread. + /// + /*--cef()--*/ + virtual CefRefPtr GetRenderProcessHandler() { return NULL; } }; diff --git a/include/cef_browser_process_handler.h b/include/cef_browser_process_handler.h new file mode 100644 index 000000000..1095e2da1 --- /dev/null +++ b/include/cef_browser_process_handler.h @@ -0,0 +1,69 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_BROWSER_PROCESS_HANDLER_H_ +#define CEF_INCLUDE_CEF_BROWSER_PROCESS_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_proxy_handler.h" + +/// +// Class used to implement browser process callbacks. The methods of this class +// will be called on the browser process main thread unless otherwise indicated. +/// +/*--cef(source=client)--*/ +class CefBrowserProcessHandler : public virtual CefBase { + public: + /// + // Return the handler for proxy events. If no handler is returned the default + // system handler will be used. This method is called on the browser process + // IO thread. + /// + /*--cef()--*/ + virtual CefRefPtr GetProxyHandler() { + return NULL; + } + + /// + // Called on the browser process UI thread immediately after the CEF context + // has been initialized. + /// + /*--cef()--*/ + virtual void OnContextInitialized() {} +}; + +#endif // CEF_INCLUDE_CEF_BROWSER_PROCESS_HANDLER_H_ diff --git a/include/cef_load_handler.h b/include/cef_load_handler.h index b8c1d8044..91cec742f 100644 --- a/include/cef_load_handler.h +++ b/include/cef_load_handler.h @@ -49,7 +49,7 @@ /*--cef(source=client)--*/ class CefLoadHandler : public virtual CefBase { public: - typedef cef_handler_errorcode_t ErrorCode; + typedef cef_errorcode_t ErrorCode; /// // Called when the browser begins loading a frame. The |frame| value will diff --git a/include/cef_request.h b/include/cef_request.h index 0b5aab563..7ac4cb027 100644 --- a/include/cef_request.h +++ b/include/cef_request.h @@ -49,23 +49,29 @@ class CefPostDataElement; // Class used to represent a web request. The methods of this class may be // called on any thread. /// -/*--cef(source=library)--*/ +/*--cef(source=library,no_debugct_check)--*/ class CefRequest : public virtual CefBase { public: typedef std::multimap HeaderMap; - typedef cef_weburlrequest_flags_t RequestFlags; /// // Create a new CefRequest object. /// /*--cef()--*/ - static CefRefPtr CreateRequest(); + static CefRefPtr Create(); + + /// + // Returns true if this object is read-only. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; /// // Get the fully qualified URL. /// /*--cef()--*/ virtual CefString GetURL() =0; + /// // Set the fully qualified URL. /// @@ -78,6 +84,7 @@ class CefRequest : public virtual CefBase { /// /*--cef()--*/ virtual CefString GetMethod() =0; + /// // Set the request method type. /// @@ -89,6 +96,7 @@ class CefRequest : public virtual CefBase { /// /*--cef()--*/ virtual CefRefPtr GetPostData() =0; + /// // Set the post data. /// @@ -100,6 +108,7 @@ class CefRequest : public virtual CefBase { /// /*--cef()--*/ virtual void GetHeaderMap(HeaderMap& headerMap) =0; + /// // Set the header values. /// @@ -116,25 +125,29 @@ class CefRequest : public virtual CefBase { const HeaderMap& headerMap) =0; /// - // Get the flags used in combination with CefWebURLRequest. + // Get the flags used in combination with CefURLRequest. See + // cef_urlrequest_flags_t for supported values. /// - /*--cef(default_retval=WUR_FLAG_NONE)--*/ - virtual RequestFlags GetFlags() =0; + /*--cef(default_retval=UR_FLAG_NONE)--*/ + virtual int GetFlags() =0; + /// - // Set the flags used in combination with CefWebURLRequest. + // Set the flags used in combination with CefURLRequest. See + // cef_urlrequest_flags_t for supported values. /// /*--cef()--*/ - virtual void SetFlags(RequestFlags flags) =0; + virtual void SetFlags(int flags) =0; /// // Set the URL to the first party for cookies used in combination with - // CefWebURLRequest. + // CefURLRequest. /// /*--cef()--*/ virtual CefString GetFirstPartyForCookies() =0; + /// // Get the URL to the first party for cookies used in combination with - // CefWebURLRequest. + // CefURLRequest. /// /*--cef()--*/ virtual void SetFirstPartyForCookies(const CefString& url) =0; @@ -145,7 +158,7 @@ class CefRequest : public virtual CefBase { // Class used to represent post data for a web request. The methods of this // class may be called on any thread. /// -/*--cef(source=library)--*/ +/*--cef(source=library,no_debugct_check)--*/ class CefPostData : public virtual CefBase { public: typedef std::vector > ElementVector; @@ -154,7 +167,13 @@ class CefPostData : public virtual CefBase { // Create a new CefPostData object. /// /*--cef()--*/ - static CefRefPtr CreatePostData(); + static CefRefPtr Create(); + + /// + // Returns true if this object is read-only. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; /// // Returns the number of existing post data elements. @@ -193,7 +212,7 @@ class CefPostData : public virtual CefBase { // Class used to represent a single element in the request post data. The // methods of this class may be called on any thread. /// -/*--cef(source=library)--*/ +/*--cef(source=library,no_debugct_check)--*/ class CefPostDataElement : public virtual CefBase { public: /// @@ -205,7 +224,13 @@ class CefPostDataElement : public virtual CefBase { // Create a new CefPostDataElement object. /// /*--cef()--*/ - static CefRefPtr CreatePostDataElement(); + static CefRefPtr Create(); + + /// + // Returns true if this object is read-only. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; /// // Remove all contents from the post data element. diff --git a/include/cef_resource_handler.h b/include/cef_resource_handler.h index fecec48e1..57c8b7fc0 100644 --- a/include/cef_resource_handler.h +++ b/include/cef_resource_handler.h @@ -41,6 +41,7 @@ #include "include/cef_base.h" #include "include/cef_browser.h" #include "include/cef_callback.h" +#include "include/cef_cookie.h" #include "include/cef_request.h" #include "include/cef_response.h" @@ -90,6 +91,21 @@ class CefResourceHandler : public virtual CefBase { int& bytes_read, CefRefPtr callback) =0; + /// + // Return true if the specified cookie can be sent with the request or false + // otherwise. If false is returned for any cookie then no cookies will be sent + // with the request. + /// + /*--cef()--*/ + virtual bool CanGetCookie(const CefCookie& cookie) { return true; } + + /// + // Return true if the specified cookie returned with the response can be set + // or false otherwise. + /// + /*--cef()--*/ + virtual bool CanSetCookie(const CefCookie& cookie) { return true; } + /// // Request processing has been canceled. /// diff --git a/include/cef_response.h b/include/cef_response.h index efa4aef67..32fbef1b0 100644 --- a/include/cef_response.h +++ b/include/cef_response.h @@ -45,16 +45,29 @@ // Class used to represent a web response. The methods of this class may be // called on any thread. /// -/*--cef(source=library)--*/ +/*--cef(source=library,no_debugct_check)--*/ class CefResponse : public virtual CefBase { public: typedef std::multimap HeaderMap; + /// + // Create a new CefResponse object. + /// + /*--cef()--*/ + static CefRefPtr Create(); + + /// + // Returns true if this object is read-only. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; + /// // Get the response status code. /// /*--cef()--*/ virtual int GetStatus() =0; + /// // Set the response status code. /// @@ -66,6 +79,7 @@ class CefResponse : public virtual CefBase { /// /*--cef()--*/ virtual CefString GetStatusText() =0; + /// // Set the response status text. /// @@ -77,6 +91,7 @@ class CefResponse : public virtual CefBase { /// /*--cef()--*/ virtual CefString GetMimeType() = 0; + /// // Set the response mime type. /// @@ -94,6 +109,7 @@ class CefResponse : public virtual CefBase { /// /*--cef()--*/ virtual void GetHeaderMap(HeaderMap& headerMap) =0; + /// // Set all response header fields. /// diff --git a/include/cef_scheme.h b/include/cef_scheme.h index 66a5e75d0..58eae5f69 100644 --- a/include/cef_scheme.h +++ b/include/cef_scheme.h @@ -143,11 +143,12 @@ class CefSchemeHandlerFactory : public virtual CefBase { public: /// // Return a new resource handler instance to handle the request. |browser| - // will be the browser window that initiated the request. If the request was - // initiated using the CefWebURLRequest API |browser| will be NULL. The + // and |frame| will be the browser window and frame respectively that + // originated the request or NULL if the request did not originate from a + // browser window (for example, if the request came from CefURLRequest). The // |request| object passed to this method will not contain cookie data. /// - /*--cef()--*/ + /*--cef(optional_param=browser,optional_param=frame)--*/ virtual CefRefPtr Create( CefRefPtr browser, CefRefPtr frame, diff --git a/include/cef_urlrequest.h b/include/cef_urlrequest.h new file mode 100644 index 000000000..069d2668c --- /dev/null +++ b/include/cef_urlrequest.h @@ -0,0 +1,159 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_URLREQUEST_H_ +#define CEF_INCLUDE_CEF_URLREQUEST_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_request.h" +#include "include/cef_response.h" + +class CefURLRequestClient; + +/// +// Class used to make a URL request. URL requests are not associated with a +// browser instance so no CefClient callbacks will be executed. URL requests +// can be created on any valid CEF thread in either the browser or render +// process. Once created the methods of the URL request object must be accessed +// on the same thread that created it. +/// +/*--cef(source=library)--*/ +class CefURLRequest : public virtual CefBase { + public: + typedef cef_urlrequest_status_t Status; + typedef cef_errorcode_t ErrorCode; + + /// + // Create a new URL request. Only GET, POST, HEAD, DELETE and PUT request + // methods are supported. The |request| object will be marked as read-only + // after calling this method. + /// + /*--cef()--*/ + static CefRefPtr Create( + CefRefPtr request, + CefRefPtr client); + + /// + // Returns the request object used to create this URL request. The returned + // object is read-only and should not be modified. + /// + /*--cef()--*/ + virtual CefRefPtr GetRequest() =0; + + /// + // Returns the client. + /// + /*--cef()--*/ + virtual CefRefPtr GetClient() =0; + + /// + // Returns the request status. + /// + /*--cef(default_retval=UR_UNKNOWN)--*/ + virtual Status GetRequestStatus() =0; + + /// + // Returns the request error if status is UR_CANCELED or UR_FAILED, or 0 + // otherwise. + /// + /*--cef(default_retval=ERR_NONE)--*/ + virtual ErrorCode GetRequestError() =0; + + /// + // Returns the response, or NULL if no response information is available. + // Response information will only be available after the upload has completed. + // The returned object is read-only and should not be modified. + /// + /*--cef()--*/ + virtual CefRefPtr GetResponse() =0; + + /// + // Cancel the request. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + +/// +// Interface that should be implemented by the CefURLRequest client. The +// methods of this class will be called on the same thread that created the +// request. +/// +/*--cef(source=client)--*/ +class CefURLRequestClient : public virtual CefBase { + public: + /// + // Notifies the client that the request has completed. Use the + // CefURLRequest::GetRequestStatus method to determine if the request was + // successful or not. + /// + /*--cef()--*/ + virtual void OnRequestComplete(CefRefPtr request) =0; + + /// + // Notifies the client of upload progress. |current| denotes the number of + // bytes sent so far and |total| is the total size of uploading data (or -1 if + // chunked upload is enabled). This method will only be called if the + // UR_FLAG_REPORT_UPLOAD_PROGRESS flag is set on the request. + /// + /*--cef()--*/ + virtual void OnUploadProgress(CefRefPtr request, + uint64 current, + uint64 total) =0; + + /// + // Notifies the client of download progress. |current| denotes the number of + // bytes received up to the call and |total| is the expected total size of the + // response (or -1 if not determined). + /// + /*--cef()--*/ + virtual void OnDownloadProgress(CefRefPtr request, + uint64 current, + uint64 total) =0; + + /// + // Called when some part of the response is read. |data| contains the current + // bytes received since the last call. This method will not be called if the + // UR_FLAG_NO_DOWNLOAD_DATA flag is set on the request. + /// + /*--cef()--*/ + virtual void OnDownloadData(CefRefPtr request, + const void* data, + size_t data_length) =0; +}; + +#endif // CEF_INCLUDE_CEF_URLREQUEST_H_ diff --git a/include/internal/cef_tuple.h b/include/internal/cef_tuple.h index d9a1a2c96..c2cdf7058 100644 --- a/include/internal/cef_tuple.h +++ b/include/internal/cef_tuple.h @@ -57,6 +57,10 @@ #define CEF_INCLUDE_INTERNAL_CEF_TUPLE_H_ #pragma once +// If base/tuple.h is included first then exclude this file. This is to +// facilitate the use of both base/bind.h and cef_runnable.h in unit tests. +#ifndef BASE_TUPLE_H__ + #if defined(OS_CHROMEOS) // To troubleshoot crosbug.com/7327. #include "base/logging.h" @@ -1079,4 +1083,6 @@ inline void DispatchToMethod(ObjT* obj, Method method, &out->a, &out->b, &out->c, &out->d, &out->e); } +#endif // BASE_TUPLE_H__ + #endif // CEF_INCLUDE_INTERNAL_CEF_TUPLE_H_ diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index 7c80407f5..eb99c1e0b 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -565,7 +565,8 @@ enum cef_storage_type_t { // Supported error code values. See net\base\net_error_list.h for complete // descriptions of the error codes. /// -enum cef_handler_errorcode_t { +enum cef_errorcode_t { + ERR_NONE = 0, ERR_FAILED = -2, ERR_ABORTED = -3, ERR_INVALID_ARGUMENT = -4, @@ -646,14 +647,95 @@ enum cef_postdataelement_type_t { PDE_TYPE_FILE, }; -enum cef_weburlrequest_flags_t { - WUR_FLAG_NONE = 0, - WUR_FLAG_SKIP_CACHE = 0x1, - WUR_FLAG_ALLOW_CACHED_CREDENTIALS = 0x2, - WUR_FLAG_ALLOW_COOKIES = 0x4, - WUR_FLAG_REPORT_UPLOAD_PROGRESS = 0x8, - WUR_FLAG_REPORT_LOAD_TIMING = 0x10, - WUR_FLAG_REPORT_RAW_HEADERS = 0x20 +/// +// Flags used to customize the behavior of CefURLRequest. +/// +enum cef_urlrequest_flags_t { + /// + // Default behavior. + /// + UR_FLAG_NONE = 0, + + /// + // If set the cache will be skipped when handling the request. + /// + UR_FLAG_SKIP_CACHE = 1 << 0, + + /// + // If set user name, password, and cookies may be sent with the request. + /// + UR_FLAG_ALLOW_CACHED_CREDENTIALS = 1 << 1, + + /// + // If set cookies may be sent with the request and saved from the response. + // UR_FLAG_ALLOW_CACHED_CREDENTIALS must also be set. + /// + UR_FLAG_ALLOW_COOKIES = 1 << 2, + + /// + // If set upload progress events will be generated when a request has a body. + /// + UR_FLAG_REPORT_UPLOAD_PROGRESS = 1 << 3, + + /// + // If set load timing info will be collected for the request. + /// + UR_FLAG_REPORT_LOAD_TIMING = 1 << 4, + + /// + // If set the headers sent and received for the request will be recorded. + /// + UR_FLAG_REPORT_RAW_HEADERS = 1 << 5, + + /// + // If set the CefURLRequestClient::OnDownloadData method will not be called. + /// + UR_FLAG_NO_DOWNLOAD_DATA = 1 << 6, + + /// + // If set 5XX redirect errors will be propagated to the observer instead of + // automatically re-tried. This currently only applies for requests + // originated in the browser process. + /// + UR_FLAG_NO_RETRY_ON_5XX = 1 << 7, +}; + +/// +// Flags that represent CefURLRequest status. +/// +enum cef_urlrequest_status_t { + /// + // Unknown status. + /// + UR_UNKNOWN = 0, + + /// + // Request succeeded. + /// + UR_SUCCESS, + + /// + // An IO request is pending, and the caller will be informed when it is + // completed. + /// + UR_IO_PENDING, + + /// + // Request was successful but was handled by an external program, so there + // is no response data. This usually means the current page should not be + // navigated, but no error should be displayed. + /// + UR_HANDLED_EXTERNALLY, + + /// + // Request was canceled programatically. + /// + UR_CANCELED, + + /// + // Request failed for some reason. + /// + UR_FAILED, }; /// diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index 80e424e7d..92491d29c 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -1462,7 +1462,7 @@ void CefBrowserHostImpl::OnLoadError(CefRefPtr frame, if (handler.get()) { // Notify the handler that loading has failed. handler->OnLoadError(this, frame, - static_cast(error_code), + static_cast(error_code), CefString(error_description), url.spec()); } diff --git a/libcef/browser/browser_urlrequest_impl.cc b/libcef/browser/browser_urlrequest_impl.cc new file mode 100644 index 000000000..c6742572c --- /dev/null +++ b/libcef/browser/browser_urlrequest_impl.cc @@ -0,0 +1,442 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that can +// be found in the LICENSE file. + +#include "libcef/browser/browser_urlrequest_impl.h" + +#include + +#include "libcef/browser/browser_context.h" +#include "libcef/browser/context.h" +#include "libcef/browser/thread_util.h" +#include "libcef/common/http_header_utils.h" +#include "libcef/common/request_impl.h" +#include "libcef/common/response_impl.h" + +#include "base/logging.h" +#include "base/message_loop.h" +#include "base/string_util.h" +#include "content/public/common/url_fetcher.h" +#include "net/base/load_flags.h" +#include "net/http/http_response_headers.h" +#include "net/url_request/url_fetcher_delegate.h" +#include "net/url_request/url_request_status.h" + + +namespace { + +class CefURLFetcherDelegate : public net::URLFetcherDelegate { + public: + CefURLFetcherDelegate(CefBrowserURLRequest::Context* context, + int request_flags); + virtual ~CefURLFetcherDelegate(); + + // net::URLFetcherDelegate methods. + virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; + virtual void OnURLFetchDownloadProgress(const net::URLFetcher* source, + int64 current, int64 total) OVERRIDE; + virtual void OnURLFetchDownloadData(const net::URLFetcher* source, + scoped_ptr download_data) + OVERRIDE; + virtual bool ShouldSendDownloadData() OVERRIDE; + virtual void OnURLFetchUploadProgress(const net::URLFetcher* source, + int64 current, int64 total) OVERRIDE; + + private: + // The context_ pointer will outlive this object. + CefBrowserURLRequest::Context* context_; + int request_flags_; +}; + +} // namespace + + +// CefBrowserURLRequest::Context ---------------------------------------------- + +class CefBrowserURLRequest::Context + : public base::RefCountedThreadSafe { + public: + Context(CefRefPtr url_request, + CefRefPtr request, + CefRefPtr client) + : url_request_(url_request), + request_(request), + client_(client), + message_loop_proxy_(MessageLoop::current()->message_loop_proxy()), + status_(UR_IO_PENDING), + error_code_(ERR_NONE), + upload_data_size_(0), + got_upload_progress_complete_(false) { + // Mark the request as read-only. + static_cast(request_.get())->SetReadOnly(true); + } + + virtual ~Context() { + if (fetcher_.get()) { + // Delete the fetcher object on the thread that created it. + message_loop_proxy_->DeleteSoon(FROM_HERE, fetcher_.release()); + } + } + + inline bool CalledOnValidThread() { + return message_loop_proxy_->BelongsToCurrentThread(); + } + + bool Start() { + DCHECK(CalledOnValidThread()); + + GURL url = GURL(request_->GetURL().ToString()); + if (!url.is_valid()) + return false; + + std::string method = request_->GetMethod(); + StringToLowerASCII(&method); + net::URLFetcher::RequestType request_type = net::URLFetcher::GET; + if (LowerCaseEqualsASCII(method, "get")) { + } else if (LowerCaseEqualsASCII(method, "post")) { + request_type = net::URLFetcher::POST; + } else if (LowerCaseEqualsASCII(method, "head")) { + request_type = net::URLFetcher::HEAD; + } else if (LowerCaseEqualsASCII(method, "delete")) { + request_type = net::URLFetcher::DELETE_REQUEST; + } else if (LowerCaseEqualsASCII(method, "put")) { + request_type = net::URLFetcher::PUT; + } else { + NOTREACHED() << "invalid request type"; + return false; + } + + fetcher_delegate_.reset( + new CefURLFetcherDelegate(this, request_->GetFlags())); + + fetcher_.reset(content::URLFetcher::Create(url, request_type, + fetcher_delegate_.get())); + fetcher_->SetRequestContext( + _Context->browser_context()->GetRequestContext()); + + CefRequest::HeaderMap headerMap; + request_->GetHeaderMap(headerMap); + + // Extract the Referer header value. + { + CefString referrerStr; + referrerStr.FromASCII(net::HttpRequestHeaders::kReferer); + CefRequest::HeaderMap::iterator it = headerMap.find(referrerStr); + if (it == headerMap.end()) { + fetcher_->SetReferrer(""); + } else { + fetcher_->SetReferrer(it->second); + headerMap.erase(it); + } + } + + std::string content_type; + + // Extract the Content-Type header value. + { + CefString contentTypeStr; + contentTypeStr.FromASCII(net::HttpRequestHeaders::kContentType); + CefRequest::HeaderMap::iterator it = headerMap.find(contentTypeStr); + if (it != headerMap.end()) { + content_type = it->second; + headerMap.erase(it); + } + } + + int64 upload_data_size = 0; + + CefRefPtr post_data = request_->GetPostData(); + if (post_data.get()) { + CefPostData::ElementVector elements; + post_data->GetElements(elements); + if (elements.size() == 1 && elements[0]->GetType() == PDE_TYPE_BYTES) { + CefPostDataElementImpl* impl = + static_cast(elements[0].get()); + + // Default to URL encoding if not specified. + if (content_type.empty()) + content_type = "application/x-www-form-urlencoded"; + + upload_data_size = impl->GetBytesCount(); + fetcher_->SetUploadData(content_type, + std::string(static_cast(impl->GetBytes()), + upload_data_size)); + } else { + NOTIMPLEMENTED() << "multi-part form data is not supported"; + } + } + + std::string first_party_for_cookies = request_->GetFirstPartyForCookies(); + if (!first_party_for_cookies.empty()) + fetcher_->SetFirstPartyForCookies(GURL(first_party_for_cookies)); + + int cef_flags = request_->GetFlags(); + + if (cef_flags & UR_FLAG_NO_RETRY_ON_5XX) + fetcher_->SetAutomaticallyRetryOn5xx(false); + + int load_flags = 0; + + if (cef_flags & UR_FLAG_SKIP_CACHE) + load_flags |= net::LOAD_BYPASS_CACHE; + + if (cef_flags & UR_FLAG_ALLOW_CACHED_CREDENTIALS) { + if (!(cef_flags & UR_FLAG_ALLOW_COOKIES)) { + load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; + load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; + } + } else { + load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA; + load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; + load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; + } + + if (cef_flags & UR_FLAG_REPORT_UPLOAD_PROGRESS) { + load_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS; + upload_data_size_ = upload_data_size; + } + + if (cef_flags & UR_FLAG_REPORT_LOAD_TIMING) + load_flags |= net::LOAD_ENABLE_LOAD_TIMING; + + if (cef_flags & UR_FLAG_REPORT_RAW_HEADERS) + load_flags |= net::LOAD_REPORT_RAW_HEADERS; + + fetcher_->SetLoadFlags(load_flags); + + fetcher_->SetExtraRequestHeaders( + HttpHeaderUtils::GenerateHeaders(headerMap)); + + fetcher_->Start(); + + return true; + } + + void Cancel() { + DCHECK(CalledOnValidThread()); + + // The request may already be complete. + if (!fetcher_.get()) + return; + + // Cancel the fetch by deleting the fetcher. + fetcher_.reset(NULL); + + status_ = UR_CANCELED; + error_code_ = ERR_ABORTED; + OnComplete(); + } + + void OnComplete() { + DCHECK(CalledOnValidThread()); + + if (fetcher_.get()) { + const net::URLRequestStatus& status = fetcher_->GetStatus(); + + if (status.is_success()) + NotifyUploadProgressIfNecessary(); + + switch (status.status()) { + case net::URLRequestStatus::SUCCESS: + status_ = UR_SUCCESS; + break; + case net::URLRequestStatus::IO_PENDING: + status_ = UR_IO_PENDING; + break; + case net::URLRequestStatus::HANDLED_EXTERNALLY: + status_ = UR_HANDLED_EXTERNALLY; + break; + case net::URLRequestStatus::CANCELED: + status_ = UR_CANCELED; + break; + case net::URLRequestStatus::FAILED: + status_ = UR_FAILED; + break; + } + + error_code_ = static_cast(status.error()); + + response_ = new CefResponseImpl(); + CefResponseImpl* responseImpl = + static_cast(response_.get()); + + net::HttpResponseHeaders* headers = fetcher_->GetResponseHeaders(); + if (headers) + responseImpl->SetResponseHeaders(*headers); + + responseImpl->SetReadOnly(true); + } + + DCHECK(url_request_.get()); + client_->OnRequestComplete(url_request_.get()); + + if (fetcher_.get()) + fetcher_.reset(NULL); + + // This may result in the Context object being deleted. + url_request_ = NULL; + } + + void OnDownloadProgress(int64 current, int64 total) { + DCHECK(CalledOnValidThread()); + DCHECK(url_request_.get()); + + NotifyUploadProgressIfNecessary(); + + client_->OnDownloadProgress(url_request_.get(), current, total); + } + + void OnDownloadData(scoped_ptr download_data) { + DCHECK(CalledOnValidThread()); + DCHECK(url_request_.get()); + client_->OnDownloadData(url_request_.get(), download_data->c_str(), + download_data->length()); + } + + void OnUploadProgress(int64 current, int64 total) { + DCHECK(CalledOnValidThread()); + DCHECK(url_request_.get()); + if (current == total) + got_upload_progress_complete_ = true; + client_->OnUploadProgress(url_request_.get(), current, total); + } + + CefRefPtr request() { return request_; } + CefRefPtr client() { return client_; } + CefURLRequest::Status status() { return status_; } + CefURLRequest::ErrorCode error_code() { return error_code_; } + CefRefPtr response() { return response_; } + + private: + void NotifyUploadProgressIfNecessary() { + if (!got_upload_progress_complete_ && upload_data_size_ > 0) { + // URLFetcher sends upload notifications using a timer and will not send + // a notification if the request completes too quickly. We therefore + // send the notification here if necessary. + client_->OnUploadProgress(url_request_.get(), upload_data_size_, + upload_data_size_); + got_upload_progress_complete_ = true; + } + } + + // Members only accessed on the initialization thread. + CefRefPtr url_request_; + CefRefPtr request_; + CefRefPtr client_; + scoped_refptr message_loop_proxy_; + scoped_ptr fetcher_; + scoped_ptr fetcher_delegate_; + CefURLRequest::Status status_; + CefURLRequest::ErrorCode error_code_; + CefRefPtr response_; + int64 upload_data_size_; + bool got_upload_progress_complete_; +}; + + +// CefURLFetcherDelegate ------------------------------------------------------ + +namespace { + +CefURLFetcherDelegate::CefURLFetcherDelegate( + CefBrowserURLRequest::Context* context, int request_flags) + : context_(context), + request_flags_(request_flags) { +} + +CefURLFetcherDelegate::~CefURLFetcherDelegate() { +} + +void CefURLFetcherDelegate::OnURLFetchComplete( + const net::URLFetcher* source) { + context_->OnComplete(); +} + +void CefURLFetcherDelegate::OnURLFetchDownloadProgress( + const net::URLFetcher* source, + int64 current, int64 total) { + context_->OnDownloadProgress(current, total); +} + +void CefURLFetcherDelegate::OnURLFetchDownloadData( + const net::URLFetcher* source, + scoped_ptr download_data) { + context_->OnDownloadData(download_data.Pass()); +} + +bool CefURLFetcherDelegate::ShouldSendDownloadData() { + return !(request_flags_ & UR_FLAG_NO_DOWNLOAD_DATA); +} + +void CefURLFetcherDelegate::OnURLFetchUploadProgress( + const net::URLFetcher* source, + int64 current, int64 total) { + if (request_flags_ & UR_FLAG_REPORT_UPLOAD_PROGRESS) + context_->OnUploadProgress(current, total); +} + +} // namespace + + +// CefBrowserURLRequest ------------------------------------------------------- + +CefBrowserURLRequest::CefBrowserURLRequest( + CefRefPtr request, + CefRefPtr client) { + context_ = new Context(this, request, client); +} + +CefBrowserURLRequest::~CefBrowserURLRequest() { +} + +bool CefBrowserURLRequest::Start() { + if (!VerifyContext()) + return false; + return context_->Start(); +} + +CefRefPtr CefBrowserURLRequest::GetRequest() { + if (!VerifyContext()) + return NULL; + return context_->request(); +} + +CefRefPtr CefBrowserURLRequest::GetClient() { + if (!VerifyContext()) + return NULL; + return context_->client(); +} + +CefURLRequest::Status CefBrowserURLRequest::GetRequestStatus() { + if (!VerifyContext()) + return UR_UNKNOWN; + return context_->status(); +} + +CefURLRequest::ErrorCode CefBrowserURLRequest::GetRequestError() { + if (!VerifyContext()) + return ERR_NONE; + return context_->error_code(); +} + +CefRefPtr CefBrowserURLRequest::GetResponse() { + if (!VerifyContext()) + return NULL; + return context_->response(); +} + +void CefBrowserURLRequest::Cancel() { + if (!VerifyContext()) + return; + return context_->Cancel(); +} + +bool CefBrowserURLRequest::VerifyContext() { + DCHECK(context_.get()); + if (!context_->CalledOnValidThread()) { + NOTREACHED() << "called on invalid thread"; + return false; + } + + return true; +} diff --git a/libcef/browser/browser_urlrequest_impl.h b/libcef/browser/browser_urlrequest_impl.h new file mode 100644 index 000000000..e1e186940 --- /dev/null +++ b/libcef/browser/browser_urlrequest_impl.h @@ -0,0 +1,37 @@ +// Copyright (c) 2012 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_BROWSER_URLREQUEST_IMPL_H_ +#define CEF_LIBCEF_BROWSER_BROWSER_URLREQUEST_IMPL_H_ + +#include "include/cef_urlrequest.h" +#include "base/memory/ref_counted.h" + +class CefBrowserURLRequest : public CefURLRequest { + public: + class Context; + + CefBrowserURLRequest(CefRefPtr request, + CefRefPtr client); + virtual ~CefBrowserURLRequest(); + + bool Start(); + + // CefURLRequest methods. + virtual CefRefPtr GetRequest() OVERRIDE; + virtual CefRefPtr GetClient() OVERRIDE; + virtual Status GetRequestStatus() OVERRIDE; + virtual ErrorCode GetRequestError() OVERRIDE; + virtual CefRefPtr GetResponse() OVERRIDE; + virtual void Cancel() OVERRIDE; + + private: + bool VerifyContext(); + + scoped_refptr context_; + + IMPLEMENT_REFCOUNTING(CefBrowserURLRequest); +}; + +#endif // CEF_LIBCEF_BROWSER_BROWSER_URLREQUEST_IMPL_H_ diff --git a/libcef/browser/context.cc b/libcef/browser/context.cc index d46db29ad..bd99684e6 100644 --- a/libcef/browser/context.cc +++ b/libcef/browser/context.cc @@ -216,14 +216,14 @@ bool CefContext::Initialize(const CefMainArgs& args, if (exit_code >= 0) return false; - // Run the process. Results in a call to CefMainDelegate::RunKnownProcess() - // which will create the browser runner and message loop without blocking. + // Run the process. Results in a call to CefMainDelegate::RunProcess() which + // will create the browser runner and message loop without blocking. exit_code = main_runner_->Run(); initialized_ = true; - // Perform DevTools scheme registration when CEF initialization is complete. - CEF_POST_TASK(CEF_UIT, base::Bind(&RegisterDevToolsSchemeHandler)); + // Continue initialization on the UI thread. + CEF_POST_TASK(CEF_UIT, base::Bind(&CefContext::OnContextInitialized, this)); return true; } @@ -346,6 +346,22 @@ CefDevToolsDelegate* CefContext::devtools_delegate() const { devtools_delegate(); } +void CefContext::OnContextInitialized() { + CEF_REQUIRE_UIT(); + + // Perform DevTools scheme registration. + RegisterDevToolsSchemeHandler(); + + // Notify the handler. + CefRefPtr app = application(); + if (app.get()) { + CefRefPtr handler = + app->GetBrowserProcessHandler(); + if (handler.get()) + handler->OnContextInitialized(); + } +} + void CefContext::FinishShutdownOnUIThread( base::WaitableEvent* uithread_shutdown_event) { CEF_REQUIRE_UIT(); diff --git a/libcef/browser/context.h b/libcef/browser/context.h index 588c9827d..874a7e3c6 100644 --- a/libcef/browser/context.h +++ b/libcef/browser/context.h @@ -69,6 +69,8 @@ class CefContext : public CefBase { CefDevToolsDelegate* devtools_delegate() const; private: + void OnContextInitialized(); + // Performs shutdown actions that need to occur on the UI thread before any // threads are destroyed. void FinishShutdownOnUIThread(base::WaitableEvent* uithread_shutdown_event); diff --git a/libcef/browser/cookie_manager_impl.cc b/libcef/browser/cookie_manager_impl.cc index 037457ba4..780f69fc6 100644 --- a/libcef/browser/cookie_manager_impl.cc +++ b/libcef/browser/cookie_manager_impl.cc @@ -14,10 +14,12 @@ #include "base/bind.h" #include "base/file_util.h" +#include "base/format_macros.h" #include "base/logging.h" #include "base/threading/thread_restrictions.h" #include "chrome/browser/net/sqlite_persistent_cookie_store.h" #include "googleurl/src/gurl.h" +#include "net/cookies/cookie_util.h" #include "net/url_request/url_request_context.h" namespace { @@ -40,18 +42,7 @@ class VisitCookiesCallback : public base::RefCounted { 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(); - cef_time_from_basetime(cc.CreationDate(), cookie.creation); - cef_time_from_basetime(cc.LastAccessDate(), cookie.last_access); - cookie.has_expires = cc.DoesExpire(); - if (cookie.has_expires) - cef_time_from_basetime(cc.ExpiryDate(), cookie.expires); + CefCookieManagerImpl::GetCefCookie(cc, cookie); bool deleteCookie = false; bool keepLooping = visitor_->Visit(cookie, count, total, deleteCookie); @@ -69,6 +60,80 @@ class VisitCookiesCallback : public base::RefCounted { CefRefPtr visitor_; }; + +// Methods extracted from net/cookies/cookie_monster.cc + +// Determine the cookie domain to use for setting the specified cookie. +bool GetCookieDomain(const GURL& url, + const net::CookieMonster::ParsedCookie& pc, + std::string* result) { + std::string domain_string; + if (pc.HasDomain()) + domain_string = pc.Domain(); + return net::cookie_util::GetCookieDomainWithString(url, domain_string, + result); +} + +std::string CanonPathWithString(const GURL& url, + const std::string& path_string) { + // The RFC says the path should be a prefix of the current URL path. + // However, Mozilla allows you to set any path for compatibility with + // broken websites. We unfortunately will mimic this behavior. We try + // to be generous and accept cookies with an invalid path attribute, and + // default the path to something reasonable. + + // The path was supplied in the cookie, we'll take it. + if (!path_string.empty() && path_string[0] == '/') + return path_string; + + // The path was not supplied in the cookie or invalid, we will default + // to the current URL path. + // """Defaults to the path of the request URL that generated the + // Set-Cookie response, up to, but not including, the + // right-most /.""" + // How would this work for a cookie on /? We will include it then. + const std::string& url_path = url.path(); + + size_t idx = url_path.find_last_of('/'); + + // The cookie path was invalid or a single '/'. + if (idx == 0 || idx == std::string::npos) + return std::string("/"); + + // Return up to the rightmost '/'. + return url_path.substr(0, idx); +} + +std::string CanonPath(const GURL& url, + const net::CookieMonster::ParsedCookie& pc) { + std::string path_string; + if (pc.HasPath()) + path_string = pc.Path(); + return CanonPathWithString(url, path_string); +} + +base::Time CanonExpiration(const net::CookieMonster::ParsedCookie& pc, + const base::Time& current) { + // First, try the Max-Age attribute. + uint64 max_age = 0; + if (pc.HasMaxAge() && +#ifdef COMPILER_MSVC + sscanf_s( +#else + sscanf( +#endif + pc.MaxAge().c_str(), " %" PRIu64, &max_age) == 1) { + return current + base::TimeDelta::FromSeconds(max_age); + } + + // Try the Expires attribute. + if (pc.HasExpires()) + return net::CookieMonster::ParseCookieTime(pc.Expires()); + + // Invalid or no expiration, persistent cookie. + return base::Time(); +} + } // namespace @@ -89,12 +154,34 @@ void CefCookieManagerImpl::Initialize(const CefString& path) { void CefCookieManagerImpl::SetSupportedSchemes( const std::vector& schemes) { if (CEF_CURRENTLY_ON_IOT()) { - if (schemes.empty()) + if (!cookie_monster_) return; + if (is_global_) { + // Global changes are handled by the request context. + CefURLRequestContextGetter* getter = + static_cast( + _Context->browser_context()->GetRequestContext()); + + std::vector scheme_vec; + std::vector::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 scheme_set; - std::vector::const_iterator it = schemes.begin(); - for (; it != schemes.end(); ++it) + std::vector::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()]; @@ -116,6 +203,9 @@ void CefCookieManagerImpl::SetSupportedSchemes( bool CefCookieManagerImpl::VisitAllCookies( CefRefPtr visitor) { if (CEF_CURRENTLY_ON_IOT()) { + if (!cookie_monster_) + return false; + scoped_refptr callback( new VisitCookiesCallback(cookie_monster_, visitor)); @@ -135,6 +225,9 @@ bool CefCookieManagerImpl::VisitUrlCookies( const CefString& url, bool includeHttpOnly, CefRefPtr visitor) { if (CEF_CURRENTLY_ON_IOT()) { + if (!cookie_monster_) + return false; + net::CookieOptions options; if (includeHttpOnly) options.set_include_httponly(); @@ -159,6 +252,9 @@ bool CefCookieManagerImpl::SetCookie(const CefString& url, const CefCookie& cookie) { CEF_REQUIRE_IOT_RETURN(false); + if (!cookie_monster_) + return false; + GURL gurl = GURL(url.ToString()); if (!gurl.is_valid()) return false; @@ -182,6 +278,9 @@ bool CefCookieManagerImpl::DeleteCookies(const CefString& url, const CefString& cookie_name) { CEF_REQUIRE_IOT_RETURN(false); + if (!cookie_monster_) + return false; + if (url.empty()) { // Delete all cookies. cookie_monster_->DeleteAllAsync(net::CookieMonster::DeleteCallback()); @@ -246,6 +345,9 @@ bool CefCookieManagerImpl::SetStoragePath(const CefString& path) { // longer referenced. cookie_monster_ = new net::CookieMonster(persistent_store.get(), NULL); storage_path_ = new_path; + + // Restore the previously supported schemes. + SetSupportedSchemes(supported_schemes_); } else { // Execute on the IO thread. CEF_POST_TASK(CEF_IOT, @@ -258,15 +360,68 @@ bool CefCookieManagerImpl::SetStoragePath(const CefString& path) { void CefCookieManagerImpl::SetGlobal() { if (CEF_CURRENTLY_ON_IOT()) { - cookie_monster_ = _Context->browser_context()->GetRequestContext()-> - GetURLRequestContext()->cookie_store()->GetCookieMonster(); - DCHECK(cookie_monster_); + if (_Context->browser_context()) { + cookie_monster_ = _Context->browser_context()->GetRequestContext()-> + GetURLRequestContext()->cookie_store()->GetCookieMonster(); + DCHECK(cookie_monster_); + } } else { // Execute on the IO thread. CEF_POST_TASK(CEF_IOT, base::Bind(&CefCookieManagerImpl::SetGlobal, this)); } } +// static +bool CefCookieManagerImpl::GetCefCookie( + const net::CookieMonster::CanonicalCookie& cc, + CefCookie& cookie) { + CefString(&cookie.name).FromString(cc.Name()); + CefString(&cookie.value).FromString(cc.Value()); + CefString(&cookie.domain).FromString(cc.Domain()); + CefString(&cookie.path).FromString(cc.Path()); + cookie.secure = cc.IsSecure(); + cookie.httponly = cc.IsHttpOnly(); + cef_time_from_basetime(cc.CreationDate(), cookie.creation); + cef_time_from_basetime(cc.LastAccessDate(), cookie.last_access); + cookie.has_expires = cc.DoesExpire(); + if (cookie.has_expires) + cef_time_from_basetime(cc.ExpiryDate(), cookie.expires); + + return true; +} + +// static +bool CefCookieManagerImpl::GetCefCookie(const GURL& url, + const std::string& cookie_line, + CefCookie& cookie) { + // Parse the cookie. + net::CookieMonster::ParsedCookie pc(cookie_line); + if (!pc.IsValid()) + return false; + + std::string cookie_domain; + if (!GetCookieDomain(url, pc, &cookie_domain)) + return false; + + std::string cookie_path = CanonPath(url, pc); + base::Time creation_time = base::Time::Now(); + base::Time cookie_expires = CanonExpiration(pc, creation_time); + + CefString(&cookie.name).FromString(pc.Name()); + CefString(&cookie.value).FromString(pc.Value()); + CefString(&cookie.domain).FromString(cookie_domain); + CefString(&cookie.path).FromString(cookie_path); + cookie.secure = pc.IsSecure(); + cookie.httponly = pc.IsHttpOnly(); + cef_time_from_basetime(creation_time, cookie.creation); + cef_time_from_basetime(creation_time, cookie.last_access); + cookie.has_expires = !cookie_expires.is_null(); + if (cookie.has_expires) + cef_time_from_basetime(cookie_expires, cookie.expires); + + return true; +} + // CefCookieManager methods ---------------------------------------------------- diff --git a/libcef/browser/cookie_manager_impl.h b/libcef/browser/cookie_manager_impl.h index bcca4cf3f..0c0cdf685 100644 --- a/libcef/browser/cookie_manager_impl.h +++ b/libcef/browser/cookie_manager_impl.h @@ -32,12 +32,18 @@ class CefCookieManagerImpl : public CefCookieManager { net::CookieMonster* cookie_monster() { return cookie_monster_; } + static bool GetCefCookie(const net::CookieMonster::CanonicalCookie& cc, + CefCookie& cookie); + static bool GetCefCookie(const GURL& url, const std::string& cookie_line, + CefCookie& cookie); + private: void SetGlobal(); scoped_refptr cookie_monster_; bool is_global_; FilePath storage_path_; + std::vector supported_schemes_; IMPLEMENT_REFCOUNTING(CefCookieManagerImpl); }; diff --git a/libcef/browser/resource_request_job.cc b/libcef/browser/resource_request_job.cc index 53f1db543..5f75bfbab 100644 --- a/libcef/browser/resource_request_job.cc +++ b/libcef/browser/resource_request_job.cc @@ -9,6 +9,7 @@ #include #include "include/cef_callback.h" +#include "libcef/browser/cookie_manager_impl.h" #include "libcef/browser/thread_util.h" #include "libcef/common/request_impl.h" #include "libcef/common/response_impl.h" @@ -138,7 +139,7 @@ CefResourceRequestJob::~CefResourceRequestJob() { void CefResourceRequestJob::Start() { CEF_REQUIRE_IOT(); - cef_request_ = CefRequest::CreateRequest(); + cef_request_ = CefRequest::Create(); // Populate the request data. static_cast(cef_request_.get())->Set(request_); @@ -255,6 +256,15 @@ void CefResourceRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { info->headers = GetResponseHeaders(); } +bool CefResourceRequestJob::GetResponseCookies( + std::vector* cookies) { + CEF_REQUIRE_IOT(); + + cookies->clear(); + FetchResponseCookies(cookies); + return true; +} + bool CefResourceRequestJob::IsRedirectResponse(GURL* location, int* http_status_code) { CEF_REQUIRE_IOT(); @@ -360,7 +370,20 @@ void CefResourceRequestJob::DoLoadCookies() { void CefResourceRequestJob::CheckCookiePolicyAndLoad( const net::CookieList& cookie_list) { - if (CanGetCookies(cookie_list)) + bool can_get_cookies = CanGetCookies(cookie_list); + if (can_get_cookies) { + net::CookieList::const_iterator it = cookie_list.begin(); + for (; it != cookie_list.end(); ++it) { + CefCookie cookie; + if (!CefCookieManagerImpl::GetCefCookie(*it, cookie) || + !handler_->CanGetCookie(cookie)) { + can_get_cookies = false; + break; + } + } + } + + if (can_get_cookies) DoLoadCookies(); else DoStartTransaction(); @@ -446,8 +469,19 @@ void CefResourceRequestJob::SaveNextCookie() { net::CookieOptions options; options.set_include_httponly(); - if (CanSetCookie( - response_cookies_[response_cookies_save_index_], &options)) { + bool can_set_cookie = CanSetCookie( + response_cookies_[response_cookies_save_index_], &options); + if (can_set_cookie) { + CefCookie cookie; + if (CefCookieManagerImpl::GetCefCookie(request_->url(), + response_cookies_[response_cookies_save_index_], cookie)) { + can_set_cookie = handler_->CanSetCookie(cookie); + } else { + can_set_cookie = false; + } + } + + if (can_set_cookie) { request_->context()->cookie_store()->SetCookieWithOptionsAsync( request_->url(), response_cookies_[response_cookies_save_index_], options, base::Bind(&CefResourceRequestJob::OnCookieSaved, diff --git a/libcef/browser/resource_request_job.h b/libcef/browser/resource_request_job.h index c41dcf77d..b66115c87 100644 --- a/libcef/browser/resource_request_job.h +++ b/libcef/browser/resource_request_job.h @@ -35,6 +35,7 @@ class CefResourceRequestJob : public net::URLRequestJob { virtual bool ReadRawData(net::IOBuffer* dest, int dest_size, int* bytes_read) OVERRIDE; virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE; + virtual bool GetResponseCookies(std::vector* cookies) OVERRIDE; virtual bool IsRedirectResponse(GURL* location, int* http_status_code) OVERRIDE; virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; diff --git a/libcef/browser/scheme_impl.cc b/libcef/browser/scheme_impl.cc index eb959c8bb..631be6d2a 100644 --- a/libcef/browser/scheme_impl.cc +++ b/libcef/browser/scheme_impl.cc @@ -45,10 +45,6 @@ using net::URLRequestStatus; namespace { -bool IsInternalScheme(const std::string& scheme) { - return (scheme == kChromeDevToolsScheme); -} - bool IsStandardScheme(const std::string& scheme) { url_parse::Component scheme_comp(0, scheme.length()); return url_util::IsStandard(scheme.c_str(), scheme_comp); @@ -231,21 +227,19 @@ class CefUrlRequestManager { if (factory) { CefRefPtr browser = CefBrowserHostImpl::GetBrowserForRequest(request); - if (browser.get() || IsInternalScheme(request->url().scheme())) { - // Populate the request data. - CefRefPtr requestPtr(new CefRequestImpl()); - requestPtr->Set(request); + CefRefPtr frame; + if (browser.get()) + frame = browser->GetFrameForRequest(request); - CefRefPtr frame; - if (browser.get()) - frame = browser->GetFrameForRequest(request); + // Populate the request data. + CefRefPtr requestPtr(new CefRequestImpl()); + requestPtr->Set(request); - // Call the handler factory to create the handler for the request. - CefRefPtr handler = - factory->Create(browser.get(), frame, scheme, requestPtr.get()); - if (handler.get()) - job = new CefResourceRequestJob(request, handler); - } + // Call the handler factory to create the handler for the request. + CefRefPtr handler = + factory->Create(browser.get(), frame, scheme, requestPtr.get()); + if (handler.get()) + job = new CefResourceRequestJob(request, handler); } if (!job && IsBuiltinScheme(scheme)) { diff --git a/libcef/browser/url_request_context_getter.cc b/libcef/browser/url_request_context_getter.cc index af9c20a75..585b09d34 100644 --- a/libcef/browser/url_request_context_getter.cc +++ b/libcef/browser/url_request_context_getter.cc @@ -169,14 +169,18 @@ net::URLRequestContext* CefURLRequestContextGetter::GetURLRequestContext() { CefRefPtr app = _Context->application(); if (app.get()) { - CefRefPtr handler = app->GetProxyHandler(); - if (handler) { - // The client will provide proxy resolution. - CreateProxyConfigService(); - storage_->set_proxy_service( - new net::ProxyService(proxy_config_service_.release(), - new CefProxyResolver(handler), NULL)); - proxy_service_set = true; + CefRefPtr handler = + app->GetBrowserProcessHandler(); + if (handler.get()) { + CefRefPtr proxy_handler = handler->GetProxyHandler(); + if (proxy_handler.get()) { + // The client will provide proxy resolution. + CreateProxyConfigService(); + storage_->set_proxy_service( + new net::ProxyService(proxy_config_service_.release(), + new CefProxyResolver(proxy_handler), NULL)); + proxy_service_set = true; + } } } @@ -315,6 +319,37 @@ void CefURLRequestContextGetter::SetCookieStoragePath(const FilePath& path) { storage_->set_cookie_store( new net::CookieMonster(persistent_store.get(), NULL)); cookie_store_path_ = path; + + // Restore the previously supported schemes. + SetCookieSupportedSchemes(cookie_supported_schemes_); +} + +void CefURLRequestContextGetter::SetCookieSupportedSchemes( + const std::vector& schemes) { + CEF_REQUIRE_IOT(); + + cookie_supported_schemes_ = schemes; + + if (cookie_supported_schemes_.empty()) { + cookie_supported_schemes_.push_back("http"); + cookie_supported_schemes_.push_back("https"); + } + + std::set scheme_set; + std::vector::const_iterator it = + cookie_supported_schemes_.begin(); + for (; it != cookie_supported_schemes_.end(); ++it) + scheme_set.insert(*it); + + const char** arr = new const char*[scheme_set.size()]; + std::set::const_iterator it2 = scheme_set.begin(); + for (int i = 0; it2 != scheme_set.end(); ++it2, ++i) + arr[i] = it2->c_str(); + + url_request_context_->cookie_store()->GetCookieMonster()-> + SetCookieableSchemes(arr, scheme_set.size()); + + delete [] arr; } void CefURLRequestContextGetter::CreateProxyConfigService() { diff --git a/libcef/browser/url_request_context_getter.h b/libcef/browser/url_request_context_getter.h index cce2f453c..b7ba8f3f0 100644 --- a/libcef/browser/url_request_context_getter.h +++ b/libcef/browser/url_request_context_getter.h @@ -6,6 +6,9 @@ #define CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_ #pragma once +#include +#include + #include "base/compiler_specific.h" #include "base/file_path.h" #include "base/memory/ref_counted.h" @@ -39,6 +42,7 @@ class CefURLRequestContextGetter : public net::URLRequestContextGetter { net::HostResolver* host_resolver(); void SetCookieStoragePath(const FilePath& path); + void SetCookieSupportedSchemes(const std::vector& schemes); private: void CreateProxyConfigService(); @@ -54,6 +58,7 @@ class CefURLRequestContextGetter : public net::URLRequestContextGetter { scoped_ptr url_security_manager_; FilePath cookie_store_path_; + std::vector cookie_supported_schemes_; DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextGetter); }; diff --git a/libcef/browser/url_request_interceptor.cc b/libcef/browser/url_request_interceptor.cc index d5a9f0b1a..fdf32bf81 100644 --- a/libcef/browser/url_request_interceptor.cc +++ b/libcef/browser/url_request_interceptor.cc @@ -37,7 +37,7 @@ net::URLRequestJob* CefRequestInterceptor::MaybeIntercept( CefRefPtr frame = browser->GetFrameForRequest(request); // Populate the request data. - CefRefPtr req(CefRequest::CreateRequest()); + CefRefPtr req(CefRequest::Create()); static_cast(req.get())->Set(request); // Give the client an opportunity to replace the request. diff --git a/libcef/common/main_delegate.cc b/libcef/common/main_delegate.cc index 436f80224..6e29ddb6c 100644 --- a/libcef/common/main_delegate.cc +++ b/libcef/common/main_delegate.cc @@ -109,8 +109,7 @@ class CefUIThread : public base::Thread { // Use our own browser process runner. browser_runner_.reset(content::BrowserMainRunner::Create()); - // Initialize browser process state. Results in a call to - // CefBrowserMain::GetMainMessageLoop(). + // Initialize browser process state. Uses the current thread's mesage loop. int exit_code = browser_runner_->Initialize(main_function_params_); CHECK_EQ(exit_code, -1); } @@ -257,7 +256,8 @@ int CefMainDelegate::RunProcess( browser_runner_.reset(content::BrowserMainRunner::Create()); // Initialize browser process state. Results in a call to - // CefBrowserMain::GetMainMessageLoop(). + // CefBrowserMain::PreMainMessageLoopStart() which creates the UI message + // loop. int exit_code = browser_runner_->Initialize(main_function_params); if (exit_code >= 0) return exit_code; diff --git a/libcef/common/request_impl.cc b/libcef/common/request_impl.cc index 7ca0202df..830524105 100644 --- a/libcef/common/request_impl.cc +++ b/libcef/common/request_impl.cc @@ -10,15 +10,46 @@ #include "base/logging.h" #include "net/url_request/url_request.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebHTTPHeaderVisitor.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLError.h" -CefRefPtr CefRequest::CreateRequest() { + +#define CHECK_READONLY_RETURN(val) \ + if (read_only_) { \ + NOTREACHED() << "object is read only"; \ + return val; \ + } + +#define CHECK_READONLY_RETURN_VOID() \ + if (read_only_) { \ + NOTREACHED() << "object is read only"; \ + return; \ + } + + +// CefRequest ----------------------------------------------------------------- + +// static +CefRefPtr CefRequest::Create() { CefRefPtr request(new CefRequestImpl()); return request; } + +// CefRequestImpl ------------------------------------------------------------- + CefRequestImpl::CefRequestImpl() : method_("GET"), - flags_(WUR_FLAG_NONE) { + flags_(UR_FLAG_NONE), + read_only_(false) { +} + +bool CefRequestImpl::IsReadOnly() { + AutoLock lock_scope(this); + return read_only_; } CefString CefRequestImpl::GetURL() { @@ -28,6 +59,7 @@ CefString CefRequestImpl::GetURL() { void CefRequestImpl::SetURL(const CefString& url) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); url_ = url; } @@ -38,6 +70,7 @@ CefString CefRequestImpl::GetMethod() { void CefRequestImpl::SetMethod(const CefString& method) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); method_ = method; } @@ -48,6 +81,7 @@ CefRefPtr CefRequestImpl::GetPostData() { void CefRequestImpl::SetPostData(CefRefPtr postData) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); postdata_ = postData; } @@ -58,6 +92,7 @@ void CefRequestImpl::GetHeaderMap(HeaderMap& headerMap) { void CefRequestImpl::SetHeaderMap(const HeaderMap& headerMap) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); headermap_ = headerMap; } @@ -66,21 +101,20 @@ void CefRequestImpl::Set(const CefString& url, CefRefPtr postData, const HeaderMap& headerMap) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); url_ = url; method_ = method; postdata_ = postData; headermap_ = headerMap; } -#define SETBOOLFLAG(obj, flags, method, FLAG) \ - obj.method((flags & (FLAG)) == (FLAG)) - -CefRequest::RequestFlags CefRequestImpl::GetFlags() { +int CefRequestImpl::GetFlags() { AutoLock lock_scope(this); return flags_; } -void CefRequestImpl::SetFlags(RequestFlags flags) { +void CefRequestImpl::SetFlags(int flags) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); flags_ = flags; } @@ -90,11 +124,13 @@ CefString CefRequestImpl::GetFirstPartyForCookies() { } void CefRequestImpl::SetFirstPartyForCookies(const CefString& url) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); first_party_for_cookies_ = url; } void CefRequestImpl::Set(net::URLRequest* request) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); url_ = request->url().spec(); method_ = request->method(); @@ -121,7 +157,7 @@ void CefRequestImpl::Set(net::URLRequest* request) { // Transfer post data, if any net::UploadData* data = request->get_upload(); if (data) { - postdata_ = CefPostData::CreatePostData(); + postdata_ = CefPostData::Create(); static_cast(postdata_.get())->Set(*data); } else if (postdata_.get()) { postdata_ = NULL; @@ -160,6 +196,98 @@ void CefRequestImpl::Get(net::URLRequest* request) { } } +void CefRequestImpl::Set(const WebKit::WebURLRequest& request) { + DCHECK(!request.isNull()); + + AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); + + url_ = request.url().spec().utf16(); + method_ = request.httpMethod(); + + const WebKit::WebHTTPBody& body = request.httpBody(); + if (!body.isNull()) { + postdata_ = new CefPostDataImpl(); + static_cast(postdata_.get())->Set(body); + } else if (postdata_.get()) { + postdata_ = NULL; + } + + headermap_.clear(); + GetHeaderMap(request, headermap_); + + flags_ = UR_FLAG_NONE; + if (request.cachePolicy() == WebKit::WebURLRequest::ReloadIgnoringCacheData) + flags_ |= UR_FLAG_SKIP_CACHE; + if (request.allowStoredCredentials()) + flags_ |= UR_FLAG_ALLOW_CACHED_CREDENTIALS; + if (request.allowCookies()) + flags_ |= UR_FLAG_ALLOW_COOKIES; + if (request.reportUploadProgress()) + flags_ |= UR_FLAG_REPORT_UPLOAD_PROGRESS; + if (request.reportLoadTiming()) + flags_ |= UR_FLAG_REPORT_LOAD_TIMING; + if (request.reportRawHeaders()) + flags_ |= UR_FLAG_REPORT_RAW_HEADERS; + + first_party_for_cookies_ = request.firstPartyForCookies().spec().utf16(); +} + +void CefRequestImpl::Get(WebKit::WebURLRequest& request) { + request.initialize(); + AutoLock lock_scope(this); + + GURL gurl = GURL(url_.ToString()); + request.setURL(WebKit::WebURL(gurl)); + + std::string method(method_); + request.setHTTPMethod(WebKit::WebString::fromUTF8(method.c_str())); + request.setTargetType(WebKit::WebURLRequest::TargetIsMainFrame); + + WebKit::WebHTTPBody body; + if (postdata_.get()) { + body.initialize(); + static_cast(postdata_.get())->Get(body); + request.setHTTPBody(body); + } + + SetHeaderMap(headermap_, request); + + request.setCachePolicy((flags_ & UR_FLAG_SKIP_CACHE) ? + WebKit::WebURLRequest::ReloadIgnoringCacheData : + WebKit::WebURLRequest::UseProtocolCachePolicy); + + #define SETBOOLFLAG(obj, flags, method, FLAG) \ + obj.method((flags & (FLAG)) == (FLAG)) + + SETBOOLFLAG(request, flags_, setAllowStoredCredentials, + UR_FLAG_ALLOW_CACHED_CREDENTIALS); + SETBOOLFLAG(request, flags_, setAllowCookies, + UR_FLAG_ALLOW_COOKIES); + SETBOOLFLAG(request, flags_, setReportUploadProgress, + UR_FLAG_REPORT_UPLOAD_PROGRESS); + SETBOOLFLAG(request, flags_, setReportLoadTiming, + UR_FLAG_REPORT_LOAD_TIMING); + SETBOOLFLAG(request, flags_, setReportRawHeaders, + UR_FLAG_REPORT_RAW_HEADERS); + + if (!first_party_for_cookies_.empty()) { + GURL gurl = GURL(first_party_for_cookies_.ToString()); + request.setFirstPartyForCookies(WebKit::WebURL(gurl)); + } +} + +void CefRequestImpl::SetReadOnly(bool read_only) { + AutoLock lock_scope(this); + if (read_only_ == read_only) + return; + + read_only_ = read_only; + + if (postdata_.get()) + static_cast(postdata_.get())->SetReadOnly(read_only); +} + // static void CefRequestImpl::GetHeaderMap(const net::HttpRequestHeaders& headers, HeaderMap& map) { @@ -172,12 +300,53 @@ void CefRequestImpl::GetHeaderMap(const net::HttpRequestHeaders& headers, } while (it.GetNext()); } -CefRefPtr CefPostData::CreatePostData() { + +// static +void CefRequestImpl::GetHeaderMap(const WebKit::WebURLRequest& request, + HeaderMap& map) { + class HeaderVisitor : public WebKit::WebHTTPHeaderVisitor { + public: + explicit HeaderVisitor(HeaderMap* map) : map_(map) {} + + virtual void visitHeader(const WebKit::WebString& name, + const WebKit::WebString& value) { + map_->insert(std::make_pair(string16(name), string16(value))); + } + + private: + HeaderMap* map_; + }; + + HeaderVisitor visitor(&map); + request.visitHTTPHeaderFields(&visitor); +} + +// static +void CefRequestImpl::SetHeaderMap(const HeaderMap& map, + WebKit::WebURLRequest& request) { + HeaderMap::const_iterator it = map.begin(); + for (; it != map.end(); ++it) + request.setHTTPHeaderField(string16(it->first), string16(it->second)); +} + +// CefPostData ---------------------------------------------------------------- + +// static +CefRefPtr CefPostData::Create() { CefRefPtr postdata(new CefPostDataImpl()); return postdata; } -CefPostDataImpl::CefPostDataImpl() { + +// CefPostDataImpl ------------------------------------------------------------ + +CefPostDataImpl::CefPostDataImpl() + : read_only_(false) { +} + +bool CefPostDataImpl::IsReadOnly() { + AutoLock lock_scope(this); + return read_only_; } size_t CefPostDataImpl::GetElementCount() { @@ -192,6 +361,7 @@ void CefPostDataImpl::GetElements(ElementVector& elements) { bool CefPostDataImpl::RemoveElement(CefRefPtr element) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN(false); ElementVector::iterator it = elements_.begin(); for (; it != elements_.end(); ++it) { @@ -208,6 +378,7 @@ bool CefPostDataImpl::AddElement(CefRefPtr element) { bool found = false; AutoLock lock_scope(this); + CHECK_READONLY_RETURN(false); // check that the element isn't already in the list before adding ElementVector::const_iterator it = elements_.begin(); @@ -226,18 +397,20 @@ bool CefPostDataImpl::AddElement(CefRefPtr element) { void CefPostDataImpl::RemoveElements() { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); elements_.clear(); } void CefPostDataImpl::Set(net::UploadData& data) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); CefRefPtr postelem; std::vector* elements = data.elements(); std::vector::const_iterator it = elements->begin(); for (; it != elements->end(); ++it) { - postelem = CefPostDataElement::CreatePostDataElement(); + postelem = CefPostDataElement::Create(); static_cast(postelem.get())->Set(*it); AddElement(postelem); } @@ -248,7 +421,7 @@ void CefPostDataImpl::Get(net::UploadData& data) { net::UploadData::Element element; std::vector data_elements; - ElementVector::iterator it = elements_.begin(); + ElementVector::const_iterator it = elements_.begin(); for (; it != elements_.end(); ++it) { static_cast(it->get())->Get(element); data_elements.push_back(element); @@ -256,32 +429,89 @@ void CefPostDataImpl::Get(net::UploadData& data) { data.SetElements(data_elements); } -CefRefPtr CefPostDataElement::CreatePostDataElement() { +void CefPostDataImpl::Set(const WebKit::WebHTTPBody& data) { + AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); + + CefRefPtr postelem; + WebKit::WebHTTPBody::Element element; + size_t size = data.elementCount(); + for (size_t i = 0; i < size; ++i) { + if (data.elementAt(i, element)) { + postelem = CefPostDataElement::Create(); + static_cast(postelem.get())->Set(element); + AddElement(postelem); + } + } +} + +void CefPostDataImpl::Get(WebKit::WebHTTPBody& data) { + AutoLock lock_scope(this); + + WebKit::WebHTTPBody::Element element; + ElementVector::iterator it = elements_.begin(); + for (; it != elements_.end(); ++it) { + static_cast(it->get())->Get(element); + if (element.type == WebKit::WebHTTPBody::Element::TypeData) { + data.appendData(element.data); + } else if (element.type == WebKit::WebHTTPBody::Element::TypeFile) { + data.appendFile(element.filePath); + } else { + NOTREACHED(); + } + } +} + +void CefPostDataImpl::SetReadOnly(bool read_only) { + AutoLock lock_scope(this); + if (read_only_ == read_only) + return; + + read_only_ = read_only; + + ElementVector::const_iterator it = elements_.begin(); + for (; it != elements_.end(); ++it) { + static_cast(it->get())->SetReadOnly(read_only); + } +} + +// CefPostDataElement --------------------------------------------------------- + +// static +CefRefPtr CefPostDataElement::Create() { CefRefPtr element(new CefPostDataElementImpl()); return element; } -CefPostDataElementImpl::CefPostDataElementImpl() { - type_ = PDE_TYPE_EMPTY; + +// CefPostDataElementImpl ----------------------------------------------------- + +CefPostDataElementImpl::CefPostDataElementImpl() + : type_(PDE_TYPE_EMPTY), + read_only_(false) { memset(&data_, 0, sizeof(data_)); } CefPostDataElementImpl::~CefPostDataElementImpl() { - SetToEmpty(); + Cleanup(); +} + +bool CefPostDataElementImpl::IsReadOnly() { + AutoLock lock_scope(this); + return read_only_; } void CefPostDataElementImpl::SetToEmpty() { AutoLock lock_scope(this); - if (type_ == PDE_TYPE_BYTES) - free(data_.bytes.bytes); - else if (type_ == PDE_TYPE_FILE) - cef_string_clear(&data_.filename); - type_ = PDE_TYPE_EMPTY; - memset(&data_, 0, sizeof(data_)); + CHECK_READONLY_RETURN_VOID(); + + Cleanup(); } void CefPostDataElementImpl::SetToFile(const CefString& fileName) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); + // Clear any data currently in the element SetToEmpty(); @@ -292,6 +522,8 @@ void CefPostDataElementImpl::SetToFile(const CefString& fileName) { void CefPostDataElementImpl::SetToBytes(size_t size, const void* bytes) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); + // Clear any data currently in the element SetToEmpty(); @@ -344,6 +576,7 @@ size_t CefPostDataElementImpl::GetBytes(size_t size, void* bytes) { void CefPostDataElementImpl::Set(const net::UploadData::Element& element) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); if (element.type() == net::UploadData::TYPE_BYTES) { SetToBytes(element.bytes().size(), @@ -369,3 +602,52 @@ void CefPostDataElementImpl::Get(net::UploadData::Element& element) { NOTREACHED(); } } + +void CefPostDataElementImpl::Set(const WebKit::WebHTTPBody::Element& element) { + AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); + + if (element.type == WebKit::WebHTTPBody::Element::TypeData) { + SetToBytes(element.data.size(), + static_cast(element.data.data())); + } else if (element.type == WebKit::WebHTTPBody::Element::TypeFile) { + SetToFile(string16(element.filePath)); + } else { + NOTREACHED(); + } +} + +void CefPostDataElementImpl::Get(WebKit::WebHTTPBody::Element& element) { + AutoLock lock_scope(this); + + if (type_ == PDE_TYPE_BYTES) { + element.type = WebKit::WebHTTPBody::Element::TypeData; + element.data.assign( + static_cast(data_.bytes.bytes), data_.bytes.size); + } else if (type_ == PDE_TYPE_FILE) { + element.type = WebKit::WebHTTPBody::Element::TypeFile; + element.filePath.assign(string16(CefString(&data_.filename))); + } else { + NOTREACHED(); + } +} + +void CefPostDataElementImpl::SetReadOnly(bool read_only) { + AutoLock lock_scope(this); + if (read_only_ == read_only) + return; + + read_only_ = read_only; +} + +void CefPostDataElementImpl::Cleanup() { + if (type_ == PDE_TYPE_EMPTY) + return; + + if (type_ == PDE_TYPE_BYTES) + free(data_.bytes.bytes); + else if (type_ == PDE_TYPE_FILE) + cef_string_clear(&data_.filename); + type_ = PDE_TYPE_EMPTY; + memset(&data_, 0, sizeof(data_)); +} diff --git a/libcef/common/request_impl.h b/libcef/common/request_impl.h index 51b8c6ca2..64295f8f4 100644 --- a/libcef/common/request_impl.h +++ b/libcef/common/request_impl.h @@ -9,17 +9,23 @@ #include "include/cef_request.h" #include "net/base/upload_data.h" #include "net/http/http_request_headers.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebHTTPBody.h" namespace net { class URLRequest; }; +namespace WebKit { +class WebURLRequest; +} + // Implementation of CefRequest class CefRequestImpl : public CefRequest { public: CefRequestImpl(); ~CefRequestImpl() {} + virtual bool IsReadOnly() OVERRIDE; virtual CefString GetURL() OVERRIDE; virtual void SetURL(const CefString& url) OVERRIDE; virtual CefString GetMethod() OVERRIDE; @@ -32,8 +38,8 @@ class CefRequestImpl : public CefRequest { const CefString& method, CefRefPtr postData, const HeaderMap& headerMap) OVERRIDE; - virtual RequestFlags GetFlags() OVERRIDE; - virtual void SetFlags(RequestFlags flags) OVERRIDE; + virtual int GetFlags() OVERRIDE; + virtual void SetFlags(int flags) OVERRIDE; virtual CefString GetFirstPartyForCookies() OVERRIDE; virtual void SetFirstPartyForCookies(const CefString& url) OVERRIDE; @@ -43,8 +49,20 @@ class CefRequestImpl : public CefRequest { // Populate the URLRequest object from this object. void Get(net::URLRequest* request); + // Populate this object from a WebURLRequest object. + void Set(const WebKit::WebURLRequest& request); + + // Populate the WebURLRequest object from this object. + void Get(WebKit::WebURLRequest& request); + + void SetReadOnly(bool read_only); + static void GetHeaderMap(const net::HttpRequestHeaders& headers, HeaderMap& map); + static void GetHeaderMap(const WebKit::WebURLRequest& request, + HeaderMap& map); + static void SetHeaderMap(const HeaderMap& map, + WebKit::WebURLRequest& request); protected: CefString url_; @@ -52,10 +70,13 @@ class CefRequestImpl : public CefRequest { CefRefPtr postdata_; HeaderMap headermap_; - // The below methods are used by WebURLRequest. - RequestFlags flags_; + // The below members are used by CefURLRequest. + int flags_; CefString first_party_for_cookies_; + // True if this object is read-only. + bool read_only_; + IMPLEMENT_REFCOUNTING(CefRequestImpl); IMPLEMENT_LOCKING(CefRequestImpl); }; @@ -66,6 +87,7 @@ class CefPostDataImpl : public CefPostData { CefPostDataImpl(); ~CefPostDataImpl() {} + virtual bool IsReadOnly() OVERRIDE; virtual size_t GetElementCount() OVERRIDE; virtual void GetElements(ElementVector& elements) OVERRIDE; virtual bool RemoveElement(CefRefPtr element) OVERRIDE; @@ -74,10 +96,17 @@ class CefPostDataImpl : public CefPostData { void Set(net::UploadData& data); void Get(net::UploadData& data); + void Set(const WebKit::WebHTTPBody& data); + void Get(WebKit::WebHTTPBody& data); + + void SetReadOnly(bool read_only); protected: ElementVector elements_; + // True if this object is read-only. + bool read_only_; + IMPLEMENT_REFCOUNTING(CefPostDataImpl); IMPLEMENT_LOCKING(CefPostDataImpl); }; @@ -88,6 +117,7 @@ class CefPostDataElementImpl : public CefPostDataElement { CefPostDataElementImpl(); ~CefPostDataElementImpl(); + virtual bool IsReadOnly() OVERRIDE; virtual void SetToEmpty() OVERRIDE; virtual void SetToFile(const CefString& fileName) OVERRIDE; virtual void SetToBytes(size_t size, const void* bytes) OVERRIDE; @@ -100,8 +130,14 @@ class CefPostDataElementImpl : public CefPostDataElement { void Set(const net::UploadData::Element& element); void Get(net::UploadData::Element& element); + void Set(const WebKit::WebHTTPBody::Element& element); + void Get(WebKit::WebHTTPBody::Element& element); + + void SetReadOnly(bool read_only); protected: + void Cleanup(); + Type type_; union { struct { @@ -111,6 +147,9 @@ class CefPostDataElementImpl : public CefPostDataElement { cef_string_t filename; } data_; + // True if this object is read-only. + bool read_only_; + IMPLEMENT_REFCOUNTING(CefPostDataElementImpl); IMPLEMENT_LOCKING(CefPostDataElementImpl); }; diff --git a/libcef/common/response_impl.cc b/libcef/common/response_impl.cc index be5aea113..ce22b1dc3 100644 --- a/libcef/common/response_impl.cc +++ b/libcef/common/response_impl.cc @@ -4,12 +4,43 @@ #include "libcef/common/response_impl.h" +#include + #include "base/logging.h" #include "base/stringprintf.h" +#include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebHTTPHeaderVisitor.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLResponse.h" + + +#define CHECK_READONLY_RETURN_VOID() \ + if (read_only_) { \ + NOTREACHED() << "object is read only"; \ + return; \ + } + + +// CefResponse ---------------------------------------------------------------- + +// static +CefRefPtr CefResponse::Create() { + CefRefPtr response(new CefResponseImpl()); + return response; +} + + +// CefResponseImpl ------------------------------------------------------------ CefResponseImpl::CefResponseImpl() - : status_code_(0) { + : status_code_(0), + read_only_(false) { +} + +bool CefResponseImpl::IsReadOnly() { + AutoLock lock_scope(this); + return read_only_; } int CefResponseImpl::GetStatus() { @@ -19,6 +50,7 @@ int CefResponseImpl::GetStatus() { void CefResponseImpl::SetStatus(int status) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); status_code_ = status; } @@ -29,6 +61,7 @@ CefString CefResponseImpl::GetStatusText() { void CefResponseImpl::SetStatusText(const CefString& statusText) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); status_text_ = statusText; } @@ -39,6 +72,7 @@ CefString CefResponseImpl::GetMimeType() { void CefResponseImpl::SetMimeType(const CefString& mimeType) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); mime_type_ = mimeType; } @@ -61,6 +95,7 @@ void CefResponseImpl::GetHeaderMap(HeaderMap& map) { void CefResponseImpl::SetHeaderMap(const HeaderMap& headerMap) { AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); header_map_ = headerMap; } @@ -69,11 +104,12 @@ net::HttpResponseHeaders* CefResponseImpl::GetResponseHeaders() { std::string response; std::string status_text; + bool has_content_type_header = false; - if (status_text_.empty()) - status_text = (status_code_ == 200)?"OK":"ERROR"; - else + if (!status_text_.empty()) status_text = status_text_; + else + status_text = (status_code_ == 200)?"OK":"ERROR"; base::SStringPrintf(&response, "HTTP/1.1 %d %s", status_code_, status_text.c_str()); @@ -90,9 +126,79 @@ net::HttpResponseHeaders* CefResponseImpl::GetResponseHeaders() { std::string value_str(value); base::StringAppendF(&response, "%c%s: %s", '\0', key_str.c_str(), value_str.c_str()); + + if (!has_content_type_header && + key_str == net::HttpRequestHeaders::kContentType) { + has_content_type_header = true; + } } } } + if (!has_content_type_header) { + std::string mime_type; + if (!mime_type_.empty()) + mime_type = mime_type_; + else + mime_type = "text/html"; + + base::StringAppendF(&response, "%c%s: %s", '\0', + net::HttpRequestHeaders::kContentType, mime_type.c_str()); + } + return new net::HttpResponseHeaders(response); } + +void CefResponseImpl::SetResponseHeaders( + const net::HttpResponseHeaders& headers) { + AutoLock lock_scope(this); + + header_map_.empty(); + + void* iter = NULL; + std::string name, value; + while (headers.EnumerateHeaderLines(&iter, &name, &value)) + header_map_.insert(std::make_pair(name, value)); + + status_code_ = headers.response_code(); + status_text_ = headers.GetStatusText(); + + std::string mime_type; + if (headers.GetMimeType(&mime_type)) + mime_type_ = mime_type; +} + +void CefResponseImpl::Set(const WebKit::WebURLResponse& response) { + DCHECK(!response.isNull()); + + AutoLock lock_scope(this); + CHECK_READONLY_RETURN_VOID(); + + WebKit::WebString str; + status_code_ = response.httpStatusCode(); + str = response.httpStatusText(); + status_text_ = CefString(str); + str = response.mimeType(); + mime_type_ = CefString(str); + + class HeaderVisitor : public WebKit::WebHTTPHeaderVisitor { + public: + explicit HeaderVisitor(HeaderMap* map) : map_(map) {} + + virtual void visitHeader(const WebKit::WebString& name, + const WebKit::WebString& value) { + map_->insert(std::make_pair(string16(name), string16(value))); + } + + private: + HeaderMap* map_; + }; + + HeaderVisitor visitor(&header_map_); + response.visitHTTPHeaderFields(&visitor); +} + +void CefResponseImpl::SetReadOnly(bool read_only) { + AutoLock lock_scope(this); + read_only_ = read_only; +} diff --git a/libcef/common/response_impl.h b/libcef/common/response_impl.h index 93eb49c6b..e14e0eecf 100644 --- a/libcef/common/response_impl.h +++ b/libcef/common/response_impl.h @@ -12,30 +12,41 @@ namespace net { class HttpResponseHeaders; } +namespace WebKit { +class WebURLResponse; +} + // Implementation of CefResponse. class CefResponseImpl : public CefResponse { public: CefResponseImpl(); ~CefResponseImpl() {} - // CefResponse API - virtual int GetStatus(); - virtual void SetStatus(int status); - virtual CefString GetStatusText(); - virtual void SetStatusText(const CefString& statusText); - virtual CefString GetMimeType(); - virtual void SetMimeType(const CefString& mimeType); - virtual CefString GetHeader(const CefString& name); - virtual void GetHeaderMap(HeaderMap& headerMap); - virtual void SetHeaderMap(const HeaderMap& headerMap); + // CefResponse methods. + virtual bool IsReadOnly() OVERRIDE; + virtual int GetStatus() OVERRIDE; + virtual void SetStatus(int status) OVERRIDE; + virtual CefString GetStatusText() OVERRIDE; + virtual void SetStatusText(const CefString& statusText) OVERRIDE; + virtual CefString GetMimeType() OVERRIDE; + virtual void SetMimeType(const CefString& mimeType) OVERRIDE; + virtual CefString GetHeader(const CefString& name) OVERRIDE; + virtual void GetHeaderMap(HeaderMap& headerMap) OVERRIDE; + virtual void SetHeaderMap(const HeaderMap& headerMap) OVERRIDE; net::HttpResponseHeaders* GetResponseHeaders(); + void SetResponseHeaders(const net::HttpResponseHeaders& headers); + + void Set(const WebKit::WebURLResponse& response); + + void SetReadOnly(bool read_only); protected: int status_code_; CefString status_text_; CefString mime_type_; HeaderMap header_map_; + bool read_only_; IMPLEMENT_REFCOUNTING(CefResponseImpl); IMPLEMENT_LOCKING(CefResponseImpl); diff --git a/libcef/common/urlrequest_impl.cc b/libcef/common/urlrequest_impl.cc new file mode 100644 index 000000000..de47161aa --- /dev/null +++ b/libcef/common/urlrequest_impl.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2012 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_urlrequest.h" +#include "libcef/browser/browser_urlrequest_impl.h" +#include "libcef/renderer/render_urlrequest_impl.h" + +#include "base/logging.h" +#include "base/message_loop.h" +#include "content/public/common/content_client.h" + +// static +CefRefPtr CefURLRequest::Create( + CefRefPtr request, + CefRefPtr client) { + if (!request.get() || !client.get()) { + NOTREACHED() << "called with invalid parameters"; + return NULL; + } + + if (!MessageLoop::current()) { + NOTREACHED() << "called on invalid thread"; + return NULL; + } + + if (content::GetContentClient()->browser()) { + // In the browser process. + CefRefPtr impl = + new CefBrowserURLRequest(request, client); + if (impl->Start()) + return impl.get(); + return NULL; + } else if (content::GetContentClient()->renderer()) { + // In the render process. + CefRefPtr impl = + new CefRenderURLRequest(request, client); + if (impl->Start()) + return impl.get(); + return NULL; + } else { + NOTREACHED() << "called in unsupported process"; + return NULL; + } +} diff --git a/libcef/renderer/render_urlrequest_impl.cc b/libcef/renderer/render_urlrequest_impl.cc new file mode 100644 index 000000000..f20ecd547 --- /dev/null +++ b/libcef/renderer/render_urlrequest_impl.cc @@ -0,0 +1,375 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that can +// be found in the LICENSE file. + +#include "libcef/renderer/render_urlrequest_impl.h" +#include "libcef/common/request_impl.h" +#include "libcef/common/response_impl.h" + +#include "base/logging.h" +#include "base/message_loop.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebKitPlatformSupport.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLError.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLLoader.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLLoaderClient.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLResponse.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" + +using WebKit::WebString; +using WebKit::WebURL; +using WebKit::WebURLError; +using WebKit::WebURLLoader; +using WebKit::WebURLRequest; +using WebKit::WebURLResponse; + + +namespace { + +class CefWebURLLoaderClient : public WebKit::WebURLLoaderClient { + public: + CefWebURLLoaderClient(CefRenderURLRequest::Context* context, + int request_flags); + virtual ~CefWebURLLoaderClient(); + + // WebKit::WebURLLoaderClient methods. + virtual void willSendRequest( + WebURLLoader* loader, + WebURLRequest& newRequest, + const WebURLResponse& redirectResponse) OVERRIDE; + virtual void didSendData( + WebURLLoader* loader, + unsigned long long bytesSent, + unsigned long long totalBytesToBeSent) OVERRIDE; + virtual void didReceiveResponse( + WebURLLoader* loader, + const WebURLResponse& response) OVERRIDE; + virtual void didDownloadData(WebURLLoader* loader, + int dataLength) OVERRIDE; + virtual void didReceiveData(WebURLLoader* loader, + const char* data, + int dataLength, + int encodedDataLength) OVERRIDE; + virtual void didReceiveCachedMetadata(WebURLLoader* loader, + const char* data, + int dataLength) OVERRIDE; + virtual void didFinishLoading(WebURLLoader* loader, + double finishTime) OVERRIDE; + virtual void didFail(WebURLLoader* loader, + const WebURLError& error) OVERRIDE; + + protected: + // The context_ pointer will outlive this object. + CefRenderURLRequest::Context* context_; + int request_flags_; +}; + +} // namespace + + +// CefRenderURLRequest::Context ----------------------------------------------- + +class CefRenderURLRequest::Context + : public base::RefCountedThreadSafe { + public: + Context(CefRefPtr url_request, + CefRefPtr request, + CefRefPtr client) + : url_request_(url_request), + request_(request), + client_(client), + message_loop_proxy_(MessageLoop::current()->message_loop_proxy()), + status_(UR_IO_PENDING), + error_code_(ERR_NONE), + upload_data_size_(0), + got_upload_progress_complete_(false), + download_data_received_(0), + download_data_total_(-1) { + // Mark the request as read-only. + static_cast(request_.get())->SetReadOnly(true); + } + + virtual ~Context() { + } + + inline bool CalledOnValidThread() { + return message_loop_proxy_->BelongsToCurrentThread(); + } + + bool Start() { + DCHECK(CalledOnValidThread()); + + GURL url = GURL(request_->GetURL().ToString()); + if (!url.is_valid()) + return false; + + loader_.reset(WebKit::webKitPlatformSupport()->createURLLoader()); + url_client_.reset(new CefWebURLLoaderClient(this, request_->GetFlags())); + + WebURLRequest urlRequest; + static_cast(request_.get())->Get(urlRequest); + + if (urlRequest.reportUploadProgress()) { + // Attempt to determine the upload data size. + CefRefPtr post_data = request_->GetPostData(); + if (post_data.get()) { + CefPostData::ElementVector elements; + post_data->GetElements(elements); + if (elements.size() == 1 && elements[0]->GetType() == PDE_TYPE_BYTES) { + CefPostDataElementImpl* impl = + static_cast(elements[0].get()); + upload_data_size_ = impl->GetBytesCount(); + } + } + } + + loader_->loadAsynchronously(urlRequest, url_client_.get()); + return true; + } + + void Cancel() { + DCHECK(CalledOnValidThread()); + + // The request may already be complete. + if (!loader_.get() || status_ != UR_IO_PENDING) + return; + + status_ = UR_CANCELED; + error_code_ = ERR_ABORTED; + + // Will result in a call to OnError(). + loader_->cancel(); + } + + void OnResponse(const WebURLResponse& response) { + DCHECK(CalledOnValidThread()); + + response_ = CefResponse::Create(); + CefResponseImpl* responseImpl = + static_cast(response_.get()); + responseImpl->Set(response); + responseImpl->SetReadOnly(true); + + download_data_total_ = response.expectedContentLength(); + } + + void OnError(const WebURLError& error) { + DCHECK(CalledOnValidThread()); + + if (status_ == UR_IO_PENDING) { + status_ = UR_FAILED; + error_code_ = static_cast(error.reason); + } + + OnComplete(); + } + + void OnComplete() { + DCHECK(CalledOnValidThread()); + + if (status_ == UR_IO_PENDING) { + status_ = UR_SUCCESS; + NotifyUploadProgressIfNecessary(); + } + + if (loader_.get()) + loader_.reset(NULL); + + DCHECK(url_request_.get()); + client_->OnRequestComplete(url_request_.get()); + + // This may result in the Context object being deleted. + url_request_ = NULL; + } + + void OnDownloadProgress(int64 current) { + DCHECK(CalledOnValidThread()); + DCHECK(url_request_.get()); + + NotifyUploadProgressIfNecessary(); + + download_data_received_ += current; + client_->OnDownloadProgress(url_request_.get(), download_data_received_, + download_data_total_); + } + + void OnDownloadData(const char* data, int dataLength) { + DCHECK(CalledOnValidThread()); + DCHECK(url_request_.get()); + client_->OnDownloadData(url_request_.get(), data, dataLength); + } + + void OnUploadProgress(int64 current, int64 total) { + DCHECK(CalledOnValidThread()); + DCHECK(url_request_.get()); + if (current == total) + got_upload_progress_complete_ = true; + client_->OnUploadProgress(url_request_.get(), current, total); + } + + CefRefPtr request() { return request_; } + CefRefPtr client() { return client_; } + CefURLRequest::Status status() { return status_; } + CefURLRequest::ErrorCode error_code() { return error_code_; } + CefRefPtr response() { return response_; } + + private: + void NotifyUploadProgressIfNecessary() { + if (!got_upload_progress_complete_ && upload_data_size_ > 0) { + // URLFetcher sends upload notifications using a timer and will not send + // a notification if the request completes too quickly. We therefore + // send the notification here if necessary. + client_->OnUploadProgress(url_request_.get(), upload_data_size_, + upload_data_size_); + got_upload_progress_complete_ = true; + } + } + + // Members only accessed on the initialization thread. + CefRefPtr url_request_; + CefRefPtr request_; + CefRefPtr client_; + scoped_refptr message_loop_proxy_; + CefURLRequest::Status status_; + CefURLRequest::ErrorCode error_code_; + CefRefPtr response_; + scoped_ptr loader_; + scoped_ptr url_client_; + int64 upload_data_size_; + bool got_upload_progress_complete_; + int64 download_data_received_; + int64 download_data_total_; +}; + + +// CefWebURLLoaderClient -------------------------------------------------- + +namespace { + +CefWebURLLoaderClient::CefWebURLLoaderClient( + CefRenderURLRequest::Context* context, + int request_flags) + : context_(context), + request_flags_(request_flags) { +} + +CefWebURLLoaderClient::~CefWebURLLoaderClient() { +} + +void CefWebURLLoaderClient::willSendRequest( + WebURLLoader* loader, + WebURLRequest& newRequest, + const WebURLResponse& redirectResponse) { +} + +void CefWebURLLoaderClient::didSendData( + WebURLLoader* loader, + unsigned long long bytesSent, + unsigned long long totalBytesToBeSent) { + if (request_flags_ & UR_FLAG_REPORT_UPLOAD_PROGRESS) + context_->OnUploadProgress(bytesSent, totalBytesToBeSent); +} + +void CefWebURLLoaderClient::didReceiveResponse( + WebURLLoader* loader, + const WebURLResponse& response) { + context_->OnResponse(response); +} + +void CefWebURLLoaderClient::didDownloadData(WebURLLoader* loader, + int dataLength) { +} + +void CefWebURLLoaderClient::didReceiveData(WebURLLoader* loader, + const char* data, + int dataLength, + int encodedDataLength) { + context_->OnDownloadProgress(dataLength); + + if (!(request_flags_ & UR_FLAG_NO_DOWNLOAD_DATA)) + context_->OnDownloadData(data, dataLength); +} + +void CefWebURLLoaderClient::didReceiveCachedMetadata(WebURLLoader* loader, + const char* data, + int dataLength) { +} + +void CefWebURLLoaderClient::didFinishLoading(WebURLLoader* loader, + double finishTime) { + context_->OnComplete(); +} + +void CefWebURLLoaderClient::didFail(WebURLLoader* loader, + const WebURLError& error) { + context_->OnError(error); +} + + +} // namespace + + +// CefRenderURLRequest -------------------------------------------------------- + +CefRenderURLRequest::CefRenderURLRequest( + CefRefPtr request, + CefRefPtr client) { + context_ = new Context(this, request, client); +} + +CefRenderURLRequest::~CefRenderURLRequest() { +} + +bool CefRenderURLRequest::Start() { + if (!VerifyContext()) + return false; + return context_->Start(); +} + +CefRefPtr CefRenderURLRequest::GetRequest() { + if (!VerifyContext()) + return NULL; + return context_->request(); +} + +CefRefPtr CefRenderURLRequest::GetClient() { + if (!VerifyContext()) + return NULL; + return context_->client(); +} + +CefURLRequest::Status CefRenderURLRequest::GetRequestStatus() { + if (!VerifyContext()) + return UR_UNKNOWN; + return context_->status(); +} + +CefURLRequest::ErrorCode CefRenderURLRequest::GetRequestError() { + if (!VerifyContext()) + return ERR_NONE; + return context_->error_code(); +} + +CefRefPtr CefRenderURLRequest::GetResponse() { + if (!VerifyContext()) + return NULL; + return context_->response(); +} + +void CefRenderURLRequest::Cancel() { + if (!VerifyContext()) + return; + return context_->Cancel(); +} + +bool CefRenderURLRequest::VerifyContext() { + DCHECK(context_.get()); + if (!context_->CalledOnValidThread()) { + NOTREACHED() << "called on invalid thread"; + return false; + } + + return true; +} diff --git a/libcef/renderer/render_urlrequest_impl.h b/libcef/renderer/render_urlrequest_impl.h new file mode 100644 index 000000000..b529b100c --- /dev/null +++ b/libcef/renderer/render_urlrequest_impl.h @@ -0,0 +1,37 @@ +// Copyright (c) 2012 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_RENDERER_RENDER_URLREQUEST_IMPL_H_ +#define CEF_LIBCEF_RENDERER_RENDER_URLREQUEST_IMPL_H_ + +#include "include/cef_urlrequest.h" +#include "base/memory/ref_counted.h" + +class CefRenderURLRequest : public CefURLRequest { + public: + class Context; + + CefRenderURLRequest(CefRefPtr request, + CefRefPtr client); + virtual ~CefRenderURLRequest(); + + bool Start(); + + // CefURLRequest methods. + virtual CefRefPtr GetRequest() OVERRIDE; + virtual CefRefPtr GetClient() OVERRIDE; + virtual Status GetRequestStatus() OVERRIDE; + virtual ErrorCode GetRequestError() OVERRIDE; + virtual CefRefPtr GetResponse() OVERRIDE; + virtual void Cancel() OVERRIDE; + + private: + bool VerifyContext(); + + scoped_refptr context_; + + IMPLEMENT_REFCOUNTING(CefBrowserURLRequest); +}; + +#endif // CEF_LIBCEF_RENDERER_RENDER_URLREQUEST_IMPL_H_ diff --git a/libcef_dll/cpptoc/app_cpptoc.cc b/libcef_dll/cpptoc/app_cpptoc.cc index 1767fd434..d699d148b 100644 --- a/libcef_dll/cpptoc/app_cpptoc.cc +++ b/libcef_dll/cpptoc/app_cpptoc.cc @@ -11,7 +11,7 @@ // #include "libcef_dll/cpptoc/app_cpptoc.h" -#include "libcef_dll/cpptoc/proxy_handler_cpptoc.h" +#include "libcef_dll/cpptoc/browser_process_handler_cpptoc.h" #include "libcef_dll/cpptoc/render_process_handler_cpptoc.h" #include "libcef_dll/cpptoc/resource_bundle_handler_cpptoc.h" #include "libcef_dll/ctocpp/command_line_ctocpp.h" @@ -57,22 +57,6 @@ void CEF_CALLBACK app_on_register_custom_schemes(struct _cef_app_t* self, CefSchemeRegistrarCToCpp::Wrap(registrar)); } -struct _cef_render_process_handler_t* CEF_CALLBACK app_get_render_process_handler( - struct _cef_app_t* self) { - // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING - - DCHECK(self); - if (!self) - return NULL; - - // Execute - CefRefPtr _retval = CefAppCppToC::Get( - self)->GetRenderProcessHandler(); - - // Return type: refptr_same - return CefRenderProcessHandlerCppToC::Wrap(_retval); -} - struct _cef_resource_bundle_handler_t* CEF_CALLBACK app_get_resource_bundle_handler( struct _cef_app_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -89,7 +73,7 @@ struct _cef_resource_bundle_handler_t* CEF_CALLBACK app_get_resource_bundle_hand return CefResourceBundleHandlerCppToC::Wrap(_retval); } -struct _cef_proxy_handler_t* CEF_CALLBACK app_get_proxy_handler( +struct _cef_browser_process_handler_t* CEF_CALLBACK app_get_browser_process_handler( struct _cef_app_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -98,11 +82,27 @@ struct _cef_proxy_handler_t* CEF_CALLBACK app_get_proxy_handler( return NULL; // Execute - CefRefPtr _retval = CefAppCppToC::Get(self)->GetProxyHandler( - ); + CefRefPtr _retval = CefAppCppToC::Get( + self)->GetBrowserProcessHandler(); // Return type: refptr_same - return CefProxyHandlerCppToC::Wrap(_retval); + return CefBrowserProcessHandlerCppToC::Wrap(_retval); +} + +struct _cef_render_process_handler_t* CEF_CALLBACK app_get_render_process_handler( + struct _cef_app_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefRefPtr _retval = CefAppCppToC::Get( + self)->GetRenderProcessHandler(); + + // Return type: refptr_same + return CefRenderProcessHandlerCppToC::Wrap(_retval); } @@ -113,9 +113,9 @@ CefAppCppToC::CefAppCppToC(CefApp* cls) struct_.struct_.on_before_command_line_processing = app_on_before_command_line_processing; struct_.struct_.on_register_custom_schemes = app_on_register_custom_schemes; - struct_.struct_.get_render_process_handler = app_get_render_process_handler; struct_.struct_.get_resource_bundle_handler = app_get_resource_bundle_handler; - struct_.struct_.get_proxy_handler = app_get_proxy_handler; + struct_.struct_.get_browser_process_handler = app_get_browser_process_handler; + struct_.struct_.get_render_process_handler = app_get_render_process_handler; } #ifndef NDEBUG diff --git a/libcef_dll/cpptoc/browser_process_handler_cpptoc.cc b/libcef_dll/cpptoc/browser_process_handler_cpptoc.cc new file mode 100644 index 000000000..fbfdfcd4a --- /dev/null +++ b/libcef_dll/cpptoc/browser_process_handler_cpptoc.cc @@ -0,0 +1,63 @@ +// Copyright (c) 2012 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/browser_process_handler_cpptoc.h" +#include "libcef_dll/cpptoc/proxy_handler_cpptoc.h" + + +// MEMBER FUNCTIONS - Body may be edited by hand. + +struct _cef_proxy_handler_t* CEF_CALLBACK browser_process_handler_get_proxy_handler( + struct _cef_browser_process_handler_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefRefPtr _retval = CefBrowserProcessHandlerCppToC::Get( + self)->GetProxyHandler(); + + // Return type: refptr_same + return CefProxyHandlerCppToC::Wrap(_retval); +} + +void CEF_CALLBACK browser_process_handler_on_context_initialized( + struct _cef_browser_process_handler_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + + // Execute + CefBrowserProcessHandlerCppToC::Get(self)->OnContextInitialized(); +} + + +// CONSTRUCTOR - Do not edit by hand. + +CefBrowserProcessHandlerCppToC::CefBrowserProcessHandlerCppToC( + CefBrowserProcessHandler* cls) + : CefCppToC(cls) { + struct_.struct_.get_proxy_handler = browser_process_handler_get_proxy_handler; + struct_.struct_.on_context_initialized = + browser_process_handler_on_context_initialized; +} + +#ifndef NDEBUG +template<> long CefCppToC::DebugObjCt = 0; +#endif + diff --git a/libcef_dll/cpptoc/browser_process_handler_cpptoc.h b/libcef_dll/cpptoc/browser_process_handler_cpptoc.h new file mode 100644 index 000000000..e9047dd07 --- /dev/null +++ b/libcef_dll/cpptoc/browser_process_handler_cpptoc.h @@ -0,0 +1,37 @@ +// Copyright (c) 2012 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_BROWSER_PROCESS_HANDLER_CPPTOC_H_ +#define CEF_LIBCEF_DLL_CPPTOC_BROWSER_PROCESS_HANDLER_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_browser_process_handler.h" +#include "include/capi/cef_browser_process_handler_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 CefBrowserProcessHandlerCppToC + : public CefCppToC { + public: + explicit CefBrowserProcessHandlerCppToC(CefBrowserProcessHandler* cls); + virtual ~CefBrowserProcessHandlerCppToC() {} +}; + +#endif // USING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CPPTOC_BROWSER_PROCESS_HANDLER_CPPTOC_H_ + diff --git a/libcef_dll/cpptoc/load_handler_cpptoc.cc b/libcef_dll/cpptoc/load_handler_cpptoc.cc index 5b13bf82b..f7da851a8 100644 --- a/libcef_dll/cpptoc/load_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/load_handler_cpptoc.cc @@ -63,9 +63,8 @@ void CEF_CALLBACK load_handler_on_load_end(struct _cef_load_handler_t* self, } void CEF_CALLBACK load_handler_on_load_error(struct _cef_load_handler_t* self, - cef_browser_t* browser, cef_frame_t* frame, - enum cef_handler_errorcode_t errorCode, const cef_string_t* errorText, - const cef_string_t* failedUrl) { + cef_browser_t* browser, cef_frame_t* frame, enum cef_errorcode_t errorCode, + const cef_string_t* errorText, const cef_string_t* failedUrl) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING DCHECK(self); diff --git a/libcef_dll/cpptoc/post_data_cpptoc.cc b/libcef_dll/cpptoc/post_data_cpptoc.cc index add00ea77..bf51e349c 100644 --- a/libcef_dll/cpptoc/post_data_cpptoc.cc +++ b/libcef_dll/cpptoc/post_data_cpptoc.cc @@ -20,7 +20,7 @@ CEF_EXPORT cef_post_data_t* cef_post_data_create() { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // Execute - CefRefPtr _retval = CefPostData::CreatePostData(); + CefRefPtr _retval = CefPostData::Create(); // Return type: refptr_same return CefPostDataCppToC::Wrap(_retval); @@ -29,6 +29,20 @@ CEF_EXPORT cef_post_data_t* cef_post_data_create() { // MEMBER FUNCTIONS - Body may be edited by hand. +int CEF_CALLBACK post_data_is_read_only(struct _cef_post_data_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + bool _retval = CefPostDataCppToC::Get(self)->IsReadOnly(); + + // Return type: bool + return _retval; +} + size_t CEF_CALLBACK post_data_get_element_count(struct _cef_post_data_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -134,6 +148,7 @@ void CEF_CALLBACK post_data_remove_elements(struct _cef_post_data_t* self) { CefPostDataCppToC::CefPostDataCppToC(CefPostData* cls) : CefCppToC(cls) { + struct_.struct_.is_read_only = post_data_is_read_only; struct_.struct_.get_element_count = post_data_get_element_count; struct_.struct_.get_elements = post_data_get_elements; struct_.struct_.remove_element = post_data_remove_element; diff --git a/libcef_dll/cpptoc/post_data_element_cpptoc.cc b/libcef_dll/cpptoc/post_data_element_cpptoc.cc index cddf7c4a9..8a3eca338 100644 --- a/libcef_dll/cpptoc/post_data_element_cpptoc.cc +++ b/libcef_dll/cpptoc/post_data_element_cpptoc.cc @@ -19,8 +19,7 @@ CEF_EXPORT cef_post_data_element_t* cef_post_data_element_create() { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // Execute - CefRefPtr _retval = - CefPostDataElement::CreatePostDataElement(); + CefRefPtr _retval = CefPostDataElement::Create(); // Return type: refptr_same return CefPostDataElementCppToC::Wrap(_retval); @@ -29,6 +28,21 @@ CEF_EXPORT cef_post_data_element_t* cef_post_data_element_create() { // MEMBER FUNCTIONS - Body may be edited by hand. +int CEF_CALLBACK post_data_element_is_read_only( + struct _cef_post_data_element_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + bool _retval = CefPostDataElementCppToC::Get(self)->IsReadOnly(); + + // Return type: bool + return _retval; +} + void CEF_CALLBACK post_data_element_set_to_empty( struct _cef_post_data_element_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -149,6 +163,7 @@ size_t CEF_CALLBACK post_data_element_get_bytes( CefPostDataElementCppToC::CefPostDataElementCppToC(CefPostDataElement* cls) : CefCppToC(cls) { + struct_.struct_.is_read_only = post_data_element_is_read_only; struct_.struct_.set_to_empty = post_data_element_set_to_empty; struct_.struct_.set_to_file = post_data_element_set_to_file; struct_.struct_.set_to_bytes = post_data_element_set_to_bytes; diff --git a/libcef_dll/cpptoc/request_cpptoc.cc b/libcef_dll/cpptoc/request_cpptoc.cc index 6d554cc1d..2d943d715 100644 --- a/libcef_dll/cpptoc/request_cpptoc.cc +++ b/libcef_dll/cpptoc/request_cpptoc.cc @@ -21,7 +21,7 @@ CEF_EXPORT cef_request_t* cef_request_create() { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // Execute - CefRefPtr _retval = CefRequest::CreateRequest(); + CefRefPtr _retval = CefRequest::Create(); // Return type: refptr_same return CefRequestCppToC::Wrap(_retval); @@ -30,6 +30,20 @@ CEF_EXPORT cef_request_t* cef_request_create() { // MEMBER FUNCTIONS - Body may be edited by hand. +int CEF_CALLBACK request_is_read_only(struct _cef_request_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + bool _retval = CefRequestCppToC::Get(self)->IsReadOnly(); + + // Return type: bool + return _retval; +} + cef_string_userfree_t CEF_CALLBACK request_get_url( struct _cef_request_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -206,23 +220,21 @@ void CEF_CALLBACK request_set(struct _cef_request_t* self, headerMapMultimap); } -enum cef_weburlrequest_flags_t CEF_CALLBACK request_get_flags( - struct _cef_request_t* self) { +int CEF_CALLBACK request_get_flags(struct _cef_request_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING DCHECK(self); if (!self) - return WUR_FLAG_NONE; + return UR_FLAG_NONE; // Execute - cef_weburlrequest_flags_t _retval = CefRequestCppToC::Get(self)->GetFlags(); + int _retval = CefRequestCppToC::Get(self)->GetFlags(); // Return type: simple return _retval; } -void CEF_CALLBACK request_set_flags(struct _cef_request_t* self, - enum cef_weburlrequest_flags_t flags) { +void CEF_CALLBACK request_set_flags(struct _cef_request_t* self, int flags) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING DCHECK(self); @@ -271,6 +283,7 @@ void CEF_CALLBACK request_set_first_party_for_cookies( CefRequestCppToC::CefRequestCppToC(CefRequest* cls) : CefCppToC(cls) { + struct_.struct_.is_read_only = request_is_read_only; struct_.struct_.get_url = request_get_url; struct_.struct_.set_url = request_set_url; struct_.struct_.get_method = request_get_method; diff --git a/libcef_dll/cpptoc/resource_handler_cpptoc.cc b/libcef_dll/cpptoc/resource_handler_cpptoc.cc index 0572e8192..bac30539f 100644 --- a/libcef_dll/cpptoc/resource_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/resource_handler_cpptoc.cc @@ -120,6 +120,56 @@ int CEF_CALLBACK resource_handler_read_response( return _retval; } +int CEF_CALLBACK resource_handler_can_get_cookie( + struct _cef_resource_handler_t* self, const struct _cef_cookie_t* cookie) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + // Verify param: cookie; type: struct_byref_const + DCHECK(cookie); + if (!cookie) + return 0; + + // Translate param: cookie; type: struct_byref_const + CefCookie cookieObj; + if (cookie) + cookieObj.Set(*cookie, false); + + // Execute + bool _retval = CefResourceHandlerCppToC::Get(self)->CanGetCookie( + cookieObj); + + // Return type: bool + return _retval; +} + +int CEF_CALLBACK resource_handler_can_set_cookie( + struct _cef_resource_handler_t* self, const struct _cef_cookie_t* cookie) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + // Verify param: cookie; type: struct_byref_const + DCHECK(cookie); + if (!cookie) + return 0; + + // Translate param: cookie; type: struct_byref_const + CefCookie cookieObj; + if (cookie) + cookieObj.Set(*cookie, false); + + // Execute + bool _retval = CefResourceHandlerCppToC::Get(self)->CanSetCookie( + cookieObj); + + // Return type: bool + return _retval; +} + void CEF_CALLBACK resource_handler_cancel( struct _cef_resource_handler_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -141,6 +191,8 @@ CefResourceHandlerCppToC::CefResourceHandlerCppToC(CefResourceHandler* cls) struct_.struct_.process_request = resource_handler_process_request; struct_.struct_.get_response_headers = resource_handler_get_response_headers; struct_.struct_.read_response = resource_handler_read_response; + struct_.struct_.can_get_cookie = resource_handler_can_get_cookie; + struct_.struct_.can_set_cookie = resource_handler_can_set_cookie; struct_.struct_.cancel = resource_handler_cancel; } diff --git a/libcef_dll/cpptoc/response_cpptoc.cc b/libcef_dll/cpptoc/response_cpptoc.cc index be51c228f..95bbe9223 100644 --- a/libcef_dll/cpptoc/response_cpptoc.cc +++ b/libcef_dll/cpptoc/response_cpptoc.cc @@ -14,8 +14,35 @@ #include "libcef_dll/transfer_util.h" +// GLOBAL FUNCTIONS - Body may be edited by hand. + +CEF_EXPORT cef_response_t* cef_response_create() { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + CefRefPtr _retval = CefResponse::Create(); + + // Return type: refptr_same + return CefResponseCppToC::Wrap(_retval); +} + + // MEMBER FUNCTIONS - Body may be edited by hand. +int CEF_CALLBACK response_is_read_only(struct _cef_response_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + bool _retval = CefResponseCppToC::Get(self)->IsReadOnly(); + + // Return type: bool + return _retval; +} + int CEF_CALLBACK response_get_status(struct _cef_response_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -178,6 +205,7 @@ void CEF_CALLBACK response_set_header_map(struct _cef_response_t* self, CefResponseCppToC::CefResponseCppToC(CefResponse* cls) : CefCppToC(cls) { + struct_.struct_.is_read_only = response_is_read_only; struct_.struct_.get_status = response_get_status; struct_.struct_.set_status = response_set_status; struct_.struct_.get_status_text = response_get_status_text; diff --git a/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.cc b/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.cc index 9fa0875e7..698527aa0 100644 --- a/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.cc +++ b/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.cc @@ -28,14 +28,6 @@ cef_resource_handler_t* CEF_CALLBACK scheme_handler_factory_create( DCHECK(self); if (!self) return NULL; - // Verify param: browser; type: refptr_diff - DCHECK(browser); - if (!browser) - return NULL; - // Verify param: frame; type: refptr_diff - DCHECK(frame); - if (!frame) - return NULL; // Verify param: scheme_name; type: string_byref_const DCHECK(scheme_name); if (!scheme_name) @@ -44,6 +36,7 @@ cef_resource_handler_t* CEF_CALLBACK scheme_handler_factory_create( DCHECK(request); if (!request) return NULL; + // Unverified params: browser, frame // Execute CefRefPtr _retval = CefSchemeHandlerFactoryCppToC::Get( diff --git a/libcef_dll/cpptoc/urlrequest_client_cpptoc.cc b/libcef_dll/cpptoc/urlrequest_client_cpptoc.cc new file mode 100644 index 000000000..b7e931eb0 --- /dev/null +++ b/libcef_dll/cpptoc/urlrequest_client_cpptoc.cc @@ -0,0 +1,116 @@ +// Copyright (c) 2012 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/urlrequest_client_cpptoc.h" +#include "libcef_dll/ctocpp/urlrequest_ctocpp.h" + + +// MEMBER FUNCTIONS - Body may be edited by hand. + +void CEF_CALLBACK urlrequest_client_on_request_complete( + struct _cef_urlrequest_client_t* self, cef_urlrequest_t* request) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + // Verify param: request; type: refptr_diff + DCHECK(request); + if (!request) + return; + + // Execute + CefURLRequestClientCppToC::Get(self)->OnRequestComplete( + CefURLRequestCToCpp::Wrap(request)); +} + +void CEF_CALLBACK urlrequest_client_on_upload_progress( + struct _cef_urlrequest_client_t* self, cef_urlrequest_t* request, + uint64 current, uint64 total) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + // Verify param: request; type: refptr_diff + DCHECK(request); + if (!request) + return; + + // Execute + CefURLRequestClientCppToC::Get(self)->OnUploadProgress( + CefURLRequestCToCpp::Wrap(request), + current, + total); +} + +void CEF_CALLBACK urlrequest_client_on_download_progress( + struct _cef_urlrequest_client_t* self, cef_urlrequest_t* request, + uint64 current, uint64 total) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + // Verify param: request; type: refptr_diff + DCHECK(request); + if (!request) + return; + + // Execute + CefURLRequestClientCppToC::Get(self)->OnDownloadProgress( + CefURLRequestCToCpp::Wrap(request), + current, + total); +} + +void CEF_CALLBACK urlrequest_client_on_download_data( + struct _cef_urlrequest_client_t* self, cef_urlrequest_t* request, + const void* data, size_t data_length) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + // Verify param: request; type: refptr_diff + DCHECK(request); + if (!request) + return; + // Verify param: data; type: simple_byaddr + DCHECK(data); + if (!data) + return; + + // Execute + CefURLRequestClientCppToC::Get(self)->OnDownloadData( + CefURLRequestCToCpp::Wrap(request), + data, + data_length); +} + + +// CONSTRUCTOR - Do not edit by hand. + +CefURLRequestClientCppToC::CefURLRequestClientCppToC(CefURLRequestClient* cls) + : CefCppToC(cls) { + struct_.struct_.on_request_complete = urlrequest_client_on_request_complete; + struct_.struct_.on_upload_progress = urlrequest_client_on_upload_progress; + struct_.struct_.on_download_progress = urlrequest_client_on_download_progress; + struct_.struct_.on_download_data = urlrequest_client_on_download_data; +} + +#ifndef NDEBUG +template<> long CefCppToC::DebugObjCt = 0; +#endif + diff --git a/libcef_dll/cpptoc/urlrequest_client_cpptoc.h b/libcef_dll/cpptoc/urlrequest_client_cpptoc.h new file mode 100644 index 000000000..faac3d89d --- /dev/null +++ b/libcef_dll/cpptoc/urlrequest_client_cpptoc.h @@ -0,0 +1,37 @@ +// Copyright (c) 2012 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_URLREQUEST_CLIENT_CPPTOC_H_ +#define CEF_LIBCEF_DLL_CPPTOC_URLREQUEST_CLIENT_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_urlrequest.h" +#include "include/capi/cef_urlrequest_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 CefURLRequestClientCppToC + : public CefCppToC { + public: + explicit CefURLRequestClientCppToC(CefURLRequestClient* cls); + virtual ~CefURLRequestClientCppToC() {} +}; + +#endif // USING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CPPTOC_URLREQUEST_CLIENT_CPPTOC_H_ + diff --git a/libcef_dll/cpptoc/urlrequest_cpptoc.cc b/libcef_dll/cpptoc/urlrequest_cpptoc.cc new file mode 100644 index 000000000..506ee8085 --- /dev/null +++ b/libcef_dll/cpptoc/urlrequest_cpptoc.cc @@ -0,0 +1,152 @@ +// Copyright (c) 2012 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/request_cpptoc.h" +#include "libcef_dll/cpptoc/response_cpptoc.h" +#include "libcef_dll/cpptoc/urlrequest_cpptoc.h" +#include "libcef_dll/ctocpp/urlrequest_client_ctocpp.h" + + +// 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) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: request; type: refptr_same + DCHECK(request); + if (!request) + return NULL; + // Verify param: client; type: refptr_diff + DCHECK(client); + if (!client) + return NULL; + + // Execute + CefRefPtr _retval = CefURLRequest::Create( + CefRequestCppToC::Unwrap(request), + CefURLRequestClientCToCpp::Wrap(client)); + + // Return type: refptr_same + return CefURLRequestCppToC::Wrap(_retval); +} + + +// MEMBER FUNCTIONS - Body may be edited by hand. + +cef_request_t* CEF_CALLBACK urlrequest_get_request( + struct _cef_urlrequest_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefRefPtr _retval = CefURLRequestCppToC::Get(self)->GetRequest(); + + // Return type: refptr_same + return CefRequestCppToC::Wrap(_retval); +} + +struct _cef_urlrequest_client_t* CEF_CALLBACK urlrequest_get_client( + struct _cef_urlrequest_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefRefPtr _retval = CefURLRequestCppToC::Get( + self)->GetClient(); + + // Return type: refptr_diff + return CefURLRequestClientCToCpp::Unwrap(_retval); +} + +enum cef_urlrequest_status_t CEF_CALLBACK urlrequest_get_request_status( + struct _cef_urlrequest_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return UR_UNKNOWN; + + // Execute + cef_urlrequest_status_t _retval = CefURLRequestCppToC::Get( + self)->GetRequestStatus(); + + // Return type: simple + return _retval; +} + +enum cef_errorcode_t CEF_CALLBACK urlrequest_get_request_error( + struct _cef_urlrequest_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return ERR_NONE; + + // Execute + cef_errorcode_t _retval = CefURLRequestCppToC::Get(self)->GetRequestError(); + + // Return type: simple + return _retval; +} + +cef_response_t* CEF_CALLBACK urlrequest_get_response( + struct _cef_urlrequest_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefRefPtr _retval = CefURLRequestCppToC::Get(self)->GetResponse( + ); + + // Return type: refptr_same + return CefResponseCppToC::Wrap(_retval); +} + +void CEF_CALLBACK urlrequest_cancel(struct _cef_urlrequest_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + + // Execute + CefURLRequestCppToC::Get(self)->Cancel(); +} + + +// CONSTRUCTOR - Do not edit by hand. + +CefURLRequestCppToC::CefURLRequestCppToC(CefURLRequest* cls) + : CefCppToC(cls) { + struct_.struct_.get_request = urlrequest_get_request; + struct_.struct_.get_client = urlrequest_get_client; + struct_.struct_.get_request_status = urlrequest_get_request_status; + struct_.struct_.get_request_error = urlrequest_get_request_error; + struct_.struct_.get_response = urlrequest_get_response; + struct_.struct_.cancel = urlrequest_cancel; +} + +#ifndef NDEBUG +template<> long CefCppToC::DebugObjCt = 0; +#endif + diff --git a/libcef_dll/cpptoc/urlrequest_cpptoc.h b/libcef_dll/cpptoc/urlrequest_cpptoc.h new file mode 100644 index 000000000..fc26a30c4 --- /dev/null +++ b/libcef_dll/cpptoc/urlrequest_cpptoc.h @@ -0,0 +1,36 @@ +// Copyright (c) 2012 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_URLREQUEST_CPPTOC_H_ +#define CEF_LIBCEF_DLL_CPPTOC_URLREQUEST_CPPTOC_H_ +#pragma once + +#ifndef BUILDING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed DLL-side only") +#else // BUILDING_CEF_SHARED + +#include "include/cef_urlrequest.h" +#include "include/capi/cef_urlrequest_capi.h" +#include "libcef_dll/cpptoc/cpptoc.h" + +// Wrap a C++ class with a C structure. +// This class may be instantiated and accessed DLL-side only. +class CefURLRequestCppToC + : public CefCppToC { + public: + explicit CefURLRequestCppToC(CefURLRequest* cls); + virtual ~CefURLRequestCppToC() {} +}; + +#endif // BUILDING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CPPTOC_URLREQUEST_CPPTOC_H_ + diff --git a/libcef_dll/ctocpp/app_ctocpp.cc b/libcef_dll/ctocpp/app_ctocpp.cc index 44fd00c22..0b3ea5405 100644 --- a/libcef_dll/ctocpp/app_ctocpp.cc +++ b/libcef_dll/ctocpp/app_ctocpp.cc @@ -13,7 +13,7 @@ #include "libcef_dll/cpptoc/command_line_cpptoc.h" #include "libcef_dll/cpptoc/scheme_registrar_cpptoc.h" #include "libcef_dll/ctocpp/app_ctocpp.h" -#include "libcef_dll/ctocpp/proxy_handler_ctocpp.h" +#include "libcef_dll/ctocpp/browser_process_handler_ctocpp.h" #include "libcef_dll/ctocpp/render_process_handler_ctocpp.h" #include "libcef_dll/ctocpp/resource_bundle_handler_ctocpp.h" @@ -56,20 +56,6 @@ void CefAppCToCpp::OnRegisterCustomSchemes( CefSchemeRegistrarCppToC::Wrap(registrar)); } -CefRefPtr CefAppCToCpp::GetRenderProcessHandler() { - if (CEF_MEMBER_MISSING(struct_, get_render_process_handler)) - return NULL; - - // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING - - // Execute - cef_render_process_handler_t* _retval = struct_->get_render_process_handler( - struct_); - - // Return type: refptr_same - return CefRenderProcessHandlerCToCpp::Wrap(_retval); -} - CefRefPtr CefAppCToCpp::GetResourceBundleHandler() { if (CEF_MEMBER_MISSING(struct_, get_resource_bundle_handler)) return NULL; @@ -84,17 +70,32 @@ CefRefPtr CefAppCToCpp::GetResourceBundleHandler() { return CefResourceBundleHandlerCToCpp::Wrap(_retval); } -CefRefPtr CefAppCToCpp::GetProxyHandler() { - if (CEF_MEMBER_MISSING(struct_, get_proxy_handler)) +CefRefPtr CefAppCToCpp::GetBrowserProcessHandler() { + if (CEF_MEMBER_MISSING(struct_, get_browser_process_handler)) return NULL; // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // Execute - cef_proxy_handler_t* _retval = struct_->get_proxy_handler(struct_); + cef_browser_process_handler_t* _retval = struct_->get_browser_process_handler( + struct_); // Return type: refptr_same - return CefProxyHandlerCToCpp::Wrap(_retval); + return CefBrowserProcessHandlerCToCpp::Wrap(_retval); +} + +CefRefPtr CefAppCToCpp::GetRenderProcessHandler() { + if (CEF_MEMBER_MISSING(struct_, get_render_process_handler)) + return NULL; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_render_process_handler_t* _retval = struct_->get_render_process_handler( + struct_); + + // Return type: refptr_same + return CefRenderProcessHandlerCToCpp::Wrap(_retval); } diff --git a/libcef_dll/ctocpp/app_ctocpp.h b/libcef_dll/ctocpp/app_ctocpp.h index 5defb9bab..8707addca 100644 --- a/libcef_dll/ctocpp/app_ctocpp.h +++ b/libcef_dll/ctocpp/app_ctocpp.h @@ -36,10 +36,11 @@ class CefAppCToCpp CefRefPtr command_line) OVERRIDE; virtual void OnRegisterCustomSchemes( CefRefPtr registrar) OVERRIDE; - virtual CefRefPtr GetRenderProcessHandler() OVERRIDE; virtual CefRefPtr GetResourceBundleHandler( ) OVERRIDE; - virtual CefRefPtr GetProxyHandler() OVERRIDE; + virtual CefRefPtr GetBrowserProcessHandler( + ) OVERRIDE; + virtual CefRefPtr GetRenderProcessHandler() OVERRIDE; }; #endif // BUILDING_CEF_SHARED diff --git a/libcef_dll/ctocpp/browser_process_handler_ctocpp.cc b/libcef_dll/ctocpp/browser_process_handler_ctocpp.cc new file mode 100644 index 000000000..4f51ae702 --- /dev/null +++ b/libcef_dll/ctocpp/browser_process_handler_ctocpp.cc @@ -0,0 +1,47 @@ +// Copyright (c) 2012 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/browser_process_handler_ctocpp.h" +#include "libcef_dll/ctocpp/proxy_handler_ctocpp.h" + + +// VIRTUAL METHODS - Body may be edited by hand. + +CefRefPtr CefBrowserProcessHandlerCToCpp::GetProxyHandler() { + if (CEF_MEMBER_MISSING(struct_, get_proxy_handler)) + return NULL; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_proxy_handler_t* _retval = struct_->get_proxy_handler(struct_); + + // Return type: refptr_same + return CefProxyHandlerCToCpp::Wrap(_retval); +} + +void CefBrowserProcessHandlerCToCpp::OnContextInitialized() { + if (CEF_MEMBER_MISSING(struct_, on_context_initialized)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + struct_->on_context_initialized(struct_); +} + + +#ifndef NDEBUG +template<> long CefCToCpp::DebugObjCt = 0; +#endif + diff --git a/libcef_dll/ctocpp/browser_process_handler_ctocpp.h b/libcef_dll/ctocpp/browser_process_handler_ctocpp.h new file mode 100644 index 000000000..25913aa3b --- /dev/null +++ b/libcef_dll/ctocpp/browser_process_handler_ctocpp.h @@ -0,0 +1,43 @@ +// Copyright (c) 2012 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_BROWSER_PROCESS_HANDLER_CTOCPP_H_ +#define CEF_LIBCEF_DLL_CTOCPP_BROWSER_PROCESS_HANDLER_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_browser_process_handler.h" +#include "include/capi/cef_browser_process_handler_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 CefBrowserProcessHandlerCToCpp + : public CefCToCpp { + public: + explicit CefBrowserProcessHandlerCToCpp(cef_browser_process_handler_t* str) + : CefCToCpp(str) {} + virtual ~CefBrowserProcessHandlerCToCpp() {} + + // CefBrowserProcessHandler methods + virtual CefRefPtr GetProxyHandler() OVERRIDE; + virtual void OnContextInitialized() OVERRIDE; +}; + +#endif // BUILDING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CTOCPP_BROWSER_PROCESS_HANDLER_CTOCPP_H_ + diff --git a/libcef_dll/ctocpp/post_data_ctocpp.cc b/libcef_dll/ctocpp/post_data_ctocpp.cc index 0a0c593cf..f698c8893 100644 --- a/libcef_dll/ctocpp/post_data_ctocpp.cc +++ b/libcef_dll/ctocpp/post_data_ctocpp.cc @@ -16,7 +16,7 @@ // STATIC METHODS - Body may be edited by hand. -CefRefPtr CefPostData::CreatePostData() { +CefRefPtr CefPostData::Create() { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // Execute @@ -29,6 +29,19 @@ CefRefPtr CefPostData::CreatePostData() { // VIRTUAL METHODS - Body may be edited by hand. +bool CefPostDataCToCpp::IsReadOnly() { + if (CEF_MEMBER_MISSING(struct_, is_read_only)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->is_read_only(struct_); + + // Return type: bool + return _retval?true:false; +} + size_t CefPostDataCToCpp::GetElementCount() { if (CEF_MEMBER_MISSING(struct_, get_element_count)) return 0; diff --git a/libcef_dll/ctocpp/post_data_ctocpp.h b/libcef_dll/ctocpp/post_data_ctocpp.h index 505980dfd..12e9e36ac 100644 --- a/libcef_dll/ctocpp/post_data_ctocpp.h +++ b/libcef_dll/ctocpp/post_data_ctocpp.h @@ -32,6 +32,7 @@ class CefPostDataCToCpp virtual ~CefPostDataCToCpp() {} // CefPostData methods + virtual bool IsReadOnly() OVERRIDE; virtual size_t GetElementCount() OVERRIDE; virtual void GetElements(ElementVector& elements) OVERRIDE; virtual bool RemoveElement(CefRefPtr element) OVERRIDE; diff --git a/libcef_dll/ctocpp/post_data_element_ctocpp.cc b/libcef_dll/ctocpp/post_data_element_ctocpp.cc index b931ecbca..005072fc4 100644 --- a/libcef_dll/ctocpp/post_data_element_ctocpp.cc +++ b/libcef_dll/ctocpp/post_data_element_ctocpp.cc @@ -15,7 +15,7 @@ // STATIC METHODS - Body may be edited by hand. -CefRefPtr CefPostDataElement::CreatePostDataElement() { +CefRefPtr CefPostDataElement::Create() { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // Execute @@ -28,6 +28,19 @@ CefRefPtr CefPostDataElement::CreatePostDataElement() { // VIRTUAL METHODS - Body may be edited by hand. +bool CefPostDataElementCToCpp::IsReadOnly() { + if (CEF_MEMBER_MISSING(struct_, is_read_only)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->is_read_only(struct_); + + // Return type: bool + return _retval?true:false; +} + void CefPostDataElementCToCpp::SetToEmpty() { if (CEF_MEMBER_MISSING(struct_, set_to_empty)) return; diff --git a/libcef_dll/ctocpp/post_data_element_ctocpp.h b/libcef_dll/ctocpp/post_data_element_ctocpp.h index 2840dbdbd..7c7e2c143 100644 --- a/libcef_dll/ctocpp/post_data_element_ctocpp.h +++ b/libcef_dll/ctocpp/post_data_element_ctocpp.h @@ -34,6 +34,7 @@ class CefPostDataElementCToCpp virtual ~CefPostDataElementCToCpp() {} // CefPostDataElement methods + virtual bool IsReadOnly() OVERRIDE; virtual void SetToEmpty() OVERRIDE; virtual void SetToFile(const CefString& fileName) OVERRIDE; virtual void SetToBytes(size_t size, const void* bytes) OVERRIDE; diff --git a/libcef_dll/ctocpp/request_ctocpp.cc b/libcef_dll/ctocpp/request_ctocpp.cc index e34c508ea..bb686ac62 100644 --- a/libcef_dll/ctocpp/request_ctocpp.cc +++ b/libcef_dll/ctocpp/request_ctocpp.cc @@ -17,7 +17,7 @@ // STATIC METHODS - Body may be edited by hand. -CefRefPtr CefRequest::CreateRequest() { +CefRefPtr CefRequest::Create() { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // Execute @@ -30,6 +30,19 @@ CefRefPtr CefRequest::CreateRequest() { // VIRTUAL METHODS - Body may be edited by hand. +bool CefRequestCToCpp::IsReadOnly() { + if (CEF_MEMBER_MISSING(struct_, is_read_only)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->is_read_only(struct_); + + // Return type: bool + return _retval?true:false; +} + CefString CefRequestCToCpp::GetURL() { if (CEF_MEMBER_MISSING(struct_, get_url)) return CefString(); @@ -201,20 +214,20 @@ void CefRequestCToCpp::Set(const CefString& url, const CefString& method, cef_string_multimap_free(headerMapMultimap); } -CefRequest::RequestFlags CefRequestCToCpp::GetFlags() { +int CefRequestCToCpp::GetFlags() { if (CEF_MEMBER_MISSING(struct_, get_flags)) - return WUR_FLAG_NONE; + return UR_FLAG_NONE; // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // Execute - cef_weburlrequest_flags_t _retval = struct_->get_flags(struct_); + int _retval = struct_->get_flags(struct_); // Return type: simple return _retval; } -void CefRequestCToCpp::SetFlags(RequestFlags flags) { +void CefRequestCToCpp::SetFlags(int flags) { if (CEF_MEMBER_MISSING(struct_, set_flags)) return; diff --git a/libcef_dll/ctocpp/request_ctocpp.h b/libcef_dll/ctocpp/request_ctocpp.h index 77be93ba2..18731c6a9 100644 --- a/libcef_dll/ctocpp/request_ctocpp.h +++ b/libcef_dll/ctocpp/request_ctocpp.h @@ -32,6 +32,7 @@ class CefRequestCToCpp virtual ~CefRequestCToCpp() {} // CefRequest methods + virtual bool IsReadOnly() OVERRIDE; virtual CefString GetURL() OVERRIDE; virtual void SetURL(const CefString& url) OVERRIDE; virtual CefString GetMethod() OVERRIDE; @@ -42,8 +43,8 @@ class CefRequestCToCpp virtual void SetHeaderMap(const HeaderMap& headerMap) OVERRIDE; virtual void Set(const CefString& url, const CefString& method, CefRefPtr postData, const HeaderMap& headerMap) OVERRIDE; - virtual RequestFlags GetFlags() OVERRIDE; - virtual void SetFlags(RequestFlags flags) OVERRIDE; + virtual int GetFlags() OVERRIDE; + virtual void SetFlags(int flags) OVERRIDE; virtual CefString GetFirstPartyForCookies() OVERRIDE; virtual void SetFirstPartyForCookies(const CefString& url) OVERRIDE; }; diff --git a/libcef_dll/ctocpp/resource_handler_ctocpp.cc b/libcef_dll/ctocpp/resource_handler_ctocpp.cc index c9b4c2067..6b4444a24 100644 --- a/libcef_dll/ctocpp/resource_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/resource_handler_ctocpp.cc @@ -90,6 +90,34 @@ bool CefResourceHandlerCToCpp::ReadResponse(void* data_out, int bytes_to_read, return _retval?true:false; } +bool CefResourceHandlerCToCpp::CanGetCookie(const CefCookie& cookie) { + if (CEF_MEMBER_MISSING(struct_, can_get_cookie)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->can_get_cookie(struct_, + &cookie); + + // Return type: bool + return _retval?true:false; +} + +bool CefResourceHandlerCToCpp::CanSetCookie(const CefCookie& cookie) { + if (CEF_MEMBER_MISSING(struct_, can_set_cookie)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->can_set_cookie(struct_, + &cookie); + + // Return type: bool + return _retval?true:false; +} + void CefResourceHandlerCToCpp::Cancel() { if (CEF_MEMBER_MISSING(struct_, cancel)) return; diff --git a/libcef_dll/ctocpp/resource_handler_ctocpp.h b/libcef_dll/ctocpp/resource_handler_ctocpp.h index e6c89b909..018c57f5f 100644 --- a/libcef_dll/ctocpp/resource_handler_ctocpp.h +++ b/libcef_dll/ctocpp/resource_handler_ctocpp.h @@ -40,6 +40,8 @@ class CefResourceHandlerCToCpp int64& response_length, CefString& redirectUrl) OVERRIDE; virtual bool ReadResponse(void* data_out, int bytes_to_read, int& bytes_read, CefRefPtr callback) OVERRIDE; + virtual bool CanGetCookie(const CefCookie& cookie) OVERRIDE; + virtual bool CanSetCookie(const CefCookie& cookie) OVERRIDE; virtual void Cancel() OVERRIDE; }; diff --git a/libcef_dll/ctocpp/response_ctocpp.cc b/libcef_dll/ctocpp/response_ctocpp.cc index e5bfc0286..25cc12671 100644 --- a/libcef_dll/ctocpp/response_ctocpp.cc +++ b/libcef_dll/ctocpp/response_ctocpp.cc @@ -14,8 +14,34 @@ #include "libcef_dll/transfer_util.h" +// STATIC METHODS - Body may be edited by hand. + +CefRefPtr CefResponse::Create() { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_response_t* _retval = cef_response_create(); + + // Return type: refptr_same + return CefResponseCToCpp::Wrap(_retval); +} + + // VIRTUAL METHODS - Body may be edited by hand. +bool CefResponseCToCpp::IsReadOnly() { + if (CEF_MEMBER_MISSING(struct_, is_read_only)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->is_read_only(struct_); + + // Return type: bool + return _retval?true:false; +} + int CefResponseCToCpp::GetStatus() { if (CEF_MEMBER_MISSING(struct_, get_status)) return 0; diff --git a/libcef_dll/ctocpp/response_ctocpp.h b/libcef_dll/ctocpp/response_ctocpp.h index 8ec8a1fc2..280e840d2 100644 --- a/libcef_dll/ctocpp/response_ctocpp.h +++ b/libcef_dll/ctocpp/response_ctocpp.h @@ -32,6 +32,7 @@ class CefResponseCToCpp virtual ~CefResponseCToCpp() {} // CefResponse methods + virtual bool IsReadOnly() OVERRIDE; virtual int GetStatus() OVERRIDE; virtual void SetStatus(int status) OVERRIDE; virtual CefString GetStatusText() OVERRIDE; diff --git a/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.cc b/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.cc index 7fa6d3fe1..1005c06db 100644 --- a/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.cc +++ b/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.cc @@ -27,14 +27,6 @@ CefRefPtr CefSchemeHandlerFactoryCToCpp::Create( // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING - // Verify param: browser; type: refptr_diff - DCHECK(browser.get()); - if (!browser.get()) - return NULL; - // Verify param: frame; type: refptr_diff - DCHECK(frame.get()); - if (!frame.get()) - return NULL; // Verify param: scheme_name; type: string_byref_const DCHECK(!scheme_name.empty()); if (scheme_name.empty()) @@ -43,6 +35,7 @@ CefRefPtr CefSchemeHandlerFactoryCToCpp::Create( DCHECK(request.get()); if (!request.get()) return NULL; + // Unverified params: browser, frame // Execute cef_resource_handler_t* _retval = struct_->create(struct_, diff --git a/libcef_dll/ctocpp/urlrequest_client_ctocpp.cc b/libcef_dll/ctocpp/urlrequest_client_ctocpp.cc new file mode 100644 index 000000000..a3a1644f1 --- /dev/null +++ b/libcef_dll/ctocpp/urlrequest_client_ctocpp.cc @@ -0,0 +1,102 @@ +// Copyright (c) 2012 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/urlrequest_cpptoc.h" +#include "libcef_dll/ctocpp/urlrequest_client_ctocpp.h" + + +// VIRTUAL METHODS - Body may be edited by hand. + +void CefURLRequestClientCToCpp::OnRequestComplete( + CefRefPtr request) { + if (CEF_MEMBER_MISSING(struct_, on_request_complete)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: request; type: refptr_diff + DCHECK(request.get()); + if (!request.get()) + return; + + // Execute + struct_->on_request_complete(struct_, + CefURLRequestCppToC::Wrap(request)); +} + +void CefURLRequestClientCToCpp::OnUploadProgress( + CefRefPtr request, uint64 current, uint64 total) { + if (CEF_MEMBER_MISSING(struct_, on_upload_progress)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: request; type: refptr_diff + DCHECK(request.get()); + if (!request.get()) + return; + + // Execute + struct_->on_upload_progress(struct_, + CefURLRequestCppToC::Wrap(request), + current, + total); +} + +void CefURLRequestClientCToCpp::OnDownloadProgress( + CefRefPtr request, uint64 current, uint64 total) { + if (CEF_MEMBER_MISSING(struct_, on_download_progress)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: request; type: refptr_diff + DCHECK(request.get()); + if (!request.get()) + return; + + // Execute + struct_->on_download_progress(struct_, + CefURLRequestCppToC::Wrap(request), + current, + total); +} + +void CefURLRequestClientCToCpp::OnDownloadData(CefRefPtr request, + const void* data, size_t data_length) { + if (CEF_MEMBER_MISSING(struct_, on_download_data)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: request; type: refptr_diff + DCHECK(request.get()); + if (!request.get()) + return; + // Verify param: data; type: simple_byaddr + DCHECK(data); + if (!data) + return; + + // Execute + struct_->on_download_data(struct_, + CefURLRequestCppToC::Wrap(request), + data, + data_length); +} + + +#ifndef NDEBUG +template<> long CefCToCpp::DebugObjCt = 0; +#endif + diff --git a/libcef_dll/ctocpp/urlrequest_client_ctocpp.h b/libcef_dll/ctocpp/urlrequest_client_ctocpp.h new file mode 100644 index 000000000..987aaffc5 --- /dev/null +++ b/libcef_dll/ctocpp/urlrequest_client_ctocpp.h @@ -0,0 +1,48 @@ +// Copyright (c) 2012 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_URLREQUEST_CLIENT_CTOCPP_H_ +#define CEF_LIBCEF_DLL_CTOCPP_URLREQUEST_CLIENT_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_urlrequest.h" +#include "include/capi/cef_urlrequest_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 CefURLRequestClientCToCpp + : public CefCToCpp { + public: + explicit CefURLRequestClientCToCpp(cef_urlrequest_client_t* str) + : CefCToCpp(str) {} + virtual ~CefURLRequestClientCToCpp() {} + + // CefURLRequestClient methods + virtual void OnRequestComplete(CefRefPtr request) OVERRIDE; + virtual void OnUploadProgress(CefRefPtr request, + uint64 current, uint64 total) OVERRIDE; + virtual void OnDownloadProgress(CefRefPtr request, + uint64 current, uint64 total) OVERRIDE; + virtual void OnDownloadData(CefRefPtr request, + const void* data, size_t data_length) OVERRIDE; +}; + +#endif // BUILDING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CTOCPP_URLREQUEST_CLIENT_CTOCPP_H_ + diff --git a/libcef_dll/ctocpp/urlrequest_ctocpp.cc b/libcef_dll/ctocpp/urlrequest_ctocpp.cc new file mode 100644 index 000000000..9292295a5 --- /dev/null +++ b/libcef_dll/ctocpp/urlrequest_ctocpp.cc @@ -0,0 +1,126 @@ +// Copyright (c) 2012 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/urlrequest_client_cpptoc.h" +#include "libcef_dll/ctocpp/request_ctocpp.h" +#include "libcef_dll/ctocpp/response_ctocpp.h" +#include "libcef_dll/ctocpp/urlrequest_ctocpp.h" + + +// STATIC METHODS - Body may be edited by hand. + +CefRefPtr CefURLRequest::Create(CefRefPtr request, + CefRefPtr client) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: request; type: refptr_same + DCHECK(request.get()); + if (!request.get()) + return NULL; + // Verify param: client; type: refptr_diff + DCHECK(client.get()); + if (!client.get()) + return NULL; + + // Execute + cef_urlrequest_t* _retval = cef_urlrequest_create( + CefRequestCToCpp::Unwrap(request), + CefURLRequestClientCppToC::Wrap(client)); + + // Return type: refptr_same + return CefURLRequestCToCpp::Wrap(_retval); +} + + +// VIRTUAL METHODS - Body may be edited by hand. + +CefRefPtr CefURLRequestCToCpp::GetRequest() { + if (CEF_MEMBER_MISSING(struct_, get_request)) + return NULL; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_request_t* _retval = struct_->get_request(struct_); + + // Return type: refptr_same + return CefRequestCToCpp::Wrap(_retval); +} + +CefRefPtr CefURLRequestCToCpp::GetClient() { + if (CEF_MEMBER_MISSING(struct_, get_client)) + return NULL; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_urlrequest_client_t* _retval = struct_->get_client(struct_); + + // Return type: refptr_diff + return CefURLRequestClientCppToC::Unwrap(_retval); +} + +CefURLRequest::Status CefURLRequestCToCpp::GetRequestStatus() { + if (CEF_MEMBER_MISSING(struct_, get_request_status)) + return UR_UNKNOWN; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_urlrequest_status_t _retval = struct_->get_request_status(struct_); + + // Return type: simple + return _retval; +} + +CefURLRequest::ErrorCode CefURLRequestCToCpp::GetRequestError() { + if (CEF_MEMBER_MISSING(struct_, get_request_error)) + return ERR_NONE; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_errorcode_t _retval = struct_->get_request_error(struct_); + + // Return type: simple + return _retval; +} + +CefRefPtr CefURLRequestCToCpp::GetResponse() { + if (CEF_MEMBER_MISSING(struct_, get_response)) + return NULL; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_response_t* _retval = struct_->get_response(struct_); + + // Return type: refptr_same + return CefResponseCToCpp::Wrap(_retval); +} + +void CefURLRequestCToCpp::Cancel() { + if (CEF_MEMBER_MISSING(struct_, cancel)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + struct_->cancel(struct_); +} + + +#ifndef NDEBUG +template<> long CefCToCpp::DebugObjCt = 0; +#endif + diff --git a/libcef_dll/ctocpp/urlrequest_ctocpp.h b/libcef_dll/ctocpp/urlrequest_ctocpp.h new file mode 100644 index 000000000..f13c7c638 --- /dev/null +++ b/libcef_dll/ctocpp/urlrequest_ctocpp.h @@ -0,0 +1,45 @@ +// Copyright (c) 2012 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_URLREQUEST_CTOCPP_H_ +#define CEF_LIBCEF_DLL_CTOCPP_URLREQUEST_CTOCPP_H_ +#pragma once + +#ifndef USING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed wrapper-side only") +#else // USING_CEF_SHARED + +#include "include/cef_urlrequest.h" +#include "include/capi/cef_urlrequest_capi.h" +#include "libcef_dll/ctocpp/ctocpp.h" + +// Wrap a C structure with a C++ class. +// This class may be instantiated and accessed wrapper-side only. +class CefURLRequestCToCpp + : public CefCToCpp { + public: + explicit CefURLRequestCToCpp(cef_urlrequest_t* str) + : CefCToCpp(str) {} + virtual ~CefURLRequestCToCpp() {} + + // CefURLRequest methods + virtual CefRefPtr GetRequest() OVERRIDE; + virtual CefRefPtr GetClient() OVERRIDE; + virtual Status GetRequestStatus() OVERRIDE; + virtual ErrorCode GetRequestError() OVERRIDE; + virtual CefRefPtr GetResponse() OVERRIDE; + virtual void Cancel() OVERRIDE; +}; + +#endif // USING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CTOCPP_URLREQUEST_CTOCPP_H_ + diff --git a/libcef_dll/libcef_dll.cc b/libcef_dll/libcef_dll.cc index 72ab5b245..d8d7da271 100644 --- a/libcef_dll/libcef_dll.cc +++ b/libcef_dll/libcef_dll.cc @@ -40,14 +40,11 @@ #include "libcef_dll/cpptoc/jsdialog_callback_cpptoc.h" #include "libcef_dll/cpptoc/list_value_cpptoc.h" #include "libcef_dll/cpptoc/menu_model_cpptoc.h" -#include "libcef_dll/cpptoc/post_data_cpptoc.h" -#include "libcef_dll/cpptoc/post_data_element_cpptoc.h" #include "libcef_dll/cpptoc/process_message_cpptoc.h" -#include "libcef_dll/cpptoc/request_cpptoc.h" -#include "libcef_dll/cpptoc/response_cpptoc.h" #include "libcef_dll/cpptoc/scheme_registrar_cpptoc.h" #include "libcef_dll/cpptoc/stream_reader_cpptoc.h" #include "libcef_dll/cpptoc/stream_writer_cpptoc.h" +#include "libcef_dll/cpptoc/urlrequest_cpptoc.h" #include "libcef_dll/cpptoc/v8context_cpptoc.h" #include "libcef_dll/cpptoc/v8exception_cpptoc.h" #include "libcef_dll/cpptoc/v8value_cpptoc.h" @@ -55,6 +52,7 @@ #include "libcef_dll/cpptoc/xml_reader_cpptoc.h" #include "libcef_dll/cpptoc/zip_reader_cpptoc.h" #include "libcef_dll/ctocpp/app_ctocpp.h" +#include "libcef_dll/ctocpp/browser_process_handler_ctocpp.h" #include "libcef_dll/ctocpp/context_menu_handler_ctocpp.h" #include "libcef_dll/ctocpp/cookie_visitor_ctocpp.h" #include "libcef_dll/ctocpp/domevent_listener_ctocpp.h" @@ -75,6 +73,7 @@ #include "libcef_dll/ctocpp/scheme_handler_factory_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" #include "libcef_dll/ctocpp/v8accessor_ctocpp.h" #include "libcef_dll/ctocpp/v8handler_ctocpp.h" #include "libcef_dll/ctocpp/web_plugin_info_visitor_ctocpp.h" @@ -152,6 +151,7 @@ CEF_EXPORT void cef_shutdown() { DCHECK_EQ(CefBinaryValueCppToC::DebugObjCt, 0); DCHECK_EQ(CefBrowserCppToC::DebugObjCt, 0); DCHECK_EQ(CefBrowserHostCppToC::DebugObjCt, 0); + DCHECK_EQ(CefBrowserProcessHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefCallbackCppToC::DebugObjCt, 0); DCHECK_EQ(CefContextMenuHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefContextMenuParamsCppToC::DebugObjCt, 0); @@ -175,23 +175,21 @@ CEF_EXPORT void cef_shutdown() { DCHECK_EQ(CefListValueCppToC::DebugObjCt, 0); DCHECK_EQ(CefLoadHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefMenuModelCppToC::DebugObjCt, 0); - DCHECK_EQ(CefPostDataCppToC::DebugObjCt, 0); - DCHECK_EQ(CefPostDataElementCppToC::DebugObjCt, 0); DCHECK_EQ(CefProcessMessageCppToC::DebugObjCt, 0); DCHECK_EQ(CefProxyHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefReadHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefRenderProcessHandlerCToCpp::DebugObjCt, 0); - DCHECK_EQ(CefRequestCppToC::DebugObjCt, 0); DCHECK_EQ(CefRequestHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefResourceBundleHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefResourceHandlerCToCpp::DebugObjCt, 0); - DCHECK_EQ(CefResponseCppToC::DebugObjCt, 0); DCHECK_EQ(CefSchemeHandlerFactoryCToCpp::DebugObjCt, 0); DCHECK_EQ(CefSchemeRegistrarCppToC::DebugObjCt, 0); DCHECK_EQ(CefStreamReaderCppToC::DebugObjCt, 0); DCHECK_EQ(CefStreamWriterCppToC::DebugObjCt, 0); DCHECK_EQ(CefStringVisitorCToCpp::DebugObjCt, 0); DCHECK_EQ(CefTaskCToCpp::DebugObjCt, 0); + DCHECK_EQ(CefURLRequestClientCToCpp::DebugObjCt, 0); + DCHECK_EQ(CefURLRequestCppToC::DebugObjCt, 0); DCHECK_EQ(CefV8AccessorCToCpp::DebugObjCt, 0); DCHECK_EQ(CefV8ContextCppToC::DebugObjCt, 0); DCHECK_EQ(CefV8ExceptionCppToC::DebugObjCt, 0); diff --git a/libcef_dll/wrapper/libcef_dll_wrapper.cc b/libcef_dll/wrapper/libcef_dll_wrapper.cc index 44847a8e5..d9ab4013a 100644 --- a/libcef_dll/wrapper/libcef_dll_wrapper.cc +++ b/libcef_dll/wrapper/libcef_dll_wrapper.cc @@ -26,6 +26,7 @@ #include "include/capi/cef_web_plugin_capi.h" #include "include/cef_version.h" #include "libcef_dll/cpptoc/app_cpptoc.h" +#include "libcef_dll/cpptoc/browser_process_handler_cpptoc.h" #include "libcef_dll/cpptoc/context_menu_handler_cpptoc.h" #include "libcef_dll/cpptoc/cookie_visitor_cpptoc.h" #include "libcef_dll/cpptoc/domevent_listener_cpptoc.h" @@ -46,6 +47,7 @@ #include "libcef_dll/cpptoc/scheme_handler_factory_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" #include "libcef_dll/cpptoc/v8accessor_cpptoc.h" #include "libcef_dll/cpptoc/v8handler_cpptoc.h" #include "libcef_dll/cpptoc/web_plugin_info_visitor_cpptoc.h" @@ -66,14 +68,11 @@ #include "libcef_dll/ctocpp/jsdialog_callback_ctocpp.h" #include "libcef_dll/ctocpp/list_value_ctocpp.h" #include "libcef_dll/ctocpp/menu_model_ctocpp.h" -#include "libcef_dll/ctocpp/post_data_ctocpp.h" -#include "libcef_dll/ctocpp/post_data_element_ctocpp.h" #include "libcef_dll/ctocpp/process_message_ctocpp.h" -#include "libcef_dll/ctocpp/request_ctocpp.h" -#include "libcef_dll/ctocpp/response_ctocpp.h" #include "libcef_dll/ctocpp/scheme_registrar_ctocpp.h" #include "libcef_dll/ctocpp/stream_reader_ctocpp.h" #include "libcef_dll/ctocpp/stream_writer_ctocpp.h" +#include "libcef_dll/ctocpp/urlrequest_ctocpp.h" #include "libcef_dll/ctocpp/v8context_ctocpp.h" #include "libcef_dll/ctocpp/v8exception_ctocpp.h" #include "libcef_dll/ctocpp/v8value_ctocpp.h" @@ -144,6 +143,7 @@ CEF_GLOBAL void CefShutdown() { DCHECK_EQ(CefBinaryValueCToCpp::DebugObjCt, 0); DCHECK_EQ(CefBrowserCToCpp::DebugObjCt, 0); DCHECK_EQ(CefBrowserHostCToCpp::DebugObjCt, 0); + DCHECK_EQ(CefBrowserProcessHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefCallbackCToCpp::DebugObjCt, 0); DCHECK_EQ(CefContextMenuHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefContextMenuParamsCToCpp::DebugObjCt, 0); @@ -167,23 +167,21 @@ CEF_GLOBAL void CefShutdown() { DCHECK_EQ(CefListValueCToCpp::DebugObjCt, 0); DCHECK_EQ(CefLoadHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefMenuModelCToCpp::DebugObjCt, 0); - DCHECK_EQ(CefPostDataCToCpp::DebugObjCt, 0); - DCHECK_EQ(CefPostDataElementCToCpp::DebugObjCt, 0); DCHECK_EQ(CefProcessMessageCToCpp::DebugObjCt, 0); DCHECK_EQ(CefProxyHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefReadHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefRenderProcessHandlerCppToC::DebugObjCt, 0); - DCHECK_EQ(CefRequestCToCpp::DebugObjCt, 0); DCHECK_EQ(CefRequestHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefResourceBundleHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefResourceHandlerCppToC::DebugObjCt, 0); - DCHECK_EQ(CefResponseCToCpp::DebugObjCt, 0); DCHECK_EQ(CefSchemeHandlerFactoryCppToC::DebugObjCt, 0); DCHECK_EQ(CefSchemeRegistrarCToCpp::DebugObjCt, 0); DCHECK_EQ(CefStreamReaderCToCpp::DebugObjCt, 0); DCHECK_EQ(CefStreamWriterCToCpp::DebugObjCt, 0); DCHECK_EQ(CefStringVisitorCppToC::DebugObjCt, 0); DCHECK_EQ(CefTaskCppToC::DebugObjCt, 0); + DCHECK_EQ(CefURLRequestCToCpp::DebugObjCt, 0); + DCHECK_EQ(CefURLRequestClientCppToC::DebugObjCt, 0); DCHECK_EQ(CefV8AccessorCppToC::DebugObjCt, 0); DCHECK_EQ(CefV8ContextCToCpp::DebugObjCt, 0); DCHECK_EQ(CefV8ExceptionCToCpp::DebugObjCt, 0); diff --git a/tests/cefclient/cefclient.cpp b/tests/cefclient/cefclient.cpp index 7b0fbefe0..8a890a727 100644 --- a/tests/cefclient/cefclient.cpp +++ b/tests/cefclient/cefclient.cpp @@ -262,18 +262,17 @@ void RunGetTextTest(CefRefPtr browser) { void RunRequestTest(CefRefPtr browser) { // Create a new request - CefRefPtr request(CefRequest::CreateRequest()); + CefRefPtr request(CefRequest::Create()); // Set the request URL request->SetURL("http://tests/request"); // Add post data to the request. The correct method and content- // type headers will be set by CEF. - CefRefPtr postDataElement( - CefPostDataElement::CreatePostDataElement()); + CefRefPtr postDataElement(CefPostDataElement::Create()); std::string data = "arg1=val1&arg2=val2"; postDataElement->SetToBytes(data.length(), data.c_str()); - CefRefPtr postData(CefPostData::CreatePostData()); + CefRefPtr postData(CefPostData::Create()); postData->AddElement(postDataElement); request->SetPostData(postData); diff --git a/tests/cefclient/client_app.cpp b/tests/cefclient/client_app.cpp index c9fcf44a3..b6a26d150 100644 --- a/tests/cefclient/client_app.cpp +++ b/tests/cefclient/client_app.cpp @@ -8,6 +8,7 @@ #include +#include "include/cef_cookie.h" #include "include/cef_process_message.h" #include "include/cef_task.h" #include "include/cef_v8.h" @@ -176,6 +177,10 @@ class ClientAppExtensionHandler : public CefV8Handler { ClientApp::ClientApp() : proxy_type_(PROXY_TYPE_DIRECT) { CreateRenderDelegates(render_delegates_); + + // Default schemes that support cookies. + cookieable_schemes_.push_back("http"); + cookieable_schemes_.push_back("https"); } void ClientApp::SetMessageCallback(const std::string& message_name, @@ -203,6 +208,13 @@ bool ClientApp::RemoveMessageCallback(const std::string& message_name, return false; } +void ClientApp::OnContextInitialized() { + // Register cookieable schemes with the global cookie manager. + CefRefPtr manager = CefCookieManager::GetGlobalManager(); + ASSERT(manager.get()); + manager->SetSupportedSchemes(cookieable_schemes_); +} + void ClientApp::GetProxyForUrl(const CefString& url, CefProxyInfo& proxy_info) { proxy_info.proxyType = proxy_type_; diff --git a/tests/cefclient/client_app.h b/tests/cefclient/client_app.h index 5c2c238a1..2a5e955aa 100644 --- a/tests/cefclient/client_app.h +++ b/tests/cefclient/client_app.h @@ -10,9 +10,11 @@ #include #include #include +#include #include "include/cef_app.h" class ClientApp : public CefApp, + public CefBrowserProcessHandler, public CefProxyHandler, public CefRenderProcessHandler { public: @@ -96,16 +98,22 @@ class ClientApp : public CefApp, static void CreateRenderDelegates(RenderDelegateSet& delegates); // Registers custom schemes. Implemented in client_app_delegates. - static void RegisterCustomSchemes(CefRefPtr registrar); + static void RegisterCustomSchemes(CefRefPtr registrar, + std::vector& cookiable_schemes); // CefApp methods. virtual void OnRegisterCustomSchemes( CefRefPtr registrar) OVERRIDE { - RegisterCustomSchemes(registrar); + RegisterCustomSchemes(registrar, cookieable_schemes_); } + virtual CefRefPtr GetBrowserProcessHandler() + OVERRIDE { return this; } virtual CefRefPtr GetRenderProcessHandler() OVERRIDE { return this; } + + // CefBrowserProcessHandler methods. virtual CefRefPtr GetProxyHandler() OVERRIDE { return this; } + virtual void OnContextInitialized(); // CefProxyHandler methods. virtual void GetProxyForUrl(const CefString& url, @@ -140,6 +148,9 @@ class ClientApp : public CefApp, // Set of supported RenderDelegates. RenderDelegateSet render_delegates_; + // Schemes that will be registered with the global cookie manager. + std::vector cookieable_schemes_; + IMPLEMENT_REFCOUNTING(ClientApp); }; diff --git a/tests/cefclient/client_app_delegates.cpp b/tests/cefclient/client_app_delegates.cpp index 68009d3c0..84a76a8dc 100644 --- a/tests/cefclient/client_app_delegates.cpp +++ b/tests/cefclient/client_app_delegates.cpp @@ -14,6 +14,8 @@ void ClientApp::CreateRenderDelegates(RenderDelegateSet& delegates) { } // static -void ClientApp::RegisterCustomSchemes(CefRefPtr registrar) { - scheme_test::RegisterCustomSchemes(registrar); +void ClientApp::RegisterCustomSchemes( + CefRefPtr registrar, + std::vector& cookiable_schemes) { + scheme_test::RegisterCustomSchemes(registrar, cookiable_schemes); } diff --git a/tests/cefclient/scheme_test.cpp b/tests/cefclient/scheme_test.cpp index 6d7b546f0..ee33a4389 100644 --- a/tests/cefclient/scheme_test.cpp +++ b/tests/cefclient/scheme_test.cpp @@ -165,7 +165,8 @@ class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory { } // namespace -void RegisterCustomSchemes(CefRefPtr registrar) { +void RegisterCustomSchemes(CefRefPtr registrar, + std::vector& cookiable_schemes) { registrar->AddCustomScheme("client", true, false, false); } diff --git a/tests/cefclient/scheme_test.h b/tests/cefclient/scheme_test.h index 3a18cc56f..724843a92 100644 --- a/tests/cefclient/scheme_test.h +++ b/tests/cefclient/scheme_test.h @@ -6,6 +6,7 @@ #define CEF_TESTS_CEFCLIENT_SCHEME_TEST_H_ #pragma once +#include #include "include/cef_base.h" class CefBrowser; @@ -14,7 +15,8 @@ class CefSchemeRegistrar; namespace scheme_test { // Register the scheme. -void RegisterCustomSchemes(CefRefPtr registrar); +void RegisterCustomSchemes(CefRefPtr registrar, + std::vector& cookiable_schemes); // Create the scheme handler. void InitTest(); diff --git a/tests/unittests/client_app_delegates.cc b/tests/unittests/client_app_delegates.cc index 7b19d75cc..e47e97698 100644 --- a/tests/unittests/client_app_delegates.cc +++ b/tests/unittests/client_app_delegates.cc @@ -18,17 +18,31 @@ void ClientApp::CreateRenderDelegates(RenderDelegateSet& delegates) { // Bring in the DOM tests. extern void CreateDOMRendererTests(RenderDelegateSet& delegates); CreateDOMRendererTests(delegates); + + // Bring in the URLRequest tests. + extern void CreateURLRequestRendererTests(RenderDelegateSet& delegates); + CreateURLRequestRendererTests(delegates); } // static -void ClientApp::RegisterCustomSchemes(CefRefPtr registrar) { +void ClientApp::RegisterCustomSchemes( + CefRefPtr registrar, + std::vector& cookiable_schemes) { // Bring in the scheme handler tests. extern void RegisterSchemeHandlerCustomSchemes( - CefRefPtr registrar); - RegisterSchemeHandlerCustomSchemes(registrar); + CefRefPtr registrar, + std::vector& cookiable_schemes); + RegisterSchemeHandlerCustomSchemes(registrar, cookiable_schemes); // Bring in the cookie tests. extern void RegisterCookieCustomSchemes( - CefRefPtr registrar); - RegisterCookieCustomSchemes(registrar); + CefRefPtr registrar, + std::vector& cookiable_schemes); + RegisterCookieCustomSchemes(registrar, cookiable_schemes); + + // Bring in the URLRequest tests. + extern void RegisterURLRequestCustomSchemes( + CefRefPtr registrar, + std::vector& cookiable_schemes); + RegisterURLRequestCustomSchemes(registrar, cookiable_schemes); } diff --git a/tests/unittests/cookie_unittest.cc b/tests/unittests/cookie_unittest.cc index 5b0a7b76e..9b2ca26f5 100644 --- a/tests/unittests/cookie_unittest.cc +++ b/tests/unittests/cookie_unittest.cc @@ -952,9 +952,11 @@ TEST(CookieTest, GetCookieManagerCustom) { EXPECT_TRUE(handler->got_cookie3_); } -// Called to register custom schemes. +// Entry point for registering custom schemes. +// Called from client_app_delegates.cc. void RegisterCookieCustomSchemes( - CefRefPtr registrar) { + CefRefPtr registrar, + std::vector& cookiable_schemes) { // Used by GetCookieManagerCustom test. registrar->AddCustomScheme("ccustom", true, false, false); } diff --git a/tests/unittests/request_unittest.cc b/tests/unittests/request_unittest.cc index da8417ae7..b651aedc0 100644 --- a/tests/unittests/request_unittest.cc +++ b/tests/unittests/request_unittest.cc @@ -4,91 +4,13 @@ #include "include/cef_request.h" #include "tests/unittests/test_handler.h" +#include "tests/unittests/test_util.h" #include "testing/gtest/include/gtest/gtest.h" -namespace { - -// Verify that CefRequest::HeaderMap objects are equal -// If |allowExtras| is true then additional header fields will be allowed in -// |map2|. -void VerifyMapEqual(CefRequest::HeaderMap &map1, - CefRequest::HeaderMap &map2, - bool allowExtras) { - if (!allowExtras) - ASSERT_EQ(map1.size(), map2.size()); - CefRequest::HeaderMap::const_iterator it1, it2; - - for (it1 = map1.begin(); it1 != map1.end(); ++it1) { - it2 = map2.find(it1->first); - ASSERT_TRUE(it2 != map2.end()); - ASSERT_EQ(it1->second, it2->second); - } -} - -// Verify that CefPostDataElement objects are equal -void VerifyPostDataElementEqual(CefRefPtr elem1, - CefRefPtr elem2) { - ASSERT_EQ(elem1->GetType(), elem2->GetType()); - switch (elem1->GetType()) { - case PDE_TYPE_BYTES: { - ASSERT_EQ(elem1->GetBytesCount(), elem2->GetBytesCount()); - size_t bytesCt = elem1->GetBytesCount(); - char* buff1 = new char[bytesCt]; - char* buff2 = new char[bytesCt]; - elem1->GetBytes(bytesCt, buff1); - elem2->GetBytes(bytesCt, buff2); - ASSERT_TRUE(!memcmp(buff1, buff2, bytesCt)); - delete [] buff1; - delete [] buff2; - } break; - case PDE_TYPE_FILE: - ASSERT_EQ(elem1->GetFile(), elem2->GetFile()); - break; - default: - break; - } -} - -// Verify that CefPostData objects are equal -void VerifyPostDataEqual(CefRefPtr postData1, - CefRefPtr postData2) { - ASSERT_TRUE(!(postData1.get()) == !(postData2.get())); - ASSERT_EQ(postData1->GetElementCount(), postData2->GetElementCount()); - - CefPostData::ElementVector ev1, ev2; - postData1->GetElements(ev1); - postData1->GetElements(ev2); - ASSERT_EQ(ev1.size(), ev2.size()); - - CefPostData::ElementVector::const_iterator it1 = ev1.begin(); - CefPostData::ElementVector::const_iterator it2 = ev2.begin(); - for (; it1 != ev1.end() && it2 != ev2.end(); ++it1, ++it2) - VerifyPostDataElementEqual((*it1), (*it2)); -} - -// Verify that CefRequest objects are equal -// If |allowExtras| is true then additional header fields will be allowed in -// |request2|. -void VerifyRequestEqual(CefRefPtr request1, - CefRefPtr request2, - bool allowExtras) { - ASSERT_EQ(request1->GetURL(), request2->GetURL()); - ASSERT_EQ(request1->GetMethod(), request2->GetMethod()); - - CefRequest::HeaderMap headers1, headers2; - request1->GetHeaderMap(headers1); - request2->GetHeaderMap(headers2); - VerifyMapEqual(headers1, headers2, allowExtras); - - VerifyPostDataEqual(request1->GetPostData(), request2->GetPostData()); -} - -} // namespace - // Verify Set/Get methods for CefRequest, CefPostData and CefPostDataElement. TEST(RequestTest, SetGet) { // CefRequest CreateRequest - CefRefPtr request(CefRequest::CreateRequest()); + CefRefPtr request(CefRequest::Create()); ASSERT_TRUE(request.get() != NULL); CefString url = "http://tests/run.html"; @@ -98,15 +20,13 @@ TEST(RequestTest, SetGet) { setHeaders.insert(std::make_pair("HeaderB", "ValueB")); // CefPostData CreatePostData - CefRefPtr postData(CefPostData::CreatePostData()); + CefRefPtr postData(CefPostData::Create()); ASSERT_TRUE(postData.get() != NULL); // CefPostDataElement CreatePostDataElement - CefRefPtr element1( - CefPostDataElement::CreatePostDataElement()); + CefRefPtr element1(CefPostDataElement::Create()); ASSERT_TRUE(element1.get() != NULL); - CefRefPtr element2( - CefPostDataElement::CreatePostDataElement()); + CefRefPtr element2(CefPostDataElement::Create()); ASSERT_TRUE(element2.get() != NULL); // CefPostDataElement SetToFile @@ -145,9 +65,9 @@ TEST(RequestTest, SetGet) { CefPostData::ElementVector::const_iterator it = elements.begin(); for (size_t i = 0; it != elements.end(); ++it, ++i) { if (i == 0) - VerifyPostDataElementEqual(element1, (*it).get()); + TestPostDataElementEqual(element1, (*it).get()); else if (i == 1) - VerifyPostDataElementEqual(element2, (*it).get()); + TestPostDataElementEqual(element2, (*it).get()); } // CefRequest SetURL @@ -161,14 +81,14 @@ TEST(RequestTest, SetGet) { // CefRequest SetHeaderMap request->SetHeaderMap(setHeaders); request->GetHeaderMap(getHeaders); - VerifyMapEqual(setHeaders, getHeaders, false); + TestMapEqual(setHeaders, getHeaders, false); getHeaders.clear(); // CefRequest SetPostData request->SetPostData(postData); - VerifyPostDataEqual(postData, request->GetPostData()); + TestPostDataEqual(postData, request->GetPostData()); - request = CefRequest::CreateRequest(); + request = CefRequest::Create(); ASSERT_TRUE(request.get() != NULL); // CefRequest Set @@ -176,15 +96,15 @@ TEST(RequestTest, SetGet) { ASSERT_EQ(url, request->GetURL()); ASSERT_EQ(method, request->GetMethod()); request->GetHeaderMap(getHeaders); - VerifyMapEqual(setHeaders, getHeaders, false); + TestMapEqual(setHeaders, getHeaders, false); getHeaders.clear(); - VerifyPostDataEqual(postData, request->GetPostData()); + TestPostDataEqual(postData, request->GetPostData()); } namespace { void CreateRequest(CefRefPtr& request) { - request = CefRequest::CreateRequest(); + request = CefRequest::Create(); ASSERT_TRUE(request.get() != NULL); request->SetURL("http://tests/run.html"); @@ -195,11 +115,11 @@ void CreateRequest(CefRefPtr& request) { headers.insert(std::make_pair("HeaderB", "ValueB")); request->SetHeaderMap(headers); - CefRefPtr postData(CefPostData::CreatePostData()); + CefRefPtr postData(CefPostData::Create()); ASSERT_TRUE(postData.get() != NULL); CefRefPtr element1( - CefPostDataElement::CreatePostDataElement()); + CefPostDataElement::Create()); ASSERT_TRUE(element1.get() != NULL); char bytes[] = "Test Bytes"; element1->SetToBytes(sizeof(bytes), bytes); @@ -231,7 +151,7 @@ class RequestSendRecvTestHandler : public TestHandler { CefRefPtr frame, CefRefPtr request) OVERRIDE { // Verify that the request is the same - VerifyRequestEqual(request_, request, true); + TestRequestEqual(request_, request, true); got_before_resource_load_.yes(); @@ -243,7 +163,7 @@ class RequestSendRecvTestHandler : public TestHandler { CefRefPtr frame, CefRefPtr request) OVERRIDE { // Verify that the request is the same - VerifyRequestEqual(request_, request, true); + TestRequestEqual(request_, request, true); got_resource_handler_.yes(); diff --git a/tests/unittests/run_all_unittests.cc b/tests/unittests/run_all_unittests.cc index 54c504173..10a7f9db3 100644 --- a/tests/unittests/run_all_unittests.cc +++ b/tests/unittests/run_all_unittests.cc @@ -10,6 +10,9 @@ #include "base/command_line.h" #include "base/threading/thread.h" +// Include after base/bind.h to avoid name collisions with cef_tuple.h. +#include "include/cef_runnable.h" + namespace { // Thread used to run the test suite. @@ -25,13 +28,7 @@ class CefTestThread : public base::Thread { retval_ = test_suite_->Run(); // Quit the CEF message loop. - class QuitTask : public CefTask { - public: - QuitTask() {} - virtual void Execute(CefThreadId threadId) { CefQuitMessageLoop(); } - IMPLEMENT_REFCOUNTING(QuitTask); - }; - CefPostTask(TID_UI, new QuitTask()); + CefPostTask(TID_UI, NewCefRunnableFunction(CefQuitMessageLoop)); } int retval() { return retval_; } @@ -41,6 +38,13 @@ class CefTestThread : public base::Thread { int retval_; }; +// Called on the UI thread. +void RunTests(CefTestThread* thread) { + // Run the test suite on the test thread. + thread->message_loop()->PostTask(FROM_HERE, + base::Bind(&CefTestThread::RunTests, base::Unretained(thread))); +} + } // namespace @@ -88,9 +92,9 @@ int main(int argc, char* argv[]) { if (!thread->Start()) return 1; - // Run the test suite on the test thread. - thread->message_loop()->PostTask(FROM_HERE, - base::Bind(&CefTestThread::RunTests, base::Unretained(thread.get()))); + // Start the tests from the UI thread so that any pending UI tasks get a + // chance to execute first. + CefPostTask(TID_UI, NewCefRunnableFunction(RunTests, thread.get())); // Run the CEF message loop. CefRunMessageLoop(); diff --git a/tests/unittests/scheme_handler_unittest.cc b/tests/unittests/scheme_handler_unittest.cc index 19c3316e8..23ddb173f 100644 --- a/tests/unittests/scheme_handler_unittest.cc +++ b/tests/unittests/scheme_handler_unittest.cc @@ -948,9 +948,11 @@ TEST(SchemeHandlerTest, HttpXSSDifferentOriginWithDomain) { ClearTestSchemes(); } -// Called to register custom schemes. +// Entry point for registering custom schemes. +// Called from client_app_delegates.cc. void RegisterSchemeHandlerCustomSchemes( - CefRefPtr registrar) { + CefRefPtr registrar, + std::vector& cookiable_schemes) { // Add a custom standard scheme. registrar->AddCustomScheme("customstd", true, false, false); // Ad a custom non-standard scheme. diff --git a/tests/unittests/test_util.cc b/tests/unittests/test_util.cc index cb0ac0e95..8fea262be 100644 --- a/tests/unittests/test_util.cc +++ b/tests/unittests/test_util.cc @@ -6,6 +6,107 @@ #include "tests/unittests/test_util.h" #include "testing/gtest/include/gtest/gtest.h" +void TestMapEqual(CefRequest::HeaderMap& map1, + CefRequest::HeaderMap& map2, + bool allowExtras) { + if (!allowExtras) + EXPECT_EQ(map1.size(), map2.size()); + CefRequest::HeaderMap::const_iterator it1, it2; + + for (it1 = map1.begin(); it1 != map1.end(); ++it1) { + it2 = map2.find(it1->first); + EXPECT_TRUE(it2 != map2.end()); + if (it2 != map2.end()) { + EXPECT_STREQ(it1->second.ToString().c_str(), + it2->second.ToString().c_str()); + } + } +} + +void TestPostDataElementEqual(CefRefPtr elem1, + CefRefPtr elem2) { + EXPECT_TRUE(elem1.get()); + EXPECT_TRUE(elem2.get()); + + EXPECT_EQ(elem1->GetType(), elem2->GetType()); + switch (elem1->GetType()) { + case PDE_TYPE_BYTES: { + EXPECT_EQ(elem1->GetBytesCount(), elem2->GetBytesCount()); + size_t bytesCt = elem1->GetBytesCount(); + char* buff1 = new char[bytesCt]; + char* buff2 = new char[bytesCt]; + elem1->GetBytes(bytesCt, buff1); + elem2->GetBytes(bytesCt, buff2); + EXPECT_TRUE(!memcmp(buff1, buff2, bytesCt)); + delete [] buff1; + delete [] buff2; + } break; + case PDE_TYPE_FILE: + EXPECT_EQ(elem1->GetFile(), elem2->GetFile()); + break; + default: + break; + } +} + +void TestPostDataEqual(CefRefPtr postData1, + CefRefPtr postData2) { + EXPECT_TRUE(postData1.get()); + EXPECT_TRUE(postData2.get()); + + EXPECT_EQ(postData1->GetElementCount(), postData2->GetElementCount()); + + CefPostData::ElementVector ev1, ev2; + postData1->GetElements(ev1); + postData1->GetElements(ev2); + ASSERT_EQ(ev1.size(), ev2.size()); + + CefPostData::ElementVector::const_iterator it1 = ev1.begin(); + CefPostData::ElementVector::const_iterator it2 = ev2.begin(); + for (; it1 != ev1.end() && it2 != ev2.end(); ++it1, ++it2) + TestPostDataElementEqual((*it1), (*it2)); +} + +void TestRequestEqual(CefRefPtr request1, + CefRefPtr request2, + bool allowExtras) { + EXPECT_TRUE(request1.get()); + EXPECT_TRUE(request2.get()); + + EXPECT_STREQ(request1->GetURL().ToString().c_str(), + request2->GetURL().ToString().c_str()); + EXPECT_STREQ(request1->GetMethod().ToString().c_str(), + request2->GetMethod().ToString().c_str()); + + CefRequest::HeaderMap headers1, headers2; + request1->GetHeaderMap(headers1); + request2->GetHeaderMap(headers2); + TestMapEqual(headers1, headers2, allowExtras); + + CefRefPtr postData1 = request1->GetPostData(); + CefRefPtr postData2 = request2->GetPostData(); + EXPECT_EQ(!!(postData1.get()), !!(postData2.get())); + if (postData1.get() && postData2.get()) + TestPostDataEqual(postData1, postData2); +} + +void TestResponseEqual(CefRefPtr response1, + CefRefPtr response2, + bool allowExtras) { + EXPECT_TRUE(response1.get()); + EXPECT_TRUE(response2.get()); + + EXPECT_EQ(response1->GetStatus(), response2->GetStatus()); + EXPECT_STREQ(response1->GetStatusText().ToString().c_str(), + response2->GetStatusText().ToString().c_str()); + EXPECT_STREQ(response1->GetMimeType().ToString().c_str(), + response2->GetMimeType().ToString().c_str()); + + CefRequest::HeaderMap headers1, headers2; + response1->GetHeaderMap(headers1); + response2->GetHeaderMap(headers2); + TestMapEqual(headers1, headers2, allowExtras); +} void TestBinaryEqual(CefRefPtr val1, CefRefPtr val2) { diff --git a/tests/unittests/test_util.h b/tests/unittests/test_util.h index 717003dfa..0339746f8 100644 --- a/tests/unittests/test_util.h +++ b/tests/unittests/test_util.h @@ -7,8 +7,39 @@ #pragma once #include "include/cef_process_message.h" +#include "include/cef_request.h" +#include "include/cef_response.h" #include "include/cef_values.h" +// Test that CefRequest::HeaderMap objects are equal +// If |allowExtras| is true then additional header fields will be allowed in +// |map2|. +void TestMapEqual(CefRequest::HeaderMap& map1, + CefRequest::HeaderMap& map2, + bool allowExtras); + +// Test that CefPostDataElement objects are equal +void TestPostDataElementEqual(CefRefPtr elem1, + CefRefPtr elem2); + +// Test that CefPostData objects are equal +void TestPostDataEqual(CefRefPtr postData1, + CefRefPtr postData2); + +// Test that CefRequest objects are equal +// If |allowExtras| is true then additional header fields will be allowed in +// |request2|. +void TestRequestEqual(CefRefPtr request1, + CefRefPtr request2, + bool allowExtras); + +// Test that CefResponse objects are equal +// If |allowExtras| is true then additional header fields will be allowed in +// |response2|. +void TestResponseEqual(CefRefPtr response1, + CefRefPtr response2, + bool allowExtras); + // Test if two binary values are equal. void TestBinaryEqual(CefRefPtr val1, CefRefPtr val2); diff --git a/tests/unittests/urlrequest_unittest.cc b/tests/unittests/urlrequest_unittest.cc new file mode 100644 index 000000000..2ab793519 --- /dev/null +++ b/tests/unittests/urlrequest_unittest.cc @@ -0,0 +1,1030 @@ +// Copyright (c) 2012 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 + +#include "include/cef_scheme.h" +#include "include/cef_task.h" +#include "include/cef_urlrequest.h" +#include "tests/cefclient/client_app.h" +#include "tests/unittests/test_handler.h" +#include "tests/unittests/test_util.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/stringprintf.h" +#include "testing/gtest/include/gtest/gtest.h" + +// Include after base/bind.h to avoid name collisions with cef_tuple.h. +#include "include/cef_runnable.h" + + +// How to add a new test: +// 1. Add a new value to the RequestTestMode enumeration. +// 2. Add methods to set up and run the test in RequestTestRunner. +// 3. Add a line for the test in the RequestTestRunner constructor. +// 4. Add lines for the test in the "Define the tests" section at the bottom of +// the file. + +namespace { + +// Unique values for URLRequest tests. +const char* kRequestTestUrl = "http://tests/URLRequestTest.Test"; +const char* kRequestTestMsg = "URLRequestTest.Test"; +const char* kRequestScheme = "urcustom"; +const char* kRequestHost = "test"; +const char* kRequestOrigin = "urcustom://test"; +const char* kRequestSendCookieName = "urcookie_send"; +const char* kRequestSaveCookieName = "urcookie_save"; + +enum RequestTestMode { + REQTEST_GET = 0, + REQTEST_GET_NODATA, + REQTEST_GET_ALLOWCOOKIES, + REQTEST_GET_REDIRECT, + REQTEST_POST, + REQTEST_POST_WITHPROGRESS, + REQTEST_HEAD, +}; + +struct RequestRunSettings { + RequestRunSettings() + : expect_upload_progress(false), + expect_download_progress(true), + expect_download_data(true), + expected_status(UR_SUCCESS), + expected_error_code(ERR_NONE), + expect_send_cookie(false), + expect_save_cookie(false), + expect_follow_redirect(true) { + } + + // Request that will be sent. + CefRefPtr request; + + // Response that will be returned by the scheme handler. + CefRefPtr response; + + // Optional response data that will be returned by the scheme handler. + std::string response_data; + + // If true upload progress notification will be expected. + bool expect_upload_progress; + + // If true download progress notification will be expected. + bool expect_download_progress; + + // If true download data will be expected. + bool expect_download_data; + + // Expected status value. + CefURLRequest::Status expected_status; + + // Expected error code value. + CefURLRequest::ErrorCode expected_error_code; + + // If true the request cookie should be sent to the server. + bool expect_send_cookie; + + // If true the response cookie should be save. + bool expect_save_cookie; + + // If specified the test will begin with this redirect request and response. + CefRefPtr redirect_request; + CefRefPtr redirect_response; + + // If true the redirect is expected to be followed. + bool expect_follow_redirect; +}; + +void SetUploadData(CefRefPtr request, + const std::string& data) { + CefRefPtr postData = CefPostData::Create(); + CefRefPtr element = CefPostDataElement::Create(); + element->SetToBytes(data.size(), data.c_str()); + postData->AddElement(element); + request->SetPostData(postData); +} + +void GetUploadData(CefRefPtr request, + std::string& data) { + CefRefPtr postData = request->GetPostData(); + EXPECT_TRUE(postData.get()); + CefPostData::ElementVector elements; + postData->GetElements(elements); + EXPECT_EQ((size_t)1, elements.size()); + CefRefPtr element = elements[0]; + EXPECT_TRUE(element.get()); + + size_t size = element->GetBytesCount(); + + data.resize(size); + EXPECT_EQ(size, data.size()); + EXPECT_EQ(size, element->GetBytes(size, const_cast(data.c_str()))); +} + +// 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) { + class Visitor : public CefCookieVisitor { + public: + Visitor(base::WaitableEvent* event, bool* cookie_exists) + : event_(event), + cookie_exists_(cookie_exists) { + } + virtual ~Visitor() { + event_->Signal(); + } + + virtual bool Visit(const CefCookie& cookie, int count, int total, + bool& deleteCookie) OVERRIDE { + std::string cookie_name = CefString(&cookie.name); + if (cookie_name == kRequestSaveCookieName) { + *cookie_exists_ = true; + deleteCookie = true; + return false; + } + return true; + } + + private: + base::WaitableEvent* event_; + bool* cookie_exists_; + + IMPLEMENT_REFCOUNTING(Visitor); + }; + + CefRefPtr cookie_manager = + CefCookieManager::GetGlobalManager(); + EXPECT_TRUE(cookie_manager.get()); + cookie_manager->VisitUrlCookies(kRequestOrigin, true, + new Visitor(event, cookie_exists)); + event->Wait(); +} + + +// Serves request responses. +class RequestSchemeHandler : public CefResourceHandler { + public: + explicit RequestSchemeHandler(const RequestRunSettings& settings) + : settings_(settings), + offset_(0) { + } + + virtual bool ProcessRequest(CefRefPtr request, + CefRefPtr callback) OVERRIDE { + EXPECT_TRUE(CefCurrentlyOn(TID_IO)); + + // Shouldn't get here if we're not following redirects. + EXPECT_TRUE(settings_.expect_follow_redirect); + + // Verify that the request was sent correctly. + TestRequestEqual(settings_.request, request, true); + + // HEAD requests are identical to GET requests except no response data is + // sent. + if (request->GetMethod() == "HEAD") + settings_.response_data.clear(); + + CefRequest::HeaderMap headerMap; + request->GetHeaderMap(headerMap); + + // Check if the request cookie was sent. + bool has_send_cookie = false; + CefRequest::HeaderMap::iterator iter = headerMap.find("Cookie"); + if (iter != headerMap.end()) { + std::string cookie = iter->second; + if (cookie.find(kRequestSendCookieName) != std::string::npos) + has_send_cookie = true; + } + + if (settings_.expect_send_cookie) + EXPECT_TRUE(has_send_cookie); + else + EXPECT_FALSE(has_send_cookie); + + // Continue immediately. + callback->Continue(); + return true; + } + + virtual void GetResponseHeaders(CefRefPtr response, + int64& response_length, + CefString& redirectUrl) OVERRIDE { + EXPECT_TRUE(CefCurrentlyOn(TID_IO)); + + response->SetStatus(settings_.response->GetStatus()); + response->SetStatusText(settings_.response->GetStatusText()); + response->SetMimeType(settings_.response->GetMimeType()); + + CefResponse::HeaderMap headerMap; + settings_.response->GetHeaderMap(headerMap); + + if (settings_.expect_save_cookie) { + std::string cookie = base::StringPrintf("%s=%s", kRequestSaveCookieName, + "save-cookie-value"); + headerMap.insert(std::make_pair("Set-Cookie", cookie)); + } + + response->SetHeaderMap(headerMap); + + response_length = settings_.response_data.length(); + } + + virtual bool ReadResponse(void* response_data_out, + int bytes_to_read, + int& bytes_read, + CefRefPtr callback) OVERRIDE { + EXPECT_TRUE(CefCurrentlyOn(TID_IO)); + + bool has_data = false; + bytes_read = 0; + + size_t size = settings_.response_data.length(); + if (offset_ < size) { + int transfer_size = + std::min(bytes_to_read, static_cast(size - offset_)); + memcpy(response_data_out, + settings_.response_data.c_str() + offset_, + transfer_size); + offset_ += transfer_size; + + bytes_read = transfer_size; + has_data = true; + } + + return has_data; + } + + virtual void Cancel() OVERRIDE { + EXPECT_TRUE(CefCurrentlyOn(TID_IO)); + } + + private: + RequestRunSettings settings_; + size_t offset_; + + IMPLEMENT_REFCOUNTING(ClientSchemeHandler); +}; + +// Serves redirect request responses. +class RequestRedirectSchemeHandler : public CefResourceHandler { + public: + explicit RequestRedirectSchemeHandler(CefRefPtr request, + CefRefPtr response) + : request_(request), + response_(response) { + } + + virtual bool ProcessRequest(CefRefPtr request, + CefRefPtr callback) OVERRIDE { + EXPECT_TRUE(CefCurrentlyOn(TID_IO)); + + // Verify that the request was sent correctly. + TestRequestEqual(request_, request, true); + + // Continue immediately. + callback->Continue(); + return true; + } + + virtual void GetResponseHeaders(CefRefPtr response, + int64& response_length, + CefString& redirectUrl) OVERRIDE { + EXPECT_TRUE(CefCurrentlyOn(TID_IO)); + + response->SetStatus(response_->GetStatus()); + response->SetStatusText(response_->GetStatusText()); + response->SetMimeType(response_->GetMimeType()); + + CefResponse::HeaderMap headerMap; + response_->GetHeaderMap(headerMap); + response->SetHeaderMap(headerMap); + + response_length = 0; + } + + virtual bool ReadResponse(void* response_data_out, + int bytes_to_read, + int& bytes_read, + CefRefPtr callback) OVERRIDE { + EXPECT_TRUE(CefCurrentlyOn(TID_IO)); + NOTREACHED(); + return false; + } + + virtual void Cancel() OVERRIDE { + EXPECT_TRUE(CefCurrentlyOn(TID_IO)); + } + + private: + CefRefPtr request_; + CefRefPtr response_; + + IMPLEMENT_REFCOUNTING(ClientSchemeHandler); +}; + + +class RequestSchemeHandlerFactory : public CefSchemeHandlerFactory { + public: + RequestSchemeHandlerFactory() { + } + + virtual CefRefPtr Create( + CefRefPtr browser, + CefRefPtr frame, + const CefString& scheme_name, + CefRefPtr request) + OVERRIDE { + EXPECT_TRUE(CefCurrentlyOn(TID_IO)); + std::string url = request->GetURL(); + + // Try to find a test match. + { + HandlerMap::const_iterator it = handler_map_.find(url); + if (it != handler_map_.end()) + return new RequestSchemeHandler(it->second); + } + + // Try to find a redirect match. + { + RedirectHandlerMap::const_iterator it = redirect_handler_map_.find(url); + if (it != redirect_handler_map_.end()) { + return new RequestRedirectSchemeHandler(it->second.first, + it->second.second); + } + } + + // Unknown test. + ADD_FAILURE(); + return NULL; + } + + void AddSchemeHandler(const RequestRunSettings& settings) { + // Verify that the scheme is correct. + std::string url = settings.request->GetURL(); + EXPECT_EQ((unsigned long)0, url.find(kRequestScheme)); + + handler_map_.insert(std::make_pair(url, settings)); + } + + void AddRedirectSchemeHandler(CefRefPtr redirect_request, + CefRefPtr redirect_response) { + // Verify that the scheme is correct. + std::string url = redirect_request->GetURL(); + EXPECT_EQ((unsigned long)0, url.find(kRequestScheme)); + + redirect_handler_map_.insert( + std::make_pair(url, + std::make_pair(redirect_request, redirect_response))); + } + + private: + typedef std::map HandlerMap; + HandlerMap handler_map_; + + typedef std::map, CefRefPtr > > + RedirectHandlerMap; + RedirectHandlerMap redirect_handler_map_; + + IMPLEMENT_REFCOUNTING(ClientSchemeHandlerFactory); +}; + + +// Implementation of CefURLRequestClient that stores response information. +class RequestClient : public CefURLRequestClient { + public: + class Delegate { + public: + // Used to notify the handler when the request has completed. + virtual void OnRequestComplete(CefRefPtr client) =0; + protected: + virtual ~Delegate() {} + }; + + static CefRefPtr Create(Delegate* delegate, + CefRefPtr request) { + CefRefPtr client = new RequestClient(delegate); + CefURLRequest::Create(request, client.get()); + return client; + } + + virtual void OnRequestComplete(CefRefPtr request) OVERRIDE { + request_complete_ct_++; + + request_ = request->GetRequest(); + EXPECT_TRUE(request_->IsReadOnly()); + status_ = request->GetRequestStatus(); + error_code_ = request->GetRequestError(); + response_ = request->GetResponse(); + EXPECT_TRUE(response_->IsReadOnly()); + + delegate_->OnRequestComplete(this); + } + + virtual void OnUploadProgress(CefRefPtr request, + uint64 current, + uint64 total) OVERRIDE { + upload_progress_ct_++; + upload_total_ = total; + } + + virtual void OnDownloadProgress(CefRefPtr request, + uint64 current, + uint64 total) OVERRIDE { + download_progress_ct_++; + download_total_ = total; + } + + virtual void OnDownloadData(CefRefPtr request, + const void* data, + size_t data_length) OVERRIDE { + download_data_ct_++; + download_data_ += std::string(static_cast(data), data_length); + } + + 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: + int request_complete_ct_; + int upload_progress_ct_; + int download_progress_ct_; + int download_data_ct_; + + uint64 upload_total_; + uint64 download_total_; + std::string download_data_; + CefRefPtr request_; + CefURLRequest::Status status_; + CefURLRequest::ErrorCode error_code_; + CefRefPtr response_; + + private: + IMPLEMENT_REFCOUNTING(RequestClient); +}; + + +// Executes the tests. +class RequestTestRunner { + public: + typedef base::Callback TestCallback; + + class Delegate { + public: + // Used to notify the handler when the test can be destroyed. + virtual void DestroyTest(const RequestRunSettings& settings) =0; + protected: + virtual ~Delegate() {} + }; + + 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))); + + // Register the test callbacks. + REGISTER_TEST(REQTEST_GET, SetupGetTest, GenericRunTest); + REGISTER_TEST(REQTEST_GET_NODATA, SetupGetNoDataTest, GenericRunTest); + REGISTER_TEST(REQTEST_GET_ALLOWCOOKIES, SetupGetAllowCookiesTest, + GenericRunTest); + REGISTER_TEST(REQTEST_GET_REDIRECT, SetupGetRedirectTest, GenericRunTest); + REGISTER_TEST(REQTEST_POST, SetupPostTest, GenericRunTest); + REGISTER_TEST(REQTEST_POST_WITHPROGRESS, SetupPostWithProgressTest, + GenericRunTest); + REGISTER_TEST(REQTEST_HEAD, SetupHeadTest, GenericRunTest); + } + + // 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); + if (it != test_map_.end()) { + it->second.setup.Run(); + AddSchemeHandler(); + } else { + // Unknown test. + ADD_FAILURE(); + } + } + + // Called in either the browser or render process to run the test. + void RunTest(RequestTestMode test_mode) { + TestMap::const_iterator it = test_map_.find(test_mode); + if (it != test_map_.end()) { + it->second.run.Run(); + } else { + // Unknown test. + ADD_FAILURE(); + DestroyTest(); + } + } + + private: + void SetupGetTest() { + settings_.request = CefRequest::Create(); + settings_.request->SetURL(MakeSchemeURL("GetTest.html")); + settings_.request->SetMethod("GET"); + + settings_.response = CefResponse::Create(); + settings_.response->SetMimeType("text/html"); + settings_.response->SetStatus(200); + settings_.response->SetStatusText("OK"); + + settings_.response_data = "GET TEST SUCCESS"; + } + + void SetupGetNoDataTest() { + // Start with the normal get test. + SetupGetTest(); + + // Disable download data notifications. + settings_.request->SetFlags(UR_FLAG_NO_DOWNLOAD_DATA); + + settings_.expect_download_data = false; + } + + void SetupGetAllowCookiesTest() { + // Start with the normal get test. + SetupGetTest(); + + // Send cookies. + settings_.request->SetFlags(UR_FLAG_ALLOW_CACHED_CREDENTIALS | + UR_FLAG_ALLOW_COOKIES); + + settings_.expect_save_cookie = true; + settings_.expect_send_cookie = true; + } + + void SetupGetRedirectTest() { + // Start with the normal get test. + SetupGetTest(); + + // Add a redirect request. + settings_.redirect_request = CefRequest::Create(); + settings_.redirect_request->SetURL(MakeSchemeURL("redirect.html")); + settings_.redirect_request->SetMethod("GET"); + + settings_.redirect_response = CefResponse::Create(); + settings_.redirect_response->SetMimeType("text/html"); + settings_.redirect_response->SetStatus(302); + settings_.redirect_response->SetStatusText("Found"); + + CefResponse::HeaderMap headerMap; + headerMap.insert(std::make_pair("Location", settings_.request->GetURL())); + settings_.redirect_response->SetHeaderMap(headerMap); + } + + void SetupPostTest() { + settings_.request = CefRequest::Create(); + settings_.request->SetURL(MakeSchemeURL("PostTest.html")); + settings_.request->SetMethod("POST"); + SetUploadData(settings_.request, "the_post_data"); + + settings_.response = CefResponse::Create(); + settings_.response->SetMimeType("text/html"); + settings_.response->SetStatus(200); + settings_.response->SetStatusText("OK"); + + settings_.response_data = "POST TEST SUCCESS"; + } + + void SetupPostWithProgressTest() { + // Start with the normal post test. + SetupPostTest(); + + // Enable upload progress notifications. + settings_.request->SetFlags(UR_FLAG_REPORT_UPLOAD_PROGRESS); + + settings_.expect_upload_progress = true; + } + + void SetupHeadTest() { + settings_.request = CefRequest::Create(); + settings_.request->SetURL(MakeSchemeURL("HeadTest.html")); + settings_.request->SetMethod("HEAD"); + + settings_.response = CefResponse::Create(); + settings_.response->SetMimeType("text/html"); + settings_.response->SetStatus(200); + settings_.response->SetStatusText("OK"); + + // The scheme handler will disregard this value when it returns the result. + settings_.response_data = "HEAD TEST SUCCESS"; + + settings_.expect_download_progress = false; + settings_.expect_download_data = false; + } + + // Generic test runner. + void GenericRunTest() { + class Test : public RequestClient::Delegate { + public: + Test(RequestTestRunner* runner, const RequestRunSettings& settings) + : runner_(runner), + settings_(settings) { + } + + virtual void OnRequestComplete(CefRefPtr client) OVERRIDE { + CefRefPtr expected_request; + CefRefPtr expected_response; + + if (runner_->settings_.redirect_request.get()) + expected_request = runner_->settings_.redirect_request; + else + expected_request = runner_->settings_.request; + + if (runner_->settings_.redirect_response.get() && + !runner_->settings_.expect_follow_redirect) { + // A redirect response was sent but the redirect is not expected to be + // followed. + expected_response = runner_->settings_.redirect_response; + } else { + expected_response = runner_->settings_.response; + } + + TestRequestEqual(expected_request, client->request_, false); + + EXPECT_EQ(settings_.expected_status, client->status_); + EXPECT_EQ(settings_.expected_error_code, client->error_code_); + TestResponseEqual(expected_response, client->response_, true); + + EXPECT_EQ(1, client->request_complete_ct_); + + if (settings_.expect_upload_progress) { + EXPECT_LE(1, client->upload_progress_ct_); + + std::string upload_data; + GetUploadData(expected_request, upload_data); + EXPECT_EQ(upload_data.size(), client->upload_total_); + } else { + EXPECT_EQ(0, client->upload_progress_ct_); + EXPECT_EQ((uint64)0, client->upload_total_); + } + + if (settings_.expect_download_progress) { + EXPECT_LE(1, client->download_progress_ct_); + EXPECT_EQ(runner_->settings_.response_data.size(), + client->download_total_); + } else { + EXPECT_EQ(0, client->download_progress_ct_); + EXPECT_EQ((uint64)0, client->download_total_); + } + + if (settings_.expect_download_data) { + EXPECT_LE(1, client->download_data_ct_); + EXPECT_STREQ(runner_->settings_.response_data.c_str(), + client->download_data_.c_str()); + } else { + EXPECT_EQ(0, client->download_data_ct_); + EXPECT_TRUE(client->download_data_.empty()); + } + + runner_->DestroyTest(); + } + + private: + RequestTestRunner* runner_; + RequestRunSettings settings_; + }; + + CefRefPtr request; + if (settings_.redirect_request) + request = settings_.redirect_request; + else + request = settings_.request; + EXPECT_TRUE(request.get()); + + RequestClient::Create(new Test(this, settings_), request); + } + + // Register a test. Called in the constructor. + void RegisterTest(RequestTestMode test_mode, + TestCallback setup, + TestCallback run) { + TestEntry entry = {setup, run}; + test_map_.insert(std::make_pair(test_mode, entry)); + } + + // Destroy the current test. Called when the test is complete. + void DestroyTest() { + if (scheme_factory_.get()) { + // Remove the factory registration. + CefRegisterSchemeHandlerFactory(kRequestScheme, kRequestHost, NULL); + scheme_factory_ = NULL; + } + + delegate_->DestroyTest(settings_); + } + + // Return an appropriate scheme URL for the specified |path|. + std::string MakeSchemeURL(const std::string& path) { + return base::StringPrintf("%s/%s", kRequestOrigin, path.c_str()); + } + + // Add a scheme handler for the current test. Called during test setup. + void AddSchemeHandler() { + // Scheme handlers are only registered in the browser process. + if (!is_browser_process_) + return; + + if (!scheme_factory_.get()) { + // Add the factory registration. + scheme_factory_ = new RequestSchemeHandlerFactory(); + CefRegisterSchemeHandlerFactory(kRequestScheme, kRequestHost, + scheme_factory_.get()); + } + + EXPECT_TRUE(settings_.request.get()); + EXPECT_TRUE(settings_.response.get()); + + scheme_factory_->AddSchemeHandler(settings_); + + if (settings_.redirect_request.get()) { + scheme_factory_->AddRedirectSchemeHandler(settings_.redirect_request, + settings_.redirect_response); + } + } + + Delegate* delegate_; + bool is_browser_process_; + + struct TestEntry { + TestCallback setup; + TestCallback run; + }; + typedef std::map TestMap; + TestMap test_map_; + + std::string scheme_name_; + CefRefPtr scheme_factory_; + + public: + RequestRunSettings settings_; +}; + +// Renderer side. +class RequestRendererTest : public ClientApp::RenderDelegate, + public RequestTestRunner::Delegate { + public: + RequestRendererTest() + : ALLOW_THIS_IN_INITIALIZER_LIST(test_runner_(this, false)) { + } + + virtual bool OnProcessMessageReceived( + CefRefPtr app, + CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) OVERRIDE { + if (message->GetName() == kRequestTestMsg) { + app_ = app; + browser_ = browser; + + RequestTestMode test_mode = + static_cast(message->GetArgumentList()->GetInt(0)); + + // 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); + + // Run the test. + test_runner_.RunTest(test_mode); + return true; + } + + // Message not handled. + return false; + } + + protected: + // Return from the test. + virtual void DestroyTest(const RequestRunSettings& settings) OVERRIDE { + // Check if the test has failed. + bool result = !TestFailed(); + + // Return the result to the browser process. + CefRefPtr return_msg = + CefProcessMessage::Create(kRequestTestMsg); + EXPECT_TRUE(return_msg->GetArgumentList()->SetBool(0, result)); + EXPECT_TRUE(browser_->SendProcessMessage(PID_BROWSER, return_msg)); + + app_ = NULL; + browser_ = NULL; + } + + CefRefPtr app_; + CefRefPtr browser_; + + RequestTestRunner test_runner_; + + IMPLEMENT_REFCOUNTING(SendRecvRendererTest); +}; + +// Browser side. +class RequestTestHandler : public TestHandler, + public RequestTestRunner::Delegate { + public: + RequestTestHandler(RequestTestMode test_mode, + bool test_in_browser, + const char* test_url) + : test_mode_(test_mode), + test_in_browser_(test_in_browser), + test_url_(test_url), + ALLOW_THIS_IN_INITIALIZER_LIST(test_runner_(this, true)) { + } + + virtual void RunTest() OVERRIDE { + EXPECT_TRUE(test_url_ != NULL); + AddResource(test_url_, "TEST", "text/html"); + + base::WaitableEvent event(false, false); + SetTestCookie(&event); + event.Wait(); + + // Setup the test. This will create the objects that we test against and + // register any scheme handlers. + test_runner_.SetupTest(test_mode_); + + CreateBrowser(test_url_); + } + + CefRefPtr CreateTestMessage() { + CefRefPtr msg = + CefProcessMessage::Create(kRequestTestMsg); + EXPECT_TRUE(msg->GetArgumentList()->SetInt(0, test_mode_)); + return msg; + } + + virtual void OnLoadEnd(CefRefPtr browser, + CefRefPtr frame, + int httpStatusCode) OVERRIDE { + 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())); + } + } + } + + virtual bool OnProcessMessageReceived( + CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) OVERRIDE { + EXPECT_TRUE(browser.get()); + EXPECT_EQ(PID_RENDERER, source_process); + EXPECT_TRUE(message.get()); + EXPECT_TRUE(message->IsReadOnly()); + + got_message_.yes(); + + if (message->GetArgumentList()->GetBool(0)) + got_success_.yes(); + + // Test is complete. + DestroyTest(test_runner_.settings_); + + return true; + } + + virtual void DestroyTest(const RequestRunSettings& settings) OVERRIDE { + 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(); + + TestHandler::DestroyTest(); + } + + 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 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, + NewCefRunnableMethod(this, &RequestTestHandler::SetTestCookie, + event)); + } + } + + // Remove the cookie that we set above. + void ClearTestCookie(base::WaitableEvent* event) { + if (CefCurrentlyOn(TID_IO)) { + CefRefPtr 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, + NewCefRunnableMethod(this, &RequestTestHandler::ClearTestCookie, + event)); + } + } + + RequestTestMode test_mode_; + bool test_in_browser_; + const char* test_url_; + + RequestTestRunner test_runner_; + + public: + // Only used when the test runs in the render process. + TrackCallback got_message_; + TrackCallback got_success_; +}; + +} // namespace + + +// Entry point for creating URLRequest renderer test objects. +// Called from client_app_delegates.cc. +void CreateURLRequestRendererTests(ClientApp::RenderDelegateSet& delegates) { + delegates.insert(new RequestRendererTest); +} + +// Entry point for registering custom schemes. +// Called from client_app_delegates.cc. +void RegisterURLRequestCustomSchemes( + CefRefPtr registrar, + std::vector& cookiable_schemes) { + registrar->AddCustomScheme(kRequestScheme, true, false, false); + cookiable_schemes.push_back(kRequestScheme); +} + + +// Helpers for defining URLRequest tests. +#define REQ_TEST_EX(name, test_mode, test_in_browser, test_url) \ + TEST(URLRequestTest, name) { \ + CefRefPtr handler = \ + new RequestTestHandler(test_mode, test_in_browser, test_url); \ + handler->ExecuteTest(); \ + if (!test_in_browser) { \ + EXPECT_TRUE(handler->got_message_); \ + EXPECT_TRUE(handler->got_success_); \ + } \ + } + +#define REQ_TEST(name, test_mode, test_in_browser) \ + REQ_TEST_EX(name, test_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(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); diff --git a/tests/unittests/v8_unittest.cc b/tests/unittests/v8_unittest.cc index a99d10711..ea2c27767 100644 --- a/tests/unittests/v8_unittest.cc +++ b/tests/unittests/v8_unittest.cc @@ -1495,8 +1495,7 @@ class V8RendererTest : public ClientApp::RenderDelegate { // Browser side. class V8TestHandler : public TestHandler { public: - explicit V8TestHandler(V8TestMode test_mode, - const char* test_url) + V8TestHandler(V8TestMode test_mode, const char* test_url) : test_mode_(test_mode), test_url_(test_url) { }