// 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/proxy_script_decider.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/profiler/scoped_tracker.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.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_script_fetcher.h"
#include "net/url_request/url_request_context.h"

namespace net {

namespace {

bool LooksLikePacScript(const base::string16& script) {
  // Note: this is only an approximation! It may not always work correctly,
  // however it is very likely that legitimate scripts have this exact string,
  // since they must minimally define a function of this name. Conversely, a
  // file not containing the string is not likely to be a PAC script.
  //
  // An exact test would have to load the script in a javascript evaluator.
  return script.find(base::ASCIIToUTF16("FindProxyForURL")) !=
             base::string16::npos;
}

}

// This is the hard-coded location used by the DNS portion of web proxy
// auto-discovery.
//
// Note that we not use DNS devolution to find the WPAD host, since that could
// be dangerous should our top level domain registry  become out of date.
//
// Instead we directly resolve "wpad", and let the operating system apply the
// DNS suffix search paths. This is the same approach taken by Firefox, and
// compatibility hasn't been an issue.
//
// For more details, also check out this comment:
// http://code.google.com/p/chromium/issues/detail?id=18575#c20
namespace {
const char kWpadUrl[] = "http://wpad/wpad.dat";
const int kQuickCheckDelayMs = 1000;
};

base::Value* ProxyScriptDecider::PacSource::NetLogCallback(
    const GURL* effective_pac_url,
    NetLog::LogLevel /* log_level */) const {
  base::DictionaryValue* dict = new base::DictionaryValue();
  std::string source;
  switch (type) {
    case PacSource::WPAD_DHCP:
      source = "WPAD DHCP";
      break;
    case PacSource::WPAD_DNS:
      source = "WPAD DNS: ";
      source += effective_pac_url->possibly_invalid_spec();
      break;
    case PacSource::CUSTOM:
      source = "Custom PAC URL: ";
      source += effective_pac_url->possibly_invalid_spec();
      break;
  }
  dict->SetString("source", source);
  return dict;
}

ProxyScriptDecider::ProxyScriptDecider(
    ProxyScriptFetcher* proxy_script_fetcher,
    DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
    NetLog* net_log)
    : proxy_script_fetcher_(proxy_script_fetcher),
      dhcp_proxy_script_fetcher_(dhcp_proxy_script_fetcher),
      current_pac_source_index_(0u),
      pac_mandatory_(false),
      next_state_(STATE_NONE),
      net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_PROXY_SCRIPT_DECIDER)),
      fetch_pac_bytes_(false),
      quick_check_enabled_(true) {
  if (proxy_script_fetcher &&
      proxy_script_fetcher->GetRequestContext() &&
      proxy_script_fetcher->GetRequestContext()->host_resolver()) {
      host_resolver_.reset(new SingleRequestHostResolver(
          proxy_script_fetcher->GetRequestContext()->host_resolver()));
  }
}

ProxyScriptDecider::~ProxyScriptDecider() {
  if (next_state_ != STATE_NONE)
    Cancel();
}

int ProxyScriptDecider::Start(
    const ProxyConfig& config, const base::TimeDelta wait_delay,
    bool fetch_pac_bytes, const CompletionCallback& callback) {
  DCHECK_EQ(STATE_NONE, next_state_);
  DCHECK(!callback.is_null());
  DCHECK(config.HasAutomaticSettings());

  net_log_.BeginEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER);

  fetch_pac_bytes_ = fetch_pac_bytes;

  // Save the |wait_delay| as a non-negative value.
  wait_delay_ = wait_delay;
  if (wait_delay_ < base::TimeDelta())
    wait_delay_ = base::TimeDelta();

  pac_mandatory_ = config.pac_mandatory();
  have_custom_pac_url_ = config.has_pac_url();

  pac_sources_ = BuildPacSourcesFallbackList(config);
  DCHECK(!pac_sources_.empty());

  next_state_ = STATE_WAIT;

  int rv = DoLoop(OK);
  if (rv == ERR_IO_PENDING)
    callback_ = callback;
  else
    DidComplete();

  return rv;
}

