url_info.h revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2006-2010 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// A UrlInfo object is used to store prediction related information about a host
6// port and scheme triplet.  When performing DNS pre-resolution of the host/port
7// pair, its state is monitored as it is resolved.
8// It includes progress, from placement in the Predictor's queue, to resolution
9// by the DNS service as either FOUND or NO_SUCH_NAME.  Each instance may also
10// hold records of previous resolution times, which might later be shown to be
11// savings relative to resolution time during a navigation.
12// UrlInfo objects are also used to describe frames, and additional instances
13// may describe associated subresources, for future speculative connections to
14// those expected subresources.
15
16#ifndef CHROME_BROWSER_NET_URL_INFO_H_
17#define CHROME_BROWSER_NET_URL_INFO_H_
18
19#include <string>
20#include <vector>
21
22#include "base/time.h"
23#include "googleurl/src/gurl.h"
24#include "net/base/host_port_pair.h"
25
26namespace chrome_browser_net {
27
28// Use command line switch to enable detailed logging.
29void EnablePredictorDetailedLog(bool enable);
30
31enum DnsBenefit {
32  PREFETCH_NO_BENEFIT,  // Prefetch never hit the network. Name was pre-cached.
33  PREFETCH_CACHE_EVICTION,  // Prefetch used network, but so did HTTP stack.
34  PREFETCH_NAME_NONEXISTANT,  // Valuable prefetch of "name not found" was used.
35  PREFETCH_NAME_FOUND,  // Valuable prefetch was used.
36  PREFETCH_OBLIVIOUS  // No prefetch attempt was even made.
37};
38
39class UrlInfo {
40 public:
41  // Reasons for a domain to be resolved.
42  enum ResolutionMotivation {
43    MOUSE_OVER_MOTIVATED,  // Mouse-over link induced resolution.
44    PAGE_SCAN_MOTIVATED,   // Scan of rendered page induced resolution.
45    UNIT_TEST_MOTIVATED,
46    LINKED_MAX_MOTIVATED,    // enum demarkation above motivation from links.
47    OMNIBOX_MOTIVATED,       // Omni-box suggested resolving this.
48    STARTUP_LIST_MOTIVATED,  // Startup list caused this resolution.
49
50    NO_PREFETCH_MOTIVATION,  // Browser navigation info (not prefetch related).
51
52    // The following involve predictive prefetching, triggered by a navigation.
53    // The referrinrg_url_ is also set when these are used.
54    // TODO(jar): Support STATIC_REFERAL_MOTIVATED API and integration.
55    STATIC_REFERAL_MOTIVATED,  // External database suggested this resolution.
56    LEARNED_REFERAL_MOTIVATED,  // Prior navigation taught us this resolution.
57  };
58
59  enum DnsProcessingState {
60      // When processed by our prefetching system, the states are:
61      PENDING,       // Constructor has completed.
62      QUEUED,        // In name queue but not yet being resolved.
63      ASSIGNED,      // Being resolved (or being reset to earlier state)
64      ASSIGNED_BUT_MARKED,  // Needs to be deleted as soon as it's resolved.
65      FOUND,         // DNS resolution completed.
66      NO_SUCH_NAME,  // DNS resolution completed.
67      // When processed by the network stack during navigation, the states are:
68      STARTED,               // Resolution has begun for a navigation.
69      FINISHED,              // Resolution has completed for a navigation.
70      FINISHED_UNRESOLVED};  // No resolution found, so navigation will fail.
71  static const base::TimeDelta kMaxNonNetworkDnsLookupDuration;
72  // The number of OS cache entries we can guarantee(?) before cache eviction
73  // might likely take place.
74  static const int kMaxGuaranteedDnsCacheSize = 50;
75
76  typedef std::vector<UrlInfo> DnsInfoTable;
77
78  static const base::TimeDelta kNullDuration;
79
80  // UrlInfo are usually made by the default constructor during
81  // initializing of the Predictor's map (of info for Hostnames).
82  UrlInfo()
83      : state_(PENDING),
84        old_prequeue_state_(state_),
85        resolve_duration_(kNullDuration),
86        queue_duration_(kNullDuration),
87        benefits_remaining_(),
88        sequence_number_(0),
89        motivation_(NO_PREFETCH_MOTIVATION),
90        was_linked_(false) {
91  }
92
93  ~UrlInfo() {}
94
95  // NeedDnsUpdate decides, based on our internal info,
96  // if it would be valuable to attempt to update (prefectch)
97  // DNS data for hostname.  This decision is based
98  // on how recently we've done DNS prefetching for hostname.
99  bool NeedsDnsUpdate();
100
101  static void set_cache_expiration(base::TimeDelta time);
102
103  // The prefetching lifecycle.
104  void SetQueuedState(ResolutionMotivation motivation);
105  void SetAssignedState();
106  void RemoveFromQueue();
107  void SetPendingDeleteState();
108  void SetFoundState();
109  void SetNoSuchNameState();
110  // The actual browsing resolution lifecycle.
111  void SetStartedState();
112  void SetFinishedState(bool was_resolved);
113
114  // Finish initialization. Must only be called once.
115  void SetUrl(const GURL& url);
116
117  bool was_linked() const { return was_linked_; }
118
119  GURL referring_url() const { return referring_url_; }
120  void SetReferringHostname(const GURL& url) {
121    referring_url_ = url;
122  }
123
124  bool was_found() const { return FOUND == state_; }
125  bool was_nonexistant() const { return NO_SUCH_NAME == state_; }
126  bool is_assigned() const {
127    return ASSIGNED == state_ || ASSIGNED_BUT_MARKED == state_;
128  }
129  bool is_marked_to_delete() const { return ASSIGNED_BUT_MARKED == state_; }
130  const GURL url() const { return url_; }
131
132  bool HasUrl(const GURL& url) const {
133    return url_ == url;
134  }
135
136  base::TimeDelta resolve_duration() const { return resolve_duration_;}
137  base::TimeDelta queue_duration() const { return queue_duration_;}
138  base::TimeDelta benefits_remaining() const { return benefits_remaining_; }
139
140  DnsBenefit AccruePrefetchBenefits(UrlInfo* navigation_info);
141
142  void DLogResultsStats(const char* message) const;
143
144  static void GetHtmlTable(const DnsInfoTable host_infos,
145                           const char* description,
146                           const bool brief,
147                           std::string* output);
148
149 private:
150  base::TimeDelta GetDuration() {
151    base::TimeTicks old_time = time_;
152    time_ = base::TimeTicks::Now();
153    return time_ - old_time;
154  }
155
156  // IsStillCached() guesses if the DNS cache still has IP data.
157  bool IsStillCached() const;
158
159  // Record why we created, or have updated (reqested pre-resolution) of this
160  // instance.
161  void SetMotivation(ResolutionMotivation motivation);
162
163  // Helper function for about:dns printing.
164  std::string GetAsciiMotivation() const;
165
166  // The next declaration is non-const to facilitate testing.
167  static base::TimeDelta kCacheExpirationDuration;
168
169  // The current state of this instance.
170  DnsProcessingState state_;
171
172  // Record the state prior to going to a queued state, in case we have to back
173  // out of the queue.
174  DnsProcessingState old_prequeue_state_;
175
176  GURL url_;  // Host, port and scheme for this info.
177
178  // When was last state changed (usually lookup completed).
179  base::TimeTicks time_;
180  // Time needed for DNS to resolve.
181  base::TimeDelta resolve_duration_;
182  // Time spent in queue.
183  base::TimeDelta queue_duration_;
184  // Unused potential benefits of a prefetch.
185  base::TimeDelta benefits_remaining_;
186
187  int sequence_number_;  // Used to calculate potential of cache eviction.
188  static int sequence_counter;  // Used to allocate sequence_number_'s.
189
190  // Motivation for creation of this instance.
191  ResolutionMotivation motivation_;
192
193  // Record if the motivation for prefetching was ever a page-link-scan.
194  bool was_linked_;
195
196  // If this instance holds data about a navigation, we store the referrer.
197  // If this instance hold data about a prefetch, and the prefetch was
198  // instigated by a referrer, we store it here (for use in about:dns).
199  GURL referring_url_;
200
201  // We put these objects into a std::map, and hence we
202  // need some "evil" constructors.
203  // DISALLOW_COPY_AND_ASSIGN(UrlInfo);
204};
205
206}  // namespace chrome_browser_net
207
208#endif  // CHROME_BROWSER_NET_URL_INFO_H_
209