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.
5 #ifndef COMPONENTS_PRECACHE_CORE_PRECACHE_FETCHER_H_
6 #define COMPONENTS_PRECACHE_CORE_PRECACHE_FETCHER_H_
12 #include "base/basictypes.h"
13 #include "base/callback.h"
14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/time/time.h"
18 #include "net/url_request/url_fetcher.h"
19 #include "net/url_request/url_fetcher_delegate.h"
23 class URLRequestContextGetter
;
28 // Visible for testing.
29 extern const int kNoTracking
;
31 // Public interface to code that fetches resources that the user is likely to
32 // want to fetch in the future, putting them in the network stack disk cache.
33 // Precaching is intended to be done when Chrome is not actively in use, likely
34 // hours ahead of the time when the resources are actually needed.
36 // This class takes as input a prioritized list of URL domains that the user
37 // commonly visits, referred to as starting hosts. This class interacts with a
38 // server, sending it the list of starting hosts sequentially. For each starting
39 // host, the server returns a manifest of resource URLs that are good candidates
40 // for precaching. Every resource returned is fetched, and responses are cached
41 // as they are received. Destroying the PrecacheFetcher while it is precaching
42 // will cancel any fetch in progress and cancel precaching.
44 // The URLs of the server-side component must be specified in order for the
45 // PrecacheFetcher to work. This includes the URL that the precache
46 // configuration settings are fetched from and the prefix of URLs where precache
47 // manifests are fetched from. These can be set by using command line switches
48 // or by providing default values.
50 // Sample interaction:
52 // class MyPrecacheFetcherDelegate : public PrecacheFetcher::PrecacheDelegate {
54 // void PrecacheResourcesForTopURLs(
55 // net::URLRequestContextGetter* request_context,
56 // const std::list<GURL>& top_urls) {
57 // fetcher_.reset(new PrecacheFetcher(request_context, top_urls, this));
61 // virtual void OnDone() {
62 // // Do something when precaching is done.
66 // scoped_ptr<PrecacheFetcher> fetcher_;
68 class PrecacheFetcher
{
70 class PrecacheDelegate
{
72 // Called when the fetching of resources has finished, whether the resources
73 // were fetched or not. If the PrecacheFetcher is destroyed before OnDone is
74 // called, then precaching will be canceled and OnDone will not be called.
75 virtual void OnDone() = 0;
78 // Visible for testing.
81 // Constructs a new PrecacheFetcher. The |starting_hosts| parameter is a
82 // prioritized list of hosts that the user commonly visits. These hosts are
83 // used by a server side component to construct a list of resource URLs that
84 // the user is likely to fetch.
85 PrecacheFetcher(const std::vector
<std::string
>& starting_hosts
,
86 net::URLRequestContextGetter
* request_context
,
87 const GURL
& config_url
,
88 const std::string
& manifest_url_prefix
,
89 PrecacheDelegate
* precache_delegate
);
91 virtual ~PrecacheFetcher();
93 // Starts fetching resources to precache. URLs are fetched sequentially. Can
94 // be called from any thread. Start should only be called once on a
95 // PrecacheFetcher instance.
99 // Fetches the next resource or manifest URL, if any remain. Fetching is done
100 // sequentially and depth-first: all resources are fetched for a manifest
101 // before the next manifest is fetched. This is done to limit the length of
102 // the |resource_urls_to_fetch_| list, reducing the memory usage.
103 void StartNextFetch();
105 // Called when the precache configuration settings have been fetched.
106 // Determines the list of manifest URLs to fetch according to the list of
107 // |starting_hosts_| and information from the precache configuration settings.
108 // If the fetch of the configuration settings fails, then precaching ends.
109 void OnConfigFetchComplete(const net::URLFetcher
& source
);
111 // Called when a precache manifest has been fetched. Builds the list of
112 // resource URLs to fetch according to the URLs in the manifest. If the fetch
113 // of a manifest fails, then it skips to the next manifest.
114 void OnManifestFetchComplete(const net::URLFetcher
& source
);
116 // Called when a resource has been fetched.
117 void OnResourceFetchComplete(const net::URLFetcher
& source
);
119 // The prioritized list of starting hosts that the server will pick resource
120 // URLs to be precached for.
121 const std::vector
<std::string
> starting_hosts_
;
123 // The request context used when fetching URLs.
124 const scoped_refptr
<net::URLRequestContextGetter
> request_context_
;
126 // The custom URL to use when fetching the config. If not provided, the
127 // default flag-specified URL will be used.
128 const GURL config_url_
;
130 // The custom URL prefix to use when fetching manifests. If not provided, the
131 // default flag-specified prefix will be used.
132 const std::string manifest_url_prefix_
;
134 // Non-owning pointer. Should not be NULL.
135 PrecacheDelegate
* precache_delegate_
;
137 // Tally of the total number of bytes contained in URL fetches, including
138 // config, manifests, and resources. This the number of bytes as they would be
139 // compressed over the network.
140 int total_response_bytes_
;
142 // Tally of the total number of bytes received over the network from URL
143 // fetches (the same ones as in total_response_bytes_). This includes response
144 // headers and intermediate responses such as 30xs.
145 int network_response_bytes_
;
147 scoped_ptr
<Fetcher
> fetcher_
;
149 // Time when the prefetch was started.
150 base::TimeTicks start_time_
;
152 int num_manifest_urls_to_fetch_
;
153 std::list
<GURL
> manifest_urls_to_fetch_
;
154 std::list
<GURL
> resource_urls_to_fetch_
;
156 DISALLOW_COPY_AND_ASSIGN(PrecacheFetcher
);
159 // Class that fetches a URL, and runs the specified callback when the fetch is
160 // complete. This class exists so that a different method can be run in
161 // response to different kinds of fetches, e.g. OnConfigFetchComplete when
162 // configuration settings are fetched, OnManifestFetchComplete when a manifest
164 class PrecacheFetcher::Fetcher
: public net::URLFetcherDelegate
{
166 // Construct a new Fetcher. This will create and start a new URLFetcher for
167 // the specified URL using the specified request context.
168 Fetcher(net::URLRequestContextGetter
* request_context
,
170 const base::Callback
<void(const net::URLFetcher
&)>& callback
,
171 bool is_resource_request
);
173 void OnURLFetchComplete(const net::URLFetcher
* source
) override
;
174 int64
response_bytes() const { return response_bytes_
; }
175 int64
network_response_bytes() const { return network_response_bytes_
; }
178 enum class FetchStage
{ CACHE
, NETWORK
};
180 void LoadFromCache();
181 void LoadFromNetwork();
183 net::URLRequestContextGetter
* const request_context_
;
185 const base::Callback
<void(const net::URLFetcher
&)> callback_
;
186 const bool is_resource_request_
;
188 FetchStage fetch_stage_
;
189 // The url_fetcher_cache_ is kept alive until Fetcher destruction for testing.
190 scoped_ptr
<net::URLFetcher
> url_fetcher_cache_
;
191 scoped_ptr
<net::URLFetcher
> url_fetcher_network_
;
192 int64 response_bytes_
;
193 int64 network_response_bytes_
;
195 DISALLOW_COPY_AND_ASSIGN(Fetcher
);
198 } // namespace precache
200 #endif // COMPONENTS_PRECACHE_CORE_PRECACHE_FETCHER_H_