mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			372 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			372 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // 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_
 |