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)#ifndef NET_PROXY_PROXY_SCRIPT_DECIDER_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_PROXY_PROXY_SCRIPT_DECIDER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 125e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string16.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_resolver.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DhcpProxyScriptFetcher; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NetLogParameter; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProxyResolver; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProxyScriptFetcher; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProxyScriptDecider is a helper class used by ProxyService to determine which 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PAC script to use given our proxy configuration. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This involves trying to use PAC scripts in this order: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (1) WPAD (DHCP) if auto-detect is on. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (2) WPAD (DNS) if auto-detect is on. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (3) Custom PAC script if a URL was given. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If no PAC script was successfully selected, then it fails with either a 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// network error, or PAC_SCRIPT_FAILED (indicating it did not pass our 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// validation). 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On successful completion, the fetched PAC script data can be accessed using 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// script_data(). 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Deleting ProxyScriptDecider while Init() is in progress, will 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cancel the request. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE ProxyScriptDecider { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |proxy_script_fetcher|, |dhcp_proxy_script_fetcher| and 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |net_log| must remain valid for the lifespan of ProxyScriptDecider. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyScriptDecider(ProxyScriptFetcher* proxy_script_fetcher, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog* net_log); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Aborts any in-progress request. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ProxyScriptDecider(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Evaluates the effective proxy settings for |config|, and downloads the 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // associated PAC script. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |wait_delay| is positive, the initialization will pause for this 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // amount of time before getting started. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On successful completion, the "effective" proxy settings we ended up 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deciding on will be available vial the effective_settings() accessor. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that this may differ from |config| since we will have stripped any 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manual settings, and decided whether to use auto-detect or the custom PAC 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URL. Finally, if auto-detect was used we may now have resolved that to a 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // specific script URL. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int Start(const ProxyConfig& config, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta wait_delay, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool fetch_pac_bytes, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyConfig& effective_config() const; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(eroman): Return a const-pointer. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolverScriptData* script_data() const; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Represents the sources from which we can get PAC files; two types of 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // auto-detect or a custom URL. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PacSource { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Type { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WPAD_DHCP, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WPAD_DNS, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CUSTOM 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PacSource(Type type, const GURL& url) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : type(type), url(url) {} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a Value representing the PacSource. |effective_pac_url| must 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be non-NULL and point to the URL derived from information contained in 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |this|, if Type is not WPAD_DHCP. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Value* NetLogCallback(const GURL* effective_pac_url, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::LogLevel log_level) const; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type type; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url; // Empty unless |type == PAC_SOURCE_CUSTOM|. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<PacSource> PacSourceList; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum State { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_NONE, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_WAIT, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_WAIT_COMPLETE, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_FETCH_PAC_SCRIPT, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_FETCH_PAC_SCRIPT_COMPLETE, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_VERIFY_PAC_SCRIPT, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_VERIFY_PAC_SCRIPT_COMPLETE, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns ordered list of PAC urls to try for |config|. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PacSourceList BuildPacSourcesFallbackList(const ProxyConfig& config) const; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnIOCompletion(int result); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoLoop(int result); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoCallback(int result); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoWait(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoWaitComplete(int result); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoFetchPacScript(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoFetchPacScriptComplete(int result); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoVerifyPacScript(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoVerifyPacScriptComplete(int result); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tries restarting using the next fallback PAC URL: 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |pac_sources_[++current_pac_source_index]|. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns OK and rewinds the state machine when there 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is something to try, otherwise returns |error|. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int TryToFallbackPacSource(int error); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets the initial state (we skip fetching when the 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ProxyResolver doesn't |expect_pac_bytes()|. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State GetStartState() const; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DetermineURL(const PacSource& pac_source, GURL* effective_pac_url); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the current PAC URL we are fetching/testing. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PacSource& current_pac_source() const; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnWaitTimerFired(); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DidComplete(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Cancel(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolver* resolver_; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyScriptFetcher* proxy_script_fetcher_; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher_; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback callback_; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t current_pac_source_index_; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Filled when the PAC script fetch completes. 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 pac_script_; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flag indicating whether the caller requested a mandatory pac script 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (i.e. fallback to direct connections are prohibited). 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pac_mandatory_; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PacSourceList pac_sources_; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State next_state_; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog net_log_; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool fetch_pac_bytes_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta wait_delay_; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::OneShotTimer<ProxyScriptDecider> wait_timer_; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Results. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfig effective_config_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ProxyResolverScriptData> script_data_; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ProxyScriptDecider); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NET_PROXY_PROXY_SCRIPT_DECIDER_H_ 185