OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #ifndef CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCHER_H_ | |
6 #define CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCHER_H_ | |
7 | |
8 #include <list> | |
9 #include <map> | |
10 #include <vector> | |
11 | |
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" | |
19 #include "url/gurl.h" | |
20 | |
21 namespace net { | |
22 class URLRequestContext; | |
23 } | |
24 | |
25 namespace predictors { | |
26 | |
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 | |
30 // hosts. | |
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 { | |
34 public: | |
35 // Denotes the prefetch request for a single subresource. | |
36 struct Request { | |
37 explicit Request(const GURL& i_resource_url); | |
38 Request(const Request& other); | |
39 | |
40 enum PrefetchStatus { | |
41 PREFETCH_STATUS_NOT_STARTED, | |
42 PREFETCH_STATUS_STARTED, | |
43 | |
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, | |
51 | |
52 // Successful prefetch states. | |
53 PREFETCH_STATUS_FROM_CACHE, | |
54 PREFETCH_STATUS_FROM_NETWORK | |
55 }; | |
56 | |
57 enum UsageStatus { | |
58 USAGE_STATUS_NOT_REQUESTED, | |
59 USAGE_STATUS_FROM_CACHE, | |
60 USAGE_STATUS_FROM_NETWORK, | |
61 USAGE_STATUS_NAVIGATION_ABANDONED | |
62 }; | |
63 | |
64 GURL resource_url; | |
65 PrefetchStatus prefetch_status; | |
66 UsageStatus usage_status; | |
67 }; | |
68 typedef ScopedVector<Request> RequestVector; | |
69 | |
70 // Used to communicate when the prefetching is done. All methods are invoked | |
71 // on the IO thread. | |
72 class Delegate { | |
73 public: | |
74 virtual ~Delegate() { } | |
75 | |
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; | |
81 | |
82 virtual net::URLRequestContext* GetURLRequestContext() = 0; | |
83 }; | |
84 | |
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 virtual ~ResourcePrefetcher(); | |
93 | |
94 void Start(); // Kicks off the prefetching. Can only be called once. | |
95 void Stop(); // No additional prefetches will be queued after this. | |
96 | |
97 const NavigationID& navigation_id() const { return navigation_id_; } | |
98 PrefetchKeyType key_type() const { return key_type_; } | |
99 | |
100 private: | |
101 friend class ResourcePrefetcherTest; | |
102 friend class TestResourcePrefetcher; | |
103 | |
104 // Launches new prefetch requests if possible. | |
105 void TryToLaunchPrefetchRequests(); | |
106 | |
107 // Starts a net::URLRequest for the input |request|. | |
108 void SendRequest(Request* request); | |
109 | |
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); | |
113 | |
114 // Marks the request as finished, with the given status. | |
115 void FinishRequest(net::URLRequest* request, Request::PrefetchStatus status); | |
116 | |
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); | |
120 | |
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); | |
124 | |
125 // net::URLRequest::Delegate methods. | |
126 virtual void OnReceivedRedirect(net::URLRequest* request, | |
127 const net::RedirectInfo& redirect_info, | |
128 bool* defer_redirect) OVERRIDE; | |
129 virtual void OnAuthRequired(net::URLRequest* request, | |
130 net::AuthChallengeInfo* auth_info) OVERRIDE; | |
131 virtual void OnCertificateRequested( | |
132 net::URLRequest* request, | |
133 net::SSLCertRequestInfo* cert_request_info) OVERRIDE; | |
134 virtual void OnSSLCertificateError(net::URLRequest* request, | |
135 const net::SSLInfo& ssl_info, | |
136 bool fatal) OVERRIDE; | |
137 virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE; | |
138 virtual void OnReadCompleted(net::URLRequest* request, | |
139 int bytes_read) OVERRIDE; | |
140 | |
141 enum PrefetcherState { | |
142 INITIALIZED = 0, // Prefetching hasn't started. | |
143 RUNNING = 1, // Prefetching started, allowed to add more requests. | |
144 STOPPED = 2, // Prefetching started, not allowed to add more requests. | |
145 FINISHED = 3 // No more inflight request, new requests not possible. | |
146 }; | |
147 | |
148 base::ThreadChecker thread_checker_; | |
149 PrefetcherState state_; | |
150 Delegate* const delegate_; | |
151 ResourcePrefetchPredictorConfig const config_; | |
152 NavigationID navigation_id_; | |
153 PrefetchKeyType key_type_; | |
154 scoped_ptr<RequestVector> request_vector_; | |
155 | |
156 std::map<net::URLRequest*, Request*> inflight_requests_; | |
157 std::list<Request*> request_queue_; | |
158 std::map<std::string, size_t> host_inflight_counts_; | |
159 | |
160 DISALLOW_COPY_AND_ASSIGN(ResourcePrefetcher); | |
161 }; | |
162 | |
163 } // namespace predictors | |
164 | |
165 #endif // CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCHER_H_ | |
OLD | NEW |