summaryrefslogtreecommitdiffstats
path: root/net/proxy
diff options
context:
space:
mode:
authoreroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-08 04:05:10 +0000
committereroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-08 04:05:10 +0000
commitbd45292e5c21fcb3fef1fd5dfb8207ae29277f8a (patch)
tree1eca5cafa1a1b87a5f5182f1d7f12aaf588fc809 /net/proxy
parent3ffe71e020ea8e3597c2835f1ba0ebb8fb85ab9e (diff)
downloadchromium_src-bd45292e5c21fcb3fef1fd5dfb8207ae29277f8a.zip
chromium_src-bd45292e5c21fcb3fef1fd5dfb8207ae29277f8a.tar.gz
chromium_src-bd45292e5c21fcb3fef1fd5dfb8207ae29277f8a.tar.bz2
Adds a NetworkChangeNotifier dependency to ProxyService; when we observer a network change through the notifier, the ProxyService re-configures itself.
So for example, if you were to switch to VPN and are using a custom PAC URL, we will re-download that URL on the new network. Similarly if you are using auto-detect PAC settings, we will re-run the autodiscovery steps for the next resolve. Note that Chromium is still passing a NULL NetworkChangeNotifier dependency into its ProxyService -- until it passes a real implementation, this will not impact Chrome. BUG=12293 TEST=ProxyServiceTest.NetworkChangeTriggersPacRefetch Review URL: http://codereview.chromium.org/525104 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35772 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/proxy')
-rw-r--r--net/proxy/proxy_service.cc33
-rw-r--r--net/proxy/proxy_service.h20
-rw-r--r--net/proxy/proxy_service_unittest.cc187
3 files changed, 190 insertions, 50 deletions
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index 01a42ac..8160e64 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -198,13 +198,18 @@ class ProxyService::PacRequest
// ProxyService ---------------------------------------------------------------
ProxyService::ProxyService(ProxyConfigService* config_service,
- ProxyResolver* resolver)
+ ProxyResolver* resolver,
+ NetworkChangeNotifier* network_change_notifier)
: config_service_(config_service),
resolver_(resolver),
next_config_id_(1),
should_use_proxy_resolver_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(init_proxy_resolver_callback_(
- this, &ProxyService::OnInitProxyResolverComplete)) {
+ this, &ProxyService::OnInitProxyResolverComplete)),
+ network_change_notifier_(network_change_notifier) {
+ // Register to receive network change notifications.
+ if (network_change_notifier_)
+ network_change_notifier_->AddObserver(this);
}
// static
@@ -212,6 +217,7 @@ ProxyService* ProxyService::Create(
ProxyConfigService* proxy_config_service,
bool use_v8_resolver,
URLRequestContext* url_request_context,
+ NetworkChangeNotifier* network_change_notifier,
MessageLoop* io_loop) {
ProxyResolver* proxy_resolver;
@@ -231,7 +237,7 @@ ProxyService* ProxyService::Create(
proxy_resolver = new SingleThreadedProxyResolver(proxy_resolver);
ProxyService* proxy_service = new ProxyService(
- proxy_config_service, proxy_resolver);
+ proxy_config_service, proxy_resolver, network_change_notifier);
if (proxy_resolver->expects_pac_bytes()) {
// Configure PAC script downloads to be issued using |url_request_context|.
@@ -245,13 +251,15 @@ ProxyService* ProxyService::Create(
// static
ProxyService* ProxyService::CreateFixed(const ProxyConfig& pc) {
- return Create(new ProxyConfigServiceFixed(pc), false, NULL, NULL);
+ return Create(new ProxyConfigServiceFixed(pc), false, NULL, NULL, NULL);
}
// static
ProxyService* ProxyService::CreateNull() {
// Use a configuration fetcher and proxy resolver which always fail.
- return new ProxyService(new ProxyConfigServiceNull, new ProxyResolverNull);
+ return new ProxyService(new ProxyConfigServiceNull,
+ new ProxyResolverNull,
+ NULL);
}
int ProxyService::ResolveProxy(const GURL& raw_url,
@@ -354,6 +362,10 @@ void ProxyService::ApplyProxyRules(const GURL& url,
}
ProxyService::~ProxyService() {
+ // Unregister to receive network change notifications.
+ if (network_change_notifier_)
+ network_change_notifier_->RemoveObserver(this);
+
// Cancel any inprogress requests.
for (PendingRequests::iterator it = pending_requests_.begin();
it != pending_requests_.end();
@@ -736,6 +748,17 @@ bool ProxyService::IsLocalName(const GURL& url) {
return host.find('.') == std::string::npos;
}
+void ProxyService::OnIPAddressChanged() {
+ DCHECK(network_change_notifier_);
+
+ // Mark the current configuration as being un-initialized.
+ //
+ // This will force us to re-fetch the configuration (and re-run all of
+ // the initialization steps) on the next ResolveProxy() request, as part
+ // of UpdateConfigIfOld().
+ config_.set_id(ProxyConfig::INVALID_ID);
+}
+
SyncProxyServiceHelper::SyncProxyServiceHelper(MessageLoop* io_message_loop,
ProxyService* proxy_service)
: io_message_loop_(io_message_loop),
diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h
index 857ab93..8cca773 100644
--- a/net/proxy/proxy_service.h
+++ b/net/proxy/proxy_service.h
@@ -12,6 +12,7 @@
#include "base/scoped_ptr.h"
#include "base/waitable_event.h"
#include "net/base/completion_callback.h"
+#include "net/base/network_change_notifier.h"
#include "net/proxy/proxy_server.h"
#include "net/proxy/proxy_info.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
@@ -31,10 +32,15 @@ class ProxyScriptFetcher;
// This class can be used to resolve the proxy server to use when loading a
// HTTP(S) URL. It uses the given ProxyResolver to handle the actual proxy
// resolution. See ProxyResolverV8 for example.
-class ProxyService : public base::RefCountedThreadSafe<ProxyService> {
+class ProxyService : public base::RefCountedThreadSafe<ProxyService>,
+ public NetworkChangeNotifier::Observer {
public:
// The instance takes ownership of |config_service| and |resolver|.
- ProxyService(ProxyConfigService* config_service, ProxyResolver* resolver);
+ // If |network_change_notifier| is non-NULL, the proxy service will register
+ // with it to detect when the network setup has changed. This is used to
+ // decide when to re-configure the proxy discovery.
+ ProxyService(ProxyConfigService* config_service, ProxyResolver* resolver,
+ NetworkChangeNotifier* network_change_notifier);
// Used internally to handle PAC queries.
// TODO(eroman): consider naming this simply "Request".
@@ -126,6 +132,8 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService> {
// |url_request_context| is only used when use_v8_resolver is true:
// it specifies the URL request context that will be used if a PAC
// script needs to be fetched.
+ // |network_change_notifier| may be NULL. Otherwise it will be used to
+ // signal the ProxyService when the network setup has changed.
// |io_loop| points to the IO thread's message loop. It is only used
// when pc is NULL.
// ##########################################################################
@@ -137,6 +145,7 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService> {
ProxyConfigService* proxy_config_service,
bool use_v8_resolver,
URLRequestContext* url_request_context,
+ NetworkChangeNotifier* network_change_notifier,
MessageLoop* io_loop);
// Convenience method that creates a proxy service using the
@@ -238,6 +247,9 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService> {
// heuristic).
static bool IsLocalName(const GURL& url);
+ // NetworkChangeNotifier::Observer methods:
+ virtual void OnIPAddressChanged();
+
scoped_ptr<ProxyConfigService> config_service_;
scoped_ptr<ProxyResolver> resolver_;
@@ -277,6 +289,10 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService> {
// Log from the *last* time |init_proxy_resolver_.Init()| was called, or NULL.
scoped_refptr<LoadLog> init_proxy_resolver_log_;
+ // The (possibly NULL) network change notifier that we use to decide when
+ // to refetch PAC scripts or re-run WPAD.
+ scoped_refptr<NetworkChangeNotifier> network_change_notifier_;
+
DISALLOW_COPY_AND_ASSIGN(ProxyService);
};
diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc
index c256a44..f220ce1 100644
--- a/net/proxy/proxy_service_unittest.cc
+++ b/net/proxy/proxy_service_unittest.cc
@@ -12,6 +12,7 @@
#include "googleurl/src/gurl.h"
#include "net/base/load_log.h"
#include "net/base/load_log_unittest.h"
+#include "net/base/mock_network_change_notifier.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/proxy/mock_proxy_resolver.h"
@@ -91,7 +92,7 @@ class MockProxyScriptFetcher : public ProxyScriptFetcher {
TEST(ProxyServiceTest, Direct) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(new MockProxyConfigService, resolver));
+ new ProxyService(new MockProxyConfigService, resolver, NULL));
GURL url("http://www.google.com/");
@@ -118,7 +119,7 @@ TEST(ProxyServiceTest, PAC) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
GURL url("http://www.google.com/");
@@ -163,7 +164,7 @@ TEST(ProxyServiceTest, PAC_NoIdentityOrHash) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
GURL url("http://username:password@www.google.com/?ref#hash#hash");
@@ -191,7 +192,7 @@ TEST(ProxyServiceTest, PAC_FailoverWithoutDirect) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
GURL url("http://www.google.com/");
@@ -248,7 +249,7 @@ TEST(ProxyServiceTest, PAC_FailoverAfterDirect) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
GURL url("http://www.google.com/");
@@ -310,7 +311,7 @@ TEST(ProxyServiceTest, ProxyResolverFails) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
// Start first resolve request.
GURL url("http://www.google.com/");
@@ -360,7 +361,7 @@ TEST(ProxyServiceTest, ProxyFallback) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
GURL url("http://www.google.com/");
@@ -438,7 +439,7 @@ TEST(ProxyServiceTest, ProxyFallbackToDirect) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
GURL url("http://www.google.com/");
@@ -498,7 +499,7 @@ TEST(ProxyServiceTest, ProxyFallback_NewSettings) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
GURL url("http://www.google.com/");
@@ -587,7 +588,7 @@ TEST(ProxyServiceTest, ProxyFallback_BadConfig) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
GURL url("http://www.google.com/");
@@ -671,7 +672,9 @@ TEST(ProxyServiceTest, ProxyBypassList) {
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver()));
+ new MockProxyConfigService(config),
+ new MockAsyncProxyResolver(),
+ NULL));
GURL url("http://www.google.com/");
// Get the proxy information.
TestCompletionCallback callback;
@@ -682,7 +685,9 @@ TEST(ProxyServiceTest, ProxyBypassList) {
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver()));
+ new MockProxyConfigService(config),
+ new MockAsyncProxyResolver(),
+ NULL));
GURL test_url("http://local");
TestCompletionCallback callback;
int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
@@ -695,7 +700,7 @@ TEST(ProxyServiceTest, ProxyBypassList) {
config.proxy_bypass_local_names = true;
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("http://www.webkit.org");
TestCompletionCallback callback;
int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
@@ -709,7 +714,7 @@ TEST(ProxyServiceTest, ProxyBypassList) {
config.proxy_bypass_local_names = true;
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("http://74.125.19.147");
TestCompletionCallback callback;
int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
@@ -722,7 +727,7 @@ TEST(ProxyServiceTest, ProxyBypassList) {
config.proxy_bypass_local_names = true;
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("http://www.msn.com");
TestCompletionCallback callback;
int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
@@ -735,7 +740,7 @@ TEST(ProxyServiceTest, ProxyBypassList) {
config.proxy_bypass_local_names = true;
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("http://www.msnbc.msn.com");
TestCompletionCallback callback;
int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
@@ -748,7 +753,7 @@ TEST(ProxyServiceTest, ProxyBypassList) {
config.proxy_bypass_local_names = true;
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("HTTP://WWW.MSNBC.MSN.COM");
TestCompletionCallback callback;
int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
@@ -769,7 +774,7 @@ TEST(ProxyServiceTest, ProxyBypassListWithPorts) {
config.proxy_bypass.push_back("*.example.com:99");
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
{
GURL test_url("http://www.example.com:99");
TestCompletionCallback callback;
@@ -797,7 +802,7 @@ TEST(ProxyServiceTest, ProxyBypassListWithPorts) {
config.proxy_bypass.push_back("*.example.com:80");
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("http://www.example.com");
TestCompletionCallback callback;
int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
@@ -809,7 +814,7 @@ TEST(ProxyServiceTest, ProxyBypassListWithPorts) {
config.proxy_bypass.push_back("*.example.com");
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("http://www.example.com:99");
TestCompletionCallback callback;
int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
@@ -822,7 +827,7 @@ TEST(ProxyServiceTest, ProxyBypassListWithPorts) {
config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]:99");
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
{
GURL test_url("http://[3ffe:2a00:100:7031::1]:99/");
TestCompletionCallback callback;
@@ -846,7 +851,7 @@ TEST(ProxyServiceTest, ProxyBypassListWithPorts) {
config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]");
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
{
GURL test_url("http://[3ffe:2a00:100:7031::1]:99/");
TestCompletionCallback callback;
@@ -870,7 +875,7 @@ TEST(ProxyServiceTest, PerProtocolProxyTests) {
config.auto_detect = false;
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("http://www.msn.com");
ProxyInfo info;
TestCompletionCallback callback;
@@ -881,7 +886,7 @@ TEST(ProxyServiceTest, PerProtocolProxyTests) {
}
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("ftp://ftp.google.com");
ProxyInfo info;
TestCompletionCallback callback;
@@ -892,7 +897,7 @@ TEST(ProxyServiceTest, PerProtocolProxyTests) {
}
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("https://webbranch.techcu.com");
ProxyInfo info;
TestCompletionCallback callback;
@@ -904,7 +909,7 @@ TEST(ProxyServiceTest, PerProtocolProxyTests) {
{
config.proxy_rules.ParseFromString("foopy1:8080");
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("http://www.microsoft.com");
ProxyInfo info;
TestCompletionCallback callback;
@@ -926,7 +931,7 @@ TEST(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("http://www.msn.com");
ProxyInfo info;
TestCompletionCallback callback;
@@ -937,7 +942,7 @@ TEST(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
}
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("ftp://ftp.google.com");
ProxyInfo info;
TestCompletionCallback callback;
@@ -948,7 +953,7 @@ TEST(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
}
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("https://webbranch.techcu.com");
ProxyInfo info;
TestCompletionCallback callback;
@@ -959,7 +964,7 @@ TEST(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
}
{
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver));
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
GURL test_url("unknown://www.microsoft.com");
ProxyInfo info;
TestCompletionCallback callback;
@@ -978,7 +983,7 @@ TEST(ProxyServiceTest, CancelInProgressRequest) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
// Start 3 requests.
@@ -1053,7 +1058,7 @@ TEST(ProxyServiceTest, InitialPACScriptDownload) {
new MockAsyncProxyResolverExpectsBytes;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
service->SetProxyScriptFetcher(fetcher);
@@ -1132,7 +1137,7 @@ TEST(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
new MockAsyncProxyResolverExpectsBytes;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
service->SetProxyScriptFetcher(fetcher);
@@ -1189,7 +1194,7 @@ TEST(ProxyServiceTest, CancelWhilePACFetching) {
new MockAsyncProxyResolverExpectsBytes;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
service->SetProxyScriptFetcher(fetcher);
@@ -1274,7 +1279,7 @@ TEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
MockAsyncProxyResolverExpectsBytes* resolver =
new MockAsyncProxyResolverExpectsBytes;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
service->SetProxyScriptFetcher(fetcher);
@@ -1345,7 +1350,7 @@ TEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
MockAsyncProxyResolverExpectsBytes* resolver =
new MockAsyncProxyResolverExpectsBytes;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
service->SetProxyScriptFetcher(fetcher);
@@ -1421,7 +1426,7 @@ TEST(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
MockAsyncProxyResolverExpectsBytes* resolver =
new MockAsyncProxyResolverExpectsBytes;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
service->SetProxyScriptFetcher(fetcher);
@@ -1479,7 +1484,7 @@ TEST(ProxyServiceTest, BypassDoesntApplyToPac) {
MockAsyncProxyResolverExpectsBytes* resolver =
new MockAsyncProxyResolverExpectsBytes;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
service->SetProxyScriptFetcher(fetcher);
@@ -1547,7 +1552,7 @@ TEST(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
MockAsyncProxyResolverExpectsBytes* resolver =
new MockAsyncProxyResolverExpectsBytes;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
service->SetProxyScriptFetcher(fetcher);
@@ -1583,7 +1588,7 @@ TEST(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingSet) {
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
GURL url("http://www.google.com/");
@@ -1604,7 +1609,9 @@ TEST(ProxyServiceTest, ResetProxyConfigService) {
config1.proxy_rules.ParseFromString("foopy1:8080");
config1.auto_detect = false;
scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config1), new MockAsyncProxyResolverExpectsBytes));
+ new MockProxyConfigService(config1),
+ new MockAsyncProxyResolverExpectsBytes,
+ NULL));
ProxyInfo info;
TestCompletionCallback callback1;
@@ -1677,7 +1684,7 @@ TEST(ProxyServiceTest, UpdateConfigAfterFailedAutodetect) {
MockProxyConfigService* config_service = new MockProxyConfigService(config);
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
// Start 1 requests.
@@ -1723,7 +1730,7 @@ TEST(ProxyServiceTest, UpdateConfigFromPACToDirect) {
MockProxyConfigService* config_service = new MockProxyConfigService(config);
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
scoped_refptr<ProxyService> service(
- new ProxyService(config_service, resolver));
+ new ProxyService(config_service, resolver, NULL));
// Start 1 request.
@@ -1768,4 +1775,98 @@ TEST(ProxyServiceTest, UpdateConfigFromPACToDirect) {
EXPECT_TRUE(info2.is_direct());
}
+TEST(ProxyServiceTest, NetworkChangeTriggersPacRefetch) {
+ MockProxyConfigService* config_service =
+ new MockProxyConfigService("http://foopy/proxy.pac");
+
+ MockAsyncProxyResolverExpectsBytes* resolver =
+ new MockAsyncProxyResolverExpectsBytes;
+
+ scoped_refptr<MockNetworkChangeNotifier> network_change_notifier(
+ new MockNetworkChangeNotifier());
+
+ scoped_refptr<ProxyService> service(
+ new ProxyService(config_service, resolver, network_change_notifier));
+
+ MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+ service->SetProxyScriptFetcher(fetcher);
+
+ // Start 1 request.
+
+ ProxyInfo info1;
+ TestCompletionCallback callback1;
+ int rv = service->ResolveProxy(
+ GURL("http://request1"), &info1, &callback1, NULL, NULL);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ // The first request should have triggered initial download of PAC script.
+ EXPECT_TRUE(fetcher->has_pending_request());
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+ // Nothing has been sent to the resolver yet.
+ EXPECT_TRUE(resolver->pending_requests().empty());
+
+ // At this point the ProxyService should be waiting for the
+ // ProxyScriptFetcher to invoke its completion callback, notifying it of
+ // PAC script download completion.
+ fetcher->NotifyFetchCompletion(OK, "pac-v1");
+
+ // Now that the PAC script is downloaded, the request will have been sent to
+ // the proxy resolver.
+ EXPECT_EQ("pac-v1", resolver->pending_set_pac_script_request()->pac_bytes());
+ resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+
+ // Complete the pending request.
+ resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+ resolver->pending_requests()[0]->CompleteNow(OK);
+
+ // Wait for completion callback, and verify that the request ran as expected.
+ EXPECT_EQ(OK, callback1.WaitForResult());
+ EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+ // Now simluate a change in the network. The ProxyConfigService is still
+ // going to return the same PAC URL as before, but this URL needs to be
+ // refetched on the new network.
+
+ network_change_notifier->NotifyIPAddressChange();
+
+ // Start a second request.
+ ProxyInfo info2;
+ TestCompletionCallback callback2;
+ rv = service->ResolveProxy(
+ GURL("http://request2"), &info2, &callback2, NULL, NULL);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ // This second request should have triggered the re-download of the PAC
+ // script (since we marked the network as having changed).
+ EXPECT_TRUE(fetcher->has_pending_request());
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+ // Nothing has been sent to the resolver yet.
+ EXPECT_TRUE(resolver->pending_requests().empty());
+
+ // Simulate the PAC script fetch as having completed (this time with
+ // different data).
+ fetcher->NotifyFetchCompletion(OK, "pac-v2");
+
+ // Now that the PAC script is downloaded, the second request will have been
+ // sent to the proxy resolver.
+ EXPECT_EQ("pac-v2", resolver->pending_set_pac_script_request()->pac_bytes());
+ resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+ ASSERT_EQ(1u, resolver->pending_requests().size());
+ EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
+
+ // Complete the pending second request.
+ resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
+ resolver->pending_requests()[0]->CompleteNow(OK);
+
+ // Wait for completion callback, and verify that the request ran as expected.
+ EXPECT_EQ(OK, callback2.WaitForResult());
+ EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
+}
+
} // namespace net