15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_script_decider.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/metrics/histogram.h" 135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/dhcp_proxy_script_fetcher.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/dhcp_proxy_script_fetcher_factory.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_script_fetcher.h" 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/url_request/url_request_context.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool LooksLikePacScript(const base::string16& script) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: this is only an approximation! It may not always work correctly, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // however it is very likely that legitimate scripts have this exact string, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since they must minimally define a function of this name. Conversely, a 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // file not containing the string is not likely to be a PAC script. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An exact test would have to load the script in a javascript evaluator. 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return script.find(base::ASCIIToUTF16("FindProxyForURL")) != 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16::npos; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the hard-coded location used by the DNS portion of web proxy 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// auto-discovery. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that we not use DNS devolution to find the WPAD host, since that could 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be dangerous should our top level domain registry become out of date. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Instead we directly resolve "wpad", and let the operating system apply the 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DNS suffix search paths. This is the same approach taken by Firefox, and 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// compatibility hasn't been an issue. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For more details, also check out this comment: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/chromium/issues/detail?id=18575#c20 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace { 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const char kWpadUrl[] = "http://wpad/wpad.dat"; 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const int kQuickCheckDelayMs = 1000; 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::Value* ProxyScriptDecider::PacSource::NetLogCallback( 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL* effective_pac_url, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::LogLevel /* log_level */) const { 597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string source; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PacSource::WPAD_DHCP: 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source = "WPAD DHCP"; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PacSource::WPAD_DNS: 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source = "WPAD DNS: "; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source += effective_pac_url->possibly_invalid_spec(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PacSource::CUSTOM: 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source = "Custom PAC URL: "; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source += effective_pac_url->possibly_invalid_spec(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("source", source); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyScriptDecider::ProxyScriptDecider( 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyScriptFetcher* proxy_script_fetcher, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog* net_log) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : resolver_(NULL), 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_script_fetcher_(proxy_script_fetcher), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dhcp_proxy_script_fetcher_(dhcp_proxy_script_fetcher), 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_pac_source_index_(0u), 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pac_mandatory_(false), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_(STATE_NONE), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_(BoundNetLog::Make( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log, NetLog::SOURCE_PROXY_SCRIPT_DECIDER)), 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetch_pac_bytes_(false), 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) quick_check_enabled_(true) { 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (proxy_script_fetcher && 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) proxy_script_fetcher->GetRequestContext() && 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) proxy_script_fetcher->GetRequestContext()->host_resolver()) { 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) host_resolver_.reset(new SingleRequestHostResolver( 96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) proxy_script_fetcher->GetRequestContext()->host_resolver())); 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyScriptDecider::~ProxyScriptDecider() { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_state_ != STATE_NONE) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyScriptDecider::Start( 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyConfig& config, const base::TimeDelta wait_delay, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool fetch_pac_bytes, const CompletionCallback& callback) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_NONE, next_state_); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(config.HasAutomaticSettings()); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.BeginEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetch_pac_bytes_ = fetch_pac_bytes; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the |wait_delay| as a non-negative value. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_delay_ = wait_delay; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (wait_delay_ < base::TimeDelta()) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_delay_ = base::TimeDelta(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pac_mandatory_ = config.pac_mandatory(); 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) have_custom_pac_url_ = config.has_pac_url(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pac_sources_ = BuildPacSourcesFallbackList(config); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!pac_sources_.empty()); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_WAIT; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = DoLoop(OK); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_ = callback; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidComplete(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProxyConfig& ProxyScriptDecider::effective_config() const { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_NONE, next_state_); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return effective_config_; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(eroman): Return a const-pointer. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyResolverScriptData* ProxyScriptDecider::script_data() const { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_NONE, next_state_); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return script_data_.get(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initialize the fallback rules. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (1) WPAD (DHCP). 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (2) WPAD (DNS). 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (3) Custom PAC URL. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyScriptDecider::PacSourceList ProxyScriptDecider:: 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildPacSourcesFallbackList( 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyConfig& config) const { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PacSourceList pac_sources; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (config.auto_detect()) { 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pac_sources.push_back(PacSource(PacSource::WPAD_DHCP, GURL(kWpadUrl))); 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pac_sources.push_back(PacSource(PacSource::WPAD_DNS, GURL(kWpadUrl))); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (config.has_pac_url()) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pac_sources.push_back(PacSource(PacSource::CUSTOM, config.pac_url())); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pac_sources; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyScriptDecider::OnIOCompletion(int result) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(STATE_NONE, next_state_); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = DoLoop(result); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != ERR_IO_PENDING) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidComplete(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoCallback(rv); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyScriptDecider::DoLoop(int result) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(next_state_, STATE_NONE); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = result; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State state = next_state_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_NONE; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_WAIT: 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoWait(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_WAIT_COMPLETE: 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoWaitComplete(rv); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case STATE_QUICK_CHECK: 190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(OK, rv); 191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) rv = DoQuickCheck(); 192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case STATE_QUICK_CHECK_COMPLETE: 194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) rv = DoQuickCheckComplete(rv); 195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_FETCH_PAC_SCRIPT: 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoFetchPacScript(); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_FETCH_PAC_SCRIPT_COMPLETE: 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoFetchPacScriptComplete(rv); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_VERIFY_PAC_SCRIPT: 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoVerifyPacScript(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_VERIFY_PAC_SCRIPT_COMPLETE: 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoVerifyPacScriptComplete(rv); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "bad state"; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ERR_UNEXPECTED; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyScriptDecider::DoCallback(int result) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(ERR_IO_PENDING, result); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback_.is_null()); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(result); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyScriptDecider::DoWait() { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_WAIT_COMPLETE; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If no waiting is required, continue on to the next state. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (wait_delay_.ToInternalValue() == 0) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise wait the specified amount of time. 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_timer_.Start(FROM_HERE, wait_delay_, this, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ProxyScriptDecider::OnWaitTimerFired); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.BeginEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_WAIT); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_IO_PENDING; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyScriptDecider::DoWaitComplete(int result) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, result); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (wait_delay_.ToInternalValue() != 0) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.EndEventWithNetErrorCode(NetLog::TYPE_PROXY_SCRIPT_DECIDER_WAIT, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (quick_check_enabled_ && current_pac_source().type == PacSource::WPAD_DNS) 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next_state_ = STATE_QUICK_CHECK; 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next_state_ = GetStartState(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int ProxyScriptDecider::DoQuickCheck() { 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(quick_check_enabled_); 254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (host_resolver_.get() == NULL) { 255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If we have no resolver, skip QuickCheck altogether. 256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) next_state_ = GetStartState(); 257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return OK; 258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) quick_check_start_time_ = base::Time::Now(); 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string host = current_pac_source().url.host(); 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HostResolver::RequestInfo reqinfo(HostPortPair(host, 80)); 263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) reqinfo.set_host_resolver_flags(HOST_RESOLVER_SYSTEM_ONLY); 264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CompletionCallback callback = base::Bind( 265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &ProxyScriptDecider::OnIOCompletion, 266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Unretained(this)); 267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next_state_ = STATE_QUICK_CHECK_COMPLETE; 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) quick_check_timer_.Start(FROM_HERE, 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta::FromMilliseconds( 271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kQuickCheckDelayMs), 272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(callback, ERR_NAME_NOT_RESOLVED)); 273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // We use HIGHEST here because proxy decision blocks doing any other requests. 275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return host_resolver_->Resolve(reqinfo, HIGHEST, &wpad_addresses_, 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) callback, net_log_); 277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int ProxyScriptDecider::DoQuickCheckComplete(int result) { 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(quick_check_enabled_); 281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::TimeDelta delta = base::Time::Now() - quick_check_start_time_; 282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result == OK) 283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UMA_HISTOGRAM_TIMES("Net.WpadQuickCheckSuccess", delta); 284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else 285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UMA_HISTOGRAM_TIMES("Net.WpadQuickCheckFailure", delta); 286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) host_resolver_->Cancel(); 287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) quick_check_timer_.Stop(); 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (result != OK) 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return TryToFallbackPacSource(result); 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next_state_ = GetStartState(); 291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return result; 292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyScriptDecider::DoFetchPacScript() { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(fetch_pac_bytes_); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_FETCH_PAC_SCRIPT_COMPLETE; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PacSource& pac_source = current_pac_source(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL effective_pac_url; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetermineURL(pac_source, &effective_pac_url); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.BeginEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PacSource::NetLogCallback, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&pac_source), 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &effective_pac_url)); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pac_source.type == PacSource::WPAD_DHCP) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dhcp_proxy_script_fetcher_) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.AddEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_HAS_NO_FETCHER); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNEXPECTED; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dhcp_proxy_script_fetcher_->Fetch( 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &pac_script_, base::Bind(&ProxyScriptDecider::OnIOCompletion, 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proxy_script_fetcher_) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.AddEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_HAS_NO_FETCHER); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNEXPECTED; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proxy_script_fetcher_->Fetch( 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effective_pac_url, &pac_script_, 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ProxyScriptDecider::OnIOCompletion, base::Unretained(this))); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyScriptDecider::DoFetchPacScriptComplete(int result) { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(fetch_pac_bytes_); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.EndEventWithNetErrorCode( 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT, result); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != OK) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TryToFallbackPacSource(result); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_VERIFY_PAC_SCRIPT; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyScriptDecider::DoVerifyPacScript() { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_VERIFY_PAC_SCRIPT_COMPLETE; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is just a heuristic. Ideally we would try to parse the script. 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fetch_pac_bytes_ && !LooksLikePacScript(pac_script_)) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_PAC_SCRIPT_FAILED; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyScriptDecider::DoVerifyPacScriptComplete(int result) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != OK) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TryToFallbackPacSource(result); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PacSource& pac_source = current_pac_source(); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extract the current script data. 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fetch_pac_bytes_) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_data_ = ProxyResolverScriptData::FromUTF16(pac_script_); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_data_ = pac_source.type == PacSource::CUSTOM ? 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolverScriptData::FromURL(pac_source.url) : 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyResolverScriptData::ForAutoDetect(); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let the caller know which automatic setting we ended up initializing the 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // resolver for (there may have been multiple fallbacks to choose from.) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_pac_source().type == PacSource::CUSTOM) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effective_config_ = 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfig::CreateFromCustomPacURL(current_pac_source().url); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effective_config_.set_pac_mandatory(pac_mandatory_); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fetch_pac_bytes_) { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL auto_detected_url; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (current_pac_source().type) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PacSource::WPAD_DHCP: 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auto_detected_url = dhcp_proxy_script_fetcher_->GetPacURL(); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PacSource::WPAD_DNS: 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auto_detected_url = GURL(kWpadUrl); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effective_config_ = 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyConfig::CreateFromCustomPacURL(auto_detected_url); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The resolver does its own resolution so we cannot know the 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URL. Just do the best we can and state that the configuration 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is to auto-detect proxy settings. 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effective_config_ = ProxyConfig::CreateAutoDetect(); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProxyScriptDecider::TryToFallbackPacSource(int error) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LT(error, 0); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_pac_source_index_ + 1 >= pac_sources_.size()) { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nothing left to fall back to. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Advance to next URL in our list. 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++current_pac_source_index_; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.AddEvent( 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::TYPE_PROXY_SCRIPT_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE); 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (quick_check_enabled_ && current_pac_source().type == PacSource::WPAD_DNS) 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next_state_ = STATE_QUICK_CHECK; 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next_state_ = GetStartState(); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyScriptDecider::State ProxyScriptDecider::GetStartState() const { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fetch_pac_bytes_ ? STATE_FETCH_PAC_SCRIPT : STATE_VERIFY_PAC_SCRIPT; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyScriptDecider::DetermineURL(const PacSource& pac_source, 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL* effective_pac_url) { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(effective_pac_url); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (pac_source.type) { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PacSource::WPAD_DHCP: 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PacSource::WPAD_DNS: 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *effective_pac_url = GURL(kWpadUrl); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PacSource::CUSTOM: 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *effective_pac_url = pac_source.url; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProxyScriptDecider::PacSource& 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyScriptDecider::current_pac_source() const { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LT(current_pac_source_index_, pac_sources_.size()); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pac_sources_[current_pac_source_index_]; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyScriptDecider::OnWaitTimerFired() { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnIOCompletion(OK); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyScriptDecider::DidComplete() { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.EndEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyScriptDecider::Cancel() { 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(STATE_NONE, next_state_); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.AddEvent(NetLog::TYPE_CANCELLED); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (next_state_) { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_WAIT_COMPLETE: 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_timer_.Stop(); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_FETCH_PAC_SCRIPT_COMPLETE: 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_script_fetcher_->Cancel(); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is safe to call in any state. 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dhcp_proxy_script_fetcher_) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dhcp_proxy_script_fetcher_->Cancel(); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidComplete(); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 483