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