diff --git a/include/cef.h b/include/cef.h index 8c14b9249..1995287f8 100644 --- a/include/cef.h +++ b/include/cef.h @@ -2575,10 +2575,13 @@ class CefSchemeHandlerFactory : public virtual CefBase { public: /// - // Return a new scheme handler instance to handle the request. + // Return a new scheme 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. /// /*--cef()--*/ - virtual CefRefPtr Create(const CefString& scheme_name, + virtual CefRefPtr Create(CefRefPtr browser, + const CefString& scheme_name, CefRefPtr request) =0; }; diff --git a/include/cef_capi.h b/include/cef_capi.h index e998ad380..48e419d6a 100644 --- a/include/cef_capi.h +++ b/include/cef_capi.h @@ -2359,11 +2359,14 @@ typedef struct _cef_scheme_handler_factory_t cef_base_t base; /// - // Return a new scheme handler instance to handle the request. + // Return a new scheme handler instance to handle the request. |browser| will + // be the browser window that initiated the request. If the request was + // initiated using the cef_web_urlrequest_t API |browser| will be NULL. /// struct _cef_scheme_handler_t* (CEF_CALLBACK *create)( struct _cef_scheme_handler_factory_t* self, - const cef_string_t* scheme_name, struct _cef_request_t* request); + struct _cef_browser_t* browser, const cef_string_t* scheme_name, + struct _cef_request_t* request); } cef_scheme_handler_factory_t; diff --git a/libcef/browser_devtools_scheme_handler.cc b/libcef/browser_devtools_scheme_handler.cc index 8fd3c0169..629a71b59 100644 --- a/libcef/browser_devtools_scheme_handler.cc +++ b/libcef/browser_devtools_scheme_handler.cc @@ -77,7 +77,8 @@ class DevToolsSchemeHandlerFactory : public CefSchemeHandlerFactory public: DevToolsSchemeHandlerFactory() {} - virtual CefRefPtr Create(const CefString& scheme_name, + virtual CefRefPtr Create(CefRefPtr browser, + const CefString& scheme_name, CefRefPtr request) OVERRIDE { diff --git a/libcef/browser_resource_loader_bridge.cc b/libcef/browser_resource_loader_bridge.cc index f9082f876..ecc6041e5 100644 --- a/libcef/browser_resource_loader_bridge.cc +++ b/libcef/browser_resource_loader_bridge.cc @@ -111,17 +111,24 @@ static const int kUpdateUploadProgressIntervalMsec = 100; class ExtraRequestInfo : public net::URLRequest::UserData { public: - ExtraRequestInfo(ResourceType::Type resource_type) - : resource_type_(resource_type), + ExtraRequestInfo(CefBrowser* browser, ResourceType::Type resource_type) + : browser_(browser), + resource_type_(resource_type), allow_download_(resource_type == ResourceType::MAIN_FRAME || resource_type == ResourceType::SUB_FRAME) { } + // The browser pointer is guaranteed to be valid for the lifespan of the + // request. The pointer will be NULL in cases where the request was + // initiated via the CefWebURLRequest API instead of by a browser window. + CefBrowser* browser() const { return browser_; } + // Identifies the type of resource, such as subframe, media, etc. ResourceType::Type resource_type() const { return resource_type_; } bool allow_download() const { return allow_download_; } private: + CefBrowser* browser_; ResourceType::Type resource_type_; bool allow_download_; }; @@ -514,7 +521,8 @@ class RequestProxy : public net::URLRequest::Delegate, request_->set_load_flags(params->load_flags); request_->set_upload(params->upload.get()); request_->set_context(_Context->request_context()); - request_->SetUserData(NULL, new ExtraRequestInfo(params->request_type)); + request_->SetUserData(NULL, + new ExtraRequestInfo(browser_.get(), params->request_type)); BrowserAppCacheSystem::SetExtraRequestInfo( request_.get(), params->appcache_host_id, params->request_type); @@ -1130,6 +1138,17 @@ void BrowserResourceLoaderBridge::SetAcceptAllCookies(bool accept_all_cookies) { &BrowserRequestContext::SetAcceptAllCookies, accept_all_cookies)); } +// static +CefRefPtr BrowserResourceLoaderBridge::GetBrowserForRequest( + net::URLRequest* request) { + REQUIRE_IOT(); + ExtraRequestInfo* extra_info = + static_cast(request->GetUserData(NULL)); + if (extra_info) + return extra_info->browser(); + return NULL; +} + //static scoped_refptr BrowserResourceLoaderBridge::GetCacheThread() { diff --git a/libcef/browser_resource_loader_bridge.h b/libcef/browser_resource_loader_bridge.h index ad02542b7..866b25bf8 100644 --- a/libcef/browser_resource_loader_bridge.h +++ b/libcef/browser_resource_loader_bridge.h @@ -6,11 +6,16 @@ #ifndef _BROWSER_RESOURCE_LOADER_BRIDGE_H #define _BROWSER_RESOURCE_LOADER_BRIDGE_H -#include +#include "include/cef.h" #include "base/message_loop_proxy.h" +#include class GURL; +namespace net { +class URLRequest; +}; + class BrowserResourceLoaderBridge { public: // May only be called after Init. @@ -21,6 +26,11 @@ class BrowserResourceLoaderBridge { const GURL& first_party_for_cookies); static void SetAcceptAllCookies(bool accept_all_cookies); + // Return the CefBrowser associated with the specified request. The browser + // will be NULL in cases where the request was initiated using the + // CefWebURLRequest API. + static CefRefPtr GetBrowserForRequest(net::URLRequest* request); + static scoped_refptr GetCacheThread(); }; diff --git a/libcef/scheme_impl.cc b/libcef/scheme_impl.cc index 9f5daebe0..147061959 100644 --- a/libcef/scheme_impl.cc +++ b/libcef/scheme_impl.cc @@ -4,6 +4,7 @@ // found in the LICENSE file. #include "include/cef.h" +#include "browser_resource_loader_bridge.h" #include "cef_context.h" #include "cef_thread.h" #include "request_impl.h" @@ -546,7 +547,10 @@ private: // Call the handler factory to create the handler for the request. CefRefPtr requestPtr(new CefRequestImpl()); static_cast(requestPtr.get())->Set(request); - CefRefPtr handler = factory->Create(scheme, requestPtr); + CefRefPtr browser = + BrowserResourceLoaderBridge::GetBrowserForRequest(request); + CefRefPtr handler = + factory->Create(browser, scheme, requestPtr); if (handler.get()) job = new CefUrlRequestJob(request, handler); } diff --git a/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.cc b/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.cc index 7e2cce815..027af3175 100644 --- a/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.cc +++ b/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.cc @@ -12,18 +12,23 @@ #include "libcef_dll/cpptoc/scheme_handler_cpptoc.h" #include "libcef_dll/cpptoc/scheme_handler_factory_cpptoc.h" +#include "libcef_dll/ctocpp/browser_ctocpp.h" #include "libcef_dll/ctocpp/request_ctocpp.h" // MEMBER FUNCTIONS - Body may be edited by hand. struct _cef_scheme_handler_t* CEF_CALLBACK scheme_handler_factory_create( - struct _cef_scheme_handler_factory_t* self, const cef_string_t* scheme_name, - cef_request_t* request) + struct _cef_scheme_handler_factory_t* self, cef_browser_t* browser, + const cef_string_t* scheme_name, cef_request_t* request) { + CefRefPtr browserPtr; + if (browser) + browserPtr = CefBrowserCToCpp::Wrap(browser); + CefRefPtr rv = - CefSchemeHandlerFactoryCppToC::Get(self)->Create(CefString(scheme_name), - CefRequestCToCpp::Wrap(request)); + CefSchemeHandlerFactoryCppToC::Get(self)->Create(browserPtr, + CefString(scheme_name), CefRequestCToCpp::Wrap(request)); if (rv.get()) return CefSchemeHandlerCppToC::Wrap(rv); diff --git a/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.cc b/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.cc index 26bf9183c..f4f4fc4bc 100644 --- a/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.cc +++ b/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.cc @@ -10,6 +10,7 @@ // tools directory for more information. // +#include "libcef_dll/cpptoc/browser_cpptoc.h" #include "libcef_dll/cpptoc/request_cpptoc.h" #include "libcef_dll/ctocpp/scheme_handler_ctocpp.h" #include "libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h" @@ -18,13 +19,18 @@ // VIRTUAL METHODS - Body may be edited by hand. CefRefPtr CefSchemeHandlerFactoryCToCpp::Create( - const CefString& scheme_name, CefRefPtr request) + CefRefPtr browser, const CefString& scheme_name, + CefRefPtr request) { if(CEF_MEMBER_MISSING(struct_, create)) return NULL; - cef_scheme_handler_t* rv = struct_->create(struct_, scheme_name.GetStruct(), - CefRequestCppToC::Wrap(request)); + cef_browser_t* browserStruct = NULL; + if (browser.get()) + browserStruct = CefBrowserCppToC::Wrap(browser); + + cef_scheme_handler_t* rv = struct_->create(struct_, browserStruct, + scheme_name.GetStruct(), CefRequestCppToC::Wrap(request)); if (rv) return CefSchemeHandlerCToCpp::Wrap(rv); diff --git a/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h b/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h index c2088b52d..4a21299a6 100644 --- a/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h +++ b/libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h @@ -33,8 +33,8 @@ public: virtual ~CefSchemeHandlerFactoryCToCpp() {} // CefSchemeHandlerFactory methods - virtual CefRefPtr Create(const CefString& scheme_name, - CefRefPtr request) OVERRIDE; + virtual CefRefPtr Create(CefRefPtr browser, + const CefString& scheme_name, CefRefPtr request) OVERRIDE; }; #endif // BUILDING_CEF_SHARED diff --git a/tests/cefclient/scheme_test.cpp b/tests/cefclient/scheme_test.cpp index 01daf0833..dac915bb6 100644 --- a/tests/cefclient/scheme_test.cpp +++ b/tests/cefclient/scheme_test.cpp @@ -145,8 +145,10 @@ class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory { public: // Return a new scheme handler instance to handle the request. - virtual CefRefPtr Create(const CefString& scheme_name, + virtual CefRefPtr Create(CefRefPtr browser, + const CefString& scheme_name, CefRefPtr request) + OVERRIDE { REQUIRE_IO_THREAD(); return new ClientSchemeHandler(); diff --git a/tests/unittests/scheme_handler_unittest.cc b/tests/unittests/scheme_handler_unittest.cc index 818230eee..e32eab40b 100644 --- a/tests/unittests/scheme_handler_unittest.cc +++ b/tests/unittests/scheme_handler_unittest.cc @@ -308,8 +308,10 @@ public: ClientSchemeHandlerFactory(TestResults* tr) : test_results_(tr){} - virtual CefRefPtr Create(const CefString& scheme_name, + virtual CefRefPtr Create(CefRefPtr browser, + const CefString& scheme_name, CefRefPtr request) + OVERRIDE { EXPECT_TRUE(CefCurrentlyOn(TID_IO)); return new ClientSchemeHandler(test_results_);