OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 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 <map> |
| 9 #include <list> |
| 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/non_thread_safe.h" |
| 16 #include "chrome/browser/predictors/resource_prefetch_common.h" |
| 17 #include "googleurl/src/gurl.h" |
| 18 #include "net/url_request/url_request.h" |
| 19 |
| 20 namespace net { |
| 21 class URLRequestContext; |
| 22 } |
| 23 |
| 24 namespace predictors { |
| 25 |
| 26 // Responsible for prefetching resources for a single navigation based on the |
| 27 // input list of resources. |
| 28 // - Limits the max number of resources in flight for any host and also across |
| 29 // hosts. |
| 30 // - When stopped, will wait for the pending requests to finish. |
| 31 // - Lives entirely on the IO thread. |
| 32 class ResourcePrefetcher : public base::NonThreadSafe, |
| 33 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 scoped_ptr<RequestVector> requests); |
| 91 virtual ~ResourcePrefetcher(); |
| 92 |
| 93 void Start(); // Kicks off the prefetching. Can only be called once. |
| 94 void Stop(); // No additional prefetches will be queued after this. |
| 95 |
| 96 const NavigationID& navigation_id() const { |
| 97 return navigation_id_; |
| 98 } |
| 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 // net::URLRequest::Delegate methods. |
| 122 virtual void OnReceivedRedirect(net::URLRequest* request, |
| 123 const GURL& new_url, |
| 124 bool* defer_redirect) OVERRIDE; |
| 125 virtual void OnAuthRequired(net::URLRequest* request, |
| 126 net::AuthChallengeInfo* auth_info) OVERRIDE; |
| 127 virtual void OnCertificateRequested( |
| 128 net::URLRequest* request, |
| 129 net::SSLCertRequestInfo* cert_request_info) OVERRIDE; |
| 130 virtual void OnSSLCertificateError(net::URLRequest* request, |
| 131 const net::SSLInfo& ssl_info, |
| 132 bool fatal) OVERRIDE; |
| 133 virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE; |
| 134 virtual void OnReadCompleted(net::URLRequest* request, |
| 135 int bytes_read) OVERRIDE; |
| 136 |
| 137 enum PrefetcherState { |
| 138 INITIALIZED = 0, // Prefetching hasn't started. |
| 139 RUNNING = 1, // Prefetching started, allowed to add more requests. |
| 140 STOPPED = 2, // Prefetching started, not allowed to add more requests. |
| 141 FINISHED = 3 // No more inflight request, new requests not possible. |
| 142 }; |
| 143 |
| 144 PrefetcherState state_; |
| 145 Delegate* const delegate_; |
| 146 ResourcePrefetchPredictorConfig const config_; |
| 147 NavigationID navigation_id_; |
| 148 scoped_ptr<RequestVector> request_vector_; |
| 149 |
| 150 std::map<net::URLRequest*, Request*> inflight_requests_; |
| 151 std::list<Request*> request_queue_; |
| 152 std::map<std::string, int> host_inflight_counts_; |
| 153 |
| 154 DISALLOW_COPY_AND_ASSIGN(ResourcePrefetcher); |
| 155 }; |
| 156 |
| 157 } // namespace predictors |
| 158 |
| 159 #endif // CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCHER_H_ |
OLD | NEW |