mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Add CefResourceManager class for mapping requests to data providers (issue #1640).
This commit is contained in:
372
include/wrapper/cef_resource_manager.h
Normal file
372
include/wrapper/cef_resource_manager.h
Normal file
@@ -0,0 +1,372 @@
|
||||
// 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_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.
|
||||
base::WeakPtrFactory<CefResourceManager> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefResourceManager);
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_
|
Reference in New Issue
Block a user