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 "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "base/values.h" |
9 #include "net/base/address_list.h" | 10 #include "net/base/address_list.h" |
10 #include "net/base/host_cache.h" | 11 #include "net/base/host_cache.h" |
11 #include "net/base/host_resolver.h" | 12 #include "net/base/host_resolver.h" |
12 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
13 #include "net/base/net_log.h" | 14 #include "net/base/net_log.h" |
14 #include "net/base/net_util.h" | 15 #include "net/base/net_util.h" |
15 #include "net/base/sys_addrinfo.h" | 16 #include "net/base/sys_addrinfo.h" |
16 #include "net/proxy/proxy_resolver_request_context.h" | 17 #include "net/proxy/proxy_resolver_request_context.h" |
17 | 18 |
18 namespace net { | 19 namespace net { |
| 20 |
19 namespace { | 21 namespace { |
20 | 22 |
| 23 // Event parameters for a PAC error message (line number + message). |
| 24 class ErrorNetlogParams : public NetLog::EventParameters { |
| 25 public: |
| 26 ErrorNetlogParams(int line_number, |
| 27 const string16& message) |
| 28 : line_number_(line_number), |
| 29 message_(message) { |
| 30 } |
| 31 |
| 32 virtual Value* ToValue() const { |
| 33 DictionaryValue* dict = new DictionaryValue(); |
| 34 dict->SetInteger(L"line_number", line_number_); |
| 35 dict->SetStringFromUTF16(L"message", message_); |
| 36 return dict; |
| 37 } |
| 38 |
| 39 private: |
| 40 const int line_number_; |
| 41 const string16 message_; |
| 42 |
| 43 DISALLOW_COPY_AND_ASSIGN(ErrorNetlogParams); |
| 44 }; |
| 45 |
| 46 // Event parameters for a PAC alert(). |
| 47 class AlertNetlogParams : public NetLog::EventParameters { |
| 48 public: |
| 49 explicit AlertNetlogParams(const string16& message) : message_(message) { |
| 50 } |
| 51 |
| 52 virtual Value* ToValue() const { |
| 53 DictionaryValue* dict = new DictionaryValue(); |
| 54 dict->SetStringFromUTF16(L"message", message_); |
| 55 return dict; |
| 56 } |
| 57 |
| 58 private: |
| 59 const string16 message_; |
| 60 |
| 61 DISALLOW_COPY_AND_ASSIGN(AlertNetlogParams); |
| 62 }; |
| 63 |
21 // ProxyResolverJSBindings implementation. | 64 // ProxyResolverJSBindings implementation. |
22 class DefaultJSBindings : public ProxyResolverJSBindings { | 65 class DefaultJSBindings : public ProxyResolverJSBindings { |
23 public: | 66 public: |
24 explicit DefaultJSBindings(HostResolver* host_resolver) | 67 DefaultJSBindings(HostResolver* host_resolver, NetLog* net_log) |
25 : host_resolver_(host_resolver) {} | 68 : host_resolver_(host_resolver), |
| 69 net_log_(net_log) { |
| 70 } |
26 | 71 |
27 // Handler for "alert(message)". | 72 // Handler for "alert(message)". |
28 virtual void Alert(const string16& message) { | 73 virtual void Alert(const string16& message) { |
29 LOG(INFO) << "PAC-alert: " << message; | 74 LOG(INFO) << "PAC-alert: " << message; |
| 75 |
| 76 // Send to the NetLog. |
| 77 LogEventToCurrentRequestAndGlobally(NetLog::TYPE_PAC_JAVASCRIPT_ALERT, |
| 78 new AlertNetlogParams(message)); |
30 } | 79 } |
31 | 80 |
32 // Handler for "myIpAddress()". | 81 // Handler for "myIpAddress()". |
33 // TODO(eroman): Perhaps enumerate the interfaces directly, using | 82 // TODO(eroman): Perhaps enumerate the interfaces directly, using |
34 // getifaddrs(). | 83 // getifaddrs(). |
35 virtual bool MyIpAddress(std::string* first_ip_address) { | 84 virtual bool MyIpAddress(std::string* first_ip_address) { |
36 std::string my_hostname = GetHostName(); | 85 LogEventToCurrentRequest(NetLog::PHASE_BEGIN, |
37 if (my_hostname.empty()) | 86 NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS, |
38 return false; | 87 NULL); |
39 return DnsResolve(my_hostname, first_ip_address); | 88 |
| 89 bool ok = MyIpAddressImpl(first_ip_address); |
| 90 |
| 91 LogEventToCurrentRequest(NetLog::PHASE_END, |
| 92 NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS, |
| 93 NULL); |
| 94 return ok; |
40 } | 95 } |
41 | 96 |
42 // Handler for "myIpAddressEx()". | 97 // Handler for "myIpAddressEx()". |
43 virtual bool MyIpAddressEx(std::string* ip_address_list) { | 98 virtual bool MyIpAddressEx(std::string* ip_address_list) { |
44 std::string my_hostname = GetHostName(); | 99 LogEventToCurrentRequest(NetLog::PHASE_BEGIN, |
45 if (my_hostname.empty()) | 100 NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS_EX, |
46 return false; | 101 NULL); |
47 return DnsResolveEx(my_hostname, ip_address_list); | 102 |
| 103 bool ok = MyIpAddressExImpl(ip_address_list); |
| 104 |
| 105 LogEventToCurrentRequest(NetLog::PHASE_END, |
| 106 NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS_EX, |
| 107 NULL); |
| 108 return ok; |
48 } | 109 } |
49 | 110 |
50 // Handler for "dnsResolve(host)". | 111 // Handler for "dnsResolve(host)". |
51 virtual bool DnsResolve(const std::string& host, | 112 virtual bool DnsResolve(const std::string& host, |
52 std::string* first_ip_address) { | 113 std::string* first_ip_address) { |
| 114 LogEventToCurrentRequest(NetLog::PHASE_BEGIN, |
| 115 NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE, |
| 116 NULL); |
| 117 |
| 118 bool ok = DnsResolveImpl(host, first_ip_address); |
| 119 |
| 120 LogEventToCurrentRequest(NetLog::PHASE_END, |
| 121 NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE, |
| 122 NULL); |
| 123 return ok; |
| 124 } |
| 125 |
| 126 // Handler for "dnsResolveEx(host)". |
| 127 virtual bool DnsResolveEx(const std::string& host, |
| 128 std::string* ip_address_list) { |
| 129 LogEventToCurrentRequest(NetLog::PHASE_BEGIN, |
| 130 NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE_EX, |
| 131 NULL); |
| 132 |
| 133 bool ok = DnsResolveExImpl(host, ip_address_list); |
| 134 |
| 135 LogEventToCurrentRequest(NetLog::PHASE_END, |
| 136 NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE_EX, |
| 137 NULL); |
| 138 return ok; |
| 139 } |
| 140 |
| 141 // Handler for when an error is encountered. |line_number| may be -1. |
| 142 virtual void OnError(int line_number, const string16& message) { |
| 143 // Send to the chrome log. |
| 144 if (line_number == -1) |
| 145 LOG(INFO) << "PAC-error: " << message; |
| 146 else |
| 147 LOG(INFO) << "PAC-error: " << "line: " << line_number << ": " << message; |
| 148 |
| 149 // Send the error to the NetLog. |
| 150 LogEventToCurrentRequestAndGlobally( |
| 151 NetLog::TYPE_PAC_JAVASCRIPT_ERROR, |
| 152 new ErrorNetlogParams(line_number, message)); |
| 153 } |
| 154 |
| 155 virtual void Shutdown() { |
| 156 host_resolver_->Shutdown(); |
| 157 } |
| 158 |
| 159 private: |
| 160 bool MyIpAddressImpl(std::string* first_ip_address) { |
| 161 std::string my_hostname = GetHostName(); |
| 162 if (my_hostname.empty()) |
| 163 return false; |
| 164 return DnsResolveImpl(my_hostname, first_ip_address); |
| 165 } |
| 166 |
| 167 bool MyIpAddressExImpl(std::string* ip_address_list) { |
| 168 std::string my_hostname = GetHostName(); |
| 169 if (my_hostname.empty()) |
| 170 return false; |
| 171 return DnsResolveExImpl(my_hostname, ip_address_list); |
| 172 } |
| 173 |
| 174 bool DnsResolveImpl(const std::string& host, |
| 175 std::string* first_ip_address) { |
53 // Do a sync resolve of the hostname. | 176 // Do a sync resolve of the hostname. |
54 // Disable IPv6 results. We do this because the PAC specification isn't | 177 // Disable IPv6 results. We do this because the PAC specification isn't |
55 // really IPv6 friendly, and Internet Explorer also restricts to IPv4. | 178 // really IPv6 friendly, and Internet Explorer also restricts to IPv4. |
56 // Consequently a lot of existing PAC scripts assume they will only get | 179 // Consequently a lot of existing PAC scripts assume they will only get |
57 // IPv4 results, and will misbehave if they get an IPv6 result. | 180 // IPv4 results, and will misbehave if they get an IPv6 result. |
58 // See http://crbug.com/24641 for more details. | 181 // See http://crbug.com/24641 for more details. |
59 HostResolver::RequestInfo info(host, 80); // Port doesn't matter. | 182 HostResolver::RequestInfo info(host, 80); // Port doesn't matter. |
60 info.set_address_family(ADDRESS_FAMILY_IPV4); | 183 info.set_address_family(ADDRESS_FAMILY_IPV4); |
61 AddressList address_list; | 184 AddressList address_list; |
62 | 185 |
63 int result = DnsResolveHelper(info, &address_list); | 186 int result = DnsResolveHelper(info, &address_list); |
64 if (result != OK) | 187 if (result != OK) |
65 return false; | 188 return false; |
66 | 189 |
67 // There may be multiple results; we will just use the first one. | 190 // There may be multiple results; we will just use the first one. |
68 // This returns empty string on failure. | 191 // This returns empty string on failure. |
69 *first_ip_address = net::NetAddressToString(address_list.head()); | 192 *first_ip_address = net::NetAddressToString(address_list.head()); |
70 if (first_ip_address->empty()) | 193 if (first_ip_address->empty()) |
71 return false; | 194 return false; |
72 | 195 |
73 return true; | 196 return true; |
74 } | 197 } |
75 | 198 |
76 // Handler for "dnsResolveEx(host)". | 199 bool DnsResolveExImpl(const std::string& host, |
77 virtual bool DnsResolveEx(const std::string& host, | 200 std::string* ip_address_list) { |
78 std::string* ip_address_list) { | |
79 // Do a sync resolve of the hostname. | 201 // Do a sync resolve of the hostname. |
80 HostResolver::RequestInfo info(host, 80); // Port doesn't matter. | 202 HostResolver::RequestInfo info(host, 80); // Port doesn't matter. |
81 AddressList address_list; | 203 AddressList address_list; |
82 int result = DnsResolveHelper(info, &address_list); | 204 int result = DnsResolveHelper(info, &address_list); |
83 | 205 |
84 if (result != OK) | 206 if (result != OK) |
85 return false; | 207 return false; |
86 | 208 |
87 // Stringify all of the addresses in the address list, separated | 209 // Stringify all of the addresses in the address list, separated |
88 // by semicolons. | 210 // by semicolons. |
89 std::string address_list_str; | 211 std::string address_list_str; |
90 const struct addrinfo* current_address = address_list.head(); | 212 const struct addrinfo* current_address = address_list.head(); |
91 while (current_address) { | 213 while (current_address) { |
92 if (!address_list_str.empty()) | 214 if (!address_list_str.empty()) |
93 address_list_str += ";"; | 215 address_list_str += ";"; |
94 const std::string address_string = NetAddressToString(current_address); | 216 const std::string address_string = NetAddressToString(current_address); |
95 if (address_string.empty()) | 217 if (address_string.empty()) |
96 return false; | 218 return false; |
97 address_list_str += address_string; | 219 address_list_str += address_string; |
98 current_address = current_address->ai_next; | 220 current_address = current_address->ai_next; |
99 } | 221 } |
100 | 222 |
101 *ip_address_list = address_list_str; | 223 *ip_address_list = address_list_str; |
102 return true; | 224 return true; |
103 } | 225 } |
104 | 226 |
105 // Handler for when an error is encountered. |line_number| may be -1. | |
106 virtual void OnError(int line_number, const string16& message) { | |
107 if (line_number == -1) | |
108 LOG(INFO) << "PAC-error: " << message; | |
109 else | |
110 LOG(INFO) << "PAC-error: " << "line: " << line_number << ": " << message; | |
111 } | |
112 | |
113 virtual void Shutdown() { | |
114 host_resolver_->Shutdown(); | |
115 } | |
116 | |
117 private: | |
118 // Helper to execute a synchronous DNS resolve, using the per-request | 227 // Helper to execute a synchronous DNS resolve, using the per-request |
119 // DNS cache if there is one. | 228 // DNS cache if there is one. |
120 int DnsResolveHelper(const HostResolver::RequestInfo& info, | 229 int DnsResolveHelper(const HostResolver::RequestInfo& info, |
121 AddressList* address_list) { | 230 AddressList* address_list) { |
122 HostCache::Key cache_key(info.hostname(), | 231 HostCache::Key cache_key(info.hostname(), |
123 info.address_family(), | 232 info.address_family(), |
124 info.host_resolver_flags()); | 233 info.host_resolver_flags()); |
125 | 234 |
126 HostCache* host_cache = current_request_context() ? | 235 HostCache* host_cache = current_request_context() ? |
127 current_request_context()->host_cache : NULL; | 236 current_request_context()->host_cache : NULL; |
(...skipping 17 matching lines...) Loading... |
145 | 254 |
146 // Save the result back to the per-request DNS cache. | 255 // Save the result back to the per-request DNS cache. |
147 if (host_cache) { | 256 if (host_cache) { |
148 host_cache->Set(cache_key, result, *address_list, | 257 host_cache->Set(cache_key, result, *address_list, |
149 base::TimeTicks::Now()); | 258 base::TimeTicks::Now()); |
150 } | 259 } |
151 | 260 |
152 return result; | 261 return result; |
153 } | 262 } |
154 | 263 |
| 264 void LogEventToCurrentRequest( |
| 265 NetLog::EventPhase phase, |
| 266 NetLog::EventType type, |
| 267 scoped_refptr<NetLog::EventParameters> params) { |
| 268 if (current_request_context() && current_request_context()->net_log) |
| 269 current_request_context()->net_log->AddEntry(type, phase, params); |
| 270 } |
| 271 |
| 272 void LogEventToCurrentRequestAndGlobally( |
| 273 NetLog::EventType type, |
| 274 scoped_refptr<NetLog::EventParameters> params) { |
| 275 LogEventToCurrentRequest(NetLog::PHASE_NONE, type, params); |
| 276 |
| 277 // Emit to the global NetLog event stream. |
| 278 if (net_log_) { |
| 279 net_log_->AddEntry( |
| 280 type, |
| 281 base::TimeTicks::Now(), |
| 282 NetLog::Source(), |
| 283 NetLog::PHASE_NONE, |
| 284 params); |
| 285 } |
| 286 } |
| 287 |
155 scoped_refptr<HostResolver> host_resolver_; | 288 scoped_refptr<HostResolver> host_resolver_; |
| 289 NetLog* net_log_; |
156 }; | 290 }; |
157 | 291 |
158 } // namespace | 292 } // namespace |
159 | 293 |
160 // static | 294 // static |
161 ProxyResolverJSBindings* ProxyResolverJSBindings::CreateDefault( | 295 ProxyResolverJSBindings* ProxyResolverJSBindings::CreateDefault( |
162 HostResolver* host_resolver) { | 296 HostResolver* host_resolver, NetLog* net_log) { |
163 return new DefaultJSBindings(host_resolver); | 297 return new DefaultJSBindings(host_resolver, net_log); |
164 } | 298 } |
165 | 299 |
166 } // namespace net | 300 } // namespace net |
OLD | NEW |