Index: net/proxy/proxy_script_decider.cc |
diff --git a/net/proxy/proxy_script_decider.cc b/net/proxy/proxy_script_decider.cc |
index 38bf751cd4da3e3c89ccdacbe079854911e1c058..3eaad3e1082838840d970a68ca7cfa90337d6210 100644 |
--- a/net/proxy/proxy_script_decider.cc |
+++ b/net/proxy/proxy_script_decider.cc |
@@ -9,6 +9,7 @@ |
#include "base/compiler_specific.h" |
#include "base/format_macros.h" |
#include "base/logging.h" |
+#include "base/metrics/histogram.h" |
#include "base/strings/string_util.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/values.h" |
@@ -81,7 +82,9 @@ ProxyScriptDecider::ProxyScriptDecider( |
next_state_(STATE_NONE), |
net_log_(BoundNetLog::Make( |
net_log, NetLog::SOURCE_PROXY_SCRIPT_DECIDER)), |
- fetch_pac_bytes_(false) { |
+ fetch_pac_bytes_(false), |
+ host_resolver_(HostResolver::CreateDefaultResolver(net_log)), |
+ quick_check_delay_(base::TimeDelta::FromMilliseconds(1000)) { |
} |
ProxyScriptDecider::~ProxyScriptDecider() { |
@@ -110,7 +113,7 @@ int ProxyScriptDecider::Start( |
pac_sources_ = BuildPacSourcesFallbackList(config); |
DCHECK(!pac_sources_.empty()); |
- next_state_ = STATE_WAIT; |
+ next_state_ = STATE_QUICK_CHECK; |
int rv = DoLoop(OK); |
if (rv == ERR_IO_PENDING) |
@@ -165,6 +168,9 @@ int ProxyScriptDecider::DoLoop(int result) { |
State state = next_state_; |
next_state_ = STATE_NONE; |
switch (state) { |
+ case STATE_QUICK_CHECK: |
+ rv = DoQuickCheck(); |
+ break; |
case STATE_WAIT: |
DCHECK_EQ(OK, rv); |
rv = DoWait(); |
@@ -186,6 +192,8 @@ int ProxyScriptDecider::DoLoop(int result) { |
case STATE_VERIFY_PAC_SCRIPT_COMPLETE: |
rv = DoVerifyPacScriptComplete(rv); |
break; |
+ case STATE_FAILED: |
+ break; |
default: |
NOTREACHED() << "bad state"; |
rv = ERR_UNEXPECTED; |
@@ -201,6 +209,54 @@ void ProxyScriptDecider::DoCallback(int result) { |
callback_.Run(result); |
} |
+int ProxyScriptDecider::DoQuickCheck() { |
+ |
+ HostResolver::RequestInfo reqinfo(HostPortPair("wpad", 80)); |
+ |
+ quick_check_started_ = base::Time::Now(); |
+ int rv = host_resolver_->Resolve(reqinfo, HIGHEST, // we block startup... |
+ &wpad_addrs_, |
+ base::Bind( |
+ &ProxyScriptDecider::OnQuickCheckComplete, |
+ base::Unretained(this)), |
+ &wpad_req_, |
+ net_log_); |
+ |
+ if (rv == OK) { |
+ // already in cache or something and valid, we're golden |
+ next_state_ = STATE_WAIT; |
+ return OK; |
+ } else if (rv != ERR_IO_PENDING) { |
+ // already in cache and invalid, bail now |
szym
2013/08/21 19:11:21
We don't actually cache negative results in HostRe
|
+ next_state_ = STATE_FAILED; |
+ return rv; |
+ } |
+ |
+ quick_check_timer_.Start(FROM_HERE, quick_check_delay_, this, |
+ &ProxyScriptDecider::OnQuickCheckTimerFired); |
+ |
+ next_state_ = STATE_QUICK_CHECK; |
+ return ERR_IO_PENDING; |
+} |
+ |
+void ProxyScriptDecider::OnQuickCheckTimerFired() { |
+ host_resolver_->CancelRequest(wpad_req_); |
+ next_state_ = STATE_FAILED; |
szym
2013/08/21 19:11:21
You'll probably want to UMA this as well. Putting
|
+ OnIOCompletion(ERR_NAME_NOT_RESOLVED); |
+} |
+ |
+void ProxyScriptDecider::OnQuickCheckComplete(int result) { |
+ base::Time quick_check_ended = base::Time::Now(); |
+ base::TimeDelta delta = quick_check_ended - quick_check_started_; |
+ UMA_HISTOGRAM_TIMES("Net.WpadQuickCheck", delta); |
+ quick_check_timer_.Stop(); |
+ if (result == OK) |
+ next_state_ = STATE_WAIT; |
+ else |
+ next_state_ = STATE_FAILED; |
+ OnIOCompletion(result); |
+} |
+ |
int ProxyScriptDecider::DoWait() { |
next_state_ = STATE_WAIT_COMPLETE; |