| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/proxy/proxy_resolver_js_bindings.h" | 5 #include "net/proxy/proxy_resolver_js_bindings.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "net/base/address_list.h" | 8 #include "net/base/address_list.h" |
| 9 #include "net/base/host_cache.h" |
| 9 #include "net/base/host_resolver.h" | 10 #include "net/base/host_resolver.h" |
| 10 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
| 11 #include "net/base/net_log.h" | 12 #include "net/base/net_log.h" |
| 12 #include "net/base/net_util.h" | 13 #include "net/base/net_util.h" |
| 13 #include "net/base/sys_addrinfo.h" | 14 #include "net/base/sys_addrinfo.h" |
| 15 #include "net/proxy/proxy_resolver_request_context.h" |
| 14 | 16 |
| 15 namespace net { | 17 namespace net { |
| 16 namespace { | 18 namespace { |
| 17 | 19 |
| 18 // ProxyResolverJSBindings implementation. | 20 // ProxyResolverJSBindings implementation. |
| 19 class DefaultJSBindings : public ProxyResolverJSBindings { | 21 class DefaultJSBindings : public ProxyResolverJSBindings { |
| 20 public: | 22 public: |
| 21 explicit DefaultJSBindings(HostResolver* host_resolver) | 23 explicit DefaultJSBindings(HostResolver* host_resolver) |
| 22 : host_resolver_(host_resolver) {} | 24 : host_resolver_(host_resolver) {} |
| 23 | 25 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 42 // Handler for "dnsResolve(host)". Returns empty string on failure. | 44 // Handler for "dnsResolve(host)". Returns empty string on failure. |
| 43 virtual std::string DnsResolve(const std::string& host) { | 45 virtual std::string DnsResolve(const std::string& host) { |
| 44 // Do a sync resolve of the hostname. | 46 // Do a sync resolve of the hostname. |
| 45 // Disable IPv6 results. We do this because the PAC specification isn't | 47 // Disable IPv6 results. We do this because the PAC specification isn't |
| 46 // really IPv6 friendly, and Internet Explorer also restricts to IPv4. | 48 // really IPv6 friendly, and Internet Explorer also restricts to IPv4. |
| 47 // Consequently a lot of existing PAC scripts assume they will only get | 49 // Consequently a lot of existing PAC scripts assume they will only get |
| 48 // IPv4 results, and will misbehave if they get an IPv6 result. | 50 // IPv4 results, and will misbehave if they get an IPv6 result. |
| 49 // See http://crbug.com/24641 for more details. | 51 // See http://crbug.com/24641 for more details. |
| 50 HostResolver::RequestInfo info(host, 80); // Port doesn't matter. | 52 HostResolver::RequestInfo info(host, 80); // Port doesn't matter. |
| 51 info.set_address_family(ADDRESS_FAMILY_IPV4); | 53 info.set_address_family(ADDRESS_FAMILY_IPV4); |
| 52 net::AddressList address_list; | 54 AddressList address_list; |
| 53 int result = host_resolver_->Resolve(info, &address_list, NULL, NULL, | |
| 54 BoundNetLog()); | |
| 55 | 55 |
| 56 int result = DnsResolveHelper(info, &address_list); |
| 56 if (result != OK) | 57 if (result != OK) |
| 57 return std::string(); // Failed. | 58 return std::string(); // Failed. |
| 58 | 59 |
| 60 // TODO(eroman): Is this check really needed? Can I remove it? |
| 59 if (!address_list.head()) | 61 if (!address_list.head()) |
| 60 return std::string(); | 62 return std::string(); |
| 61 | 63 |
| 62 // There may be multiple results; we will just use the first one. | 64 // There may be multiple results; we will just use the first one. |
| 63 // This returns empty string on failure. | 65 // This returns empty string on failure. |
| 64 return net::NetAddressToString(address_list.head()); | 66 return NetAddressToString(address_list.head()); |
| 65 } | 67 } |
| 66 | 68 |
| 67 // Handler for "dnsResolveEx(host)". Returns empty string on failure. | 69 // Handler for "dnsResolveEx(host)". Returns empty string on failure. |
| 68 virtual std::string DnsResolveEx(const std::string& host) { | 70 virtual std::string DnsResolveEx(const std::string& host) { |
| 69 // Do a sync resolve of the hostname. | 71 // Do a sync resolve of the hostname. |
| 70 HostResolver::RequestInfo info(host, 80); // Port doesn't matter. | 72 HostResolver::RequestInfo info(host, 80); // Port doesn't matter. |
| 71 net::AddressList address_list; | 73 AddressList address_list; |
| 72 int result = host_resolver_->Resolve(info, &address_list, NULL, NULL, | 74 int result = DnsResolveHelper(info, &address_list); |
| 73 BoundNetLog()); | |
| 74 | 75 |
| 75 if (result != OK) | 76 if (result != OK) |
| 76 return std::string(); // Failed. | 77 return std::string(); // Failed. |
| 77 | 78 |
| 78 // Stringify all of the addresses in the address list, separated | 79 // Stringify all of the addresses in the address list, separated |
| 79 // by semicolons. | 80 // by semicolons. |
| 80 std::string address_list_str; | 81 std::string address_list_str; |
| 81 const struct addrinfo* current_address = address_list.head(); | 82 const struct addrinfo* current_address = address_list.head(); |
| 82 while (current_address) { | 83 while (current_address) { |
| 83 if (!address_list_str.empty()) | 84 if (!address_list_str.empty()) |
| 84 address_list_str += ";"; | 85 address_list_str += ";"; |
| 85 address_list_str += net::NetAddressToString(current_address); | 86 address_list_str += NetAddressToString(current_address); |
| 86 current_address = current_address->ai_next; | 87 current_address = current_address->ai_next; |
| 87 } | 88 } |
| 88 | 89 |
| 89 return address_list_str; | 90 return address_list_str; |
| 90 } | 91 } |
| 91 | 92 |
| 92 // Handler for when an error is encountered. |line_number| may be -1. | 93 // Handler for when an error is encountered. |line_number| may be -1. |
| 93 virtual void OnError(int line_number, const std::string& message) { | 94 virtual void OnError(int line_number, const std::string& message) { |
| 94 if (line_number == -1) | 95 if (line_number == -1) |
| 95 LOG(INFO) << "PAC-error: " << message; | 96 LOG(INFO) << "PAC-error: " << message; |
| 96 else | 97 else |
| 97 LOG(INFO) << "PAC-error: " << "line: " << line_number << ": " << message; | 98 LOG(INFO) << "PAC-error: " << "line: " << line_number << ": " << message; |
| 98 } | 99 } |
| 99 | 100 |
| 100 private: | 101 private: |
| 102 // Helper to execute a syncrhonous DNS resolve, using the per-request |
| 103 // DNS cache if there is one. |
| 104 int DnsResolveHelper(const HostResolver::RequestInfo& info, |
| 105 AddressList* address_list) { |
| 106 HostCache::Key cache_key(info.hostname(), |
| 107 info.address_family(), |
| 108 info.host_resolver_flags()); |
| 109 |
| 110 HostCache* host_cache = current_request_context() ? |
| 111 current_request_context()->host_cache : NULL; |
| 112 |
| 113 // First try to service this request from the per-request DNS cache. |
| 114 // (we cache DNS failures much more aggressively within the context |
| 115 // of a FindProxyForURL() request). |
| 116 if (host_cache) { |
| 117 const HostCache::Entry* entry = |
| 118 host_cache->Lookup(cache_key, base::TimeTicks::Now()); |
| 119 if (entry) { |
| 120 if (entry->error == OK) |
| 121 *address_list = entry->addrlist; |
| 122 return entry->error; |
| 123 } |
| 124 } |
| 125 |
| 126 // Otherwise ask the resolver. |
| 127 int result = host_resolver_->Resolve(info, address_list, NULL, NULL, |
| 128 BoundNetLog()); |
| 129 |
| 130 // Save the result back to the per-request DNS cache. |
| 131 if (host_cache) { |
| 132 host_cache->Set(cache_key, result, *address_list, |
| 133 base::TimeTicks::Now()); |
| 134 } |
| 135 |
| 136 return result; |
| 137 } |
| 138 |
| 101 scoped_refptr<HostResolver> host_resolver_; | 139 scoped_refptr<HostResolver> host_resolver_; |
| 102 }; | 140 }; |
| 103 | 141 |
| 104 } // namespace | 142 } // namespace |
| 105 | 143 |
| 106 // static | 144 // static |
| 107 ProxyResolverJSBindings* ProxyResolverJSBindings::CreateDefault( | 145 ProxyResolverJSBindings* ProxyResolverJSBindings::CreateDefault( |
| 108 HostResolver* host_resolver) { | 146 HostResolver* host_resolver) { |
| 109 return new DefaultJSBindings(host_resolver); | 147 return new DefaultJSBindings(host_resolver); |
| 110 } | 148 } |
| 111 | 149 |
| 112 } // namespace net | 150 } // namespace net |
| OLD | NEW |