diff options
Diffstat (limited to 'net/proxy')
-rw-r--r-- | net/proxy/proxy_resolver_perftest.cc | 7 | ||||
-rw-r--r-- | net/proxy/proxy_resolver_v8.cc | 95 | ||||
-rw-r--r-- | net/proxy/proxy_resolver_v8.h | 32 | ||||
-rw-r--r-- | net/proxy/proxy_resolver_v8_unittest.cc | 11 | ||||
-rw-r--r-- | net/proxy/proxy_script_fetcher_unittest.cc | 7 | ||||
-rw-r--r-- | net/proxy/proxy_service.cc | 15 |
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); |