diff options
author | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-22 18:56:12 +0000 |
---|---|---|
committer | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-22 18:56:12 +0000 |
commit | 59872eb99d936134542a0afef965bdd84dfcf7dc (patch) | |
tree | 57ce5940c58945becc91d4ea4069912cb64d33c5 /net/proxy/proxy_resolver_js_bindings.cc | |
parent | 715a5d7dd8e1b17d428d79ce9309fd0fb554a987 (diff) | |
download | chromium_src-59872eb99d936134542a0afef965bdd84dfcf7dc.zip chromium_src-59872eb99d936134542a0afef965bdd84dfcf7dc.tar.gz chromium_src-59872eb99d936134542a0afef965bdd84dfcf7dc.tar.bz2 |
Add an additional per-request DNS cache when executing FindProxyForURL() from a PAC script.
This mini-cache is more aggressive in caching negative resolutions, to avoid performance problems with PAC scripts that do lots of serial DNS resolves.
This is necessary now that we no longer globally cache DNS resolve failures to avoid performance regressions.
BUG=46821
Review URL: http://codereview.chromium.org/2833021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50495 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/proxy/proxy_resolver_js_bindings.cc')
-rw-r--r-- | net/proxy/proxy_resolver_js_bindings.cc | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/net/proxy/proxy_resolver_js_bindings.cc b/net/proxy/proxy_resolver_js_bindings.cc index 4703f2e..347b953 100644 --- a/net/proxy/proxy_resolver_js_bindings.cc +++ b/net/proxy/proxy_resolver_js_bindings.cc @@ -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 @@ class DefaultJSBindings : public ProxyResolverJSBindings { // 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 @@ class DefaultJSBindings : public ProxyResolverJSBindings { 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 @@ class DefaultJSBindings : public ProxyResolverJSBindings { } 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_; }; |