Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/proxy/proxy_script_decider.h" | 5 #include "net/proxy/proxy_script_decider.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/metrics/histogram.h" | |
| 12 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 14 #include "base/values.h" | 15 #include "base/values.h" |
| 15 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
| 16 #include "net/proxy/dhcp_proxy_script_fetcher.h" | 17 #include "net/proxy/dhcp_proxy_script_fetcher.h" |
| 17 #include "net/proxy/dhcp_proxy_script_fetcher_factory.h" | 18 #include "net/proxy/dhcp_proxy_script_fetcher_factory.h" |
| 18 #include "net/proxy/proxy_script_fetcher.h" | 19 #include "net/proxy/proxy_script_fetcher.h" |
| 19 | 20 |
| 20 namespace net { | 21 namespace net { |
| 21 | 22 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher, | 75 DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher, |
| 75 NetLog* net_log) | 76 NetLog* net_log) |
| 76 : resolver_(NULL), | 77 : resolver_(NULL), |
| 77 proxy_script_fetcher_(proxy_script_fetcher), | 78 proxy_script_fetcher_(proxy_script_fetcher), |
| 78 dhcp_proxy_script_fetcher_(dhcp_proxy_script_fetcher), | 79 dhcp_proxy_script_fetcher_(dhcp_proxy_script_fetcher), |
| 79 current_pac_source_index_(0u), | 80 current_pac_source_index_(0u), |
| 80 pac_mandatory_(false), | 81 pac_mandatory_(false), |
| 81 next_state_(STATE_NONE), | 82 next_state_(STATE_NONE), |
| 82 net_log_(BoundNetLog::Make( | 83 net_log_(BoundNetLog::Make( |
| 83 net_log, NetLog::SOURCE_PROXY_SCRIPT_DECIDER)), | 84 net_log, NetLog::SOURCE_PROXY_SCRIPT_DECIDER)), |
| 84 fetch_pac_bytes_(false) { | 85 fetch_pac_bytes_(false), |
| 86 host_resolver_(HostResolver::CreateDefaultResolver(net_log)), | |
| 87 quick_check_delay_(base::TimeDelta::FromMilliseconds(1000)) { | |
| 85 } | 88 } |
| 86 | 89 |
| 87 ProxyScriptDecider::~ProxyScriptDecider() { | 90 ProxyScriptDecider::~ProxyScriptDecider() { |
| 88 if (next_state_ != STATE_NONE) | 91 if (next_state_ != STATE_NONE) |
| 89 Cancel(); | 92 Cancel(); |
| 90 } | 93 } |
| 91 | 94 |
| 92 int ProxyScriptDecider::Start( | 95 int ProxyScriptDecider::Start( |
| 93 const ProxyConfig& config, const base::TimeDelta wait_delay, | 96 const ProxyConfig& config, const base::TimeDelta wait_delay, |
| 94 bool fetch_pac_bytes, const CompletionCallback& callback) { | 97 bool fetch_pac_bytes, const CompletionCallback& callback) { |
| 95 DCHECK_EQ(STATE_NONE, next_state_); | 98 DCHECK_EQ(STATE_NONE, next_state_); |
| 96 DCHECK(!callback.is_null()); | 99 DCHECK(!callback.is_null()); |
| 97 DCHECK(config.HasAutomaticSettings()); | 100 DCHECK(config.HasAutomaticSettings()); |
| 98 | 101 |
| 99 net_log_.BeginEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER); | 102 net_log_.BeginEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER); |
| 100 | 103 |
| 101 fetch_pac_bytes_ = fetch_pac_bytes; | 104 fetch_pac_bytes_ = fetch_pac_bytes; |
| 102 | 105 |
| 103 // Save the |wait_delay| as a non-negative value. | 106 // Save the |wait_delay| as a non-negative value. |
| 104 wait_delay_ = wait_delay; | 107 wait_delay_ = wait_delay; |
| 105 if (wait_delay_ < base::TimeDelta()) | 108 if (wait_delay_ < base::TimeDelta()) |
| 106 wait_delay_ = base::TimeDelta(); | 109 wait_delay_ = base::TimeDelta(); |
| 107 | 110 |
| 108 pac_mandatory_ = config.pac_mandatory(); | 111 pac_mandatory_ = config.pac_mandatory(); |
| 109 | 112 |
| 110 pac_sources_ = BuildPacSourcesFallbackList(config); | 113 pac_sources_ = BuildPacSourcesFallbackList(config); |
| 111 DCHECK(!pac_sources_.empty()); | 114 DCHECK(!pac_sources_.empty()); |
| 112 | 115 |
| 113 next_state_ = STATE_WAIT; | 116 next_state_ = STATE_QUICK_CHECK; |
| 114 | 117 |
| 115 int rv = DoLoop(OK); | 118 int rv = DoLoop(OK); |
| 116 if (rv == ERR_IO_PENDING) | 119 if (rv == ERR_IO_PENDING) |
| 117 callback_ = callback; | 120 callback_ = callback; |
| 118 else | 121 else |
| 119 DidComplete(); | 122 DidComplete(); |
| 120 | 123 |
| 121 return rv; | 124 return rv; |
| 122 } | 125 } |
| 123 | 126 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 } | 161 } |
| 159 } | 162 } |
| 160 | 163 |
| 161 int ProxyScriptDecider::DoLoop(int result) { | 164 int ProxyScriptDecider::DoLoop(int result) { |
| 162 DCHECK_NE(next_state_, STATE_NONE); | 165 DCHECK_NE(next_state_, STATE_NONE); |
| 163 int rv = result; | 166 int rv = result; |
| 164 do { | 167 do { |
| 165 State state = next_state_; | 168 State state = next_state_; |
| 166 next_state_ = STATE_NONE; | 169 next_state_ = STATE_NONE; |
| 167 switch (state) { | 170 switch (state) { |
| 171 case STATE_QUICK_CHECK: | |
| 172 rv = DoQuickCheck(); | |
| 173 break; | |
| 168 case STATE_WAIT: | 174 case STATE_WAIT: |
| 169 DCHECK_EQ(OK, rv); | 175 DCHECK_EQ(OK, rv); |
| 170 rv = DoWait(); | 176 rv = DoWait(); |
| 171 break; | 177 break; |
| 172 case STATE_WAIT_COMPLETE: | 178 case STATE_WAIT_COMPLETE: |
| 173 rv = DoWaitComplete(rv); | 179 rv = DoWaitComplete(rv); |
| 174 break; | 180 break; |
| 175 case STATE_FETCH_PAC_SCRIPT: | 181 case STATE_FETCH_PAC_SCRIPT: |
| 176 DCHECK_EQ(OK, rv); | 182 DCHECK_EQ(OK, rv); |
| 177 rv = DoFetchPacScript(); | 183 rv = DoFetchPacScript(); |
| 178 break; | 184 break; |
| 179 case STATE_FETCH_PAC_SCRIPT_COMPLETE: | 185 case STATE_FETCH_PAC_SCRIPT_COMPLETE: |
| 180 rv = DoFetchPacScriptComplete(rv); | 186 rv = DoFetchPacScriptComplete(rv); |
| 181 break; | 187 break; |
| 182 case STATE_VERIFY_PAC_SCRIPT: | 188 case STATE_VERIFY_PAC_SCRIPT: |
| 183 DCHECK_EQ(OK, rv); | 189 DCHECK_EQ(OK, rv); |
| 184 rv = DoVerifyPacScript(); | 190 rv = DoVerifyPacScript(); |
| 185 break; | 191 break; |
| 186 case STATE_VERIFY_PAC_SCRIPT_COMPLETE: | 192 case STATE_VERIFY_PAC_SCRIPT_COMPLETE: |
| 187 rv = DoVerifyPacScriptComplete(rv); | 193 rv = DoVerifyPacScriptComplete(rv); |
| 188 break; | 194 break; |
| 195 case STATE_FAILED: | |
| 196 break; | |
| 189 default: | 197 default: |
| 190 NOTREACHED() << "bad state"; | 198 NOTREACHED() << "bad state"; |
| 191 rv = ERR_UNEXPECTED; | 199 rv = ERR_UNEXPECTED; |
| 192 break; | 200 break; |
| 193 } | 201 } |
| 194 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 202 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
| 195 return rv; | 203 return rv; |
| 196 } | 204 } |
| 197 | 205 |
| 198 void ProxyScriptDecider::DoCallback(int result) { | 206 void ProxyScriptDecider::DoCallback(int result) { |
| 199 DCHECK_NE(ERR_IO_PENDING, result); | 207 DCHECK_NE(ERR_IO_PENDING, result); |
| 200 DCHECK(!callback_.is_null()); | 208 DCHECK(!callback_.is_null()); |
| 201 callback_.Run(result); | 209 callback_.Run(result); |
| 202 } | 210 } |
| 203 | 211 |
| 212 int ProxyScriptDecider::DoQuickCheck() { | |
| 213 | |
| 214 HostResolver::RequestInfo reqinfo(HostPortPair("wpad", 80)); | |
| 215 | |
| 216 quick_check_started_ = base::Time::Now(); | |
| 217 int rv = host_resolver_->Resolve(reqinfo, HIGHEST, // we block startup... | |
| 218 &wpad_addrs_, | |
| 219 base::Bind( | |
| 220 &ProxyScriptDecider::OnQuickCheckComplete, | |
| 221 base::Unretained(this)), | |
| 222 &wpad_req_, | |
| 223 net_log_); | |
| 224 | |
| 225 if (rv == OK) { | |
| 226 // already in cache or something and valid, we're golden | |
| 227 next_state_ = STATE_WAIT; | |
| 228 return OK; | |
| 229 } else if (rv != ERR_IO_PENDING) { | |
| 230 // already in cache and invalid, bail now | |
|
szym
2013/08/21 19:11:21
We don't actually cache negative results in HostRe
| |
| 231 next_state_ = STATE_FAILED; | |
| 232 return rv; | |
| 233 } | |
| 234 | |
| 235 quick_check_timer_.Start(FROM_HERE, quick_check_delay_, this, | |
| 236 &ProxyScriptDecider::OnQuickCheckTimerFired); | |
| 237 | |
| 238 next_state_ = STATE_QUICK_CHECK; | |
| 239 return ERR_IO_PENDING; | |
| 240 } | |
| 241 | |
| 242 void ProxyScriptDecider::OnQuickCheckTimerFired() { | |
| 243 host_resolver_->CancelRequest(wpad_req_); | |
| 244 next_state_ = STATE_FAILED; | |
|
szym
2013/08/21 19:11:21
You'll probably want to UMA this as well. Putting
| |
| 245 OnIOCompletion(ERR_NAME_NOT_RESOLVED); | |
| 246 } | |
| 247 | |
| 248 void ProxyScriptDecider::OnQuickCheckComplete(int result) { | |
| 249 base::Time quick_check_ended = base::Time::Now(); | |
| 250 base::TimeDelta delta = quick_check_ended - quick_check_started_; | |
| 251 UMA_HISTOGRAM_TIMES("Net.WpadQuickCheck", delta); | |
| 252 quick_check_timer_.Stop(); | |
| 253 if (result == OK) | |
| 254 next_state_ = STATE_WAIT; | |
| 255 else | |
| 256 next_state_ = STATE_FAILED; | |
| 257 OnIOCompletion(result); | |
| 258 } | |
| 259 | |
| 204 int ProxyScriptDecider::DoWait() { | 260 int ProxyScriptDecider::DoWait() { |
| 205 next_state_ = STATE_WAIT_COMPLETE; | 261 next_state_ = STATE_WAIT_COMPLETE; |
| 206 | 262 |
| 207 // If no waiting is required, continue on to the next state. | 263 // If no waiting is required, continue on to the next state. |
| 208 if (wait_delay_.ToInternalValue() == 0) | 264 if (wait_delay_.ToInternalValue() == 0) |
| 209 return OK; | 265 return OK; |
| 210 | 266 |
| 211 // Otherwise wait the specified amount of time. | 267 // Otherwise wait the specified amount of time. |
| 212 wait_timer_.Start(FROM_HERE, wait_delay_, this, | 268 wait_timer_.Start(FROM_HERE, wait_delay_, this, |
| 213 &ProxyScriptDecider::OnWaitTimerFired); | 269 &ProxyScriptDecider::OnWaitTimerFired); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 405 } | 461 } |
| 406 | 462 |
| 407 // This is safe to call in any state. | 463 // This is safe to call in any state. |
| 408 if (dhcp_proxy_script_fetcher_) | 464 if (dhcp_proxy_script_fetcher_) |
| 409 dhcp_proxy_script_fetcher_->Cancel(); | 465 dhcp_proxy_script_fetcher_->Cancel(); |
| 410 | 466 |
| 411 DidComplete(); | 467 DidComplete(); |
| 412 } | 468 } |
| 413 | 469 |
| 414 } // namespace net | 470 } // namespace net |
| OLD | NEW |