15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef WEBKIT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define WEBKIT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_host.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_response.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_storage.h"
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "webkit/browser/webkit_storage_browser_export.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/common/appcache/appcache_interfaces.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace appcache {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HostNotifier;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Application cache Update algorithm and state.
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheUpdateJob
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public AppCacheStorage::Delegate,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public AppCacheHost::Observer {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheUpdateJob(AppCacheService* service, AppCacheGroup* group);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AppCacheUpdateJob();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Triggers the update process or adds more info if this update is already
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in progress.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartUpdate(AppCacheHost* host, const GURL& new_master_resource);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class AppCacheUpdateJobTest;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class URLFetcher;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Master entries have multiple hosts, for example, the same page is opened
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in different tabs.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<AppCacheHost*> PendingHosts;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<GURL, PendingHosts> PendingMasters;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<GURL, URLFetcher*> PendingUrlFetches;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<int64, GURL> LoadingResponses;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kRerunDelayMs = 1000;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): Rework the set of states vs update types vs stored states.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NO_UPDATE state is really more of an update type. For all update types
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // storing the results is relevant.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum UpdateType {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNKNOWN_TYPE,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UPGRADE_ATTEMPT,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CACHE_ATTEMPT,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum InternalUpdateState {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FETCH_MANIFEST,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NO_UPDATE,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DOWNLOADING,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Every state after this comment indicates the update is terminating.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    REFETCH_MANIFEST,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CACHE_FAILURE,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CANCELLED,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    COMPLETED,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum StoredState {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNSTORED,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STORING,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STORED,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct UrlToFetch {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UrlToFetch(const GURL& url, bool checked, AppCacheResponseInfo* info);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~UrlToFetch();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool storage_checked;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<AppCacheResponseInfo> existing_response_info;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class URLFetcher : public net::URLRequest::Delegate {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum FetchType {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MANIFEST_FETCH,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URL_FETCH,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MASTER_ENTRY_FETCH,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MANIFEST_REFETCH,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLFetcher(const GURL& url,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               FetchType fetch_type,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               AppCacheUpdateJob* job);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~URLFetcher();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Start();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FetchType fetch_type() const { return fetch_type_; }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequest* request() const { return request_.get(); }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AppCacheEntry& existing_entry() const { return existing_entry_; }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& manifest_data() const { return manifest_data_; }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheResponseWriter* response_writer() const {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return response_writer_.get();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void set_existing_response_headers(net::HttpResponseHeaders* headers) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      existing_response_headers_ = headers;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void set_existing_entry(const AppCacheEntry& entry) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      existing_entry_ = entry;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // URLRequest::Delegate overrides
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnReceivedRedirect(net::URLRequest* request,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const GURL& new_url,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool* defer_redirect) OVERRIDE;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnReadCompleted(net::URLRequest* request,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 int bytes_read) OVERRIDE;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void AddConditionalHeaders(const net::HttpResponseHeaders* headers);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void OnWriteComplete(int result);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void ReadResponseData();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool ConsumeResponseData(int bytes_read);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void OnResponseCompleted();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool MaybeRetryRequest();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url_;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheUpdateJob* job_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FetchType fetch_type_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retry_503_attempts_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::IOBuffer> buffer_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<net::URLRequest> request_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheEntry existing_entry_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> existing_response_headers_;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string manifest_data_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<AppCacheResponseWriter> response_writer_;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };  // class URLFetcher
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheResponseWriter* CreateResponseWriter();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Methods for AppCacheStorage::Delegate.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int64 response_id) OVERRIDE;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnGroupAndNewestCacheStored(AppCacheGroup* group,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           AppCache* newest_cache,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           bool success,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           bool would_exceed_quota) OVERRIDE;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnGroupMadeObsolete(AppCacheGroup* group, bool success) OVERRIDE;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Methods for AppCacheHost::Observer.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnCacheSelectionComplete(AppCacheHost* host) OVERRIDE {}  // N/A
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnDestructionImminent(AppCacheHost* host) OVERRIDE;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleCacheFailure(const std::string& error_message);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FetchManifest(bool is_first_fetch);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleManifestFetchCompleted(URLFetcher* fetcher);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ContinueHandleManifestFetchCompleted(bool changed);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleUrlFetchCompleted(URLFetcher* fetcher);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleMasterEntryFetchCompleted(URLFetcher* fetcher);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleManifestRefetchCompleted(URLFetcher* fetcher);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnManifestInfoWriteComplete(int result);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnManifestDataWriteComplete(int result);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StoreGroupAndCache();
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifySingleHost(AppCacheHost* host, EventID event_id);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyAllAssociatedHosts(EventID event_id);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyAllProgress(const GURL& url);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyAllFinalProgress();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyAllError(const std::string& error_message);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddAllAssociatedHostsToNotifier(HostNotifier* notifier);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks if manifest is byte for byte identical with the manifest
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the newest application cache.
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckIfManifestChanged();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnManifestDataReadComplete(int result);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates the list of files that may need to be fetched and initiates
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetches. Section 6.9.4 steps 12-17
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BuildUrlFileList(const Manifest& manifest);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddUrlToFileList(const GURL& url, int type);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FetchUrls();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelAllUrlFetches();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ShouldSkipUrlFetch(const AppCacheEntry& entry);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If entry already exists in the cache currently being updated, merge
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the entry type information with the existing entry.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if entry exists in cache currently being updated.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool AlreadyFetchedEntry(const GURL& url, int entry_type);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(jennb): Delete when update no longer fetches master entries directly.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates the list of master entries that need to be fetched and initiates
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetches.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddMasterEntryToFetchList(AppCacheHost* host, const GURL& url,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 bool is_new);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FetchMasterEntries();
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelAllMasterEntryFetches(const std::string& error_message);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Asynchronously loads the entry from the newest complete cache if the
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP caching semantics allow.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns false if immediately obvious that data cannot be loaded from
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // newest complete cache.
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool MaybeLoadFromNewestCache(const GURL& url, AppCacheEntry& entry);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LoadFromNewestCacheFailed(const GURL& url,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 AppCacheResponseInfo* newest_response_info);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Does nothing if update process is still waiting for pending master
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entries or URL fetches to complete downloading. Otherwise, completes
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the update process.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MaybeCompleteUpdate();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Schedules a rerun of the entire update with the same parameters as
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this update job after a short delay.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScheduleUpdateRetry(int delay_ms);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Cancel();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearPendingMasterEntries();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DiscardInprogressCache();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DiscardDuplicateResponses();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deletes this object after letting the stack unwind.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeleteSoon();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsTerminating() { return internal_state_ >= REFETCH_MANIFEST ||
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                stored_state_ != UNSTORED; }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheService* service_;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL manifest_url_;  // here for easier access
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AppCache> inprogress_cache_;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheGroup* group_;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateType update_type_;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InternalUpdateState internal_state_;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingMasters pending_master_entries_;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t master_entries_completed_;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(jennb): Delete when update no longer fetches master entries directly.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper containers to track which pending master entries have yet to be
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetched and which are currently being fetched. Master entries that
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are listed in the manifest may be fetched as a regular URL instead of
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as a separate master entry fetch to optimize against duplicate fetches.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<GURL> master_entries_to_fetch_;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingUrlFetches master_entry_fetches_;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URLs of files to fetch along with their flags.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCache::EntryMap url_file_list_;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t url_fetches_completed_;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper container to track which urls have not been fetched yet. URLs are
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // removed when the fetch is initiated. Flag indicates whether an attempt
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to load the URL from storage has already been tried and failed.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::deque<UrlToFetch> urls_to_fetch_;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper container to track which urls are being loaded from response
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // storage.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadingResponses loading_responses_;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keep track of pending URL requests so we can cancel them if necessary.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLFetcher* manifest_fetcher_;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingUrlFetches pending_url_fetches_;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Temporary storage of manifest response data for parsing and comparison.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string manifest_data_;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::HttpResponseInfo> manifest_response_info_;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AppCacheResponseWriter> manifest_response_writer_;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBuffer> read_manifest_buffer_;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string loaded_manifest_data_;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AppCacheResponseReader> manifest_response_reader_;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // New master entries added to the cache by this job, used to cleanup
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in error conditions.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> added_master_entries_;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Response ids stored by this update job, used to cleanup in
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // error conditions.
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int64> stored_response_ids_;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In some cases we fetch the same resource multiple times, and then
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have to delete the duplicates upon successful update. These ids
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are also in the stored_response_ids_ collection so we only schedule
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // these for deletion on success.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): Rework when we no longer fetches master entries directly.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int64> duplicate_response_ids_;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether we've stored the resulting group/cache yet.
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StoredState stored_state_;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(AppCacheGroupTest, QueueUpdate);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AppCacheUpdateJob);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace appcache
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif  // WEBKIT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
311