diff options
Diffstat (limited to 'net/proxy/proxy_resolver_v8.cc')
-rw-r--r-- | net/proxy/proxy_resolver_v8.cc | 108 |
1 files changed, 106 insertions, 2 deletions
diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc index 7fd00bd..4db6bc3 100644 --- a/net/proxy/proxy_resolver_v8.cc +++ b/net/proxy/proxy_resolver_v8.cc @@ -14,6 +14,51 @@ #include "net/proxy/proxy_resolver_script.h" #include "v8/include/v8.h" +// Notes on the javascript environment: +// +// For the majority of the PAC utility functions, we use the same code +// as Firefox. See the javascript library that proxy_resolver_scipt.h +// pulls in. +// +// In addition, we implement a subset of Microsoft's extensions to PAC. +// TODO(eroman): Implement the rest. +// +// - myIpAddressEx() +// - dnsResolveEx() +// - isResolvableEx() +// +// It is worth noting that the original PAC specification does not describe +// the return values on failure. Consequently, there are compatibility +// differences between browsers on what to return on failure, which are +// illustrated below: +// +// ----------------+-------------+-------------------+-------------- +// | Firefox3 | InternetExplorer8 | --> Us <--- +// ----------------+-------------+-------------------+-------------- +// myIpAddress() | "127.0.0.1" | ??? | "127.0.0.1" +// dnsResolve() | null | false | null +// myIpAddressEx() | N/A | "" | "" +// dnsResolveEx() | N/A | "" | "" +// ----------------+-------------+-------------------+-------------- +// +// TODO(eroman): The cell above reading ??? means I didn't test it. +// +// Another difference is in how dnsResolve() and myIpAddress() are +// implemented -- whether they should restrict to IPv4 results, or +// include both IPv4 and IPv6. The following table illustrates the +// differences: +// +// -----------------+-------------+-------------------+-------------- +// | Firefox3 | InternetExplorer8 | --> Us <--- +// -----------------+-------------+-------------------+-------------- +// myIpAddress() | IPv4/IPv6 | IPv4 | IPv4 +// dnsResolve() | IPv4/IPv6 | IPv4 | IPv4 +// isResolvable() | IPv4/IPv6 | IPv4 | IPv4 +// myIpAddressEx() | N/A | IPv4/IPv6 | IPv4/IPv6 +// dnsResolveEx() | N/A | IPv4/IPv6 | IPv4/IPv6 +// isResolvableEx() | N/A | IPv4/IPv6 | IPv4/IPv6 +// -----------------+-------------+-------------------+-------------- + namespace net { namespace { @@ -128,13 +173,28 @@ class ProxyResolverV8::Context { global_template->Set(v8::String::New("dnsResolve"), dns_resolve_template); + // Microsoft's PAC extensions (incomplete): + + v8::Local<v8::FunctionTemplate> dns_resolve_ex_template = + v8::FunctionTemplate::New(&DnsResolveExCallback, v8_this_); + global_template->Set(v8::String::New("dnsResolveEx"), + dns_resolve_ex_template); + + v8::Local<v8::FunctionTemplate> my_ip_address_ex_template = + v8::FunctionTemplate::New(&MyIpAddressExCallback, v8_this_); + global_template->Set(v8::String::New("myIpAddressEx"), + my_ip_address_ex_template); + v8_context_ = v8::Context::New(NULL, global_template); v8::Context::Scope ctx(v8_context_); // Add the PAC utility functions to the environment. // (This script should never fail, as it is a string literal!) - int rv = RunScript(PROXY_RESOLVER_SCRIPT, kPacUtilityResourceName); + // Note that the two string literals are concatenated. + int rv = RunScript(PROXY_RESOLVER_SCRIPT + PROXY_RESOLVER_SCRIPT_EX, + kPacUtilityResourceName); if (rv != OK) { NOTREACHED(); return rv; @@ -248,6 +308,25 @@ class ProxyResolverV8::Context { return StdStringToV8String(result); } + // V8 callback for when "myIpAddressEx()" is invoked by the PAC script. + static v8::Handle<v8::Value> MyIpAddressExCallback( + const v8::Arguments& args) { + Context* context = + static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); + + LoadLog::BeginEvent(context->current_request_load_log_, + LoadLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS_EX); + + // We shouldn't be called with any arguments, but will not complain if + // we are. + std::string result = context->js_bindings_->MyIpAddressEx(); + + LoadLog::EndEvent(context->current_request_load_log_, + LoadLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS_EX); + + return StdStringToV8String(result); + } + // V8 callback for when "dnsResolve()" is invoked by the PAC script. static v8::Handle<v8::Value> DnsResolveCallback(const v8::Arguments& args) { Context* context = @@ -270,10 +349,35 @@ class ProxyResolverV8::Context { LoadLog::EndEvent(context->current_request_load_log_, LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE); - // DoDnsResolve() returns empty string on failure. + // DnsResolve() returns empty string on failure. return result.empty() ? v8::Null() : StdStringToV8String(result); } + // V8 callback for when "dnsResolveEx()" is invoked by the PAC script. + static v8::Handle<v8::Value> DnsResolveExCallback(const v8::Arguments& args) { + Context* context = + static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); + + // We need at least one argument. + std::string host; + if (args.Length() == 0) { + host = "undefined"; + } else { + if (!V8ObjectToString(args[0], &host)) + return v8::Undefined(); + } + + LoadLog::BeginEvent(context->current_request_load_log_, + LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE_EX); + + std::string result = context->js_bindings_->DnsResolveEx(host); + + LoadLog::EndEvent(context->current_request_load_log_, + LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE_EX); + + return StdStringToV8String(result); + } + ProxyResolverJSBindings* js_bindings_; LoadLog* current_request_load_log_; v8::Persistent<v8::External> v8_this_; |