| 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..00597f331ce361c0c9265fbfb30100b437adfe97 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"
|
| @@ -16,6 +17,7 @@
|
| #include "net/proxy/dhcp_proxy_script_fetcher.h"
|
| #include "net/proxy/dhcp_proxy_script_fetcher_factory.h"
|
| #include "net/proxy/proxy_script_fetcher.h"
|
| +#include "net/url_request/url_request_context.h"
|
|
|
| namespace net {
|
|
|
| @@ -45,7 +47,10 @@ bool LooksLikePacScript(const base::string16& script) {
|
| //
|
| // For more details, also check out this comment:
|
| // http://code.google.com/p/chromium/issues/detail?id=18575#c20
|
| -static const char kWpadUrl[] = "http://wpad/wpad.dat";
|
| +namespace {
|
| +const char kWpadUrl[] = "http://wpad/wpad.dat";
|
| +const int kQuickCheckDelayMs = 1000;
|
| +};
|
|
|
| base::Value* ProxyScriptDecider::PacSource::NetLogCallback(
|
| const GURL* effective_pac_url,
|
| @@ -82,6 +87,12 @@ ProxyScriptDecider::ProxyScriptDecider(
|
| net_log_(BoundNetLog::Make(
|
| net_log, NetLog::SOURCE_PROXY_SCRIPT_DECIDER)),
|
| fetch_pac_bytes_(false) {
|
| + if (proxy_script_fetcher &&
|
| + proxy_script_fetcher->GetRequestContext() &&
|
| + proxy_script_fetcher->GetRequestContext()->host_resolver()) {
|
| + host_resolver_.reset(new SingleRequestHostResolver(
|
| + proxy_script_fetcher->GetRequestContext()->host_resolver()));
|
| + }
|
| }
|
|
|
| ProxyScriptDecider::~ProxyScriptDecider() {
|
| @@ -172,6 +183,13 @@ int ProxyScriptDecider::DoLoop(int result) {
|
| case STATE_WAIT_COMPLETE:
|
| rv = DoWaitComplete(rv);
|
| break;
|
| + case STATE_QUICK_CHECK:
|
| + DCHECK_EQ(OK, rv);
|
| + rv = DoQuickCheck();
|
| + break;
|
| + case STATE_QUICK_CHECK_COMPLETE:
|
| + rv = DoQuickCheckComplete(rv);
|
| + break;
|
| case STATE_FETCH_PAC_SCRIPT:
|
| DCHECK_EQ(OK, rv);
|
| rv = DoFetchPacScript();
|
| @@ -221,10 +239,58 @@ int ProxyScriptDecider::DoWaitComplete(int result) {
|
| net_log_.EndEventWithNetErrorCode(NetLog::TYPE_PROXY_SCRIPT_DECIDER_WAIT,
|
| result);
|
| }
|
| - next_state_ = GetStartState();
|
| + next_state_ = STATE_QUICK_CHECK;
|
| return OK;
|
| }
|
|
|
| +int ProxyScriptDecider::DoQuickCheck() {
|
| + if (host_resolver_.get() == NULL) {
|
| + // If we have no resolver, skip QuickCheck altogether.
|
| + next_state_ = GetStartState();
|
| + return OK;
|
| + }
|
| +
|
| + quick_check_start_time_ = base::Time::Now();
|
| + HostResolver::RequestInfo reqinfo(HostPortPair("wpad", 80));
|
| + reqinfo.set_host_resolver_flags(HOST_RESOLVER_SYSTEM_ONLY);
|
| + CompletionCallback callback = base::Bind(
|
| + &ProxyScriptDecider::OnIOCompletion,
|
| + base::Unretained(this));
|
| +
|
| +
|
| + // We use HIGHEST here because proxy decision blocks doing any other requests.
|
| + int rv = host_resolver_->Resolve(reqinfo, HIGHEST, &wpad_addresses_,
|
| + callback, net_log_);
|
| +
|
| + // We can't get an error response - the name is known to be valid, and we
|
| + // don't cache negative dns responses.
|
| + DCHECK(rv == OK || rv == ERR_IO_PENDING);
|
| +
|
| + if (rv == OK) {
|
| + next_state_ = GetStartState();
|
| + } else {
|
| + quick_check_timer_.Start(FROM_HERE,
|
| + base::TimeDelta::FromMilliseconds(
|
| + kQuickCheckDelayMs),
|
| + base::Bind(callback, ERR_NAME_NOT_RESOLVED));
|
| + next_state_ = STATE_QUICK_CHECK_COMPLETE;
|
| + }
|
| + return rv;
|
| +}
|
| +
|
| +int ProxyScriptDecider::DoQuickCheckComplete(int result) {
|
| + base::TimeDelta delta = base::Time::Now() - quick_check_start_time_;
|
| + if (result == OK)
|
| + UMA_HISTOGRAM_TIMES("Net.WpadQuickCheckSuccess", delta);
|
| + else
|
| + UMA_HISTOGRAM_TIMES("Net.WpadQuickCheckFailure", delta);
|
| + host_resolver_->Cancel();
|
| + quick_check_timer_.Stop();
|
| + if (result == OK)
|
| + next_state_ = GetStartState();
|
| + return result;
|
| +}
|
| +
|
| int ProxyScriptDecider::DoFetchPacScript() {
|
| DCHECK(fetch_pac_bytes_);
|
|
|
|
|