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 |