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 18namespace net { 19 20class ProxyConfig; 21class ProxyResolver; 22class 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// 40class 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