11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#ifndef CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCHER_H_ 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCHER_H_ 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <list> 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <map> 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <vector> 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/gtest_prod_util.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/scoped_ptr.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/scoped_vector.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/threading/thread_checker.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/predictors/resource_prefetch_common.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/url_request/redirect_info.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/url_request/url_request.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "url/gurl.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace net { 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass URLRequestContext; 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace predictors { 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Responsible for prefetching resources for a single navigation based on the 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// input list of resources. 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// - Limits the max number of resources in flight for any host and also across 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// hosts. 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// - When stopped, will wait for the pending requests to finish. 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// - Lives entirely on the IO thread. 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ResourcePrefetcher : public net::URLRequest::Delegate { 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Denotes the prefetch request for a single subresource. 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct Request { 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci explicit Request(const GURL& i_resource_url); 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Request(const Request& other); 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci enum PrefetchStatus { 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PREFETCH_STATUS_NOT_STARTED, 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PREFETCH_STATUS_STARTED, 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Cancellation reasons. 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PREFETCH_STATUS_REDIRECTED, 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PREFETCH_STATUS_AUTH_REQUIRED, 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PREFETCH_STATUS_CERT_REQUIRED, 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PREFETCH_STATUS_CERT_ERROR, 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PREFETCH_STATUS_CANCELLED, 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PREFETCH_STATUS_FAILED, 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Successful prefetch states. 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PREFETCH_STATUS_FROM_CACHE, 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PREFETCH_STATUS_FROM_NETWORK 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci enum UsageStatus { 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci USAGE_STATUS_NOT_REQUESTED, 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci USAGE_STATUS_FROM_CACHE, 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci USAGE_STATUS_FROM_NETWORK, 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci USAGE_STATUS_NAVIGATION_ABANDONED 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL resource_url; 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrefetchStatus prefetch_status; 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UsageStatus usage_status; 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci typedef ScopedVector<Request> RequestVector; 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Used to communicate when the prefetching is done. All methods are invoked 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // on the IO thread. 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci class Delegate { 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual ~Delegate() { } 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Called when the ResourcePrefetcher is finished, i.e. there is nothing 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // pending in flight. Should take ownership of |requests|. 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void ResourcePrefetcherFinished( 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ResourcePrefetcher* prefetcher, 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RequestVector* requests) = 0; 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual net::URLRequestContext* GetURLRequestContext() = 0; 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |delegate| has to outlive the ResourcePrefetcher. The ResourcePrefetcher 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // takes ownership of |requests|. 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ResourcePrefetcher(Delegate* delegate, 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ResourcePrefetchPredictorConfig& config, 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const NavigationID& navigation_id, 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrefetchKeyType key_type, 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<RequestVector> requests); 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual ~ResourcePrefetcher(); 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void Start(); // Kicks off the prefetching. Can only be called once. 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void Stop(); // No additional prefetches will be queued after this. 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const NavigationID& navigation_id() const { return navigation_id_; } 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrefetchKeyType key_type() const { return key_type_; } 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci friend class ResourcePrefetcherTest; 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci friend class TestResourcePrefetcher; 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Launches new prefetch requests if possible. 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void TryToLaunchPrefetchRequests(); 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Starts a net::URLRequest for the input |request|. 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void SendRequest(Request* request); 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Called by |SendRequest| to start the |request|. This is necessary to stub 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // out the Start() call to net::URLRequest for unittesting. 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void StartURLRequest(net::URLRequest* request); 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Marks the request as finished, with the given status. 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void FinishRequest(net::URLRequest* request, Request::PrefetchStatus status); 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Reads the response data from the response - required for the resource to 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // be cached correctly. Stubbed out during testing. 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void ReadFullResponse(net::URLRequest* request); 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Returns true if the request has more data that needs to be read. If it 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // returns false, the request should not be referenced again. 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool ShouldContinueReadingRequest(net::URLRequest* request, int bytes_read); 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // net::URLRequest::Delegate methods. 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnReceivedRedirect(net::URLRequest* request, 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const net::RedirectInfo& redirect_info, 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool* defer_redirect) OVERRIDE; 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnAuthRequired(net::URLRequest* request, 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::AuthChallengeInfo* auth_info) OVERRIDE; 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnCertificateRequested( 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequest* request, 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::SSLCertRequestInfo* cert_request_info) OVERRIDE; 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnSSLCertificateError(net::URLRequest* request, 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const net::SSLInfo& ssl_info, 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool fatal) OVERRIDE; 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE; 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnReadCompleted(net::URLRequest* request, 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int bytes_read) OVERRIDE; 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci enum PrefetcherState { 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INITIALIZED = 0, // Prefetching hasn't started. 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RUNNING = 1, // Prefetching started, allowed to add more requests. 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci STOPPED = 2, // Prefetching started, not allowed to add more requests. 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FINISHED = 3 // No more inflight request, new requests not possible. 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ThreadChecker thread_checker_; 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrefetcherState state_; 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Delegate* const delegate_; 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ResourcePrefetchPredictorConfig const config_; 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NavigationID navigation_id_; 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrefetchKeyType key_type_; 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<RequestVector> request_vector_; 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::map<net::URLRequest*, Request*> inflight_requests_; 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::list<Request*> request_queue_; 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::map<std::string, size_t> host_inflight_counts_; 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(ResourcePrefetcher); 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace predictors 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif // CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCHER_H_ 166