const ProxyConfig& ProxyScriptDecider::effective_config() const {
  DCHECK_EQ(STATE_NONE, next_state_);
  return effective_config_;
}

// TODO(eroman): Return a const-pointer.
ProxyResolverScriptData* ProxyScriptDecider::script_data() const {
  DCHECK_EQ(STATE_NONE, next_state_);
  return script_data_.get();
}

// Initialize the fallback rules.
// (1) WPAD (DHCP).
// (2) WPAD (DNS).
// (3) Custom PAC URL.
ProxyScriptDecider::PacSourceList ProxyScriptDecider::
    BuildPacSourcesFallbackList(
    const ProxyConfig& config) const {
  PacSourceList pac_sources;
  if (config.auto_detect()) {
    pac_sources.push_back(PacSource(PacSource::WPAD_DHCP, GURL(kWpadUrl)));
    pac_sources.push_back(PacSource(PacSource::WPAD_DNS, GURL(kWpadUrl)));
  }
  if (config.has_pac_url())
    pac_sources.push_back(PacSource(PacSource::CUSTOM, config.pac_url()));
  return pac_sources;
}

void ProxyScriptDecider::OnIOCompletion(int result) {
  // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed.
  tracked_objects::ScopedTracker tracking_profile(
      FROM_HERE_WITH_EXPLICIT_FUNCTION(
          "436634 ProxyScriptDecider::OnIOCompletion"));

  DCHECK_NE(STATE_NONE, next_state_);
  int rv = DoLoop(result);
  if (rv != ERR_IO_PENDING) {
    DidComplete();
    DoCallback(rv);
  }
}

int ProxyScriptDecider::DoLoop(int result) {
  DCHECK_NE(next_state_, STATE_NONE);
  int rv = result;
  do {
    State state = next_state_;
    next_state_ = STATE_NONE;
    switch (state) {
      case STATE_WAIT:
        DCHECK_EQ(OK, rv);
        rv = DoWait();
        break;
      case STATE_WAIT_COMPLETE:
        rv = DoWaitComplete(rv);
        break;
      case STATE_QUICK_CHECK:
        DCHECK_EQ(OK, rv);
        rv = DoQuickCheck();
        break;
      case STATE_QUICK_CHECK_COMPLETE:
        rv = DoQuickCheckComplete(rv);
        break;
      case STATE_FETCH_PAC_SCRIPT:
        DCHECK_EQ(OK, rv);
        rv = DoFetchPacScript();
        break;
      case STATE_FETCH_PAC_SCRIPT_COMPLETE:
        rv = DoFetchPacScriptComplete(rv);
        break;
      case STATE_VERIFY_PAC_SCRIPT:
        DCHECK_EQ(OK, rv);
        rv = DoVerifyPacScript();
        break;
      case STATE_VERIFY_PAC_SCRIPT_COMPLETE:
        rv = DoVerifyPacScriptComplete(rv);
        break;
      default:
        NOTREACHED() << "bad state";
        rv = ERR_UNEXPECTED;
        break;
    }
  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
  return rv;
}

void ProxyScriptDecider::DoCallback(int result) {
  DCHECK_NE(ERR_IO_PENDING, result);
  DCHECK(!callback_.is_null());
  callback_.Run(result);
}

int ProxyScriptDecider::DoWait() {
  next_state_ = STATE_WAIT_COMPLETE;

  // If no waiting is required, continue on to the next state.
  if (wait_delay_.ToInternalValue() == 0)
    return OK;

  // Otherwise wait the specified amount of time.
  wait_timer_.Start(FROM_HERE, wait_delay_, this,
                    &ProxyScriptDecider::OnWaitTimerFired);
  net_log_.BeginEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_WAIT);
  return ERR_IO_PENDING;
}

