• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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_H_
6 #define WEBKIT_BROWSER_APPCACHE_APPCACHE_H_
7 
8 #include <map>
9 #include <set>
10 #include <vector>
11 
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/time/time.h"
15 #include "url/gurl.h"
16 #include "webkit/browser/appcache/appcache_database.h"
17 #include "webkit/browser/appcache/appcache_entry.h"
18 #include "webkit/browser/appcache/manifest_parser.h"
19 #include "webkit/browser/webkit_storage_browser_export.h"
20 
21 namespace net {
22 class IOBuffer;
23 }
24 
25 namespace appcache {
26 
27 class AppCacheExecutableHandler;
28 class AppCacheGroup;
29 class AppCacheHost;
30 class AppCacheStorage;
31 
32 // Set of cached resources for an application. A cache exists as long as a
33 // host is associated with it, the cache is in an appcache group or the
34 // cache is being created during an appcache upate.
35 class WEBKIT_STORAGE_BROWSER_EXPORT AppCache
36     : public base::RefCounted<AppCache> {
37  public:
38   typedef std::map<GURL, AppCacheEntry> EntryMap;
39   typedef std::set<AppCacheHost*> AppCacheHosts;
40 
41   AppCache(AppCacheStorage* storage, int64 cache_id);
42 
cache_id()43   int64 cache_id() const { return cache_id_; }
44 
owning_group()45   AppCacheGroup* owning_group() const { return owning_group_.get(); }
46 
is_complete()47   bool is_complete() const { return is_complete_; }
set_complete(bool value)48   void set_complete(bool value) { is_complete_ = value; }
49 
50   // Adds a new entry. Entry must not already be in cache.
51   void AddEntry(const GURL& url, const AppCacheEntry& entry);
52 
53   // Adds a new entry or modifies an existing entry by merging the types
54   // of the new entry with the existing entry. Returns true if a new entry
55   // is added, false if the flags are merged into an existing entry.
56   bool AddOrModifyEntry(const GURL& url, const AppCacheEntry& entry);
57 
58   // Removes an entry from the EntryMap, the URL must be in the set.
59   void RemoveEntry(const GURL& url);
60 
61   // Do not store or delete the returned ptr, they're owned by 'this'.
62   AppCacheEntry* GetEntry(const GURL& url);
GetEntryWithResponseId(int64 response_id)63   const AppCacheEntry* GetEntryWithResponseId(int64 response_id) {
64     return GetEntryAndUrlWithResponseId(response_id, NULL);
65   }
66   const AppCacheEntry* GetEntryAndUrlWithResponseId(
67       int64 response_id, GURL* optional_url);
entries()68   const EntryMap& entries() const { return entries_; }
69 
70   // The AppCache owns the collection of executable handlers that have
71   // been started for this instance. The getter looks up an existing
72   // handler returning null if not found, the GetOrCreate method will
73   // cons one up if not found.
74   // Do not store the returned ptrs, they're owned by 'this'.
75   AppCacheExecutableHandler* GetExecutableHandler(int64 response_id);
76   AppCacheExecutableHandler* GetOrCreateExecutableHandler(
77       int64 response_id, net::IOBuffer* handler_source);
78 
79   // Returns the URL of the resource used as entry for 'namespace_url'.
GetFallbackEntryUrl(const GURL & namespace_url)80   GURL GetFallbackEntryUrl(const GURL& namespace_url) const {
81     return GetNamespaceEntryUrl(fallback_namespaces_, namespace_url);
82   }
GetInterceptEntryUrl(const GURL & namespace_url)83   GURL GetInterceptEntryUrl(const GURL& namespace_url) const {
84     return GetNamespaceEntryUrl(intercept_namespaces_, namespace_url);
85   }
86 
associated_hosts()87   AppCacheHosts& associated_hosts() { return associated_hosts_; }
88 
IsNewerThan(AppCache * cache)89   bool IsNewerThan(AppCache* cache) const {
90     // TODO(michaeln): revisit, the system clock can be set
91     // back in time which would confuse this logic.
92     if (update_time_ > cache->update_time_)
93       return true;
94 
95     // Tie breaker. Newer caches have a larger cache ID.
96     if (update_time_ == cache->update_time_)
97       return cache_id_ > cache->cache_id_;
98 
99     return false;
100   }
101 
update_time()102   base::Time update_time() const { return update_time_; }
103 
cache_size()104   int64 cache_size() const { return cache_size_; }
105 
set_update_time(base::Time ticks)106   void set_update_time(base::Time ticks) { update_time_ = ticks; }
107 
108   // Initializes the cache with information in the manifest.
109   // Do not use the manifest after this call.
110   void InitializeWithManifest(Manifest* manifest);
111 
112   // Initializes the cache with the information in the database records.
113   void InitializeWithDatabaseRecords(
114       const AppCacheDatabase::CacheRecord& cache_record,
115       const std::vector<AppCacheDatabase::EntryRecord>& entries,
116       const std::vector<AppCacheDatabase::NamespaceRecord>& intercepts,
117       const std::vector<AppCacheDatabase::NamespaceRecord>& fallbacks,
118       const std::vector<AppCacheDatabase::OnlineWhiteListRecord>& whitelists);
119 
120   // Returns the database records to be stored in the AppCacheDatabase
121   // to represent this cache.
122   void ToDatabaseRecords(
123       const AppCacheGroup* group,
124       AppCacheDatabase::CacheRecord* cache_record,
125       std::vector<AppCacheDatabase::EntryRecord>* entries,
126       std::vector<AppCacheDatabase::NamespaceRecord>* intercepts,
127       std::vector<AppCacheDatabase::NamespaceRecord>* fallbacks,
128       std::vector<AppCacheDatabase::OnlineWhiteListRecord>* whitelists);
129 
130   bool FindResponseForRequest(const GURL& url,
131       AppCacheEntry* found_entry, GURL* found_intercept_namespace,
132       AppCacheEntry* found_fallback_entry, GURL* found_fallback_namespace,
133       bool* found_network_namespace);
134 
135   // Populates the 'infos' vector with an element per entry in the appcache.
136   void ToResourceInfoVector(AppCacheResourceInfoVector* infos) const;
137 
138   static const Namespace* FindNamespace(
139       const NamespaceVector& namespaces,
140       const GURL& url);
141 
142  private:
143   friend class AppCacheGroup;
144   friend class AppCacheHost;
145   friend class AppCacheStorageImplTest;
146   friend class AppCacheUpdateJobTest;
147   friend class base::RefCounted<AppCache>;
148 
149   ~AppCache();
150 
151   // Use AppCacheGroup::Add/RemoveCache() to manipulate owning group.
set_owning_group(AppCacheGroup * group)152   void set_owning_group(AppCacheGroup* group) { owning_group_ = group; }
153 
154   // FindResponseForRequest helpers
FindInterceptNamespace(const GURL & url)155   const Namespace* FindInterceptNamespace(const GURL& url) {
156     return FindNamespace(intercept_namespaces_, url);
157   }
FindFallbackNamespace(const GURL & url)158   const Namespace* FindFallbackNamespace(const GURL& url) {
159     return FindNamespace(fallback_namespaces_, url);
160   }
IsInNetworkNamespace(const GURL & url)161   bool IsInNetworkNamespace(const GURL& url) {
162     return FindNamespace(online_whitelist_namespaces_, url) != NULL;
163   }
164 
165   GURL GetNamespaceEntryUrl(const NamespaceVector& namespaces,
166                             const GURL& namespace_url) const;
167 
168   // Use AppCacheHost::Associate*Cache() to manipulate host association.
AssociateHost(AppCacheHost * host)169   void AssociateHost(AppCacheHost* host) {
170     associated_hosts_.insert(host);
171   }
172   void UnassociateHost(AppCacheHost* host);
173 
174   const int64 cache_id_;
175   scoped_refptr<AppCacheGroup> owning_group_;
176   AppCacheHosts associated_hosts_;
177 
178   EntryMap entries_;    // contains entries of all types
179 
180   NamespaceVector intercept_namespaces_;
181   NamespaceVector fallback_namespaces_;
182   NamespaceVector online_whitelist_namespaces_;
183   bool online_whitelist_all_;
184 
185   bool is_complete_;
186 
187   // when this cache was last updated
188   base::Time update_time_;
189 
190   int64 cache_size_;
191 
192   typedef std::map<int64, AppCacheExecutableHandler*> HandlerMap;
193   HandlerMap executable_handlers_;
194 
195   // to notify storage when cache is deleted
196   AppCacheStorage* storage_;
197 
198   FRIEND_TEST_ALL_PREFIXES(AppCacheTest, InitializeWithManifest);
199   FRIEND_TEST_ALL_PREFIXES(AppCacheTest, ToFromDatabaseRecords);
200   DISALLOW_COPY_AND_ASSIGN(AppCache);
201 };
202 
203 }  // namespace appcache
204 
205 #endif  // WEBKIT_BROWSER_APPCACHE_APPCACHE_H_
206