1 // Copyright (c) 2015 Marshall A. Greenblatt. All rights reserved. 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google Inc. nor the name Chromium Embedded 14 // Framework nor the names of its contributors may be used to endorse 15 // or promote products derived from this software without specific prior 16 // written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 // 30 // --------------------------------------------------------------------------- 31 // 32 // The contents of this file are only available to applications that link 33 // against the libcef_dll_wrapper target. 34 // 35 36 #ifndef CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_ 37 #define CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_ 38 #pragma once 39 40 #include <list> 41 42 #include "include/base/cef_macros.h" 43 #include "include/base/cef_ref_counted.h" 44 #include "include/base/cef_scoped_ptr.h" 45 #include "include/base/cef_weak_ptr.h" 46 #include "include/cef_request_handler.h" 47 #include "include/wrapper/cef_closure_task.h" 48 #include "include/wrapper/cef_helpers.h" 49 50 /// 51 // Class for managing multiple resource providers. For each resource request 52 // providers will be called in order and have the option to (a) handle the 53 // request by returning a CefResourceHandler, (b) pass the request to the next 54 // provider in order, or (c) stop handling the request. See comments on the 55 // Request object for additional usage information. The methods of this class 56 // may be called on any browser process thread unless otherwise indicated. 57 /// 58 class CefResourceManager 59 : public base::RefCountedThreadSafe<CefResourceManager, 60 CefDeleteOnIOThread> { 61 public: 62 /// 63 // Provides an opportunity to modify |url| before it is passed to a provider. 64 // For example, the implementation could rewrite |url| to include a default 65 // file extension. |url| will be fully qualified and may contain query or 66 // fragment components. 67 /// 68 typedef base::Callback<std::string(const std::string& /*url*/)> UrlFilter; 69 70 /// 71 // Used to resolve mime types for URLs, usually based on the file extension. 72 // |url| will be fully qualified and may contain query or fragment components. 73 /// 74 typedef base::Callback<std::string(const std::string& /*url*/)> 75 MimeTypeResolver; 76 77 private: 78 // Values that stay with a request as it moves between providers. 79 struct RequestParams { 80 std::string url_; 81 CefRefPtr<CefBrowser> browser_; 82 CefRefPtr<CefFrame> frame_; 83 CefRefPtr<CefRequest> request_; 84 UrlFilter url_filter_; 85 MimeTypeResolver mime_type_resolver_; 86 }; 87 88 // Values that are associated with the pending request only. 89 struct RequestState; 90 91 public: 92 /// 93 // Object representing a request. Each request object is used for a single 94 // call to Provider::OnRequest and will become detached (meaning the callbacks 95 // will no longer trigger) after Request::Continue or Request::Stop is called. 96 // A request passed to Provider::OnRequestCanceled will already have been 97 // detached. The methods of this class may be called on any browser process 98 // thread. 99 /// 100 class Request : public base::RefCountedThreadSafe<Request> { 101 public: 102 /// 103 // Returns the URL associated with this request. The returned value will be 104 // fully qualified but will not contain query or fragment components. It 105 // will already have been passed through the URL filter. 106 /// url()107 std::string url() const { return params_.url_; } 108 109 /// 110 // Returns the CefBrowser associated with this request. 111 /// browser()112 CefRefPtr<CefBrowser> browser() const { return params_.browser_; } 113 114 /// 115 // Returns the CefFrame associated with this request. 116 /// frame()117 CefRefPtr<CefFrame> frame() const { return params_.frame_; } 118 119 /// 120 // Returns the CefRequest associated with this request. 121 /// request()122 CefRefPtr<CefRequest> request() const { return params_.request_; } 123 124 /// 125 // Returns the current URL filter. 126 /// url_filter()127 const CefResourceManager::UrlFilter& url_filter() const { 128 return params_.url_filter_; 129 } 130 131 /// 132 // Returns the current mime type resolver. 133 /// mime_type_resolver()134 const CefResourceManager::MimeTypeResolver& mime_type_resolver() const { 135 return params_.mime_type_resolver_; 136 } 137 138 /// 139 // Continue handling the request. If |handler| is non-NULL then no 140 // additional providers will be called and the |handler| value will be 141 // returned via CefResourceManager::GetResourceHandler. If |handler| is NULL 142 // then the next provider in order, if any, will be called. If there are no 143 // additional providers then NULL will be returned via CefResourceManager:: 144 // GetResourceHandler. 145 /// 146 void Continue(CefRefPtr<CefResourceHandler> handler); 147 148 /// 149 // Stop handling the request. No additional providers will be called and 150 // NULL will be returned via CefResourceManager::GetResourceHandler. 151 /// 152 void Stop(); 153 154 private: 155 // Only allow deletion via scoped_refptr. 156 friend class base::RefCountedThreadSafe<Request>; 157 158 friend class CefResourceManager; 159 160 // The below methods are called on the browser process IO thread. 161 162 explicit Request(scoped_ptr<RequestState> state); 163 164 scoped_ptr<RequestState> SendRequest(); 165 bool HasState(); 166 167 static void ContinueOnIOThread(scoped_ptr<RequestState> state, 168 CefRefPtr<CefResourceHandler> handler); 169 static void StopOnIOThread(scoped_ptr<RequestState> state); 170 171 // Will be non-NULL while the request is pending. Only accessed on the 172 // browser process IO thread. 173 scoped_ptr<RequestState> state_; 174 175 // Params that stay with this request object. Safe to access on any thread. 176 RequestParams params_; 177 178 DISALLOW_COPY_AND_ASSIGN(Request); 179 }; 180 181 typedef std::list<scoped_refptr<Request>> RequestList; 182 183 /// 184 // Interface implemented by resource providers. A provider may be created on 185 // any thread but the methods will be called on, and the object will be 186 // destroyed on, the browser process IO thread. 187 /// 188 class Provider { 189 public: 190 /// 191 // Called to handle a request. If the provider knows immediately that it 192 // will not handle the request return false. Otherwise, return true and call 193 // Request::Continue or Request::Stop either in this method or 194 // asynchronously to indicate completion. See comments on Request for 195 // additional usage information. 196 /// 197 virtual bool OnRequest(scoped_refptr<Request> request) = 0; 198 199 /// 200 // Called when a request has been canceled. It is still safe to dereference 201 // |request| but any calls to Request::Continue or Request::Stop will be 202 // ignored. 203 /// OnRequestCanceled(scoped_refptr<Request> request)204 virtual void OnRequestCanceled(scoped_refptr<Request> request) {} 205 ~Provider()206 virtual ~Provider() {} 207 }; 208 209 CefResourceManager(); 210 211 /// 212 // Add a provider that maps requests for |url| to |content|. |url| should be 213 // fully qualified but not include a query or fragment component. If 214 // |mime_type| is empty the MimeTypeResolver will be used. See comments on 215 // AddProvider for usage of the |order| and |identifier| parameters. 216 /// 217 void AddContentProvider(const std::string& url, 218 const std::string& content, 219 const std::string& mime_type, 220 int order, 221 const std::string& identifier); 222 223 /// 224 // Add a provider that maps requests that start with |url_path| to files under 225 // |directory_path|. |url_path| should include an origin and optional path 226 // component only. Files will be loaded when a matching URL is requested. 227 // See comments on AddProvider for usage of the |order| and |identifier| 228 // parameters. 229 /// 230 void AddDirectoryProvider(const std::string& url_path, 231 const std::string& directory_path, 232 int order, 233 const std::string& identifier); 234 235 /// 236 // Add a provider that maps requests that start with |url_path| to files 237 // stored in the archive file at |archive_path|. |url_path| should include an 238 // origin and optional path component only. The archive file will be loaded 239 // when a matching URL is requested for the first time. See comments on 240 // AddProvider for usage of the |order| and |identifier| parameters. 241 /// 242 void AddArchiveProvider(const std::string& url_path, 243 const std::string& archive_path, 244 const std::string& password, 245 int order, 246 const std::string& identifier); 247 248 /// 249 // Add a provider. This object takes ownership of |provider|. Providers will 250 // be called in ascending order based on the |order| value. Multiple providers 251 // sharing the same |order| value will be called in the order that they were 252 // added. The |identifier| value, which does not need to be unique, can be 253 // used to remove the provider at a later time. 254 /// 255 void AddProvider(Provider* provider, 256 int order, 257 const std::string& identifier); 258 259 /// 260 // Remove all providers with the specified |identifier| value. If any removed 261 // providers have pending requests the Provider::OnRequestCancel method will 262 // be called. The removed providers may be deleted immediately or at a later 263 // time. 264 /// 265 void RemoveProviders(const std::string& identifier); 266 267 /// 268 // Remove all providers. If any removed providers have pending requests the 269 // Provider::OnRequestCancel method will be called. The removed providers may 270 // be deleted immediately or at a later time. 271 /// 272 void RemoveAllProviders(); 273 274 /// 275 // Set the url filter. If not set the default no-op filter will be used. 276 // Changes to this value will not affect currently pending requests. 277 /// 278 void SetUrlFilter(const UrlFilter& filter); 279 280 /// 281 // Set the mime type resolver. If not set the default resolver will be used. 282 // Changes to this value will not affect currently pending requests. 283 /// 284 void SetMimeTypeResolver(const MimeTypeResolver& resolver); 285 286 // The below methods should be called from other CEF handlers. They must be 287 // called exactly as documented for the manager to function correctly. 288 289 /// 290 // Called from CefRequestHandler::OnBeforeResourceLoad on the browser process 291 // IO thread. 292 /// 293 cef_return_value_t OnBeforeResourceLoad( 294 CefRefPtr<CefBrowser> browser, 295 CefRefPtr<CefFrame> frame, 296 CefRefPtr<CefRequest> request, 297 CefRefPtr<CefRequestCallback> callback); 298 299 /// 300 // Called from CefRequestHandler::GetResourceHandler on the browser process 301 // IO thread. 302 /// 303 CefRefPtr<CefResourceHandler> GetResourceHandler( 304 CefRefPtr<CefBrowser> browser, 305 CefRefPtr<CefFrame> frame, 306 CefRefPtr<CefRequest> request); 307 308 private: 309 // Only allow deletion via scoped_refptr. 310 friend struct CefDeleteOnThread<TID_IO>; 311 friend class base::RefCountedThreadSafe<CefResourceManager, 312 CefDeleteOnIOThread>; 313 314 ~CefResourceManager(); 315 316 // Provider and associated information. 317 struct ProviderEntry; 318 typedef std::list<ProviderEntry*> ProviderEntryList; 319 320 // Values associated with the pending request only. Ownership will be passed 321 // between requests and the resource manager as request handling proceeds. 322 struct RequestState { 323 ~RequestState(); 324 325 base::WeakPtr<CefResourceManager> manager_; 326 327 // Callback to execute once request handling is complete. 328 CefRefPtr<CefRequestCallback> callback_; 329 330 // Position of the currently associated ProviderEntry in the |providers_| 331 // list. 332 ProviderEntryList::iterator current_entry_pos_; 333 334 // Position of this request object in the currently associated 335 // ProviderEntry's |pending_requests_| list. 336 RequestList::iterator current_request_pos_; 337 338 // Params that will be copied to each request object. 339 RequestParams params_; 340 }; 341 342 // Methods that manage request state between requests. Called on the browser 343 // process IO thread. 344 bool SendRequest(scoped_ptr<RequestState> state); 345 void ContinueRequest(scoped_ptr<RequestState> state, 346 CefRefPtr<CefResourceHandler> handler); 347 void StopRequest(scoped_ptr<RequestState> state); 348 bool IncrementProvider(RequestState* state); 349 void DetachRequestFromProvider(RequestState* state); 350 void GetNextValidProvider(ProviderEntryList::iterator& iterator); 351 void DeleteProvider(ProviderEntryList::iterator& iterator, bool stop); 352 353 // The below members are only accessed on the browser process IO thread. 354 355 // List of providers including additional associated information. 356 ProviderEntryList providers_; 357 358 // Map of response ID to pending CefResourceHandler object. 359 typedef std::map<uint64, CefRefPtr<CefResourceHandler>> PendingHandlersMap; 360 PendingHandlersMap pending_handlers_; 361 362 UrlFilter url_filter_; 363 MimeTypeResolver mime_type_resolver_; 364 365 // Must be the last member. Created and accessed on the IO thread. 366 scoped_ptr<base::WeakPtrFactory<CefResourceManager>> weak_ptr_factory_; 367 368 DISALLOW_COPY_AND_ASSIGN(CefResourceManager); 369 }; 370 371 #endif // CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_ 372