1 // Copyright 2014 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 CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCHER_H_
6 #define CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCHER_H_
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/threading/thread_checker.h"
16 #include "chrome/browser/predictors/resource_prefetch_common.h"
17 #include "net/url_request/redirect_info.h"
18 #include "net/url_request/url_request.h"
22 class URLRequestContext
;
25 namespace predictors
{
27 // Responsible for prefetching resources for a single navigation based on the
28 // input list of resources.
29 // - Limits the max number of resources in flight for any host and also across
31 // - When stopped, will wait for the pending requests to finish.
32 // - Lives entirely on the IO thread.
33 class ResourcePrefetcher
: public net::URLRequest::Delegate
{
35 // Denotes the prefetch request for a single subresource.
37 explicit Request(const GURL
& i_resource_url
);
38 Request(const Request
& other
);
41 PREFETCH_STATUS_NOT_STARTED
,
42 PREFETCH_STATUS_STARTED
,
44 // Cancellation reasons.
45 PREFETCH_STATUS_REDIRECTED
,
46 PREFETCH_STATUS_AUTH_REQUIRED
,
47 PREFETCH_STATUS_CERT_REQUIRED
,
48 PREFETCH_STATUS_CERT_ERROR
,
49 PREFETCH_STATUS_CANCELLED
,
50 PREFETCH_STATUS_FAILED
,
52 // Successful prefetch states.
53 PREFETCH_STATUS_FROM_CACHE
,
54 PREFETCH_STATUS_FROM_NETWORK
58 USAGE_STATUS_NOT_REQUESTED
,
59 USAGE_STATUS_FROM_CACHE
,
60 USAGE_STATUS_FROM_NETWORK
,
61 USAGE_STATUS_NAVIGATION_ABANDONED
65 PrefetchStatus prefetch_status
;
66 UsageStatus usage_status
;
68 typedef ScopedVector
<Request
> RequestVector
;
70 // Used to communicate when the prefetching is done. All methods are invoked
74 virtual ~Delegate() { }
76 // Called when the ResourcePrefetcher is finished, i.e. there is nothing
77 // pending in flight. Should take ownership of |requests|.
78 virtual void ResourcePrefetcherFinished(
79 ResourcePrefetcher
* prefetcher
,
80 RequestVector
* requests
) = 0;
82 virtual net::URLRequestContext
* GetURLRequestContext() = 0;
85 // |delegate| has to outlive the ResourcePrefetcher. The ResourcePrefetcher
86 // takes ownership of |requests|.
87 ResourcePrefetcher(Delegate
* delegate
,
88 const ResourcePrefetchPredictorConfig
& config
,
89 const NavigationID
& navigation_id
,
90 PrefetchKeyType key_type
,
91 scoped_ptr
<RequestVector
> requests
);
92 ~ResourcePrefetcher() override
;
94 void Start(); // Kicks off the prefetching. Can only be called once.
95 void Stop(); // No additional prefetches will be queued after this.
97 const NavigationID
& navigation_id() const { return navigation_id_
; }
98 PrefetchKeyType
key_type() const { return key_type_
; }
101 friend class ResourcePrefetcherTest
;
102 friend class TestResourcePrefetcher
;
104 // Launches new prefetch requests if possible.
105 void TryToLaunchPrefetchRequests();
107 // Starts a net::URLRequest for the input |request|.
108 void SendRequest(Request
* request
);
110 // Called by |SendRequest| to start the |request|. This is necessary to stub
111 // out the Start() call to net::URLRequest for unittesting.
112 virtual void StartURLRequest(net::URLRequest
* request
);
114 // Marks the request as finished, with the given status.
115 void FinishRequest(net::URLRequest
* request
, Request::PrefetchStatus status
);
117 // Reads the response data from the response - required for the resource to
118 // be cached correctly. Stubbed out during testing.
119 virtual void ReadFullResponse(net::URLRequest
* request
);
121 // Returns true if the request has more data that needs to be read. If it
122 // returns false, the request should not be referenced again.
123 bool ShouldContinueReadingRequest(net::URLRequest
* request
, int bytes_read
);
125 // net::URLRequest::Delegate methods.
126 void OnReceivedRedirect(net::URLRequest
* request
,
127 const net::RedirectInfo
& redirect_info
,
128 bool* defer_redirect
) override
;
129 void OnAuthRequired(net::URLRequest
* request
,
130 net::AuthChallengeInfo
* auth_info
) override
;
131 void OnCertificateRequested(
132 net::URLRequest
* request
,
133 net::SSLCertRequestInfo
* cert_request_info
) override
;
134 void OnSSLCertificateError(net::URLRequest
* request
,
135 const net::SSLInfo
& ssl_info
,
136 bool fatal
) override
;
137 void OnResponseStarted(net::URLRequest
* request
) override
;
138 void OnReadCompleted(net::URLRequest
* request
, int bytes_read
) override
;
140 enum PrefetcherState
{
141 INITIALIZED
= 0, // Prefetching hasn't started.
142 RUNNING
= 1, // Prefetching started, allowed to add more requests.
143 STOPPED
= 2, // Prefetching started, not allowed to add more requests.
144 FINISHED
= 3 // No more inflight request, new requests not possible.
147 base::ThreadChecker thread_checker_
;
148 PrefetcherState state_
;
149 Delegate
* const delegate_
;
150 ResourcePrefetchPredictorConfig
const config_
;
151 NavigationID navigation_id_
;
152 PrefetchKeyType key_type_
;
153 scoped_ptr
<RequestVector
> request_vector_
;
155 std::map
<net::URLRequest
*, Request
*> inflight_requests_
;
156 std::list
<Request
*> request_queue_
;
157 std::map
<std::string
, size_t> host_inflight_counts_
;
159 DISALLOW_COPY_AND_ASSIGN(ResourcePrefetcher
);
162 } // namespace predictors
164 #endif // CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCHER_H_