Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: webkit/browser/appcache/appcache_update_job.h

Issue 344493002: Move all remaining appcache-related code to content namespace (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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_UPDATE_JOB_H_
6 #define WEBKIT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
7
8 #include <deque>
9 #include <map>
10 #include <set>
11 #include <string>
12 #include <vector>
13
14 #include "base/gtest_prod_util.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/time/time.h"
17 #include "net/base/completion_callback.h"
18 #include "net/http/http_response_headers.h"
19 #include "net/url_request/url_request.h"
20 #include "url/gurl.h"
21 #include "webkit/browser/appcache/appcache.h"
22 #include "webkit/browser/appcache/appcache_host.h"
23 #include "webkit/browser/appcache/appcache_response.h"
24 #include "webkit/browser/appcache/appcache_service_impl.h"
25 #include "webkit/browser/appcache/appcache_storage.h"
26 #include "webkit/browser/webkit_storage_browser_export.h"
27 #include "webkit/common/appcache/appcache_interfaces.h"
28
29 namespace content {
30 FORWARD_DECLARE_TEST(AppCacheGroupTest, QueueUpdate);
31 class AppCacheGroupTest;
32 class AppCacheUpdateJobTest;
33 }
34
35 namespace appcache {
36
37 class HostNotifier;
38
39 // Application cache Update algorithm and state.
40 class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheUpdateJob
41 : public AppCacheStorage::Delegate,
42 public AppCacheHost::Observer,
43 public AppCacheServiceImpl::Observer {
44 public:
45 // Used for uma stats only for now, so new values are append only.
46 enum ResultType {
47 UPDATE_OK, DB_ERROR, DISKCACHE_ERROR, APPCACHE_QUOTA_ERROR, REDIRECT_ERROR,
48 APPCACHE_MANIFEST_ERROR, NETWORK_ERROR, SERVER_ERROR, CANCELLED_ERROR,
49 NUM_UPDATE_JOB_RESULT_TYPES
50 };
51
52 AppCacheUpdateJob(AppCacheServiceImpl* service, AppCacheGroup* group);
53 virtual ~AppCacheUpdateJob();
54
55 // Triggers the update process or adds more info if this update is already
56 // in progress.
57 void StartUpdate(AppCacheHost* host, const GURL& new_master_resource);
58
59 private:
60 friend class content::AppCacheGroupTest;
61 friend class content::AppCacheUpdateJobTest;
62 class URLFetcher;
63
64 // Master entries have multiple hosts, for example, the same page is opened
65 // in different tabs.
66 typedef std::vector<AppCacheHost*> PendingHosts;
67 typedef std::map<GURL, PendingHosts> PendingMasters;
68 typedef std::map<GURL, URLFetcher*> PendingUrlFetches;
69 typedef std::map<int64, GURL> LoadingResponses;
70
71 static const int kRerunDelayMs = 1000;
72
73 // TODO(michaeln): Rework the set of states vs update types vs stored states.
74 // The NO_UPDATE state is really more of an update type. For all update types
75 // storing the results is relevant.
76
77 enum UpdateType {
78 UNKNOWN_TYPE,
79 UPGRADE_ATTEMPT,
80 CACHE_ATTEMPT,
81 };
82
83 enum InternalUpdateState {
84 FETCH_MANIFEST,
85 NO_UPDATE,
86 DOWNLOADING,
87
88 // Every state after this comment indicates the update is terminating.
89 REFETCH_MANIFEST,
90 CACHE_FAILURE,
91 CANCELLED,
92 COMPLETED,
93 };
94
95 enum StoredState {
96 UNSTORED,
97 STORING,
98 STORED,
99 };
100
101 struct UrlToFetch {
102 UrlToFetch(const GURL& url, bool checked, AppCacheResponseInfo* info);
103 ~UrlToFetch();
104
105 GURL url;
106 bool storage_checked;
107 scoped_refptr<AppCacheResponseInfo> existing_response_info;
108 };
109
110 class URLFetcher : public net::URLRequest::Delegate {
111 public:
112 enum FetchType {
113 MANIFEST_FETCH,
114 URL_FETCH,
115 MASTER_ENTRY_FETCH,
116 MANIFEST_REFETCH,
117 };
118 URLFetcher(const GURL& url,
119 FetchType fetch_type,
120 AppCacheUpdateJob* job);
121 virtual ~URLFetcher();
122 void Start();
123 FetchType fetch_type() const { return fetch_type_; }
124 net::URLRequest* request() const { return request_.get(); }
125 const AppCacheEntry& existing_entry() const { return existing_entry_; }
126 const std::string& manifest_data() const { return manifest_data_; }
127 AppCacheResponseWriter* response_writer() const {
128 return response_writer_.get();
129 }
130 void set_existing_response_headers(net::HttpResponseHeaders* headers) {
131 existing_response_headers_ = headers;
132 }
133 void set_existing_entry(const AppCacheEntry& entry) {
134 existing_entry_ = entry;
135 }
136 ResultType result() const { return result_; }
137 int redirect_response_code() const { return redirect_response_code_; }
138
139 private:
140 // URLRequest::Delegate overrides
141 virtual void OnReceivedRedirect(net::URLRequest* request,
142 const GURL& new_url,
143 bool* defer_redirect) OVERRIDE;
144 virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
145 virtual void OnReadCompleted(net::URLRequest* request,
146 int bytes_read) OVERRIDE;
147
148 void AddConditionalHeaders(const net::HttpResponseHeaders* headers);
149 void OnWriteComplete(int result);
150 void ReadResponseData();
151 bool ConsumeResponseData(int bytes_read);
152 void OnResponseCompleted();
153 bool MaybeRetryRequest();
154
155 GURL url_;
156 AppCacheUpdateJob* job_;
157 FetchType fetch_type_;
158 int retry_503_attempts_;
159 scoped_refptr<net::IOBuffer> buffer_;
160 scoped_ptr<net::URLRequest> request_;
161 AppCacheEntry existing_entry_;
162 scoped_refptr<net::HttpResponseHeaders> existing_response_headers_;
163 std::string manifest_data_;
164 ResultType result_;
165 int redirect_response_code_;
166 scoped_ptr<AppCacheResponseWriter> response_writer_;
167 }; // class URLFetcher
168
169 AppCacheResponseWriter* CreateResponseWriter();
170
171 // Methods for AppCacheStorage::Delegate.
172 virtual void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
173 int64 response_id) OVERRIDE;
174 virtual void OnGroupAndNewestCacheStored(AppCacheGroup* group,
175 AppCache* newest_cache,
176 bool success,
177 bool would_exceed_quota) OVERRIDE;
178 virtual void OnGroupMadeObsolete(AppCacheGroup* group,
179 bool success,
180 int response_code) OVERRIDE;
181
182 // Methods for AppCacheHost::Observer.
183 virtual void OnCacheSelectionComplete(AppCacheHost* host) OVERRIDE {} // N/A
184 virtual void OnDestructionImminent(AppCacheHost* host) OVERRIDE;
185
186 // Methods for AppCacheServiceImpl::Observer.
187 virtual void OnServiceReinitialized(
188 AppCacheStorageReference* old_storage) OVERRIDE;
189
190 void HandleCacheFailure(const AppCacheErrorDetails& details,
191 ResultType result,
192 const GURL& failed_resource_url);
193
194 void FetchManifest(bool is_first_fetch);
195 void HandleManifestFetchCompleted(URLFetcher* fetcher);
196 void ContinueHandleManifestFetchCompleted(bool changed);
197
198 void HandleUrlFetchCompleted(URLFetcher* fetcher);
199 void HandleMasterEntryFetchCompleted(URLFetcher* fetcher);
200
201 void HandleManifestRefetchCompleted(URLFetcher* fetcher);
202 void OnManifestInfoWriteComplete(int result);
203 void OnManifestDataWriteComplete(int result);
204
205 void StoreGroupAndCache();
206
207 void NotifySingleHost(AppCacheHost* host, AppCacheEventID event_id);
208 void NotifyAllAssociatedHosts(AppCacheEventID event_id);
209 void NotifyAllProgress(const GURL& url);
210 void NotifyAllFinalProgress();
211 void NotifyAllError(const AppCacheErrorDetails& detals);
212 void LogConsoleMessageToAll(const std::string& message);
213 void AddAllAssociatedHostsToNotifier(HostNotifier* notifier);
214
215 // Checks if manifest is byte for byte identical with the manifest
216 // in the newest application cache.
217 void CheckIfManifestChanged();
218 void OnManifestDataReadComplete(int result);
219
220 // Creates the list of files that may need to be fetched and initiates
221 // fetches. Section 6.9.4 steps 12-17
222 void BuildUrlFileList(const Manifest& manifest);
223 void AddUrlToFileList(const GURL& url, int type);
224 void FetchUrls();
225 void CancelAllUrlFetches();
226 bool ShouldSkipUrlFetch(const AppCacheEntry& entry);
227
228 // If entry already exists in the cache currently being updated, merge
229 // the entry type information with the existing entry.
230 // Returns true if entry exists in cache currently being updated.
231 bool AlreadyFetchedEntry(const GURL& url, int entry_type);
232
233 // TODO(jennb): Delete when update no longer fetches master entries directly.
234 // Creates the list of master entries that need to be fetched and initiates
235 // fetches.
236 void AddMasterEntryToFetchList(AppCacheHost* host, const GURL& url,
237 bool is_new);
238 void FetchMasterEntries();
239 void CancelAllMasterEntryFetches(const AppCacheErrorDetails& details);
240
241 // Asynchronously loads the entry from the newest complete cache if the
242 // HTTP caching semantics allow.
243 // Returns false if immediately obvious that data cannot be loaded from
244 // newest complete cache.
245 bool MaybeLoadFromNewestCache(const GURL& url, AppCacheEntry& entry);
246 void LoadFromNewestCacheFailed(const GURL& url,
247 AppCacheResponseInfo* newest_response_info);
248
249 // Does nothing if update process is still waiting for pending master
250 // entries or URL fetches to complete downloading. Otherwise, completes
251 // the update process.
252 void MaybeCompleteUpdate();
253
254 // Schedules a rerun of the entire update with the same parameters as
255 // this update job after a short delay.
256 void ScheduleUpdateRetry(int delay_ms);
257
258 void Cancel();
259 void ClearPendingMasterEntries();
260 void DiscardInprogressCache();
261 void DiscardDuplicateResponses();
262
263 void LogHistogramStats(ResultType result, const GURL& failed_resource_url);
264 void MadeProgress() { last_progress_time_ = base::Time::Now(); }
265
266 // Deletes this object after letting the stack unwind.
267 void DeleteSoon();
268
269 bool IsTerminating() { return internal_state_ >= REFETCH_MANIFEST ||
270 stored_state_ != UNSTORED; }
271
272 AppCacheServiceImpl* service_;
273 const GURL manifest_url_; // here for easier access
274
275 // Defined prior to refs to AppCaches and Groups because destruction
276 // order matters, the disabled_storage_reference_ must outlive those
277 // objects.
278 scoped_refptr<AppCacheStorageReference> disabled_storage_reference_;
279
280 scoped_refptr<AppCache> inprogress_cache_;
281
282 AppCacheGroup* group_;
283
284 UpdateType update_type_;
285 InternalUpdateState internal_state_;
286 base::Time last_progress_time_;
287
288 PendingMasters pending_master_entries_;
289 size_t master_entries_completed_;
290
291 // TODO(jennb): Delete when update no longer fetches master entries directly.
292 // Helper containers to track which pending master entries have yet to be
293 // fetched and which are currently being fetched. Master entries that
294 // are listed in the manifest may be fetched as a regular URL instead of
295 // as a separate master entry fetch to optimize against duplicate fetches.
296 std::set<GURL> master_entries_to_fetch_;
297 PendingUrlFetches master_entry_fetches_;
298
299 // URLs of files to fetch along with their flags.
300 AppCache::EntryMap url_file_list_;
301 size_t url_fetches_completed_;
302
303 // Helper container to track which urls have not been fetched yet. URLs are
304 // removed when the fetch is initiated. Flag indicates whether an attempt
305 // to load the URL from storage has already been tried and failed.
306 std::deque<UrlToFetch> urls_to_fetch_;
307
308 // Helper container to track which urls are being loaded from response
309 // storage.
310 LoadingResponses loading_responses_;
311
312 // Keep track of pending URL requests so we can cancel them if necessary.
313 URLFetcher* manifest_fetcher_;
314 PendingUrlFetches pending_url_fetches_;
315
316 // Temporary storage of manifest response data for parsing and comparison.
317 std::string manifest_data_;
318 scoped_ptr<net::HttpResponseInfo> manifest_response_info_;
319 scoped_ptr<AppCacheResponseWriter> manifest_response_writer_;
320 scoped_refptr<net::IOBuffer> read_manifest_buffer_;
321 std::string loaded_manifest_data_;
322 scoped_ptr<AppCacheResponseReader> manifest_response_reader_;
323 bool manifest_has_valid_mime_type_;
324
325 // New master entries added to the cache by this job, used to cleanup
326 // in error conditions.
327 std::vector<GURL> added_master_entries_;
328
329 // Response ids stored by this update job, used to cleanup in
330 // error conditions.
331 std::vector<int64> stored_response_ids_;
332
333 // In some cases we fetch the same resource multiple times, and then
334 // have to delete the duplicates upon successful update. These ids
335 // are also in the stored_response_ids_ collection so we only schedule
336 // these for deletion on success.
337 // TODO(michaeln): Rework when we no longer fetches master entries directly.
338 std::vector<int64> duplicate_response_ids_;
339
340 // Whether we've stored the resulting group/cache yet.
341 StoredState stored_state_;
342
343 AppCacheStorage* storage_;
344
345 FRIEND_TEST_ALL_PREFIXES(content::AppCacheGroupTest, QueueUpdate);
346
347 DISALLOW_COPY_AND_ASSIGN(AppCacheUpdateJob);
348 };
349
350 } // namespace appcache
351
352 #endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698