summaryrefslogtreecommitdiffstats
path: root/net/proxy
diff options
context:
space:
mode:
Diffstat (limited to 'net/proxy')
-rw-r--r--net/proxy/init_proxy_resolver.cc12
-rw-r--r--net/proxy/init_proxy_resolver.h2
-rw-r--r--net/proxy/mock_proxy_resolver.cc115
-rw-r--r--net/proxy/proxy_script_fetcher.h7
-rw-r--r--net/proxy/proxy_script_fetcher_impl.cc13
-rw-r--r--net/proxy/proxy_script_fetcher_impl_unittest.cc66
-rw-r--r--net/proxy/proxy_server.h4
-rw-r--r--net/proxy/proxy_service.cc4
-rw-r--r--net/proxy/proxy_service.h4
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();