appcache_host.h revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef WEBKIT_BROWSER_APPCACHE_APPCACHE_HOST_H_ 6#define WEBKIT_BROWSER_APPCACHE_APPCACHE_HOST_H_ 7 8#include "base/callback.h" 9#include "base/gtest_prod_util.h" 10#include "base/memory/ref_counted.h" 11#include "base/observer_list.h" 12#include "url/gurl.h" 13#include "webkit/browser/appcache/appcache_group.h" 14#include "webkit/browser/appcache/appcache_service.h" 15#include "webkit/browser/appcache/appcache_storage.h" 16#include "webkit/browser/webkit_storage_browser_export.h" 17#include "webkit/common/appcache/appcache_interfaces.h" 18#include "webkit/common/resource_type.h" 19 20namespace net { 21class URLRequest; 22} // namespace net 23 24namespace content { 25class AppCacheStorageImplTest; 26} 27 28namespace appcache { 29 30class AppCache; 31class AppCacheFrontend; 32class AppCacheRequestHandler; 33 34typedef base::Callback<void(Status, void*)> GetStatusCallback; 35typedef base::Callback<void(bool, void*)> StartUpdateCallback; 36typedef base::Callback<void(bool, void*)> SwapCacheCallback; 37 38// Server-side representation of an application cache host. 39class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheHost 40 : public AppCacheStorage::Delegate, 41 public AppCacheGroup::UpdateObserver, 42 public AppCacheService::Observer { 43 public: 44 45 class WEBKIT_STORAGE_BROWSER_EXPORT Observer { 46 public: 47 // Called just after the cache selection algorithm completes. 48 virtual void OnCacheSelectionComplete(AppCacheHost* host) = 0; 49 50 // Called just prior to the instance being deleted. 51 virtual void OnDestructionImminent(AppCacheHost* host) = 0; 52 53 virtual ~Observer() {} 54 }; 55 56 AppCacheHost(int host_id, AppCacheFrontend* frontend, 57 AppCacheService* service); 58 virtual ~AppCacheHost(); 59 60 // Adds/removes an observer, the AppCacheHost does not take 61 // ownership of the observer. 62 void AddObserver(Observer* observer); 63 void RemoveObserver(Observer* observer); 64 65 // Support for cache selection and scriptable method calls. 66 void SelectCache(const GURL& document_url, 67 const int64 cache_document_was_loaded_from, 68 const GURL& manifest_url); 69 void SelectCacheForWorker(int parent_process_id, 70 int parent_host_id); 71 void SelectCacheForSharedWorker(int64 appcache_id); 72 void MarkAsForeignEntry(const GURL& document_url, 73 int64 cache_document_was_loaded_from); 74 void GetStatusWithCallback(const GetStatusCallback& callback, 75 void* callback_param); 76 void StartUpdateWithCallback(const StartUpdateCallback& callback, 77 void* callback_param); 78 void SwapCacheWithCallback(const SwapCacheCallback& callback, 79 void* callback_param); 80 81 // Called prior to the main resource load. When the system contains multiple 82 // candidates for a main resource load, the appcache preferred by the host 83 // that created this host is used to break ties. 84 void SetSpawningHostId(int spawning_process_id, int spawning_host_id); 85 86 // May return NULL if the spawning host context has been closed, or if a 87 // spawning host context was never identified. 88 const AppCacheHost* GetSpawningHost() const; 89 90 const GURL& preferred_manifest_url() const { 91 return preferred_manifest_url_; 92 } 93 void set_preferred_manifest_url(const GURL& url) { 94 preferred_manifest_url_ = url; 95 } 96 97 // Support for loading resources out of the appcache. 98 // May return NULL if the request isn't subject to retrieval from an appache. 99 AppCacheRequestHandler* CreateRequestHandler( 100 net::URLRequest* request, ResourceType::Type resource_type); 101 102 // Support for devtools inspecting appcache resources. 103 void GetResourceList(std::vector<AppCacheResourceInfo>* resource_infos); 104 105 // Breaks any existing association between this host and a cache. 106 // 'manifest_url' is sent to DevTools as the manifest url that could have 107 // been associated before or could be associated later with this host. 108 // Associations are broken either thru the cache selection algorithm 109 // implemented in this class, or by the update algorithm (see 110 // AppCacheUpdateJob). 111 void AssociateNoCache(const GURL& manifest_url); 112 113 // Establishes an association between this host and an incomplete cache. 114 // 'manifest_url' is manifest url of the cache group being updated. 115 // Associations with incomplete caches are established by the update algorithm 116 // (see AppCacheUpdateJob). 117 void AssociateIncompleteCache(AppCache* cache, const GURL& manifest_url); 118 119 // Establishes an association between this host and a complete cache. 120 // Associations with complete caches are established either thru the cache 121 // selection algorithm implemented (in this class), or by the update algorithm 122 // (see AppCacheUpdateJob). 123 void AssociateCompleteCache(AppCache* cache); 124 125 // Adds a reference to the newest complete cache in a group, unless it's the 126 // same as the cache that is currently associated with the host. 127 void SetSwappableCache(AppCacheGroup* group); 128 129 // Used to ensure that a loaded appcache survives a frame navigation. 130 void LoadMainResourceCache(int64 cache_id); 131 132 // Used to notify the host that a namespace resource is being delivered as 133 // the main resource of the page and to provide its url. 134 void NotifyMainResourceIsNamespaceEntry(const GURL& namespace_entry_url); 135 136 // Used to notify the host that the main resource was blocked by a policy. To 137 // work properly, this method needs to by invoked prior to cache selection. 138 void NotifyMainResourceBlocked(const GURL& manifest_url); 139 140 // Used by the update job to keep track of which hosts are associated 141 // with which pending master entries. 142 const GURL& pending_master_entry_url() const { 143 return new_master_entry_url_; 144 } 145 146 int host_id() const { return host_id_; } 147 AppCacheService* service() const { return service_; } 148 AppCacheStorage* storage() const { return storage_; } 149 AppCacheFrontend* frontend() const { return frontend_; } 150 AppCache* associated_cache() const { return associated_cache_.get(); } 151 152 bool is_selection_pending() const { 153 return pending_selected_cache_id_ != kNoCacheId || 154 !pending_selected_manifest_url_.is_empty(); 155 } 156 157 const GURL& first_party_url() const { return first_party_url_; } 158 159 // Methods to support cross site navigations. 160 void PrepareForTransfer(); 161 void CompleteTransfer(int host_id, AppCacheFrontend* frontend); 162 163 private: 164 Status GetStatus(); 165 void LoadSelectedCache(int64 cache_id); 166 void LoadOrCreateGroup(const GURL& manifest_url); 167 168 // See public Associate*Host() methods above. 169 void AssociateCacheHelper(AppCache* cache, const GURL& manifest_url); 170 171 // AppCacheStorage::Delegate impl 172 virtual void OnCacheLoaded(AppCache* cache, int64 cache_id) OVERRIDE; 173 virtual void OnGroupLoaded(AppCacheGroup* group, 174 const GURL& manifest_url) OVERRIDE; 175 // AppCacheService::Observer impl 176 virtual void OnServiceReinitialized( 177 AppCacheStorageReference* old_storage_ref) OVERRIDE; 178 179 void FinishCacheSelection(AppCache* cache, AppCacheGroup* group); 180 void DoPendingGetStatus(); 181 void DoPendingStartUpdate(); 182 void DoPendingSwapCache(); 183 184 void ObserveGroupBeingUpdated(AppCacheGroup* group); 185 186 // AppCacheGroup::UpdateObserver methods. 187 virtual void OnUpdateComplete(AppCacheGroup* group) OVERRIDE; 188 189 // Returns true if this host is for a dedicated worker context. 190 bool is_for_dedicated_worker() const { 191 return parent_host_id_ != kNoHostId; 192 } 193 194 // Returns the parent context's host instance. This is only valid 195 // to call when this instance is_for_dedicated_worker. 196 AppCacheHost* GetParentAppCacheHost() const; 197 198 // Identifies the corresponding appcache host in the child process. 199 int host_id_; 200 201 // Information about the host that created this one; the manifest 202 // preferred by our creator influences which cache our main resource 203 // should be loaded from. 204 int spawning_host_id_; 205 int spawning_process_id_; 206 GURL preferred_manifest_url_; 207 208 // Hosts for dedicated workers are special cased to shunt 209 // request handling off to the dedicated worker's parent. 210 // The scriptable api is not accessible in dedicated workers 211 // so the other aspects of this class are not relevant for 212 // these special case instances. 213 int parent_host_id_; 214 int parent_process_id_; 215 216 // Defined prior to refs to AppCaches and Groups because destruction 217 // order matters, the disabled_storage_reference_ must outlive those 218 // objects. See additional comments for the storage_ member. 219 scoped_refptr<AppCacheStorageReference> disabled_storage_reference_; 220 221 // The cache associated with this host, if any. 222 scoped_refptr<AppCache> associated_cache_; 223 224 // Hold a reference to the newest complete cache (if associated cache is 225 // not the newest) to keep the newest cache in existence while the app cache 226 // group is in use. The newest complete cache may have no associated hosts 227 // holding any references to it and would otherwise be deleted prematurely. 228 scoped_refptr<AppCache> swappable_cache_; 229 230 // Keep a reference to the group being updated until the update completes. 231 scoped_refptr<AppCacheGroup> group_being_updated_; 232 233 // Similarly, keep a reference to the newest cache of the group until the 234 // update completes. When adding a new master entry to a cache that is not 235 // in use in any other host, this reference keeps the cache in memory. 236 scoped_refptr<AppCache> newest_cache_of_group_being_updated_; 237 238 // Keep a reference to the cache of the main resource so it survives frame 239 // navigations. 240 scoped_refptr<AppCache> main_resource_cache_; 241 int64 pending_main_resource_cache_id_; 242 243 // Cache loading is async, if we're loading a specific cache or group 244 // for the purposes of cache selection, one or the other of these will 245 // indicate which cache or group is being loaded. 246 int64 pending_selected_cache_id_; 247 GURL pending_selected_manifest_url_; 248 249 // A new master entry to be added to the cache, may be empty. 250 GURL new_master_entry_url_; 251 252 // The frontend proxy to deliver notifications to the child process. 253 AppCacheFrontend* frontend_; 254 255 // Our central service object. 256 AppCacheService* service_; 257 258 // And the equally central storage object, with a twist. In some error 259 // conditions the storage object gets recreated and reinitialized. The 260 // disabled_storage_reference_ (defined earlier) allows for cleanup of an 261 // instance that got disabled after we had latched onto it. In normal 262 // circumstances, disabled_storage_reference_ is expected to be NULL. 263 // When non-NULL both storage_ and disabled_storage_reference_ refer to the 264 // same instance. 265 AppCacheStorage* storage_; 266 267 // Since these are synchronous scriptable API calls in the client, there can 268 // only be one type of callback pending. Also, we have to wait until we have a 269 // cache selection prior to responding to these calls, as cache selection 270 // involves async loading of a cache or a group from storage. 271 GetStatusCallback pending_get_status_callback_; 272 StartUpdateCallback pending_start_update_callback_; 273 SwapCacheCallback pending_swap_cache_callback_; 274 void* pending_callback_param_; 275 276 // True if an intercept or fallback namespace resource was 277 // delivered as the main resource. 278 bool main_resource_was_namespace_entry_; 279 GURL namespace_entry_url_; 280 281 // True if requests for this host were blocked by a policy. 282 bool main_resource_blocked_; 283 GURL blocked_manifest_url_; 284 285 // Tells if info about associated cache is pending. Info is pending 286 // when update job has not returned success yet. 287 bool associated_cache_info_pending_; 288 289 // List of objects observing us. 290 ObserverList<Observer> observers_; 291 292 // Used to inform the QuotaManager of what origins are currently in use. 293 GURL origin_in_use_; 294 295 // First party url to be used in policy checks. 296 GURL first_party_url_; 297 298 friend class content::AppCacheStorageImplTest; 299 friend class AppCacheRequestHandlerTest; 300 friend class AppCacheUpdateJobTest; 301 FRIEND_TEST_ALL_PREFIXES(AppCacheTest, CleanupUnusedCache); 302 FRIEND_TEST_ALL_PREFIXES(AppCacheGroupTest, CleanupUnusedGroup); 303 FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, Basic); 304 FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, SelectNoCache); 305 FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, ForeignEntry); 306 FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, FailedCacheLoad); 307 FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, FailedGroupLoad); 308 FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, SetSwappableCache); 309 FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, ForDedicatedWorker); 310 FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, SelectCacheAllowed); 311 FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, SelectCacheBlocked); 312 FRIEND_TEST_ALL_PREFIXES(AppCacheGroupTest, QueueUpdate); 313 314 DISALLOW_COPY_AND_ASSIGN(AppCacheHost); 315}; 316 317} // namespace appcache 318 319#endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_HOST_H_ 320