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