Index: net/proxy/proxy_resolver_js_bindings.cc |
=================================================================== |
--- net/proxy/proxy_resolver_js_bindings.cc (revision 50290) |
+++ net/proxy/proxy_resolver_js_bindings.cc (working copy) |
@@ -6,11 +6,13 @@ |
#include "base/logging.h" |
#include "net/base/address_list.h" |
+#include "net/base/host_cache.h" |
#include "net/base/host_resolver.h" |
#include "net/base/net_errors.h" |
#include "net/base/net_log.h" |
#include "net/base/net_util.h" |
#include "net/base/sys_addrinfo.h" |
+#include "net/proxy/proxy_resolver_request_context.h" |
namespace net { |
namespace { |
@@ -49,28 +51,27 @@ |
// See http://crbug.com/24641 for more details. |
HostResolver::RequestInfo info(host, 80); // Port doesn't matter. |
info.set_address_family(ADDRESS_FAMILY_IPV4); |
- net::AddressList address_list; |
- int result = host_resolver_->Resolve(info, &address_list, NULL, NULL, |
- BoundNetLog()); |
+ AddressList address_list; |
+ int result = DnsResolveHelper(info, &address_list); |
if (result != OK) |
return std::string(); // Failed. |
+ // TODO(eroman): Is this check really needed? Can I remove it? |
if (!address_list.head()) |
return std::string(); |
// There may be multiple results; we will just use the first one. |
// This returns empty string on failure. |
- return net::NetAddressToString(address_list.head()); |
+ return NetAddressToString(address_list.head()); |
} |
// Handler for "dnsResolveEx(host)". Returns empty string on failure. |
virtual std::string DnsResolveEx(const std::string& host) { |
// Do a sync resolve of the hostname. |
HostResolver::RequestInfo info(host, 80); // Port doesn't matter. |
- net::AddressList address_list; |
- int result = host_resolver_->Resolve(info, &address_list, NULL, NULL, |
- BoundNetLog()); |
+ AddressList address_list; |
+ int result = DnsResolveHelper(info, &address_list); |
if (result != OK) |
return std::string(); // Failed. |
@@ -82,7 +83,7 @@ |
while (current_address) { |
if (!address_list_str.empty()) |
address_list_str += ";"; |
- address_list_str += net::NetAddressToString(current_address); |
+ address_list_str += NetAddressToString(current_address); |
current_address = current_address->ai_next; |
} |
@@ -98,6 +99,43 @@ |
} |
private: |
+ // Helper to execute a syncrhonous DNS resolve, using the per-request |
+ // DNS cache if there is one. |
+ int DnsResolveHelper(const HostResolver::RequestInfo& info, |
+ AddressList* address_list) { |
+ HostCache::Key cache_key(info.hostname(), |
+ info.address_family(), |
+ info.host_resolver_flags()); |
+ |
+ HostCache* host_cache = current_request_context() ? |
+ current_request_context()->host_cache : NULL; |
+ |
+ // First try to service this request from the per-request DNS cache. |
+ // (we cache DNS failures much more aggressively within the context |
+ // of a FindProxyForURL() request). |
+ if (host_cache) { |
+ const HostCache::Entry* entry = |
+ host_cache->Lookup(cache_key, base::TimeTicks::Now()); |
+ if (entry) { |
+ if (entry->error == OK) |
+ *address_list = entry->addrlist; |
+ return entry->error; |
+ } |
+ } |
+ |
+ // Otherwise ask the resolver. |
+ int result = host_resolver_->Resolve(info, address_list, NULL, NULL, |
+ BoundNetLog()); |
+ |
+ // Save the result back to the per-request DNS cache. |
+ if (host_cache) { |
+ host_cache->Set(cache_key, result, *address_list, |
+ base::TimeTicks::Now()); |
+ } |
+ |
+ return result; |
+ } |
+ |
scoped_refptr<HostResolver> host_resolver_; |
}; |