| Index: net/proxy/dhcp_proxy_script_adapter_fetcher_win.cc
|
| 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 8d41d661c783a102b1e5d2be0679a2a52c1e0858..0000000000000000000000000000000000000000
|
| --- a/net/proxy/dhcp_proxy_script_adapter_fetcher_win.cc
|
| +++ /dev/null
|
| @@ -1,292 +0,0 @@
|
| -// Copyright (c) 2012 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/bind.h"
|
| -#include "base/bind_helpers.h"
|
| -#include "base/logging.h"
|
| -#include "base/message_loop/message_loop_proxy.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/sys_string_conversions.h"
|
| -#include "base/task_runner.h"
|
| -#include "base/time/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,
|
| - scoped_refptr<base::TaskRunner> task_runner)
|
| - : task_runner_(task_runner),
|
| - state_(STATE_START),
|
| - result_(ERR_IO_PENDING),
|
| - url_request_context_(url_request_context) {
|
| - DCHECK(url_request_context_);
|
| -}
|
| -
|
| -DhcpProxyScriptAdapterFetcher::~DhcpProxyScriptAdapterFetcher() {
|
| - Cancel();
|
| -}
|
| -
|
| -void DhcpProxyScriptAdapterFetcher::Fetch(
|
| - const std::string& adapter_name, const CompletionCallback& callback) {
|
| - DCHECK(CalledOnValidThread());
|
| - DCHECK_EQ(state_, STATE_START);
|
| - result_ = ERR_IO_PENDING;
|
| - pac_script_ = base::string16();
|
| - state_ = STATE_WAIT_DHCP;
|
| - callback_ = callback;
|
| -
|
| - wait_timer_.Start(FROM_HERE, ImplGetTimeout(),
|
| - this, &DhcpProxyScriptAdapterFetcher::OnTimeout);
|
| - scoped_refptr<DhcpQuery> dhcp_query(ImplCreateDhcpQuery());
|
| - task_runner_->PostTaskAndReply(
|
| - FROM_HERE,
|
| - base::Bind(
|
| - &DhcpProxyScriptAdapterFetcher::DhcpQuery::GetPacURLForAdapter,
|
| - dhcp_query.get(),
|
| - adapter_name),
|
| - base::Bind(
|
| - &DhcpProxyScriptAdapterFetcher::OnDhcpQueryDone,
|
| - AsWeakPtr(),
|
| - dhcp_query));
|
| -}
|
| -
|
| -void DhcpProxyScriptAdapterFetcher::Cancel() {
|
| - DCHECK(CalledOnValidThread());
|
| - callback_.Reset();
|
| - 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_;
|
| -}
|
| -
|
| -base::string16 DhcpProxyScriptAdapterFetcher::GetPacScript() const {
|
| - DCHECK(CalledOnValidThread());
|
| - return pac_script_;
|
| -}
|
| -
|
| -GURL DhcpProxyScriptAdapterFetcher::GetPacURL() const {
|
| - DCHECK(CalledOnValidThread());
|
| - return pac_url_;
|
| -}
|
| -
|
| -DhcpProxyScriptAdapterFetcher::DhcpQuery::DhcpQuery() {
|
| -}
|
| -
|
| -DhcpProxyScriptAdapterFetcher::DhcpQuery::~DhcpQuery() {
|
| -}
|
| -
|
| -void DhcpProxyScriptAdapterFetcher::DhcpQuery::GetPacURLForAdapter(
|
| - const std::string& adapter_name) {
|
| - url_ = ImplGetPacURLFromDhcp(adapter_name);
|
| -}
|
| -
|
| -const std::string& DhcpProxyScriptAdapterFetcher::DhcpQuery::url() const {
|
| - return url_;
|
| -}
|
| -
|
| -std::string
|
| - DhcpProxyScriptAdapterFetcher::DhcpQuery::ImplGetPacURLFromDhcp(
|
| - const std::string& adapter_name) {
|
| - return DhcpProxyScriptAdapterFetcher::GetPacURLFromDhcp(adapter_name);
|
| -}
|
| -
|
| -void DhcpProxyScriptAdapterFetcher::OnDhcpQueryDone(
|
| - scoped_refptr<DhcpQuery> dhcp_query) {
|
| - 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(dhcp_query->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_,
|
| - base::Bind(&DhcpProxyScriptAdapterFetcher::OnFetcherDone,
|
| - base::Unretained(this)));
|
| - }
|
| -}
|
| -
|
| -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;
|
| - CompletionCallback callback = callback_;
|
| - callback_.Reset();
|
| -
|
| - // Be careful not to touch any member state after this, as the client
|
| - // may delete us during this callback.
|
| - callback.Run(result_);
|
| -}
|
| -
|
| -DhcpProxyScriptAdapterFetcher::State
|
| - DhcpProxyScriptAdapterFetcher::state() const {
|
| - return state_;
|
| -}
|
| -
|
| -ProxyScriptFetcher* DhcpProxyScriptAdapterFetcher::ImplCreateScriptFetcher() {
|
| - return new ProxyScriptFetcherImpl(url_request_context_);
|
| -}
|
| -
|
| -DhcpProxyScriptAdapterFetcher::DhcpQuery*
|
| - DhcpProxyScriptAdapterFetcher::ImplCreateDhcpQuery() {
|
| - return new DhcpQuery();
|
| -}
|
| -
|
| -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 };
|
| -
|
| - 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<BYTE, base::FreeDeleter> result_buffer;
|
| - int retry_count = 0;
|
| - DWORD res = NO_ERROR;
|
| - do {
|
| - result_buffer.reset(static_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) {
|
| - VLOG(1) << "Error fetching PAC URL from DHCP: " << res;
|
| - } else if (wpad_params.nBytesData) {
|
| - return SanitizeDhcpApiString(
|
| - reinterpret_cast<const char*>(wpad_params.Data),
|
| - wpad_params.nBytesData);
|
| - }
|
| -
|
| - return "";
|
| -}
|
| -
|
| -// static
|
| -std::string DhcpProxyScriptAdapterFetcher::SanitizeDhcpApiString(
|
| - const char* data, size_t count_bytes) {
|
| - // The result should be ASCII, not wide character. Some DHCP
|
| - // servers appear to count the trailing NULL in nBytesData, others
|
| - // do not. A few (we've had one report, http://crbug.com/297810)
|
| - // do not NULL-terminate but may \n-terminate.
|
| - //
|
| - // Belt and suspenders and elastic waistband: First, ensure we
|
| - // NULL-terminate after nBytesData; this is the inner constructor
|
| - // with nBytesData as a parameter. Then, return only up to the
|
| - // first null in case of embedded NULLs; this is the outer
|
| - // constructor that takes the result of c_str() on the inner. If
|
| - // the server is giving us back a buffer with embedded NULLs,
|
| - // something is broken anyway. Finally, trim trailing whitespace.
|
| - std::string result(std::string(data, count_bytes).c_str());
|
| - base::TrimWhitespaceASCII(result, base::TRIM_TRAILING, &result);
|
| - return result;
|
| -}
|
| -
|
| -} // namespace net
|
|
|