proxy_service.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 165e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/thread_task_runner_handle.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/dhcp_proxy_script_fetcher.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/multi_threaded_proxy_resolver.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/network_delegate_error_observer.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config_service_fixed.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_resolver.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_script_decider.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_script_fetcher.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h" 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config_service_win.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_resolver_winhttp.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_IOS) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config_service_ios.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_resolver_mac.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config_service_mac.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_resolver_mac.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_LINUX) && !defined(OS_CHROMEOS) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config_service_linux.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_ANDROID) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config_service_android.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t kMaxNumNetLogEntries = 100; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When the IP address changes we don't immediately re-run proxy auto-config. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Instead, we wait for |kDelayAfterNetworkChangesMs| before 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// attempting to re-valuate proxy auto-config. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// During this time window, any resolve requests sent to the ProxyService will 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be queued. Once we have waited the required amount of them, the proxy 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// auto-config step will be run, and the queued requests resumed. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The reason we play this game is that our signal for detecting network 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// changes (NetworkChangeNotifier) may fire *before* the system's networking 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dependencies are fully configured. This is a problem since it means if 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we were to run proxy auto-config right away, it could fail due to spurious 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DNS failures. (see http://crbug.com/50779 for more details.) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// By adding the wait window, we give things a better chance to get properly 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// set up. Network failures can happen at any time though, so we additionally 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// poll the PAC script for changes, which will allow us to recover from these 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sorts of problems. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kDelayAfterNetworkChangesMs = 2000; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the default policy for polling the PAC script. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In response to a failure, the poll intervals are: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 0: 8 seconds (scheduled on timer) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1: 32 seconds 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2: 2 minutes 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3+: 4 hours 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In response to a success, the poll intervals are: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 0+: 12 hours 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Only the 8 second poll is scheduled on a timer, the rest happen in response 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to network activity (and hence will take longer than the written time). 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Explanation for these values: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(eroman): These values are somewhat arbitrary, and need to be tuned 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// using some histograms data. Trying to be conservative so as not to break 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// existing setups when deployed. A simple exponential retry scheme would be 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// more elegant, but places more load on server. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The motivation for trying quickly after failures (8 seconds) is to recover 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from spurious network failures, which are common after the IP address has 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// just changed (like DNS failing to resolve). The next 32 second boundary is 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to try and catch other VPN weirdness which anecdotally I have seen take 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 10+ seconds for some users. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The motivation for re-trying after a success is to check for possible 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// content changes to the script, or to the WPAD auto-discovery results. We are 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not very aggressive with these checks so as to minimize the risk of 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// overloading existing PAC setups. Moreover it is unlikely that PAC scripts 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// change very frequently in existing setups. More research is needed to 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// motivate what safe values are here, and what other user agents do. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Comparison to other browsers: 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In Firefox the PAC URL is re-tried on failures according to 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// network.proxy.autoconfig_retry_interval_min and 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// network.proxy.autoconfig_retry_interval_max. The defaults are 5 seconds and 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5 minutes respectively. It doubles the interval at each attempt. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(eroman): Figure out what Internet Explorer does. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DefaultPollPolicy : public ProxyService::PacPollPolicy { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultPollPolicy() {} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Mode GetNextDelay(int initial_error, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta current_delay, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta* next_delay) const OVERRIDE { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initial_error != OK) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Re-try policy for failures. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kDelay1Seconds = 8; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kDelay2Seconds = 32; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kDelay3Seconds = 2 * 60; // 2 minutes 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kDelay4Seconds = 4 * 60 * 60; // 4 Hours 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initial poll. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_delay < TimeDelta()) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *next_delay = TimeDelta::FromSeconds(kDelay1Seconds); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MODE_USE_TIMER; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (current_delay.InSeconds()) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kDelay1Seconds: 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *next_delay = TimeDelta::FromSeconds(kDelay2Seconds); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MODE_START_AFTER_ACTIVITY; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kDelay2Seconds: 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *next_delay = TimeDelta::FromSeconds(kDelay3Seconds); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MODE_START_AFTER_ACTIVITY; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *next_delay = TimeDelta::FromSeconds(kDelay4Seconds); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MODE_START_AFTER_ACTIVITY; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Re-try policy for succeses. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *next_delay = TimeDelta::FromHours(12); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MODE_START_AFTER_ACTIVITY; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DefaultPollPolicy); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Config getter that always returns direct settings. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProxyConfigServiceDirect : public ProxyConfigService { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ProxyConfigService implementation: 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddObserver(Observer* observer) OVERRIDE {} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RemoveObserver(Observer* observer) OVERRIDE {} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OVERRIDE { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *config = ProxyConfig::CreateDirect(); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config->set_source(PROXY_CONFIG_SOURCE_UNKNOWN); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CONFIG_VALID; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Proxy resolver that fails every time. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProxyResolverNull : public ProxyResolver { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolverNull() : ProxyResolver(false /*expects_pac_bytes*/) {} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ProxyResolver implementation. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetProxyForURL(const GURL& url, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyInfo* results, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestHandle* request, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) OVERRIDE { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_NOT_IMPLEMENTED; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void CancelRequest(RequestHandle request) OVERRIDE { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LOAD_STATE_IDLE; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void CancelSetPacScript() OVERRIDE { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int SetPacScript( 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<ProxyResolverScriptData>& /*script_data*/, 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& /*callback*/) OVERRIDE { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_NOT_IMPLEMENTED; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProxyResolver that simulates a PAC script which returns 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |pac_string| for every single URL. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProxyResolverFromPacString : public ProxyResolver { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit ProxyResolverFromPacString(const std::string& pac_string) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ProxyResolver(false /*expects_pac_bytes*/), 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pac_string_(pac_string) {} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetProxyForURL(const GURL& url, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyInfo* results, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestHandle* request, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) OVERRIDE { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results->UsePacString(pac_string_); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void CancelRequest(RequestHandle request) OVERRIDE { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LOAD_STATE_IDLE; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void CancelSetPacScript() OVERRIDE { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int SetPacScript( 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<ProxyResolverScriptData>& pac_script, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback) OVERRIDE { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string pac_string_; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates ProxyResolvers using a platform-specific implementation. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProxyResolverFactoryForSystem : public ProxyResolverFactory { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolverFactoryForSystem() 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ProxyResolverFactory(false /*expects_pac_bytes*/) {} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ProxyResolver* CreateProxyResolver() OVERRIDE { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsSupported()); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ProxyResolverWinHttp(); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ProxyResolverMac(); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool IsSupported() { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) || defined(OS_MACOSX) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns NetLog parameters describing a proxy configuration change. 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Value* NetLogProxyConfigChangedCallback( 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ProxyConfig* old_config, 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ProxyConfig* new_config, 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog::LogLevel /* log_level */) { 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The "old_config" is optional -- the first notification will not have 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any "previous" configuration. 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_config->is_valid()) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set("old_config", old_config->ToValue()); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set("new_config", new_config->ToValue()); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Value* NetLogBadProxyListCallback(const ProxyRetryInfoMap* retry_info, 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog::LogLevel /* log_level */) { 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* list = new base::ListValue(); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ProxyRetryInfoMap::const_iterator iter = retry_info->begin(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != retry_info->end(); ++iter) { 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) list->Append(new base::StringValue(iter->first)); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set("bad_proxy_list", list); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns NetLog parameters on a successfuly proxy resolution. 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Value* NetLogFinishedResolvingProxyCallback( 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyInfo* result, 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog::LogLevel /* log_level */) { 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("pac_string", result->ToPacString()); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UnsetProxyConfigService : public ProxyConfigService { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnsetProxyConfigService() {} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~UnsetProxyConfigService() {} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddObserver(Observer* observer) OVERRIDE {} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RemoveObserver(Observer* observer) OVERRIDE {} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ConfigAvailability GetLatestProxyConfig( 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfig* config) OVERRIDE { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CONFIG_UNSET; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProxyService::InitProxyResolver -------------------------------------------- 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This glues together two asynchronous steps: 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (1) ProxyScriptDecider -- try to fetch/validate a sequence of PAC scripts 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to figure out what we should configure against. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (2) Feed the fetched PAC script into the ProxyResolver. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InitProxyResolver is a single-use class which encapsulates cancellation as 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// part of its destructor. Start() or StartSkipDecider() should be called just 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once. The instance can be destroyed at any time, and the request will be 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cancelled. 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProxyService::InitProxyResolver { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitProxyResolver() 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : proxy_resolver_(NULL), 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_(STATE_NONE) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~InitProxyResolver() { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that the destruction of ProxyScriptDecider will automatically cancel 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any outstanding work. 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_state_ == STATE_SET_PAC_SCRIPT_COMPLETE) { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_resolver_->CancelSetPacScript(); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Begins initializing the proxy resolver; calls |callback| when done. 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int Start(ProxyResolver* proxy_resolver, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyScriptFetcher* proxy_script_fetcher, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher, 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog* net_log, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyConfig& config, 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta wait_delay, 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback) { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_NONE, next_state_); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_resolver_ = proxy_resolver; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decider_.reset(new ProxyScriptDecider( 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_script_fetcher, dhcp_proxy_script_fetcher, net_log)); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = config; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_delay_ = wait_delay; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_ = callback; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_DECIDE_PROXY_SCRIPT; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DoLoop(OK); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Similar to Start(), however it skips the ProxyScriptDecider stage. Instead 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |effective_config|, |decider_result| and |script_data| will be used as the 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inputs for initializing the ProxyResolver. 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int StartSkipDecider(ProxyResolver* proxy_resolver, 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyConfig& effective_config, 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int decider_result, 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolverScriptData* script_data, 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback) { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_NONE, next_state_); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_resolver_ = proxy_resolver; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effective_config_ = effective_config; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_data_ = script_data; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_ = callback; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decider_result != OK) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return decider_result; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_SET_PAC_SCRIPT; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DoLoop(OK); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the proxy configuration that was selected by ProxyScriptDecider. 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should only be called upon completion of the initialization. 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyConfig& effective_config() const { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_NONE, next_state_); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return effective_config_; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the PAC script data that was selected by ProxyScriptDecider. 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should only be called upon completion of the initialization. 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolverScriptData* script_data() { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_NONE, next_state_); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return script_data_.get(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadState GetLoadState() const { 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (next_state_ == STATE_DECIDE_PROXY_SCRIPT_COMPLETE) { 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In addition to downloading, this state may also include the stall time 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // after network change events (kDelayAfterNetworkChangesMs). 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return LOAD_STATE_DOWNLOADING_PROXY_SCRIPT; 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return LOAD_STATE_RESOLVING_PROXY_FOR_URL; 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum State { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_NONE, 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_DECIDE_PROXY_SCRIPT, 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_DECIDE_PROXY_SCRIPT_COMPLETE, 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_SET_PAC_SCRIPT, 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_SET_PAC_SCRIPT_COMPLETE, 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoLoop(int result) { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(next_state_, STATE_NONE); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = result; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State state = next_state_; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_NONE; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state) { 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_DECIDE_PROXY_SCRIPT: 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoDecideProxyScript(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_DECIDE_PROXY_SCRIPT_COMPLETE: 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoDecideProxyScriptComplete(rv); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SET_PAC_SCRIPT: 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoSetPacScript(); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SET_PAC_SCRIPT_COMPLETE: 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoSetPacScriptComplete(rv); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "bad state: " << state; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ERR_UNEXPECTED; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoDecideProxyScript() { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_DECIDE_PROXY_SCRIPT_COMPLETE; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return decider_->Start( 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_, wait_delay_, proxy_resolver_->expects_pac_bytes(), 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&InitProxyResolver::OnIOCompletion, base::Unretained(this))); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoDecideProxyScriptComplete(int result) { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != OK) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effective_config_ = decider_->effective_config(); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_data_ = decider_->script_data(); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_SET_PAC_SCRIPT; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoSetPacScript() { 480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(script_data_.get()); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(eroman): Should log this latency to the NetLog. 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_SET_PAC_SCRIPT_COMPLETE; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proxy_resolver_->SetPacScript( 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_data_, 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&InitProxyResolver::OnIOCompletion, base::Unretained(this))); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoSetPacScriptComplete(int result) { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnIOCompletion(int result) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(STATE_NONE, next_state_); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = DoLoop(result); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != ERR_IO_PENDING) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoCallback(rv); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoCallback(int result) { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(ERR_IO_PENDING, result); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(result); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfig config_; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfig effective_config_; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ProxyResolverScriptData> script_data_; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta wait_delay_; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ProxyScriptDecider> decider_; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolver* proxy_resolver_; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback callback_; 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State next_state_; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(InitProxyResolver); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProxyService::ProxyScriptDeciderPoller ------------------------------------- 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This helper class encapsulates the logic to schedule and run periodic 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// background checks to see if the PAC script (or effective proxy configuration) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// has changed. If a change is detected, then the caller will be notified via 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the ChangeCallback. 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProxyService::ProxyScriptDeciderPoller { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(int, ProxyResolverScriptData*, 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyConfig&)> ChangeCallback; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Builds a poller helper, and starts polling for updates. Whenever a change 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is observed, |callback| will be invoked with the details. 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |config| specifies the (unresolved) proxy configuration to poll. 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |proxy_resolver_expects_pac_bytes| the type of proxy resolver we expect 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to use the resulting script data with 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (so it can choose the right format). 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |proxy_script_fetcher| this pointer must remain alive throughout our 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lifetime. It is the dependency that will be used 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for downloading proxy scripts. 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |dhcp_proxy_script_fetcher| similar to |proxy_script_fetcher|, but for 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the DHCP dependency. 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |init_net_error| This is the initial network error (possibly success) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // encountered by the first PAC fetch attempt. We use it 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to schedule updates more aggressively if the initial 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fetch resulted in an error. 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |init_script_data| the initial script data from the PAC fetch attempt. 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the baseline used to determine when the 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // script's contents have changed. 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |net_log| the NetLog to log progress into. 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyScriptDeciderPoller(ChangeCallback callback, 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyConfig& config, 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool proxy_resolver_expects_pac_bytes, 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyScriptFetcher* proxy_script_fetcher, 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher, 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int init_net_error, 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolverScriptData* init_script_data, 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog* net_log) 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : weak_factory_(this), 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_callback_(callback), 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_(config), 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_resolver_expects_pac_bytes_(proxy_resolver_expects_pac_bytes), 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_script_fetcher_(proxy_script_fetcher), 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dhcp_proxy_script_fetcher_(dhcp_proxy_script_fetcher), 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_error_(init_net_error), 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_script_data_(init_script_data), 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_poll_time_(TimeTicks::Now()) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the initial poll delay. 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_poll_mode_ = poll_policy()->GetNextDelay( 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_error_, TimeDelta::FromSeconds(-1), &next_poll_delay_); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryToStartNextPoll(false); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnLazyPoll() { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have just been notified of network activity. Use this opportunity to 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // see if we can start our next poll. 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryToStartNextPoll(true); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const PacPollPolicy* set_policy(const PacPollPolicy* policy) { 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PacPollPolicy* prev = poll_policy_; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) poll_policy_ = policy; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return prev; 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the effective poll policy (the one injected by unit-tests, or the 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default). 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PacPollPolicy* poll_policy() { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (poll_policy_) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return poll_policy_; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &default_poll_policy_; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartPollTimer() { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!decider_.get()); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ProxyScriptDeciderPoller::DoPoll, 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr()), 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_poll_delay_); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void TryToStartNextPoll(bool triggered_by_activity) { 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (next_poll_mode_) { 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PacPollPolicy::MODE_USE_TIMER: 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!triggered_by_activity) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartPollTimer(); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PacPollPolicy::MODE_START_AFTER_ACTIVITY: 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (triggered_by_activity && !decider_.get()) { 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta elapsed_time = TimeTicks::Now() - last_poll_time_; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (elapsed_time >= next_poll_delay_) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoPoll(); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoPoll() { 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_poll_time_ = TimeTicks::Now(); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the proxy script decider to see if anything has changed. 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(eroman): Pass a proper NetLog rather than NULL. 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decider_.reset(new ProxyScriptDecider( 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_script_fetcher_, dhcp_proxy_script_fetcher_, NULL)); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = decider_->Start( 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_, TimeDelta(), proxy_resolver_expects_pac_bytes_, 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ProxyScriptDeciderPoller::OnProxyScriptDeciderCompleted, 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != ERR_IO_PENDING) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnProxyScriptDeciderCompleted(result); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnProxyScriptDeciderCompleted(int result) { 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasScriptDataChanged(result, decider_->script_data())) { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Something has changed, we must notify the ProxyService so it can 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // re-initialize its ProxyResolver. Note that we post a notification task 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rather than calling it directly -- this is done to avoid an ugly 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destruction sequence, since |this| might be destroyed as a result of 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the notification. 64190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 64290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 64390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&ProxyScriptDeciderPoller::NotifyProxyServiceOfChange, 64490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_factory_.GetWeakPtr(), 64590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) result, 64690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) make_scoped_refptr(decider_->script_data()), 64790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decider_->effective_config())); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decider_.reset(); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Decide when the next poll should take place, and possibly start the 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // next timer. 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_poll_mode_ = poll_policy()->GetNextDelay( 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_error_, next_poll_delay_, &next_poll_delay_); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryToStartNextPoll(false); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasScriptDataChanged(int result, ProxyResolverScriptData* script_data) { 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != last_error_) { 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Something changed -- it was failing before and now it succeeded, or 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // conversely it succeeded before and now it failed. Or it failed in 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // both cases, however the specific failure error codes differ. 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != OK) { 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If it failed last time and failed again with the same error code this 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // time, then nothing has actually changed. 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise if it succeeded both this time and last time, we need to look 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // closer and see if we ended up downloading different content for the PAC 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // script. 677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !script_data->Equals(last_script_data_.get()); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NotifyProxyServiceOfChange( 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result, 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<ProxyResolverScriptData>& script_data, 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyConfig& effective_config) { 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that |this| may be deleted after calling into the ProxyService. 685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) change_callback_.Run(result, script_data.get(), effective_config); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<ProxyScriptDeciderPoller> weak_factory_; 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeCallback change_callback_; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfig config_; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool proxy_resolver_expects_pac_bytes_; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyScriptFetcher* proxy_script_fetcher_; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher_; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int last_error_; 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ProxyResolverScriptData> last_script_data_; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ProxyScriptDecider> decider_; 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta next_poll_delay_; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PacPollPolicy::Mode next_poll_mode_; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks last_poll_time_; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Polling policy injected by unit-tests. Otherwise this is NULL and the 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default policy will be used. 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const PacPollPolicy* poll_policy_; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DefaultPollPolicy default_poll_policy_; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ProxyScriptDeciderPoller); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProxyService::PacPollPolicy* 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyService::ProxyScriptDeciderPoller::poll_policy_ = NULL; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProxyService::PacRequest --------------------------------------------------- 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProxyService::PacRequest 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::RefCounted<ProxyService::PacRequest> { 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PacRequest(ProxyService* service, 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url, 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyInfo* results, 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::CompletionCallback& user_callback, 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BoundNetLog& net_log) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : service_(service), 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_callback_(user_callback), 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_(results), 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_(url), 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resolve_job_(NULL), 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_id_(ProxyConfig::kInvalidConfigID), 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_source_(PROXY_CONFIG_SOURCE_UNKNOWN), 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_(net_log) { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!user_callback.is_null()); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts the resolve proxy request. 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int Start() { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!was_cancelled()); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_started()); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(service_->config_.is_valid()); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_id_ = service_->config_.id(); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_source_ = service_->config_.source(); 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxy_resolve_start_time_ = TimeTicks::Now(); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return resolver()->GetProxyForURL( 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_, results_, 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PacRequest::QueryComplete, base::Unretained(this)), 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &resolve_job_, net_log_); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_started() const { 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that !! casts to bool. (VS gives a warning otherwise). 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !!resolve_job_; 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartAndCompleteCheckingForSynchronous() { 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = service_->TryToCompleteSynchronously(url_, results_); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = Start(); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != ERR_IO_PENDING) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueryComplete(rv); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CancelResolveJob() { 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_started()); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The request may already be running in the resolver. 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resolver()->CancelRequest(resolve_job_); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resolve_job_ = NULL; 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_started()); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Cancel() { 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.AddEvent(NetLog::TYPE_CANCELLED); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_started()) 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelResolveJob(); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark as cancelled, to prevent accessing this again later. 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_ = NULL; 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_callback_.Reset(); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = NULL; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.EndEvent(NetLog::TYPE_PROXY_SERVICE); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if Cancel() has been called. 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_cancelled() const { 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return user_callback_.is_null(); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper to call after ProxyResolver completion (both synchronous and 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // asynchronous). Fixes up the result that is to be returned to user. 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int QueryDidComplete(int result_code) { 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!was_cancelled()); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that DidFinishResolvingProxy might modify |results_|. 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = service_->DidFinishResolvingProxy(results_, result_code, net_log_); 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a note in the results which configuration was in use at the 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // time of the resolve. 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_->config_id_ = config_id_; 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_->config_source_ = config_source_; 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_->did_use_pac_script_ = true; 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) results_->proxy_resolve_start_time_ = proxy_resolve_start_time_; 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) results_->proxy_resolve_end_time_ = TimeTicks::Now(); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset the state associated with in-progress-resolve. 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resolve_job_ = NULL; 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_id_ = ProxyConfig::kInvalidConfigID; 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_source_ = PROXY_CONFIG_SOURCE_UNKNOWN; 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog* net_log() { return &net_log_; } 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadState GetLoadState() const { 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_started()) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return resolver()->GetLoadState(resolve_job_); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LOAD_STATE_RESOLVING_PROXY_FOR_URL; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<ProxyService::PacRequest>; 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~PacRequest() {} 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callback for when the ProxyResolver request has completed. 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void QueryComplete(int result_code) { 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_code = QueryDidComplete(result_code); 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove this completed PacRequest from the service's pending list. 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// (which will probably cause deletion of |this|). 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!user_callback_.is_null()) { 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback callback = user_callback_; 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_->RemovePendingRequest(this); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(result_code); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolver* resolver() const { return service_->resolver_.get(); } 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that we don't hold a reference to the ProxyService. Outstanding 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requests are cancelled during ~ProxyService, so this is guaranteed 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be valid throughout our lifetime. 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyService* service_; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback user_callback_; 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyInfo* results_; 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url_; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolver::RequestHandle resolve_job_; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfig::ID config_id_; // The config id when the resolve was started. 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfigSource config_source_; // The source of proxy settings. 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog net_log_; 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Time when the PAC is started. Cached here since resetting ProxyInfo also 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // clears the proxy times. 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TimeTicks proxy_resolve_start_time_; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProxyService --------------------------------------------------------------- 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyService::ProxyService(ProxyConfigService* config_service, 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolver* resolver, 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog* net_log) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : resolver_(resolver), 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_config_id_(1), 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_state_(STATE_NONE) , 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_(net_log), 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stall_proxy_auto_config_delay_(TimeDelta::FromMilliseconds( 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kDelayAfterNetworkChangesMs)) { 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkChangeNotifier::AddIPAddressObserver(this); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkChangeNotifier::AddDNSObserver(this); 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetConfigService(config_service); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyService* ProxyService::CreateUsingSystemProxyResolver( 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfigService* proxy_config_service, 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_pac_threads, 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog* net_log) { 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(proxy_config_service); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ProxyResolverFactoryForSystem::IsSupported()) { 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "PAC support disabled because there is no " 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "system implementation"; 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateWithoutProxyResolver(proxy_config_service, net_log); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_pac_threads == 0) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_pac_threads = kDefaultNumPacThreads; 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolver* proxy_resolver = new MultiThreadedProxyResolver( 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ProxyResolverFactoryForSystem(), num_pac_threads); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ProxyService(proxy_config_service, proxy_resolver, net_log); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyService* ProxyService::CreateWithoutProxyResolver( 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfigService* proxy_config_service, 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog* net_log) { 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ProxyService(proxy_config_service, 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ProxyResolverNull(), 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log); 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyService* ProxyService::CreateFixed(const ProxyConfig& pc) { 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(eroman): This isn't quite right, won't work if |pc| specifies 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a PAC script. 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateUsingSystemProxyResolver(new ProxyConfigServiceFixed(pc), 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, NULL); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyService* ProxyService::CreateFixed(const std::string& proxy) { 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::ProxyConfig proxy_config; 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_config.proxy_rules().ParseFromString(proxy); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProxyService::CreateFixed(proxy_config); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyService* ProxyService::CreateDirect() { 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateDirectWithNetLog(NULL); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyService* ProxyService::CreateDirectWithNetLog(NetLog* net_log) { 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use direct connections. 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ProxyService(new ProxyConfigServiceDirect, new ProxyResolverNull, 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log); 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyService* ProxyService::CreateFixedFromPacResult( 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& pac_string) { 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need the settings to contain an "automatic" setting, otherwise the 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ProxyResolver dependency we give it will never be used. 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ProxyConfigService> proxy_config_service( 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ProxyConfigServiceFixed(ProxyConfig::CreateAutoDetect())); 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ProxyResolver> proxy_resolver( 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ProxyResolverFromPacString(pac_string)); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ProxyService(proxy_config_service.release(), 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_resolver.release(), 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyService::ResolveProxy(const GURL& raw_url, 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyInfo* result, 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback, 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PacRequest** pac_request, 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log.BeginEvent(NetLog::TYPE_PROXY_SERVICE); 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notify our polling-based dependencies that a resolve is taking place. 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This way they can schedule their polls in response to network activity. 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_service_->OnLazyPoll(); 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (script_poller_.get()) 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_poller_->OnLazyPoll(); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_state_ == STATE_NONE) 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ApplyProxyConfigIfAvailable(); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strip away any reference fragments and the username/password, as they 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are not relevant to proxy resolution. 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url = SimplifyUrlForRequest(raw_url); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the request can be completed right away. (This is the case when 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // using a direct connection for example). 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = TryToCompleteSynchronously(url, result); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != ERR_IO_PENDING) 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DidFinishResolvingProxy(result, rv, net_log); 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<PacRequest> req( 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new PacRequest(this, url, result, callback, net_log)); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_state_ == STATE_READY) { 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the resolve request. 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = req->Start(); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != ERR_IO_PENDING) 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return req->QueryDidComplete(rv); 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) req->net_log()->BeginEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(ERR_IO_PENDING, rv); 996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!ContainsPendingRequest(req.get())); 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_requests_.push_back(req); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Completion will be notified through |callback|, unless the caller cancels 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the request using |pac_request|. 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pac_request) 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pac_request = req.get(); 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; // ERR_IO_PENDING 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyService::TryToCompleteSynchronously(const GURL& url, 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyInfo* result) { 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(STATE_NONE, current_state_); 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_state_ != STATE_READY) 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_IO_PENDING; // Still initializing. 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(config_.id(), ProxyConfig::kInvalidConfigID); 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If it was impossible to fetch or parse the PAC script, we cannot complete 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the request here and bail out. 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (permanent_error_ != OK) 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return permanent_error_; 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (config_.HasAutomaticSettings()) 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_IO_PENDING; // Must submit the request to the proxy resolver. 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use the manual proxy settings. 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_.proxy_rules().Apply(url, result); 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->config_source_ = config_.source(); 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->config_id_ = config_.id(); 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyService::~ProxyService() { 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkChangeNotifier::RemoveIPAddressObserver(this); 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkChangeNotifier::RemoveDNSObserver(this); 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_service_->RemoveObserver(this); 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel any inprogress requests. 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PendingRequests::iterator it = pending_requests_.begin(); 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != pending_requests_.end(); 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*it)->Cancel(); 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::SuspendAllPendingRequests() { 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PendingRequests::iterator it = pending_requests_.begin(); 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != pending_requests_.end(); 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PacRequest* req = it->get(); 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (req->is_started()) { 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) req->CancelResolveJob(); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) req->net_log()->BeginEvent( 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::SetReady() { 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!init_proxy_resolver_.get()); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_state_ = STATE_READY; 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a copy in case |this| is deleted during the synchronous completion 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of one of the requests. If |this| is deleted then all of the PacRequest 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instances will be Cancel()-ed. 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingRequests pending_copy = pending_requests_; 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PendingRequests::iterator it = pending_copy.begin(); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != pending_copy.end(); 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PacRequest* req = it->get(); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!req->is_started() && !req->was_cancelled()) { 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) req->net_log()->EndEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC); 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that we re-check for synchronous completion, in case we are 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no longer using a ProxyResolver (can happen if we fell-back to manual). 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) req->StartAndCompleteCheckingForSynchronous(); 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::ApplyProxyConfigIfAvailable() { 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_NONE, current_state_); 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_service_->OnLazyPoll(); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we have already fetched the configuration, start applying it. 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fetched_config_.is_valid()) { 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeUsingLastFetchedConfig(); 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise we need to first fetch the configuration. 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_state_ = STATE_WAITING_FOR_PROXY_CONFIG; 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retrieve the current proxy configuration from the ProxyConfigService. 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a configuration is not available yet, we will get called back later 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by our ProxyConfigService::Observer once it changes. 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfig config; 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfigService::ConfigAvailability availability = 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_service_->GetLatestProxyConfig(&config); 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (availability != ProxyConfigService::CONFIG_PENDING) 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnProxyConfigChanged(config, availability); 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::OnInitProxyResolverComplete(int result) { 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_WAITING_FOR_INIT_PROXY_RESOLVER, current_state_); 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(init_proxy_resolver_.get()); 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(fetched_config_.HasAutomaticSettings()); 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = init_proxy_resolver_->effective_config(); 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At this point we have decided which proxy settings to use (i.e. which PAC 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // script if any). We start up a background poller to periodically revisit 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this decision. If the contents of the PAC script change, or if the 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // result of proxy auto-discovery changes, this poller will notice it and 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will trigger a re-initialization using the newly discovered PAC. 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_poller_.reset(new ProxyScriptDeciderPoller( 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ProxyService::InitializeUsingDecidedConfig, 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this)), 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetched_config_, 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resolver_->expects_pac_bytes(), 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_script_fetcher_.get(), 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dhcp_proxy_script_fetcher_.get(), 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result, 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_proxy_resolver_->script_data(), 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL)); 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_proxy_resolver_.reset(); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != OK) { 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fetched_config_.pac_mandatory()) { 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Failed configuring with mandatory PAC script, blocking all " 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "traffic."; 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = fetched_config_; 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = ERR_MANDATORY_PROXY_CONFIGURATION_FAILED; 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Failed configuring with PAC script, falling-back to manual " 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "proxy servers."; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = fetched_config_; 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_.ClearAutomaticSettings(); 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = OK; 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) permanent_error_ = result; 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(eroman): Make this ID unique in the case where configuration changed 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // due to ProxyScriptDeciderPoller. 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_.set_id(fetched_config_.id()); 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_.set_source(fetched_config_.source()); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resume any requests which we had to defer until the PAC script was 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // downloaded. 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetReady(); 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyService::ReconsiderProxyAfterError(const GURL& url, 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyInfo* result, 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback, 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PacRequest** pac_request, 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check to see if we have a new config since ResolveProxy was called. We 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // direct connection failed and we never tried the current config. 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool re_resolve = result->config_id_ != config_.id(); 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (re_resolve) { 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we have a new config or the config was never tried, we delete the 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // list of bad proxies and we try again. 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_retry_info_.clear(); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ResolveProxy(url, result, callback, pac_request, net_log); 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't have new proxy settings to try, try to fallback to the next proxy 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the list. 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool did_fallback = result->Fallback(net_log); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return synchronous failure if there is nothing left to fall-back to. 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(eroman): This is a yucky API, clean it up. 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return did_fallback ? OK : ERR_FAILED; 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyService::MarkProxyAsBad(const ProxyInfo& result, 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.proxy_list_.UpdateRetryInfoOnFallback(&proxy_retry_info_, net_log); 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.proxy_list_.HasUntriedProxies(proxy_retry_info_); 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::ReportSuccess(const ProxyInfo& result) { 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyRetryInfoMap& new_retry_info = result.proxy_retry_info(); 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_retry_info.empty()) 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ProxyRetryInfoMap::const_iterator iter = new_retry_info.begin(); 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != new_retry_info.end(); ++iter) { 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyRetryInfoMap::iterator existing = proxy_retry_info_.find(iter->first); 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (existing == proxy_retry_info_.end()) 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_retry_info_[iter->first] = iter->second; 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (existing->second.bad_until < iter->second.bad_until) 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing->second.bad_until = iter->second.bad_until; 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_log_) { 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_->AddGlobalEntry( 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::TYPE_BAD_PROXY_LIST_REPORTED, 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&NetLogBadProxyListCallback, &new_retry_info)); 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::CancelPacRequest(PacRequest* req) { 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(req); 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) req->Cancel(); 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemovePendingRequest(req); 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState ProxyService::GetLoadState(const PacRequest* req) const { 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(req); 12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (current_state_ == STATE_WAITING_FOR_INIT_PROXY_RESOLVER) 12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return init_proxy_resolver_->GetLoadState(); 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return req->GetLoadState(); 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyService::ContainsPendingRequest(PacRequest* req) { 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingRequests::iterator it = std::find( 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_requests_.begin(), pending_requests_.end(), req); 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pending_requests_.end() != it; 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::RemovePendingRequest(PacRequest* req) { 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ContainsPendingRequest(req)); 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingRequests::iterator it = std::find( 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_requests_.begin(), pending_requests_.end(), req); 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_requests_.erase(it); 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyService::DidFinishResolvingProxy(ProxyInfo* result, 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result_code, 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Log the result of the proxy resolution. 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result_code == OK) { 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When logging all events is enabled, dump the proxy list. 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_log.IsLoggingAllEvents()) { 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log.AddEvent( 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST, 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&NetLogFinishedResolvingProxyCallback, result)); 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->DeprioritizeBadProxies(proxy_retry_info_); 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log.AddEventWithNetErrorCode( 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST, result_code); 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!config_.pac_mandatory()) { 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fall-back to direct when the proxy resolver fails. This corresponds 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with a javascript runtime error in the PAC script. 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This implicit fall-back to direct matches Firefox 3.5 and 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Internet Explorer 8. For more information, see: 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://www.chromium.org/developers/design-documents/proxy-settings-fallback 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->UseDirect(); 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_code = OK; 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_code = ERR_MANDATORY_PROXY_CONFIGURATION_FAILED; 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log.EndEvent(NetLog::TYPE_PROXY_SERVICE); 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result_code; 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::SetProxyScriptFetchers( 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyScriptFetcher* proxy_script_fetcher, 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher) { 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State previous_state = ResetProxyConfig(false); 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_script_fetcher_.reset(proxy_script_fetcher); 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dhcp_proxy_script_fetcher_.reset(dhcp_proxy_script_fetcher); 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (previous_state != STATE_NONE) 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ApplyProxyConfigIfAvailable(); 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyScriptFetcher* ProxyService::GetProxyScriptFetcher() const { 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proxy_script_fetcher_.get(); 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyService::State ProxyService::ResetProxyConfig(bool reset_fetched_config) { 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State previous_state = current_state_; 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) permanent_error_ = OK; 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_retry_info_.clear(); 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_poller_.reset(); 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_proxy_resolver_.reset(); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SuspendAllPendingRequests(); 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = ProxyConfig(); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reset_fetched_config) 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetched_config_ = ProxyConfig(); 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_state_ = STATE_NONE; 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return previous_state; 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::ResetConfigService( 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfigService* new_proxy_config_service) { 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State previous_state = ResetProxyConfig(true); 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release the old configuration service. 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (config_service_.get()) 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_service_->RemoveObserver(this); 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the new configuration service. 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_service_.reset(new_proxy_config_service); 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_service_->AddObserver(this); 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (previous_state != STATE_NONE) 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ApplyProxyConfigIfAvailable(); 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::PurgeMemory() { 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resolver_.get()) 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resolver_->PurgeMemory(); 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::ForceReloadProxyConfig() { 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetProxyConfig(false); 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ApplyProxyConfigIfAvailable(); 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyConfigService* ProxyService::CreateSystemProxyConfigService( 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SingleThreadTaskRunner* io_thread_task_runner, 133890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop* file_loop) { 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ProxyConfigServiceWin(); 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_IOS) 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ProxyConfigServiceIOS(); 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ProxyConfigServiceMac(io_thread_task_runner); 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_CHROMEOS) 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ProxyConfigService for ChromeOS should be created in " 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "profile_io_data.cc::CreateProxyConfigService and this should " 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "be used only for examples."; 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new UnsetProxyConfigService; 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_LINUX) 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfigServiceLinux* linux_config_service = 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ProxyConfigServiceLinux(); 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assume we got called on the thread that runs the default glib 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // main loop, so the current thread is where we should be running 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // gconf calls from. 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> glib_thread_task_runner = 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadTaskRunnerHandle::Get(); 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The file loop should be a MessageLoopForIO on Linux. 136190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(base::MessageLoop::TYPE_IO, file_loop->type()); 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Synchronously fetch the current proxy config (since we are 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // running on glib_default_loop). Additionally register for 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notifications (delivered in either |glib_default_loop| or 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |file_loop|) to keep us updated when the proxy config changes. 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) linux_config_service->SetupAndFetchInitialConfig( 1368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) glib_thread_task_runner.get(), 136990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) io_thread_task_runner, 137090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<base::MessageLoopForIO*>(file_loop)); 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return linux_config_service; 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_ANDROID) 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ProxyConfigServiceAndroid( 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_task_runner, 137690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->message_loop_proxy()); 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Failed to choose a system proxy settings fetcher " 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "for this platform."; 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ProxyConfigServiceDirect(); 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProxyService::PacPollPolicy* ProxyService::set_pac_script_poll_policy( 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PacPollPolicy* policy) { 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProxyScriptDeciderPoller::set_policy(policy); 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<ProxyService::PacPollPolicy> 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyService::CreateDefaultPacPollPolicy() { 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scoped_ptr<PacPollPolicy>(new DefaultPollPolicy()); 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::OnProxyConfigChanged( 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyConfig& config, 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfigService::ConfigAvailability availability) { 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retrieve the current proxy configuration from the ProxyConfigService. 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a configuration is not available yet, we will get called back later 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by our ProxyConfigService::Observer once it changes. 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfig effective_config; 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (availability) { 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ProxyConfigService::CONFIG_PENDING: 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ProxyConfigService implementors should never pass CONFIG_PENDING. 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Proxy config change with CONFIG_PENDING availability!"; 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ProxyConfigService::CONFIG_VALID: 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effective_config = config; 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ProxyConfigService::CONFIG_UNSET: 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effective_config = ProxyConfig::CreateDirect(); 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Emit the proxy settings change to the NetLog stream. 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_log_) { 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_->AddGlobalEntry( 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_PROXY_CONFIG_CHANGED, 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&NetLogProxyConfigChangedCallback, 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &fetched_config_, &effective_config)); 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the new configuration as the most recently fetched one. 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetched_config_ = effective_config; 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetched_config_.set_id(1); // Needed for a later DCHECK of is_valid(). 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeUsingLastFetchedConfig(); 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::InitializeUsingLastFetchedConfig() { 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetProxyConfig(false); 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(fetched_config_.is_valid()); 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Increment the ID to reflect that the config has changed. 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetched_config_.set_id(next_config_id_++); 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!fetched_config_.HasAutomaticSettings()) { 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = fetched_config_; 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetReady(); 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start downloading + testing the PAC scripts for this new configuration. 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_state_ = STATE_WAITING_FOR_INIT_PROXY_RESOLVER; 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we changed networks recently, we should delay running proxy auto-config. 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta wait_delay = 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stall_proxy_autoconfig_until_ - TimeTicks::Now(); 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_proxy_resolver_.reset(new InitProxyResolver()); 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = init_proxy_resolver_->Start( 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resolver_.get(), 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_script_fetcher_.get(), 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dhcp_proxy_script_fetcher_.get(), 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_, 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetched_config_, 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_delay, 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ProxyService::OnInitProxyResolverComplete, 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != ERR_IO_PENDING) 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitProxyResolverComplete(rv); 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::InitializeUsingDecidedConfig( 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int decider_result, 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolverScriptData* script_data, 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyConfig& effective_config) { 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(fetched_config_.is_valid()); 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(fetched_config_.HasAutomaticSettings()); 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetProxyConfig(false); 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_state_ = STATE_WAITING_FOR_INIT_PROXY_RESOLVER; 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_proxy_resolver_.reset(new InitProxyResolver()); 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = init_proxy_resolver_->StartSkipDecider( 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resolver_.get(), 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effective_config, 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decider_result, 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_data, 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ProxyService::OnInitProxyResolverComplete, 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != ERR_IO_PENDING) 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitProxyResolverComplete(rv); 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::OnIPAddressChanged() { 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See the comment block by |kDelayAfterNetworkChangesMs| for info. 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stall_proxy_autoconfig_until_ = 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks::Now() + stall_proxy_auto_config_delay_; 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State previous_state = ResetProxyConfig(false); 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (previous_state != STATE_NONE) 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ApplyProxyConfigIfAvailable(); 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyService::OnDNSChanged() { 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnIPAddressChanged(); 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 150590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)SyncProxyServiceHelper::SyncProxyServiceHelper( 150690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop* io_message_loop, 150790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ProxyService* proxy_service) 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : io_message_loop_(io_message_loop), 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_service_(proxy_service), 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_(false, false), 1511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback_(base::Bind(&SyncProxyServiceHelper::OnCompletion, 1512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))) { 151390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(io_message_loop_ != base::MessageLoop::current()); 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SyncProxyServiceHelper::ResolveProxy(const GURL& url, 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyInfo* proxy_info, 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 151990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(io_message_loop_ != base::MessageLoop::current()); 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_message_loop_->PostTask( 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SyncProxyServiceHelper::StartAsyncResolve, this, url, 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log)); 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_.Wait(); 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result_ == net::OK) { 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *proxy_info = proxy_info_; 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result_; 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SyncProxyServiceHelper::ReconsiderProxyAfterError( 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, ProxyInfo* proxy_info, const BoundNetLog& net_log) { 153690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(io_message_loop_ != base::MessageLoop::current()); 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_message_loop_->PostTask( 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SyncProxyServiceHelper::StartAsyncReconsider, this, url, 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log)); 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_.Wait(); 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result_ == net::OK) { 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *proxy_info = proxy_info_; 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result_; 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncProxyServiceHelper::~SyncProxyServiceHelper() {} 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncProxyServiceHelper::StartAsyncResolve(const GURL& url, 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_ = proxy_service_->ResolveProxy( 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url, &proxy_info_, callback_, NULL, net_log); 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result_ != net::ERR_IO_PENDING) { 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCompletion(result_); 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncProxyServiceHelper::StartAsyncReconsider(const GURL& url, 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_ = proxy_service_->ReconsiderProxyAfterError( 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url, &proxy_info_, callback_, NULL, net_log); 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result_ != net::ERR_IO_PENDING) { 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCompletion(result_); 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncProxyServiceHelper::OnCompletion(int rv) { 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_ = rv; 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_.Signal(); 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1577