1// Copyright 2013 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 COMPONENTS_PRECACHE_CORE_PRECACHE_FETCHER_H_
6#define COMPONENTS_PRECACHE_CORE_PRECACHE_FETCHER_H_
7
8#include <list>
9
10#include "base/basictypes.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "url/gurl.h"
14
15namespace net {
16class URLFetcher;
17class URLRequestContextGetter;
18}
19
20namespace precache {
21
22// Public interface to code that fetches resources that the user is likely to
23// want to fetch in the future, putting them in the network stack disk cache.
24// Precaching is intended to be done when Chrome is not actively in use, likely
25// hours ahead of the time when the resources are actually needed.
26//
27// This class takes as input a prioritized list of page URLs that the user
28// commonly visits, referred to as starting URLs. This class interacts with a
29// server, sending it the list of starting URLs sequentially. For each starting
30// URL, the server returns a manifest of resource URLs that are good candidates
31// for precaching. Every resource returned is fetched, and responses are cached
32// as they are received. Destroying the PrecacheFetcher while it is precaching
33// will cancel any fetch in progress and cancel precaching.
34//
35// The URLs of the server-side component must be specified in order for the
36// PrecacheFetcher to work. This includes the URL that the precache
37// configuration settings are fetched from and the prefix of URLs where precache
38// manifests are fetched from. These can be set by using command line switches
39// or by providing default values.
40//
41// Sample interaction:
42//
43// class MyPrecacheFetcherDelegate : public PrecacheFetcher::PrecacheDelegate {
44//  public:
45//   void PrecacheResourcesForTopURLs(
46//       net::URLRequestContextGetter* request_context,
47//       const std::list<GURL>& top_urls) {
48//     fetcher_.reset(new PrecacheFetcher(request_context, top_urls, this));
49//     fetcher_->Start();
50//   }
51//
52//   virtual void OnDone() {
53//     // Do something when precaching is done.
54//   }
55//
56//  private:
57//   scoped_ptr<PrecacheFetcher> fetcher_;
58// };
59class PrecacheFetcher {
60 public:
61  class PrecacheDelegate {
62   public:
63    // Called when the fetching of resources has finished, whether the resources
64    // were fetched or not. If the PrecacheFetcher is destroyed before OnDone is
65    // called, then precaching will be canceled and OnDone will not be called.
66    virtual void OnDone() = 0;
67  };
68
69  // Constructs a new PrecacheFetcher. The |starting_urls| parameter is a
70  // prioritized list of page URLs that the user commonly visits. These URLs are
71  // used by a server side component to construct a list of resource URLs that
72  // the user is likely to fetch.
73  PrecacheFetcher(const std::list<GURL>& starting_urls,
74                  net::URLRequestContextGetter* request_context,
75                  PrecacheDelegate* precache_delegate);
76
77  virtual ~PrecacheFetcher();
78
79  // Starts fetching resources to precache. URLs are fetched sequentially. Can
80  // be called from any thread. Start should only be called once on a
81  // PrecacheFetcher instance.
82  void Start();
83
84 private:
85  class Fetcher;
86
87  // Fetches the next resource or manifest URL, if any remain. Fetching is done
88  // sequentially and depth-first: all resources are fetched for a manifest
89  // before the next manifest is fetched. This is done to limit the length of
90  // the |resource_urls_to_fetch_| list, reducing the memory usage.
91  void StartNextFetch();
92
93  // Called when the precache configuration settings have been fetched.
94  // Determines the list of manifest URLs to fetch according to the list of
95  // |starting_urls_| and information from the precache configuration settings.
96  // If the fetch of the configuration settings fails, then precaching ends.
97  void OnConfigFetchComplete(const net::URLFetcher& source);
98
99  // Called when a precache manifest has been fetched. Builds the list of
100  // resource URLs to fetch according to the URLs in the manifest. If the fetch
101  // of a manifest fails, then it skips to the next manifest.
102  void OnManifestFetchComplete(const net::URLFetcher& source);
103
104  // Called when a resource has been fetched.
105  void OnResourceFetchComplete(const net::URLFetcher& source);
106
107  // The prioritized list of starting URLs that the server will pick resource
108  // URLs to be precached for.
109  const std::list<GURL> starting_urls_;
110
111  // The request context used when fetching URLs.
112  scoped_refptr<net::URLRequestContextGetter> request_context_;
113
114  // Non-owning pointer. Should not be NULL.
115  PrecacheDelegate* precache_delegate_;
116
117  scoped_ptr<Fetcher> fetcher_;
118
119  std::list<GURL> manifest_urls_to_fetch_;
120  std::list<GURL> resource_urls_to_fetch_;
121
122  DISALLOW_COPY_AND_ASSIGN(PrecacheFetcher);
123};
124
125}  // namespace precache
126
127#endif  // COMPONENTS_PRECACHE_CORE_PRECACHE_FETCHER_H_
128