summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-23 01:22:43 +0000
committerjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-23 01:22:43 +0000
commitc5629c3842ca9fab0a6bb71a478df3fc528b8837 (patch)
tree8141f7d0b43e0cba093f049b688a336693abab1b /chrome/browser
parent3f9345838d9af871413f7350ca587b0152299e02 (diff)
downloadchromium_src-c5629c3842ca9fab0a6bb71a478df3fc528b8837.zip
chromium_src-c5629c3842ca9fab0a6bb71a478df3fc528b8837.tar.gz
chromium_src-c5629c3842ca9fab0a6bb71a478df3fc528b8837.tar.bz2
Do speculative preconnection based on network traffic (not just DNS)
This rev also handles the triple of scheme/host/port for recording both referrers and speculative connections, so that we can soon support SSL warming as well as "mere" TCP/IP preconnection. r=mbelshe Review URL: http://codereview.chromium.org/2563004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50563 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/io_thread.cc29
-rw-r--r--chrome/browser/io_thread.h22
-rw-r--r--chrome/browser/net/connect_interceptor.cc41
-rw-r--r--chrome/browser/net/connect_interceptor.h40
-rw-r--r--chrome/browser/net/dns_global.cc173
-rw-r--r--chrome/browser/net/dns_global.h19
-rw-r--r--chrome/browser/net/dns_host_info.cc20
-rw-r--r--chrome/browser/net/dns_host_info.h20
-rw-r--r--chrome/browser/net/dns_host_info_unittest.cc10
-rw-r--r--chrome/browser/net/dns_master.cc216
-rw-r--r--chrome/browser/net/dns_master.h51
-rw-r--r--chrome/browser/net/dns_master_unittest.cc206
-rw-r--r--chrome/browser/net/preconnect.cc12
-rw-r--r--chrome/browser/net/preconnect.h4
-rw-r--r--chrome/browser/net/referrer.cc44
-rw-r--r--chrome/browser/net/referrer.h15
16 files changed, 547 insertions, 375 deletions
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 5fcdb3d..d2b8fdd 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -86,6 +86,7 @@ DISABLE_RUNNABLE_METHOD_REFCOUNT(IOThread);
IOThread::IOThread()
: BrowserProcessSubThread(ChromeThread::IO),
globals_(NULL),
+ speculative_interceptor_(NULL),
prefetch_observer_(NULL),
dns_master_(NULL) {}
@@ -105,7 +106,7 @@ void IOThread::InitDnsMaster(
bool prefetching_enabled,
base::TimeDelta max_queue_delay,
size_t max_concurrent,
- const chrome_common_net::NameList& hostnames_to_prefetch,
+ const chrome_common_net::UrlList& startup_urls,
ListValue* referral_list,
bool preconnect_enabled) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
@@ -115,7 +116,7 @@ void IOThread::InitDnsMaster(
this,
&IOThread::InitDnsMasterOnIOThread,
prefetching_enabled, max_queue_delay, max_concurrent,
- hostnames_to_prefetch, referral_list, preconnect_enabled));
+ startup_urls, referral_list, preconnect_enabled));
}
void IOThread::ChangedToOnTheRecord() {
@@ -149,8 +150,6 @@ void IOThread::CleanUp() {
// Not initialized in Init(). May not be initialized.
if (dns_master_) {
- DCHECK(prefetch_observer_);
-
dns_master_->Shutdown();
// TODO(willchan): Stop reference counting DnsMaster. It's owned by
@@ -160,6 +159,10 @@ void IOThread::CleanUp() {
chrome_browser_net::FreeDnsPrefetchResources();
}
+ // Deletion will unregister this interceptor.
+ delete speculative_interceptor_;
+ speculative_interceptor_ = NULL;
+
// Not initialized in Init(). May not be initialized.
if (prefetch_observer_) {
globals_->host_resolver->RemoveObserver(prefetch_observer_);
@@ -241,7 +244,7 @@ void IOThread::InitDnsMasterOnIOThread(
bool prefetching_enabled,
base::TimeDelta max_queue_delay,
size_t max_concurrent,
- chrome_common_net::NameList hostnames_to_prefetch,
+ const chrome_common_net::UrlList& startup_urls,
ListValue* referral_list,
bool preconnect_enabled) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
@@ -256,12 +259,20 @@ void IOThread::InitDnsMasterOnIOThread(
preconnect_enabled);
dns_master_->AddRef();
- DCHECK(!prefetch_observer_);
- prefetch_observer_ = chrome_browser_net::CreatePrefetchObserver();
- globals_->host_resolver->AddObserver(prefetch_observer_);
+ // TODO(jar): Until connection notification and DNS observation handling are
+ // properly combined into a learning model, we'll only use one observation
+ // mechanism or the other.
+ if (preconnect_enabled) {
+ DCHECK(!speculative_interceptor_);
+ speculative_interceptor_ = new chrome_browser_net::ConnectInterceptor;
+ } else {
+ DCHECK(!prefetch_observer_);
+ prefetch_observer_ = chrome_browser_net::CreatePrefetchObserver();
+ globals_->host_resolver->AddObserver(prefetch_observer_);
+ }
FinalizeDnsPrefetchInitialization(
- dns_master_, prefetch_observer_, hostnames_to_prefetch, referral_list);
+ dns_master_, prefetch_observer_, startup_urls, referral_list);
}
void IOThread::ChangedToOnTheRecordOnIOThread() {
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index 4c7374e..83a781d 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_IO_THREAD_H_
#define CHROME_BROWSER_IO_THREAD_H_
+#include <vector>
+
#include "base/basictypes.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
@@ -12,6 +14,7 @@
#include "chrome/browser/browser_process_sub_thread.h"
#include "chrome/browser/net/chrome_network_delegate.h"
#include "chrome/common/net/dns.h"
+#include "chrome/browser/net/connect_interceptor.h"
#include "net/base/host_resolver.h"
class ChromeNetLog;
@@ -47,14 +50,15 @@ class IOThread : public BrowserProcessSubThread {
// Can only be called on the IO thread.
Globals* globals();
- // Initializes the DnsMaster. |prefetching_enabled| indicates whether or
- // not dns prefetching should be enabled. This should be called by the UI
- // thread. It will post a task to the IO thread to perform the actual
- // initialization.
+ // Initializes the network predictor, which induces DNS pre-resolution and/or
+ // TCP/IP preconnections. |prefetching_enabled| indicates whether or not DNS
+ // prefetching should be enabled, and |preconnect_enabled| controls whether
+ // TCP/IP preconnection is enabled. This should be called by the UI thread.
+ // It will post a task to the IO thread to perform the actual initialization.
void InitDnsMaster(bool prefetching_enabled,
base::TimeDelta max_queue_delay,
size_t max_concurrent,
- const chrome_common_net::NameList& hostnames_to_prefetch,
+ const chrome_common_net::UrlList& startup_urls,
ListValue* referral_list,
bool preconnect_enabled);
@@ -74,7 +78,8 @@ class IOThread : public BrowserProcessSubThread {
bool prefetching_enabled,
base::TimeDelta max_queue_delay,
size_t max_concurrent,
- chrome_common_net::NameList hostnames_to_prefetch,
+ const chrome_common_net::UrlList& startup_urls,
+
ListValue* referral_list,
bool preconnect_enabled);
@@ -99,6 +104,11 @@ class IOThread : public BrowserProcessSubThread {
// These member variables are initialized by a task posted to the IO thread,
// which gets posted by calling certain member functions of IOThread.
+ // Note: we user explicit pointers rather than smart pointers to be more
+ // explicit about destruction order, and ensure that there is no chance that
+ // these observers would be used accidentally after we have begun to tear
+ // down.
+ chrome_browser_net::ConnectInterceptor* speculative_interceptor_;
net::HostResolver::Observer* prefetch_observer_;
chrome_browser_net::DnsMaster* dns_master_;
diff --git a/chrome/browser/net/connect_interceptor.cc b/chrome/browser/net/connect_interceptor.cc
new file mode 100644
index 0000000..ab45ddb
--- /dev/null
+++ b/chrome/browser/net/connect_interceptor.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/net/connect_interceptor.h"
+
+#include "chrome/browser/net/dns_global.h"
+
+namespace chrome_browser_net {
+
+ConnectInterceptor::ConnectInterceptor() {
+ URLRequest::RegisterRequestInterceptor(this);
+}
+
+ConnectInterceptor::~ConnectInterceptor() {
+ URLRequest::UnregisterRequestInterceptor(this);
+}
+
+URLRequestJob* ConnectInterceptor::MaybeIntercept(URLRequest* request) {
+ if (!request->referrer().empty()) {
+ // Learn about our referring URL, for use in the future.
+ GURL referring_url(GURL(request->referrer()).GetWithEmptyPath());
+ // TODO(jar): Only call if we think this was part of a frame load, and not a
+ // link navigation. For now, we'll "learn" that to preconnect when a user
+ // actually does a click... which will probably waste space in our referrers
+ // table (since it probably won't be that deterministic).
+ NonlinkNavigation(referring_url, request->url().GetWithEmptyPath());
+ }
+ // Now we use previous learning and setup for our subresources.
+ if (request->was_fetched_via_proxy())
+ return NULL;
+ // TODO(jar): Only call if we believe this is a frame, and might have
+ // subresources. We could "guess" by looking at path extensions (such as
+ // foo.jpg or goo.gif etc.), but better would be to get this info from webkit
+ // and have it add the info to the request (we currently only set the
+ // priority, but we could record whether it was a frame).
+ NavigatingToFrame(request->url().GetWithEmptyPath());
+ return NULL;
+}
+
+} // namespace chrome_browser_net
diff --git a/chrome/browser/net/connect_interceptor.h b/chrome/browser/net/connect_interceptor.h
new file mode 100644
index 0000000..21a6b00
--- /dev/null
+++ b/chrome/browser/net/connect_interceptor.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NET_CONNECT_INTERCEPTOR_H_
+#define CHROME_BROWSER_NET_CONNECT_INTERCEPTOR_H_
+
+#include "net/url_request/url_request.h"
+
+namespace chrome_browser_net {
+
+//------------------------------------------------------------------------------
+// An interceptor to monitor URLRequests so that we can do speculative DNS
+// resolution and/or speculative TCP preconnections.
+class ConnectInterceptor : public URLRequest::Interceptor {
+ public:
+ // Construction includes registration as an URL.
+ ConnectInterceptor();
+ // Destruction includes unregistering.
+ virtual ~ConnectInterceptor();
+
+ protected:
+ // URLRequest::Interceptor overrides
+ // Learn about referrers, and optionally preconnect based on history.
+ virtual URLRequestJob* MaybeIntercept(URLRequest* request);
+ virtual URLRequestJob* MaybeInterceptResponse(URLRequest* request) {
+ return NULL;
+ }
+ virtual URLRequestJob* MaybeInterceptRedirect(URLRequest* request,
+ const GURL& location) {
+ return NULL;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ConnectInterceptor);
+};
+
+} // namespace chrome_browser_net
+
+#endif // CHROME_BROWSER_NET_CONNECT_INTERCEPTOR_H_
diff --git a/chrome/browser/net/dns_global.cc b/chrome/browser/net/dns_global.cc
index f57e029..fa33217 100644
--- a/chrome/browser/net/dns_global.cc
+++ b/chrome/browser/net/dns_global.cc
@@ -35,13 +35,13 @@ using base::TimeDelta;
namespace chrome_browser_net {
-static void DnsMotivatedPrefetch(const net::HostPortPair& hostport,
+static void DnsMotivatedPrefetch(const GURL& url,
DnsHostInfo::ResolutionMotivation motivation);
-static void DnsPrefetchMotivatedList(const NameList& hostnames,
+static void DnsPrefetchMotivatedList(const UrlList& urls,
DnsHostInfo::ResolutionMotivation motivation);
-static NameList GetDnsPrefetchHostNamesAtStartup(
+static UrlList GetPrefetchUrlListAtStartup(
PrefService* user_prefs, PrefService* local_state);
// static
@@ -52,7 +52,37 @@ const int DnsGlobalInit::kMaxPrefetchQueueingDelayMs = 500;
// A version number for prefs that are saved. This should be incremented when
// we change the format so that we discard old data.
-static const int kDnsStartupFormatVersion = 0;
+static const int kDnsStartupFormatVersion = 1;
+
+//------------------------------------------------------------------------------
+// Static helper functions
+//------------------------------------------------------------------------------
+
+// Put URL in canonical form, including a scheme, host, and port.
+// Returns GURL::EmptyGURL() if the scheme is not http/https or if the url
+// cannot be otherwise canonicalized.
+static GURL CanonicalizeUrl(const GURL& url) {
+ if (!url.has_host())
+ return GURL::EmptyGURL();
+
+ std::string scheme;
+ if (url.has_scheme()) {
+ scheme = url.scheme();
+ if (scheme != "http" && scheme != "https")
+ return GURL::EmptyGURL();
+ if (url.has_port())
+ return url.GetWithEmptyPath();
+ } else {
+ scheme = "http";
+ }
+
+ // If we omit a port, it will default to 80 or 443 as appropriate.
+ std::string colon_plus_port;
+ if (url.has_port())
+ colon_plus_port = ":" + url.port();
+
+ return GURL(scheme + "://" + url.host() + colon_plus_port);
+}
//------------------------------------------------------------------------------
// This section contains all the globally accessable API entry points for the
@@ -99,12 +129,20 @@ static DnsMaster* dns_master = NULL;
// includes both Page-Scan, and Link-Hover prefetching.
// TODO(jar): Separate out link-hover prefetching, and page-scan results.
void DnsPrefetchList(const NameList& hostnames) {
+ // TODO(jar): Push GURL transport further back into renderer.
+ UrlList urls;
+ for (NameList::const_iterator it = hostnames.begin();
+ it < hostnames.end();
+ ++it) {
+ urls.push_back(GURL("http://" + *it + ":80"));
+ }
+
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
- DnsPrefetchMotivatedList(hostnames, DnsHostInfo::PAGE_SCAN_MOTIVATED);
+ DnsPrefetchMotivatedList(urls, DnsHostInfo::PAGE_SCAN_MOTIVATED);
}
static void DnsPrefetchMotivatedList(
- const NameList& hostnames,
+ const UrlList& urls,
DnsHostInfo::ResolutionMotivation motivation) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI) ||
ChromeThread::CurrentlyOn(ChromeThread::IO));
@@ -112,13 +150,13 @@ static void DnsPrefetchMotivatedList(
return;
if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
- dns_master->ResolveList(hostnames, motivation);
+ dns_master->ResolveList(urls, motivation);
} else {
ChromeThread::PostTask(
ChromeThread::IO,
FROM_HERE,
NewRunnableMethod(dns_master,
- &DnsMaster::ResolveList, hostnames, motivation));
+ &DnsMaster::ResolveList, urls, motivation));
}
}
@@ -147,7 +185,7 @@ void DnsPrefetchUrl(const GURL& url, bool preconnectable) {
}
last_prefetch_for_host = now;
- net::HostPortPair hostport(url.HostNoBrackets(), url.EffectiveIntPort());
+ GURL canonical_url(CanonicalizeUrl(url));
if (dns_master->preconnect_enabled() && preconnectable) {
static base::TimeTicks last_keepalive;
@@ -159,26 +197,25 @@ void DnsPrefetchUrl(const GURL& url, bool preconnectable) {
return;
last_keepalive = now;
- if (Preconnect::PreconnectOnUIThread(hostport))
+ if (Preconnect::PreconnectOnUIThread(canonical_url))
return; // Skip pre-resolution, since we'll open a connection.
}
// Perform at least DNS pre-resolution.
- // TODO(jar): We could propogate a hostport here instead of a host.
- DnsMotivatedPrefetch(hostport, DnsHostInfo::OMNIBOX_MOTIVATED);
+ DnsMotivatedPrefetch(canonical_url, DnsHostInfo::OMNIBOX_MOTIVATED);
}
-static void DnsMotivatedPrefetch(const net::HostPortPair& hostport,
+static void DnsMotivatedPrefetch(const GURL& url,
DnsHostInfo::ResolutionMotivation motivation) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
- if (!dns_prefetch_enabled || NULL == dns_master || hostport.host.empty())
+ if (!dns_prefetch_enabled || NULL == dns_master || !url.has_host())
return;
ChromeThread::PostTask(
ChromeThread::IO,
FROM_HERE,
NewRunnableMethod(dns_master,
- &DnsMaster::Resolve, hostport, motivation));
+ &DnsMaster::Resolve, url, motivation));
}
//------------------------------------------------------------------------------
@@ -190,23 +227,34 @@ static void DnsMotivatedPrefetch(const net::HostPortPair& hostport,
// This function determines if there was a saving by prefetching the hostname
// for which the navigation_info is supplied.
-static bool AccruePrefetchBenefits(const GURL& referrer,
+static bool AccruePrefetchBenefits(const GURL& referrer_url,
DnsHostInfo* navigation_info) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
if (!dns_prefetch_enabled || NULL == dns_master)
return false;
- return dns_master->AccruePrefetchBenefits(
- net::HostPortPair(referrer.host(), referrer.EffectiveIntPort()),
- navigation_info);
+ DCHECK(referrer_url == referrer_url.GetWithEmptyPath());
+ return dns_master->AccruePrefetchBenefits(referrer_url, navigation_info);
+}
+
+void NavigatingTo(const GURL& url) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ if (!dns_prefetch_enabled || NULL == dns_master)
+ return;
+ dns_master->NavigatingTo(url);
+}
+
+void NavigatingToFrame(const GURL& url) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ if (!dns_prefetch_enabled || NULL == dns_master)
+ return;
+ dns_master->NavigatingToFrame(url);
}
-// When we navigate, we may know in advance some other domains that will need to
-// be resolved. This function initiates those side effects.
-static void NavigatingTo(const net::HostPortPair& hostport) {
+void NonlinkNavigation(const GURL& referring_url, const GURL& target_url) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
if (!dns_prefetch_enabled || NULL == dns_master)
return;
- dns_master->NavigatingTo(hostport);
+ dns_master->NonlinkNavigation(referring_url, target_url);
}
// The observer class needs to connect starts and finishes of HTTP network
@@ -218,7 +266,7 @@ typedef std::map<int, DnsHostInfo> ObservedResolutionMap;
// resolutions made by the network stack.
class PrefetchObserver : public net::HostResolver::Observer {
public:
- typedef std::map<net::HostPortPair, DnsHostInfo> FirstResolutionMap;
+ typedef std::map<GURL, DnsHostInfo> FirstResolutionMap;
// net::HostResolver::Observer implementation:
virtual void OnStartResolution(
@@ -261,8 +309,14 @@ void PrefetchObserver::OnStartResolution(
DCHECK_NE(0U, request_info.hostname().length());
DnsHostInfo navigation_info;
- navigation_info.SetHostname(net::HostPortPair(request_info.hostname(),
- request_info.port()));
+ // TODO(jar): Remove hack which guestimates ssl via port number, and perhaps
+ // have actual URL passed down in request_info instead.
+ bool is_ssl(443 == request_info.port());
+ std::string url_spec = is_ssl ? "https://" : "http://";
+ url_spec += request_info.hostname();
+ url_spec += ":";
+ url_spec += IntToString(request_info.port());
+ navigation_info.SetUrl(GURL(url_spec));
navigation_info.SetStartedState();
// This entry will be deleted either by OnFinishResolutionWithStatus(), or
@@ -291,12 +345,16 @@ void PrefetchObserver::OnFinishResolutionWithStatus(
}
navigation_info.SetFinishedState(was_resolved); // Get timing info
- AccruePrefetchBenefits(request_info.referrer(), &navigation_info);
+ AccruePrefetchBenefits(CanonicalizeUrl(request_info.referrer()),
+ &navigation_info);
// Handle sub-resource resolutions now that the critical navigational
// resolution has completed. This prevents us from in any way delaying that
// navigational resolution.
- NavigatingTo(net::HostPortPair(request_info.hostname(), request_info.port()));
+ std::string url_spec;
+ StringAppendF(&url_spec, "http%s://%s:%d", "",
+ request_info.hostname().c_str(), request_info.port());
+ NavigatingTo(GURL(url_spec));
if (kStartupResolutionCount <= startup_count || !was_resolved)
return;
@@ -329,9 +387,9 @@ void PrefetchObserver::StartupListAppend(const DnsHostInfo& navigation_info) {
return;
if (kStartupResolutionCount <= first_resolutions_.size())
return; // Someone just added the last item.
- if (ContainsKey(first_resolutions_, navigation_info.hostport()))
+ if (ContainsKey(first_resolutions_, navigation_info.url()))
return; // We already have this hostname listed.
- first_resolutions_[navigation_info.hostport()] = navigation_info;
+ first_resolutions_[navigation_info.url()] = navigation_info;
}
void PrefetchObserver::GetInitialDnsResolutionList(ListValue* startup_list) {
@@ -343,8 +401,8 @@ void PrefetchObserver::GetInitialDnsResolutionList(ListValue* startup_list) {
for (FirstResolutionMap::iterator it = first_resolutions_.begin();
it != first_resolutions_.end();
++it) {
- startup_list->Append(new StringValue(it->first.host));
- startup_list->Append(new FundamentalValue(it->first.port));
+ DCHECK(it->first == CanonicalizeUrl(it->first));
+ startup_list->Append(new StringValue(it->first.spec()));
}
}
@@ -435,7 +493,8 @@ void DnsPrefetchGetHtmlInfo(std::string* output) {
output->append("Incognito mode is active in a window.");
} else {
dns_master->GetHtmlInfo(output);
- g_prefetch_observer->DnsGetFirstResolutionsHtml(output);
+ if (g_prefetch_observer)
+ g_prefetch_observer->DnsGetFirstResolutionsHtml(output);
dns_master->GetHtmlReferrerLists(output);
}
}
@@ -455,22 +514,22 @@ static void InitDnsPrefetch(TimeDelta max_queue_delay, size_t max_concurrent,
user_prefs->GetBoolean(prefs::kDnsPrefetchingEnabled);
// Gather the list of hostnames to prefetch on startup.
- NameList hostnames =
- GetDnsPrefetchHostNamesAtStartup(user_prefs, local_state);
+ UrlList urls =
+ GetPrefetchUrlListAtStartup(user_prefs, local_state);
ListValue* referral_list =
static_cast<ListValue*>(
local_state->GetMutableList(prefs::kDnsHostReferralList)->DeepCopy());
g_browser_process->io_thread()->InitDnsMaster(
- prefetching_enabled, max_queue_delay, max_concurrent, hostnames,
+ prefetching_enabled, max_queue_delay, max_concurrent, urls,
referral_list, preconnect_enabled);
}
void FinalizeDnsPrefetchInitialization(
DnsMaster* global_dns_master,
net::HostResolver::Observer* global_prefetch_observer,
- const NameList& hostnames_to_prefetch,
+ const UrlList& startup_urls,
ListValue* referral_list) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
dns_master = global_dns_master;
@@ -480,7 +539,7 @@ void FinalizeDnsPrefetchInitialization(
DLOG(INFO) << "DNS Prefetch service started";
// Prefetch these hostnames on startup.
- DnsPrefetchMotivatedList(hostnames_to_prefetch,
+ DnsPrefetchMotivatedList(startup_urls,
DnsHostInfo::STARTUP_LIST_MOTIVATED);
dns_master->DeserializeReferrersThenDelete(referral_list);
}
@@ -511,7 +570,8 @@ static void SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread(
return;
}
- g_prefetch_observer->GetInitialDnsResolutionList(startup_list);
+ if (g_prefetch_observer)
+ g_prefetch_observer->GetInitialDnsResolutionList(startup_list);
// TODO(jar): Trimming should be done more regularly, such as every 48 hours
// of physical time, or perhaps after 48 hours of running (excluding time
@@ -544,11 +604,11 @@ void SaveDnsPrefetchStateForNextStartupAndTrim(PrefService* prefs) {
completion.Wait();
}
-static NameList GetDnsPrefetchHostNamesAtStartup(PrefService* user_prefs,
- PrefService* local_state) {
+static UrlList GetPrefetchUrlListAtStartup(PrefService* user_prefs,
+ PrefService* local_state) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
- NameList hostnames;
- // Prefetch DNS for hostnames we learned about during last session.
+ UrlList urls;
+ // Recall list of URLs we learned about during last session.
// This may catch secondary hostnames, pulled in by the homepages. It will
// also catch more of the "primary" home pages, since that was (presumably)
// rendered first (and will be rendered first this time too).
@@ -562,15 +622,18 @@ static NameList GetDnsPrefetchHostNamesAtStartup(PrefService* user_prefs,
format_version == kDnsStartupFormatVersion) {
++it;
for (; it != startup_list->end(); ++it) {
- std::string hostname;
- if (!(*it)->GetAsString(&hostname))
+ std::string url_spec;
+ if (!(*it)->GetAsString(&url_spec)) {
+ LOG(DFATAL);
break; // Format incompatibility.
- int port;
- if (!(*++it)->GetAsInteger(&port))
+ }
+ GURL url(url_spec);
+ if (!url.has_host() || !url.has_scheme()) {
+ LOG(DFATAL);
break; // Format incompatibility.
+ }
- // TODO(jar): We sohould accept hostport pairs.
- hostnames.push_back(hostname);
+ urls.push_back(url);
}
}
}
@@ -582,15 +645,17 @@ static NameList GetDnsPrefetchHostNamesAtStartup(PrefService* user_prefs,
if (SessionStartupPref::URLS == tab_start_pref.type) {
for (size_t i = 0; i < tab_start_pref.urls.size(); i++) {
GURL gurl = tab_start_pref.urls[i];
- if (gurl.is_valid() && !gurl.host().empty())
- hostnames.push_back(gurl.HostNoBrackets());
+ if (!gurl.is_valid() || gurl.SchemeIsFile() || gurl.host().empty())
+ continue;
+ if (gurl.SchemeIs("http") || gurl.SchemeIs("https"))
+ urls.push_back(gurl.GetWithEmptyPath());
}
}
- if (hostnames.empty())
- hostnames.push_back("www.google.com");
+ if (urls.empty())
+ urls.push_back(GURL("http://www.google.com:80"));
- return hostnames;
+ return urls;
}
//------------------------------------------------------------------------------
diff --git a/chrome/browser/net/dns_global.h b/chrome/browser/net/dns_global.h
index 639f614..0abacc5 100644
--- a/chrome/browser/net/dns_global.h
+++ b/chrome/browser/net/dns_global.h
@@ -13,6 +13,7 @@
#include <string>
+#include <vector>
#include "base/field_trial.h"
#include "base/scoped_ptr.h"
@@ -28,7 +29,7 @@ namespace chrome_browser_net {
void FinalizeDnsPrefetchInitialization(
DnsMaster* global_dns_master,
net::HostResolver::Observer* global_prefetch_observer,
- const NameList& hostnames_to_prefetch,
+ const std::vector<GURL>& urls_to_prefetch,
ListValue* referral_list);
// Free all resources allocated by FinalizeDnsPrefetchInitialization. After that
@@ -45,6 +46,7 @@ void RegisterPrefs(PrefService* local_state);
void RegisterUserPrefs(PrefService* user_prefs);
// Renderer bundles up list and sends to this browser API via IPC.
+// TODO(jar): Use UrlList instead to include port and scheme.
void DnsPrefetchList(const NameList& hostnames);
// This API is used by the autocomplete popup box (as user types).
@@ -56,6 +58,21 @@ void DnsPrefetchUrl(const GURL& url, bool preconnectable);
void DnsPrefetchGetHtmlInfo(std::string* output);
//------------------------------------------------------------------------------
+// When we navigate, we may know in advance some other domains that will need to
+// be resolved. This function initiates those side effects.
+void NavigatingTo(const GURL& url);
+
+// When we navigate to a frame that may contain embedded resources, we may know
+// in advance some other URLs that will need to be connected to (via TCP and
+// sometimes SSL). This function initiates those connections
+void NavigatingToFrame(const GURL& url);
+
+// Call when we should learn from a navigation about a relationship to a
+// subresource target, and its containing frame, which was loaded as a referring
+// URL.
+void NonlinkNavigation(const GURL& referring_url, const GURL& target_url);
+
+//------------------------------------------------------------------------------
void SaveDnsPrefetchStateForNextStartupAndTrim(PrefService* prefs);
// Helper class to handle global init and shutdown.
class DnsGlobalInit {
diff --git a/chrome/browser/net/dns_host_info.cc b/chrome/browser/net/dns_host_info.cc
index 2fb626d..522b69e 100644
--- a/chrome/browser/net/dns_host_info.cc
+++ b/chrome/browser/net/dns_host_info.cc
@@ -170,11 +170,11 @@ void DnsHostInfo::SetFinishedState(bool was_resolved) {
DLogResultsStats("DNS HTTP Finished");
}
-void DnsHostInfo::SetHostname(const net::HostPortPair& hostport) {
- if (hostport_.host.empty()) // Not yet initialized.
- hostport_ = hostport;
+void DnsHostInfo::SetUrl(const GURL& url) {
+ if (url_.is_empty()) // Not yet initialized.
+ url_ = url;
else
- DCHECK(hostport_.Equals(hostport));
+ DCHECK_EQ(url_, url);
}
// IsStillCached() guesses if the DNS cache still has IP data,
@@ -200,7 +200,7 @@ bool DnsHostInfo::IsStillCached() const {
DnsBenefit DnsHostInfo::AccruePrefetchBenefits(DnsHostInfo* navigation_info) {
DCHECK(FINISHED == navigation_info->state_ ||
FINISHED_UNRESOLVED == navigation_info->state_);
- DCHECK(navigation_info->hostport().Equals(hostport_));
+ DCHECK(navigation_info->url() == url_);
if ((0 == benefits_remaining_.InMilliseconds()) ||
(FOUND != state_ && NO_SUCH_NAME != state_)) {
@@ -220,7 +220,7 @@ DnsBenefit DnsHostInfo::AccruePrefetchBenefits(DnsHostInfo* navigation_info) {
navigation_info->motivation_ = motivation_;
if (LEARNED_REFERAL_MOTIVATED == motivation_ ||
STATIC_REFERAL_MOTIVATED == motivation_)
- navigation_info->referring_hostport_ = referring_hostport_;
+ navigation_info->referring_url_ = referring_url_;
if (navigation_info->resolve_duration_ > kMaxNonNetworkDnsLookupDuration) {
// Our precache effort didn't help since HTTP stack hit the network.
@@ -255,7 +255,7 @@ void DnsHostInfo::DLogResultsStats(const char* message) const {
<< resolve_duration().InMilliseconds() << "ms\tp="
<< benefits_remaining_.InMilliseconds() << "ms\tseq="
<< sequence_number_
- << "\t" << hostport_.ToString();
+ << "\t" << url_.spec();
}
//------------------------------------------------------------------------------
@@ -361,7 +361,7 @@ void DnsHostInfo::GetHtmlTable(const DnsInfoTable host_infos,
it != host_infos.end(); it++) {
queue.sample((it->queue_duration_.InMilliseconds()));
StringAppendF(output, row_format,
- RemoveJs(it->hostport_.ToString()).c_str(),
+ RemoveJs(it->url_.spec()).c_str(),
preresolve.sample((it->benefits_remaining_.InMilliseconds())),
resolve.sample((it->resolve_duration_.InMilliseconds())),
HoursMinutesSeconds(when.sample(
@@ -426,10 +426,10 @@ std::string DnsHostInfo::GetAsciiMotivation() const {
return "n/a";
case STATIC_REFERAL_MOTIVATED:
- return RemoveJs(referring_hostport_.ToString()) + "*";
+ return RemoveJs(referring_url_.spec()) + "*";
case LEARNED_REFERAL_MOTIVATED:
- return RemoveJs(referring_hostport_.ToString());
+ return RemoveJs(referring_url_.spec());
default:
return "";
diff --git a/chrome/browser/net/dns_host_info.h b/chrome/browser/net/dns_host_info.h
index 73a0b2e..6c34025 100644
--- a/chrome/browser/net/dns_host_info.h
+++ b/chrome/browser/net/dns_host_info.h
@@ -44,7 +44,7 @@ class DnsHostInfo {
NO_PREFETCH_MOTIVATION, // Browser navigation info (not prefetch related).
// The following involve predictive prefetching, triggered by a navigation.
- // The referring_hostport_ is also set when these are used.
+ // The referrinrg_url_ is also set when these are used.
// TODO(jar): Support STATIC_REFERAL_MOTIVATED API and integration.
STATIC_REFERAL_MOTIVATED, // External database suggested this resolution.
LEARNED_REFERAL_MOTIVATED, // Prior navigation taught us this resolution.
@@ -106,13 +106,13 @@ class DnsHostInfo {
void SetFinishedState(bool was_resolved);
// Finish initialization. Must only be called once.
- void SetHostname(const net::HostPortPair& hostport);
+ void SetUrl(const GURL& url);
bool was_linked() const { return was_linked_; }
- net::HostPortPair referring_hostname() const { return referring_hostport_; }
- void SetReferringHostname(const net::HostPortPair& hostport) {
- referring_hostport_ = hostport;
+ GURL referring_url() const { return referring_url_; }
+ void SetReferringHostname(const GURL& url) {
+ referring_url_ = url;
}
bool was_found() const { return FOUND == state_; }
@@ -121,10 +121,10 @@ class DnsHostInfo {
return ASSIGNED == state_ || ASSIGNED_BUT_MARKED == state_;
}
bool is_marked_to_delete() const { return ASSIGNED_BUT_MARKED == state_; }
- const net::HostPortPair hostport() const { return hostport_; }
+ const GURL url() const { return url_; }
- bool HasHostname(const net::HostPortPair& hostport) const {
- return (hostport.Equals(hostport_));
+ bool HasUrl(const GURL& url) const {
+ return url_ == url;
}
base::TimeDelta resolve_duration() const { return resolve_duration_;}
@@ -167,7 +167,7 @@ class DnsHostInfo {
// out of the queue.
DnsProcessingState old_prequeue_state_;
- net::HostPortPair hostport_; // Hostname for this info.
+ GURL url_; // Host, port and scheme for this info.
// When was last state changed (usually lookup completed).
base::TimeTicks time_;
@@ -190,7 +190,7 @@ class DnsHostInfo {
// If this instance holds data about a navigation, we store the referrer.
// If this instance hold data about a prefetch, and the prefetch was
// instigated by a referrer, we store it here (for use in about:dns).
- net::HostPortPair referring_hostport_;
+ GURL referring_url_;
// We put these objects into a std::map, and hence we
// need some "evil" constructors.
diff --git a/chrome/browser/net/dns_host_info_unittest.cc b/chrome/browser/net/dns_host_info_unittest.cc
index 7c145a4..ffe122f 100644
--- a/chrome/browser/net/dns_host_info_unittest.cc
+++ b/chrome/browser/net/dns_host_info_unittest.cc
@@ -22,19 +22,19 @@ typedef chrome_browser_net::DnsHostInfo DnsHostInfo;
TEST(DnsHostInfoTest, StateChangeTest) {
DnsHostInfo info_practice, info;
- net::HostPortPair hostname1("domain1.com", 80), hostname2("domain2.com", 443);
+ GURL url1("http://domain1.com:80"), url2("https://domain2.com:443");
// First load DLL, so that their load time won't interfere with tests.
// Some tests involve timing function performance, and DLL time can overwhelm
// test durations (which are considering network vs cache response times).
- info_practice.SetHostname(hostname2);
+ info_practice.SetUrl(url2);
info_practice.SetQueuedState(DnsHostInfo::UNIT_TEST_MOTIVATED);
info_practice.SetAssignedState();
info_practice.SetFoundState();
PlatformThread::Sleep(500); // Allow time for DLLs to fully load.
// Complete the construction of real test object.
- info.SetHostname(hostname1);
+ info.SetUrl(url1);
EXPECT_TRUE(info.NeedsDnsUpdate()) << "error in construction state";
info.SetQueuedState(DnsHostInfo::UNIT_TEST_MOTIVATED);
@@ -93,9 +93,9 @@ TEST(DnsHostInfoTest, StateChangeTest) {
// the state transitions used in such congestion handling.
TEST(DnsHostInfoTest, CongestionResetStateTest) {
DnsHostInfo info;
- net::HostPortPair hostname1("domain1.com", 80);
+ GURL url("http://domain1.com:80");
- info.SetHostname(hostname1);
+ info.SetUrl(url);
info.SetQueuedState(DnsHostInfo::UNIT_TEST_MOTIVATED);
info.SetAssignedState();
EXPECT_TRUE(info.is_assigned());
diff --git a/chrome/browser/net/dns_master.cc b/chrome/browser/net/dns_master.cc
index 11f65d7..972759f 100644
--- a/chrome/browser/net/dns_master.cc
+++ b/chrome/browser/net/dns_master.cc
@@ -30,11 +30,11 @@ class DnsMaster::LookupRequest {
public:
LookupRequest(DnsMaster* master,
net::HostResolver* host_resolver,
- const net::HostPortPair& hostport)
+ const GURL& url)
: ALLOW_THIS_IN_INITIALIZER_LIST(
net_callback_(this, &LookupRequest::OnLookupFinished)),
master_(master),
- hostport_(hostport),
+ url_(url),
resolver_(host_resolver) {
}
@@ -43,7 +43,8 @@ class DnsMaster::LookupRequest {
// net:ERR_IO_PENDING ==> Network will callback later with result.
// anything else ==> Host was not found synchronously.
int Start() {
- net::HostResolver::RequestInfo resolve_info(hostport_.host, hostport_.port);
+ net::HostResolver::RequestInfo resolve_info(url_.host(),
+ url_.EffectiveIntPort());
// Make a note that this is a speculative resolve request. This allows us
// to separate it from real navigations in the observer's callback, and
@@ -55,7 +56,7 @@ class DnsMaster::LookupRequest {
private:
void OnLookupFinished(int result) {
- master_->OnLookupFinished(this, hostport_, result == net::OK);
+ master_->OnLookupFinished(this, url_, result == net::OK);
}
// HostResolver will call us using this callback when resolution is complete.
@@ -63,7 +64,7 @@ class DnsMaster::LookupRequest {
DnsMaster* master_; // Master which started us.
- const net::HostPortPair hostport_; // Hostname to resolve.
+ const GURL url_; // Hostname to resolve.
net::SingleRequestHostResolver resolver_;
net::AddressList addresses_;
@@ -98,38 +99,37 @@ void DnsMaster::Shutdown() {
}
// Overloaded Resolve() to take a vector of names.
-void DnsMaster::ResolveList(const NameList& hostnames,
+void DnsMaster::ResolveList(const UrlList& urls,
DnsHostInfo::ResolutionMotivation motivation) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
- NameList::const_iterator it;
- for (it = hostnames.begin(); it < hostnames.end(); ++it)
- // TODO(jar): I should pass port all the way in from renderer.
- AppendToResolutionQueue(net::HostPortPair(*it, 80), motivation);
+ for (UrlList::const_iterator it = urls.begin(); it < urls.end(); ++it) {
+ AppendToResolutionQueue(*it, motivation);
+ }
}
// Basic Resolve() takes an invidual name, and adds it
// to the queue.
-void DnsMaster::Resolve(const net::HostPortPair& hostport,
+void DnsMaster::Resolve(const GURL& url,
DnsHostInfo::ResolutionMotivation motivation) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
- if (hostport.host.empty())
+ if (!url.has_host())
return;
- AppendToResolutionQueue(hostport, motivation);
+ AppendToResolutionQueue(url, motivation);
}
-bool DnsMaster::AccruePrefetchBenefits(const net::HostPortPair& referrer,
+bool DnsMaster::AccruePrefetchBenefits(const GURL& referrer,
DnsHostInfo* navigation_info) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
- net::HostPortPair hostport = navigation_info->hostport();
- Results::iterator it = results_.find(hostport);
+ GURL url = navigation_info->url();
+ Results::iterator it = results_.find(url);
if (it == results_.end()) {
// Use UMA histogram to quantify potential future gains here.
UMA_HISTOGRAM_LONG_TIMES("DNS.UnexpectedResolutionL",
navigation_info->resolve_duration());
navigation_info->DLogResultsStats("DNS UnexpectedResolution");
- NonlinkNavigation(referrer, navigation_info);
+ NonlinkNavigation(referrer, navigation_info->url());
return false;
}
DnsHostInfo& prefetched_host_info(it->second);
@@ -141,7 +141,7 @@ bool DnsMaster::AccruePrefetchBenefits(const net::HostPortPair& referrer,
bool referrer_based_prefetch = !prefetched_host_info.was_linked();
if (referrer_based_prefetch) {
// This wasn't the first time this host refered to *some* referrer.
- NonlinkNavigation(referrer, navigation_info);
+ NonlinkNavigation(referrer, navigation_info->url());
}
DnsBenefit benefit = prefetched_host_info.AccruePrefetchBenefits(
@@ -151,15 +151,15 @@ bool DnsMaster::AccruePrefetchBenefits(const net::HostPortPair& referrer,
case PREFETCH_NAME_NONEXISTANT:
cache_hits_.push_back(*navigation_info);
if (referrer_based_prefetch) {
- if (!referrer.host.empty()) {
+ if (referrer.has_host()) {
referrers_[referrer].AccrueValue(
- navigation_info->benefits_remaining(), hostport);
+ navigation_info->benefits_remaining(), url);
}
}
return true;
case PREFETCH_CACHE_EVICTION:
- cache_eviction_map_[hostport] = *navigation_info;
+ cache_eviction_map_[url] = *navigation_info;
return false;
case PREFETCH_NO_BENEFIT:
@@ -172,36 +172,45 @@ bool DnsMaster::AccruePrefetchBenefits(const net::HostPortPair& referrer,
}
}
-void DnsMaster::NonlinkNavigation(const net::HostPortPair& referring_hostport,
- const DnsHostInfo* navigation_info) {
+void DnsMaster::NonlinkNavigation(const GURL& referring_url,
+ const GURL& target_url) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
- if (referring_hostport.host.empty() ||
- referring_hostport.Equals(navigation_info->hostport()))
- return;
- referrers_[referring_hostport].SuggestHost(navigation_info->hostport());
+ if (referring_url.has_host() &&
+ referring_url != target_url) {
+ DCHECK(referring_url == referring_url.GetWithEmptyPath());
+ referrers_[referring_url].SuggestHost(target_url);
+ }
}
-void DnsMaster::NavigatingTo(const net::HostPortPair& hostport) {
+void DnsMaster::NavigatingTo(const GURL& url) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
- Referrers::iterator it = referrers_.find(hostport);
+ Referrers::iterator it = referrers_.find(url);
if (referrers_.end() == it)
return;
Referrer* referrer = &(it->second);
referrer->IncrementUseCount();
- for (Referrer::iterator future_hostport = referrer->begin();
- future_hostport != referrer->end(); ++future_hostport) {
- if (preconnect_enabled_) {
- if (future_hostport->second.IsPreconnectWorthDoing()) {
- Preconnect::PreconnectOnIOThread(future_hostport->first);
- continue; // No need he pre-resolve DNS.
- }
- // Fall through and do DNS pre-resolution.
- }
+ for (Referrer::iterator future_url = referrer->begin();
+ future_url != referrer->end(); ++future_url) {
DnsHostInfo* queued_info = AppendToResolutionQueue(
- future_hostport->first,
+ future_url->first,
DnsHostInfo::LEARNED_REFERAL_MOTIVATED);
if (queued_info)
- queued_info->SetReferringHostname(hostport);
+ queued_info->SetReferringHostname(url);
+ }
+}
+
+void DnsMaster::NavigatingToFrame(const GURL& url) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ DCHECK(url.GetWithEmptyPath() == url);
+ Referrers::iterator it = referrers_.find(url);
+ if (referrers_.end() == it)
+ return;
+ Referrer* referrer = &(it->second);
+ referrer->IncrementUseCount();
+ for (Referrer::iterator future_url = referrer->begin();
+ future_url != referrer->end(); ++future_url) {
+ if (future_url->second.IsPreconnectWorthDoing())
+ Preconnect::PreconnectOnIOThread(future_url->first);
}
}
@@ -278,7 +287,7 @@ void DnsMaster::GetHtmlReferrerLists(std::string* output) {
// TODO(jar): Remove any plausible JavaScript from names before displaying.
- typedef std::set<net::HostPortPair, struct RightToLeftStringSorter>
+ typedef std::set<GURL, struct RightToLeftStringSorter>
SortedNames;
SortedNames sorted_names;
@@ -300,23 +309,23 @@ void DnsMaster::GetHtmlReferrerLists(std::string* output) {
sorted_names.end() != it; ++it) {
Referrer* referrer = &(referrers_[*it]);
bool first_set_of_futures = true;
- for (Referrer::iterator future_hostport = referrer->begin();
- future_hostport != referrer->end(); ++future_hostport) {
+ for (Referrer::iterator future_url = referrer->begin();
+ future_url != referrer->end(); ++future_url) {
output->append("<tr align=right>");
if (first_set_of_futures)
StringAppendF(output, "<td rowspan=%d>%s</td><td rowspan=%d>%d</td>",
static_cast<int>(referrer->size()),
- it->ToString().c_str(),
+ it->spec().c_str(),
static_cast<int>(referrer->size()),
static_cast<int>(referrer->use_count()));
first_set_of_futures = false;
StringAppendF(output,
"<td>%d</td><td>%d</td><td>%2.3f</td><td>%dms</td><td>%s</td></tr>",
- static_cast<int>(future_hostport->second.navigation_count()),
- static_cast<int>(future_hostport->second.preconnection_count()),
- static_cast<double>(future_hostport->second.subresource_use_rate()),
- static_cast<int>(future_hostport->second.latency().InMilliseconds()),
- future_hostport->first.ToString().c_str());
+ static_cast<int>(future_url->second.navigation_count()),
+ static_cast<int>(future_url->second.preconnection_count()),
+ static_cast<double>(future_url->second.subresource_use_rate()),
+ static_cast<int>(future_url->second.latency().InMilliseconds()),
+ future_url->first.spec().c_str());
}
}
output->append("</table>");
@@ -332,7 +341,7 @@ void DnsMaster::GetHtmlInfo(std::string* output) {
DnsHostInfo::DnsInfoTable already_cached;
// Get copies of all useful data.
- typedef std::map<net::HostPortPair, DnsHostInfo, RightToLeftStringSorter>
+ typedef std::map<GURL, DnsHostInfo, RightToLeftStringSorter>
Snapshot;
Snapshot snapshot;
{
@@ -393,20 +402,20 @@ void DnsMaster::GetHtmlInfo(std::string* output) {
}
DnsHostInfo* DnsMaster::AppendToResolutionQueue(
- const net::HostPortPair& hostport,
+ const GURL& url,
DnsHostInfo::ResolutionMotivation motivation) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
- DCHECK(!hostport.host.empty());
+ DCHECK(url.has_host());
if (shutdown_)
return NULL;
- DnsHostInfo* info = &results_[hostport];
- info->SetHostname(hostport); // Initialize or DCHECK.
+ DnsHostInfo* info = &results_[url];
+ info->SetUrl(url); // Initialize or DCHECK.
// TODO(jar): I need to discard names that have long since expired.
// Currently we only add to the domain map :-/
- DCHECK(info->HasHostname(hostport));
+ DCHECK(info->HasUrl(url));
if (!info->NeedsDnsUpdate()) {
info->DLogResultsStats("DNS PrefetchNotUpdated");
@@ -414,7 +423,7 @@ DnsHostInfo* DnsMaster::AppendToResolutionQueue(
}
info->SetQueuedState(motivation);
- work_queue_.Push(hostport, motivation);
+ work_queue_.Push(url, motivation);
StartSomeQueuedResolutions();
return info;
}
@@ -424,9 +433,9 @@ void DnsMaster::StartSomeQueuedResolutions() {
while (!work_queue_.IsEmpty() &&
pending_lookups_.size() < max_concurrent_lookups_) {
- const net::HostPortPair hostport(work_queue_.Pop());
- DnsHostInfo* info = &results_[hostport];
- DCHECK(info->HasHostname(hostport));
+ const GURL url(work_queue_.Pop());
+ DnsHostInfo* info = &results_[url];
+ DCHECK(info->HasUrl(url));
info->SetAssignedState();
if (CongestionControlPerformed(info)) {
@@ -434,7 +443,7 @@ void DnsMaster::StartSomeQueuedResolutions() {
return;
}
- LookupRequest* request = new LookupRequest(this, host_resolver_, hostport);
+ LookupRequest* request = new LookupRequest(this, host_resolver_, url);
int status = request->Start();
if (status == net::ERR_IO_PENDING) {
// Will complete asynchronously.
@@ -445,7 +454,7 @@ void DnsMaster::StartSomeQueuedResolutions() {
// Completed synchronously (was already cached by HostResolver), or else
// there was (equivalently) some network error that prevents us from
// finding the name. Status net::OK means it was "found."
- LookupFinished(request, hostport, status == net::OK);
+ LookupFinished(request, url, status == net::OK);
delete request;
}
}
@@ -469,26 +478,24 @@ bool DnsMaster::CongestionControlPerformed(DnsHostInfo* info) {
return true;
}
-void DnsMaster::OnLookupFinished(LookupRequest* request,
- const net::HostPortPair& hostport,
+void DnsMaster::OnLookupFinished(LookupRequest* request, const GURL& url,
bool found) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
- LookupFinished(request, hostport, found);
+ LookupFinished(request, url, found);
pending_lookups_.erase(request);
delete request;
StartSomeQueuedResolutions();
}
-void DnsMaster::LookupFinished(LookupRequest* request,
- const net::HostPortPair& hostport,
+void DnsMaster::LookupFinished(LookupRequest* request, const GURL& url,
bool found) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
- DnsHostInfo* info = &results_[hostport];
- DCHECK(info->HasHostname(hostport));
+ DnsHostInfo* info = &results_[url];
+ DCHECK(info->HasUrl(url));
if (info->is_marked_to_delete()) {
- results_.erase(hostport);
+ results_.erase(url);
} else {
if (found)
info->SetFoundState();
@@ -508,9 +515,9 @@ void DnsMaster::DiscardAllResults() {
// Try to delete anything in our work queue.
while (!work_queue_.IsEmpty()) {
// Emulate processing cycle as though host was not found.
- net::HostPortPair hostport = work_queue_.Pop();
- DnsHostInfo* info = &results_[hostport];
- DCHECK(info->HasHostname(hostport));
+ GURL url = work_queue_.Pop();
+ DnsHostInfo* info = &results_[url];
+ DCHECK(info->HasUrl(url));
info->SetAssignedState();
info->SetNoSuchNameState();
}
@@ -521,12 +528,12 @@ void DnsMaster::DiscardAllResults() {
// We can't erase anything being worked on.
Results assignees;
for (Results::iterator it = results_.begin(); results_.end() != it; ++it) {
- net::HostPortPair hostport(it->first);
+ GURL url(it->first);
DnsHostInfo* info = &it->second;
- DCHECK(info->HasHostname(hostport));
+ DCHECK(info->HasUrl(url));
if (info->is_assigned()) {
info->SetPendingDeleteState();
- assignees[hostport] = *info;
+ assignees[url] = *info;
}
}
DCHECK(assignees.size() <= max_concurrent_lookups_);
@@ -540,13 +547,13 @@ void DnsMaster::DiscardAllResults() {
void DnsMaster::TrimReferrers() {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
- std::vector<net::HostPortPair> hosts;
+ std::vector<GURL> urls;
for (Referrers::const_iterator it = referrers_.begin();
it != referrers_.end(); ++it)
- hosts.push_back(it->first);
- for (size_t i = 0; i < hosts.size(); ++i)
- if (!referrers_[hosts[i]].Trim())
- referrers_.erase(hosts[i]);
+ urls.push_back(it->first);
+ for (size_t i = 0; i < urls.size(); ++i)
+ if (!referrers_[urls[i]].Trim())
+ referrers_.erase(urls[i]);
}
void DnsMaster::SerializeReferrers(ListValue* referral_list) {
@@ -560,8 +567,7 @@ void DnsMaster::SerializeReferrers(ListValue* referral_list) {
// Create a list for each referer.
ListValue* motivator(new ListValue);
- motivator->Append(new FundamentalValue(it->first.port));
- motivator->Append(new StringValue(it->first.host));
+ motivator->Append(new StringValue(it->first.spec()));
motivator->Append(subresource_list);
referral_list->Append(motivator);
@@ -578,30 +584,21 @@ void DnsMaster::DeserializeReferrers(const ListValue& referral_list) {
ListValue* motivator;
if (!referral_list.GetList(i, &motivator)) {
NOTREACHED();
- continue;
- }
- int motivating_port;
- if (!motivator->GetInteger(0, &motivating_port)) {
- NOTREACHED();
- continue;
+ return;
}
- std::string motivating_host;
- if (!motivator->GetString(1, &motivating_host)) {
+ std::string motivating_url_spec;
+ if (!motivator->GetString(0, &motivating_url_spec)) {
NOTREACHED();
- continue;
- }
- if (motivating_host.empty()) {
- NOTREACHED();
- continue;
+ return;
}
Value* subresource_list;
- if (!motivator->Get(2, &subresource_list)) {
+ if (!motivator->Get(1, &subresource_list)) {
NOTREACHED();
- continue;
+ return;
}
- net::HostPortPair motivating_hostport(motivating_host, motivating_port);
- referrers_[motivating_hostport].Deserialize(*subresource_list);
+
+ referrers_[GURL(motivating_url_spec)].Deserialize(*subresource_list);
}
}
}
@@ -615,17 +612,17 @@ DnsMaster::HostNameQueue::HostNameQueue() {
DnsMaster::HostNameQueue::~HostNameQueue() {
}
-void DnsMaster::HostNameQueue::Push(const net::HostPortPair& hostport,
+void DnsMaster::HostNameQueue::Push(const GURL& url,
DnsHostInfo::ResolutionMotivation motivation) {
switch (motivation) {
case DnsHostInfo::STATIC_REFERAL_MOTIVATED:
case DnsHostInfo::LEARNED_REFERAL_MOTIVATED:
case DnsHostInfo::MOUSE_OVER_MOTIVATED:
- rush_queue_.push(hostport);
+ rush_queue_.push(url);
break;
default:
- background_queue_.push(hostport);
+ background_queue_.push(url);
break;
}
}
@@ -634,16 +631,13 @@ bool DnsMaster::HostNameQueue::IsEmpty() const {
return rush_queue_.empty() && background_queue_.empty();
}
-net::HostPortPair DnsMaster::HostNameQueue::Pop() {
+GURL DnsMaster::HostNameQueue::Pop() {
DCHECK(!IsEmpty());
- if (!rush_queue_.empty()) {
- net::HostPortPair hostport(rush_queue_.front());
- rush_queue_.pop();
- return hostport;
- }
- net::HostPortPair hostport(background_queue_.front());
- background_queue_.pop();
- return hostport;
+ std::queue<GURL> *queue(rush_queue_.empty() ? &background_queue_
+ : &rush_queue_);
+ GURL url(queue->front());
+ queue->pop();
+ return url;
}
} // namespace chrome_browser_net
diff --git a/chrome/browser/net/dns_master.h b/chrome/browser/net/dns_master.h
index 0586b1c..29d3278 100644
--- a/chrome/browser/net/dns_master.h
+++ b/chrome/browser/net/dns_master.h
@@ -18,6 +18,7 @@
#include <queue>
#include <set>
#include <string>
+#include <vector>
#include "base/gtest_prod_util.h"
#include "base/ref_counted.h"
@@ -32,8 +33,9 @@ class HostResolver;
namespace chrome_browser_net {
+typedef chrome_common_net::UrlList UrlList;
typedef chrome_common_net::NameList NameList;
-typedef std::map<net::HostPortPair, DnsHostInfo> Results;
+typedef std::map<GURL, DnsHostInfo> Results;
// Note that DNS master is not thread safe, and must only be called from
// the IO thread. Failure to do so will result in a DCHECK at runtime.
@@ -41,7 +43,7 @@ class DnsMaster : public base::RefCountedThreadSafe<DnsMaster> {
public:
// A version number for prefs that are saved. This should be incremented when
// we change the format so that we discard old data.
- enum {DNS_REFERRER_VERSION = 0 };
+ enum { DNS_REFERRER_VERSION = 1 };
// |max_concurrent| specifies how many concurrent (parallel) prefetches will
// be performed. Host lookups will be issued through |host_resolver|.
@@ -60,24 +62,26 @@ class DnsMaster : public base::RefCountedThreadSafe<DnsMaster> {
void DiscardAllResults();
// Add hostname(s) to the queue for processing.
- void ResolveList(const NameList& hostnames,
+ void ResolveList(const UrlList& urls,
DnsHostInfo::ResolutionMotivation motivation);
- void Resolve(const net::HostPortPair& hostport,
+ void Resolve(const GURL& url,
DnsHostInfo::ResolutionMotivation motivation);
// Get latency benefit of the prefetch that we are navigating to.
- bool AccruePrefetchBenefits(const net::HostPortPair& referrer,
+ bool AccruePrefetchBenefits(const GURL& referrer,
DnsHostInfo* navigation_info);
- // Instigate prefetch of any domains we predict will be needed after this
+ // Instigate preresolution of any domains we predict will be needed after this
// navigation.
- void NavigatingTo(const net::HostPortPair& hostport);
+ void NavigatingTo(const GURL& url);
+
+ // Instigate pre-connection to any URLs we predict will be needed after this
+ // navigation (typically more-embedded resources on a page).
+ void NavigatingToFrame(const GURL& url);
// Record details of a navigation so that we can preresolve the host name
// ahead of time the next time the users navigates to the indicated host.
- // TODO(eroman): can this be a const& instead?
- void NonlinkNavigation(const net::HostPortPair& referrer,
- const DnsHostInfo* navigation_info);
+ void NonlinkNavigation(const GURL& referring_url, const GURL& target_url);
// Dump HTML table containing list of referrers for about:dns.
void GetHtmlReferrerLists(std::string* output);
@@ -140,17 +144,17 @@ class DnsMaster : public base::RefCountedThreadSafe<DnsMaster> {
public:
HostNameQueue();
~HostNameQueue();
- void Push(const net::HostPortPair& hostport,
+ void Push(const GURL& url,
DnsHostInfo::ResolutionMotivation motivation);
bool IsEmpty() const;
- net::HostPortPair Pop();
+ GURL Pop();
private:
// The names in the queue that should be serviced (popped) ASAP.
- std::queue<net::HostPortPair> rush_queue_;
+ std::queue<GURL> rush_queue_;
// The names in the queue that should only be serviced when rush_queue is
// empty.
- std::queue<net::HostPortPair> background_queue_;
+ std::queue<GURL> background_queue_;
DISALLOW_COPY_AND_ASSIGN(HostNameQueue);
};
@@ -158,39 +162,38 @@ class DnsMaster : public base::RefCountedThreadSafe<DnsMaster> {
// A map that is keyed with the host/port that we've learned were the cause
// of loading additional URLs. The list of additional targets is held
// in a Referrer instance, which is a value in this map.
- typedef std::map<net::HostPortPair, Referrer> Referrers;
+ typedef std::map<GURL, Referrer> Referrers;
// Only for testing. Returns true if hostname has been successfully resolved
// (name found).
- bool WasFound(const net::HostPortPair& hostport) const {
- Results::const_iterator it(results_.find(hostport));
+ bool WasFound(const GURL& url) const {
+ Results::const_iterator it(results_.find(url));
return (it != results_.end()) &&
it->second.was_found();
}
// Only for testing. Return how long was the resolution
// or DnsHostInfo::kNullDuration if it hasn't been resolved yet.
- base::TimeDelta GetResolutionDuration(const net::HostPortPair& hostport) {
+ base::TimeDelta GetResolutionDuration(const GURL& url) {
- if (results_.find(hostport) == results_.end())
+ if (results_.find(url) == results_.end())
return DnsHostInfo::kNullDuration;
- return results_[hostport].resolve_duration();
+ return results_[url].resolve_duration();
}
// Only for testing;
size_t peak_pending_lookups() const { return peak_pending_lookups_; }
// Access method for use by async lookup request to pass resolution result.
- void OnLookupFinished(LookupRequest* request,
- const net::HostPortPair& hostport, bool found);
+ void OnLookupFinished(LookupRequest* request, const GURL& url, bool found);
// Underlying method for both async and synchronous lookup to update state.
void LookupFinished(LookupRequest* request,
- const net::HostPortPair& hostport, bool found);
+ const GURL& url, bool found);
// Queue hostname for resolution. If queueing was done, return the pointer
// to the queued instance, otherwise return NULL.
- DnsHostInfo* AppendToResolutionQueue(const net::HostPortPair& hostport,
+ DnsHostInfo* AppendToResolutionQueue(const GURL& url,
DnsHostInfo::ResolutionMotivation motivation);
// Check to see if too much queuing delay has been noted for the given info,
diff --git a/chrome/browser/net/dns_master_unittest.cc b/chrome/browser/net/dns_master_unittest.cc
index 2699b1f..63323bb 100644
--- a/chrome/browser/net/dns_master_unittest.cc
+++ b/chrome/browser/net/dns_master_unittest.cc
@@ -32,7 +32,7 @@ typedef base::RepeatingTimer<WaitForResolutionHelper> HelperTimer;
class WaitForResolutionHelper {
public:
- WaitForResolutionHelper(DnsMaster* master, const NameList& hosts,
+ WaitForResolutionHelper(DnsMaster* master, const UrlList& hosts,
HelperTimer* timer)
: master_(master),
hosts_(hosts),
@@ -40,8 +40,8 @@ class WaitForResolutionHelper {
}
void Run() {
- for (NameList::const_iterator i = hosts_.begin(); i != hosts_.end(); ++i)
- if (master_->GetResolutionDuration(net::HostPortPair(*i, 80)) ==
+ for (UrlList::const_iterator i = hosts_.begin(); i != hosts_.end(); ++i)
+ if (master_->GetResolutionDuration(*i) ==
DnsHostInfo::kNullDuration)
return; // We don't have resolution for that host.
@@ -54,7 +54,7 @@ class WaitForResolutionHelper {
private:
DnsMaster* master_;
- const NameList hosts_;
+ const UrlList hosts_;
HelperTimer* timer_;
};
@@ -82,7 +82,7 @@ class DnsMasterTest : public testing::Test {
rules->AddRuleWithLatency("gmail.com", "127.0.0.1", 63);
}
- void WaitForResolution(DnsMaster* master, const NameList& hosts) {
+ void WaitForResolution(DnsMaster* master, const UrlList& hosts) {
HelperTimer* timer = new HelperTimer();
timer->Start(TimeDelta::FromMilliseconds(100),
new WaitForResolutionHelper(master, hosts, timer),
@@ -122,17 +122,17 @@ TEST_F(DnsMasterTest, BenefitLookupTest) {
DnsGlobalInit::kMaxPrefetchConcurrentLookups,
false);
- net::HostPortPair goog("www.google.com", 80),
- goog2("gmail.google.com.com", 80),
- goog3("mail.google.com", 80),
- goog4("gmail.com", 80);
+ GURL goog("http://www.google.com:80"),
+ goog2("http://gmail.google.com.com:80"),
+ goog3("http://mail.google.com:80"),
+ goog4("http://gmail.com:80");
DnsHostInfo goog_info, goog2_info, goog3_info, goog4_info;
// Simulate getting similar names from a network observer
- goog_info.SetHostname(goog);
- goog2_info.SetHostname(goog2);
- goog3_info.SetHostname(goog3);
- goog4_info.SetHostname(goog4);
+ goog_info.SetUrl(goog);
+ goog2_info.SetUrl(goog2);
+ goog3_info.SetUrl(goog3);
+ goog4_info.SetUrl(goog4);
goog_info.SetStartedState();
goog2_info.SetStartedState();
@@ -144,11 +144,11 @@ TEST_F(DnsMasterTest, BenefitLookupTest) {
goog3_info.SetFinishedState(true);
goog4_info.SetFinishedState(true);
- NameList names;
- names.push_back(goog.host);
- names.push_back(goog2.host);
- names.push_back(goog3.host);
- names.push_back(goog4.host);
+ UrlList names;
+ names.push_back(goog);
+ names.push_back(goog2);
+ names.push_back(goog3);
+ names.push_back(goog4);
testing_master->ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
@@ -162,7 +162,7 @@ TEST_F(DnsMasterTest, BenefitLookupTest) {
// With the mock DNS, each of these should have taken some time, and hence
// shown a benefit (i.e., prefetch cost more than network access time).
- net::HostPortPair referer; // Null host.
+ GURL referer; // Null host.
// Simulate actual navigation, and acrue the benefit for "helping" the DNS
// part of the navigation.
@@ -190,9 +190,9 @@ TEST_F(DnsMasterTest, ShutdownWhenResolutionIsPendingTest) {
DnsGlobalInit::kMaxPrefetchConcurrentLookups,
false);
- net::HostPortPair localhost("127.0.0.1", 80);
- NameList names;
- names.push_back(localhost.host);
+ GURL localhost("http://127.0.0.1:80");
+ UrlList names;
+ names.push_back(localhost);
testing_master->ResolveList(names, DnsHostInfo::PAGE_SCAN_MOTIVATED);
@@ -215,10 +215,10 @@ TEST_F(DnsMasterTest, SingleLookupTest) {
DnsGlobalInit::kMaxPrefetchConcurrentLookups,
false);
- net::HostPortPair goog("www.google.com", 80);
+ GURL goog("http://www.google.com:80");
- NameList names;
- names.push_back(goog.host);
+ UrlList names;
+ names.push_back(goog);
// Try to flood the master with many concurrent requests.
for (int i = 0; i < 10; i++)
@@ -246,21 +246,21 @@ TEST_F(DnsMasterTest, ConcurrentLookupTest) {
DnsGlobalInit::kMaxPrefetchConcurrentLookups,
false);
- net::HostPortPair goog("www.google.com", 80),
- goog2("gmail.google.com.com", 80),
- goog3("mail.google.com", 80),
- goog4("gmail.com", 80);
- net::HostPortPair bad1("bad1.notfound", 80),
- bad2("bad2.notfound", 80);
-
- NameList names;
- names.push_back(goog.host);
- names.push_back(goog3.host);
- names.push_back(bad1.host);
- names.push_back(goog2.host);
- names.push_back(bad2.host);
- names.push_back(goog4.host);
- names.push_back(goog.host);
+ GURL goog("http://www.google.com:80"),
+ goog2("http://gmail.google.com.com:80"),
+ goog3("http://mail.google.com:80"),
+ goog4("http://gmail.com:80");
+ GURL bad1("http://bad1.notfound:80"),
+ bad2("http://bad2.notfound:80");
+
+ UrlList names;
+ names.push_back(goog);
+ names.push_back(goog3);
+ names.push_back(bad1);
+ names.push_back(goog2);
+ names.push_back(bad2);
+ names.push_back(goog4);
+ names.push_back(goog);
// Try to flood the master with many concurrent requests.
for (int i = 0; i < 10; i++)
@@ -297,9 +297,9 @@ TEST_F(DnsMasterTest, MassiveConcurrentLookupTest) {
DnsGlobalInit::kMaxPrefetchConcurrentLookups,
false);
- NameList names;
+ UrlList names;
for (int i = 0; i < 100; i++)
- names.push_back("host" + IntToString(i) + ".notfound");
+ names.push_back(GURL("http://host" + IntToString(i) + ".notfound:80"));
// Try to flood the master with many concurrent requests.
for (int i = 0; i < 10; i++)
@@ -323,7 +323,7 @@ TEST_F(DnsMasterTest, MassiveConcurrentLookupTest) {
// Return a motivation_list if we can find one for the given motivating_host (or
// NULL if a match is not found).
static ListValue* FindSerializationMotivation(
- const net::HostPortPair& motivation, const ListValue& referral_list) {
+ const GURL& motivation, const ListValue& referral_list) {
CHECK_LT(0u, referral_list.GetSize()); // Room for version.
int format_version = -1;
CHECK(referral_list.GetInteger(0, &format_version));
@@ -331,11 +331,9 @@ static ListValue* FindSerializationMotivation(
ListValue* motivation_list(NULL);
for (size_t i = 1; i < referral_list.GetSize(); ++i) {
referral_list.GetList(i, &motivation_list);
- std::string existing_host;
- int existing_port;
- EXPECT_TRUE(motivation_list->GetInteger(0, &existing_port));
- EXPECT_TRUE(motivation_list->GetString(1, &existing_host));
- if (motivation.host == existing_host && motivation.port == existing_port)
+ std::string existing_spec;
+ EXPECT_TRUE(motivation_list->GetString(0, &existing_spec));
+ if (motivation == GURL(existing_spec))
return motivation_list;
}
return NULL;
@@ -351,8 +349,8 @@ static ListValue* NewEmptySerializationList() {
// Add a motivating_host and a subresource_host to a serialized list, using
// this given latency. This is a helper function for quickly building these
// lists.
-static void AddToSerializedList(const net::HostPortPair& motivation,
- const net::HostPortPair& subresource,
+static void AddToSerializedList(const GURL& motivation,
+ const GURL& subresource,
int latency,
double rate,
ListValue* referral_list ) {
@@ -362,8 +360,7 @@ static void AddToSerializedList(const net::HostPortPair& motivation,
if (!motivation_list) {
// This is the first mention of this motivation, so build a list.
motivation_list = new ListValue;
- motivation_list->Append(new FundamentalValue(motivation.port));
- motivation_list->Append(new StringValue(motivation.host));
+ motivation_list->Append(new StringValue(motivation.spec()));
// Provide empty subresource list.
motivation_list->Append(new ListValue());
@@ -372,15 +369,14 @@ static void AddToSerializedList(const net::HostPortPair& motivation,
}
ListValue* subresource_list(NULL);
- // 0 == port; 1 == host; 2 == subresource_list.
- EXPECT_TRUE(motivation_list->GetList(2, &subresource_list));
+ // 0 == url; 1 == subresource_list.
+ EXPECT_TRUE(motivation_list->GetList(1, &subresource_list));
// We won't bother to check for the subresource being there already. Worst
// case, during deserialization, the latency value we supply plus the
// existing value(s) will be added to the referrer.
- subresource_list->Append(new FundamentalValue(subresource.port));
- subresource_list->Append(new StringValue(subresource.host));
+ subresource_list->Append(new StringValue(subresource.spec()));
subresource_list->Append(new FundamentalValue(latency));
subresource_list->Append(new FundamentalValue(rate));
}
@@ -391,8 +387,8 @@ static const int kLatencyNotFound = -1;
// listed. This assume a well formed serialization, which has at most one such
// entry for any pair of names. If no such pair is found, then return false.
// Data is written into rate and latency arguments.
-static bool GetDataFromSerialization(const net::HostPortPair& motivation,
- const net::HostPortPair& subresource,
+static bool GetDataFromSerialization(const GURL& motivation,
+ const GURL& subresource,
const ListValue& referral_list,
double* rate,
int* latency) {
@@ -401,15 +397,13 @@ static bool GetDataFromSerialization(const net::HostPortPair& motivation,
if (!motivation_list)
return false;
ListValue* subresource_list;
- EXPECT_TRUE(motivation_list->GetList(2, &subresource_list));
+ EXPECT_TRUE(motivation_list->GetList(1, &subresource_list));
for (size_t i = 0; i < subresource_list->GetSize();) {
- std::string host;
- int port;
- EXPECT_TRUE(subresource_list->GetInteger(i++, &port));
- EXPECT_TRUE(subresource_list->GetString(i++, &host));
+ std::string url_spec;
+ EXPECT_TRUE(subresource_list->GetString(i++, &url_spec));
EXPECT_TRUE(subresource_list->GetInteger(i++, latency));
EXPECT_TRUE(subresource_list->GetReal(i++, rate));
- if (subresource.host == host && subresource.port == port) {
+ if (subresource == GURL(url_spec)) {
return true;
}
}
@@ -428,7 +422,7 @@ TEST_F(DnsMasterTest, ReferrerSerializationNilTest) {
master->SerializeReferrers(referral_list.get());
EXPECT_EQ(1U, referral_list->GetSize());
EXPECT_FALSE(GetDataFromSerialization(
- net::HostPortPair("a.com", 79), net::HostPortPair("b.com", 78),
+ GURL("http://a.com:79"), GURL("http://b.com:78"),
*referral_list.get(), NULL, NULL));
master->Shutdown();
@@ -442,13 +436,13 @@ TEST_F(DnsMasterTest, ReferrerSerializationSingleReferrerTest) {
default_max_queueing_delay_,
DnsGlobalInit::kMaxPrefetchConcurrentLookups,
false);
- const net::HostPortPair motivation_hostport("www.google.com", 91);
- const net::HostPortPair subresource_hostport("icons.google.com", 90);
+ const GURL motivation_url("http://www.google.com:91");
+ const GURL subresource_url("http://icons.google.com:90");
const int kLatency = 3;
const double kRate = 23.4;
scoped_ptr<ListValue> referral_list(NewEmptySerializationList());
- AddToSerializedList(motivation_hostport, subresource_hostport,
+ AddToSerializedList(motivation_url, subresource_url,
kLatency, kRate, referral_list.get());
master->DeserializeReferrers(*referral_list.get());
@@ -459,7 +453,7 @@ TEST_F(DnsMasterTest, ReferrerSerializationSingleReferrerTest) {
int latency;
double rate;
EXPECT_TRUE(GetDataFromSerialization(
- motivation_hostport, subresource_hostport, recovered_referral_list, &rate,
+ motivation_url, subresource_url, recovered_referral_list, &rate,
&latency));
EXPECT_EQ(rate, kRate);
EXPECT_EQ(latency, kLatency);
@@ -473,21 +467,21 @@ TEST_F(DnsMasterTest, ReferrerSerializationTrimTest) {
default_max_queueing_delay_,
DnsGlobalInit::kMaxPrefetchConcurrentLookups,
false);
- net::HostPortPair motivation_hostport("www.google.com", 110);
+ GURL motivation_url("http://www.google.com:110");
- net::HostPortPair icon_subresource_hostport("icons.google.com", 111);
+ GURL icon_subresource_url("http://icons.google.com:111");
const int kLatencyIcon = 10;
const double kRateIcon = 0.; // User low rate, so latency will dominate.
- net::HostPortPair img_subresource_hostport("img.google.com", 118);
+ GURL img_subresource_url("http://img.google.com:118");
const int kLatencyImg = 3;
const double kRateImg = 0.;
scoped_ptr<ListValue> referral_list(NewEmptySerializationList());
AddToSerializedList(
- motivation_hostport, icon_subresource_hostport,
+ motivation_url, icon_subresource_url,
kLatencyIcon, kRateIcon, referral_list.get());
AddToSerializedList(
- motivation_hostport, img_subresource_hostport,
+ motivation_url, img_subresource_url,
kLatencyImg, kRateImg, referral_list.get());
master->DeserializeReferrers(*referral_list.get());
@@ -498,13 +492,13 @@ TEST_F(DnsMasterTest, ReferrerSerializationTrimTest) {
int latency;
double rate;
EXPECT_TRUE(GetDataFromSerialization(
- motivation_hostport, icon_subresource_hostport, recovered_referral_list,
+ motivation_url, icon_subresource_url, recovered_referral_list,
&rate, &latency));
EXPECT_EQ(latency, kLatencyIcon);
EXPECT_EQ(rate, kRateIcon);
EXPECT_TRUE(GetDataFromSerialization(
- motivation_hostport, img_subresource_hostport, recovered_referral_list,
+ motivation_url, img_subresource_url, recovered_referral_list,
&rate, &latency));
EXPECT_EQ(latency, kLatencyImg);
EXPECT_EQ(rate, kRateImg);
@@ -515,13 +509,13 @@ TEST_F(DnsMasterTest, ReferrerSerializationTrimTest) {
master->SerializeReferrers(&recovered_referral_list);
EXPECT_EQ(2U, recovered_referral_list.GetSize());
EXPECT_TRUE(GetDataFromSerialization(
- motivation_hostport, icon_subresource_hostport, recovered_referral_list,
+ motivation_url, icon_subresource_url, recovered_referral_list,
&rate, &latency));
EXPECT_EQ(latency, kLatencyIcon / 2);
EXPECT_EQ(rate, kRateIcon);
EXPECT_TRUE(GetDataFromSerialization(
- motivation_hostport, img_subresource_hostport, recovered_referral_list,
+ motivation_url, img_subresource_url, recovered_referral_list,
&rate, &latency));
EXPECT_EQ(latency, kLatencyImg / 2);
EXPECT_EQ(rate, kRateImg);
@@ -530,13 +524,13 @@ TEST_F(DnsMasterTest, ReferrerSerializationTrimTest) {
master->SerializeReferrers(&recovered_referral_list);
EXPECT_EQ(2U, recovered_referral_list.GetSize());
EXPECT_TRUE(GetDataFromSerialization(
- motivation_hostport, icon_subresource_hostport, recovered_referral_list,
+ motivation_url, icon_subresource_url, recovered_referral_list,
&rate, &latency));
EXPECT_EQ(latency, kLatencyIcon / 4);
EXPECT_EQ(rate, kRateIcon);
// Img is down to zero, but we don't delete it yet.
EXPECT_TRUE(GetDataFromSerialization(
- motivation_hostport, img_subresource_hostport, recovered_referral_list,
+ motivation_url, img_subresource_url, recovered_referral_list,
&rate, &latency));
EXPECT_EQ(kLatencyImg / 4, 0);
EXPECT_EQ(latency, kLatencyImg / 4);
@@ -546,14 +540,14 @@ TEST_F(DnsMasterTest, ReferrerSerializationTrimTest) {
master->SerializeReferrers(&recovered_referral_list);
EXPECT_EQ(2U, recovered_referral_list.GetSize());
EXPECT_TRUE(GetDataFromSerialization(
- motivation_hostport, icon_subresource_hostport, recovered_referral_list,
+ motivation_url, icon_subresource_url, recovered_referral_list,
&rate, &latency));
EXPECT_EQ(latency, kLatencyIcon / 8);
EXPECT_EQ(rate, kRateIcon);
// Img is down to zero, but we don't delete it yet.
EXPECT_TRUE(GetDataFromSerialization(
- motivation_hostport, img_subresource_hostport, recovered_referral_list,
+ motivation_url, img_subresource_url, recovered_referral_list,
&rate, &latency));
EXPECT_EQ(kLatencyImg / 8, 0);
EXPECT_EQ(latency, kLatencyImg / 8);
@@ -564,10 +558,10 @@ TEST_F(DnsMasterTest, ReferrerSerializationTrimTest) {
// Icon is also trimmed away, so entire set gets discarded.
EXPECT_EQ(1U, recovered_referral_list.GetSize());
EXPECT_FALSE(GetDataFromSerialization(
- motivation_hostport, icon_subresource_hostport, recovered_referral_list,
+ motivation_url, icon_subresource_url, recovered_referral_list,
&rate, &latency));
EXPECT_FALSE(GetDataFromSerialization(
- motivation_hostport, img_subresource_hostport, recovered_referral_list,
+ motivation_url, img_subresource_url, recovered_referral_list,
&rate, &latency));
master->Shutdown();
@@ -577,7 +571,7 @@ TEST_F(DnsMasterTest, ReferrerSerializationTrimTest) {
TEST_F(DnsMasterTest, PriorityQueuePushPopTest) {
DnsMaster::HostNameQueue queue;
- net::HostPortPair first("first", 80), second("second", 90);
+ GURL first("http://first:80"), second("http://second:90");
// First check high priority queue FIFO functionality.
EXPECT_TRUE(queue.IsEmpty());
@@ -585,9 +579,9 @@ TEST_F(DnsMasterTest, PriorityQueuePushPopTest) {
EXPECT_FALSE(queue.IsEmpty());
queue.Push(second, DnsHostInfo::MOUSE_OVER_MOTIVATED);
EXPECT_FALSE(queue.IsEmpty());
- EXPECT_EQ(queue.Pop().ToString(), first.ToString());
+ EXPECT_EQ(queue.Pop(), first);
EXPECT_FALSE(queue.IsEmpty());
- EXPECT_EQ(queue.Pop().ToString(), second.ToString());
+ EXPECT_EQ(queue.Pop(), second);
EXPECT_TRUE(queue.IsEmpty());
// Then check low priority queue FIFO functionality.
@@ -595,9 +589,9 @@ TEST_F(DnsMasterTest, PriorityQueuePushPopTest) {
EXPECT_FALSE(queue.IsEmpty());
queue.Push(second, DnsHostInfo::OMNIBOX_MOTIVATED);
EXPECT_FALSE(queue.IsEmpty());
- EXPECT_EQ(queue.Pop().ToString(), first.ToString());
+ EXPECT_EQ(queue.Pop(), first);
EXPECT_FALSE(queue.IsEmpty());
- EXPECT_EQ(queue.Pop().ToString(), second.ToString());
+ EXPECT_EQ(queue.Pop(), second);
EXPECT_TRUE(queue.IsEmpty());
}
@@ -605,14 +599,14 @@ TEST_F(DnsMasterTest, PriorityQueueReorderTest) {
DnsMaster::HostNameQueue queue;
// Push all the low priority items.
- net::HostPortPair low1("low1", 80),
- low2("low2", 80),
- low3("low3", 443),
- low4("low4", 80),
- low5("low5", 80),
- hi1("hi1", 80),
- hi2("hi2", 80),
- hi3("hi3", 80);
+ GURL low1("http://low1:80"),
+ low2("http://low2:80"),
+ low3("http://low3:443"),
+ low4("http://low4:80"),
+ low5("http://low5:80"),
+ hi1("http://hi1:80"),
+ hi2("http://hi2:80"),
+ hi3("http://hi3:80");
EXPECT_TRUE(queue.IsEmpty());
queue.Push(low1, DnsHostInfo::PAGE_SCAN_MOTIVATED);
@@ -628,17 +622,17 @@ TEST_F(DnsMasterTest, PriorityQueueReorderTest) {
queue.Push(hi3, DnsHostInfo::MOUSE_OVER_MOTIVATED);
// Check that high priority stuff comes out first, and in FIFO order.
- EXPECT_EQ(queue.Pop().ToString(), hi1.ToString());
- EXPECT_EQ(queue.Pop().ToString(), hi2.ToString());
- EXPECT_EQ(queue.Pop().ToString(), hi3.ToString());
+ EXPECT_EQ(queue.Pop(), hi1);
+ EXPECT_EQ(queue.Pop(), hi2);
+ EXPECT_EQ(queue.Pop(), hi3);
// ...and then low priority strings.
- EXPECT_EQ(queue.Pop().ToString(), low1.ToString());
- EXPECT_EQ(queue.Pop().ToString(), low2.ToString());
- EXPECT_EQ(queue.Pop().ToString(), low3.ToString());
- EXPECT_EQ(queue.Pop().ToString(), low4.ToString());
- EXPECT_EQ(queue.Pop().ToString(), low5.ToString());
- EXPECT_EQ(queue.Pop().ToString(), low4.ToString());
+ EXPECT_EQ(queue.Pop(), low1);
+ EXPECT_EQ(queue.Pop(), low2);
+ EXPECT_EQ(queue.Pop(), low3);
+ EXPECT_EQ(queue.Pop(), low4);
+ EXPECT_EQ(queue.Pop(), low5);
+ EXPECT_EQ(queue.Pop(), low4);
EXPECT_TRUE(queue.IsEmpty());
}
diff --git a/chrome/browser/net/preconnect.cc b/chrome/browser/net/preconnect.cc
index ff200de..c4c7c97 100644
--- a/chrome/browser/net/preconnect.cc
+++ b/chrome/browser/net/preconnect.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -20,7 +20,7 @@ namespace chrome_browser_net {
Preconnect* Preconnect::callback_instance_;
// static
-bool Preconnect::PreconnectOnUIThread(const net::HostPortPair& hostport) {
+bool Preconnect::PreconnectOnUIThread(const GURL& url) {
// Try to do connection warming for this search provider.
URLRequestContextGetter* getter = Profile::GetDefaultRequestContext();
if (!getter)
@@ -29,12 +29,12 @@ bool Preconnect::PreconnectOnUIThread(const net::HostPortPair& hostport) {
ChromeThread::PostTask(
ChromeThread::IO,
FROM_HERE,
- NewRunnableFunction(Preconnect::PreconnectOnIOThread, hostport));
+ NewRunnableFunction(Preconnect::PreconnectOnIOThread, url));
return true;
}
// static
-void Preconnect::PreconnectOnIOThread(const net::HostPortPair& hostport) {
+void Preconnect::PreconnectOnIOThread(const GURL& url) {
URLRequestContextGetter* getter = Profile::GetDefaultRequestContext();
if (!getter)
return;
@@ -47,7 +47,7 @@ void Preconnect::PreconnectOnIOThread(const net::HostPortPair& hostport) {
net::HttpNetworkSession* session = factory->GetSession();
scoped_refptr<net::TCPClientSocketPool> pool = session->tcp_socket_pool();
- net::TCPSocketParams params(hostport.host, hostport.port, net::LOW,
+ net::TCPSocketParams params(url.host(), url.EffectiveIntPort(), net::LOW,
GURL(), false);
net::ClientSocketHandle handle;
@@ -55,7 +55,7 @@ void Preconnect::PreconnectOnIOThread(const net::HostPortPair& hostport) {
callback_instance_ = new Preconnect;
// TODO(jar): This does not handle proxies currently.
- handle.Init(hostport.ToString() , params, net::LOWEST,
+ handle.Init(url.spec(), params, net::LOWEST,
callback_instance_, pool, net::BoundNetLog());
handle.Reset();
}
diff --git a/chrome/browser/net/preconnect.h b/chrome/browser/net/preconnect.h
index d4fb0dd..5251c05 100644
--- a/chrome/browser/net/preconnect.h
+++ b/chrome/browser/net/preconnect.h
@@ -19,9 +19,9 @@ namespace chrome_browser_net {
class Preconnect : public net::CompletionCallback {
public:
- static bool PreconnectOnUIThread(const net::HostPortPair& hostport);
+ static bool PreconnectOnUIThread(const GURL& url);
- static void PreconnectOnIOThread(const net::HostPortPair& hostport);
+ static void PreconnectOnIOThread(const GURL& url);
private:
Preconnect() {}
diff --git a/chrome/browser/net/referrer.cc b/chrome/browser/net/referrer.cc
index 736790a..936d25b 100644
--- a/chrome/browser/net/referrer.cc
+++ b/chrome/browser/net/referrer.cc
@@ -44,7 +44,7 @@ static const double kInitialExpectedValue = 0.0;
// static
bool Referrer::use_preconnect_valuations_ = false;
-void Referrer::SuggestHost(const net::HostPortPair& hostport) {
+void Referrer::SuggestHost(const GURL& url) {
// Limit how large our list can get, in case we make mistakes about what
// hostnames are in sub-resources (example: Some advertisments have a link to
// the ad agency, and then provide a "surprising" redirect to the advertised
@@ -53,9 +53,10 @@ void Referrer::SuggestHost(const net::HostPortPair& hostport) {
// TODO(jar): Do experiments to optimize the max count of suggestions.
static const size_t kMaxSuggestions = 10;
- if (hostport.host.empty()) // Is this really needed????
+ if (!url.has_host()) // TODO(jar): Is this really needed????
return;
- SubresourceMap::iterator it = find(hostport);
+ DCHECK(url == url.GetWithEmptyPath());
+ SubresourceMap::iterator it = find(url);
if (it != end()) {
it->second.SubresourceIsNeeded();
return;
@@ -65,13 +66,13 @@ void Referrer::SuggestHost(const net::HostPortPair& hostport) {
DeleteLeastUseful();
DCHECK(kMaxSuggestions > size());
}
- (*this)[hostport].SubresourceIsNeeded();
+ (*this)[url].SubresourceIsNeeded();
}
void Referrer::DeleteLeastUseful() {
// Find the item with the lowest value. Most important is preconnection_rate,
// next is latency savings, and last is lifetime (age).
- net::HostPortPair least_useful_hostport;
+ GURL least_useful_url;
double lowest_rate_seen = 0.0;
// We use longs for durations because we will use multiplication on them.
int64 lowest_latency_seen = 0; // Duration in milliseconds.
@@ -82,7 +83,7 @@ void Referrer::DeleteLeastUseful() {
int64 lifetime = (kNow - it->second.birth_time()).InMilliseconds();
int64 latency = it->second.latency().InMilliseconds();
double rate = it->second.subresource_use_rate();
- if (!least_useful_hostport.host.empty()) {
+ if (least_useful_url.has_host()) {
if (rate > lowest_rate_seen)
continue;
if (!latency && !lowest_latency_seen) {
@@ -102,21 +103,21 @@ void Referrer::DeleteLeastUseful() {
}
}
}
- least_useful_hostport = it->first;
+ least_useful_url = it->first;
lowest_rate_seen = rate;
lowest_latency_seen = latency;
least_useful_lifetime = lifetime;
}
- erase(least_useful_hostport);
- // Note: there is a small chance that we will discard a least_useful_hostport
+ erase(least_useful_url);
+ // Note: there is a small chance that we will discard a least_useful_url
// that is currently being prefetched because it *was* in this referer list.
// In that case, when a benefit appears in AccrueValue() below, we are careful
// to check before accessing the member.
}
void Referrer::AccrueValue(const base::TimeDelta& delta,
- const net::HostPortPair& hostport) {
- SubresourceMap::iterator it = find(hostport);
+ const GURL& url) {
+ SubresourceMap::iterator it = find(url);
// Be careful that we weren't evicted from this referrer in DeleteLeastUseful.
if (it != end())
it->second.AccrueValue(delta);
@@ -144,11 +145,8 @@ void Referrer::Deserialize(const Value& value) {
const ListValue* subresource_list(static_cast<const ListValue*>(&value));
size_t index = 0; // Bounds checking is done by subresource_list->Get*().
while (true) {
- int port;
- if (!subresource_list->GetInteger(index++, &port))
- return;
- std::string host;
- if (!subresource_list->GetString(index++, &host))
+ std::string url_spec;
+ if (!subresource_list->GetString(index++, &url_spec))
return;
int latency_ms;
if (!subresource_list->GetInteger(index++, &latency_ms))
@@ -157,24 +155,23 @@ void Referrer::Deserialize(const Value& value) {
if (!subresource_list->GetReal(index++, &rate))
return;
- net::HostPortPair hostport(host, port);
+ GURL url(url_spec);
base::TimeDelta latency = base::TimeDelta::FromMilliseconds(latency_ms);
// TODO(jar): We could be more direct, and change birth date or similar to
// show that this is a resurrected value we're adding in. I'm not yet sure
// of how best to optimize the learning and pruning (Trim) algorithm at this
// level, so for now, we just suggest subresources, which leaves them all
// with the same birth date (typically start of process).
- SuggestHost(hostport);
- AccrueValue(latency, hostport);
- (*this)[hostport].SetSubresourceUseRate(rate);
+ SuggestHost(url);
+ AccrueValue(latency, url);
+ (*this)[url].SetSubresourceUseRate(rate);
}
}
Value* Referrer::Serialize() const {
ListValue* subresource_list(new ListValue);
for (const_iterator it = begin(); it != end(); ++it) {
- FundamentalValue* port(new FundamentalValue(it->first.port));
- StringValue* host(new StringValue(it->first.host));
+ StringValue* url_spec(new StringValue(it->first.spec()));
int latency_integer = static_cast<int>(it->second.latency().
InMilliseconds());
// Watch out for overflow in the above static_cast! Check to see if we went
@@ -188,8 +185,7 @@ Value* Referrer::Serialize() const {
FundamentalValue* rate(new FundamentalValue(
it->second.subresource_use_rate()));
- subresource_list->Append(port);
- subresource_list->Append(host);
+ subresource_list->Append(url_spec);
subresource_list->Append(latency);
subresource_list->Append(rate);
}
diff --git a/chrome/browser/net/referrer.h b/chrome/browser/net/referrer.h
index bef13a1..8b98a5c 100644
--- a/chrome/browser/net/referrer.h
+++ b/chrome/browser/net/referrer.h
@@ -20,6 +20,7 @@
#include "base/basictypes.h"
#include "base/time.h"
#include "base/values.h"
+#include "googleurl/src/gurl.h"
#include "net/base/host_port_pair.h"
namespace chrome_browser_net {
@@ -74,7 +75,7 @@ class ReferrerValue {
// A list of domain names to pre-resolve. The names are the keys to this map,
// and the values indicate the amount of benefit derived from having each name
// around.
-typedef std::map<net::HostPortPair, ReferrerValue> SubresourceMap;
+typedef std::map<GURL, ReferrerValue> SubresourceMap;
//------------------------------------------------------------------------------
// There is one Referrer instance for each hostname that has acted as an HTTP
@@ -91,15 +92,15 @@ class Referrer : public SubresourceMap {
void IncrementUseCount() { ++use_count_; }
int64 use_count() const { return use_count_; }
- // Add the indicated host/port to the list of hosts that are resolved via DNS
- // when the user navigates to this referrer. Note that if the list is long,
- // an entry may be discarded to make room for this insertion.
- void SuggestHost(const net::HostPortPair& hostport);
+ // Add the indicated url to the list that are resolved via DNS when the user
+ // navigates to this referrer. Note that if the list is long, an entry may be
+ // discarded to make room for this insertion.
+ void SuggestHost(const GURL& url);
- // Record additional usefulness of having this host/port name in the list.
+ // Record additional usefulness of having this url in the list.
// Value is expressed as positive latency of amount delta.
void AccrueValue(const base::TimeDelta& delta,
- const net::HostPortPair& hostport);
+ const GURL& url);
// Trim the Referrer, by first diminishing (scaling down) the latency for each
// ReferredValue.