summaryrefslogtreecommitdiffstats
path: root/net/proxy/init_proxy_resolver.cc
diff options
context:
space:
mode:
authorericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-04 22:43:12 +0000
committerericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-04 22:43:12 +0000
commit620f57148c311c4dc2cf680a4a5861fbdcd29993 (patch)
tree93408ed35ebbaccd8f45734c7267392c81d71ca9 /net/proxy/init_proxy_resolver.cc
parent289fdf862c649d17ddb2e08295304efb98f641f6 (diff)
downloadchromium_src-620f57148c311c4dc2cf680a4a5861fbdcd29993.zip
chromium_src-620f57148c311c4dc2cf680a4a5861fbdcd29993.tar.gz
chromium_src-620f57148c311c4dc2cf680a4a5861fbdcd29993.tar.bz2
Better match IE's proxy settings.
* When BOTH autodetect and custom PAC script are given, try both. * Use successful PAC parsing as the heuristic for determining when a script is valid (rather than first-request). * Only apply the proxy bypass list when using non-PAC. The high level explanation on how this works: http://sites.google.com/a/chromium.org/dev/developers/design-documents/proxy-settings-fallback BUG= http://crbug.com/18271, http://crbug.com/9985 TEST=unit tests. Review URL: http://codereview.chromium.org/160510 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22430 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/proxy/init_proxy_resolver.cc')
-rw-r--r--net/proxy/init_proxy_resolver.cc189
1 files changed, 189 insertions, 0 deletions
diff --git a/net/proxy/init_proxy_resolver.cc b/net/proxy/init_proxy_resolver.cc
new file mode 100644
index 0000000..7b98c4a
--- /dev/null
+++ b/net/proxy/init_proxy_resolver.cc
@@ -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