diff options
author | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-17 17:55:35 +0000 |
---|---|---|
committer | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-17 17:55:35 +0000 |
commit | 00106e1c05c9dcd01f055f8682e87bc97a09c648 (patch) | |
tree | 9fb08a6a44726056dd75607022dbbf31315cb994 /net/proxy | |
parent | 92c6608cda88cf297275ba4b964b64f3475abbd6 (diff) | |
download | chromium_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')
23 files changed, 158 insertions, 2468 deletions
diff --git a/net/proxy/dhcp_proxy_script_adapter_fetcher_win.cc b/net/proxy/dhcp_proxy_script_adapter_fetcher_win.cc deleted file mode 100644 index f09537c..0000000 --- a/net/proxy/dhcp_proxy_script_adapter_fetcher_win.cc +++ /dev/null @@ -1,286 +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_adapter_fetcher_win.h" - -#include "base/message_loop_proxy.h" -#include "base/sys_string_conversions.h" -#include "base/task.h" -#include "base/threading/worker_pool.h" -#include "base/time.h" -#include "net/base/net_errors.h" -#include "net/proxy/dhcpcsvc_init_win.h" -#include "net/proxy/proxy_script_fetcher_impl.h" -#include "net/url_request/url_request_context.h" - -#include <windows.h> -#include <winsock2.h> -#include <dhcpcsdk.h> -#pragma comment(lib, "dhcpcsvc.lib") - -namespace { - -// Maximum amount of time to wait for response from the Win32 DHCP API. -const int kTimeoutMs = 2000; - -} // namespace - -namespace net { - -DhcpProxyScriptAdapterFetcher::DhcpProxyScriptAdapterFetcher( - URLRequestContext* url_request_context) - : state_(STATE_START), - result_(ERR_IO_PENDING), - callback_(NULL), - ALLOW_THIS_IN_INITIALIZER_LIST( - script_fetcher_callback_( - this, &DhcpProxyScriptAdapterFetcher::OnFetcherDone)), - url_request_context_(url_request_context) { -} - -DhcpProxyScriptAdapterFetcher::~DhcpProxyScriptAdapterFetcher() { - Cancel(); - - // The WeakPtr we passed to the worker thread may be destroyed on the - // worker thread. This detaches any outstanding WeakPtr state from - // the current thread. - base::SupportsWeakPtr<DhcpProxyScriptAdapterFetcher>::DetachFromThread(); -} - -void DhcpProxyScriptAdapterFetcher::Fetch( - const std::string& adapter_name, CompletionCallback* callback) { - DCHECK(CalledOnValidThread()); - DCHECK_EQ(state_, STATE_START); - result_ = ERR_IO_PENDING; - pac_script_ = string16(); - state_ = STATE_WAIT_DHCP; - callback_ = callback; - - wait_timer_.Start(ImplGetTimeout(), - this, &DhcpProxyScriptAdapterFetcher::OnTimeout); - worker_thread_ = ImplCreateWorkerThread(AsWeakPtr()); - worker_thread_->Start(adapter_name); -} - -void DhcpProxyScriptAdapterFetcher::Cancel() { - DCHECK(CalledOnValidThread()); - callback_ = NULL; - wait_timer_.Stop(); - script_fetcher_.reset(); - - switch (state_) { - case STATE_WAIT_DHCP: - // Nothing to do here, we let the worker thread run to completion, - // the task it posts back when it completes will check the state. - break; - case STATE_WAIT_URL: - break; - case STATE_START: - case STATE_FINISH: - case STATE_CANCEL: - break; - } - - if (state_ != STATE_FINISH) { - result_ = ERR_ABORTED; - state_ = STATE_CANCEL; - } -} - -bool DhcpProxyScriptAdapterFetcher::DidFinish() const { - DCHECK(CalledOnValidThread()); - return state_ == STATE_FINISH; -} - -int DhcpProxyScriptAdapterFetcher::GetResult() const { - DCHECK(CalledOnValidThread()); - return result_; -} - -string16 DhcpProxyScriptAdapterFetcher::GetPacScript() const { - DCHECK(CalledOnValidThread()); - return pac_script_; -} - -GURL DhcpProxyScriptAdapterFetcher::GetPacURL() const { - DCHECK(CalledOnValidThread()); - return pac_url_; -} - -DhcpProxyScriptAdapterFetcher::WorkerThread::WorkerThread( - const base::WeakPtr<DhcpProxyScriptAdapterFetcher>& owner) - : owner_(owner), - origin_loop_(base::MessageLoopProxy::CreateForCurrentThread()) { -} - -DhcpProxyScriptAdapterFetcher::WorkerThread::~WorkerThread() { -} - -void DhcpProxyScriptAdapterFetcher::WorkerThread::Start( - const std::string& adapter_name) { - bool succeeded = base::WorkerPool::PostTask( - FROM_HERE, - NewRunnableMethod( - this, - &DhcpProxyScriptAdapterFetcher::WorkerThread::ThreadFunc, - adapter_name), - true); - DCHECK(succeeded); -} - -void DhcpProxyScriptAdapterFetcher::WorkerThread::ThreadFunc( - const std::string& adapter_name) { - std::string url = ImplGetPacURLFromDhcp(adapter_name); - - bool succeeded = origin_loop_->PostTask( - FROM_HERE, - NewRunnableMethod( - this, - &DhcpProxyScriptAdapterFetcher::WorkerThread::OnThreadDone, - url)); - DCHECK(succeeded); -} - -void DhcpProxyScriptAdapterFetcher::WorkerThread::OnThreadDone( - const std::string& url) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (owner_) - owner_->OnQueryDhcpDone(url); -} - -std::string - DhcpProxyScriptAdapterFetcher::WorkerThread::ImplGetPacURLFromDhcp( - const std::string& adapter_name) { - return DhcpProxyScriptAdapterFetcher::GetPacURLFromDhcp(adapter_name); -} - -void DhcpProxyScriptAdapterFetcher::OnQueryDhcpDone( - const std::string& url) { - DCHECK(CalledOnValidThread()); - // Because we can't cancel the call to the Win32 API, we can expect - // it to finish while we are in a few different states. The expected - // one is WAIT_DHCP, but it could be in CANCEL if Cancel() was called, - // or FINISH if timeout occurred. - DCHECK(state_ == STATE_WAIT_DHCP || state_ == STATE_CANCEL || - state_ == STATE_FINISH); - if (state_ != STATE_WAIT_DHCP) - return; - - wait_timer_.Stop(); - - pac_url_ = GURL(url); - if (pac_url_.is_empty() || !pac_url_.is_valid()) { - result_ = ERR_PAC_NOT_IN_DHCP; - TransitionToFinish(); - } else { - state_ = STATE_WAIT_URL; - script_fetcher_.reset(ImplCreateScriptFetcher()); - script_fetcher_->Fetch(pac_url_, &pac_script_, &script_fetcher_callback_); - } -} - -void DhcpProxyScriptAdapterFetcher::OnTimeout() { - DCHECK_EQ(state_, STATE_WAIT_DHCP); - result_ = ERR_TIMED_OUT; - TransitionToFinish(); -} - -void DhcpProxyScriptAdapterFetcher::OnFetcherDone(int result) { - DCHECK(CalledOnValidThread()); - DCHECK(state_ == STATE_WAIT_URL || state_ == STATE_CANCEL); - if (state_ == STATE_CANCEL) - return; - - // At this point, pac_script_ has already been written to. - script_fetcher_.reset(); - result_ = result; - TransitionToFinish(); -} - -void DhcpProxyScriptAdapterFetcher::TransitionToFinish() { - DCHECK(state_ == STATE_WAIT_DHCP || state_ == STATE_WAIT_URL); - state_ = STATE_FINISH; - callback_->Run(result_); - callback_ = NULL; -} - -ProxyScriptFetcher* DhcpProxyScriptAdapterFetcher::ImplCreateScriptFetcher() { - return new ProxyScriptFetcherImpl(url_request_context_); -} - -DhcpProxyScriptAdapterFetcher::WorkerThread* - DhcpProxyScriptAdapterFetcher::ImplCreateWorkerThread( - const base::WeakPtr<DhcpProxyScriptAdapterFetcher>& owner) { - return new WorkerThread(owner); -} - -base::TimeDelta DhcpProxyScriptAdapterFetcher::ImplGetTimeout() const { - return base::TimeDelta::FromMilliseconds(kTimeoutMs); -} - -// static -std::string DhcpProxyScriptAdapterFetcher::GetPacURLFromDhcp( - const std::string& adapter_name) { - EnsureDhcpcsvcInit(); - - std::wstring adapter_name_wide = base::SysMultiByteToWide(adapter_name, - CP_ACP); - - DHCPCAPI_PARAMS_ARRAY send_params = { 0, NULL }; - - BYTE option_data[] = { 1, 252 }; - DHCPCAPI_PARAMS wpad_params = { 0 }; - wpad_params.OptionId = 252; - wpad_params.IsVendor = FALSE; // Surprising, but intentional. - - DHCPCAPI_PARAMS_ARRAY request_params = { 0 }; - request_params.nParams = 1; - request_params.Params = &wpad_params; - - // The maximum message size is typically 4096 bytes on Windows per - // http://support.microsoft.com/kb/321592 - DWORD result_buffer_size = 4096; - scoped_ptr_malloc<BYTE> result_buffer; - int retry_count = 0; - DWORD res = NO_ERROR; - do { - result_buffer.reset(reinterpret_cast<BYTE*>(malloc(result_buffer_size))); - - // Note that while the DHCPCAPI_REQUEST_SYNCHRONOUS flag seems to indicate - // there might be an asynchronous mode, there seems to be (at least in - // terms of well-documented use of this API) only a synchronous mode, with - // an optional "async notifications later if the option changes" mode. - // Even IE9, which we hope to emulate as IE is the most widely deployed - // previous implementation of the DHCP aspect of WPAD and the only one - // on Windows (Konqueror is the other, on Linux), uses this API with the - // synchronous flag. There seem to be several Microsoft Knowledge Base - // articles about calls to this function failing when other flags are used - // (e.g. http://support.microsoft.com/kb/885270) so we won't take any - // chances on non-standard, poorly documented usage. - res = ::DhcpRequestParams(DHCPCAPI_REQUEST_SYNCHRONOUS, - NULL, - const_cast<LPWSTR>(adapter_name_wide.c_str()), - NULL, - send_params, request_params, - result_buffer.get(), &result_buffer_size, - NULL); - ++retry_count; - } while (res == ERROR_MORE_DATA && retry_count <= 3); - - if (res != NO_ERROR) { - NOTREACHED(); - } else if (wpad_params.nBytesData) { - // The result should be ASCII, not wide character. - DCHECK_EQ(strlen(reinterpret_cast<const char*>(wpad_params.Data)) + 1, - wpad_params.nBytesData); - // Return only up to the first null in case of embedded NULLs; if the - // server is giving us back a buffer with embedded NULLs, something is - // broken anyway. - return std::string(reinterpret_cast<const char *>(wpad_params.Data)); - } - - return ""; -} - -} // namespace net diff --git a/net/proxy/dhcp_proxy_script_adapter_fetcher_win.h b/net/proxy/dhcp_proxy_script_adapter_fetcher_win.h deleted file mode 100644 index bab7468..0000000 --- a/net/proxy/dhcp_proxy_script_adapter_fetcher_win.h +++ /dev/null @@ -1,198 +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. - -#ifndef NET_PROXY_DHCP_SCRIPT_ADAPTER_FETCHER_WIN_H_ -#define NET_PROXY_DHCP_SCRIPT_ADAPTER_FETCHER_WIN_H_ -#pragma once - -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/string16.h" -#include "base/threading/non_thread_safe.h" -#include "base/timer.h" -#include "net/base/completion_callback.h" -#include "googleurl/src/gurl.h" - -namespace base { -class MessageLoopProxy; -} - -namespace net { - -class ProxyScriptFetcher; -class URLRequestContext; - -// For a given adapter, this class takes care of first doing a DHCP lookup -// to get the PAC URL, then if there is one, trying to fetch it. -class DhcpProxyScriptAdapterFetcher - : public base::SupportsWeakPtr<DhcpProxyScriptAdapterFetcher>, - public base::NonThreadSafe { - public: - // |url_request_context| must outlive DhcpProxyScriptAdapterFetcher. - explicit DhcpProxyScriptAdapterFetcher( - URLRequestContext* url_request_context); - virtual ~DhcpProxyScriptAdapterFetcher(); - - // Starts a fetch. On completion (but not cancellation), |callback| - // will be invoked with the network error indicating success or failure - // of fetching a DHCP-configured PAC file on this adapter. - // - // On completion, results can be obtained via |GetPacScript()|, |GetPacURL()|. - // - // You may only call Fetch() once on a given instance of - // DhcpProxyScriptAdapterFetcher. - virtual void Fetch(const std::string& adapter_name, - CompletionCallback* callback); - - // Cancels the fetch on this adapter. - virtual void Cancel(); - - // Returns true if in the FINISH state (not CANCEL). - virtual bool DidFinish() const; - - // Returns the network error indicating the result of the fetch. Will - // return IO_PENDING until the fetch is complete or cancelled. This is - // the same network error passed to the |callback| provided to |Fetch()|. - virtual int GetResult() const; - - // Returns the contents of the PAC file retrieved. Only valid if - // |IsComplete()| is true. Returns the empty string if |GetResult()| - // returns anything other than OK. - virtual string16 GetPacScript() const; - - // Returns the PAC URL retrieved from DHCP. Only guaranteed to be - // valid if |IsComplete()| is true. Returns an empty URL if no URL was - // configured in DHCP. May return a valid URL even if |result()| does - // not return OK (this would indicate that we found a URL configured in - // DHCP but failed to download it). - virtual GURL GetPacURL() const; - - // Returns the PAC URL configured in DHCP for the given |adapter_name|, or - // the empty string if none is configured. - // - // This function executes synchronously due to limitations of the Windows - // DHCP client API. - static std::string GetPacURLFromDhcp(const std::string& adapter_name); - - protected: - // This inner class is used to encapsulate the worker thread, which has - // only a weak reference back to the main object, so that the main object - // can be destroyed before the thread ends. This also keeps the main - // object completely thread safe and allows it to be non-refcounted. - class WorkerThread : public base::RefCountedThreadSafe<WorkerThread> { - public: - // Creates and initializes (but does not start) the worker thread. - explicit WorkerThread( - const base::WeakPtr<DhcpProxyScriptAdapterFetcher>& owner); - virtual ~WorkerThread(); - - // Starts the worker thread, fetching information for |adapter_name| using - // |get_pac_from_url_func|. - void Start(const std::string& adapter_name); - - protected: - // Virtual method introduced to allow unit testing. - virtual std::string ImplGetPacURLFromDhcp(const std::string& adapter_name); - - private: - // This is the method that runs on the worker thread. - void ThreadFunc(const std::string& adapter_name); - - // Callback for the above; this executes back on the main thread, - // not the worker thread. - void OnThreadDone(const std::string& url); - - // All work except ThreadFunc and (sometimes) destruction should occur - // on the thread that constructs the object. - base::ThreadChecker thread_checker_; - - // May only be accessed on the thread that constructs the object. - base::WeakPtr<DhcpProxyScriptAdapterFetcher> owner_; - - // Used by worker thread to post a message back to the original - // thread. Fine to use a proxy since in the case where the original - // thread has gone away, that would mean the |owner_| object is gone - // anyway, so there is nobody to receive the result. - scoped_refptr<base::MessageLoopProxy> origin_loop_; - - DISALLOW_COPY_AND_ASSIGN(WorkerThread); - }; - - // Event/state transition handlers - void OnQueryDhcpDone(const std::string& url); - void OnTimeout(); - void OnFetcherDone(int result); - void TransitionToFinish(); - - // Virtual methods introduced to allow unit testing. - virtual ProxyScriptFetcher* ImplCreateScriptFetcher(); - virtual WorkerThread* ImplCreateWorkerThread( - const base::WeakPtr<DhcpProxyScriptAdapterFetcher>& owner); - virtual base::TimeDelta ImplGetTimeout() const; - - // This is the state machine for fetching from a given adapter. - // - // The state machine goes from START->WAIT_DHCP when it starts - // a worker thread to fetch the PAC URL from DHCP. - // - // In state WAIT_DHCP, if the DHCP query finishes and has no URL, it - // moves to state FINISH. If there is a URL, it starts a - // ProxyScriptFetcher to fetch it and moves to state WAIT_URL. - // - // It goes from WAIT_URL->FINISH when the ProxyScriptFetcher completes. - // - // In state FINISH, completion is indicated to the outer class, with - // the results of the fetch if a PAC script was successfully fetched. - // - // In state WAIT_DHCP, our timeout occurring can push us to FINISH. - // - // In any state except FINISH, a call to Cancel() will move to state - // CANCEL and cause all outstanding work to be cancelled or its - // results ignored when available. - enum State { - STATE_START, - STATE_WAIT_DHCP, - STATE_WAIT_URL, - STATE_FINISH, - STATE_CANCEL, - }; - - // Current state of this state machine. - State state_; - - // A network error indicating result of operation. - int result_; - - // Empty string or the PAC script downloaded. - string16 pac_script_; - - // Empty URL or the PAC URL configured in DHCP. - GURL pac_url_; - - // Callback to let our client know we're done. Invalid in states - // START, FINISH and CANCEL. - CompletionCallback* callback_; - - // Container for our worker thread. NULL if not currently running. - scoped_refptr<WorkerThread> worker_thread_; - - // Fetcher to retrieve PAC files once URL is known. - scoped_ptr<ProxyScriptFetcher> script_fetcher_; - - // Callback from the script fetcher. - CompletionCallbackImpl<DhcpProxyScriptAdapterFetcher> - script_fetcher_callback_; - - // Implements a timeout on the call to the Win32 DHCP API. - base::OneShotTimer<DhcpProxyScriptAdapterFetcher> wait_timer_; - - scoped_refptr<URLRequestContext> url_request_context_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(DhcpProxyScriptAdapterFetcher); -}; - -} // namespace net - -#endif // NET_PROXY_DHCP_SCRIPT_ADAPTER_FETCHER_WIN_H_ diff --git a/net/proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc b/net/proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc deleted file mode 100644 index b4b05f9..0000000 --- a/net/proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc +++ /dev/null @@ -1,300 +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_adapter_fetcher_win.h" - -#include "base/perftimer.h" -#include "base/synchronization/waitable_event.h" -#include "base/timer.h" -#include "net/base/net_errors.h" -#include "net/base/test_completion_callback.h" -#include "net/proxy/mock_proxy_script_fetcher.h" -#include "net/proxy/proxy_script_fetcher_impl.h" -#include "net/test/test_server.h" -#include "net/url_request/url_request_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -namespace { - -const char* const kPacUrl = "http://pacserver/script.pac"; - -// In net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc there are a few -// tests that exercise DhcpProxyScriptAdapterFetcher end-to-end along with -// DhcpProxyScriptFetcherWin, i.e. it tests the end-to-end usage of Win32 -// APIs and the network. In this file we test only by stubbing out -// functionality. - -// Version of DhcpProxyScriptAdapterFetcher that mocks out dependencies -// to allow unit testing. -class MockDhcpProxyScriptAdapterFetcher - : public DhcpProxyScriptAdapterFetcher { - public: - explicit MockDhcpProxyScriptAdapterFetcher(URLRequestContext* context) - : DhcpProxyScriptAdapterFetcher(context), - dhcp_delay_ms_(1), - timeout_ms_(100), - configured_url_(kPacUrl), - fetcher_delay_ms_(1), - fetcher_result_(OK), - pac_script_("bingo") { - } - - void Cancel() { - DhcpProxyScriptAdapterFetcher::Cancel(); - fetcher_ = NULL; - } - - virtual ProxyScriptFetcher* ImplCreateScriptFetcher() OVERRIDE { - // We don't maintain ownership of the fetcher, it is transferred to - // the caller. - fetcher_ = new MockProxyScriptFetcher(); - if (fetcher_delay_ms_ != -1) { - fetcher_timer_.Start( - base::TimeDelta::FromMilliseconds(fetcher_delay_ms_), - this, &MockDhcpProxyScriptAdapterFetcher::OnFetcherTimer); - } - return fetcher_; - } - - class DelayingWorkerThread : public WorkerThread { - public: - explicit DelayingWorkerThread( - const base::WeakPtr<DhcpProxyScriptAdapterFetcher>& owner) - : WorkerThread(owner), - test_finished_event_(true, false) { - } - - std::string ImplGetPacURLFromDhcp( - const std::string& adapter_name) OVERRIDE { - PerfTimer timer; - test_finished_event_.TimedWait(dhcp_delay_); - return configured_url_; - } - - base::WaitableEvent test_finished_event_; - TimeDelta dhcp_delay_; - std::string configured_url_; - }; - - virtual WorkerThread* ImplCreateWorkerThread( - const base::WeakPtr<DhcpProxyScriptAdapterFetcher>& owner) OVERRIDE { - worker_thread_ = new DelayingWorkerThread(owner); - worker_thread_->dhcp_delay_ = TimeDelta::FromMilliseconds(dhcp_delay_ms_); - worker_thread_->configured_url_ = configured_url_; - return worker_thread_; - } - - // Use a shorter timeout so tests can finish more quickly. - virtual base::TimeDelta ImplGetTimeout() const OVERRIDE { - return base::TimeDelta::FromMilliseconds(timeout_ms_); - } - - void OnFetcherTimer() { - // Note that there is an assumption by this mock implementation that - // DhcpProxyScriptAdapterFetcher::Fetch will call ImplCreateScriptFetcher - // and call Fetch on the fetcher before the message loop is re-entered. - // This holds true today, but if you hit this DCHECK the problem can - // possibly be resolved by having a separate subclass of - // MockProxyScriptFetcher that adds the delay internally (instead of - // the simple approach currently used in ImplCreateScriptFetcher above). - DCHECK(fetcher_ && fetcher_->has_pending_request()); - fetcher_->NotifyFetchCompletion(fetcher_result_, pac_script_); - fetcher_ = NULL; - } - - bool IsWaitingForFetcher() const { - return state_ == STATE_WAIT_URL; - } - - bool WasCancelled() const { - return state_ == STATE_CANCEL; - } - - void FinishTest() { - DCHECK(worker_thread_); - worker_thread_->test_finished_event_.Signal(); - } - - int dhcp_delay_ms_; - int timeout_ms_; - std::string configured_url_; - int fetcher_delay_ms_; - int fetcher_result_; - std::string pac_script_; - MockProxyScriptFetcher* fetcher_; - base::OneShotTimer<MockDhcpProxyScriptAdapterFetcher> fetcher_timer_; - scoped_refptr<DelayingWorkerThread> worker_thread_; -}; - -class FetcherClient { - public: - FetcherClient() - : url_request_context_(new TestURLRequestContext()), - fetcher_( - new MockDhcpProxyScriptAdapterFetcher(url_request_context_.get())) { - } - - void WaitForResult(int expected_error) { - EXPECT_EQ(expected_error, callback_.WaitForResult()); - } - - void RunTest() { - fetcher_->Fetch("adapter name", &callback_); - } - - void FinishTestAllowCleanup() { - fetcher_->FinishTest(); - MessageLoop::current()->RunAllPending(); - } - - TestCompletionCallback callback_; - scoped_refptr<URLRequestContext> url_request_context_; - scoped_ptr<MockDhcpProxyScriptAdapterFetcher> fetcher_; - string16 pac_text_; -}; - -TEST(DhcpProxyScriptAdapterFetcher, NormalCaseURLNotInDhcp) { - FetcherClient client; - client.fetcher_->configured_url_ = ""; - client.RunTest(); - client.WaitForResult(ERR_PAC_NOT_IN_DHCP); - ASSERT_TRUE(client.fetcher_->DidFinish()); - EXPECT_EQ(ERR_PAC_NOT_IN_DHCP, client.fetcher_->GetResult()); - EXPECT_EQ(string16(L""), client.fetcher_->GetPacScript()); -} - -TEST(DhcpProxyScriptAdapterFetcher, NormalCaseURLInDhcp) { - FetcherClient client; - client.RunTest(); - client.WaitForResult(OK); - ASSERT_TRUE(client.fetcher_->DidFinish()); - EXPECT_EQ(OK, client.fetcher_->GetResult()); - EXPECT_EQ(string16(L"bingo"), client.fetcher_->GetPacScript()); - EXPECT_EQ(GURL(kPacUrl), client.fetcher_->GetPacURL()); -} - -TEST(DhcpProxyScriptAdapterFetcher, TimeoutDuringDhcp) { - // Does a Fetch() with a long enough delay on accessing DHCP that the - // fetcher should time out. This is to test a case manual testing found, - // where under certain circumstances (e.g. adapter enabled for DHCP and - // needs to retrieve its configuration from DHCP, but no DHCP server - // present on the network) accessing DHCP can take on the order of tens - // of seconds. - FetcherClient client; - client.fetcher_->dhcp_delay_ms_ = 20 * 1000; - client.fetcher_->timeout_ms_ = 25; - - PerfTimer timer; - client.RunTest(); - client.WaitForResult(ERR_TIMED_OUT); - - // The timeout should occur within about 25 ms, way before the 20s set as - // the API delay above. - ASSERT_GT(base::TimeDelta::FromMilliseconds(35), timer.Elapsed()); - ASSERT_TRUE(client.fetcher_->DidFinish()); - EXPECT_EQ(ERR_TIMED_OUT, client.fetcher_->GetResult()); - EXPECT_EQ(string16(L""), client.fetcher_->GetPacScript()); - EXPECT_EQ(GURL(), client.fetcher_->GetPacURL()); - client.FinishTestAllowCleanup(); -} - -TEST(DhcpProxyScriptAdapterFetcher, CancelWhileDhcp) { - FetcherClient client; - client.fetcher_->dhcp_delay_ms_ = 10; - client.RunTest(); - client.fetcher_->Cancel(); - MessageLoop::current()->RunAllPending(); - ASSERT_FALSE(client.fetcher_->DidFinish()); - ASSERT_TRUE(client.fetcher_->WasCancelled()); - EXPECT_EQ(ERR_ABORTED, client.fetcher_->GetResult()); - EXPECT_EQ(string16(L""), client.fetcher_->GetPacScript()); - EXPECT_EQ(GURL(), client.fetcher_->GetPacURL()); - client.FinishTestAllowCleanup(); -} - -TEST(DhcpProxyScriptAdapterFetcher, CancelWhileFetcher) { - FetcherClient client; - // This causes the mock fetcher not to pretend the - // fetcher finishes after a timeout. - client.fetcher_->fetcher_delay_ms_ = -1; - client.RunTest(); - int max_loops = 4; - while (!client.fetcher_->IsWaitingForFetcher() && max_loops--) { - base::PlatformThread::Sleep(10); - MessageLoop::current()->RunAllPending(); - } - client.fetcher_->Cancel(); - MessageLoop::current()->RunAllPending(); - ASSERT_FALSE(client.fetcher_->DidFinish()); - ASSERT_TRUE(client.fetcher_->WasCancelled()); - EXPECT_EQ(ERR_ABORTED, client.fetcher_->GetResult()); - EXPECT_EQ(string16(L""), client.fetcher_->GetPacScript()); - // GetPacURL() still returns the URL fetched in this case. - EXPECT_EQ(GURL(kPacUrl), client.fetcher_->GetPacURL()); - client.FinishTestAllowCleanup(); -} - -TEST(DhcpProxyScriptAdapterFetcher, CancelAtCompletion) { - FetcherClient client; - client.RunTest(); - client.WaitForResult(OK); - client.fetcher_->Cancel(); - // Canceling after you're done should have no effect, so these - // are identical expectations to the NormalCaseURLInDhcp test. - ASSERT_TRUE(client.fetcher_->DidFinish()); - EXPECT_EQ(OK, client.fetcher_->GetResult()); - EXPECT_EQ(string16(L"bingo"), client.fetcher_->GetPacScript()); - EXPECT_EQ(GURL(kPacUrl), client.fetcher_->GetPacURL()); - client.FinishTestAllowCleanup(); -} - -// Does a real fetch on a mock DHCP configuration. -class MockDhcpRealFetchProxyScriptAdapterFetcher - : public MockDhcpProxyScriptAdapterFetcher { - public: - explicit MockDhcpRealFetchProxyScriptAdapterFetcher( - URLRequestContext* context) - : MockDhcpProxyScriptAdapterFetcher(context), - url_request_context_(context) { - } - - // Returns a real proxy script fetcher. - ProxyScriptFetcher* ImplCreateScriptFetcher() OVERRIDE { - ProxyScriptFetcher* fetcher = - new ProxyScriptFetcherImpl(url_request_context_); - return fetcher; - } - - URLRequestContext* url_request_context_; -}; - -TEST(DhcpProxyScriptAdapterFetcher, MockDhcpRealFetch) { - TestServer test_server( - TestServer::TYPE_HTTP, - FilePath(FILE_PATH_LITERAL("net/data/proxy_script_fetcher_unittest"))); - ASSERT_TRUE(test_server.Start()); - - GURL configured_url = test_server.GetURL("files/downloadable.pac"); - - FetcherClient client; - scoped_refptr<URLRequestContext> url_request_context( - new TestURLRequestContext()); - client.fetcher_.reset( - new MockDhcpRealFetchProxyScriptAdapterFetcher( - url_request_context.get())); - client.fetcher_->configured_url_ = configured_url.spec(); - client.RunTest(); - client.WaitForResult(OK); - ASSERT_TRUE(client.fetcher_->DidFinish()); - EXPECT_EQ(OK, client.fetcher_->GetResult()); - EXPECT_EQ(string16(L"-downloadable.pac-\n"), client.fetcher_->GetPacScript()); - EXPECT_EQ(configured_url, - client.fetcher_->GetPacURL()); -} - -} // namespace - -} // namespace net diff --git a/net/proxy/dhcp_proxy_script_fetcher.cc b/net/proxy/dhcp_proxy_script_fetcher.cc deleted file mode 100644 index 3797ecd..0000000 --- a/net/proxy/dhcp_proxy_script_fetcher.cc +++ /dev/null @@ -1,39 +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.h" - -#include "net/base/net_errors.h" - -namespace net { - -DhcpProxyScriptFetcher::DhcpProxyScriptFetcher() { -} - -DhcpProxyScriptFetcher::~DhcpProxyScriptFetcher() { -} - -std::string DhcpProxyScriptFetcher::GetFetcherName() const { - return ""; -} - -DoNothingDhcpProxyScriptFetcher::DoNothingDhcpProxyScriptFetcher() { -} - -DoNothingDhcpProxyScriptFetcher::~DoNothingDhcpProxyScriptFetcher() { -} - -int DoNothingDhcpProxyScriptFetcher::Fetch(string16* utf16_text, - CompletionCallback* callback) { - return ERR_NOT_IMPLEMENTED; -} - -void DoNothingDhcpProxyScriptFetcher::Cancel() { -} - -const GURL& DoNothingDhcpProxyScriptFetcher::GetPacURL() const { - return gurl_; -} - -} // namespace net diff --git a/net/proxy/dhcp_proxy_script_fetcher.h b/net/proxy/dhcp_proxy_script_fetcher.h deleted file mode 100644 index adb011d..0000000 --- a/net/proxy/dhcp_proxy_script_fetcher.h +++ /dev/null @@ -1,98 +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. - -#ifndef NET_PROXY_DHCP_SCRIPT_FETCHER_H_ -#define NET_PROXY_DHCP_SCRIPT_FETCHER_H_ -#pragma once - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/string16.h" -#include "net/base/completion_callback.h" -#include "net/proxy/proxy_script_fetcher.h" -#include "net/url_request/url_request_context.h" - -namespace net { - -// Interface for classes that can fetch a proxy script as configured via DHCP. -// -// The Fetch method on this interface tries to retrieve the most appropriate -// PAC script configured via DHCP. -// -// Normally there are zero or one DHCP scripts configured, but in the -// presence of multiple adapters with DHCP enabled, the fetcher resolves -// which PAC script to use if one or more are available. -class DhcpProxyScriptFetcher { - public: - // Destruction should cancel any outstanding requests. - virtual ~DhcpProxyScriptFetcher(); - - // Attempts to retrieve the most appropriate PAC script configured via DHCP, - // and invokes |callback| on completion. - // - // Returns OK on success, otherwise the error code. If the return code is - // ERR_IO_PENDING, then the request completes asynchronously, and |callback| - // will be invoked later with the final error code. - // - // After synchronous or asynchronous completion with a result code of OK, - // |*utf16_text| is filled with the response. On failure, the result text is - // an empty string, and the result code is a network error. Some special - // network errors that may occur are: - // - // ERR_PAC_NOT_IN_DHCP -- no script configured in DHCP. - // - // The following all indicate there was one or more script configured - // in DHCP but all failed to download, and the error for the most - // preferred adapter that had a script configured was what the error - // code says: - // - // ERR_TIMED_OUT -- fetch took too long to complete. - // ERR_FILE_TOO_BIG -- response body was too large. - // ERR_PAC_STATUS_NOT_OK -- script failed to download. - // ERR_NOT_IMPLEMENTED -- script required authentication. - // - // If the request is cancelled (either using the "Cancel()" method or by - // deleting |this|), then no callback is invoked. - // - // Only one fetch is allowed to be outstanding at a time. - virtual int Fetch(string16* utf16_text, - CompletionCallback* callback) = 0; - - // Aborts the in-progress fetch (if any). - virtual void Cancel() = 0; - - // After successful completion of |Fetch()|, this will return the URL - // retrieved from DHCP. It is reset if/when |Fetch()| is called again. - virtual const GURL& GetPacURL() const = 0; - - // Intended for unit tests only, so they can test that factories return - // the right types under given circumstances. - virtual std::string GetFetcherName() const; - - protected: - DhcpProxyScriptFetcher(); - - private: - DISALLOW_COPY_AND_ASSIGN(DhcpProxyScriptFetcher); -}; - -// A do-nothing retriever, always returns synchronously with -// ERR_NOT_IMPLEMENTED result and empty text. -class DoNothingDhcpProxyScriptFetcher : public DhcpProxyScriptFetcher { - public: - DoNothingDhcpProxyScriptFetcher(); - virtual ~DoNothingDhcpProxyScriptFetcher(); - - virtual int Fetch(string16* utf16_text, - CompletionCallback* callback) OVERRIDE; - virtual void Cancel() OVERRIDE; - virtual const GURL& GetPacURL() const OVERRIDE; - private: - GURL gurl_; - DISALLOW_COPY_AND_ASSIGN(DoNothingDhcpProxyScriptFetcher); -}; - -} // namespace net - -#endif // NET_PROXY_DHCP_SCRIPT_FETCHER_H_ diff --git a/net/proxy/dhcp_proxy_script_fetcher_factory.cc b/net/proxy/dhcp_proxy_script_fetcher_factory.cc deleted file mode 100644 index dfdf58e3..0000000 --- a/net/proxy/dhcp_proxy_script_fetcher_factory.cc +++ /dev/null @@ -1,56 +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_factory.h" - -#include "net/base/net_errors.h" -#include "net/proxy/dhcp_proxy_script_fetcher.h" - -#if defined(OS_WIN) -#include "net/proxy/dhcp_proxy_script_fetcher_win.h" -#endif - -namespace net { - -DhcpProxyScriptFetcherFactory::DhcpProxyScriptFetcherFactory() { - // TODO(joi): Change this default, and the comment on |set_enabled()|, - // when the time is right. - set_enabled(false); -} - -DhcpProxyScriptFetcher* DhcpProxyScriptFetcherFactory::Create( - URLRequestContext* context) { - if (!feature_enabled_) { - return new DoNothingDhcpProxyScriptFetcher(); - } else { - DCHECK(IsSupported()); - DhcpProxyScriptFetcher* ret = NULL; -#if defined(OS_WIN) - ret = new DhcpProxyScriptFetcherWin(context); -#endif - DCHECK(ret); - return ret; - } -} - -void DhcpProxyScriptFetcherFactory::set_enabled(bool enabled) { - if (IsSupported()) { - feature_enabled_ = enabled; - } -} - -bool DhcpProxyScriptFetcherFactory::enabled() const { - return feature_enabled_; -} - -// static -bool DhcpProxyScriptFetcherFactory::IsSupported() { -#if defined(OS_WIN) - return true; -#else - return false; -#endif -} - -} // namespace net diff --git a/net/proxy/dhcp_proxy_script_fetcher_factory.h b/net/proxy/dhcp_proxy_script_fetcher_factory.h deleted file mode 100644 index 20e4104..0000000 --- a/net/proxy/dhcp_proxy_script_fetcher_factory.h +++ /dev/null @@ -1,68 +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. - -#ifndef NET_PROXY_DHCP_SCRIPT_FETCHER_FACTORY_H_ -#define NET_PROXY_DHCP_SCRIPT_FETCHER_FACTORY_H_ -#pragma once - -#include "base/basictypes.h" -#include "base/memory/singleton.h" -#include "net/base/completion_callback.h" -#include "net/url_request/url_request_context.h" - -namespace net { - -class DhcpProxyScriptFetcher; - -// Factory object for creating the appropriate concrete base class of -// DhcpProxyScriptFetcher for your operating system and settings. -// -// You might think we could just implement a DHCP client at the protocol -// level and have cross-platform support for retrieving PAC configuration -// from DHCP, but unfortunately the DHCP protocol assumes there is a single -// client per machine (specifically per network interface card), and there -// is an implicit state machine between the client and server, so adding a -// second client to the machine would not be advisable (see e.g. some -// discussion of what can happen at this URL: -// http://www.net.princeton.edu/multi-dhcp-one-interface-handling.html). -// -// Therefore, we have platform-specific implementations, and so we use -// this factory to select the right one. -class DhcpProxyScriptFetcherFactory { - public: - // Creates a new factory object with default settings. - DhcpProxyScriptFetcherFactory(); - - // Ownership is transferred to the caller. url_request_context must be valid - // and its lifetime must exceed that of the returned DhcpProxyScriptFetcher. - // - // Note that while a request is in progress, the fetcher may be holding a - // reference to |url_request_context|. Be careful not to create cycles - // between the fetcher and the context; you can break such cycles by calling - // Cancel(). - DhcpProxyScriptFetcher* Create(URLRequestContext* url_request_context); - - // Attempts to enable/disable the DHCP WPAD feature. Does nothing - // if |IsSupported()| returns false. - // - // The current default is |enabled() == false|. - void set_enabled(bool enabled); - - // Returns true if the DHCP WPAD feature is enabled. Always returns - // false if |IsSupported()| is false. - bool enabled() const; - - // Returns true if the DHCP WPAD feature is supported on the current - // operating system. - static bool IsSupported(); - - protected: - bool feature_enabled_; - - DISALLOW_COPY_AND_ASSIGN(DhcpProxyScriptFetcherFactory); -}; - -} // namespace net - -#endif // NET_PROXY_DHCP_SCRIPT_FETCHER_FACTORY_H_ 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 diff --git a/net/proxy/dhcp_proxy_script_fetcher_win.h b/net/proxy/dhcp_proxy_script_fetcher_win.h deleted file mode 100644 index 3783971..0000000 --- a/net/proxy/dhcp_proxy_script_fetcher_win.h +++ /dev/null @@ -1,123 +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. - -#ifndef NET_PROXY_DHCP_PROXY_SCRIPT_FETCHER_WIN_H_ -#define NET_PROXY_DHCP_PROXY_SCRIPT_FETCHER_WIN_H_ -#pragma once - -#include <set> -#include <string> - -#include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" -#include "base/threading/non_thread_safe.h" -#include "base/timer.h" -#include "net/proxy/dhcp_proxy_script_fetcher.h" - -namespace net { - -class DhcpProxyScriptAdapterFetcher; -class URLRequestContext; - -// Windows-specific implementation. -class DhcpProxyScriptFetcherWin - : public DhcpProxyScriptFetcher, - public base::NonThreadSafe { - public: - // Creates a DhcpProxyScriptFetcherWin that issues requests through - // |url_request_context|. |url_request_context| must remain valid for - // the lifetime of DhcpProxyScriptFetcherWin. - explicit DhcpProxyScriptFetcherWin(URLRequestContext* url_request_context); - virtual ~DhcpProxyScriptFetcherWin(); - - // DhcpProxyScriptFetcher implementation. - int Fetch(string16* utf16_text, CompletionCallback* callback) OVERRIDE; - void Cancel() OVERRIDE; - const GURL& GetPacURL() const OVERRIDE; - std::string GetFetcherName() const OVERRIDE; - - // Sets |adapter_names| to contain the name of each network adapter on - // this machine that has DHCP enabled and is not a loop-back adapter. Returns - // false on error. - static bool GetCandidateAdapterNames(std::set<std::string>* adapter_names); - - protected: - // Event/state transition handlers - void OnFetcherDone(int result); - void OnWaitTimer(); - void TransitionToDone(); - - // Virtual methods introduced to allow unit testing. - virtual DhcpProxyScriptAdapterFetcher* ImplCreateAdapterFetcher(); - virtual bool ImplGetCandidateAdapterNames( - std::set<std::string>* adapter_names); - virtual int ImplGetMaxWaitMs(); - - // This is the outer state machine for fetching PAC configuration from - // DHCP. It relies for sub-states on the state machine of the - // DhcpProxyScriptAdapterFetcher class. - // - // The goal of the implementation is to the following work in parallel - // for all network adapters that are using DHCP: - // a) Try to get the PAC URL configured in DHCP; - // b) If one is configured, try to fetch the PAC URL. - // c) Once this is done for all adapters, or a timeout has passed after - // it has completed for the fastest adapter, return the PAC file - // available for the most preferred network adapter, if any. - // - // The state machine goes from START->NO_RESULTS when it creates - // and starts an DhcpProxyScriptAdapterFetcher for each adapter. It goes - // from NO_RESULTS->SOME_RESULTS when it gets the first result; at this - // point a wait timer is started. It goes from SOME_RESULTS->DONE in - // two cases: All results are known, or the wait timer expired. A call - // to Cancel() will also go straight to DONE from any state. Any - // way the DONE state is entered, we will at that point cancel any - // outstanding work and return the best known PAC script or the empty - // string. - // - // The state machine is reset for each Fetch(), a call to which is - // only valid in states START and DONE, as only one Fetch() is - // allowed to be outstanding at any given time. - enum State { - STATE_START, - STATE_NO_RESULTS, - STATE_SOME_RESULTS, - STATE_DONE, - }; - - // Current state of this state machine. - State state_; - - // Vector, in Windows' network adapter preference order, of - // DhcpProxyScriptAdapterFetcher objects that are or were attempting - // to fetch a PAC file based on DHCP configuration. - typedef ScopedVector<DhcpProxyScriptAdapterFetcher> FetcherVector; - FetcherVector fetchers_; - - // Callback invoked when any fetcher completes. - CompletionCallbackImpl<DhcpProxyScriptFetcherWin> fetcher_callback_; - - // Number of fetchers we are waiting for. - int num_pending_fetchers_; - - // Lets our client know we're done. Not valid in states START or DONE. - CompletionCallback* client_callback_; - - // Pointer to string we will write results to. Not valid in states - // START and DONE. - string16* destination_string_; - - // PAC URL retrieved from DHCP, if any. Valid only in state STATE_DONE. - GURL pac_url_; - - base::OneShotTimer<DhcpProxyScriptFetcherWin> wait_timer_; - - scoped_refptr<URLRequestContext> url_request_context_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(DhcpProxyScriptFetcherWin); -}; - -} // namespace net - -#endif // NET_PROXY_DHCP_PROXY_SCRIPT_FETCHER_WIN_H_ diff --git a/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc b/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc deleted file mode 100644 index 596e298..0000000 --- a/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc +++ /dev/null @@ -1,545 +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 <vector> - -#include "base/message_loop.h" -#include "base/perftimer.h" -#include "base/rand_util.h" -#include "base/threading/platform_thread.h" -#include "net/base/completion_callback.h" -#include "net/proxy/dhcp_proxy_script_adapter_fetcher_win.h" -#include "net/url_request/url_request_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -namespace { - -TEST(DhcpProxyScriptFetcherWin, AdapterNamesAndPacURLFromDhcp) { - // This tests our core Win32 implementation without any of the wrappers - // we layer on top to achieve asynchronous and parallel operations. - // - // We don't make assumptions about the environment this unit test is - // running in, so it just exercises the code to make sure there - // is no crash and no error returned, but does not assert on the number - // of interfaces or the information returned via DHCP. - std::set<std::string> adapter_names; - DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(&adapter_names); - for (std::set<std::string>::const_iterator it = adapter_names.begin(); - it != adapter_names.end(); - ++it) { - const std::string& adapter_name = *it; - std::string pac_url = - DhcpProxyScriptAdapterFetcher::GetPacURLFromDhcp(adapter_name); - printf("Adapter '%s' has PAC URL '%s' configured in DHCP.\n", - adapter_name.c_str(), - pac_url.c_str()); - } -} - -// Helper for RealFetch* tests below. -class RealFetchTester { - public: - RealFetchTester() - : context_((new TestURLRequestContext())), - fetcher_(new DhcpProxyScriptFetcherWin(context_.get())), - finished_(false), - ALLOW_THIS_IN_INITIALIZER_LIST( - completion_callback_(this, &RealFetchTester::OnCompletion)), - on_completion_is_error_(false) { - // Make sure the test ends. - timeout_.Start( - base::TimeDelta::FromSeconds(5), this, &RealFetchTester::OnTimeout); - } - - void RunTest() { - fetcher_->Fetch(&pac_text_, &completion_callback_); - } - - void RunTestWithCancel() { - RunTest(); - fetcher_->Cancel(); - } - - void RunTestWithDeferredCancel() { - RunTest(); - cancel_timer_.Start(base::TimeDelta::FromMilliseconds(1), - this, &RealFetchTester::OnCancelTimer); - } - - void OnCompletion(int result) { - if (on_completion_is_error_) { - FAIL() << "Received completion for test in which this is error."; - } - finished_ = true; - printf("Result code %d PAC data length %d\n", result, pac_text_.size()); - } - - void OnTimeout() { - printf("Timeout!"); - OnCompletion(0); - } - - void OnCancelTimer() { - fetcher_->Cancel(); - finished_ = true; - } - - void WaitUntilDone() { - while (!finished_) { - MessageLoop::current()->RunAllPending(); - } - MessageLoop::current()->RunAllPending(); - } - - // Attempts to give worker threads time to finish. This is currently - // very simplistic as completion (via completion callback or cancellation) - // immediately "detaches" any worker threads, so the best we can do is give - // them a little time. If we start running into Valgrind leaks, we can - // do something a bit more clever to track worker threads even when the - // DhcpProxyScriptFetcherWin state machine has finished. - void FinishTestAllowCleanup() { - base::PlatformThread::Sleep(30); - } - - scoped_refptr<URLRequestContext> context_; - scoped_ptr<DhcpProxyScriptFetcherWin> fetcher_; - bool finished_; - string16 pac_text_; - CompletionCallbackImpl<RealFetchTester> completion_callback_; - base::OneShotTimer<RealFetchTester> timeout_; - base::OneShotTimer<RealFetchTester> cancel_timer_; - bool on_completion_is_error_; -}; - -TEST(DhcpProxyScriptFetcherWin, RealFetch) { - // This tests a call to Fetch() with no stubbing out of dependencies. - // - // We don't make assumptions about the environment this unit test is - // running in, so it just exercises the code to make sure there - // is no crash and no unexpected error returned, but does not assert on - // results beyond that. - RealFetchTester fetcher; - fetcher.RunTest(); - - fetcher.WaitUntilDone(); - printf("PAC URL was %s\n", - fetcher.fetcher_->GetPacURL().possibly_invalid_spec().c_str()); - - fetcher.FinishTestAllowCleanup(); -} - -TEST(DhcpProxyScriptFetcherWin, RealFetchWithCancel) { - // Does a Fetch() with an immediate cancel. As before, just - // exercises the code without stubbing out dependencies. - RealFetchTester fetcher; - fetcher.RunTestWithCancel(); - MessageLoop::current()->RunAllPending(); - - // Attempt to avoid Valgrind leak reports in case worker thread is - // still running. - fetcher.FinishTestAllowCleanup(); -} - -// For RealFetchWithDeferredCancel, below. -class DelayingDhcpProxyScriptAdapterFetcher - : public DhcpProxyScriptAdapterFetcher { - public: - explicit DelayingDhcpProxyScriptAdapterFetcher( - URLRequestContext* url_request_context) - : DhcpProxyScriptAdapterFetcher(url_request_context) { - } - - class DelayingWorkerThread : public WorkerThread { - public: - explicit DelayingWorkerThread( - const base::WeakPtr<DhcpProxyScriptAdapterFetcher>& owner) - : WorkerThread(owner) { - } - - std::string ImplGetPacURLFromDhcp( - const std::string& adapter_name) OVERRIDE { - base::PlatformThread::Sleep(20); - return WorkerThread::ImplGetPacURLFromDhcp(adapter_name); - } - }; - - WorkerThread* ImplCreateWorkerThread( - const base::WeakPtr<DhcpProxyScriptAdapterFetcher>& owner) OVERRIDE { - return new DelayingWorkerThread(owner); - } -}; - -// For RealFetchWithDeferredCancel, below. -class DelayingDhcpProxyScriptFetcherWin - : public DhcpProxyScriptFetcherWin { - public: - explicit DelayingDhcpProxyScriptFetcherWin( - URLRequestContext* context) - : DhcpProxyScriptFetcherWin(context) { - } - - DhcpProxyScriptAdapterFetcher* ImplCreateAdapterFetcher() OVERRIDE { - return new DelayingDhcpProxyScriptAdapterFetcher(url_request_context_); - } -}; - -TEST(DhcpProxyScriptFetcherWin, RealFetchWithDeferredCancel) { - // Does a Fetch() with a slightly delayed cancel. As before, just - // exercises the code without stubbing out dependencies, but - // introduces a guaranteed 20 ms delay on the worker threads so that - // the cancel is called before they complete. - RealFetchTester fetcher; - fetcher.fetcher_.reset( - new DelayingDhcpProxyScriptFetcherWin(fetcher.context_)); - fetcher.on_completion_is_error_ = true; - fetcher.RunTestWithDeferredCancel(); - fetcher.WaitUntilDone(); -} - -// The remaining tests are to exercise our state machine in various -// situations, with actual network access fully stubbed out. - -class DummyDhcpProxyScriptAdapterFetcher - : public DhcpProxyScriptAdapterFetcher { - public: - DummyDhcpProxyScriptAdapterFetcher() - : DhcpProxyScriptAdapterFetcher(new TestURLRequestContext()), - did_finish_(false), - result_(OK), - pac_script_(L"bingo"), - fetch_delay_ms_(1), - client_callback_(NULL) { - } - - void Fetch(const std::string& adapter_name, - CompletionCallback* callback) OVERRIDE { - client_callback_ = callback; - timer_.Start(base::TimeDelta::FromMilliseconds(fetch_delay_ms_), - this, &DummyDhcpProxyScriptAdapterFetcher::OnTimer); - } - - void Cancel() OVERRIDE { - timer_.Stop(); - } - - bool DidFinish() const OVERRIDE { - return did_finish_; - } - - int GetResult() const OVERRIDE { - return result_; - } - - string16 GetPacScript() const OVERRIDE { - return pac_script_; - } - - void OnTimer() { - client_callback_->Run(result_); - } - - void Configure( - bool did_finish, int result, string16 pac_script, int fetch_delay_ms) { - did_finish_ = did_finish; - result_ = result; - pac_script_ = pac_script; - fetch_delay_ms_ = fetch_delay_ms; - } - - private: - bool did_finish_; - int result_; - string16 pac_script_; - int fetch_delay_ms_; - CompletionCallback* client_callback_; - base::OneShotTimer<DummyDhcpProxyScriptAdapterFetcher> timer_; -}; - -class MockDhcpProxyScriptFetcherWin : public DhcpProxyScriptFetcherWin { - public: - MockDhcpProxyScriptFetcherWin() - : DhcpProxyScriptFetcherWin(new TestURLRequestContext()), - next_adapter_fetcher_index_(0) { - } - - // Adds a fetcher object to the queue of fetchers used by - // |ImplCreateAdapterFetcher()|, and its name to the list of adapters - // returned by ImplGetCandidateAdapterNames. - void PushBackAdapter(const std::string& adapter_name, - DhcpProxyScriptAdapterFetcher* fetcher) { - adapter_names_.push_back(adapter_name); - adapter_fetchers_.push_back(fetcher); - } - - void ConfigureAndPushBackAdapter(const std::string& adapter_name, - bool did_finish, - int result, - string16 pac_script, - int fetch_delay_ms) { - scoped_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher( - new DummyDhcpProxyScriptAdapterFetcher()); - adapter_fetcher->Configure(did_finish, result, pac_script, fetch_delay_ms); - PushBackAdapter(adapter_name, adapter_fetcher.release()); - } - - DhcpProxyScriptAdapterFetcher* ImplCreateAdapterFetcher() OVERRIDE { - return adapter_fetchers_[next_adapter_fetcher_index_++]; - } - - bool ImplGetCandidateAdapterNames( - std::set<std::string>* adapter_names) OVERRIDE { - adapter_names->insert(adapter_names_.begin(), adapter_names_.end()); - return true; - } - - int ImplGetMaxWaitMs() OVERRIDE { - return 25; - } - - void ResetTestState() { - next_adapter_fetcher_index_ = 0; - adapter_fetchers_.clear(); - // String pointers contained herein will have been freed during test. - adapter_names_.clear(); - } - - int next_adapter_fetcher_index_; - - // Ownership is not here; it gets transferred to the implementation - // class via ImplCreateAdapterFetcher. - std::vector<DhcpProxyScriptAdapterFetcher*> adapter_fetchers_; - - std::vector<std::string> adapter_names_; -}; - -class FetcherClient { -public: - FetcherClient() - : finished_(false), - result_(ERR_UNEXPECTED), - ALLOW_THIS_IN_INITIALIZER_LIST( - completion_callback_(this, &FetcherClient::OnCompletion)) { - } - - void RunTest() { - int result = fetcher_.Fetch(&pac_text_, &completion_callback_); - ASSERT_EQ(ERR_IO_PENDING, result); - } - - void RunImmediateReturnTest() { - int result = fetcher_.Fetch(&pac_text_, &completion_callback_); - ASSERT_EQ(ERR_PAC_NOT_IN_DHCP, result); - } - - void RunMessageLoopUntilComplete() { - while (!finished_) { - MessageLoop::current()->RunAllPending(); - } - MessageLoop::current()->RunAllPending(); - } - - void OnCompletion(int result) { - finished_ = true; - result_ = result; - } - - void ResetTestState() { - finished_ = false; - result_ = ERR_UNEXPECTED; - pac_text_ = L""; - fetcher_.ResetTestState(); - } - - MockDhcpProxyScriptFetcherWin fetcher_; - bool finished_; - int result_; - string16 pac_text_; - CompletionCallbackImpl<FetcherClient> completion_callback_; -}; - -// We separate out each test's logic so that we can easily implement -// the ReuseFetcher test at the bottom. -void TestNormalCaseURLConfiguredOneAdapter(FetcherClient* client) { - scoped_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher( - new DummyDhcpProxyScriptAdapterFetcher()); - adapter_fetcher->Configure(true, OK, L"bingo", 1); - client->fetcher_.PushBackAdapter("a", adapter_fetcher.release()); - client->RunTest(); - client->RunMessageLoopUntilComplete(); - ASSERT_EQ(OK, client->result_); - ASSERT_EQ(L"bingo", client->pac_text_); -} - -TEST(DhcpProxyScriptFetcherWin, NormalCaseURLConfiguredOneAdapter) { - FetcherClient client; - TestNormalCaseURLConfiguredOneAdapter(&client); -} - -void TestNormalCaseURLConfiguredMultipleAdapters(FetcherClient* client) { - client->fetcher_.ConfigureAndPushBackAdapter( - "most_preferred", true, ERR_PAC_NOT_IN_DHCP, L"", 1); - client->fetcher_.ConfigureAndPushBackAdapter( - "second", true, OK, L"bingo", 50); - client->fetcher_.ConfigureAndPushBackAdapter( - "third", true, OK, L"rocko", 1); - client->RunTest(); - client->RunMessageLoopUntilComplete(); - ASSERT_EQ(OK, client->result_); - ASSERT_EQ(L"bingo", client->pac_text_); -} - -TEST(DhcpProxyScriptFetcherWin, NormalCaseURLConfiguredMultipleAdapters) { - FetcherClient client; - TestNormalCaseURLConfiguredMultipleAdapters(&client); -} - -void TestNormalCaseURLConfiguredMultipleAdaptersWithTimeout( - FetcherClient* client) { - client->fetcher_.ConfigureAndPushBackAdapter( - "most_preferred", true, ERR_PAC_NOT_IN_DHCP, L"", 1); - // This will time out. - client->fetcher_.ConfigureAndPushBackAdapter( - "second", false, ERR_IO_PENDING, L"bingo", 1000); - client->fetcher_.ConfigureAndPushBackAdapter( - "third", true, OK, L"rocko", 1); - client->RunTest(); - client->RunMessageLoopUntilComplete(); - ASSERT_EQ(OK, client->result_); - ASSERT_EQ(L"rocko", client->pac_text_); -} - -TEST(DhcpProxyScriptFetcherWin, - NormalCaseURLConfiguredMultipleAdaptersWithTimeout) { - FetcherClient client; - TestNormalCaseURLConfiguredMultipleAdaptersWithTimeout(&client); -} - -void TestFailureCaseURLConfiguredMultipleAdaptersWithTimeout( - FetcherClient* client) { - client->fetcher_.ConfigureAndPushBackAdapter( - "most_preferred", true, ERR_PAC_NOT_IN_DHCP, L"", 1); - // This will time out. - client->fetcher_.ConfigureAndPushBackAdapter( - "second", false, ERR_IO_PENDING, L"bingo", 1000); - // This is the first non-ERR_PAC_NOT_IN_DHCP error and as such - // should be chosen. - client->fetcher_.ConfigureAndPushBackAdapter( - "third", true, ERR_PAC_STATUS_NOT_OK, L"", 1); - client->fetcher_.ConfigureAndPushBackAdapter( - "fourth", true, ERR_NOT_IMPLEMENTED, L"", 1); - client->RunTest(); - client->RunMessageLoopUntilComplete(); - ASSERT_EQ(ERR_PAC_STATUS_NOT_OK, client->result_); - ASSERT_EQ(L"", client->pac_text_); -} - -TEST(DhcpProxyScriptFetcherWin, - FailureCaseURLConfiguredMultipleAdaptersWithTimeout) { - FetcherClient client; - TestFailureCaseURLConfiguredMultipleAdaptersWithTimeout(&client); -} - -void TestFailureCaseNoURLConfigured(FetcherClient* client) { - client->fetcher_.ConfigureAndPushBackAdapter( - "most_preferred", true, ERR_PAC_NOT_IN_DHCP, L"", 1); - // This will time out. - client->fetcher_.ConfigureAndPushBackAdapter( - "second", false, ERR_IO_PENDING, L"bingo", 1000); - // This is the first non-ERR_PAC_NOT_IN_DHCP error and as such - // should be chosen. - client->fetcher_.ConfigureAndPushBackAdapter( - "third", true, ERR_PAC_NOT_IN_DHCP, L"", 1); - client->RunTest(); - client->RunMessageLoopUntilComplete(); - ASSERT_EQ(ERR_PAC_NOT_IN_DHCP, client->result_); - ASSERT_EQ(L"", client->pac_text_); -} - -TEST(DhcpProxyScriptFetcherWin, FailureCaseNoURLConfigured) { - FetcherClient client; - TestFailureCaseNoURLConfigured(&client); -} - -void TestFailureCaseNoDhcpAdapters(FetcherClient* client) { - client->RunImmediateReturnTest(); - // In case there are any pending messages that get us in a bad state - // (there shouldn't be). - MessageLoop::current()->RunAllPending(); -} - -TEST(DhcpProxyScriptFetcherWin, FailureCaseNoDhcpAdapters) { - FetcherClient client; - TestFailureCaseNoDhcpAdapters(&client); -} - -void TestShortCircuitLessPreferredAdapters(FetcherClient* client) { - // Here we have a bunch of adapters; the first reports no PAC in DHCP, - // the second responds quickly with a PAC file, the rest take a long - // time. Verify that we complete quickly and do not wait for the slow - // adapters, i.e. we finish before timeout. - client->fetcher_.ConfigureAndPushBackAdapter( - "1", true, ERR_PAC_NOT_IN_DHCP, L"", 1); - client->fetcher_.ConfigureAndPushBackAdapter( - "2", true, OK, L"bingo", 1); - client->fetcher_.ConfigureAndPushBackAdapter( - "3", true, OK, L"wrongo", 1000); - - PerfTimer timer; - client->RunTest(); - client->RunMessageLoopUntilComplete(); - // Assert that the time passed is just less than the wait timer - // timeout (which we have mocked out above to be 25 ms), to avoid - // flakiness but still get a strong signal that it was the shortcut - // mechanism (in OnFetcherDone) that kicked in. - ASSERT_GT(TimeDelta::FromMilliseconds(23), timer.Elapsed()); -} - -TEST(DhcpProxyScriptFetcherWin, ShortCircuitLessPreferredAdapters) { - FetcherClient client; - TestShortCircuitLessPreferredAdapters(&client); -} - -TEST(DhcpProxyScriptFetcherWin, ReuseFetcher) { - FetcherClient client; - - // The ProxyScriptFetcher interface stipulates that only a single - // |Fetch()| may be in flight at once, but allows reuse, so test - // that the state transitions correctly from done to start in all - // cases we're testing. - - typedef void (*FetcherClientTestFunction)(FetcherClient*); - typedef std::vector<FetcherClientTestFunction> TestVector; - TestVector test_functions; - test_functions.push_back(TestNormalCaseURLConfiguredOneAdapter); - test_functions.push_back(TestNormalCaseURLConfiguredMultipleAdapters); - test_functions.push_back( - TestNormalCaseURLConfiguredMultipleAdaptersWithTimeout); - test_functions.push_back( - TestFailureCaseURLConfiguredMultipleAdaptersWithTimeout); - test_functions.push_back(TestFailureCaseNoURLConfigured); - test_functions.push_back(TestFailureCaseNoDhcpAdapters); - test_functions.push_back(TestShortCircuitLessPreferredAdapters); - - std::random_shuffle(test_functions.begin(), - test_functions.end(), - base::RandGenerator); - for (TestVector::const_iterator it = test_functions.begin(); - it != test_functions.end(); - ++it) { - (*it)(&client); - client.ResetTestState(); - } - - // Re-do the first test to make sure the last test that was run did - // not leave things in a bad state. - (*test_functions.begin())(&client); -} - -} // namespace - -} // namespace net diff --git a/net/proxy/dhcpcsvc_init_win.cc b/net/proxy/dhcpcsvc_init_win.cc deleted file mode 100644 index 3a0aa02..0000000 --- a/net/proxy/dhcpcsvc_init_win.cc +++ /dev/null @@ -1,40 +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/dhcpcsvc_init_win.h" - -#include "base/lazy_instance.h" -#include "base/logging.h" - -#include <dhcpcsdk.h> -#include <dhcpv6csdk.h> - -namespace { - -class DhcpcsvcInitSingleton { - public: - DhcpcsvcInitSingleton() { - DWORD version = 0; - DWORD err = DhcpCApiInitialize(&version); - DCHECK(err == ERROR_SUCCESS); // DCHECK_EQ complains of unsigned mismatch. - } - - ~DhcpcsvcInitSingleton() { - // Worker pool threads that use the DHCP API may still be running, so skip - // cleanup. - } -}; - -static base::LazyInstance<DhcpcsvcInitSingleton> g_dhcpcsvc_init_singleton( - base::LINKER_INITIALIZED); - -} // namespace - -namespace net { - -void EnsureDhcpcsvcInit() { - g_dhcpcsvc_init_singleton.Get(); -} - -} // namespace net diff --git a/net/proxy/dhcpcsvc_init_win.h b/net/proxy/dhcpcsvc_init_win.h deleted file mode 100644 index 9c557d0..0000000 --- a/net/proxy/dhcpcsvc_init_win.h +++ /dev/null @@ -1,20 +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. -#ifndef NET_PROXY_DHCPCSVC_INIT_WIN_H -#define NET_PROXY_DHCPCSVC_INIT_WIN_H -#pragma once - -namespace net { - -// Initialization of the Dhcpcsvc library must happen before any of its -// calls are made. This function will make sure that the appropriate -// initialization has been done, and that uninitialization is also -// performed at static uninitialization time. -// -// Note: This initializes only for DHCP, not DHCPv6. -void EnsureDhcpcsvcInit(); - -} // namespace net - -#endif // NET_PROXY_DHCPCSVC_INIT_WIN_H diff --git a/net/proxy/init_proxy_resolver.cc b/net/proxy/init_proxy_resolver.cc index 52c5421..d9d55ea 100644 --- a/net/proxy/init_proxy_resolver.cc +++ b/net/proxy/init_proxy_resolver.cc @@ -10,8 +10,6 @@ #include "base/string_util.h" #include "net/base/net_log.h" #include "net/base/net_errors.h" -#include "net/proxy/dhcp_proxy_script_fetcher.h" -#include "net/proxy/dhcp_proxy_script_fetcher_factory.h" #include "net/proxy/proxy_config.h" #include "net/proxy/proxy_resolver.h" #include "net/proxy/proxy_script_fetcher.h" @@ -32,18 +30,15 @@ namespace net { // http://code.google.com/p/chromium/issues/detail?id=18575#c20 static const char kWpadUrl[] = "http://wpad/wpad.dat"; -InitProxyResolver::InitProxyResolver( - ProxyResolver* resolver, - ProxyScriptFetcher* proxy_script_fetcher, - DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher, - NetLog* net_log) +InitProxyResolver::InitProxyResolver(ProxyResolver* resolver, + ProxyScriptFetcher* proxy_script_fetcher, + NetLog* net_log) : resolver_(resolver), proxy_script_fetcher_(proxy_script_fetcher), - dhcp_proxy_script_fetcher_(dhcp_proxy_script_fetcher), ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( this, &InitProxyResolver::OnIOCompletion)), user_callback_(NULL), - current_pac_source_index_(0u), + current_pac_url_index_(0u), pac_mandatory_(false), next_state_(STATE_NONE), net_log_(BoundNetLog::Make( @@ -75,8 +70,8 @@ int InitProxyResolver::Init(const ProxyConfig& config, pac_mandatory_ = config.pac_mandatory(); - pac_sources_ = BuildPacSourcesFallbackList(config); - DCHECK(!pac_sources_.empty()); + pac_urls_ = BuildPacUrlsFallbackList(config); + DCHECK(!pac_urls_.empty()); next_state_ = STATE_WAIT; @@ -90,19 +85,16 @@ int InitProxyResolver::Init(const ProxyConfig& config, } // Initialize the fallback rules. -// (1) WPAD (DHCP). -// (2) WPAD (DNS). -// (3) Custom PAC URL. -InitProxyResolver::PacSourceList InitProxyResolver::BuildPacSourcesFallbackList( +// (1) WPAD (DNS). +// (2) Custom PAC URL. +InitProxyResolver::UrlList InitProxyResolver::BuildPacUrlsFallbackList( const ProxyConfig& config) const { - PacSourceList pac_sources; - if (config.auto_detect()) { - pac_sources.push_back(PacSource(PacSource::WPAD_DHCP, GURL())); - pac_sources.push_back(PacSource(PacSource::WPAD_DNS, GURL())); - } + UrlList pac_urls; + if (config.auto_detect()) + pac_urls.push_back(PacURL(true, GURL())); if (config.has_pac_url()) - pac_sources.push_back(PacSource(PacSource::CUSTOM, config.pac_url())); - return pac_sources; + pac_urls.push_back(PacURL(false, config.pac_url())); + return pac_urls; } void InitProxyResolver::OnIOCompletion(int result) { @@ -185,32 +177,24 @@ int InitProxyResolver::DoFetchPacScript() { next_state_ = STATE_FETCH_PAC_SCRIPT_COMPLETE; - const PacSource& pac_source = current_pac_source(); + const PacURL& pac_url = current_pac_url(); - GURL effective_pac_url; - NetLogStringParameter* log_parameter = - CreateNetLogParameterAndDetermineURL(pac_source, &effective_pac_url); + const GURL effective_pac_url = + pac_url.auto_detect ? GURL(kWpadUrl) : pac_url.url; net_log_.BeginEvent( NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT, - make_scoped_refptr(log_parameter)); - - if (pac_source.type == PacSource::WPAD_DHCP) { - if (!dhcp_proxy_script_fetcher_) { - net_log_.AddEvent(NetLog::TYPE_INIT_PROXY_RESOLVER_HAS_NO_FETCHER, NULL); - return ERR_UNEXPECTED; - } - - return dhcp_proxy_script_fetcher_->Fetch(&pac_script_, &io_callback_); - } + make_scoped_refptr(new NetLogStringParameter( + "url", effective_pac_url.possibly_invalid_spec()))); if (!proxy_script_fetcher_) { net_log_.AddEvent(NetLog::TYPE_INIT_PROXY_RESOLVER_HAS_NO_FETCHER, NULL); return ERR_UNEXPECTED; } - return proxy_script_fetcher_->Fetch( - effective_pac_url, &pac_script_, &io_callback_); + return proxy_script_fetcher_->Fetch(effective_pac_url, + &pac_script_, + &io_callback_); } int InitProxyResolver::DoFetchPacScriptComplete(int result) { @@ -219,7 +203,7 @@ int InitProxyResolver::DoFetchPacScriptComplete(int result) { net_log_.EndEventWithNetErrorCode( NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT, result); if (result != OK) - return TryToFallbackPacSource(result); + return TryToFallbackPacUrl(result); next_state_ = STATE_SET_PAC_SCRIPT; return result; @@ -228,7 +212,7 @@ int InitProxyResolver::DoFetchPacScriptComplete(int result) { int InitProxyResolver::DoSetPacScript() { net_log_.BeginEvent(NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT, NULL); - const PacSource& pac_source = current_pac_source(); + const PacURL& pac_url = current_pac_url(); next_state_ = STATE_SET_PAC_SCRIPT_COMPLETE; @@ -237,9 +221,9 @@ int InitProxyResolver::DoSetPacScript() { if (resolver_->expects_pac_bytes()) { script_data = ProxyResolverScriptData::FromUTF16(pac_script_); } else { - script_data = pac_source.type == PacSource::CUSTOM ? - ProxyResolverScriptData::FromURL(pac_source.url) : - ProxyResolverScriptData::ForAutoDetect(); + script_data = pac_url.auto_detect ? + ProxyResolverScriptData::ForAutoDetect() : + ProxyResolverScriptData::FromURL(pac_url.url); } return resolver_->SetPacScript(script_data, &io_callback_); @@ -249,59 +233,39 @@ int InitProxyResolver::DoSetPacScriptComplete(int result) { net_log_.EndEventWithNetErrorCode( NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT, result); if (result != OK) - return TryToFallbackPacSource(result); + return TryToFallbackPacUrl(result); // Let the caller know which automatic setting we ended up initializing the // resolver for (there may have been multiple fallbacks to choose from.) if (effective_config_) { - if (current_pac_source().type == PacSource::CUSTOM) { + if (current_pac_url().auto_detect && resolver_->expects_pac_bytes()) { *effective_config_ = - ProxyConfig::CreateFromCustomPacURL(current_pac_source().url); - effective_config_->set_pac_mandatory(pac_mandatory_); + ProxyConfig::CreateFromCustomPacURL(GURL(kWpadUrl)); + } else if (current_pac_url().auto_detect) { + *effective_config_ = ProxyConfig::CreateAutoDetect(); } else { - if (resolver_->expects_pac_bytes()) { - GURL auto_detected_url; - - switch (current_pac_source().type) { - case PacSource::WPAD_DHCP: - auto_detected_url = dhcp_proxy_script_fetcher_->GetPacURL(); - break; - - case PacSource::WPAD_DNS: - auto_detected_url = GURL(kWpadUrl); - break; - - default: - NOTREACHED(); - } - - *effective_config_ = - ProxyConfig::CreateFromCustomPacURL(auto_detected_url); - } else { - // The resolver does its own resolution so we cannot know the - // URL. Just do the best we can and state that the configuration - // is to auto-detect proxy settings. - *effective_config_ = ProxyConfig::CreateAutoDetect(); - } + *effective_config_ = + ProxyConfig::CreateFromCustomPacURL(current_pac_url().url); + effective_config_->set_pac_mandatory(pac_mandatory_); } } return result; } -int InitProxyResolver::TryToFallbackPacSource(int error) { +int InitProxyResolver::TryToFallbackPacUrl(int error) { DCHECK_LT(error, 0); - if (current_pac_source_index_ + 1 >= pac_sources_.size()) { + 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_source_index_; + ++current_pac_url_index_; net_log_.AddEvent( - NetLog::TYPE_INIT_PROXY_RESOLVER_FALLING_BACK_TO_NEXT_PAC_SOURCE, NULL); + NetLog::TYPE_INIT_PROXY_RESOLVER_FALLING_BACK_TO_NEXT_PAC_URL, NULL); next_state_ = GetStartState(); @@ -313,34 +277,9 @@ InitProxyResolver::State InitProxyResolver::GetStartState() const { STATE_FETCH_PAC_SCRIPT : STATE_SET_PAC_SCRIPT; } -NetLogStringParameter* InitProxyResolver::CreateNetLogParameterAndDetermineURL( - const PacSource& pac_source, - GURL* effective_pac_url) { - DCHECK(effective_pac_url); - - std::string source_field; - switch (pac_source.type) { - case PacSource::WPAD_DHCP: - source_field = "WPAD DHCP"; - break; - case PacSource::WPAD_DNS: - *effective_pac_url = GURL(kWpadUrl); - source_field = "WPAD DNS: "; - source_field += effective_pac_url->possibly_invalid_spec(); - break; - case PacSource::CUSTOM: - *effective_pac_url = pac_source.url; - source_field = "Custom PAC URL: "; - source_field += effective_pac_url->possibly_invalid_spec(); - break; - } - return new NetLogStringParameter("source", source_field); -} - -const InitProxyResolver::PacSource& - InitProxyResolver::current_pac_source() const { - DCHECK_LT(current_pac_source_index_, pac_sources_.size()); - return pac_sources_[current_pac_source_index_]; +const InitProxyResolver::PacURL& InitProxyResolver::current_pac_url() const { + DCHECK_LT(current_pac_url_index_, pac_urls_.size()); + return pac_urls_[current_pac_url_index_]; } void InitProxyResolver::OnWaitTimerFired() { diff --git a/net/proxy/init_proxy_resolver.h b/net/proxy/init_proxy_resolver.h index ffb1b83..67cf1cb 100644 --- a/net/proxy/init_proxy_resolver.h +++ b/net/proxy/init_proxy_resolver.h @@ -11,19 +11,15 @@ #include "base/string16.h" #include "base/time.h" #include "base/timer.h" -#include "base/scoped_ptr.h" #include "googleurl/src/gurl.h" #include "net/base/completion_callback.h" #include "net/base/net_log.h" namespace net { -class DhcpProxyScriptFetcher; -class NetLogParameter; class ProxyConfig; class ProxyResolver; class ProxyScriptFetcher; -class URLRequestContext; // InitProxyResolver is a helper class used by ProxyService to // initialize a ProxyResolver with the PAC script data specified @@ -43,11 +39,10 @@ class URLRequestContext; // class InitProxyResolver { public: - // |resolver|, |proxy_script_fetcher|, |dhcp_proxy_script_fetcher| and - // |net_log| must remain valid for the lifespan of InitProxyResolver. + // |resolver|, |proxy_script_fetcher| and |net_log| must remain valid for + // the lifespan of InitProxyResolver. InitProxyResolver(ProxyResolver* resolver, ProxyScriptFetcher* proxy_script_fetcher, - DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher, NetLog* net_log); // Aborts any in-progress request. @@ -68,23 +63,14 @@ class InitProxyResolver { CompletionCallback* callback); private: - // Represents the sources from which we can get PAC files; two types of - // auto-detect or a custom URL. - struct PacSource { - enum Type { - WPAD_DHCP, - WPAD_DNS, - CUSTOM - }; - - PacSource(Type type, const GURL& url) - : type(type), url(url) {} - - Type type; - GURL url; // Empty unless |type == PAC_SOURCE_CUSTOM|. + struct PacURL { + PacURL(bool auto_detect, const GURL& url) + : auto_detect(auto_detect), url(url) {} + bool auto_detect; + GURL url; }; - typedef std::vector<PacSource> PacSourceList; + typedef std::vector<PacURL> UrlList; enum State { STATE_NONE, @@ -97,7 +83,7 @@ class InitProxyResolver { }; // Returns ordered list of PAC urls to try for |config|. - PacSourceList BuildPacSourcesFallbackList(const ProxyConfig& config) const; + UrlList BuildPacUrlsFallbackList(const ProxyConfig& config) const; void OnIOCompletion(int result); int DoLoop(int result); @@ -113,20 +99,17 @@ class InitProxyResolver { int DoSetPacScriptComplete(int result); // Tries restarting using the next fallback PAC URL: - // |pac_sources_[++current_pac_source_index]|. + // |pac_urls_[++current_pac_url_index]|. // Returns OK and rewinds the state machine when there // is something to try, otherwise returns |error|. - int TryToFallbackPacSource(int error); + int TryToFallbackPacUrl(int error); // Gets the initial state (we skip fetching when the // ProxyResolver doesn't |expect_pac_bytes()|. State GetStartState() const; - NetLogStringParameter* CreateNetLogParameterAndDetermineURL( - const PacSource& pac_source, GURL* effective_pac_url); - // Returns the current PAC URL we are fetching/testing. - const PacSource& current_pac_source() const; + const PacURL& current_pac_url() const; void OnWaitTimerFired(); void DidCompleteInit(); @@ -134,12 +117,11 @@ class InitProxyResolver { ProxyResolver* resolver_; ProxyScriptFetcher* proxy_script_fetcher_; - DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher_; CompletionCallbackImpl<InitProxyResolver> io_callback_; CompletionCallback* user_callback_; - size_t current_pac_source_index_; + size_t current_pac_url_index_; // Filled when the PAC script fetch completes. string16 pac_script_; @@ -148,7 +130,7 @@ class InitProxyResolver { // (i.e. fallback to direct connections are prohibited). bool pac_mandatory_; - PacSourceList pac_sources_; + UrlList pac_urls_; State next_state_; BoundNetLog net_log_; diff --git a/net/proxy/init_proxy_resolver_unittest.cc b/net/proxy/init_proxy_resolver_unittest.cc index 628abee..b0d416d 100644 --- a/net/proxy/init_proxy_resolver_unittest.cc +++ b/net/proxy/init_proxy_resolver_unittest.cc @@ -11,7 +11,6 @@ #include "net/base/net_log_unittest.h" #include "net/base/test_completion_callback.h" #include "net/proxy/init_proxy_resolver.h" -#include "net/proxy/dhcp_proxy_script_fetcher.h" #include "net/proxy/proxy_config.h" #include "net/proxy/proxy_resolver.h" #include "net/proxy/proxy_script_fetcher.h" @@ -108,7 +107,7 @@ class RuleBasedProxyScriptFetcher : public ProxyScriptFetcher { virtual void Cancel() {} - virtual URLRequestContext* GetRequestContext() const { return NULL; } + virtual URLRequestContext* GetRequestContext() { return NULL; } private: const Rules* rules_; @@ -175,7 +174,6 @@ TEST(InitProxyResolverTest, CustomPacSucceeds) { Rules rules; RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); RuleBasedProxyScriptFetcher fetcher(&rules); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_pac_url(GURL("http://custom/proxy.pac")); @@ -184,10 +182,8 @@ TEST(InitProxyResolverTest, CustomPacSucceeds) { TestCompletionCallback callback; CapturingNetLog log(CapturingNetLog::kUnbounded); - ProxyConfig effective_config; - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, &log); - EXPECT_EQ(OK, init.Init( - config, base::TimeDelta(), &effective_config, &callback)); + InitProxyResolver init(&resolver, &fetcher, &log); + EXPECT_EQ(OK, init.Init(config, base::TimeDelta(), NULL, &callback)); EXPECT_EQ(rule.text(), resolver.script_data()->utf16()); // Check the NetLog was filled correctly. @@ -207,9 +203,6 @@ TEST(InitProxyResolverTest, CustomPacSucceeds) { entries, 4, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT)); EXPECT_TRUE(LogContainsEndEvent( entries, 5, NetLog::TYPE_INIT_PROXY_RESOLVER)); - - EXPECT_TRUE(effective_config.has_pac_url()); - EXPECT_EQ(config.pac_url(), effective_config.pac_url()); } // Fail downloading the custom PAC script. @@ -217,7 +210,6 @@ TEST(InitProxyResolverTest, CustomPacFails1) { Rules rules; RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); RuleBasedProxyScriptFetcher fetcher(&rules); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_pac_url(GURL("http://custom/proxy.pac")); @@ -226,10 +218,9 @@ TEST(InitProxyResolverTest, CustomPacFails1) { TestCompletionCallback callback; CapturingNetLog log(CapturingNetLog::kUnbounded); - ProxyConfig effective_config; - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, &log); + InitProxyResolver init(&resolver, &fetcher, &log); EXPECT_EQ(kFailedDownloading, - init.Init(config, base::TimeDelta(), &effective_config, &callback)); + init.Init(config, base::TimeDelta(), NULL, &callback)); EXPECT_EQ(NULL, resolver.script_data()); // Check the NetLog was filled correctly. @@ -245,8 +236,6 @@ TEST(InitProxyResolverTest, CustomPacFails1) { entries, 2, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT)); EXPECT_TRUE(LogContainsEndEvent( entries, 3, NetLog::TYPE_INIT_PROXY_RESOLVER)); - - EXPECT_FALSE(effective_config.has_pac_url()); } // Fail parsing the custom PAC script. @@ -254,7 +243,6 @@ TEST(InitProxyResolverTest, CustomPacFails2) { Rules rules; RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); RuleBasedProxyScriptFetcher fetcher(&rules); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_pac_url(GURL("http://custom/proxy.pac")); @@ -262,7 +250,7 @@ TEST(InitProxyResolverTest, CustomPacFails2) { rules.AddFailParsingRule("http://custom/proxy.pac"); TestCompletionCallback callback; - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, NULL); + InitProxyResolver init(&resolver, &fetcher, NULL); EXPECT_EQ(kFailedParsing, init.Init(config, base::TimeDelta(), NULL, &callback)); EXPECT_EQ(NULL, resolver.script_data()); @@ -272,24 +260,22 @@ TEST(InitProxyResolverTest, CustomPacFails2) { TEST(InitProxyResolverTest, HasNullProxyScriptFetcher) { Rules rules; RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_pac_url(GURL("http://custom/proxy.pac")); TestCompletionCallback callback; - InitProxyResolver init(&resolver, NULL, &dhcp_fetcher, NULL); + InitProxyResolver init(&resolver, NULL, NULL); EXPECT_EQ(ERR_UNEXPECTED, init.Init(config, base::TimeDelta(), NULL, &callback)); EXPECT_EQ(NULL, resolver.script_data()); } -// Succeeds in choosing autodetect (WPAD DNS). +// Succeeds in choosing autodetect (wpad). TEST(InitProxyResolverTest, AutodetectSuccess) { Rules rules; RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); RuleBasedProxyScriptFetcher fetcher(&rules); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_auto_detect(true); @@ -297,14 +283,9 @@ TEST(InitProxyResolverTest, AutodetectSuccess) { Rules::Rule rule = rules.AddSuccessRule("http://wpad/wpad.dat"); TestCompletionCallback callback; - ProxyConfig effective_config; - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, NULL); - EXPECT_EQ(OK, init.Init( - config, base::TimeDelta(), &effective_config, &callback)); + InitProxyResolver init(&resolver, &fetcher, NULL); + EXPECT_EQ(OK, init.Init(config, base::TimeDelta(), NULL, &callback)); EXPECT_EQ(rule.text(), resolver.script_data()->utf16()); - - EXPECT_TRUE(effective_config.has_pac_url()); - EXPECT_EQ(rule.url, effective_config.pac_url()); } // Fails at WPAD (downloading), but succeeds in choosing the custom PAC. @@ -312,7 +293,6 @@ TEST(InitProxyResolverTest, AutodetectFailCustomSuccess1) { Rules rules; RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); RuleBasedProxyScriptFetcher fetcher(&rules); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_auto_detect(true); @@ -322,23 +302,16 @@ TEST(InitProxyResolverTest, AutodetectFailCustomSuccess1) { Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac"); TestCompletionCallback callback; - ProxyConfig effective_config; - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, NULL); - EXPECT_EQ(OK, init.Init( - config, base::TimeDelta(), &effective_config, &callback)); + InitProxyResolver init(&resolver, &fetcher, NULL); + EXPECT_EQ(OK, init.Init(config, base::TimeDelta(), NULL, &callback)); EXPECT_EQ(rule.text(), resolver.script_data()->utf16()); - - EXPECT_TRUE(effective_config.has_pac_url()); - EXPECT_EQ(rule.url, effective_config.pac_url()); } -// Fails at WPAD (no DHCP config, DNS PAC fails parsing), but succeeds in -// choosing the custom PAC. +// Fails at WPAD (parsing), but succeeds in choosing the custom PAC. TEST(InitProxyResolverTest, AutodetectFailCustomSuccess2) { Rules rules; RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); RuleBasedProxyScriptFetcher fetcher(&rules); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_auto_detect(true); @@ -352,7 +325,7 @@ TEST(InitProxyResolverTest, AutodetectFailCustomSuccess2) { CapturingNetLog log(CapturingNetLog::kUnbounded); ProxyConfig effective_config; - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, &log); + InitProxyResolver init(&resolver, &fetcher, &log); EXPECT_EQ(OK, init.Init(config, base::TimeDelta(), &effective_config, &callback)); EXPECT_EQ(rule.text(), resolver.script_data()->utf16()); @@ -363,48 +336,36 @@ TEST(InitProxyResolverTest, AutodetectFailCustomSuccess2) { ProxyConfig::CreateFromCustomPacURL(GURL("http://custom/proxy.pac")))); // Check the NetLog was filled correctly. - // (Note that various states are repeated since both WPAD and custom + // (Note that the Fetch and Set states are repeated since both WPAD and custom // PAC scripts are tried). CapturingNetLog::EntryList entries; log.GetEntries(&entries); - EXPECT_EQ(14u, entries.size()); + EXPECT_EQ(11u, entries.size()); EXPECT_TRUE(LogContainsBeginEvent( entries, 0, NetLog::TYPE_INIT_PROXY_RESOLVER)); - // This is the DHCP phase, which fails fetching rather than parsing, so - // there is no pair of SET_PAC_SCRIPT events. EXPECT_TRUE(LogContainsBeginEvent( entries, 1, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT)); EXPECT_TRUE(LogContainsEndEvent( entries, 2, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT)); - EXPECT_TRUE(LogContainsEvent( - entries, 3, - NetLog::TYPE_INIT_PROXY_RESOLVER_FALLING_BACK_TO_NEXT_PAC_SOURCE, - NetLog::PHASE_NONE)); - // This is the DNS phase, which attempts a fetch but fails. - EXPECT_TRUE(LogContainsBeginEvent( - entries, 4, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT)); - EXPECT_TRUE(LogContainsEndEvent( - entries, 5, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT)); EXPECT_TRUE(LogContainsBeginEvent( - entries, 6, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT)); + entries, 3, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT)); EXPECT_TRUE(LogContainsEndEvent( - entries, 7, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT)); + entries, 4, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT)); EXPECT_TRUE(LogContainsEvent( - entries, 8, - NetLog::TYPE_INIT_PROXY_RESOLVER_FALLING_BACK_TO_NEXT_PAC_SOURCE, + entries, 5, + NetLog::TYPE_INIT_PROXY_RESOLVER_FALLING_BACK_TO_NEXT_PAC_URL, NetLog::PHASE_NONE)); - // Finally, the custom PAC URL phase. EXPECT_TRUE(LogContainsBeginEvent( - entries, 9, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT)); + entries, 6, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT)); EXPECT_TRUE(LogContainsEndEvent( - entries, 10, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT)); + entries, 7, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT)); EXPECT_TRUE(LogContainsBeginEvent( - entries, 11, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT)); + entries, 8, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT)); EXPECT_TRUE(LogContainsEndEvent( - entries, 12, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT)); + entries, 9, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT)); EXPECT_TRUE(LogContainsEndEvent( - entries, 13, NetLog::TYPE_INIT_PROXY_RESOLVER)); + entries, 10, NetLog::TYPE_INIT_PROXY_RESOLVER)); } // Fails at WPAD (downloading), and fails at custom PAC (downloading). @@ -412,7 +373,6 @@ TEST(InitProxyResolverTest, AutodetectFailCustomFails1) { Rules rules; RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); RuleBasedProxyScriptFetcher fetcher(&rules); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_auto_detect(true); @@ -422,7 +382,7 @@ TEST(InitProxyResolverTest, AutodetectFailCustomFails1) { rules.AddFailDownloadRule("http://custom/proxy.pac"); TestCompletionCallback callback; - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, NULL); + InitProxyResolver init(&resolver, &fetcher, NULL); EXPECT_EQ(kFailedDownloading, init.Init(config, base::TimeDelta(), NULL, &callback)); EXPECT_EQ(NULL, resolver.script_data()); @@ -433,7 +393,6 @@ TEST(InitProxyResolverTest, AutodetectFailCustomFails2) { Rules rules; RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); RuleBasedProxyScriptFetcher fetcher(&rules); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_auto_detect(true); @@ -443,7 +402,7 @@ TEST(InitProxyResolverTest, AutodetectFailCustomFails2) { rules.AddFailParsingRule("http://custom/proxy.pac"); TestCompletionCallback callback; - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, NULL); + InitProxyResolver init(&resolver, &fetcher, NULL); EXPECT_EQ(kFailedParsing, init.Init(config, base::TimeDelta(), NULL, &callback)); EXPECT_EQ(NULL, resolver.script_data()); @@ -456,7 +415,6 @@ TEST(InitProxyResolverTest, AutodetectFailCustomSuccess2_NoFetch) { Rules rules; RuleBasedProxyResolver resolver(&rules, false /*expects_pac_bytes*/); RuleBasedProxyScriptFetcher fetcher(&rules); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_auto_detect(true); @@ -466,7 +424,7 @@ TEST(InitProxyResolverTest, AutodetectFailCustomSuccess2_NoFetch) { Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac"); TestCompletionCallback callback; - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, NULL); + InitProxyResolver init(&resolver, &fetcher, NULL); EXPECT_EQ(OK, init.Init(config, base::TimeDelta(), NULL, &callback)); EXPECT_EQ(rule.url, resolver.script_data()->url()); } @@ -478,7 +436,6 @@ TEST(InitProxyResolverTest, CustomPacFails1_WithPositiveDelay) { Rules rules; RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); RuleBasedProxyScriptFetcher fetcher(&rules); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_pac_url(GURL("http://custom/proxy.pac")); @@ -487,7 +444,7 @@ TEST(InitProxyResolverTest, CustomPacFails1_WithPositiveDelay) { TestCompletionCallback callback; CapturingNetLog log(CapturingNetLog::kUnbounded); - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, &log); + InitProxyResolver init(&resolver, &fetcher, &log); EXPECT_EQ(ERR_IO_PENDING, init.Init(config, base::TimeDelta::FromMilliseconds(1), NULL, &callback)); @@ -521,7 +478,6 @@ TEST(InitProxyResolverTest, CustomPacFails1_WithNegativeDelay) { Rules rules; RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); RuleBasedProxyScriptFetcher fetcher(&rules); - DoNothingDhcpProxyScriptFetcher dhcp_fetcher; ProxyConfig config; config.set_pac_url(GURL("http://custom/proxy.pac")); @@ -530,7 +486,7 @@ TEST(InitProxyResolverTest, CustomPacFails1_WithNegativeDelay) { TestCompletionCallback callback; CapturingNetLog log(CapturingNetLog::kUnbounded); - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, &log); + InitProxyResolver init(&resolver, &fetcher, &log); EXPECT_EQ(kFailedDownloading, init.Init(config, base::TimeDelta::FromSeconds(-5), NULL, &callback)); @@ -551,87 +507,5 @@ TEST(InitProxyResolverTest, CustomPacFails1_WithNegativeDelay) { entries, 3, NetLog::TYPE_INIT_PROXY_RESOLVER)); } -class SynchronousSuccessDhcpFetcher : public DhcpProxyScriptFetcher { - public: - explicit SynchronousSuccessDhcpFetcher(const string16& expected_text) - : gurl_("http://dhcppac/"), expected_text_(expected_text) { - } - - int Fetch(string16* utf16_text, CompletionCallback* callback) OVERRIDE { - *utf16_text = expected_text_; - return OK; - } - - void Cancel() OVERRIDE { - } - - const GURL& GetPacURL() const OVERRIDE { - return gurl_; - } - - const string16& expected_text() const { - return expected_text_; - } - - private: - GURL gurl_; - string16 expected_text_; -}; - -// All of the tests above that use InitProxyResolver have tested -// failure to fetch a PAC file via DHCP configuration, so we now test -// success at downloading and parsing, and then success at downloading, -// failure at parsing. - -TEST(InitProxyResolverTest, AutodetectDhcpSuccess) { - Rules rules; - RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); - RuleBasedProxyScriptFetcher fetcher(&rules); - SynchronousSuccessDhcpFetcher dhcp_fetcher( - WideToUTF16(L"http://bingo/!valid-script")); - - ProxyConfig config; - config.set_auto_detect(true); - - rules.AddSuccessRule("http://bingo/"); - rules.AddFailDownloadRule("http://wpad/wpad.dat"); - - TestCompletionCallback callback; - ProxyConfig effective_config; - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, NULL); - EXPECT_EQ(OK, init.Init( - config, base::TimeDelta(), &effective_config, &callback)); - EXPECT_EQ(dhcp_fetcher.expected_text(), - resolver.script_data()->utf16()); - - EXPECT_TRUE(effective_config.has_pac_url()); - EXPECT_EQ(GURL("http://dhcppac/"), effective_config.pac_url()); -} - -TEST(InitProxyResolverTest, AutodetectDhcpFailParse) { - Rules rules; - RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/); - RuleBasedProxyScriptFetcher fetcher(&rules); - SynchronousSuccessDhcpFetcher dhcp_fetcher( - WideToUTF16(L"http://bingo/!invalid-script")); - - ProxyConfig config; - config.set_auto_detect(true); - - rules.AddFailParsingRule("http://bingo/"); - rules.AddFailDownloadRule("http://wpad/wpad.dat"); - - TestCompletionCallback callback; - ProxyConfig effective_config; - InitProxyResolver init(&resolver, &fetcher, &dhcp_fetcher, NULL); - // Since there is fallback to DNS-based WPAD, the final error will be that - // it failed downloading, not that it failed parsing. - EXPECT_EQ(kFailedDownloading, - init.Init(config, base::TimeDelta(), &effective_config, &callback)); - EXPECT_EQ(NULL, resolver.script_data()); - - EXPECT_FALSE(effective_config.has_pac_url()); -} - } // namespace } // namespace net diff --git a/net/proxy/mock_proxy_script_fetcher.cc b/net/proxy/mock_proxy_script_fetcher.cc deleted file mode 100644 index 3e9b601..0000000 --- a/net/proxy/mock_proxy_script_fetcher.cc +++ /dev/null @@ -1,55 +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/mock_proxy_script_fetcher.h" - -#include "base/logging.h" -#include "base/string16.h" -#include "base/utf_string_conversions.h" -#include "net/base/net_errors.h" - -namespace net { - -MockProxyScriptFetcher::MockProxyScriptFetcher() - : pending_request_callback_(NULL), pending_request_text_(NULL) { -} - -// ProxyScriptFetcher implementation. -int MockProxyScriptFetcher::Fetch(const GURL& url, - string16* text, - CompletionCallback* callback) { - DCHECK(!has_pending_request()); - - // Save the caller's information, and have them wait. - pending_request_url_ = url; - pending_request_callback_ = callback; - pending_request_text_ = text; - return ERR_IO_PENDING; -} - -void MockProxyScriptFetcher::NotifyFetchCompletion( - int result, const std::string& ascii_text) { - DCHECK(has_pending_request()); - *pending_request_text_ = ASCIIToUTF16(ascii_text); - CompletionCallback* callback = pending_request_callback_; - pending_request_callback_ = NULL; - callback->Run(result); -} - -void MockProxyScriptFetcher::Cancel() { -} - -URLRequestContext* MockProxyScriptFetcher::GetRequestContext() const { - return NULL; -} - -const GURL& MockProxyScriptFetcher::pending_request_url() const { - return pending_request_url_; -} - -bool MockProxyScriptFetcher::has_pending_request() const { - return pending_request_callback_ != NULL; -} - -} // namespace net diff --git a/net/proxy/mock_proxy_script_fetcher.h b/net/proxy/mock_proxy_script_fetcher.h deleted file mode 100644 index bd6ac42..0000000 --- a/net/proxy/mock_proxy_script_fetcher.h +++ /dev/null @@ -1,44 +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. - -#ifndef NET_PROXY_MOCK_PROXY_SCRIPT_FETCHER_H_ -#define NET_PROXY_MOCK_PROXY_SCRIPT_FETCHER_H_ -#pragma once - -#include "base/compiler_specific.h" -#include "googleurl/src/gurl.h" -#include "net/proxy/proxy_script_fetcher.h" - -#include <string> - -namespace net { - -class URLRequestContext; - -// A mock ProxyScriptFetcher. No result will be returned to the fetch client -// until we call NotifyFetchCompletion() to set the results. -class MockProxyScriptFetcher : public ProxyScriptFetcher { - public: - MockProxyScriptFetcher(); - - // ProxyScriptFetcher implementation. - virtual int Fetch(const GURL& url, - string16* text, - CompletionCallback* callback) OVERRIDE; - virtual void Cancel() OVERRIDE; - virtual URLRequestContext* GetRequestContext() const OVERRIDE; - - void NotifyFetchCompletion(int result, const std::string& ascii_text); - const GURL& pending_request_url() const; - bool has_pending_request() const; - - private: - GURL pending_request_url_; - CompletionCallback* pending_request_callback_; - string16* pending_request_text_; -}; - -} // namespace net - -#endif // NET_PROXY_MOCK_PROXY_SCRIPT_FETCHER_H_ diff --git a/net/proxy/proxy_script_fetcher.h b/net/proxy/proxy_script_fetcher.h index d488375..c8cda24 100644 --- a/net/proxy/proxy_script_fetcher.h +++ b/net/proxy/proxy_script_fetcher.h @@ -52,7 +52,7 @@ class ProxyScriptFetcher { // Returns the request context that this fetcher uses to issue downloads, // or NULL. - virtual URLRequestContext* GetRequestContext() const = 0; + virtual URLRequestContext* GetRequestContext() = 0; }; } // namespace net diff --git a/net/proxy/proxy_script_fetcher_impl.cc b/net/proxy/proxy_script_fetcher_impl.cc index c276c30..aabe340 100644 --- a/net/proxy/proxy_script_fetcher_impl.cc +++ b/net/proxy/proxy_script_fetcher_impl.cc @@ -171,7 +171,7 @@ void ProxyScriptFetcherImpl::Cancel() { ResetCurRequestState(); } -URLRequestContext* ProxyScriptFetcherImpl::GetRequestContext() const { +URLRequestContext* ProxyScriptFetcherImpl::GetRequestContext() { return url_request_context_; } diff --git a/net/proxy/proxy_script_fetcher_impl.h b/net/proxy/proxy_script_fetcher_impl.h index 8e9ca3b..419293f 100644 --- a/net/proxy/proxy_script_fetcher_impl.h +++ b/net/proxy/proxy_script_fetcher_impl.h @@ -45,9 +45,9 @@ class ProxyScriptFetcherImpl : public ProxyScriptFetcher, // ProxyScriptFetcher methods: virtual int Fetch(const GURL& url, string16* text, - CompletionCallback* callback) OVERRIDE; - virtual void Cancel() OVERRIDE; - virtual URLRequestContext* GetRequestContext() const OVERRIDE; + CompletionCallback* callback); + virtual void Cancel(); + virtual URLRequestContext* GetRequestContext(); // URLRequest::Delegate methods: virtual void OnAuthRequired(URLRequest* request, diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc index a16cb57..a134133 100644 --- a/net/proxy/proxy_service.cc +++ b/net/proxy/proxy_service.cc @@ -16,7 +16,6 @@ #include "net/base/net_errors.h" #include "net/base/net_log.h" #include "net/base/net_util.h" -#include "net/proxy/dhcp_proxy_script_fetcher.h" #include "net/proxy/init_proxy_resolver.h" #include "net/proxy/multi_threaded_proxy_resolver.h" #include "net/proxy/network_delegate_error_observer.h" @@ -410,13 +409,11 @@ ProxyService* ProxyService::CreateUsingV8ProxyResolver( ProxyConfigService* proxy_config_service, size_t num_pac_threads, ProxyScriptFetcher* proxy_script_fetcher, - DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher, HostResolver* host_resolver, NetLog* net_log, NetworkDelegate* network_delegate) { DCHECK(proxy_config_service); DCHECK(proxy_script_fetcher); - DCHECK(dhcp_proxy_script_fetcher); DCHECK(host_resolver); if (num_pac_threads == 0) @@ -436,9 +433,8 @@ ProxyService* ProxyService::CreateUsingV8ProxyResolver( ProxyService* proxy_service = new ProxyService(proxy_config_service, proxy_resolver, net_log); - // Configure fetchers to use for PAC script downloads and auto-detect. - proxy_service->SetProxyScriptFetchers(proxy_script_fetcher, - dhcp_proxy_script_fetcher); + // Configure PAC script downloads to be issued using |proxy_script_fetcher|. + proxy_service->SetProxyScriptFetcher(proxy_script_fetcher); return proxy_service; } @@ -778,13 +774,11 @@ int ProxyService::DidFinishResolvingProxy(ProxyInfo* result, return result_code; } -void ProxyService::SetProxyScriptFetchers( - ProxyScriptFetcher* proxy_script_fetcher, - DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher) { +void ProxyService::SetProxyScriptFetcher( + ProxyScriptFetcher* proxy_script_fetcher) { DCHECK(CalledOnValidThread()); State previous_state = ResetProxyConfig(false); proxy_script_fetcher_.reset(proxy_script_fetcher); - dhcp_proxy_script_fetcher_.reset(dhcp_proxy_script_fetcher); if (previous_state != STATE_NONE) ApplyProxyConfigIfAvailable(); } @@ -933,9 +927,7 @@ void ProxyService::InitializeUsingLastFetchedConfig() { current_state_ = STATE_WAITING_FOR_INIT_PROXY_RESOLVER; init_proxy_resolver_.reset( - new InitProxyResolver(resolver_.get(), - proxy_script_fetcher_.get(), - dhcp_proxy_script_fetcher_.get(), + new InitProxyResolver(resolver_.get(), proxy_script_fetcher_.get(), net_log_)); // If we changed networks recently, we should delay running proxy auto-config. diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h index cee7ef6..f7856e5 100644 --- a/net/proxy/proxy_service.h +++ b/net/proxy/proxy_service.h @@ -25,7 +25,6 @@ class MessageLoop; namespace net { -class DhcpProxyScriptFetcher; class HostResolver; class InitProxyResolver; class NetworkDelegate; @@ -99,12 +98,10 @@ class ProxyService : public NetworkChangeNotifier::IPAddressObserver, // Call this method with a non-null |pac_request| to cancel the PAC request. void CancelPacRequest(PacRequest* pac_request); - // Sets the ProxyScriptFetcher and DhcpProxyScriptFetcher dependencies. This - // is needed if the ProxyResolver is of type ProxyResolverWithoutFetch. - // ProxyService takes ownership of both objects. - void SetProxyScriptFetchers( - ProxyScriptFetcher* proxy_script_fetcher, - DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher); + // Sets the ProxyScriptFetcher dependency. This is needed if the ProxyResolver + // is of type ProxyResolverWithoutFetch. ProxyService takes ownership of + // |proxy_script_fetcher|. + void SetProxyScriptFetcher(ProxyScriptFetcher* proxy_script_fetcher); ProxyScriptFetcher* GetProxyScriptFetcher() const; // Tells this ProxyService to start using a new ProxyConfigService to @@ -164,10 +161,6 @@ class ProxyService : public NetworkChangeNotifier::IPAddressObserver, // |proxy_script_fetcher| specifies the dependency to use for downloading // any PAC scripts. The resulting ProxyService will take ownership of it. // - // |dhcp_proxy_script_fetcher| specifies the dependency to use for attempting - // to retrieve the most appropriate PAC script configured in DHCP. The - // resulting ProxyService will take ownership of it. - // // |host_resolver| points to the host resolving dependency the PAC script // should use for any DNS queries. It must remain valid throughout the // lifetime of the ProxyService. @@ -181,7 +174,6 @@ class ProxyService : public NetworkChangeNotifier::IPAddressObserver, ProxyConfigService* proxy_config_service, size_t num_pac_threads, ProxyScriptFetcher* proxy_script_fetcher, - DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher, HostResolver* host_resolver, NetLog* net_log, NetworkDelegate* network_delegate); @@ -327,11 +319,6 @@ class ProxyService : public NetworkChangeNotifier::IPAddressObserver, // external PAC script fetching. scoped_ptr<ProxyScriptFetcher> proxy_script_fetcher_; - // The fetcher to use when attempting to download the most appropriate PAC - // script configured in DHCP, if any. Can be NULL if the ProxyResolver has - // no need for DHCP PAC script fetching. - scoped_ptr<DhcpProxyScriptFetcher> dhcp_proxy_script_fetcher_; - // Callback for when |init_proxy_resolver_| is done. CompletionCallbackImpl<ProxyService> init_proxy_resolver_callback_; diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc index aac8bc9..f5ae3d7 100644 --- a/net/proxy/proxy_service_unittest.cc +++ b/net/proxy/proxy_service_unittest.cc @@ -15,9 +15,7 @@ #include "net/base/net_log.h" #include "net/base/net_log_unittest.h" #include "net/base/test_completion_callback.h" -#include "net/proxy/dhcp_proxy_script_fetcher.h" #include "net/proxy/mock_proxy_resolver.h" -#include "net/proxy/mock_proxy_script_fetcher.h" #include "net/proxy/proxy_config_service.h" #include "net/proxy/proxy_resolver.h" #include "net/proxy/proxy_script_fetcher.h" @@ -69,6 +67,53 @@ class MockProxyConfigService: public ProxyConfigService { } // namespace +// A mock ProxyScriptFetcher. No result will be returned to the fetch client +// until we call NotifyFetchCompletion() to set the results. +class MockProxyScriptFetcher : public ProxyScriptFetcher { + public: + MockProxyScriptFetcher() + : pending_request_callback_(NULL), pending_request_text_(NULL) { + } + + // ProxyScriptFetcher implementation. + virtual int Fetch(const GURL& url, + string16* text, + CompletionCallback* callback) { + DCHECK(!has_pending_request()); + + // Save the caller's information, and have them wait. + pending_request_url_ = url; + pending_request_callback_ = callback; + pending_request_text_ = text; + return ERR_IO_PENDING; + } + + void NotifyFetchCompletion(int result, const std::string& ascii_text) { + DCHECK(has_pending_request()); + *pending_request_text_ = ASCIIToUTF16(ascii_text); + CompletionCallback* callback = pending_request_callback_; + pending_request_callback_ = NULL; + callback->Run(result); + } + + virtual void Cancel() {} + + virtual URLRequestContext* GetRequestContext() { return NULL; } + + const GURL& pending_request_url() const { + return pending_request_url_; + } + + bool has_pending_request() const { + return pending_request_callback_ != NULL; + } + + private: + GURL pending_request_url_; + CompletionCallback* pending_request_callback_; + string16* pending_request_text_; +}; + TEST(ProxyServiceTest, Direct) { MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; ProxyService service(new MockProxyConfigService( @@ -404,8 +449,7 @@ TEST(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) { ProxyService service(config_service, resolver, NULL); MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - DhcpProxyScriptFetcher* dhcp_fetcher = new DoNothingDhcpProxyScriptFetcher(); - service.SetProxyScriptFetchers(fetcher, dhcp_fetcher); + service.SetProxyScriptFetcher(fetcher); // Start resolve request. GURL url("http://www.google.com/"); @@ -1139,8 +1183,7 @@ TEST(ProxyServiceTest, InitialPACScriptDownload) { ProxyService service(config_service, resolver, NULL); MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetchers(fetcher, - new DoNothingDhcpProxyScriptFetcher()); + service.SetProxyScriptFetcher(fetcher); // Start 3 requests. @@ -1219,8 +1262,7 @@ TEST(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) { ProxyService service(config_service, resolver, NULL); MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetchers(fetcher, - new DoNothingDhcpProxyScriptFetcher()); + service.SetProxyScriptFetcher(fetcher); // Start 2 requests. @@ -1248,8 +1290,7 @@ TEST(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) { // the initialization with the new fetcher. fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetchers(fetcher, - new DoNothingDhcpProxyScriptFetcher()); + service.SetProxyScriptFetcher(fetcher); // Nothing has been sent to the resolver yet. EXPECT_TRUE(resolver->pending_requests().empty()); @@ -1278,8 +1319,7 @@ TEST(ProxyServiceTest, CancelWhilePACFetching) { ProxyService service(config_service, resolver, NULL); MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetchers(fetcher, - new DoNothingDhcpProxyScriptFetcher()); + service.SetProxyScriptFetcher(fetcher); // Start 3 requests. ProxyInfo info1; @@ -1370,8 +1410,7 @@ TEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac) { ProxyService service(config_service, resolver, NULL); MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetchers(fetcher, - new DoNothingDhcpProxyScriptFetcher()); + service.SetProxyScriptFetcher(fetcher); // Start 2 requests. @@ -1441,8 +1480,7 @@ TEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) { ProxyService service(config_service, resolver, NULL); MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetchers(fetcher, - new DoNothingDhcpProxyScriptFetcher()); + service.SetProxyScriptFetcher(fetcher); // Start 2 requests. @@ -1517,8 +1555,7 @@ TEST(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) { ProxyService service(config_service, resolver, NULL); MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetchers(fetcher, - new DoNothingDhcpProxyScriptFetcher()); + service.SetProxyScriptFetcher(fetcher); // Start 2 requests. @@ -1575,8 +1612,7 @@ TEST(ProxyServiceTest, BypassDoesntApplyToPac) { ProxyService service(config_service, resolver, NULL); MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetchers(fetcher, - new DoNothingDhcpProxyScriptFetcher()); + service.SetProxyScriptFetcher(fetcher); // Start 1 requests. @@ -1643,8 +1679,7 @@ TEST(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) { ProxyService service(config_service, resolver, NULL); MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetchers(fetcher, - new DoNothingDhcpProxyScriptFetcher()); + service.SetProxyScriptFetcher(fetcher); // Start 1 request. @@ -1775,8 +1810,7 @@ TEST(ProxyServiceTest, NetworkChangeTriggersPacRefetch) { ProxyService service(config_service, resolver, &log); MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; - service.SetProxyScriptFetchers(fetcher, - new DoNothingDhcpProxyScriptFetcher()); + service.SetProxyScriptFetcher(fetcher); // Disable the "wait after IP address changes" hack, so this unit-test can // complete quickly. |