diff options
author | jennb@chromium.org <jennb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-06 17:19:37 +0000 |
---|---|---|
committer | jennb@chromium.org <jennb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-06 17:19:37 +0000 |
commit | ae3c0b266d4a3f7f2f121589e24e76528d44f4f7 (patch) | |
tree | 85af04a19120db4a75b1ad07ca2a6e1473f1767e /webkit/appcache/appcache_update_job.h | |
parent | ff9cfce7ec2ae06df4ac413cfde3bfd7ae503677 (diff) | |
download | chromium_src-ae3c0b266d4a3f7f2f121589e24e76528d44f4f7.zip chromium_src-ae3c0b266d4a3f7f2f121589e24e76528d44f4f7.tar.gz chromium_src-ae3c0b266d4a3f7f2f121589e24e76528d44f4f7.tar.bz2 |
Implementation of application cache update algorithm.
Does not include storage nor processing of pending master entries.
TEST=verify update functionality
BUG=none
Review URL: http://codereview.chromium.org/201070
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28123 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/appcache/appcache_update_job.h')
-rw-r--r-- | webkit/appcache/appcache_update_job.h | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/webkit/appcache/appcache_update_job.h b/webkit/appcache/appcache_update_job.h new file mode 100644 index 0000000..160e27e --- /dev/null +++ b/webkit/appcache/appcache_update_job.h @@ -0,0 +1,184 @@ +// Copyright (c) 2009 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 WEBKIT_APPCACHE_APPCACHE_UPDATE_JOB_H_ +#define WEBKIT_APPCACHE_APPCACHE_UPDATE_JOB_H_ + +#include <deque> +#include <map> + +#include "base/ref_counted.h" +#include "base/task.h" +#include "googleurl/src/gurl.h" +#include "net/url_request/url_request.h" +#include "webkit/appcache/appcache.h" +#include "webkit/appcache/appcache_interfaces.h" + +namespace appcache { + +struct UpdateJobInfo; + +// Application cache Update algorithm and state. +class AppCacheUpdateJob : public URLRequest::Delegate { + public: + AppCacheUpdateJob(AppCacheService* service, AppCacheGroup* group); + ~AppCacheUpdateJob(); + + // Triggers the update process or adds more info if this update is already + // in progress. + void StartUpdate(AppCacheHost* host, const GURL& new_master_resource); + + + // TODO(jennb): add callback method for writing data to storage + // TODO(jennb): add callback method for reading data from storage + + private: + friend class ScopedRunnableMethodFactory<AppCacheUpdateJob>; + friend class AppCacheUpdateJobTest; + + // Master entries have multiple hosts, for example, the same page is opened + // in different tabs. + // TODO(jennb): detect when hosts are deleted + typedef std::vector<AppCacheHost*> PendingHosts; + typedef std::map<GURL, PendingHosts> PendingMasters; + typedef std::map<GURL, URLRequest*> PendingUrlFetches; + typedef std::pair<GURL, bool> UrlToFetch; // flag TRUE if storage checked + + static const int kRerunDelayMs = 1000; + + enum UpdateType { + UNKNOWN_TYPE, + UPGRADE_ATTEMPT, + CACHE_ATTEMPT, + }; + + enum InternalUpdateState { + FETCH_MANIFEST, + NO_UPDATE, + DOWNLOADING, + REFETCH_MANIFEST, + CACHE_FAILURE, + CANCELLED, + }; + + // Methods for URLRequest::Delegate. + void OnResponseStarted(URLRequest* request); + void OnReadCompleted(URLRequest* request, int bytes_read); + void OnReceivedRedirect(URLRequest* request, + const GURL& new_url, + bool* defer_redirect); + // TODO(jennb): any other delegate callbacks to handle? certificate? + + void FetchManifest(bool is_first_fetch); + + void OnResponseCompleted(URLRequest* request); + + void ReadResponseData(URLRequest* request); + + // Returns false if response data is processed asynchronously, in which + // case a callback will be invoked when it is safe to continue reading + // more response data from the request. + bool ConsumeResponseData(URLRequest* request, + UpdateJobInfo* info, + int bytes_read); + + void HandleManifestFetchCompleted(URLRequest* request); + void ContinueHandleManifestFetchCompleted(bool changed); + void HandleUrlFetchCompleted(URLRequest* request); + void HandleManifestRefetchCompleted(URLRequest* request); + + void NotifySingleHost(AppCacheHost* host, EventID event_id); + void NotifyAllPendingMasterHosts(EventID event_id); + void NotifyAllAssociatedHosts(EventID event_id); + + // Checks if manifest is byte for byte identical with the manifest + // in the newest application cache. + void CheckIfManifestChanged(); + void ContinueCheckIfManifestChanged(const std::string& loaded_manifest); + + // TODO(jennb): delete when able to mock storage behavior + void SimulateManifestChanged(bool changed) { + simulate_manifest_changed_ = changed; + } + + // Creates the list of files that may need to be fetched and initiates + // fetches. Section 6.9.4 steps 12-17 + void BuildUrlFileList(const Manifest& manifest); + void AddUrlToFileList(const GURL& url, int type); + void FetchUrls(); + bool ShouldSkipUrlFetch(const AppCacheEntry& entry); + + // Asynchronously loads the entry from the newest complete cache if the + // HTTP caching semantics allow. + // Returns false if immediately obvious that data cannot be loaded from + // newest complete cache. + bool MaybeLoadFromNewestCache(const GURL& url, AppCacheEntry& entry); + + // TODO(jennb): delete me after storage code added + void SimulateFailedLoadFromNewestCache(const GURL& url); + + // Copies the data from src entry to dest entry and adds the modified + // entry to the inprogress cache. + void CopyEntryToCache(const GURL& url, const AppCacheEntry& src, + AppCacheEntry* dest); + + // Does nothing if update process is still waiting for pending master + // entries or URL fetches to complete downloading. Otherwise, completes + // the update process. + // Returns true if update process is completed. + bool MaybeCompleteUpdate(); + + // Runs the cache failure steps after all pending master entry downloads + // have completed. + void HandleCacheFailure(); + + // Schedules a rerun of the entire update with the same parameters as + // this update job after a short delay. + void ScheduleUpdateRetry(int delay_ms); + + void Cancel(); + + // Deletes this object after letting the stack unwind. + void DeleteSoon(); + + // This factory will be used to schedule invocations of various methods. + ScopedRunnableMethodFactory<AppCacheUpdateJob> method_factory_; + + GURL manifest_url_; // here for easier access + AppCacheService* service_; + scoped_refptr<AppCache> inprogress_cache_; + scoped_refptr<AppCacheGroup> group_; + + UpdateType update_type_; + InternalUpdateState internal_state_; + + PendingMasters pending_master_entries_; + size_t master_entries_completed_; + + // URLs of files to fetch along with their flags. + AppCache::EntryMap url_file_list_; + size_t url_fetches_completed_; + + // Helper container to track which urls have not been fetched yet. URLs are + // removed when the fetch is initiated. Flag indicates whether an attempt + // to load the URL from storage has already been tried and failed. + std::deque<UrlToFetch> urls_to_fetch_; + + // Keep track of pending URL requests so we can cancel them if necessary. + URLRequest* manifest_url_request_; + PendingUrlFetches pending_url_fetches_; + + // Temporary storage of manifest response data for parsing and comparison. + std::string manifest_data_; + std::string manifest_refetch_data_; + + // TODO(jennb): delete when able to mock storage behavior + bool simulate_manifest_changed_; + + DISALLOW_COPY_AND_ASSIGN(AppCacheUpdateJob); +}; + +} // namespace appcache + +#endif // WEBKIT_APPCACHE_APPCACHE_UPDATE_JOB_H_ |