1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_service.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <algorithm> 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/compiler_specific.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/values.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "googleurl/src/gurl.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/net_log.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_util.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/init_proxy_resolver.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/proxy/multi_threaded_proxy_resolver.h" 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_config_service_fixed.h" 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/proxy/proxy_resolver.h" 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/proxy/proxy_resolver_js_bindings.h" 23d77e7f37b175317d38b1e3067d27eba0584b93c6Kristian Monsen#ifndef ANDROID 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/proxy/proxy_resolver_v8.h" 25d77e7f37b175317d38b1e3067d27eba0584b93c6Kristian Monsen#endif 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_script_fetcher.h" 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/proxy/sync_host_resolver_bridge.h" 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/url_request/url_request_context.h" 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_config_service_win.h" 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_resolver_winhttp.h" 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_MACOSX) 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_config_service_mac.h" 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_resolver_mac.h" 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#elif defined(OS_LINUX) && !defined(OS_CHROMEOS) 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_config_service_linux.h" 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::TimeDelta; 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::TimeTicks; 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknamespace { 463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst size_t kMaxNumNetLogEntries = 100; 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst size_t kDefaultNumPacThreads = 4; 493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// When the IP address changes we don't immediately re-run proxy auto-config. 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Instead, we wait for |kNumMillisToStallAfterNetworkChanges| before 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// attempting to re-valuate proxy auto-config. 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// During this time window, any resolve requests sent to the ProxyService will 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// be queued. Once we have waited the required amount of them, the proxy 563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// auto-config step will be run, and the queued requests resumed. 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The reason we play this game is that our signal for detecting network 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// changes (NetworkChangeNotifier) may fire *before* the system's networking 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// dependencies are fully configured. This is a problem since it means if 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// we were to run proxy auto-config right away, it could fail due to spurious 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// DNS failures. (see http://crbug.com/50779 for more details.) 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// By adding the wait window, we give things a chance to get properly set up. 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Now by the time we run the proxy-autoconfig there is a lower chance of 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// getting transient DNS / connect failures. 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Admitedly this is a hack. Ideally we would have NetworkChangeNotifier 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// deliver a reliable signal indicating that the network has changed AND is 703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// ready for action... But until then, we can reduce the likelihood of users 713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// getting wedged because of proxy detection failures on network switch. 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The obvious downside to this strategy is it introduces an additional 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// latency when switching networks. This delay shouldn't be too disruptive 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// assuming network switches are infrequent and user initiated. However if 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// NetworkChangeNotifier delivers network changes more frequently this could 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// cause jankiness. (NetworkChangeNotifier broadcasts a change event when ANY 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// interface goes up/down. So in theory if the non-primary interface were 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// hopping on and off wireless networks our constant delayed reconfiguration 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// could add noticeable jank.) 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The specific hard-coded wait time below is arbitrary. 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Basically I ran some experiments switching between wireless networks on 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// a Linux Ubuntu (Lucid) laptop, and experimentally found this timeout fixes 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// things. It is entirely possible that the value is insuficient for other 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// setups. 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst int64 kNumMillisToStallAfterNetworkChanges = 2000; 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Config getter that always returns direct settings. 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass ProxyConfigServiceDirect : public ProxyConfigService { 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ProxyConfigService implementation: 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void AddObserver(Observer* observer) {} 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void RemoveObserver(Observer* observer) {} 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) { 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *config = ProxyConfig::CreateDirect(); 97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return CONFIG_VALID; 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Proxy resolver that fails every time. 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ProxyResolverNull : public ProxyResolver { 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyResolverNull() : ProxyResolver(false /*expects_pac_bytes*/) {} 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ProxyResolver implementation: 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int GetProxyForURL(const GURL& url, 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyInfo* results, 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* callback, 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RequestHandle* request, 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log) { 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_NOT_IMPLEMENTED; 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void CancelRequest(RequestHandle request) { 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual void CancelSetPacScript() { 12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NOTREACHED(); 12121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual int SetPacScript( 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const scoped_refptr<ProxyResolverScriptData>& /*script_data*/, 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* /*callback*/) { 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_NOT_IMPLEMENTED; 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// ProxyResolver that simulates a PAC script which returns 1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// |pac_string| for every single URL. 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass ProxyResolverFromPacString : public ProxyResolver { 1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public: 1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyResolverFromPacString(const std::string& pac_string) 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : ProxyResolver(false /*expects_pac_bytes*/), 1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick pac_string_(pac_string) {} 1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual int GetProxyForURL(const GURL& url, 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyInfo* results, 1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CompletionCallback* callback, 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick RequestHandle* request, 1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const BoundNetLog& net_log) { 1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick results->UsePacString(pac_string_); 1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return OK; 1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void CancelRequest(RequestHandle request) { 1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual void CancelSetPacScript() { 15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NOTREACHED(); 15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 15421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual int SetPacScript( 1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const scoped_refptr<ProxyResolverScriptData>& pac_script, 1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CompletionCallback* callback) { 1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return OK; 1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string pac_string_; 1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 165d77e7f37b175317d38b1e3067d27eba0584b93c6Kristian Monsen#ifndef ANDROID 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This factory creates V8ProxyResolvers with appropriate javascript bindings. 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ProxyResolverFactoryForV8 : public ProxyResolverFactory { 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |async_host_resolver|, |io_loop| and |net_log| must remain 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // valid for the duration of our lifetime. 17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // |async_host_resolver| will only be operated on |io_loop|. 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxyResolverFactoryForV8(HostResolver* async_host_resolver, 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop* io_loop, 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog* net_log) 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : ProxyResolverFactory(true /*expects_pac_bytes*/), 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch async_host_resolver_(async_host_resolver), 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch io_loop_(io_loop), 17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log_(net_log) { 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ProxyResolver* CreateProxyResolver() { 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a synchronous host resolver wrapper that operates 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |async_host_resolver_| on |io_loop_|. 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SyncHostResolverBridge* sync_host_resolver = 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new SyncHostResolverBridge(async_host_resolver_, io_loop_); 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxyResolverJSBindings* js_bindings = 18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ProxyResolverJSBindings::CreateDefault(sync_host_resolver, net_log_); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ProxyResolverV8 takes ownership of |js_bindings|. 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new ProxyResolverV8(js_bindings); 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick HostResolver* const async_host_resolver_; 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop* io_loop_; 19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NetLog* net_log_; 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 199d77e7f37b175317d38b1e3067d27eba0584b93c6Kristian Monsen#endif 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Creates ProxyResolvers using a platform-specific implementation. 202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass ProxyResolverFactoryForSystem : public ProxyResolverFactory { 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyResolverFactoryForSystem() 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : ProxyResolverFactory(false /*expects_pac_bytes*/) {} 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ProxyResolver* CreateProxyResolver() { 208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(IsSupported()); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new ProxyResolverWinHttp(); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX) 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new ProxyResolverMac(); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 214731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NOTREACHED(); 215731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return NULL; 216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif 217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick static bool IsSupported() { 220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if defined(OS_WIN) || defined(OS_MACOSX) 221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#else 223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// NetLog parameter to describe a proxy configuration change. 2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass ProxyConfigChangedNetLogParam : public NetLog::EventParameters { 2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public: 2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyConfigChangedNetLogParam(const ProxyConfig& old_config, 2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ProxyConfig& new_config) 2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : old_config_(old_config), 2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new_config_(new_config) { 2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual Value* ToValue() const { 2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DictionaryValue* dict = new DictionaryValue(); 2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The "old_config" is optional -- the first notification will not have 2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // any "previous" configuration. 2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (old_config_.is_valid()) 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick dict->Set("old_config", old_config_.ToValue()); 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick dict->Set("new_config", new_config_.ToValue()); 2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return dict; 2453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ProxyConfig old_config_; 2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ProxyConfig new_config_; 2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DISALLOW_COPY_AND_ASSIGN(ProxyConfigChangedNetLogParam); 2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} // namespace 2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ProxyService::PacRequest --------------------------------------------------- 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ProxyService::PacRequest 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : public base::RefCounted<ProxyService::PacRequest> { 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PacRequest(ProxyService* service, 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const GURL& url, 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyInfo* results, 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* user_callback, 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log) 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : service_(service), 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott user_callback_(user_callback), 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &PacRequest::QueryComplete)), 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott results_(results), 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott url_(url), 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott resolve_job_(NULL), 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott config_id_(ProxyConfig::INVALID_ID), 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net_log_(net_log) { 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(user_callback); 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Starts the resolve proxy request. 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int Start() { 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!was_cancelled()); 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!is_started()); 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(service_->config_.is_valid()); 2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott config_id_ = service_->config_.id(); 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return resolver()->GetProxyForURL( 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_, results_, &io_callback_, &resolve_job_, net_log_); 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool is_started() const { 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that !! casts to bool. (VS gives a warning otherwise). 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return !!resolve_job_; 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void StartAndCompleteCheckingForSynchronous() { 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = service_->TryToCompleteSynchronously(url_, results_); 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == ERR_IO_PENDING) 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = Start(); 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv != ERR_IO_PENDING) 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott QueryComplete(rv); 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void CancelResolveJob() { 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(is_started()); 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The request may already be running in the resolver. 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott resolver()->CancelRequest(resolve_job_); 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott resolve_job_ = NULL; 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!is_started()); 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Cancel() { 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (is_started()) 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CancelResolveJob(); 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Mark as cancelled, to prevent accessing this again later. 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott service_ = NULL; 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott user_callback_ = NULL; 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott results_ = NULL; 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net_log_.EndEvent(NetLog::TYPE_PROXY_SERVICE, NULL); 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if Cancel() has been called. 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool was_cancelled() const { return user_callback_ == NULL; } 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Helper to call after ProxyResolver completion (both synchronous and 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // asynchronous). Fixes up the result that is to be returned to user. 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int QueryDidComplete(int result_code) { 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!was_cancelled()); 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Make a note in the results which configuration was in use at the 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // time of the resolve. 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott results_->config_id_ = config_id_; 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Reset the state associated with in-progress-resolve. 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott resolve_job_ = NULL; 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott config_id_ = ProxyConfig::INVALID_ID; 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return service_->DidFinishResolvingProxy(results_, result_code, net_log_); 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog* net_log() { return &net_log_; } 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend class base::RefCounted<ProxyService::PacRequest>; 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~PacRequest() {} 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Callback for when the ProxyResolver request has completed. 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void QueryComplete(int result_code) { 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott result_code = QueryDidComplete(result_code); 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Remove this completed PacRequest from the service's pending list. 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /// (which will probably cause deletion of |this|). 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* callback = user_callback_; 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott service_->RemovePendingRequest(this); 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott callback->Run(result_code); 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyResolver* resolver() const { return service_->resolver_.get(); } 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that we don't hold a reference to the ProxyService. Outstanding 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // requests are cancelled during ~ProxyService, so this is guaranteed 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to be valid throughout our lifetime. 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyService* service_; 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* user_callback_; 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallbackImpl<PacRequest> io_callback_; 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyInfo* results_; 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GURL url_; 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyResolver::RequestHandle resolve_job_; 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyConfig::ID config_id_; // The config id when the resolve was started. 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog net_log_; 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ProxyService --------------------------------------------------------------- 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottProxyService::ProxyService(ProxyConfigService* config_service, 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyResolver* resolver, 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog* net_log) 3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : resolver_(resolver), 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott next_config_id_(1), 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ALLOW_THIS_IN_INITIALIZER_LIST(init_proxy_resolver_callback_( 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &ProxyService::OnInitProxyResolverComplete)), 3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick current_state_(STATE_NONE) , 3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net_log_(net_log), 3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stall_proxy_auto_config_delay_( 3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::TimeDelta::FromMilliseconds( 3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kNumMillisToStallAfterNetworkChanges)) { 392dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NetworkChangeNotifier::AddIPAddressObserver(this); 3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ResetConfigService(config_service); 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 396d77e7f37b175317d38b1e3067d27eba0584b93c6Kristian Monsen#ifndef ANDROID 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 398731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickProxyService* ProxyService::CreateUsingV8ProxyResolver( 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyConfigService* proxy_config_service, 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t num_pac_threads, 401731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyScriptFetcher* proxy_script_fetcher, 402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick HostResolver* host_resolver, 403731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NetLog* net_log) { 404731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(proxy_config_service); 405731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(proxy_script_fetcher); 406731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(host_resolver); 407731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (num_pac_threads == 0) 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch num_pac_threads = kDefaultNumPacThreads; 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 411731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyResolverFactory* sync_resolver_factory = 412731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new ProxyResolverFactoryForV8( 413731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick host_resolver, 414731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MessageLoop::current(), 415731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net_log); 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxyResolver* proxy_resolver = 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new MultiThreadedProxyResolver(sync_resolver_factory, num_pac_threads); 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxyService* proxy_service = 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new ProxyService(proxy_config_service, proxy_resolver, net_log); 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 423731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Configure PAC script downloads to be issued using |proxy_script_fetcher|. 424731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick proxy_service->SetProxyScriptFetcher(proxy_script_fetcher); 425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return proxy_service; 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 428d77e7f37b175317d38b1e3067d27eba0584b93c6Kristian Monsen#endif 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 431731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickProxyService* ProxyService::CreateUsingSystemProxyResolver( 432731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyConfigService* proxy_config_service, 433731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick size_t num_pac_threads, 434731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NetLog* net_log) { 435731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(proxy_config_service); 436731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 437731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ProxyResolverFactoryForSystem::IsSupported()) { 438731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(WARNING) << "PAC support disabled because there is no " 439731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "system implementation"; 440731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return CreateWithoutProxyResolver(proxy_config_service, net_log); 441731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 442731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 443731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (num_pac_threads == 0) 444731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick num_pac_threads = kDefaultNumPacThreads; 445731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 446731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyResolver* proxy_resolver = new MultiThreadedProxyResolver( 447731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new ProxyResolverFactoryForSystem(), num_pac_threads); 448731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 449731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return new ProxyService(proxy_config_service, proxy_resolver, net_log); 450731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 451731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 452731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// static 453731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickProxyService* ProxyService::CreateWithoutProxyResolver( 454731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ProxyConfigService* proxy_config_service, 455731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NetLog* net_log) { 456731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return new ProxyService(proxy_config_service, 457731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new ProxyResolverNull(), 458731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net_log); 459731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 460731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 461731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// static 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottProxyService* ProxyService::CreateFixed(const ProxyConfig& pc) { 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(eroman): This isn't quite right, won't work if |pc| specifies 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a PAC script. 465731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return CreateUsingSystemProxyResolver(new ProxyConfigServiceFixed(pc), 466731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 0, NULL); 467731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 468731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 469731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// static 470731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickProxyService* ProxyService::CreateFixed(const std::string& proxy) { 471731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick net::ProxyConfig proxy_config; 472731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick proxy_config.proxy_rules().ParseFromString(proxy); 473731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ProxyService::CreateFixed(proxy_config); 474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickProxyService* ProxyService::CreateDirect() { 47821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return CreateDirectWithNetLog(NULL); 47921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 48021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 48121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenProxyService* ProxyService::CreateDirectWithNetLog(NetLog* net_log) { 4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Use direct connections. 4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return new ProxyService(new ProxyConfigServiceDirect, new ProxyResolverNull, 48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log); 4853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 4883345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickProxyService* ProxyService::CreateFixedFromPacResult( 4893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& pac_string) { 4903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We need the settings to contain an "automatic" setting, otherwise the 4923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // ProxyResolver dependency we give it will never be used. 4933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<ProxyConfigService> proxy_config_service( 4943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new ProxyConfigServiceFixed(ProxyConfig::CreateAutoDetect())); 4953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<ProxyResolver> proxy_resolver( 4973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new ProxyResolverFromPacString(pac_string)); 4983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return new ProxyService(proxy_config_service.release(), 5003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick proxy_resolver.release(), 501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NULL); 502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint ProxyService::ResolveProxy(const GURL& raw_url, 505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyInfo* result, 506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* callback, 507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PacRequest** pac_request, 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log) { 509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(callback); 511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net_log.BeginEvent(NetLog::TYPE_PROXY_SERVICE, NULL); 513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config_service_->OnLazyPoll(); 5153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (current_state_ == STATE_NONE) 5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ApplyProxyConfigIfAvailable(); 5173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Strip away any reference fragments and the username/password, as they 519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // are not relevant to proxy resolution. 520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GURL url = SimplifyUrlForRequest(raw_url); 521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Check if the request can be completed right away. (This is the case when 5233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // using a direct connection for example). 524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = TryToCompleteSynchronously(url, result); 525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv != ERR_IO_PENDING) 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return DidFinishResolvingProxy(result, rv, net_log); 527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 528513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<PacRequest> req( 529513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new PacRequest(this, url, result, callback, net_log)); 530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (current_state_ == STATE_READY) { 532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Start the resolve request. 533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = req->Start(); 534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv != ERR_IO_PENDING) 535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return req->QueryDidComplete(rv); 536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch req->net_log()->BeginEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC, 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK_EQ(ERR_IO_PENDING, rv); 542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!ContainsPendingRequest(req)); 543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_requests_.push_back(req); 544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Completion will be notifed through |callback|, unless the caller cancels 546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the request using |pac_request|. 547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (pac_request) 548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *pac_request = req.get(); 549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return rv; // ERR_IO_PENDING 550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint ProxyService::TryToCompleteSynchronously(const GURL& url, 553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyInfo* result) { 5543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_NE(STATE_NONE, current_state_); 555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (current_state_ != STATE_READY) 5573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_IO_PENDING; // Still initializing. 558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_NE(config_.id(), ProxyConfig::INVALID_ID); 5603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (config_.HasAutomaticSettings()) 5623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_IO_PENDING; // Must submit the request to the proxy resolver. 563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use the manual proxy settings. 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch config_.proxy_rules().Apply(url, result); 5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result->config_id_ = config_.id(); 567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return OK; 568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottProxyService::~ProxyService() { 571dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NetworkChangeNotifier::RemoveIPAddressObserver(this); 5723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config_service_->RemoveObserver(this); 573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Cancel any inprogress requests. 575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (PendingRequests::iterator it = pending_requests_.begin(); 576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it != pending_requests_.end(); 577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++it) { 578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (*it)->Cancel(); 579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ProxyService::SuspendAllPendingRequests() { 583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (PendingRequests::iterator it = pending_requests_.begin(); 584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it != pending_requests_.end(); 585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++it) { 586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PacRequest* req = it->get(); 587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req->is_started()) { 588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req->CancelResolveJob(); 589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch req->net_log()->BeginEvent( 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC, NULL); 592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProxyService::SetReady() { 5973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!init_proxy_resolver_.get()); 5983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick current_state_ = STATE_READY; 599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Make a copy in case |this| is deleted during the synchronous completion 601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // of one of the requests. If |this| is deleted then all of the PacRequest 602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // instances will be Cancel()-ed. 603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PendingRequests pending_copy = pending_requests_; 604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (PendingRequests::iterator it = pending_copy.begin(); 606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it != pending_copy.end(); 607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++it) { 608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PacRequest* req = it->get(); 609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!req->is_started() && !req->was_cancelled()) { 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch req->net_log()->EndEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC, 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that we re-check for synchronous completion, in case we are 614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // no longer using a ProxyResolver (can happen if we fell-back to manual). 615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req->StartAndCompleteCheckingForSynchronous(); 616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProxyService::ApplyProxyConfigIfAvailable() { 6213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_EQ(STATE_NONE, current_state_); 6223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config_service_->OnLazyPoll(); 6243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If we have already fetched the configuration, start applying it. 6263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (fetched_config_.is_valid()) { 6273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick InitializeUsingLastFetchedConfig(); 6283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 6293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Otherwise we need to first fetch the configuration. 6323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick current_state_ = STATE_WAITING_FOR_PROXY_CONFIG; 6333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Retrieve the current proxy configuration from the ProxyConfigService. 6353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If a configuration is not available yet, we will get called back later 6363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // by our ProxyConfigService::Observer once it changes. 6373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ProxyConfig config; 638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProxyConfigService::ConfigAvailability availability = 639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen config_service_->GetLatestProxyConfig(&config); 640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (availability != ProxyConfigService::CONFIG_PENDING) 641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen OnProxyConfigChanged(config, availability); 6423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ProxyService::OnInitProxyResolverComplete(int result) { 6453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_EQ(STATE_WAITING_FOR_INIT_PROXY_RESOLVER, current_state_); 646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(init_proxy_resolver_.get()); 6473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(fetched_config_.HasAutomaticSettings()); 648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott init_proxy_resolver_.reset(); 649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result != OK) { 651731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << "Failed configuring with PAC script, falling-back to manual " 652731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "proxy servers."; 6533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config_ = fetched_config_; 6543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config_.ClearAutomaticSettings(); 655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config_.set_id(fetched_config_.id()); 6583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Resume any requests which we had to defer until the PAC script was 660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // downloaded. 6613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetReady(); 662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint ProxyService::ReconsiderProxyAfterError(const GURL& url, 665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyInfo* result, 666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* callback, 667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PacRequest** pac_request, 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log) { 669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Check to see if we have a new config since ResolveProxy was called. We 672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a 673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // direct connection failed and we never tried the current config. 674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool re_resolve = result->config_id_ != config_.id(); 6763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (re_resolve) { 678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If we have a new config or the config was never tried, we delete the 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // list of bad proxies and we try again. 680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott proxy_retry_info_.clear(); 681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResolveProxy(url, result, callback, pac_request, net_log); 682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We don't have new proxy settings to try, try to fallback to the next proxy 685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in the list. 686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool did_fallback = result->Fallback(&proxy_retry_info_); 687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Return synchronous failure if there is nothing left to fall-back to. 689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(eroman): This is a yucky API, clean it up. 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return did_fallback ? OK : ERR_FAILED; 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ProxyService::CancelPacRequest(PacRequest* req) { 694ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(req); 696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req->Cancel(); 697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RemovePendingRequest(req); 698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ProxyService::ContainsPendingRequest(PacRequest* req) { 701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PendingRequests::iterator it = std::find( 702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_requests_.begin(), pending_requests_.end(), req); 703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return pending_requests_.end() != it; 704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ProxyService::RemovePendingRequest(PacRequest* req) { 707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(ContainsPendingRequest(req)); 708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PendingRequests::iterator it = std::find( 709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_requests_.begin(), pending_requests_.end(), req); 710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_requests_.erase(it); 711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint ProxyService::DidFinishResolvingProxy(ProxyInfo* result, 714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int result_code, 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log) { 716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Log the result of the proxy resolution. 717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result_code == OK) { 718731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // When logging all events is enabled, dump the proxy list. 719731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (net_log.IsLoggingAllEvents()) { 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net_log.AddEvent( 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST, 722513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch make_scoped_refptr(new NetLogStringParameter( 723513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "pac_string", result->ToPacString()))); 724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result->DeprioritizeBadProxies(proxy_retry_info_); 726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net_log.AddEvent( 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST, 729513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch make_scoped_refptr(new NetLogIntegerParameter( 730513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "net_error", result_code))); 731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fall-back to direct when the proxy resolver fails. This corresponds 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // with a javascript runtime error in the PAC script. 734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This implicit fall-back to direct matches Firefox 3.5 and 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Internet Explorer 8. For more information, see: 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // http://www.chromium.org/developers/design-documents/proxy-settings-fallback 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result->UseDirect(); 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result_code = OK; 741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net_log.EndEvent(NetLog::TYPE_PROXY_SERVICE, NULL); 744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return result_code; 745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ProxyService::SetProxyScriptFetcher( 748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyScriptFetcher* proxy_script_fetcher) { 749ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 7503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick State previous_state = ResetProxyConfig(false); 7513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick proxy_script_fetcher_.reset(proxy_script_fetcher); 7523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (previous_state != STATE_NONE) 7533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ApplyProxyConfigIfAvailable(); 754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottProxyScriptFetcher* ProxyService::GetProxyScriptFetcher() const { 757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return proxy_script_fetcher_.get(); 759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7613345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickProxyService::State ProxyService::ResetProxyConfig(bool reset_fetched_config) { 762ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 7633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick State previous_state = current_state_; 7643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick proxy_retry_info_.clear(); 7663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick init_proxy_resolver_.reset(); 7673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SuspendAllPendingRequests(); 7683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config_ = ProxyConfig(); 7693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (reset_fetched_config) 7703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick fetched_config_ = ProxyConfig(); 7713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick current_state_ = STATE_NONE; 7723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return previous_state; 7743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ProxyService::ResetConfigService( 777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyConfigService* new_proxy_config_service) { 778ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 7793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick State previous_state = ResetProxyConfig(true); 7803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Release the old configuration service. 7823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (config_service_.get()) 7833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config_service_->RemoveObserver(this); 7843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Set the new configuration service. 786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott config_service_.reset(new_proxy_config_service); 7873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config_service_->AddObserver(this); 7883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (previous_state != STATE_NONE) 7903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ApplyProxyConfigIfAvailable(); 791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ProxyService::PurgeMemory() { 794ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (resolver_.get()) 796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott resolver_->PurgeMemory(); 797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ProxyService::ForceReloadProxyConfig() { 800ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 8013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ResetProxyConfig(false); 8023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ApplyProxyConfigIfAvailable(); 803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottProxyConfigService* ProxyService::CreateSystemProxyConfigService( 807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop* io_loop, MessageLoop* file_loop) { 808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new ProxyConfigServiceWin(); 810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_MACOSX) 8113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return new ProxyConfigServiceMac(io_loop); 8123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#elif defined(OS_CHROMEOS) 8133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED() << "ProxyConfigService for ChromeOS should be created in " 814ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen << "profile_io_data.cc::CreateProxyConfigService."; 8153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 8162d04b11d60881569d8142cf294b1fad59f14a2a5Kristian Monsen#elif defined(ANDROID) 8172d04b11d60881569d8142cf294b1fad59f14a2a5Kristian Monsen NOTREACHED() << "ProxyConfigService for Android should be created in " 8182d04b11d60881569d8142cf294b1fad59f14a2a5Kristian Monsen << "WebCache.cpp: WebCache::WebCache"; 8192d04b11d60881569d8142cf294b1fad59f14a2a5Kristian Monsen return NULL; 8202d04b11d60881569d8142cf294b1fad59f14a2a5Kristian Monsen#elif defined(OS_LINUX) 821ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProxyConfigServiceLinux* linux_config_service = 822ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new ProxyConfigServiceLinux(); 823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Assume we got called from the UI loop, which runs the default 825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // glib main loop, so the current thread is where we should be 826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // running gconf calls from. 827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop* glib_default_loop = MessageLoopForUI::current(); 828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The file loop should be a MessageLoopForIO on Linux. 830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK_EQ(MessageLoop::TYPE_IO, file_loop->type()); 831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Synchronously fetch the current proxy config (since we are 833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // running on glib_default_loop). Additionally register for 834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // notifications (delivered in either |glib_default_loop| or 835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |file_loop|) to keep us updated when the proxy config changes. 836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott linux_config_service->SetupAndFetchInitialConfig(glib_default_loop, io_loop, 837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static_cast<MessageLoopForIO*>(file_loop)); 838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return linux_config_service; 840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(WARNING) << "Failed to choose a system proxy settings fetcher " 842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "for this platform."; 843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new ProxyConfigServiceNull(); 844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 847ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ProxyService::OnProxyConfigChanged( 848ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const ProxyConfig& config, 849ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProxyConfigService::ConfigAvailability availability) { 850ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Retrieve the current proxy configuration from the ProxyConfigService. 851ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If a configuration is not available yet, we will get called back later 852ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // by our ProxyConfigService::Observer once it changes. 853ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProxyConfig effective_config; 854ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switch (availability) { 855ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case ProxyConfigService::CONFIG_PENDING: 856ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // ProxyConfigService implementors should never pass CONFIG_PENDING. 857ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED() << "Proxy config change with CONFIG_PENDING availability!"; 858ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 859ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case ProxyConfigService::CONFIG_VALID: 860ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen effective_config = config; 861ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 862ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case ProxyConfigService::CONFIG_UNSET: 863ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen effective_config = ProxyConfig::CreateDirect(); 864ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 865ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 866ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 8673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Emit the proxy settings change to the NetLog stream. 8683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (net_log_) { 869513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<NetLog::EventParameters> params( 870ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new ProxyConfigChangedNetLogParam(fetched_config_, effective_config)); 8713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net_log_->AddEntry(net::NetLog::TYPE_PROXY_CONFIG_CHANGED, 8723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::TimeTicks::Now(), 8733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog::Source(), 8743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog::PHASE_NONE, 8753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick params); 876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 8783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Set the new configuration as the most recently fetched one. 879ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fetched_config_ = effective_config; 8803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick fetched_config_.set_id(1); // Needed for a later DCHECK of is_valid(). 881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 8823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick InitializeUsingLastFetchedConfig(); 883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 8853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProxyService::InitializeUsingLastFetchedConfig() { 8863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ResetProxyConfig(false); 887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 8883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(fetched_config_.is_valid()); 889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 8903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Increment the ID to reflect that the config has changed. 8913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick fetched_config_.set_id(next_config_id_++); 892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 8933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!fetched_config_.HasAutomaticSettings()) { 8943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick config_ = fetched_config_; 8953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetReady(); 8963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 8993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start downloading + testing the PAC scripts for this new configuration. 9003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick current_state_ = STATE_WAITING_FOR_INIT_PROXY_RESOLVER; 901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott init_proxy_resolver_.reset( 903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new InitProxyResolver(resolver_.get(), proxy_script_fetcher_.get(), 904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net_log_)); 905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If we changed networks recently, we should delay running proxy auto-config. 9073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::TimeDelta wait_delay = 9083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stall_proxy_autoconfig_until_ - base::TimeTicks::Now(); 9093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = init_proxy_resolver_->Init( 9113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick fetched_config_, wait_delay, &config_, &init_proxy_resolver_callback_); 912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv != ERR_IO_PENDING) 914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OnInitProxyResolverComplete(rv); 915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ProxyService::OnIPAddressChanged() { 9183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // See the comment block by |kNumMillisToStallAfterNetworkChanges| for info. 9193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stall_proxy_autoconfig_until_ = 9203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::TimeTicks::Now() + stall_proxy_auto_config_delay_; 9213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick State previous_state = ResetProxyConfig(false); 9233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (previous_state != STATE_NONE) 9243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ApplyProxyConfigIfAvailable(); 925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSyncProxyServiceHelper::SyncProxyServiceHelper(MessageLoop* io_message_loop, 928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyService* proxy_service) 929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : io_message_loop_(io_message_loop), 930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott proxy_service_(proxy_service), 931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_(false, false), 932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ALLOW_THIS_IN_INITIALIZER_LIST(callback_( 933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &SyncProxyServiceHelper::OnCompletion)) { 934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(io_message_loop_ != MessageLoop::current()); 935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint SyncProxyServiceHelper::ResolveProxy(const GURL& url, 938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProxyInfo* proxy_info, 939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log) { 940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(io_message_loop_ != MessageLoop::current()); 941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( 943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this, &SyncProxyServiceHelper::StartAsyncResolve, url, net_log)); 944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_.Wait(); 946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result_ == net::OK) { 948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *proxy_info = proxy_info_; 949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return result_; 951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint SyncProxyServiceHelper::ReconsiderProxyAfterError( 954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, ProxyInfo* proxy_info, const BoundNetLog& net_log) { 955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(io_message_loop_ != MessageLoop::current()); 956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( 958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this, &SyncProxyServiceHelper::StartAsyncReconsider, url, net_log)); 959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_.Wait(); 961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result_ == net::OK) { 963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *proxy_info = proxy_info_; 964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return result_; 966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 968731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickSyncProxyServiceHelper::~SyncProxyServiceHelper() {} 969731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SyncProxyServiceHelper::StartAsyncResolve(const GURL& url, 971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log) { 972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott result_ = proxy_service_->ResolveProxy( 973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url, &proxy_info_, &callback_, NULL, net_log); 974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result_ != net::ERR_IO_PENDING) { 975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OnCompletion(result_); 976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SyncProxyServiceHelper::StartAsyncReconsider(const GURL& url, 980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log) { 981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott result_ = proxy_service_->ReconsiderProxyAfterError( 982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url, &proxy_info_, &callback_, NULL, net_log); 983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result_ != net::ERR_IO_PENDING) { 984c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OnCompletion(result_); 985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SyncProxyServiceHelper::OnCompletion(int rv) { 989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott result_ = rv; 990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_.Signal(); 991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 994