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