- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / predictors / resource_prefetcher.h
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 <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/non_thread_safe.h"
16 #include "chrome/browser/predictors/resource_prefetch_common.h"
17 #include "net/url_request/url_request.h"
18 #include "url/gurl.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                      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 GURL& new_url,
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   PrefetcherState state_;
149   Delegate* const delegate_;
150   ResourcePrefetchPredictorConfig const config_;
151   NavigationID navigation_id_;
152   PrefetchKeyType key_type_;
153   scoped_ptr<RequestVector> request_vector_;
154
155   std::map<net::URLRequest*, Request*> inflight_requests_;
156   std::list<Request*> request_queue_;
157   std::map<std::string, int> host_inflight_counts_;
158
159   DISALLOW_COPY_AND_ASSIGN(ResourcePrefetcher);
160 };
161
162 }  // namespace predictors
163
164 #endif  // CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCHER_H_