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_
|