int ProxyScriptDecider::DoWaitComplete(int result) {
  DCHECK_EQ(OK, result);
  if (wait_delay_.ToInternalValue() != 0) {
    net_log_.EndEventWithNetErrorCode(NetLog::TYPE_PROXY_SCRIPT_DECIDER_WAIT,
                                      result);
  }
  if (quick_check_enabled_ && current_pac_source().type == PacSource::WPAD_DNS)
    next_state_ = STATE_QUICK_CHECK;
  else
    next_state_ = GetStartState();
  return OK;
}

int ProxyScriptDecider::DoQuickCheck() {
  DCHECK(quick_check_enabled_);
  if (host_resolver_.get() == NULL) {
    // If we have no resolver, skip QuickCheck altogether.
    next_state_ = GetStartState();
    return OK;
  }

  quick_check_start_time_ = base::Time::Now();
  std::string host = current_pac_source().url.host();
  HostResolver::RequestInfo reqinfo(HostPortPair(host, 80));
  reqinfo.set_host_resolver_flags(HOST_RESOLVER_SYSTEM_ONLY);
  CompletionCallback callback = base::Bind(
      &ProxyScriptDecider::OnIOCompletion,
      base::Unretained(this));

  next_state_ = STATE_QUICK_CHECK_COMPLETE;
  quick_check_timer_.Start(FROM_HERE,
                           base::TimeDelta::FromMilliseconds(
                              kQuickCheckDelayMs),
                           base::Bind(callback, ERR_NAME_NOT_RESOLVED));

  // We use HIGHEST here because proxy decision blocks doing any other requests.
  return host_resolver_->Resolve(reqinfo, HIGHEST, &wpad_addresses_,
                                 callback, net_log_);
}

int ProxyScriptDecider::DoQuickCheckComplete(int result) {
  DCHECK(quick_check_enabled_);
  base::TimeDelta delta = base::Time::Now() - quick_check_start_time_;
  if (result == OK)
    UMA_HISTOGRAM_TIMES("Net.WpadQuickCheckSuccess", delta);
  else
    UMA_HISTOGRAM_TIMES("Net.WpadQuickCheckFailure", delta);
  host_resolver_->Cancel();
  quick_check_timer_.Stop();
  if (result != OK)
    return TryToFallbackPacSource(result);
  next_state_ = GetStartState();
  return result;
}

int ProxyScriptDecider::DoFetchPacScript() {
  DCHECK(fetch_pac_bytes_);

  next_state_ = STATE_FETCH_PAC_SCRIPT_COMPLETE;

  const PacSource& pac_source = current_pac_source();

  GURL effective_pac_url;
  DetermineURL(pac_source, &effective_pac_url);

  net_log_.BeginEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT,
                      base::Bind(&PacSource::NetLogCallback,
                                 base::Unretained(&pac_source),
                                 &effective_pac_url));

  if (pac_source.type == PacSource::WPAD_DHCP) {
    if (!dhcp_proxy_script_fetcher_) {
      net_log_.AddEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_HAS_NO_FETCHER);
      return ERR_UNEXPECTED;
    }

    return dhcp_proxy_script_fetcher_->Fetch(
        &pac_script_, base::Bind(&ProxyScriptDecider::OnIOCompletion,
                                 base::Unretained(this)));
  }

  if (!proxy_script_fetcher_) {
    net_log_.AddEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_HAS_NO_FETCHER);
    return ERR_UNEXPECTED;
  }

  return proxy_script_fetcher_->Fetch(
      effective_pac_url, &pac_script_,
      base::Bind(&ProxyScriptDecider::OnIOCompletion, base::Unretained(this)));
}

int ProxyScriptDecider::DoFetchPacScriptComplete(int result) {
  DCHECK(fetch_pac_bytes_);

  net_log_.EndEventWithNetErrorCode(
      NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT, result);
  if (result != OK)
    return TryToFallbackPacSource(result);

  next_state_ = STATE_VERIFY_PAC_SCRIPT;
  return result;
}

