1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_PROXY_INIT_PROXY_RESOLVER_H_ 6 #define NET_PROXY_INIT_PROXY_RESOLVER_H_ 7 #pragma once 8 9 #include <vector> 10 11 #include "base/string16.h" 12 #include "base/time.h" 13 #include "base/timer.h" 14 #include "googleurl/src/gurl.h" 15 #include "net/base/completion_callback.h" 16 #include "net/base/net_log.h" 17 18 namespace net { 19 20 class ProxyConfig; 21 class ProxyResolver; 22 class ProxyScriptFetcher; 23 24 // InitProxyResolver is a helper class used by ProxyService to 25 // initialize a ProxyResolver with the PAC script data specified 26 // by a particular ProxyConfig. 27 // 28 // This involves trying to use PAC scripts in this order: 29 // 30 // (1) WPAD (DNS) if auto-detect is on. 31 // (2) Custom PAC script if a URL was given. 32 // 33 // If no PAC script was successfully downloaded + parsed, then it fails with 34 // a network error. Otherwise the proxy resolver is left initialized with 35 // the PAC script. 36 // 37 // Deleting InitProxyResolver while Init() is in progress, will 38 // cancel the request. 39 // 40 class InitProxyResolver { 41 public: 42 // |resolver|, |proxy_script_fetcher| and |net_log| must remain valid for 43 // the lifespan of InitProxyResolver. 44 InitProxyResolver(ProxyResolver* resolver, 45 ProxyScriptFetcher* proxy_script_fetcher, 46 NetLog* net_log); 47 48 // Aborts any in-progress request. 49 ~InitProxyResolver(); 50 51 // Applies the PAC settings of |config| to |resolver_|. 52 // If |wait_delay| is positive, the initialization will pause for this 53 // amount of time before getting started. 54 // If |effective_config| is non-NULL, then on successful initialization of 55 // |resolver_| the "effective" proxy settings we ended up using will be 56 // written out to |*effective_config|. Note that this may differ from 57 // |config| since we will have stripped any manual settings, and decided 58 // whether to use auto-detect or the custom PAC URL. Finally, if auto-detect 59 // was used we may now have resolved that to a specific script URL. 60 int Init(const ProxyConfig& config, 61 const base::TimeDelta wait_delay, 62 ProxyConfig* effective_config, 63 CompletionCallback* callback); 64 65 private: 66 struct PacURL { 67 PacURL(bool auto_detect, const GURL& url) 68 : auto_detect(auto_detect), url(url) {} 69 bool auto_detect; 70 GURL url; 71 }; 72 73 typedef std::vector<PacURL> UrlList; 74 75 enum State { 76 STATE_NONE, 77 STATE_WAIT, 78 STATE_WAIT_COMPLETE, 79 STATE_FETCH_PAC_SCRIPT, 80 STATE_FETCH_PAC_SCRIPT_COMPLETE, 81 STATE_SET_PAC_SCRIPT, 82 STATE_SET_PAC_SCRIPT_COMPLETE, 83 }; 84 85 // Returns ordered list of PAC urls to try for |config|. 86 UrlList BuildPacUrlsFallbackList(const ProxyConfig& config) const; 87 88 void OnIOCompletion(int result); 89 int DoLoop(int result); 90 void DoCallback(int result); 91 92 int DoWait(); 93 int DoWaitComplete(int result); 94 95 int DoFetchPacScript(); 96 int DoFetchPacScriptComplete(int result); 97 98 int DoSetPacScript(); 99 int DoSetPacScriptComplete(int result); 100 101 // Tries restarting using the next fallback PAC URL: 102 // |pac_urls_[++current_pac_url_index]|. 103 // Returns OK and rewinds the state machine when there 104 // is something to try, otherwise returns |error|. 105 int TryToFallbackPacUrl(int error); 106 107 // Gets the initial state (we skip fetching when the 108 // ProxyResolver doesn't |expect_pac_bytes()|. 109 State GetStartState() const; 110 111 // Returns the current PAC URL we are fetching/testing. 112 const PacURL& current_pac_url() const; 113 114 void OnWaitTimerFired(); 115 void DidCompleteInit(); 116 void Cancel(); 117 118 ProxyResolver* resolver_; 119 ProxyScriptFetcher* proxy_script_fetcher_; 120 121 CompletionCallbackImpl<InitProxyResolver> io_callback_; 122 CompletionCallback* user_callback_; 123 124 size_t current_pac_url_index_; 125 126 // Filled when the PAC script fetch completes. 127 string16 pac_script_; 128 129 UrlList pac_urls_; 130 State next_state_; 131 132 BoundNetLog net_log_; 133 134 base::TimeDelta wait_delay_; 135 base::OneShotTimer<InitProxyResolver> wait_timer_; 136 137 ProxyConfig* effective_config_; 138 139 DISALLOW_COPY_AND_ASSIGN(InitProxyResolver); 140 }; 141 142 } // namespace net 143 144 #endif // NET_PROXY_INIT_PROXY_RESOLVER_H_ 145