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