int ProxyScriptDecider::DoVerifyPacScript() {
  next_state_ = STATE_VERIFY_PAC_SCRIPT_COMPLETE;

  // This is just a heuristic. Ideally we would try to parse the script.
  if (fetch_pac_bytes_ && !LooksLikePacScript(pac_script_))
    return ERR_PAC_SCRIPT_FAILED;

  return OK;
}

int ProxyScriptDecider::DoVerifyPacScriptComplete(int result) {
  if (result != OK)
    return TryToFallbackPacSource(result);

  const PacSource& pac_source = current_pac_source();

  // Extract the current script data.
  if (fetch_pac_bytes_) {
    script_data_ = ProxyResolverScriptData::FromUTF16(pac_script_);
  } else {
    script_data_ = pac_source.type == PacSource::CUSTOM ?
        ProxyResolverScriptData::FromURL(pac_source.url) :
        ProxyResolverScriptData::ForAutoDetect();
  }

  // Let the caller know which automatic setting we ended up initializing the
  // resolver for (there may have been multiple fallbacks to choose from.)
  if (current_pac_source().type == PacSource::CUSTOM) {
    effective_config_ =
        ProxyConfig::CreateFromCustomPacURL(current_pac_source().url);
    effective_config_.set_pac_mandatory(pac_mandatory_);
  } else {
    if (fetch_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();
    }
  }

  return OK;
}

int ProxyScriptDecider::TryToFallbackPacSource(int error) {
  DCHECK_LT(error, 0);

  if (current_pac_source_index_ + 1 >= pac_sources_.size()) {
    // Nothing left to fall back to.
    return error;
  }

  // Advance to next URL in our list.
  ++current_pac_source_index_;

  net_log_.AddEvent(
      NetLog::TYPE_PROXY_SCRIPT_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE);
  if (quick_check_enabled_ && current_pac_source().type == PacSource::WPAD_DNS)
    next_state_ = STATE_QUICK_CHECK;
  else
    next_state_ = GetStartState();

  return OK;
}

ProxyScriptDecider::State ProxyScriptDecider::GetStartState() const {
  return fetch_pac_bytes_ ?  STATE_FETCH_PAC_SCRIPT : STATE_VERIFY_PAC_SCRIPT;
}

void ProxyScriptDecider::DetermineURL(const PacSource& pac_source,
                                      GURL* effective_pac_url) {
  DCHECK(effective_pac_url);

  switch (pac_source.type) {
    case PacSource::WPAD_DHCP:
      break;
    case PacSource::WPAD_DNS:
      *effective_pac_url = GURL(kWpadUrl);
      break;
    case PacSource::CUSTOM:
      *effective_pac_url = pac_source.url;
      break;
  }
}

const ProxyScriptDecider::PacSource&
    ProxyScriptDecider::current_pac_source() const {
  DCHECK_LT(current_pac_source_index_, pac_sources_.size());
  return pac_sources_[current_pac_source_index_];
}

void ProxyScriptDecider::OnWaitTimerFired() {
  OnIOCompletion(OK);
}

void ProxyScriptDecider::DidComplete() {
  net_log_.EndEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER);
}

void ProxyScriptDecider::Cancel() {
  DCHECK_NE(STATE_NONE, next_state_);

  net_log_.AddEvent(NetLog::TYPE_CANCELLED);

  switch (next_state_) {
    case STATE_WAIT_COMPLETE:
      wait_timer_.Stop();
      break;
    case STATE_FETCH_PAC_SCRIPT_COMPLETE:
      proxy_script_fetcher_->Cancel();
      break;
    default:
      NOTREACHED();
      break;
  }

  // This is safe to call in any state.
  if (dhcp_proxy_script_fetcher_)
    dhcp_proxy_script_fetcher_->Cancel();

  DidComplete();
}

}  // namespace net
