summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-15 05:08:42 +0000
committerericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-15 05:08:42 +0000
commit2884a4619edeac1787e2b1d1b57e913f7e442cae (patch)
treef194f30877c49ce17031a29393143039eacfb496 /net
parent202e7a773359b24943d7de0943dd9c7d257ab1cb (diff)
downloadchromium_src-2884a4619edeac1787e2b1d1b57e913f7e442cae.zip
chromium_src-2884a4619edeac1787e2b1d1b57e913f7e442cae.tar.gz
chromium_src-2884a4619edeac1787e2b1d1b57e913f7e442cae.tar.bz2
* Move the global "DnsResolutionObserver" code depended on by DNS prefetcher, into HostResolver. This has the advantage that consumers of DNS no longer have to remember to call "DidFinishDnsResolutionWithStatus()" followed by "DidStartDnsResolution()" in order for the prefetcher to observe the resolution. Instead it just happens automatically, and subscribers register via HostResolver::AddObserver() on a particular resolver instance.
* To accomodate the prefetcher's observer, HostResolver::Resolve() needs an additional "referrer" parameter. This is slightly awkward since "referrer" has nothing to do with the actual resolve request. To simplify plumbing through this and other optional parameters, Resolve() was changed to take a "RequestInfo&" parameter in place of say {hostname, port, flags}. * Added an option to HostResolver::Resolve() for disallowing cached responses (RequestInfo::allow_cached_response). This will be used when you refresh a page, to bypass the host cache. The code to do this has been added to HttpNetworkTransaction, but is commented out pending an appropriate unit-test to verify it. BUG=14056 Review URL: http://codereview.chromium.org/125107 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18371 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/base/client_socket_handle.cc5
-rw-r--r--net/base/client_socket_handle.h8
-rw-r--r--net/base/client_socket_pool.h5
-rw-r--r--net/base/dns_resolution_observer.cc60
-rw-r--r--net/base/dns_resolution_observer.h42
-rw-r--r--net/base/host_resolver.cc115
-rw-r--r--net/base/host_resolver.h80
-rw-r--r--net/base/host_resolver_unittest.cc208
-rw-r--r--net/base/ssl_client_socket_unittest.cc25
-rw-r--r--net/base/ssl_test_util.cc3
-rw-r--r--net/base/tcp_client_socket_pool.cc41
-rw-r--r--net/base/tcp_client_socket_pool.h20
-rw-r--r--net/base/tcp_client_socket_pool_unittest.cc51
-rw-r--r--net/base/tcp_client_socket_unittest.cc3
-rw-r--r--net/base/tcp_pinger_unittest.cc6
-rw-r--r--net/ftp/ftp_network_transaction.cc14
-rw-r--r--net/http/http_network_transaction.cc21
-rw-r--r--net/net.gyp1
-rw-r--r--net/proxy/proxy_resolver_v8.cc13
19 files changed, 478 insertions, 243 deletions
diff --git a/net/base/client_socket_handle.cc b/net/base/client_socket_handle.cc
index 043cefd..adedcd4 100644
--- a/net/base/client_socket_handle.cc
+++ b/net/base/client_socket_handle.cc
@@ -24,15 +24,14 @@ ClientSocketHandle::~ClientSocketHandle() {
}
int ClientSocketHandle::Init(const std::string& group_name,
- const std::string& host,
- int port,
+ const HostResolver::RequestInfo& resolve_info,
int priority,
CompletionCallback* callback) {
ResetInternal(true);
group_name_ = group_name;
user_callback_ = callback;
return pool_->RequestSocket(
- group_name, host, port, priority, this, &callback_);
+ group_name, resolve_info, priority, this, &callback_);
}
void ClientSocketHandle::Reset() {
diff --git a/net/base/client_socket_handle.h b/net/base/client_socket_handle.h
index 5bac2c8..777c752 100644
--- a/net/base/client_socket_handle.h
+++ b/net/base/client_socket_handle.h
@@ -11,6 +11,7 @@
#include "base/scoped_ptr.h"
#include "net/base/client_socket.h"
#include "net/base/completion_callback.h"
+#include "net/base/host_resolver.h"
#include "net/base/load_states.h"
namespace net {
@@ -37,8 +38,8 @@ class ClientSocketHandle {
// connected socket if an existing connected socket was available to reuse,
// otherwise it will be set to a new connected socket. Consumers can then
// call is_reused() to see if the socket was reused. If not reusing an
- // existing socket, ClientSocketPool may need to establish a new
- // connection to the |host| |port| pair.
+ // existing socket, ClientSocketPool may need to establish a new
+ // connection to the |resolve_info.host| |resolve_info.port| pair.
//
// This method returns ERR_IO_PENDING if it cannot complete synchronously, in
// which case the consumer will be notified of completion via |callback|.
@@ -46,8 +47,7 @@ class ClientSocketHandle {
// Init may be called multiple times.
//
int Init(const std::string& group_name,
- const std::string& host,
- int port,
+ const HostResolver::RequestInfo& resolve_info,
int priority,
CompletionCallback* callback);
diff --git a/net/base/client_socket_pool.h b/net/base/client_socket_pool.h
index 6d200c0..86c67b8 100644
--- a/net/base/client_socket_pool.h
+++ b/net/base/client_socket_pool.h
@@ -11,13 +11,13 @@
#include "base/ref_counted.h"
#include "net/base/completion_callback.h"
+#include "net/base/host_resolver.h"
#include "net/base/load_states.h"
namespace net {
class ClientSocket;
class ClientSocketHandle;
-class HostResolver;
// A ClientSocketPool is used to restrict the number of sockets open at a time.
// It also maintains a list of idle persistent sockets.
@@ -47,8 +47,7 @@ class ClientSocketPool : public base::RefCounted<ClientSocketPool> {
// client of completion.
//
virtual int RequestSocket(const std::string& group_name,
- const std::string& host,
- int port,
+ const HostResolver::RequestInfo& resolve_info,
int priority,
ClientSocketHandle* handle,
CompletionCallback* callback) = 0;
diff --git a/net/base/dns_resolution_observer.cc b/net/base/dns_resolution_observer.cc
deleted file mode 100644
index 179a15c..0000000
--- a/net/base/dns_resolution_observer.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2006-2008 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.
-
-// This file supports network stack independent notification of progress
-// towards resolving a hostname.
-
-#include "net/base/dns_resolution_observer.h"
-
-#include <string>
-
-#include "base/logging.h"
-
-namespace net {
-
-static DnsResolutionObserver* dns_resolution_observer;
-
-void AddDnsResolutionObserver(DnsResolutionObserver* new_observer) {
- if (new_observer == dns_resolution_observer)
- return; // Facilitate unit tests that init/teardown repeatedly.
- DCHECK(!dns_resolution_observer);
- dns_resolution_observer = new_observer;
-}
-
-DnsResolutionObserver* RemoveDnsResolutionObserver() {
- // We really need to check that the entire network subsystem is shutting down,
- // and hence no additional calls can even *possibly* still be lingering in the
- // notification path that includes our observer. Until we have a way to
- // really assert that fact, we will outlaw the calling of this function.
- // Darin suggested that the caller use a static initializer for the observer,
- // so that it can safely be destroyed after process termination, and without
- // inducing a memory leak.
- // Bottom line: Don't call this function! You will crash for now.
- CHECK(0);
- DnsResolutionObserver* old_observer = dns_resolution_observer;
- dns_resolution_observer = NULL;
- return old_observer;
-}
-
-// Locking access to dns_resolution_observer is not really critical... but we
-// should test the value of dns_resolution_observer that we use.
-// Worst case, we'll get an "out of date" value... which is no big deal for the
-// DNS prefetching system (the most common (only?) observer).
-void DidStartDnsResolution(const std::string& name, void* context) {
- DnsResolutionObserver* current_observer = dns_resolution_observer;
- if (current_observer)
- current_observer->OnStartResolution(name, context);
-}
-
-void DidFinishDnsResolutionWithStatus(bool was_resolved,
- const GURL& referrer,
- void* context) {
- DnsResolutionObserver* current_observer = dns_resolution_observer;
- if (current_observer) {
- current_observer->OnFinishResolutionWithStatus(was_resolved, referrer,
- context);
- }
-}
-
-} // namspace net
diff --git a/net/base/dns_resolution_observer.h b/net/base/dns_resolution_observer.h
index 9dd9a90..1651308 100644
--- a/net/base/dns_resolution_observer.h
+++ b/net/base/dns_resolution_observer.h
@@ -15,10 +15,13 @@
#include <string>
+#include "net/base/host_resolver.h"
+
class GURL;
namespace net {
+// TODO(eroman): Move this interface to HostResolver::Observer.
class DnsResolutionObserver {
public:
virtual ~DnsResolutionObserver() {}
@@ -26,40 +29,17 @@ class DnsResolutionObserver {
// For each OnStartResolution() notification, there should be a later
// OnFinishResolutionWithStatus() indicating completion of the resolution
// activity.
- // Related pairs of notification will arrive with matching context values.
- // A caller may use the context values to match up these asynchronous calls
+ // Related pairs of notification will arrive with matching id values.
+ // A caller may use the id values to match up these asynchronous calls
// from among a larger call stream.
- // Once a matching pair of notifications has been provided (i.e., a pair with
- // identical context values), and the notification methods (below) have
- // returned, the context values *might* be reused.
- virtual void OnStartResolution(const std::string& host_name,
- void* context) = 0;
- virtual void OnFinishResolutionWithStatus(bool was_resolved,
- const GURL& referrer,
- void* context) = 0;
+ virtual void OnStartResolution(int id,
+ const HostResolver::RequestInfo& info) = 0;
+ virtual void OnFinishResolutionWithStatus(
+ int id,
+ bool was_resolved,
+ const HostResolver::RequestInfo& info) = 0;
};
-
-// Note that *exactly* one observer is currently supported, and any attempt to
-// add a second observer via AddDnsResolutionObserver() before removing the
-// first DnsResolutionObserver will induce a DCHECK() assertion.
-void AddDnsResolutionObserver(DnsResolutionObserver* new_observer);
-
-// Note that the RemoveDnsResolutionObserver() will NOT perform any delete
-// operations, and it is the responsibility of the code that called
-// AddDnsResolutionObserver() to make a corresponding call to
-// RemoveDnsResolutionObserver() and then delete the returned
-// DnsResolutionObserver instance.
-DnsResolutionObserver* RemoveDnsResolutionObserver();
-
-// The following functions are expected to be called only by network stack
-// implementations. This above observer class will relay the notifications
-// to any registered observer.
-void DidStartDnsResolution(const std::string& name,
- void* context);
-void DidFinishDnsResolutionWithStatus(bool was_resolved,
- const GURL& url,
- void* context);
} // namspace net
#endif // NET_BASE_DNS_RESOLUTION_OBSERVER_H_
diff --git a/net/base/host_resolver.cc b/net/base/host_resolver.cc
index 40ed8fd..6dcef85 100644
--- a/net/base/host_resolver.cc
+++ b/net/base/host_resolver.cc
@@ -22,6 +22,7 @@
#include "base/time.h"
#include "base/worker_pool.h"
#include "net/base/address_list.h"
+#include "net/base/dns_resolution_observer.h"
#include "net/base/net_errors.h"
#if defined(OS_LINUX)
@@ -178,8 +179,10 @@ static int ResolveAddrInfo(HostMapper* mapper, const std::string& host,
class HostResolver::Request {
public:
- Request(CompletionCallback* callback, AddressList* addresses, int port)
- : job_(NULL), callback_(callback), addresses_(addresses), port_(port) {}
+ Request(int id, const RequestInfo& info, CompletionCallback* callback,
+ AddressList* addresses)
+ : id_(id), info_(info), job_(NULL), callback_(callback),
+ addresses_(addresses) {}
// Mark the request as cancelled.
void Cancel() {
@@ -200,19 +203,33 @@ class HostResolver::Request {
void OnComplete(int error, const AddressList& addrlist) {
if (error == OK)
- addresses_->SetFrom(addrlist, port_);
+ addresses_->SetFrom(addrlist, port());
callback_->Run(error);
}
int port() const {
- return port_;
+ return info_.port();
}
Job* job() const {
return job_;
}
+ int id() const {
+ return id_;
+ }
+
+ const RequestInfo& info() const {
+ return info_;
+ }
+
private:
+ // Unique ID for this request. Used by observers to identify requests.
+ int id_;
+
+ // The request info that started the request.
+ RequestInfo info_;
+
// The resolve job (running in worker pool) that this request is dependent on.
Job* job_;
@@ -222,9 +239,6 @@ class HostResolver::Request {
// The address list to save result into.
AddressList* addresses_;
- // The desired port number for the socket addresses.
- int port_;
-
DISALLOW_COPY_AND_ASSIGN(Request);
};
@@ -369,7 +383,7 @@ class HostResolver::Job : public base::RefCountedThreadSafe<HostResolver::Job> {
//-----------------------------------------------------------------------------
HostResolver::HostResolver(int max_cache_entries, int cache_duration_ms)
- : cache_(max_cache_entries, cache_duration_ms) {
+ : cache_(max_cache_entries, cache_duration_ms), next_request_id_(0) {
#if defined(OS_WIN)
EnsureWinsockInit();
#endif
@@ -388,40 +402,51 @@ HostResolver::~HostResolver() {
// TODO(eroman): Don't create cache entries for hostnames which are simply IP
// address literals.
-int HostResolver::Resolve(const std::string& hostname, int port,
+int HostResolver::Resolve(const RequestInfo& info,
AddressList* addresses,
CompletionCallback* callback,
Request** out_req) {
+ // Choose a unique ID number for observers to see.
+ int request_id = next_request_id_++;
+
+ // Notify registered observers.
+ NotifyObserversStartRequest(request_id, info);
+
// If we have an unexpired cache entry, use it.
- const HostCache::Entry* cache_entry = cache_.Lookup(
- hostname, base::TimeTicks::Now());
- if (cache_entry) {
- addresses->SetFrom(cache_entry->addrlist, port);
- return OK;
+ if (info.allow_cached_response()) {
+ const HostCache::Entry* cache_entry = cache_.Lookup(
+ info.hostname(), base::TimeTicks::Now());
+ if (cache_entry) {
+ addresses->SetFrom(cache_entry->addrlist, info.port());
+ return OK;
+ }
}
// If no callback was specified, do a synchronous resolution.
if (!callback) {
struct addrinfo* results;
- int error = ResolveAddrInfo(host_mapper, hostname, &results);
+ int error = ResolveAddrInfo(host_mapper, info.hostname(), &results);
// Adopt the address list.
AddressList addrlist;
if (error == OK) {
addrlist.Adopt(results);
- addrlist.SetPort(port);
+ addrlist.SetPort(info.port());
*addresses = addrlist;
}
// Write to cache.
- cache_.Set(hostname, error, addrlist, base::TimeTicks::Now());
+ cache_.Set(info.hostname(), error, addrlist, base::TimeTicks::Now());
+
+ // Notify registered observers.
+ NotifyObserversFinishRequest(request_id, info, error);
return error;
}
// Create a handle for this request, and pass it back to the user if they
// asked for it (out_req != NULL).
- Request* req = new Request(callback, addresses, port);
+ Request* req = new Request(request_id, info, callback, addresses);
if (out_req)
*out_req = req;
@@ -429,14 +454,14 @@ int HostResolver::Resolve(const std::string& hostname, int port,
// calling "getaddrinfo(hostname)" on a worker thread.
scoped_refptr<Job> job;
- // If there is already an outstanding job to resolve |hostname|, use it.
- // This prevents starting concurrent resolves for the same hostname.
- job = FindOutstandingJob(hostname);
+ // If there is already an outstanding job to resolve |info.hostname()|, use
+ // it. This prevents starting concurrent resolves for the same hostname.
+ job = FindOutstandingJob(info.hostname());
if (job) {
job->AddRequest(req);
} else {
// Create a new job for this request.
- job = new Job(this, hostname);
+ job = new Job(this, info.hostname());
job->AddRequest(req);
AddOutstandingJob(job);
// TODO(eroman): Bound the total number of concurrent jobs.
@@ -457,6 +482,20 @@ void HostResolver::CancelRequest(Request* req) {
req->Cancel();
}
+void HostResolver::AddObserver(DnsResolutionObserver* observer) {
+ observers_.push_back(observer);
+}
+
+void HostResolver::RemoveObserver(DnsResolutionObserver* observer) {
+ ObserversList::iterator it =
+ std::find(observers_.begin(), observers_.end(), observer);
+
+ // Observer must exist.
+ DCHECK(it != observers_.end());
+
+ observers_.erase(it);
+}
+
void HostResolver::AddOutstandingJob(Job* job) {
scoped_refptr<Job>& found_job = jobs_[job->host()];
DCHECK(!found_job);
@@ -497,6 +536,10 @@ void HostResolver::OnJobComplete(Job* job,
Request* req = *it;
if (!req->was_cancelled()) {
DCHECK_EQ(job, req->job());
+
+ // Notify registered observers.
+ NotifyObserversFinishRequest(req->id(), req->info(), error);
+
req->OnComplete(error, addrlist);
// Check if the job was cancelled as a result of running the callback.
@@ -509,6 +552,24 @@ void HostResolver::OnJobComplete(Job* job,
cur_completing_job_ = NULL;
}
+void HostResolver::NotifyObserversStartRequest(int request_id,
+ const RequestInfo& info) {
+ for (ObserversList::iterator it = observers_.begin();
+ it != observers_.end(); ++it) {
+ (*it)->OnStartResolution(request_id, info);
+ }
+}
+
+void HostResolver::NotifyObserversFinishRequest(int request_id,
+ const RequestInfo& info,
+ int error) {
+ bool was_resolved = error == OK;
+ for (ObserversList::iterator it = observers_.begin();
+ it != observers_.end(); ++it) {
+ (*it)->OnFinishResolutionWithStatus(request_id, was_resolved, info);
+ }
+}
+
//-----------------------------------------------------------------------------
SingleRequestHostResolver::SingleRequestHostResolver(HostResolver* resolver)
@@ -526,10 +587,9 @@ SingleRequestHostResolver::~SingleRequestHostResolver() {
}
}
-int SingleRequestHostResolver::Resolve(
- const std::string& hostname, int port,
- AddressList* addresses,
- CompletionCallback* callback) {
+int SingleRequestHostResolver::Resolve(const HostResolver::RequestInfo& info,
+ AddressList* addresses,
+ CompletionCallback* callback) {
DCHECK(!cur_request_ && !cur_request_callback_) << "resolver already in use";
HostResolver::Request* request = NULL;
@@ -538,8 +598,7 @@ int SingleRequestHostResolver::Resolve(
// we can clear out |cur_request_*|.
CompletionCallback* transient_callback = callback ? &callback_ : NULL;
- int rv = resolver_->Resolve(
- hostname, port, addresses, transient_callback, &request);
+ int rv = resolver_->Resolve(info, addresses, transient_callback, &request);
if (rv == ERR_IO_PENDING) {
// Cleared in OnResolveCompletion().
diff --git a/net/base/host_resolver.h b/net/base/host_resolver.h
index a67419a..9a7b7b9 100644
--- a/net/base/host_resolver.h
+++ b/net/base/host_resolver.h
@@ -11,6 +11,7 @@
#include "base/basictypes.h"
#include "base/lock.h"
#include "base/ref_counted.h"
+#include "googleurl/src/gurl.h"
#include "net/base/completion_callback.h"
#include "net/base/host_cache.h"
@@ -19,6 +20,7 @@ class MessageLoop;
namespace net {
class AddressList;
+class DnsResolutionObserver;
class HostMapper;
// This class represents the task of resolving hostnames (or IP address
@@ -58,6 +60,46 @@ class HostMapper;
//
class HostResolver {
public:
+ // The parameters for doing a Resolve(). |hostname| and |port| are required,
+ // the rest are optional (and have reasonable defaults).
+ class RequestInfo {
+ public:
+ RequestInfo(const std::string& hostname, int port)
+ : hostname_(hostname),
+ port_(port),
+ allow_cached_response_(true),
+ is_speculative_(false) {}
+
+ const int port() const { return port_; }
+ const std::string& hostname() const { return hostname_; }
+
+ bool allow_cached_response() const { return allow_cached_response_; }
+ void set_allow_cached_response(bool b) { allow_cached_response_ = b; }
+
+ bool is_speculative() const { return is_speculative_; }
+ void set_is_speculative(bool b) { is_speculative_ = b; }
+
+ const GURL& referrer() const { return referrer_; }
+ void set_referrer(const GURL& referrer) { referrer_ = referrer; }
+
+ private:
+ // The hostname to resolve.
+ std::string hostname_;
+
+ // The port number to set in the result's sockaddrs.
+ int port_;
+
+ // Whether it is ok to return a result from the host cache.
+ bool allow_cached_response_;
+
+ // Whether this request was started by the DNS prefetcher.
+ bool is_speculative_;
+
+ // Optional data for consumption by observers. This is the URL of the
+ // page that lead us to the navigation, for DNS prefetcher's benefit.
+ GURL referrer_;
+ };
+
// Creates a HostResolver that caches up to |max_cache_entries| for
// |cache_duration_ms| milliseconds.
//
@@ -74,9 +116,9 @@ class HostResolver {
class Request;
// Resolves the given hostname (or IP address literal), filling out the
- // |addresses| object upon success. The |port| parameter will be set as the
- // sin(6)_port field of the sockaddr_in{6} struct. Returns OK if successful
- // or an error code upon failure.
+ // |addresses| object upon success. The |info.port| parameter will be set as
+ // the sin(6)_port field of the sockaddr_in{6} struct. Returns OK if
+ // successful or an error code upon failure.
//
// When callback is null, the operation completes synchronously.
//
@@ -85,18 +127,26 @@ class HostResolver {
// result code will be passed to the completion callback. If |req| is
// non-NULL, then |*req| will be filled with a handle to the async request.
// This handle is not valid after the request has completed.
- int Resolve(const std::string& hostname, int port,
- AddressList* addresses, CompletionCallback* callback,
- Request** req);
+ int Resolve(const RequestInfo& info, AddressList* addresses,
+ CompletionCallback* callback, Request** req);
// Cancels the specified request. |req| is the handle returned by Resolve().
// After a request is cancelled, its completion callback will not be called.
void CancelRequest(Request* req);
+ // Adds an observer to this resolver. The observer will be notified of the
+ // start and completion of all requests (excluding cancellation). |observer|
+ // must remain valid for the duration of this HostResolver's lifetime.
+ void AddObserver(DnsResolutionObserver* observer);
+
+ // Unregisters an observer previously added by AddObserver().
+ void RemoveObserver(DnsResolutionObserver* observer);
+
private:
class Job;
typedef std::vector<Request*> RequestsList;
typedef base::hash_map<std::string, scoped_refptr<Job> > JobMap;
+ typedef std::vector<DnsResolutionObserver*> ObserversList;
// Adds a job to outstanding jobs list.
void AddOutstandingJob(Job* job);
@@ -110,6 +160,15 @@ class HostResolver {
// Callback for when |job| has completed with |error| and |addrlist|.
void OnJobComplete(Job* job, int error, const AddressList& addrlist);
+ // Notify all obsevers of the start of a resolve request.
+ void NotifyObserversStartRequest(int request_id,
+ const RequestInfo& info);
+
+ // Notify all obsevers of the completion of a resolve request.
+ void NotifyObserversFinishRequest(int request_id,
+ const RequestInfo& info,
+ int error);
+
// Cache of host resolution results.
HostCache cache_;
@@ -120,6 +179,13 @@ class HostResolver {
// HostResolver gets deleted from within the callback).
scoped_refptr<Job> cur_completing_job_;
+ // The observers to notify when a request starts/ends.
+ ObserversList observers_;
+
+ // Monotonically increasing ID number to assign to the next request.
+ // Observers are the only consumers of this ID number.
+ int next_request_id_;
+
DISALLOW_COPY_AND_ASSIGN(HostResolver);
};
@@ -137,7 +203,7 @@ class SingleRequestHostResolver {
// Resolves the given hostname (or IP address literal), filling out the
// |addresses| object upon success. See HostResolver::Resolve() for details.
- int Resolve(const std::string& hostname, int port,
+ int Resolve(const HostResolver::RequestInfo& info,
AddressList* addresses, CompletionCallback* callback);
private:
diff --git a/net/base/host_resolver_unittest.cc b/net/base/host_resolver_unittest.cc
index 090fd5c..393385af 100644
--- a/net/base/host_resolver_unittest.cc
+++ b/net/base/host_resolver_unittest.cc
@@ -18,6 +18,7 @@
#include "base/ref_counted.h"
#include "net/base/address_list.h"
#include "net/base/completion_callback.h"
+#include "net/base/dns_resolution_observer.h"
#include "net/base/host_resolver_unittest.h"
#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -82,12 +83,22 @@ class ResolveRequest {
const std::string& hostname,
int port,
Delegate* delegate)
- : hostname_(hostname), port_(port), resolver_(resolver),
- delegate_(delegate),
+ : info_(hostname, port), resolver_(resolver), delegate_(delegate),
ALLOW_THIS_IN_INITIALIZER_LIST(
callback_(this, &ResolveRequest::OnLookupFinished)) {
// Start the request.
- int err = resolver->Resolve(hostname, port, &addrlist_, &callback_, &req_);
+ int err = resolver->Resolve(info_, &addrlist_, &callback_, &req_);
+ EXPECT_EQ(net::ERR_IO_PENDING, err);
+ }
+
+ ResolveRequest(net::HostResolver* resolver,
+ const net::HostResolver::RequestInfo& info,
+ Delegate* delegate)
+ : info_(info), resolver_(resolver), delegate_(delegate),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ callback_(this, &ResolveRequest::OnLookupFinished)) {
+ // Start the request.
+ int err = resolver->Resolve(info, &addrlist_, &callback_, &req_);
EXPECT_EQ(net::ERR_IO_PENDING, err);
}
@@ -96,11 +107,11 @@ class ResolveRequest {
}
const std::string& hostname() const {
- return hostname_;
+ return info_.hostname();
}
int port() const {
- return port_;
+ return info_.port();
}
int result() const {
@@ -122,8 +133,7 @@ class ResolveRequest {
}
// The request details.
- std::string hostname_;
- int port_;
+ net::HostResolver::RequestInfo info_;
net::HostResolver::Request* req_;
// The result of the resolve.
@@ -168,8 +178,8 @@ TEST_F(HostResolverTest, SynchronousLookup) {
mapper->AddRule("just.testing", "192.168.1.42");
ScopedHostMapper scoped_mapper(mapper.get());
- int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist, NULL,
- NULL);
+ net::HostResolver::RequestInfo info("just.testing", kPortnum);
+ int err = host_resolver.Resolve(info, &adrlist, NULL, NULL);
EXPECT_EQ(net::OK, err);
const struct addrinfo* ainfo = adrlist.head();
@@ -191,8 +201,8 @@ TEST_F(HostResolverTest, AsynchronousLookup) {
mapper->AddRule("just.testing", "192.168.1.42");
ScopedHostMapper scoped_mapper(mapper.get());
- int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist,
- &callback_, NULL);
+ net::HostResolver::RequestInfo info("just.testing", kPortnum);
+ int err = host_resolver.Resolve(info, &adrlist, &callback_, NULL);
EXPECT_EQ(net::ERR_IO_PENDING, err);
MessageLoop::current()->Run();
@@ -219,8 +229,8 @@ TEST_F(HostResolverTest, CanceledAsynchronousLookup) {
net::AddressList adrlist;
const int kPortnum = 80;
- int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist,
- &callback_, NULL);
+ net::HostResolver::RequestInfo info("just.testing", kPortnum);
+ int err = host_resolver.Resolve(info, &adrlist, &callback_, NULL);
EXPECT_EQ(net::ERR_IO_PENDING, err);
// Make sure we will exit the queue even when callback is not called.
@@ -245,7 +255,8 @@ TEST_F(HostResolverTest, NumericIPv4Address) {
net::HostResolver host_resolver;
net::AddressList adrlist;
const int kPortnum = 5555;
- int err = host_resolver.Resolve("127.1.2.3", kPortnum, &adrlist, NULL, NULL);
+ net::HostResolver::RequestInfo info("127.1.2.3", kPortnum);
+ int err = host_resolver.Resolve(info, &adrlist, NULL, NULL);
EXPECT_EQ(net::OK, err);
const struct addrinfo* ainfo = adrlist.head();
@@ -268,8 +279,8 @@ TEST_F(HostResolverTest, NumericIPv6Address) {
net::HostResolver host_resolver;
net::AddressList adrlist;
const int kPortnum = 5555;
- int err = host_resolver.Resolve("2001:db8::1", kPortnum, &adrlist, NULL,
- NULL);
+ net::HostResolver::RequestInfo info("2001:db8::1", kPortnum);
+ int err = host_resolver.Resolve(info, &adrlist, NULL, NULL);
// On computers without IPv6 support, getaddrinfo cannot convert IPv6
// address literals to addresses (getaddrinfo returns EAI_NONAME). So this
// test has to allow host_resolver.Resolve to fail.
@@ -302,7 +313,8 @@ TEST_F(HostResolverTest, EmptyHost) {
net::HostResolver host_resolver;
net::AddressList adrlist;
const int kPortnum = 5555;
- int err = host_resolver.Resolve("", kPortnum, &adrlist, NULL, NULL);
+ net::HostResolver::RequestInfo info("", kPortnum);
+ int err = host_resolver.Resolve(info, &adrlist, NULL, NULL);
EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, err);
}
@@ -457,7 +469,7 @@ class CancelWithinCallbackVerifier : public ResolveRequest::Delegate {
// Start a request (so we can make sure the canceled requests don't
// complete before "finalrequest" finishes.
final_request_.reset(new ResolveRequest(
- resolve->resolver(), "finalrequest", 70, this));
+ resolve->resolver(), "finalrequest", 70, this));
} else if (83 == resolve->port()) {
EXPECT_EQ("a", resolve->hostname());
@@ -618,4 +630,164 @@ TEST_F(HostResolverTest, StartWithinCallback) {
MessageLoop::current()->Run();
}
+// Helper class used by HostResolverTest.BypassCache.
+class BypassCacheVerifier : public ResolveRequest::Delegate {
+ public:
+ BypassCacheVerifier() {}
+
+ virtual void OnCompleted(ResolveRequest* resolve) {
+ EXPECT_EQ("a", resolve->hostname());
+ net::HostResolver* resolver = resolve->resolver();
+
+ if (80 == resolve->port()) {
+ // On completing the first request, start another request for "a".
+ // Since caching is enabled, this should complete synchronously.
+
+ // Note that |junk_callback| shouldn't be used since we are going to
+ // complete synchronously. We can't specify NULL though since that would
+ // mean synchronous mode so we give it a value of 1.
+ net::CompletionCallback* junk_callback =
+ reinterpret_cast<net::CompletionCallback*> (1);
+ net::AddressList addrlist;
+
+ net::HostResolver::RequestInfo info("a", 70);
+ int error = resolver->Resolve(info, &addrlist, junk_callback, NULL);
+ EXPECT_EQ(net::OK, error);
+
+ // Ok good. Now make sure that if we ask to bypass the cache, it can no
+ // longer service the request synchronously.
+ info = net::HostResolver::RequestInfo("a", 71);
+ info.set_allow_cached_response(false);
+ final_request_.reset(new ResolveRequest(resolver, info, this));
+ } else if (71 == resolve->port()) {
+ // Test is done.
+ MessageLoop::current()->Quit();
+ } else {
+ FAIL() << "Unexpected port number";
+ }
+ }
+
+ private:
+ scoped_ptr<ResolveRequest> final_request_;
+ DISALLOW_COPY_AND_ASSIGN(BypassCacheVerifier);
+};
+
+TEST_F(HostResolverTest, BypassCache) {
+ net::HostResolver host_resolver;
+
+ // The class will receive callbacks for when each resolve completes. It
+ // checks that the right things happened.
+ BypassCacheVerifier verifier;
+
+ // Start a request.
+ ResolveRequest req1(&host_resolver, "a", 80, &verifier);
+
+ // |verifier| will send quit message once all the requests have finished.
+ MessageLoop::current()->Run();
+}
+
+bool operator==(const net::HostResolver::RequestInfo& a,
+ const net::HostResolver::RequestInfo& b) {
+ return a.hostname() == b.hostname() &&
+ a.port() == b.port() &&
+ a.allow_cached_response() == b.allow_cached_response() &&
+ a.is_speculative() == b.is_speculative() &&
+ a.referrer() == b.referrer();
+}
+
+// Observer that just makes note of how it was called. The test code can then
+// inspect to make sure it was called with the right parameters.
+class CapturingObserver : public net::DnsResolutionObserver {
+ public:
+ // DnsResolutionObserver methods:
+ virtual void OnStartResolution(int id,
+ const net::HostResolver::RequestInfo& info) {
+ start_log.push_back(StartEntry(id, info));
+ }
+
+ virtual void OnFinishResolutionWithStatus(
+ int id,
+ bool was_resolved,
+ const net::HostResolver::RequestInfo& info) {
+ finish_log.push_back(FinishEntry(id, was_resolved, info));
+ }
+
+ // Tuple (id, info).
+ struct StartEntry {
+ StartEntry(int id, const net::HostResolver::RequestInfo& info)
+ : id(id), info(info) {}
+
+ bool operator==(const StartEntry& other) const {
+ return id == other.id && info == other.info;
+ }
+
+ int id;
+ net::HostResolver::RequestInfo info;
+ };
+
+ // Tuple (id, was_resolved, info).
+ struct FinishEntry {
+ FinishEntry(int id, bool was_resolved,
+ const net::HostResolver::RequestInfo& info)
+ : id(id), was_resolved(was_resolved), info(info) {}
+
+ bool operator==(const FinishEntry& other) const {
+ return id == other.id &&
+ was_resolved == other.was_resolved &&
+ info == other.info;
+ }
+
+ int id;
+ bool was_resolved;
+ net::HostResolver::RequestInfo info;
+ };
+
+ std::vector<StartEntry> start_log;
+ std::vector<FinishEntry> finish_log;
+};
+
+// Test that registering, unregistering, and notifying of observers works.
+TEST_F(HostResolverTest, Observers) {
+ net::HostResolver host_resolver;
+
+ CapturingObserver observer;
+
+ host_resolver.AddObserver(&observer);
+
+ net::AddressList addrlist;
+
+ // Resolve "host1".
+ net::HostResolver::RequestInfo info1("host1", 70);
+ host_resolver.Resolve(info1, &addrlist, NULL, NULL);
+
+ EXPECT_EQ(1U, observer.start_log.size());
+ EXPECT_EQ(1U, observer.finish_log.size());
+ EXPECT_TRUE(
+ observer.start_log[0] == CapturingObserver::StartEntry(0, info1));
+ EXPECT_TRUE(
+ observer.finish_log[0] == CapturingObserver::FinishEntry(0, true, info1));
+
+ // Resolve "host2", setting referrer to "http://foobar.com"
+ net::HostResolver::RequestInfo info2("host2", 70);
+ info2.set_referrer(GURL("http://foobar.com"));
+ host_resolver.Resolve(info2, &addrlist, NULL, NULL);
+
+ EXPECT_EQ(2U, observer.start_log.size());
+ EXPECT_EQ(2U, observer.finish_log.size());
+ EXPECT_TRUE(observer.start_log[1] == CapturingObserver::StartEntry(1, info2));
+ EXPECT_TRUE(observer.finish_log[1] == CapturingObserver::FinishEntry(
+ 1, true, info2));
+
+ // Unregister the observer.
+ host_resolver.RemoveObserver(&observer);
+
+ // Resolve "host3"
+ net::HostResolver::RequestInfo info3("host3", 70);
+ host_resolver.Resolve(info3, &addrlist, NULL, NULL);
+
+ // No effect this time, since observer was removed.
+ EXPECT_EQ(2U, observer.start_log.size());
+ EXPECT_EQ(2U, observer.finish_log.size());
+}
+
} // namespace
diff --git a/net/base/ssl_client_socket_unittest.cc b/net/base/ssl_client_socket_unittest.cc
index ab29cc4..ef308a1 100644
--- a/net/base/ssl_client_socket_unittest.cc
+++ b/net/base/ssl_client_socket_unittest.cc
@@ -76,8 +76,8 @@ TEST_F(SSLClientSocketTest, MAYBE_Connect) {
net::HostResolver resolver;
TestCompletionCallback callback;
- int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort,
- &addr, NULL, NULL);
+ net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
+ int rv = resolver.Resolve(info, &addr, NULL, NULL);
EXPECT_EQ(net::OK, rv);
net::ClientSocket *transport = new net::TCPClientSocket(addr);
@@ -114,8 +114,8 @@ TEST_F(SSLClientSocketTest, MAYBE_ConnectExpired) {
net::HostResolver resolver;
TestCompletionCallback callback;
- int rv = resolver.Resolve(server_.kHostName, server_.kBadHTTPSPort,
- &addr, NULL, NULL);
+ net::HostResolver::RequestInfo info(server_.kHostName, server_.kBadHTTPSPort);
+ int rv = resolver.Resolve(info, &addr, NULL, NULL);
EXPECT_EQ(net::OK, rv);
net::ClientSocket *transport = new net::TCPClientSocket(addr);
@@ -151,8 +151,9 @@ TEST_F(SSLClientSocketTest, MAYBE_ConnectMismatched) {
net::HostResolver resolver;
TestCompletionCallback callback;
- int rv = resolver.Resolve(server_.kMismatchedHostName, server_.kOKHTTPSPort,
- &addr, NULL, NULL);
+ net::HostResolver::RequestInfo info(server_.kMismatchedHostName,
+ server_.kOKHTTPSPort);
+ int rv = resolver.Resolve(info, &addr, NULL, NULL);
EXPECT_EQ(net::OK, rv);
net::ClientSocket *transport = new net::TCPClientSocket(addr);
@@ -193,8 +194,8 @@ TEST_F(SSLClientSocketTest, MAYBE_Read) {
net::HostResolver resolver;
TestCompletionCallback callback;
- int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort,
- &addr, &callback, NULL);
+ net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
+ int rv = resolver.Resolve(info, &addr, &callback, NULL);
EXPECT_EQ(net::ERR_IO_PENDING, rv);
rv = callback.WaitForResult();
@@ -254,8 +255,8 @@ TEST_F(SSLClientSocketTest, MAYBE_Read_SmallChunks) {
net::HostResolver resolver;
TestCompletionCallback callback;
- int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort,
- &addr, NULL, NULL);
+ net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
+ int rv = resolver.Resolve(info, &addr, NULL, NULL);
EXPECT_EQ(net::OK, rv);
net::ClientSocket *transport = new net::TCPClientSocket(addr);
@@ -310,8 +311,8 @@ TEST_F(SSLClientSocketTest, MAYBE_Read_Interrupted) {
net::HostResolver resolver;
TestCompletionCallback callback;
- int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort,
- &addr, NULL, NULL);
+ net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
+ int rv = resolver.Resolve(info, &addr, NULL, NULL);
EXPECT_EQ(net::OK, rv);
net::ClientSocket *transport = new net::TCPClientSocket(addr);
diff --git a/net/base/ssl_test_util.cc b/net/base/ssl_test_util.cc
index cac5d04..f470139 100644
--- a/net/base/ssl_test_util.cc
+++ b/net/base/ssl_test_util.cc
@@ -247,7 +247,8 @@ bool TestServerLauncher::WaitToStart(const std::string& host_name, int port) {
// Otherwise tests can fail if they run faster than Python can start.
net::AddressList addr;
net::HostResolver resolver;
- int rv = resolver.Resolve(host_name, port, &addr, NULL, NULL);
+ net::HostResolver::RequestInfo info(host_name, port);
+ int rv = resolver.Resolve(info, &addr, NULL, NULL);
if (rv != net::OK)
return false;
diff --git a/net/base/tcp_client_socket_pool.cc b/net/base/tcp_client_socket_pool.cc
index 4a52c10..c5e961e 100644
--- a/net/base/tcp_client_socket_pool.cc
+++ b/net/base/tcp_client_socket_pool.cc
@@ -58,11 +58,9 @@ TCPClientSocketPool::ConnectingSocket::~ConnectingSocket() {
}
int TCPClientSocketPool::ConnectingSocket::Connect(
- const std::string& host,
- int port) {
+ const HostResolver::RequestInfo& resolve_info) {
CHECK(!canceled_);
- DidStartDnsResolution(host, this);
- int rv = resolver_.Resolve(host, port, &addresses_, &callback_);
+ int rv = resolver_.Resolve(resolve_info, &addresses_, &callback_);
if (rv != ERR_IO_PENDING)
rv = OnIOCompleteInternal(rv, true /* synchronous */);
return rv;
@@ -186,26 +184,20 @@ void TCPClientSocketPool::InsertRequestIntoQueue(
pending_requests->insert(it, r);
}
-int TCPClientSocketPool::RequestSocket(const std::string& group_name,
- const std::string& host,
- int port,
- int priority,
- ClientSocketHandle* handle,
- CompletionCallback* callback) {
- DCHECK(!host.empty());
+int TCPClientSocketPool::RequestSocket(
+ const std::string& group_name,
+ const HostResolver::RequestInfo& resolve_info,
+ int priority,
+ ClientSocketHandle* handle,
+ CompletionCallback* callback) {
+ DCHECK(!resolve_info.hostname().empty());
DCHECK_GE(priority, 0);
Group& group = group_map_[group_name];
// Can we make another active socket now?
if (group.active_socket_count == max_sockets_per_group_) {
- Request r;
- r.handle = handle;
CHECK(callback);
- r.callback = callback;
- r.priority = priority;
- r.host = host;
- r.port = port;
- r.load_state = LOAD_STATE_IDLE;
+ Request r(handle, callback, priority, resolve_info, LOAD_STATE_IDLE);
InsertRequestIntoQueue(r, &group.pending_requests);
return ERR_IO_PENDING;
}
@@ -234,20 +226,15 @@ int TCPClientSocketPool::RequestSocket(const std::string& group_name,
if (ContainsKey(connecting_socket_map_, handle))
connecting_socket_map_[handle]->Cancel();
- Request r;
- r.handle = handle;
CHECK(callback);
- r.callback = callback;
- r.priority = priority;
- r.host = host;
- r.port = port;
- r.load_state = LOAD_STATE_RESOLVING_HOST;
+ Request r(handle, callback, priority, resolve_info,
+ LOAD_STATE_RESOLVING_HOST);
group_map_[group_name].connecting_requests[handle] = r;
// connecting_socket will delete itself.
ConnectingSocket* connecting_socket =
new ConnectingSocket(group_name, handle, client_socket_factory_, this);
- int rv = connecting_socket->Connect(host, port);
+ int rv = connecting_socket->Connect(resolve_info);
return rv;
}
@@ -419,7 +406,7 @@ void TCPClientSocketPool::DoReleaseSocket(const std::string& group_name,
group.pending_requests.pop_front();
int rv = RequestSocket(
- group_name, r.host, r.port, r.priority, r.handle, r.callback);
+ group_name, r.resolve_info, r.priority, r.handle, r.callback);
if (rv != ERR_IO_PENDING)
r.callback->Run(rv);
return;
diff --git a/net/base/tcp_client_socket_pool.h b/net/base/tcp_client_socket_pool.h
index 82255c5..ad75585 100644
--- a/net/base/tcp_client_socket_pool.h
+++ b/net/base/tcp_client_socket_pool.h
@@ -31,8 +31,7 @@ class TCPClientSocketPool : public ClientSocketPool {
// ClientSocketPool methods:
virtual int RequestSocket(const std::string& group_name,
- const std::string& host,
- int port,
+ const HostResolver::RequestInfo& resolve_info,
int priority,
ClientSocketHandle* handle,
CompletionCallback* callback);
@@ -62,11 +61,22 @@ class TCPClientSocketPool : public ClientSocketPool {
// A Request is allocated per call to RequestSocket that results in
// ERR_IO_PENDING.
struct Request {
+ // HostResolver::RequestInfo has no default constructor, so fudge something.
+ Request() : resolve_info(std::string(), 0) {}
+
+ Request(ClientSocketHandle* handle,
+ CompletionCallback* callback,
+ int priority,
+ const HostResolver::RequestInfo& resolve_info,
+ LoadState load_state)
+ : handle(handle), callback(callback), priority(priority),
+ resolve_info(resolve_info), load_state(load_state) {
+ }
+
ClientSocketHandle* handle;
CompletionCallback* callback;
int priority;
- std::string host;
- int port;
+ HostResolver::RequestInfo resolve_info;
LoadState load_state;
};
@@ -118,7 +128,7 @@ class TCPClientSocketPool : public ClientSocketPool {
// Begins the host resolution and the TCP connect. Returns OK on success
// and ERR_IO_PENDING if it cannot immediately service the request.
// Otherwise, it returns a net error code.
- int Connect(const std::string& host, int port);
+ int Connect(const HostResolver::RequestInfo& resolve_info);
// Called by the TCPClientSocketPool to cancel this ConnectingSocket. Only
// necessary if a ClientSocketHandle is reused.
diff --git a/net/base/tcp_client_socket_pool_unittest.cc b/net/base/tcp_client_socket_pool_unittest.cc
index 54b6330..2d19605 100644
--- a/net/base/tcp_client_socket_pool_unittest.cc
+++ b/net/base/tcp_client_socket_pool_unittest.cc
@@ -232,7 +232,8 @@ class TCPClientSocketPoolTest : public testing::Test {
TEST_F(TCPClientSocketPoolTest, Basic) {
TestCompletionCallback callback;
ClientSocketHandle handle(pool_.get());
- int rv = handle.Init("a", "www.google.com", 80, 0, &callback);
+ HostResolver::RequestInfo info("www.google.com", 80);
+ int rv = handle.Init("a", info, 0, &callback);
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -252,8 +253,8 @@ TEST_F(TCPClientSocketPoolTest, InitHostResolutionFailure) {
host_mapper->AddSimulatedFailure("unresolvable.host.name");
ScopedHostMapper scoped_host_mapper(host_mapper);
TestSocketRequest req(pool_.get(), &request_order_);
- EXPECT_EQ(ERR_IO_PENDING,
- req.handle.Init("a", "unresolvable.host.name", 80, 5, &req));
+ HostResolver::RequestInfo info("unresolvable.host.name", 80);
+ EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req));
EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req.WaitForResult());
}
@@ -261,8 +262,9 @@ TEST_F(TCPClientSocketPoolTest, InitConnectionFailure) {
client_socket_factory_.set_client_socket_type(
MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET);
TestSocketRequest req(pool_.get(), &request_order_);
+ HostResolver::RequestInfo info("unresolvable.host.name", 80);
EXPECT_EQ(ERR_IO_PENDING,
- req.handle.Init("a", "unresolvable.host.name", 80, 5, &req));
+ req.handle.Init("a", info, 5, &req));
EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
}
@@ -275,13 +277,14 @@ TEST_F(TCPClientSocketPoolTest, PendingRequests) {
// Create connections or queue up requests.
// First request finishes asynchronously.
- int rv = reqs[0]->handle.Init("a", "www.google.com", 80, 5, reqs[0].get());
+ HostResolver::RequestInfo info("www.google.com", 80);
+ int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, reqs[0]->WaitForResult());
// Rest of them finish synchronously, since they're in the HostCache.
for (int i = 1; i < kMaxSocketsPerGroup; ++i) {
- rv = reqs[i]->handle.Init("a", "www.google.com", 80, 5, reqs[i].get());
+ rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get());
EXPECT_EQ(OK, rv);
request_order_.push_back(reqs[i].get());
}
@@ -289,8 +292,7 @@ TEST_F(TCPClientSocketPoolTest, PendingRequests) {
// The rest are pending since we've used all active sockets.
for (int i = 0; i < kNumPendingRequests; ++i) {
rv = reqs[kMaxSocketsPerGroup + i]->handle.Init(
- "a", "www.google.com", 80, kPriorities[i],
- reqs[kMaxSocketsPerGroup + i].get());
+ "a", info, kPriorities[i], reqs[kMaxSocketsPerGroup + i].get());
EXPECT_EQ(ERR_IO_PENDING, rv);
}
@@ -336,13 +338,14 @@ TEST_F(TCPClientSocketPoolTest, PendingRequests_NoKeepAlive) {
// Create connections or queue up requests.
// First request finishes asynchronously.
- int rv = reqs[0]->handle.Init("a", "www.google.com", 80, 5, reqs[0].get());
+ HostResolver::RequestInfo info("www.google.com", 80);
+ int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, reqs[0]->WaitForResult());
// Rest of them finish synchronously, since they're in the HostCache.
for (int i = 1; i < kMaxSocketsPerGroup; ++i) {
- rv = reqs[i]->handle.Init("a", "www.google.com", 80, 5, reqs[i].get());
+ rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get());
EXPECT_EQ(OK, rv);
request_order_.push_back(reqs[i].get());
}
@@ -350,7 +353,7 @@ TEST_F(TCPClientSocketPoolTest, PendingRequests_NoKeepAlive) {
// The rest are pending since we've used all active sockets.
for (int i = 0; i < kNumPendingRequests; ++i) {
EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init(
- "a", "www.google.com", 80, 0, reqs[kMaxSocketsPerGroup + i].get()));
+ "a", info, 0, reqs[kMaxSocketsPerGroup + i].get()));
}
// Release any connections until we have no connections.
@@ -379,8 +382,8 @@ TEST_F(TCPClientSocketPoolTest, PendingRequests_NoKeepAlive) {
// ClientSocketPool which will crash if the group was not cleared properly.
TEST_F(TCPClientSocketPoolTest, CancelRequestClearGroup) {
TestSocketRequest req(pool_.get(), &request_order_);
- EXPECT_EQ(ERR_IO_PENDING,
- req.handle.Init("a", "www.google.com", 80, 5, &req));
+ HostResolver::RequestInfo info("www.google.com", 80);
+ EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req));
req.handle.Reset();
PlatformThread::Sleep(100);
@@ -397,10 +400,9 @@ TEST_F(TCPClientSocketPoolTest, TwoRequestsCancelOne) {
TestSocketRequest req(pool_.get(), &request_order_);
TestSocketRequest req2(pool_.get(), &request_order_);
- EXPECT_EQ(ERR_IO_PENDING,
- req.handle.Init("a", "www.google.com", 80, 5, &req));
- EXPECT_EQ(ERR_IO_PENDING,
- req2.handle.Init("a", "www.google.com", 80, 5, &req2));
+ HostResolver::RequestInfo info("www.google.com", 80);
+ EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req));
+ EXPECT_EQ(ERR_IO_PENDING, req2.handle.Init("a", info, 5, &req2));
req.handle.Reset();
@@ -417,14 +419,13 @@ TEST_F(TCPClientSocketPoolTest, ConnectCancelConnect) {
TestCompletionCallback callback;
TestSocketRequest req(pool_.get(), &request_order_);
- EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", "www.google.com", 80, 5, &callback));
+ HostResolver::RequestInfo info("www.google.com", 80);
+ EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", info, 5, &callback));
handle.Reset();
TestCompletionCallback callback2;
- EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", "www.google.com", 80, 5, &callback2));
+ EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", info, 5, &callback2));
// At this point, handle has two ConnectingSockets out for it. Due to the
// host cache, the host resolution for both will return in the same loop of
@@ -449,15 +450,16 @@ TEST_F(TCPClientSocketPoolTest, CancelRequest) {
reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
// Create connections or queue up requests.
+ HostResolver::RequestInfo info("www.google.com", 80);
// First request finishes asynchronously.
- int rv = reqs[0]->handle.Init("a", "www.google.com", 80, 5, reqs[0].get());
+ int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, reqs[0]->WaitForResult());
// Rest of them finish synchronously, since they're in the HostCache.
for (int i = 1; i < kMaxSocketsPerGroup; ++i) {
- rv = reqs[i]->handle.Init("a", "www.google.com", 80, 5, reqs[i].get());
+ rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get());
EXPECT_EQ(OK, rv);
request_order_.push_back(reqs[i].get());
}
@@ -465,8 +467,7 @@ TEST_F(TCPClientSocketPoolTest, CancelRequest) {
// The rest are pending since we've used all active sockets.
for (int i = 0; i < kNumPendingRequests; ++i) {
EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init(
- "a", "www.google.com", 80, kPriorities[i],
- reqs[kMaxSocketsPerGroup + i].get()));
+ "a", info, kPriorities[i], reqs[kMaxSocketsPerGroup + i].get()));
}
// Cancel a request.
diff --git a/net/base/tcp_client_socket_unittest.cc b/net/base/tcp_client_socket_unittest.cc
index fe37c71..21f524e 100644
--- a/net/base/tcp_client_socket_unittest.cc
+++ b/net/base/tcp_client_socket_unittest.cc
@@ -87,7 +87,8 @@ void TCPClientSocketTest::SetUp() {
AddressList addr;
HostResolver resolver;
- int rv = resolver.Resolve("localhost", listen_port_, &addr, NULL, NULL);
+ HostResolver::RequestInfo info("localhost", listen_port_);
+ int rv = resolver.Resolve(info, &addr, NULL, NULL);
CHECK(rv == OK);
sock_.reset(new TCPClientSocket(addr));
}
diff --git a/net/base/tcp_pinger_unittest.cc b/net/base/tcp_pinger_unittest.cc
index edf29a5..d09f42a 100644
--- a/net/base/tcp_pinger_unittest.cc
+++ b/net/base/tcp_pinger_unittest.cc
@@ -67,7 +67,8 @@ TEST_F(TCPPingerTest, Ping) {
net::AddressList addr;
net::HostResolver resolver;
- int rv = resolver.Resolve("localhost", listen_port_, &addr, NULL, NULL);
+ net::HostResolver::RequestInfo info("localhost", listen_port_);
+ int rv = resolver.Resolve(info, &addr, NULL, NULL);
EXPECT_EQ(rv, net::OK);
net::TCPPinger pinger(addr);
@@ -82,7 +83,8 @@ TEST_F(TCPPingerTest, PingFail) {
// "Kill" "server"
listen_sock_ = NULL;
- int rv = resolver.Resolve("localhost", listen_port_, &addr, NULL, NULL);
+ net::HostResolver::RequestInfo info("localhost", listen_port_);
+ int rv = resolver.Resolve(info, &addr, NULL, NULL);
EXPECT_EQ(rv, net::OK);
net::TCPPinger pinger(addr);
diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc
index 87f9217..18bd808 100644
--- a/net/ftp/ftp_network_transaction.cc
+++ b/net/ftp/ftp_network_transaction.cc
@@ -339,13 +339,13 @@ int FtpNetworkTransaction::DoCtrlResolveHost() {
host = request_->url.host();
port = request_->url.EffectiveIntPort();
- DidStartDnsResolution(host, this);
- return resolver_.Resolve(host, port, &addresses_, &io_callback_);
+ HostResolver::RequestInfo info(host, port);
+ // No known referrer.
+ return resolver_.Resolve(info, &addresses_, &io_callback_);
}
int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) {
bool ok = (result == OK);
- DidFinishDnsResolutionWithStatus(ok, GURL(), this);
if (ok) {
next_state_ = STATE_CTRL_CONNECT;
return result;
@@ -832,14 +832,14 @@ int FtpNetworkTransaction::DoDataResolveHost() {
next_state_ = STATE_DATA_RESOLVE_HOST_COMPLETE;
- DidStartDnsResolution(data_connection_ip_, this);
- return resolver_.Resolve(data_connection_ip_, data_connection_port_,
- &addresses_, &io_callback_);
+ HostResolver::RequestInfo info(data_connection_ip_,
+ data_connection_port_);
+ // No known referrer.
+ return resolver_.Resolve(info, &addresses_, &io_callback_);
}
int FtpNetworkTransaction::DoDataResolveHostComplete(int result) {
bool ok = (result == OK);
- DidFinishDnsResolutionWithStatus(ok, GURL(), this);
if (ok) {
next_state_ = STATE_DATA_CONNECT;
return result;
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 4fbd5cb..d5cd81f 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -570,7 +570,26 @@ int HttpNetworkTransaction::DoInitConnection() {
connection_group.append(request_->url.GetOrigin().spec());
DCHECK(!connection_group.empty());
- int rv = connection_.Init(connection_group, host, port, request_->priority,
+
+ HostResolver::RequestInfo resolve_info(host, port);
+
+ // The referrer is used by the DNS prefetch system to corellate resolutions
+ // with the page that triggered them. It doesn't impact the actual addresses
+ // that we resolve to.
+ resolve_info.set_referrer(request_->referrer);
+
+// TODO(eroman): Enable this!
+// Needs some unit-tests before turning on.
+// http://crbug.com/13163
+#if 0
+ // If the user is refreshing the page, bypass the host cache.
+ if (request_->load_flags & LOAD_BYPASS_CACHE ||
+ request_->load_flags & LOAD_DISABLE_CACHE) {
+ resolve_info.allow_cached_response = false;
+ }
+#endif
+
+ int rv = connection_.Init(connection_group, resolve_info, request_->priority,
&io_callback_);
return rv;
}
diff --git a/net/net.gyp b/net/net.gyp
index c6c92b5..d187781 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -61,7 +61,6 @@
'base/data_url.h',
'base/directory_lister.cc',
'base/directory_lister.h',
- 'base/dns_resolution_observer.cc',
'base/dns_resolution_observer.h',
'base/effective_tld_names.cc',
'base/effective_tld_names.dat',
diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc
index 38e0a83..ad4f1eb6 100644
--- a/net/proxy/proxy_resolver_v8.cc
+++ b/net/proxy/proxy_resolver_v8.cc
@@ -70,15 +70,16 @@ class SyncHostResolverBridge
// Run the resolve on host_resolver_loop, and wait for result.
int Resolve(const std::string& hostname, net::AddressList* addresses) {
- int kPort = 80; // Doesn't matter.
+ // Port number doesn't matter.
+ HostResolver::RequestInfo info(hostname, 80);
// Hack for tests -- run synchronously on current thread.
if (!host_resolver_loop_)
- return host_resolver_->Resolve(hostname, kPort, addresses, NULL, NULL);
+ return host_resolver_->Resolve(info, addresses, NULL, NULL);
// Otherwise start an async resolve on the resolver's thread.
host_resolver_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
- &SyncHostResolverBridge::StartResolve, hostname, kPort, addresses));
+ &SyncHostResolverBridge::StartResolve, info, addresses));
// Wait for the resolve to complete in the resolver's thread.
event_.Wait();
@@ -87,12 +88,10 @@ class SyncHostResolverBridge
private:
// Called on host_resolver_loop_.
- void StartResolve(const std::string& hostname,
- int port,
+ void StartResolve(const HostResolver::RequestInfo& info,
net::AddressList* addresses) {
DCHECK_EQ(host_resolver_loop_, MessageLoop::current());
- int error = host_resolver_->Resolve(
- hostname, port, addresses, &callback_, NULL);
+ int error = host_resolver_->Resolve(info, addresses, &callback_, NULL);
if (error != ERR_IO_PENDING)
OnResolveCompletion(error); // Completed synchronously.
}