| Index: net/proxy/init_proxy_resolver.cc
|
| ===================================================================
|
| --- net/proxy/init_proxy_resolver.cc (revision 0)
|
| +++ net/proxy/init_proxy_resolver.cc (revision 0)
|
| @@ -0,0 +1,189 @@
|
| +// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "net/proxy/init_proxy_resolver.h"
|
| +
|
| +#include "base/compiler_specific.h"
|
| +#include "base/logging.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "net/proxy/proxy_config.h"
|
| +#include "net/proxy/proxy_resolver.h"
|
| +#include "net/proxy/proxy_script_fetcher.h"
|
| +
|
| +namespace net {
|
| +
|
| +InitProxyResolver::InitProxyResolver(ProxyResolver* resolver,
|
| + ProxyScriptFetcher* proxy_script_fetcher)
|
| + : resolver_(resolver),
|
| + proxy_script_fetcher_(proxy_script_fetcher),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_(
|
| + this, &InitProxyResolver::OnIOCompletion)),
|
| + user_callback_(NULL),
|
| + current_pac_url_index_(0u),
|
| + next_state_(STATE_NONE) {
|
| +}
|
| +
|
| +InitProxyResolver::~InitProxyResolver() {
|
| + switch (next_state_) {
|
| + case STATE_FETCH_PAC_SCRIPT_COMPLETE:
|
| + proxy_script_fetcher_->Cancel();
|
| + break;
|
| + case STATE_SET_PAC_SCRIPT_COMPLETE:
|
| + resolver_->CancelSetPacScript();
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| +}
|
| +
|
| +int InitProxyResolver::Init(const ProxyConfig& config,
|
| + CompletionCallback* callback) {
|
| + DCHECK_EQ(STATE_NONE, next_state_);
|
| + DCHECK(callback);
|
| + DCHECK(config.MayRequirePACResolver());
|
| +
|
| + pac_urls_ = BuildPacUrlsFallbackList(config);
|
| + DCHECK(!pac_urls_.empty());
|
| +
|
| + next_state_ = GetStartState();
|
| +
|
| + int rv = DoLoop(OK);
|
| + if (rv == ERR_IO_PENDING)
|
| + user_callback_ = callback;
|
| + return rv;
|
| +}
|
| +
|
| +// Initialize the fallback rules.
|
| +// (1) WPAD
|
| +// (2) Custom PAC URL.
|
| +InitProxyResolver::UrlList InitProxyResolver::BuildPacUrlsFallbackList(
|
| + const ProxyConfig& config) const {
|
| + UrlList pac_urls;
|
| + if (config.auto_detect) {
|
| + GURL pac_url = resolver_->expects_pac_bytes() ?
|
| + GURL("http://wpad/wpad.dat") : GURL();
|
| + pac_urls.push_back(pac_url);
|
| + }
|
| + if (config.pac_url.is_valid())
|
| + pac_urls.push_back(config.pac_url);
|
| + return pac_urls;
|
| +}
|
| +
|
| +void InitProxyResolver::OnIOCompletion(int result) {
|
| + DCHECK_NE(STATE_NONE, next_state_);
|
| + int rv = DoLoop(result);
|
| + if (rv != ERR_IO_PENDING)
|
| + DoCallback(rv);
|
| +}
|
| +
|
| +int InitProxyResolver::DoLoop(int result) {
|
| + DCHECK_NE(next_state_, STATE_NONE);
|
| + int rv = result;
|
| + do {
|
| + State state = next_state_;
|
| + next_state_ = STATE_NONE;
|
| + switch (state) {
|
| + case STATE_FETCH_PAC_SCRIPT:
|
| + DCHECK_EQ(OK, rv);
|
| + rv = DoFetchPacScript();
|
| + break;
|
| + case STATE_FETCH_PAC_SCRIPT_COMPLETE:
|
| + rv = DoFetchPacScriptComplete(rv);
|
| + break;
|
| + case STATE_SET_PAC_SCRIPT:
|
| + DCHECK_EQ(OK, rv);
|
| + rv = DoSetPacScript();
|
| + break;
|
| + case STATE_SET_PAC_SCRIPT_COMPLETE:
|
| + rv = DoSetPacScriptComplete(rv);
|
| + break;
|
| + default:
|
| + NOTREACHED() << "bad state";
|
| + rv = ERR_UNEXPECTED;
|
| + break;
|
| + }
|
| + } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
|
| + return rv;
|
| +}
|
| +
|
| +void InitProxyResolver::DoCallback(int result) {
|
| + DCHECK_NE(ERR_IO_PENDING, result);
|
| + DCHECK(user_callback_);
|
| + user_callback_->Run(result);
|
| +}
|
| +
|
| +int InitProxyResolver::DoFetchPacScript() {
|
| + DCHECK(resolver_->expects_pac_bytes());
|
| +
|
| + next_state_ = STATE_FETCH_PAC_SCRIPT_COMPLETE;
|
| +
|
| + const GURL& pac_url = current_pac_url();
|
| +
|
| + LOG(INFO) << "Starting fetch of PAC script " << pac_url;
|
| +
|
| + return proxy_script_fetcher_->Fetch(pac_url, &pac_bytes_, &io_callback_);
|
| +}
|
| +
|
| +int InitProxyResolver::DoFetchPacScriptComplete(int result) {
|
| + DCHECK(resolver_->expects_pac_bytes());
|
| +
|
| + LOG(INFO) << "Completed PAC script fetch of " << current_pac_url()
|
| + << " with result " << ErrorToString(result)
|
| + << ". Fetched a total of " << pac_bytes_.size() << " bytes";
|
| +
|
| + if (result != OK)
|
| + return TryToFallbackPacUrl(result);
|
| +
|
| + next_state_ = STATE_SET_PAC_SCRIPT;
|
| + return result;
|
| +}
|
| +
|
| +int InitProxyResolver::DoSetPacScript() {
|
| + const GURL& pac_url = current_pac_url();
|
| +
|
| + next_state_ = STATE_SET_PAC_SCRIPT_COMPLETE;
|
| +
|
| + return resolver_->expects_pac_bytes() ?
|
| + resolver_->SetPacScriptByData(pac_bytes_, &io_callback_) :
|
| + resolver_->SetPacScriptByUrl(pac_url, &io_callback_);
|
| +}
|
| +
|
| +int InitProxyResolver::DoSetPacScriptComplete(int result) {
|
| + if (result != OK) {
|
| + LOG(INFO) << "Failed configuring PAC using " << current_pac_url()
|
| + << " with error " << ErrorToString(result);
|
| + return TryToFallbackPacUrl(result);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +int InitProxyResolver::TryToFallbackPacUrl(int error) {
|
| + DCHECK_LT(error, 0);
|
| +
|
| + if (current_pac_url_index_ + 1 >= pac_urls_.size()) {
|
| + // Nothing left to fall back to.
|
| + return error;
|
| + }
|
| +
|
| + // Advance to next URL in our list.
|
| + ++current_pac_url_index_;
|
| +
|
| + LOG(INFO) << "Falling back to next PAC URL...";
|
| +
|
| + next_state_ = GetStartState();
|
| +
|
| + return OK;
|
| +}
|
| +
|
| +InitProxyResolver::State InitProxyResolver::GetStartState() const {
|
| + return resolver_->expects_pac_bytes() ?
|
| + STATE_FETCH_PAC_SCRIPT : STATE_SET_PAC_SCRIPT;
|
| +}
|
| +
|
| +const GURL& InitProxyResolver::current_pac_url() const {
|
| + DCHECK_LT(current_pac_url_index_, pac_urls_.size());
|
| + return pac_urls_[current_pac_url_index_];
|
| +}
|
| +
|
| +} // namespace net
|
|
|
| Property changes on: net\proxy\init_proxy_resolver.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|