Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. | 3 // LICENSE file. |
| 4 | 4 |
| 5 #include "net/proxy/proxy_resolver_v8.h" | 5 #include "net/proxy/proxy_resolver_v8.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 "googleurl/src/gurl.h" | 9 #include "googleurl/src/gurl.h" |
| 10 #include "net/base/load_log.h" | 10 #include "net/base/load_log.h" |
| 11 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
| 12 #include "net/proxy/proxy_info.h" | 12 #include "net/proxy/proxy_info.h" |
| 13 #include "net/proxy/proxy_resolver_js_bindings.h" | 13 #include "net/proxy/proxy_resolver_js_bindings.h" |
| 14 #include "net/proxy/proxy_resolver_script.h" | 14 #include "net/proxy/proxy_resolver_script.h" |
| 15 #include "v8/include/v8.h" | 15 #include "v8/include/v8.h" |
| 16 | 16 |
| 17 // Notes on the javascript environment: | |
|
wtc
2009/10/24 04:40:59
Very nice! Thanks.
| |
| 18 // | |
| 19 // For the majority of the PAC utility functions, we use the same code | |
| 20 // as Firefox. See the javascript library that proxy_resolver_scipt.h | |
| 21 // pulls in. | |
| 22 // | |
| 23 // In addition, we implement a subset of Microsoft's extensions to PAC. | |
| 24 // TODO(eroman): Implement the rest. | |
| 25 // | |
| 26 // - myIpAddressEx() | |
| 27 // - dnsResolveEx() | |
| 28 // - isResolvableEx() | |
| 29 // | |
| 30 // It is worth noting that the original PAC specification does not describe | |
| 31 // the return values on failure. Consequently, there are compatibility | |
| 32 // differences between browsers on what to return on failure, which are | |
| 33 // illustrated below: | |
| 34 // | |
| 35 // ----------------+-------------+-------------------+-------------- | |
| 36 // | Firefox3 | InternetExplorer8 | --> Us <--- | |
| 37 // ----------------+-------------+-------------------+-------------- | |
| 38 // myIpAddress() | "127.0.0.1" | ??? | "127.0.0.1" | |
| 39 // dnsResolve() | null | false | null | |
| 40 // myIpAddressEx() | N/A | "" | "" | |
| 41 // dnsResolveEx() | N/A | "" | "" | |
| 42 // ----------------+-------------+-------------------+-------------- | |
| 43 // | |
| 44 // TODO(eroman): The cell above reading ??? means I didn't test it. | |
| 45 // | |
| 46 // Another difference is in how dnsResolve() and myIpAddress() are | |
| 47 // implemented -- whether they should restrict to IPv4 results, or | |
| 48 // include both IPv4 and IPv6. The following table illustrates the | |
| 49 // differences: | |
| 50 // | |
| 51 // -----------------+-------------+-------------------+-------------- | |
| 52 // | Firefox3 | InternetExplorer8 | --> Us <--- | |
| 53 // -----------------+-------------+-------------------+-------------- | |
| 54 // myIpAddress() | IPv4/IPv6 | IPv4 | IPv4 | |
| 55 // dnsResolve() | IPv4/IPv6 | IPv4 | IPv4 | |
|
wtc
2009/10/24 04:40:59
It's possible that Firefox's dnsResolve returns IP
| |
| 56 // isResolvable() | IPv4/IPv6 | IPv4 | IPv4 | |
| 57 // myIpAddressEx() | N/A | IPv4/IPv6 | IPv4/IPv6 | |
| 58 // dnsResolveEx() | N/A | IPv4/IPv6 | IPv4/IPv6 | |
| 59 // isResolvableEx() | N/A | IPv4/IPv6 | IPv4/IPv6 | |
| 60 // -----------------+-------------+-------------------+-------------- | |
| 61 | |
| 17 namespace net { | 62 namespace net { |
| 18 | 63 |
| 19 namespace { | 64 namespace { |
| 20 | 65 |
| 21 // Pseudo-name for the PAC script. | 66 // Pseudo-name for the PAC script. |
| 22 const char kPacResourceName[] = "proxy-pac-script.js"; | 67 const char kPacResourceName[] = "proxy-pac-script.js"; |
| 23 // Pseudo-name for the PAC utility script. | 68 // Pseudo-name for the PAC utility script. |
| 24 const char kPacUtilityResourceName[] = "proxy-pac-utility-script.js"; | 69 const char kPacUtilityResourceName[] = "proxy-pac-utility-script.js"; |
| 25 | 70 |
| 26 // Convert a V8 String to a std::string. | 71 // Convert a V8 String to a std::string. |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 v8::Local<v8::FunctionTemplate> my_ip_address_template = | 166 v8::Local<v8::FunctionTemplate> my_ip_address_template = |
| 122 v8::FunctionTemplate::New(&MyIpAddressCallback, v8_this_); | 167 v8::FunctionTemplate::New(&MyIpAddressCallback, v8_this_); |
| 123 global_template->Set(v8::String::New("myIpAddress"), | 168 global_template->Set(v8::String::New("myIpAddress"), |
| 124 my_ip_address_template); | 169 my_ip_address_template); |
| 125 | 170 |
| 126 v8::Local<v8::FunctionTemplate> dns_resolve_template = | 171 v8::Local<v8::FunctionTemplate> dns_resolve_template = |
| 127 v8::FunctionTemplate::New(&DnsResolveCallback, v8_this_); | 172 v8::FunctionTemplate::New(&DnsResolveCallback, v8_this_); |
| 128 global_template->Set(v8::String::New("dnsResolve"), | 173 global_template->Set(v8::String::New("dnsResolve"), |
| 129 dns_resolve_template); | 174 dns_resolve_template); |
| 130 | 175 |
| 176 // Microsoft's PAC extensions (incomplete): | |
| 177 | |
| 178 v8::Local<v8::FunctionTemplate> dns_resolve_ex_template = | |
| 179 v8::FunctionTemplate::New(&DnsResolveExCallback, v8_this_); | |
| 180 global_template->Set(v8::String::New("dnsResolveEx"), | |
| 181 dns_resolve_ex_template); | |
| 182 | |
| 183 v8::Local<v8::FunctionTemplate> my_ip_address_ex_template = | |
| 184 v8::FunctionTemplate::New(&MyIpAddressExCallback, v8_this_); | |
| 185 global_template->Set(v8::String::New("myIpAddressEx"), | |
| 186 my_ip_address_ex_template); | |
| 187 | |
| 131 v8_context_ = v8::Context::New(NULL, global_template); | 188 v8_context_ = v8::Context::New(NULL, global_template); |
| 132 | 189 |
| 133 v8::Context::Scope ctx(v8_context_); | 190 v8::Context::Scope ctx(v8_context_); |
| 134 | 191 |
| 135 // Add the PAC utility functions to the environment. | 192 // Add the PAC utility functions to the environment. |
| 136 // (This script should never fail, as it is a string literal!) | 193 // (This script should never fail, as it is a string literal!) |
| 137 int rv = RunScript(PROXY_RESOLVER_SCRIPT, kPacUtilityResourceName); | 194 // Note that the two string literals are concatenated. |
| 195 int rv = RunScript(PROXY_RESOLVER_SCRIPT | |
| 196 PROXY_RESOLVER_SCRIPT_EX, | |
| 197 kPacUtilityResourceName); | |
| 138 if (rv != OK) { | 198 if (rv != OK) { |
| 139 NOTREACHED(); | 199 NOTREACHED(); |
| 140 return rv; | 200 return rv; |
| 141 } | 201 } |
| 142 | 202 |
| 143 // Add the user's PAC code to the environment. | 203 // Add the user's PAC code to the environment. |
| 144 rv = RunScript(pac_data_utf8, kPacResourceName); | 204 rv = RunScript(pac_data_utf8, kPacResourceName); |
| 145 if (rv != OK) | 205 if (rv != OK) |
| 146 return rv; | 206 return rv; |
| 147 | 207 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 std::string result = context->js_bindings_->MyIpAddress(); | 301 std::string result = context->js_bindings_->MyIpAddress(); |
| 242 | 302 |
| 243 LoadLog::EndEvent(context->current_request_load_log_, | 303 LoadLog::EndEvent(context->current_request_load_log_, |
| 244 LoadLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS); | 304 LoadLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS); |
| 245 | 305 |
| 246 if (result.empty()) | 306 if (result.empty()) |
| 247 result = "127.0.0.1"; | 307 result = "127.0.0.1"; |
| 248 return StdStringToV8String(result); | 308 return StdStringToV8String(result); |
| 249 } | 309 } |
| 250 | 310 |
| 311 // V8 callback for when "myIpAddressEx()" is invoked by the PAC script. | |
| 312 static v8::Handle<v8::Value> MyIpAddressExCallback( | |
| 313 const v8::Arguments& args) { | |
| 314 Context* context = | |
| 315 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | |
| 316 | |
| 317 LoadLog::BeginEvent(context->current_request_load_log_, | |
| 318 LoadLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS_EX); | |
| 319 | |
| 320 // We shouldn't be called with any arguments, but will not complain if | |
| 321 // we are. | |
| 322 std::string result = context->js_bindings_->MyIpAddressEx(); | |
| 323 | |
| 324 LoadLog::EndEvent(context->current_request_load_log_, | |
| 325 LoadLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS_EX); | |
| 326 | |
| 327 return StdStringToV8String(result); | |
| 328 } | |
| 329 | |
| 251 // V8 callback for when "dnsResolve()" is invoked by the PAC script. | 330 // V8 callback for when "dnsResolve()" is invoked by the PAC script. |
| 252 static v8::Handle<v8::Value> DnsResolveCallback(const v8::Arguments& args) { | 331 static v8::Handle<v8::Value> DnsResolveCallback(const v8::Arguments& args) { |
| 253 Context* context = | 332 Context* context = |
| 254 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 333 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
| 255 | 334 |
| 256 // We need at least one argument. | 335 // We need at least one argument. |
| 257 std::string host; | 336 std::string host; |
| 258 if (args.Length() == 0) { | 337 if (args.Length() == 0) { |
| 259 host = "undefined"; | 338 host = "undefined"; |
| 260 } else { | 339 } else { |
| 261 if (!V8ObjectToString(args[0], &host)) | 340 if (!V8ObjectToString(args[0], &host)) |
| 262 return v8::Undefined(); | 341 return v8::Undefined(); |
| 263 } | 342 } |
| 264 | 343 |
| 265 LoadLog::BeginEvent(context->current_request_load_log_, | 344 LoadLog::BeginEvent(context->current_request_load_log_, |
| 266 LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE); | 345 LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE); |
| 267 | 346 |
| 268 std::string result = context->js_bindings_->DnsResolve(host); | 347 std::string result = context->js_bindings_->DnsResolve(host); |
| 269 | 348 |
| 270 LoadLog::EndEvent(context->current_request_load_log_, | 349 LoadLog::EndEvent(context->current_request_load_log_, |
| 271 LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE); | 350 LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE); |
| 272 | 351 |
| 273 // DoDnsResolve() returns empty string on failure. | 352 // DnsResolve() returns empty string on failure. |
| 274 return result.empty() ? v8::Null() : StdStringToV8String(result); | 353 return result.empty() ? v8::Null() : StdStringToV8String(result); |
| 275 } | 354 } |
| 276 | 355 |
| 356 // V8 callback for when "dnsResolveEx()" is invoked by the PAC script. | |
| 357 static v8::Handle<v8::Value> DnsResolveExCallback(const v8::Arguments& args) { | |
| 358 Context* context = | |
| 359 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | |
| 360 | |
| 361 // We need at least one argument. | |
| 362 std::string host; | |
| 363 if (args.Length() == 0) { | |
| 364 host = "undefined"; | |
| 365 } else { | |
| 366 if (!V8ObjectToString(args[0], &host)) | |
| 367 return v8::Undefined(); | |
| 368 } | |
| 369 | |
| 370 LoadLog::BeginEvent(context->current_request_load_log_, | |
| 371 LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE_EX); | |
| 372 | |
| 373 std::string result = context->js_bindings_->DnsResolveEx(host); | |
| 374 | |
| 375 LoadLog::EndEvent(context->current_request_load_log_, | |
| 376 LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE_EX); | |
| 377 | |
| 378 return StdStringToV8String(result); | |
| 379 } | |
| 380 | |
| 277 ProxyResolverJSBindings* js_bindings_; | 381 ProxyResolverJSBindings* js_bindings_; |
| 278 LoadLog* current_request_load_log_; | 382 LoadLog* current_request_load_log_; |
| 279 v8::Persistent<v8::External> v8_this_; | 383 v8::Persistent<v8::External> v8_this_; |
| 280 v8::Persistent<v8::Context> v8_context_; | 384 v8::Persistent<v8::Context> v8_context_; |
| 281 }; | 385 }; |
| 282 | 386 |
| 283 // ProxyResolverV8 ------------------------------------------------------------ | 387 // ProxyResolverV8 ------------------------------------------------------------ |
| 284 | 388 |
| 285 ProxyResolverV8::ProxyResolverV8( | 389 ProxyResolverV8::ProxyResolverV8( |
| 286 ProxyResolverJSBindings* custom_js_bindings) | 390 ProxyResolverJSBindings* custom_js_bindings) |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 | 430 |
| 327 // Try parsing the PAC script. | 431 // Try parsing the PAC script. |
| 328 scoped_ptr<Context> context(new Context(js_bindings_.get())); | 432 scoped_ptr<Context> context(new Context(js_bindings_.get())); |
| 329 int rv = context->InitV8(bytes_utf8); | 433 int rv = context->InitV8(bytes_utf8); |
| 330 if (rv == OK) | 434 if (rv == OK) |
| 331 context_.reset(context.release()); | 435 context_.reset(context.release()); |
| 332 return rv; | 436 return rv; |
| 333 } | 437 } |
| 334 | 438 |
| 335 } // namespace net | 439 } // namespace net |
| OLD | NEW |