summaryrefslogtreecommitdiffstats
path: root/net/proxy
diff options
context:
space:
mode:
Diffstat (limited to 'net/proxy')
-rw-r--r--net/proxy/proxy_resolver_perftest.cc7
-rw-r--r--net/proxy/proxy_resolver_v8.cc95
-rw-r--r--net/proxy/proxy_resolver_v8.h32
-rw-r--r--net/proxy/proxy_resolver_v8_unittest.cc11
-rw-r--r--net/proxy/proxy_script_fetcher_unittest.cc7
-rw-r--r--net/proxy/proxy_service.cc15
6 files changed, 132 insertions, 35 deletions
diff --git a/net/proxy/proxy_resolver_perftest.cc b/net/proxy/proxy_resolver_perftest.cc
index 3ad7d2a0..85ad554 100644
--- a/net/proxy/proxy_resolver_perftest.cc
+++ b/net/proxy/proxy_resolver_perftest.cc
@@ -185,7 +185,12 @@ TEST(ProxyResolverPerfTest, ProxyResolverMac) {
#endif
TEST(ProxyResolverPerfTest, ProxyResolverV8) {
- net::ProxyResolverV8 resolver;
+ net::HostResolver host_resolver;
+
+ net::ProxyResolverV8::JSBindings* js_bindings =
+ net::ProxyResolverV8::CreateDefaultBindings(&host_resolver, NULL);
+
+ net::ProxyResolverV8 resolver(js_bindings);
PacPerfSuiteRunner runner(&resolver, "ProxyResolverV8");
runner.RunAllTests();
}
diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc
index a5d1c76..38e0a83 100644
--- a/net/proxy/proxy_resolver_v8.cc
+++ b/net/proxy/proxy_resolver_v8.cc
@@ -4,7 +4,10 @@
#include "net/proxy/proxy_resolver_v8.h"
+#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/waitable_event.h"
#include "base/string_util.h"
#include "googleurl/src/gurl.h"
#include "net/base/address_list.h"
@@ -50,9 +53,78 @@ bool V8ObjectToString(v8::Handle<v8::Value> object, std::string* result) {
return true;
}
+// Wrapper around HostResolver to give a sync API while running the resolve
+// in async mode on |host_resolver_loop|. If |host_resolver_loop| is NULL,
+// runs sync on the current thread (this mode is just used by testing).
+class SyncHostResolverBridge
+ : public base::RefCountedThreadSafe<SyncHostResolverBridge> {
+ public:
+ SyncHostResolverBridge(HostResolver* host_resolver,
+ MessageLoop* host_resolver_loop)
+ : host_resolver_(host_resolver),
+ host_resolver_loop_(host_resolver_loop),
+ event_(false, false),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ callback_(this, &SyncHostResolverBridge::OnResolveCompletion)) {
+ }
+
+ // Run the resolve on host_resolver_loop, and wait for result.
+ int Resolve(const std::string& hostname, net::AddressList* addresses) {
+ int kPort = 80; // Doesn't matter.
+
+ // Hack for tests -- run synchronously on current thread.
+ if (!host_resolver_loop_)
+ return host_resolver_->Resolve(hostname, kPort, addresses, NULL, NULL);
+
+ // Otherwise start an async resolve on the resolver's thread.
+ host_resolver_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &SyncHostResolverBridge::StartResolve, hostname, kPort, addresses));
+
+ // Wait for the resolve to complete in the resolver's thread.
+ event_.Wait();
+ return err_;
+ }
+
+ private:
+ // Called on host_resolver_loop_.
+ void StartResolve(const std::string& hostname,
+ int port,
+ net::AddressList* addresses) {
+ DCHECK_EQ(host_resolver_loop_, MessageLoop::current());
+ int error = host_resolver_->Resolve(
+ hostname, port, addresses, &callback_, NULL);
+ if (error != ERR_IO_PENDING)
+ OnResolveCompletion(error); // Completed synchronously.
+ }
+
+ // Called on host_resolver_loop_.
+ void OnResolveCompletion(int result) {
+ DCHECK_EQ(host_resolver_loop_, MessageLoop::current());
+ err_ = result;
+ event_.Signal();
+ }
+
+ HostResolver* host_resolver_;
+ MessageLoop* host_resolver_loop_;
+
+ // Event to notify completion of resolve request.
+ base::WaitableEvent event_;
+
+ // Callback for when the resolve completes on host_resolver_loop_.
+ net::CompletionCallbackImpl<SyncHostResolverBridge> callback_;
+
+ // The result from the result request (set by in host_resolver_loop_).
+ int err_;
+};
+
// JSBIndings implementation.
class DefaultJSBindings : public ProxyResolverV8::JSBindings {
public:
+ DefaultJSBindings(HostResolver* host_resolver,
+ MessageLoop* host_resolver_loop)
+ : host_resolver_(new SyncHostResolverBridge(
+ host_resolver, host_resolver_loop)) {}
+
// Handler for "alert(message)".
virtual void Alert(const std::string& message) {
LOG(INFO) << "PAC-alert: " << message;
@@ -71,10 +143,9 @@ class DefaultJSBindings : public ProxyResolverV8::JSBindings {
if (host.empty())
return std::string();
- // Try to resolve synchronously.
+ // Do a sync resolve of the hostname.
net::AddressList address_list;
- const int kPort = 80; // Doesn't matter what this is.
- int result = host_resolver_.Resolve(host, kPort, &address_list, NULL);
+ int result = host_resolver_->Resolve(host, &address_list);
if (result != OK)
return std::string(); // Failed.
@@ -96,7 +167,7 @@ class DefaultJSBindings : public ProxyResolverV8::JSBindings {
}
private:
- HostResolver host_resolver_;
+ scoped_refptr<SyncHostResolverBridge> host_resolver_;
};
} // namespace
@@ -106,7 +177,7 @@ class DefaultJSBindings : public ProxyResolverV8::JSBindings {
class ProxyResolverV8::Context {
public:
Context(JSBindings* js_bindings, const std::string& pac_data)
- : js_bindings_(js_bindings) {
+ : js_bindings_(js_bindings) {
DCHECK(js_bindings != NULL);
InitV8(pac_data);
}
@@ -266,20 +337,12 @@ class ProxyResolverV8::Context {
}
JSBindings* js_bindings_;
- HostResolver host_resolver_;
v8::Persistent<v8::External> v8_this_;
v8::Persistent<v8::Context> v8_context_;
};
// ProxyResolverV8 ------------------------------------------------------------
-// the |false| argument to ProxyResolver means the ProxyService will handle
-// downloading of the PAC script, and notify changes through SetPacScript().
-ProxyResolverV8::ProxyResolverV8()
- : ProxyResolver(false /*does_fetch*/),
- js_bindings_(new DefaultJSBindings()) {
-}
-
ProxyResolverV8::ProxyResolverV8(
ProxyResolverV8::JSBindings* custom_js_bindings)
: ProxyResolver(false), js_bindings_(custom_js_bindings) {
@@ -305,4 +368,10 @@ void ProxyResolverV8::SetPacScript(const std::string& data) {
context_.reset(new Context(js_bindings_.get(), data));
}
+// static
+ProxyResolverV8::JSBindings* ProxyResolverV8::CreateDefaultBindings(
+ HostResolver* host_resolver, MessageLoop* host_resolver_loop) {
+ return new DefaultJSBindings(host_resolver, host_resolver_loop);
+}
+
} // namespace net
diff --git a/net/proxy/proxy_resolver_v8.h b/net/proxy/proxy_resolver_v8.h
index 219560c..3bf2bec 100644
--- a/net/proxy/proxy_resolver_v8.h
+++ b/net/proxy/proxy_resolver_v8.h
@@ -10,8 +10,12 @@
#include "base/scoped_ptr.h"
#include "net/proxy/proxy_resolver.h"
+class MessageLoop;
+
namespace net {
+class HostResolver;
+
// Implementation of ProxyResolver that uses V8 to evaluate PAC scripts.
//
// ----------------------------------------------------------------------------
@@ -32,19 +36,6 @@ namespace net {
// and does not use locking since it expects to be alone.
class ProxyResolverV8 : public ProxyResolver {
public:
- // Constructs a ProxyResolverV8 with default javascript bindings.
- //
- // The default javascript bindings will:
- // - Send script error messages to LOG(INFO)
- // - Send script alert()s to LOG(INFO)
- // - Use the default host mapper to service dnsResolve(), synchronously
- // on the V8 thread.
- //
- // For clients that need more control (for example, sending the script output
- // to a UI widget), use the ProxyResolverV8(JSBindings*) and specify your
- // own bindings.
- ProxyResolverV8();
-
class JSBindings;
// Constructs a ProxyResolverV8 with custom bindings. ProxyResolverV8 takes
@@ -62,6 +53,21 @@ class ProxyResolverV8 : public ProxyResolver {
JSBindings* js_bindings() const { return js_bindings_.get(); }
+ // Creates a default javascript bindings implementation that will:
+ // - Send script error messages to LOG(INFO)
+ // - Send script alert()s to LOG(INFO)
+ // - Use the provided host mapper to service dnsResolve().
+ //
+ // For clients that need more control (for example, sending the script output
+ // to a UI widget), use the ProxyResolverV8(JSBindings*) and specify your
+ // own bindings.
+ //
+ // |host_resolver| will be used in async mode on |host_resolver_loop|. If
+ // |host_resolver_loop| is NULL, then |host_resolver| will be used in sync
+ // mode on the PAC thread.
+ static JSBindings* CreateDefaultBindings(HostResolver* host_resolver,
+ MessageLoop* host_resolver_loop);
+
private:
// Context holds the Javascript state for the most recently loaded PAC
// script. It corresponds with the data from the last call to
diff --git a/net/proxy/proxy_resolver_v8_unittest.cc b/net/proxy/proxy_resolver_v8_unittest.cc
index dff8843..0e8ba47 100644
--- a/net/proxy/proxy_resolver_v8_unittest.cc
+++ b/net/proxy/proxy_resolver_v8_unittest.cc
@@ -6,6 +6,7 @@
#include "base/string_util.h"
#include "base/path_service.h"
#include "googleurl/src/gurl.h"
+#include "net/base/host_resolver.h"
#include "net/base/net_errors.h"
#include "net/proxy/proxy_resolver_v8.h"
#include "net/proxy/proxy_info.h"
@@ -377,8 +378,9 @@ TEST(ProxyResolverV8Test, V8Bindings) {
TEST(ProxyResolverV8DefaultBindingsTest, DnsResolve) {
// Get a hold of a DefaultJSBindings* (it is a hidden impl class).
- net::ProxyResolverV8 resolver;
- net::ProxyResolverV8::JSBindings* bindings = resolver.js_bindings();
+ net::HostResolver host_resolver;
+ scoped_ptr<net::ProxyResolverV8::JSBindings> bindings(
+ net::ProxyResolverV8::CreateDefaultBindings(&host_resolver, NULL));
// Considered an error.
EXPECT_EQ("", bindings->DnsResolve(""));
@@ -428,8 +430,9 @@ TEST(ProxyResolverV8DefaultBindingsTest, DnsResolve) {
TEST(ProxyResolverV8DefaultBindingsTest, MyIpAddress) {
// Get a hold of a DefaultJSBindings* (it is a hidden impl class).
- net::ProxyResolverV8 resolver;
- net::ProxyResolverV8::JSBindings* bindings = resolver.js_bindings();
+ net::HostResolver host_resolver;
+ scoped_ptr<net::ProxyResolverV8::JSBindings> bindings(
+ net::ProxyResolverV8::CreateDefaultBindings(&host_resolver, NULL));
// Our ip address is always going to be 127.0.0.1, since we are using a
// mock host mapper when running in unit-test mode.
diff --git a/net/proxy/proxy_script_fetcher_unittest.cc b/net/proxy/proxy_script_fetcher_unittest.cc
index 3614cfe..5b16738b 100644
--- a/net/proxy/proxy_script_fetcher_unittest.cc
+++ b/net/proxy/proxy_script_fetcher_unittest.cc
@@ -30,15 +30,18 @@ class RequestContext : public URLRequestContext {
public:
RequestContext() {
net::ProxyConfig no_proxy;
+ host_resolver_ = new net::HostResolver;
proxy_service_ = net::ProxyService::CreateFixed(no_proxy);
http_transaction_factory_ =
- new net::HttpCache(net::HttpNetworkLayer::CreateFactory(proxy_service_),
- disk_cache::CreateInMemoryCacheBackend(0));
+ new net::HttpCache(net::HttpNetworkLayer::CreateFactory(
+ host_resolver_, proxy_service_),
+ disk_cache::CreateInMemoryCacheBackend(0));
}
~RequestContext() {
delete http_transaction_factory_;
delete proxy_service_;
+ delete host_resolver_;
}
};
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index 65db636..3a0cd7f 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -23,6 +23,7 @@
#endif
#include "net/proxy/proxy_resolver.h"
#include "net/proxy/proxy_resolver_v8.h"
+#include "net/url_request/url_request_context.h"
using base::TimeDelta;
using base::TimeTicks;
@@ -217,8 +218,18 @@ ProxyService* ProxyService::Create(
new ProxyConfigServiceFixed(*pc) :
CreateSystemProxyConfigService(io_loop);
- ProxyResolver* proxy_resolver = use_v8_resolver ?
- new ProxyResolverV8() : CreateNonV8ProxyResolver();
+ ProxyResolver* proxy_resolver;
+
+ if (use_v8_resolver) {
+ // Send javascript errors and alerts to LOG(INFO).
+ HostResolver* host_resolver = url_request_context->host_resolver();
+ ProxyResolverV8::JSBindings* js_bindings =
+ ProxyResolverV8::CreateDefaultBindings(host_resolver, io_loop);
+
+ proxy_resolver = new ProxyResolverV8(js_bindings);
+ } else {
+ proxy_resolver = CreateNonV8ProxyResolver();
+ }
ProxyService* proxy_service = new ProxyService(
proxy_config_service, proxy_resolver);