summaryrefslogtreecommitdiffstats
path: root/net/proxy/proxy_resolver_v8.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/proxy/proxy_resolver_v8.cc')
-rw-r--r--net/proxy/proxy_resolver_v8.cc108
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_;