summaryrefslogtreecommitdiffstats
path: root/net/proxy/dhcp_proxy_script_fetcher_win.cc
diff options
context:
space:
mode:
authorjoi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-17 17:55:35 +0000
committerjoi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-17 17:55:35 +0000
commit00106e1c05c9dcd01f055f8682e87bc97a09c648 (patch)
tree9fb08a6a44726056dd75607022dbbf31315cb994 /net/proxy/dhcp_proxy_script_fetcher_win.cc
parent92c6608cda88cf297275ba4b964b64f3475abbd6 (diff)
downloadchromium_src-00106e1c05c9dcd01f055f8682e87bc97a09c648.zip
chromium_src-00106e1c05c9dcd01f055f8682e87bc97a09c648.tar.gz
chromium_src-00106e1c05c9dcd01f055f8682e87bc97a09c648.tar.bz2
Revert 85646 - Adds support for the DHCP portion of the WPAD (proxy auto-discovery) protocol.
This is Windows-only for now, and is disabled by default. Start Chrome with the flag --enable-dhcp-wpad to enable the feature. See discussion in comment on DhcpProxyScriptFetcherFactory for why this needs to be done in a per-platform way rather than cross-platform. The code is factored so that adding other platform implementations will be straight forward. Most of the implementation is stand-alone and extends the ScriptProxyFetcher class hierarchy (and makes its interface slightly more generic). The integration point into existing code is in InitProxyResolver, which previously handled fallback from DNS auto-detect to custom PAC URL and now does fallback from DHCP to DNS to custom PAC URL. BUG=18575 TEST=net_unittests has good coverage for the new and changed code, but manual tests on a network with a PAC URL configured in DHCP are also needed. Review URL: http://codereview.chromium.org/6831025 TBR=joi@chromium.org Review URL: http://codereview.chromium.org/7019015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85648 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/proxy/dhcp_proxy_script_fetcher_win.cc')
-rw-r--r--net/proxy/dhcp_proxy_script_fetcher_win.cc246
1 files changed, 0 insertions, 246 deletions
diff --git a/net/proxy/dhcp_proxy_script_fetcher_win.cc b/net/proxy/dhcp_proxy_script_fetcher_win.cc
deleted file mode 100644
index 35109f6..0000000
--- a/net/proxy/dhcp_proxy_script_fetcher_win.cc
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright (c) 2011 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/dhcp_proxy_script_fetcher_win.h"
-
-#include "net/base/net_errors.h"
-#include "net/proxy/dhcp_proxy_script_adapter_fetcher_win.h"
-
-#include <winsock2.h>
-#include <iphlpapi.h>
-#pragma comment(lib, "iphlpapi.lib")
-
-namespace {
-
-// How long to wait at maximum after we get results (a PAC file or
-// knowledge that no PAC file is configured) from whichever network
-// adapter finishes first.
-const int kMaxWaitAfterFirstResultMs = 400;
-
-} // namespace
-
-namespace net {
-
-DhcpProxyScriptFetcherWin::DhcpProxyScriptFetcherWin(
- URLRequestContext* url_request_context)
- : state_(STATE_START),
- ALLOW_THIS_IN_INITIALIZER_LIST(fetcher_callback_(
- this, &DhcpProxyScriptFetcherWin::OnFetcherDone)),
- num_pending_fetchers_(0),
- url_request_context_(url_request_context) {
- DCHECK(url_request_context_);
-}
-
-DhcpProxyScriptFetcherWin::~DhcpProxyScriptFetcherWin() {
- Cancel();
-}
-
-int DhcpProxyScriptFetcherWin::Fetch(string16* utf16_text,
- CompletionCallback* callback) {
- DCHECK(CalledOnValidThread());
- if (state_ != STATE_START && state_ != STATE_DONE) {
- NOTREACHED();
- return ERR_UNEXPECTED;
- }
-
- std::set<std::string> adapter_names;
- if (!ImplGetCandidateAdapterNames(&adapter_names)) {
- return ERR_UNEXPECTED;
- }
- if (adapter_names.empty()) {
- return ERR_PAC_NOT_IN_DHCP;
- }
-
- state_ = STATE_NO_RESULTS;
-
- client_callback_ = callback;
- destination_string_ = utf16_text;
-
- for (std::set<std::string>::iterator it = adapter_names.begin();
- it != adapter_names.end();
- ++it) {
- DhcpProxyScriptAdapterFetcher* fetcher(ImplCreateAdapterFetcher());
- fetcher->Fetch(*it, &fetcher_callback_);
- fetchers_.push_back(fetcher);
- }
- num_pending_fetchers_ = fetchers_.size();
-
- return ERR_IO_PENDING;
-}
-
-void DhcpProxyScriptFetcherWin::Cancel() {
- DCHECK(CalledOnValidThread());
-
- if (state_ != STATE_DONE) {
- wait_timer_.Stop();
- state_ = STATE_DONE;
-
- for (FetcherVector::iterator it = fetchers_.begin();
- it != fetchers_.end();
- ++it) {
- (*it)->Cancel();
- }
-
- fetchers_.reset();
- }
-}
-
-std::string DhcpProxyScriptFetcherWin::GetFetcherName() const {
- DCHECK(CalledOnValidThread());
- return "win";
-}
-
-const GURL& DhcpProxyScriptFetcherWin::GetPacURL() const {
- DCHECK(CalledOnValidThread());
- DCHECK_EQ(state_, STATE_DONE);
-
- return pac_url_;
-}
-
-void DhcpProxyScriptFetcherWin::OnFetcherDone(int result) {
- DCHECK(state_ == STATE_NO_RESULTS || state_ == STATE_SOME_RESULTS);
-
- if (--num_pending_fetchers_ == 0) {
- TransitionToDone();
- return;
- }
-
- // If the only pending adapters are those less preferred than one
- // with a valid PAC script, we do not need to wait any longer.
- for (FetcherVector::iterator it = fetchers_.begin();
- it != fetchers_.end();
- ++it) {
- bool did_finish = (*it)->DidFinish();
- int result = (*it)->GetResult();
- if (did_finish && result == OK) {
- TransitionToDone();
- return;
- }
- if (!did_finish || result != ERR_PAC_NOT_IN_DHCP) {
- break;
- }
- }
-
- // Once we have a single result, we set a maximum on how long to wait
- // for the rest of the results.
- if (state_ == STATE_NO_RESULTS) {
- state_ = STATE_SOME_RESULTS;
- wait_timer_.Start(
- base::TimeDelta::FromMilliseconds(ImplGetMaxWaitMs()),
- this, &DhcpProxyScriptFetcherWin::OnWaitTimer);
- }
-}
-
-void DhcpProxyScriptFetcherWin::OnWaitTimer() {
- DCHECK_EQ(state_, STATE_SOME_RESULTS);
- TransitionToDone();
-}
-
-void DhcpProxyScriptFetcherWin::TransitionToDone() {
- DCHECK(state_ == STATE_NO_RESULTS || state_ == STATE_SOME_RESULTS);
-
- // Should have returned immediately at Fetch() if no adapters to check.
- DCHECK(!fetchers_.empty());
-
- // Scan twice for the result; once through the whole list for success,
- // then if no success, return result for most preferred network adapter,
- // preferring "real" network errors to the ERR_PAC_NOT_IN_DHCP error.
- // Default to ERR_ABORTED if no fetcher completed.
- int result = ERR_ABORTED;
- for (FetcherVector::iterator it = fetchers_.begin();
- it != fetchers_.end();
- ++it) {
- if ((*it)->DidFinish() && (*it)->GetResult() == OK) {
- result = OK;
- *destination_string_ = (*it)->GetPacScript();
- pac_url_ = (*it)->GetPacURL();
- break;
- }
- }
- if (result != OK) {
- destination_string_->clear();
- for (FetcherVector::iterator it = fetchers_.begin();
- it != fetchers_.end();
- ++it) {
- if ((*it)->DidFinish()) {
- result = (*it)->GetResult();
- if (result != ERR_PAC_NOT_IN_DHCP) {
- break;
- }
- }
- }
- }
-
- Cancel();
- DCHECK_EQ(state_, STATE_DONE);
- DCHECK(fetchers_.empty());
-
- client_callback_->Run(result);
-}
-
-DhcpProxyScriptAdapterFetcher*
- DhcpProxyScriptFetcherWin::ImplCreateAdapterFetcher() {
- return new DhcpProxyScriptAdapterFetcher(url_request_context_);
-}
-
-bool DhcpProxyScriptFetcherWin::ImplGetCandidateAdapterNames(
- std::set<std::string>* adapter_names) {
- return GetCandidateAdapterNames(adapter_names);
-}
-
-int DhcpProxyScriptFetcherWin::ImplGetMaxWaitMs() {
- return kMaxWaitAfterFirstResultMs;
-}
-
-bool DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(
- std::set<std::string>* adapter_names) {
- DCHECK(adapter_names);
- adapter_names->clear();
-
- // The GetAdaptersAddresses MSDN page recommends using a size of 15000 to
- // avoid reallocation.
- ULONG adapters_size = 15000;
- scoped_ptr_malloc<IP_ADAPTER_ADDRESSES> adapters;
- ULONG error = ERROR_SUCCESS;
- int num_tries = 0;
- do {
- adapters.reset(
- reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(adapters_size)));
- // Return only unicast addresses, and skip information we do not need.
- error = GetAdaptersAddresses(AF_UNSPEC,
- GAA_FLAG_SKIP_ANYCAST |
- GAA_FLAG_SKIP_MULTICAST |
- GAA_FLAG_SKIP_DNS_SERVER |
- GAA_FLAG_SKIP_FRIENDLY_NAME,
- NULL,
- adapters.get(),
- &adapters_size);
- ++num_tries;
- } while (error == ERROR_BUFFER_OVERFLOW && num_tries <= 3);
-
- if (error == ERROR_NO_DATA) {
- // There are no adapters that we care about.
- return true;
- }
-
- if (error != ERROR_SUCCESS) {
- LOG(WARNING) << "Unexpected error retrieving WPAD configuration from DHCP.";
- return false;
- }
-
- IP_ADAPTER_ADDRESSES* adapter = NULL;
- for (adapter = adapters.get(); adapter; adapter = adapter->Next) {
- if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
- continue;
- if ((adapter->Flags & IP_ADAPTER_DHCP_ENABLED) == 0)
- continue;
-
- DCHECK(adapter->AdapterName);
- adapter_names->insert(adapter->AdapterName);
- }
-
- return true;
-}
-
-} // namespace net