| // Copyright (c) 2015 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 are only available to applications that link |
| // against the libcef_dll_wrapper target. |
| // |
| |
| #ifndef CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_ |
| #define CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_ |
| #pragma once |
| |
| #include <list> |
| |
| #include "include/base/cef_macros.h" |
| #include "include/base/cef_ref_counted.h" |
| #include "include/base/cef_scoped_ptr.h" |
| #include "include/base/cef_weak_ptr.h" |
| #include "include/cef_request_handler.h" |
| #include "include/wrapper/cef_closure_task.h" |
| #include "include/wrapper/cef_helpers.h" |
| |
| /// |
| // Class for managing multiple resource providers. For each resource request |
| // providers will be called in order and have the option to (a) handle the |
| // request by returning a CefResourceHandler, (b) pass the request to the next |
| // provider in order, or (c) stop handling the request. See comments on the |
| // Request object for additional usage information. The methods of this class |
| // may be called on any browser process thread unless otherwise indicated. |
| /// |
| class CefResourceManager |
| : public base::RefCountedThreadSafe<CefResourceManager, |
| CefDeleteOnIOThread> { |
| public: |
| /// |
| // Provides an opportunity to modify |url| before it is passed to a provider. |
| // For example, the implementation could rewrite |url| to include a default |
| // file extension. |url| will be fully qualified and may contain query or |
| // fragment components. |
| /// |
| typedef base::Callback<std::string(const std::string& /*url*/)> UrlFilter; |
| |
| /// |
| // Used to resolve mime types for URLs, usually based on the file extension. |
| // |url| will be fully qualified and may contain query or fragment components. |
| /// |
| typedef base::Callback<std::string(const std::string& /*url*/)> |
| MimeTypeResolver; |
| |
| private: |
| // Values that stay with a request as it moves between providers. |
| struct RequestParams { |
| std::string url_; |
| CefRefPtr<CefBrowser> browser_; |
| CefRefPtr<CefFrame> frame_; |
| CefRefPtr<CefRequest> request_; |
| UrlFilter url_filter_; |
| MimeTypeResolver mime_type_resolver_; |
| }; |
| |
| // Values that are associated with the pending request only. |
| struct RequestState; |
| |
| public: |
| /// |
| // Object representing a request. Each request object is used for a single |
| // call to Provider::OnRequest and will become detached (meaning the callbacks |
| // will no longer trigger) after Request::Continue or Request::Stop is called. |
| // A request passed to Provider::OnRequestCanceled will already have been |
| // detached. The methods of this class may be called on any browser process |
| // thread. |
| /// |
| class Request : public base::RefCountedThreadSafe<Request> { |
| public: |
| /// |
| // Returns the URL associated with this request. The returned value will be |
| // fully qualified but will not contain query or fragment components. It |
| // will already have been passed through the URL filter. |
| /// |
| std::string url() const { return params_.url_; } |
| |
| /// |
| // Returns the CefBrowser associated with this request. |
| /// |
| CefRefPtr<CefBrowser> browser() const { return params_.browser_; } |
| |
| /// |
| // Returns the CefFrame associated with this request. |
| /// |
| CefRefPtr<CefFrame> frame() const { return params_.frame_; } |
| |
| /// |
| // Returns the CefRequest associated with this request. |
| /// |
| CefRefPtr<CefRequest> request() const { return params_.request_; } |
| |
| /// |
| // Returns the current URL filter. |
| /// |
| const CefResourceManager::UrlFilter& url_filter() const { |
| return params_.url_filter_; |
| } |
| |
| /// |
| // Returns the current mime type resolver. |
| /// |
| const CefResourceManager::MimeTypeResolver& mime_type_resolver() const { |
| return params_.mime_type_resolver_; |
| } |
| |
| /// |
| // Continue handling the request. If |handler| is non-NULL then no |
| // additional providers will be called and the |handler| value will be |
| // returned via CefResourceManager::GetResourceHandler. If |handler| is NULL |
| // then the next provider in order, if any, will be called. If there are no |
| // additional providers then NULL will be returned via CefResourceManager:: |
| // GetResourceHandler. |
| /// |
| void Continue(CefRefPtr<CefResourceHandler> handler); |
| |
| /// |
| // Stop handling the request. No additional providers will be called and |
| // NULL will be returned via CefResourceManager::GetResourceHandler. |
| /// |
| void Stop(); |
| |
| private: |
| // Only allow deletion via scoped_refptr. |
| friend class base::RefCountedThreadSafe<Request>; |
| |
| friend class CefResourceManager; |
| |
| // The below methods are called on the browser process IO thread. |
| |
| explicit Request(scoped_ptr<RequestState> state); |
| |
| scoped_ptr<RequestState> SendRequest(); |
| bool HasState(); |
| |
| static void ContinueOnIOThread(scoped_ptr<RequestState> state, |
| CefRefPtr<CefResourceHandler> handler); |
| static void StopOnIOThread(scoped_ptr<RequestState> state); |
| |
| // Will be non-NULL while the request is pending. Only accessed on the |
| // browser process IO thread. |
| scoped_ptr<RequestState> state_; |
| |
| // Params that stay with this request object. Safe to access on any thread. |
| RequestParams params_; |
| |
| DISALLOW_COPY_AND_ASSIGN(Request); |
| }; |
| |
| typedef std::list<scoped_refptr<Request>> RequestList; |
| |
| /// |
| // Interface implemented by resource providers. A provider may be created on |
| // any thread but the methods will be called on, and the object will be |
| // destroyed on, the browser process IO thread. |
| /// |
| class Provider { |
| public: |
| /// |
| // Called to handle a request. If the provider knows immediately that it |
| // will not handle the request return false. Otherwise, return true and call |
| // Request::Continue or Request::Stop either in this method or |
| // asynchronously to indicate completion. See comments on Request for |
| // additional usage information. |
| /// |
| virtual bool OnRequest(scoped_refptr<Request> request) = 0; |
| |
| /// |
| // Called when a request has been canceled. It is still safe to dereference |
| // |request| but any calls to Request::Continue or Request::Stop will be |
| // ignored. |
| /// |
| virtual void OnRequestCanceled(scoped_refptr<Request> request) {} |
| |
| virtual ~Provider() {} |
| }; |
| |
| CefResourceManager(); |
| |
| /// |
| // Add a provider that maps requests for |url| to |content|. |url| should be |
| // fully qualified but not include a query or fragment component. If |
| // |mime_type| is empty the MimeTypeResolver will be used. See comments on |
| // AddProvider for usage of the |order| and |identifier| parameters. |
| /// |
| void AddContentProvider(const std::string& url, |
| const std::string& content, |
| const std::string& mime_type, |
| int order, |
| const std::string& identifier); |
| |
| /// |
| // Add a provider that maps requests that start with |url_path| to files under |
| // |directory_path|. |url_path| should include an origin and optional path |
| // component only. Files will be loaded when a matching URL is requested. |
| // See comments on AddProvider for usage of the |order| and |identifier| |
| // parameters. |
| /// |
| void AddDirectoryProvider(const std::string& url_path, |
| const std::string& directory_path, |
| int order, |
| const std::string& identifier); |
| |
| /// |
| // Add a provider that maps requests that start with |url_path| to files |
| // stored in the archive file at |archive_path|. |url_path| should include an |
| // origin and optional path component only. The archive file will be loaded |
| // when a matching URL is requested for the first time. See comments on |
| // AddProvider for usage of the |order| and |identifier| parameters. |
| /// |
| void AddArchiveProvider(const std::string& url_path, |
| const std::string& archive_path, |
| const std::string& password, |
| int order, |
| const std::string& identifier); |
| |
| /// |
| // Add a provider. This object takes ownership of |provider|. Providers will |
| // be called in ascending order based on the |order| value. Multiple providers |
| // sharing the same |order| value will be called in the order that they were |
| // added. The |identifier| value, which does not need to be unique, can be |
| // used to remove the provider at a later time. |
| /// |
| void AddProvider(Provider* provider, |
| int order, |
| const std::string& identifier); |
| |
| /// |
| // Remove all providers with the specified |identifier| value. If any removed |
| // providers have pending requests the Provider::OnRequestCancel method will |
| // be called. The removed providers may be deleted immediately or at a later |
| // time. |
| /// |
| void RemoveProviders(const std::string& identifier); |
| |
| /// |
| // Remove all providers. If any removed providers have pending requests the |
| // Provider::OnRequestCancel method will be called. The removed providers may |
| // be deleted immediately or at a later time. |
| /// |
| void RemoveAllProviders(); |
| |
| /// |
| // Set the url filter. If not set the default no-op filter will be used. |
| // Changes to this value will not affect currently pending requests. |
| /// |
| void SetUrlFilter(const UrlFilter& filter); |
| |
| /// |
| // Set the mime type resolver. If not set the default resolver will be used. |
| // Changes to this value will not affect currently pending requests. |
| /// |
| void SetMimeTypeResolver(const MimeTypeResolver& resolver); |
| |
| // The below methods should be called from other CEF handlers. They must be |
| // called exactly as documented for the manager to function correctly. |
| |
| /// |
| // Called from CefRequestHandler::OnBeforeResourceLoad on the browser process |
| // IO thread. |
| /// |
| cef_return_value_t OnBeforeResourceLoad( |
| CefRefPtr<CefBrowser> browser, |
| CefRefPtr<CefFrame> frame, |
| CefRefPtr<CefRequest> request, |
| CefRefPtr<CefRequestCallback> callback); |
| |
| /// |
| // Called from CefRequestHandler::GetResourceHandler on the browser process |
| // IO thread. |
| /// |
| CefRefPtr<CefResourceHandler> GetResourceHandler( |
| CefRefPtr<CefBrowser> browser, |
| CefRefPtr<CefFrame> frame, |
| CefRefPtr<CefRequest> request); |
| |
| private: |
| // Only allow deletion via scoped_refptr. |
| friend struct CefDeleteOnThread<TID_IO>; |
| friend class base::RefCountedThreadSafe<CefResourceManager, |
| CefDeleteOnIOThread>; |
| |
| ~CefResourceManager(); |
| |
| // Provider and associated information. |
| struct ProviderEntry; |
| typedef std::list<ProviderEntry*> ProviderEntryList; |
| |
| // Values associated with the pending request only. Ownership will be passed |
| // between requests and the resource manager as request handling proceeds. |
| struct RequestState { |
| ~RequestState(); |
| |
| base::WeakPtr<CefResourceManager> manager_; |
| |
| // Callback to execute once request handling is complete. |
| CefRefPtr<CefRequestCallback> callback_; |
| |
| // Position of the currently associated ProviderEntry in the |providers_| |
| // list. |
| ProviderEntryList::iterator current_entry_pos_; |
| |
| // Position of this request object in the currently associated |
| // ProviderEntry's |pending_requests_| list. |
| RequestList::iterator current_request_pos_; |
| |
| // Params that will be copied to each request object. |
| RequestParams params_; |
| }; |
| |
| // Methods that manage request state between requests. Called on the browser |
| // process IO thread. |
| bool SendRequest(scoped_ptr<RequestState> state); |
| void ContinueRequest(scoped_ptr<RequestState> state, |
| CefRefPtr<CefResourceHandler> handler); |
| void StopRequest(scoped_ptr<RequestState> state); |
| bool IncrementProvider(RequestState* state); |
| void DetachRequestFromProvider(RequestState* state); |
| void GetNextValidProvider(ProviderEntryList::iterator& iterator); |
| void DeleteProvider(ProviderEntryList::iterator& iterator, bool stop); |
| |
| // The below members are only accessed on the browser process IO thread. |
| |
| // List of providers including additional associated information. |
| ProviderEntryList providers_; |
| |
| // Map of response ID to pending CefResourceHandler object. |
| typedef std::map<uint64, CefRefPtr<CefResourceHandler>> PendingHandlersMap; |
| PendingHandlersMap pending_handlers_; |
| |
| UrlFilter url_filter_; |
| MimeTypeResolver mime_type_resolver_; |
| |
| // Must be the last member. Created and accessed on the IO thread. |
| scoped_ptr<base::WeakPtrFactory<CefResourceManager>> weak_ptr_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CefResourceManager); |
| }; |
| |
| #endif // CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_ |