diff options
Diffstat (limited to 'net/proxy')
-rw-r--r-- | net/proxy/init_proxy_resolver.cc | 12 | ||||
-rw-r--r-- | net/proxy/init_proxy_resolver.h | 2 | ||||
-rw-r--r-- | net/proxy/mock_proxy_resolver.cc | 115 | ||||
-rw-r--r-- | net/proxy/proxy_script_fetcher.h | 7 | ||||
-rw-r--r-- | net/proxy/proxy_script_fetcher_impl.cc | 13 | ||||
-rw-r--r-- | net/proxy/proxy_script_fetcher_impl_unittest.cc | 66 | ||||
-rw-r--r-- | net/proxy/proxy_server.h | 4 | ||||
-rw-r--r-- | net/proxy/proxy_service.cc | 4 | ||||
-rw-r--r-- | net/proxy/proxy_service.h | 4 |
9 files changed, 204 insertions, 23 deletions
diff --git a/net/proxy/init_proxy_resolver.cc b/net/proxy/init_proxy_resolver.cc index c60dd21..9091168 100644 --- a/net/proxy/init_proxy_resolver.cc +++ b/net/proxy/init_proxy_resolver.cc @@ -18,6 +18,16 @@ namespace net { // This is the hard-coded location used by the DNS portion of web proxy // auto-discovery. +// +// Note that we not use DNS devolution to find the WPAD host, since that could +// be dangerous should our top level domain registry become out of date. +// +// Instead we directly resolve "wpad", and let the operating system apply the +// DNS suffix search paths. This is the same approach taken by Firefox, and +// compatibility hasn't been an issue. +// +// For more details, also check out this comment: +// http://code.google.com/p/chromium/issues/detail?id=18575#c20 static const char kWpadUrl[] = "http://wpad/wpad.dat"; InitProxyResolver::InitProxyResolver(ProxyResolver* resolver, @@ -72,7 +82,7 @@ int InitProxyResolver::Init(const ProxyConfig& config, } // Initialize the fallback rules. -// (1) WPAD +// (1) WPAD (DNS). // (2) Custom PAC URL. InitProxyResolver::UrlList InitProxyResolver::BuildPacUrlsFallbackList( const ProxyConfig& config) const { diff --git a/net/proxy/init_proxy_resolver.h b/net/proxy/init_proxy_resolver.h index ec6bfc1..fd65642 100644 --- a/net/proxy/init_proxy_resolver.h +++ b/net/proxy/init_proxy_resolver.h @@ -27,7 +27,7 @@ class ProxyScriptFetcher; // // This involves trying to use PAC scripts in this order: // -// (1) WPAD if auto-detect is on. +// (1) WPAD (DNS) if auto-detect is on. // (2) Custom PAC script if a URL was given. // // If no PAC script was successfully downloaded + parsed, then it fails with diff --git a/net/proxy/mock_proxy_resolver.cc b/net/proxy/mock_proxy_resolver.cc new file mode 100644 index 0000000..bb29984 --- /dev/null +++ b/net/proxy/mock_proxy_resolver.cc @@ -0,0 +1,115 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/proxy/mock_proxy_resolver.h" + +#include "base/logging.h" +#include "base/message_loop.h" + +namespace net { + +MockAsyncProxyResolverBase::Request::Request( + MockAsyncProxyResolverBase* resolver, + const GURL& url, + ProxyInfo* results, + CompletionCallback* callback) + : resolver_(resolver), + url_(url), + results_(results), + callback_(callback), + origin_loop_(MessageLoop::current()) { + } + + void MockAsyncProxyResolverBase::Request::CompleteNow(int rv) { + CompletionCallback* callback = callback_; + + // May delete |this|. + resolver_->RemovePendingRequest(this); + + callback->Run(rv); + } + +MockAsyncProxyResolverBase::Request::~Request() {} + + +MockAsyncProxyResolverBase::SetPacScriptRequest::SetPacScriptRequest( + MockAsyncProxyResolverBase* resolver, + const scoped_refptr<ProxyResolverScriptData>& script_data, + CompletionCallback* callback) + : resolver_(resolver), + script_data_(script_data), + callback_(callback), + origin_loop_(MessageLoop::current()) { + } + +MockAsyncProxyResolverBase::SetPacScriptRequest::~SetPacScriptRequest() {} + + void MockAsyncProxyResolverBase::SetPacScriptRequest::CompleteNow(int rv) { + CompletionCallback* callback = callback_; + + // Will delete |this|. + resolver_->RemovePendingSetPacScriptRequest(this); + + callback->Run(rv); + } + +MockAsyncProxyResolverBase::~MockAsyncProxyResolverBase() {} + +int MockAsyncProxyResolverBase::GetProxyForURL(const GURL& url, + ProxyInfo* results, + CompletionCallback* callback, + RequestHandle* request_handle, + const BoundNetLog& /*net_log*/) { + scoped_refptr<Request> request = new Request(this, url, results, callback); + pending_requests_.push_back(request); + + if (request_handle) + *request_handle = reinterpret_cast<RequestHandle>(request.get()); + + // Test code completes the request by calling request->CompleteNow(). + return ERR_IO_PENDING; +} + +void MockAsyncProxyResolverBase::CancelRequest(RequestHandle request_handle) { + scoped_refptr<Request> request = reinterpret_cast<Request*>(request_handle); + cancelled_requests_.push_back(request); + RemovePendingRequest(request); +} + +int MockAsyncProxyResolverBase::SetPacScript( + const scoped_refptr<ProxyResolverScriptData>& script_data, + CompletionCallback* callback) { + DCHECK(!pending_set_pac_script_request_.get()); + pending_set_pac_script_request_.reset( + new SetPacScriptRequest(this, script_data, callback)); + // Finished when user calls SetPacScriptRequest::CompleteNow(). + return ERR_IO_PENDING; +} + +void MockAsyncProxyResolverBase::CancelSetPacScript() { + // Do nothing (caller was responsible for completing the request). +} + +MockAsyncProxyResolverBase::SetPacScriptRequest* +MockAsyncProxyResolverBase::pending_set_pac_script_request() const { + return pending_set_pac_script_request_.get(); +} + +void MockAsyncProxyResolverBase::RemovePendingRequest(Request* request) { + RequestsList::iterator it = std::find( + pending_requests_.begin(), pending_requests_.end(), request); + DCHECK(it != pending_requests_.end()); + pending_requests_.erase(it); +} + +void MockAsyncProxyResolverBase::RemovePendingSetPacScriptRequest( + SetPacScriptRequest* request) { + DCHECK_EQ(request, pending_set_pac_script_request()); + pending_set_pac_script_request_.reset(); +} + +MockAsyncProxyResolverBase::MockAsyncProxyResolverBase(bool expects_pac_bytes) + : ProxyResolver(expects_pac_bytes) {} + +} // namespace net diff --git a/net/proxy/proxy_script_fetcher.h b/net/proxy/proxy_script_fetcher.h index 9829316..c8cda24 100644 --- a/net/proxy/proxy_script_fetcher.h +++ b/net/proxy/proxy_script_fetcher.h @@ -27,8 +27,11 @@ class ProxyScriptFetcher { virtual ~ProxyScriptFetcher() {} // Downloads the given PAC URL, and invokes |callback| on completion. - // On success |callback| is executed with a result code of OK, |*utf16_text| - // is filled with the response. On failure, the result text is + // Returns OK on success, otherwise the error code. If the return code is + // ERR_IO_PENDING, then the request completes asynchronously, and |callback| + // will be invoked later with the final error code. + // After synchronous or asynchronous completion with a result code of OK, + // |*utf16_text| is filled with the response. On failure, the result text is // an empty string, and the result code is a network error. Some special // network errors that may occur are: // diff --git a/net/proxy/proxy_script_fetcher_impl.cc b/net/proxy/proxy_script_fetcher_impl.cc index bc245a2..e840189 100644 --- a/net/proxy/proxy_script_fetcher_impl.cc +++ b/net/proxy/proxy_script_fetcher_impl.cc @@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/message_loop.h" #include "base/string_util.h" +#include "net/base/data_url.h" #include "net/base/io_buffer.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" @@ -123,6 +124,18 @@ int ProxyScriptFetcherImpl::Fetch(const GURL& url, DCHECK(callback); DCHECK(text); + // Handle base-64 encoded data-urls that contain custom PAC scripts. + if (url.SchemeIs("data")) { + std::string mime_type; + std::string charset; + std::string data; + if (!DataURL::Parse(url, &mime_type, &charset, &data)) + return ERR_FAILED; + + ConvertResponseToUTF16(charset, data, text); + return OK; + } + cur_request_.reset(new URLRequest(url, this)); cur_request_->set_context(url_request_context_); cur_request_->set_method("GET"); diff --git a/net/proxy/proxy_script_fetcher_impl_unittest.cc b/net/proxy/proxy_script_fetcher_impl_unittest.cc index ce92986..56cccb1 100644 --- a/net/proxy/proxy_script_fetcher_impl_unittest.cc +++ b/net/proxy/proxy_script_fetcher_impl_unittest.cc @@ -41,30 +41,30 @@ class RequestContext : public URLRequestContext { public: RequestContext() { ProxyConfig no_proxy; - host_resolver_ = + set_host_resolver( CreateSystemHostResolver(HostResolver::kDefaultParallelism, - NULL, NULL); - cert_verifier_ = new CertVerifier; - proxy_service_ = ProxyService::CreateFixed(no_proxy); - ssl_config_service_ = new SSLConfigServiceDefaults; + NULL, NULL)); + set_cert_verifier(new CertVerifier); + set_proxy_service(ProxyService::CreateFixed(no_proxy)); + set_ssl_config_service(new SSLConfigServiceDefaults); HttpNetworkSession::Params params; - params.host_resolver = host_resolver_; - params.cert_verifier = cert_verifier_; - params.proxy_service = proxy_service_; - params.ssl_config_service = ssl_config_service_; + params.host_resolver = host_resolver(); + params.cert_verifier = cert_verifier(); + params.proxy_service = proxy_service(); + params.ssl_config_service = ssl_config_service(); scoped_refptr<HttpNetworkSession> network_session( new HttpNetworkSession(params)); - http_transaction_factory_ = new HttpCache( + set_http_transaction_factory(new HttpCache( network_session, - HttpCache::DefaultBackend::InMemory(0)); + HttpCache::DefaultBackend::InMemory(0))); } private: ~RequestContext() { - delete http_transaction_factory_; - delete cert_verifier_; - delete host_resolver_; + delete http_transaction_factory(); + delete cert_verifier(); + delete host_resolver(); } }; @@ -340,4 +340,42 @@ TEST_F(ProxyScriptFetcherImplTest, Encodings) { } } +TEST_F(ProxyScriptFetcherImplTest, DataURLs) { + scoped_refptr<URLRequestContext> context(new RequestContext); + ProxyScriptFetcherImpl pac_fetcher(context); + + const char kEncodedUrl[] = + "data:application/x-ns-proxy-autoconfig;base64,ZnVuY3Rpb24gRmluZFByb3h5R" + "m9yVVJMKHVybCwgaG9zdCkgewogIGlmIChob3N0ID09ICdmb29iYXIuY29tJykKICAgIHJl" + "dHVybiAnUFJPWFkgYmxhY2tob2xlOjgwJzsKICByZXR1cm4gJ0RJUkVDVCc7Cn0="; + const char kPacScript[] = + "function FindProxyForURL(url, host) {\n" + " if (host == 'foobar.com')\n" + " return 'PROXY blackhole:80';\n" + " return 'DIRECT';\n" + "}"; + + // Test fetching a "data:"-url containing a base64 encoded PAC script. + { + GURL url(kEncodedUrl); + string16 text; + TestCompletionCallback callback; + int result = pac_fetcher.Fetch(url, &text, &callback); + EXPECT_EQ(OK, result); + EXPECT_EQ(ASCIIToUTF16(kPacScript), text); + } + + const char kEncodedUrlBroken[] = + "data:application/x-ns-proxy-autoconfig;base64,ZnVuY3Rpb24gRmluZFByb3h5R"; + + // Test a broken "data:"-url containing a base64 encoded PAC script. + { + GURL url(kEncodedUrlBroken); + string16 text; + TestCompletionCallback callback; + int result = pac_fetcher.Fetch(url, &text, &callback); + EXPECT_EQ(ERR_FAILED, result); + } +} + } // namespace net diff --git a/net/proxy/proxy_server.h b/net/proxy/proxy_server.h index 3167252..c127aad 100644 --- a/net/proxy/proxy_server.h +++ b/net/proxy/proxy_server.h @@ -42,7 +42,7 @@ class ProxyServer { bool is_valid() const { return scheme_ != SCHEME_INVALID; } - // Gets the proxy's scheme (i.e. SOCKS4, SOCKS5, HTTP} + // Gets the proxy's scheme (i.e. SOCKS4, SOCKS5, HTTP) Scheme scheme() const { return scheme_; } // Returns true if this ProxyServer is actually just a DIRECT connection. @@ -158,6 +158,8 @@ class ProxyServer { HostPortPair host_port_pair_; }; +typedef std::pair<HostPortPair, ProxyServer> HostPortProxyPair; + } // namespace net #endif // NET_PROXY_PROXY_SERVER_H_ diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc index e493623..25155c2 100644 --- a/net/proxy/proxy_service.cc +++ b/net/proxy/proxy_service.cc @@ -384,7 +384,7 @@ ProxyService::ProxyService(ProxyConfigService* config_service, stall_proxy_auto_config_delay_( base::TimeDelta::FromMilliseconds( kNumMillisToStallAfterNetworkChanges)) { - NetworkChangeNotifier::AddObserver(this); + NetworkChangeNotifier::AddIPAddressObserver(this); ResetConfigService(config_service); } @@ -560,7 +560,7 @@ int ProxyService::TryToCompleteSynchronously(const GURL& url, } ProxyService::~ProxyService() { - NetworkChangeNotifier::RemoveObserver(this); + NetworkChangeNotifier::RemoveIPAddressObserver(this); config_service_->RemoveObserver(this); // Cancel any inprogress requests. diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h index 75ac3c9..72b76ef 100644 --- a/net/proxy/proxy_service.h +++ b/net/proxy/proxy_service.h @@ -34,7 +34,7 @@ class URLRequestContext; // HTTP(S) URL. It uses the given ProxyResolver to handle the actual proxy // resolution. See ProxyResolverV8 for example. class ProxyService : public base::RefCountedThreadSafe<ProxyService>, - public NetworkChangeNotifier::Observer, + public NetworkChangeNotifier::IPAddressObserver, public ProxyConfigService::Observer { public: // The instance takes ownership of |config_service| and |resolver|. @@ -280,7 +280,7 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService>, // Start initialization using |fetched_config_|. void InitializeUsingLastFetchedConfig(); - // NetworkChangeNotifier::Observer + // NetworkChangeNotifier::IPAddressObserver // When this is called, we re-fetch PAC scripts and re-run WPAD. virtual void OnIPAddressChanged(); |