| Index: net/proxy/proxy_service.cc
|
| ===================================================================
|
| --- net/proxy/proxy_service.cc (revision 22399)
|
| +++ net/proxy/proxy_service.cc (working copy)
|
| @@ -13,6 +13,7 @@
|
| #include "googleurl/src/gurl.h"
|
| #include "net/base/net_errors.h"
|
| #include "net/base/net_util.h"
|
| +#include "net/proxy/init_proxy_resolver.h"
|
| #include "net/proxy/proxy_config_service_fixed.h"
|
| #include "net/proxy/proxy_script_fetcher.h"
|
| #if defined(OS_WIN)
|
| @@ -61,7 +62,11 @@
|
| }
|
|
|
| private:
|
| - virtual void SetPacScriptByUrlInternal(const GURL& pac_url) {}
|
| + virtual int SetPacScript(const GURL& /*pac_url*/,
|
| + const std::string& /*pac_bytes*/,
|
| + CompletionCallback* /*callback*/) {
|
| + return ERR_NOT_IMPLEMENTED;
|
| + }
|
| };
|
|
|
| // ProxyService::PacRequest ---------------------------------------------------
|
| @@ -100,19 +105,26 @@
|
| return !!resolve_job_;
|
| }
|
|
|
| - void StartAndComplete() {
|
| - int rv = Start();
|
| + void StartAndCompleteCheckingForSynchronous() {
|
| + int rv = service_->TryToCompleteSynchronously(url_, results_);
|
| + if (rv == ERR_IO_PENDING)
|
| + rv = Start();
|
| if (rv != ERR_IO_PENDING)
|
| QueryComplete(rv);
|
| }
|
|
|
| - void Cancel() {
|
| + void CancelResolveJob() {
|
| // The request may already be running in the resolver.
|
| if (is_started()) {
|
| resolver()->CancelRequest(resolve_job_);
|
| resolve_job_ = NULL;
|
| }
|
| + DCHECK(!is_started());
|
| + }
|
|
|
| + void Cancel() {
|
| + CancelResolveJob();
|
| +
|
| // Mark as cancelled, to prevent accessing this again later.
|
| service_ = NULL;
|
| user_callback_ = NULL;
|
| @@ -177,11 +189,8 @@
|
| resolver_(resolver),
|
| next_config_id_(1),
|
| config_is_bad_(false),
|
| - ALLOW_THIS_IN_INITIALIZER_LIST(proxy_script_fetcher_callback_(
|
| - this, &ProxyService::OnScriptFetchCompletion)),
|
| - fetched_pac_config_id_(ProxyConfig::INVALID_ID),
|
| - fetched_pac_error_(OK),
|
| - in_progress_fetch_config_id_(ProxyConfig::INVALID_ID) {
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(init_proxy_resolver_callback_(
|
| + this, &ProxyService::OnInitProxyResolverComplete)) {
|
| }
|
|
|
| // static
|
| @@ -254,7 +263,7 @@
|
|
|
| scoped_refptr<PacRequest> req = new PacRequest(this, url, result, callback);
|
|
|
| - bool resolver_is_ready = PrepareResolverForRequests();
|
| + bool resolver_is_ready = !IsInitializingProxyResolver();
|
|
|
| if (resolver_is_ready) {
|
| // Start the resolve request.
|
| @@ -290,22 +299,15 @@
|
| // Remember that we are trying to use the current proxy configuration.
|
| result->config_was_tried_ = true;
|
|
|
| + if (config_.MayRequirePACResolver()) {
|
| + // Need to go through ProxyResolver for this.
|
| + return ERR_IO_PENDING;
|
| + }
|
| +
|
| if (!config_.proxy_rules.empty()) {
|
| ApplyProxyRules(url, config_.proxy_rules, result);
|
| return OK;
|
| }
|
| -
|
| - if (config_.pac_url.is_valid() || config_.auto_detect) {
|
| - // If we failed to download the PAC script, return the network error
|
| - // from the failed download. This is only going to happen for the first
|
| - // request after the failed download -- after that |config_is_bad_| will
|
| - // be set to true, so we short-cuircuit sooner.
|
| - if (fetched_pac_error_ != OK && !IsFetchingPacScript()) {
|
| - DidCompletePacRequest(fetched_pac_config_id_, fetched_pac_error_);
|
| - return fetched_pac_error_;
|
| - }
|
| - return ERR_IO_PENDING;
|
| - }
|
| }
|
|
|
| // otherwise, we have no proxy config
|
| @@ -354,7 +356,17 @@
|
| }
|
| }
|
|
|
| +void ProxyService::SuspendAllPendingRequests() {
|
| + for (PendingRequests::iterator it = pending_requests_.begin();
|
| + it != pending_requests_.end();
|
| + ++it) {
|
| + it->get()->CancelResolveJob();
|
| + }
|
| +}
|
| +
|
| void ProxyService::ResumeAllPendingRequests() {
|
| + DCHECK(!IsInitializingProxyResolver());
|
| +
|
| // Make a copy in case |this| is deleted during the synchronous completion
|
| // of one of the requests. If |this| is deleted then all of the PacRequest
|
| // instances will be Cancel()-ed.
|
| @@ -364,57 +376,27 @@
|
| it != pending_copy.end();
|
| ++it) {
|
| PacRequest* req = it->get();
|
| - if (!req->is_started() && !req->was_cancelled())
|
| - req->StartAndComplete();
|
| + if (!req->is_started() && !req->was_cancelled()) {
|
| + // Note that we re-check for synchronous completion, in case we are
|
| + // no longer using a ProxyResolver (can happen if we fell-back to manual).
|
| + req->StartAndCompleteCheckingForSynchronous();
|
| + }
|
| }
|
| }
|
|
|
| -bool ProxyService::PrepareResolverForRequests() {
|
| - // While the PAC script is being downloaded, block requests.
|
| - if (IsFetchingPacScript())
|
| - return false;
|
| +void ProxyService::OnInitProxyResolverComplete(int result) {
|
| + DCHECK(init_proxy_resolver_.get());
|
| + DCHECK(config_.MayRequirePACResolver());
|
| + init_proxy_resolver_.reset();
|
|
|
| - // Check if a new PAC script needs to be downloaded.
|
| - DCHECK(config_.id() != ProxyConfig::INVALID_ID);
|
| - if (resolver_->expects_pac_bytes() &&
|
| - config_.id() != fetched_pac_config_id_) {
|
| - // For auto-detect we use the well known WPAD url.
|
| - GURL pac_url = config_.auto_detect ?
|
| - GURL("http://wpad/wpad.dat") : config_.pac_url;
|
| -
|
| - in_progress_fetch_config_id_ = config_.id();
|
| -
|
| - LOG(INFO) << "Starting fetch of PAC script " << pac_url
|
| - << " for config_id=" << in_progress_fetch_config_id_;
|
| -
|
| - proxy_script_fetcher_->Fetch(
|
| - pac_url, &in_progress_fetch_bytes_, &proxy_script_fetcher_callback_);
|
| - return false;
|
| + if (result != OK) {
|
| + LOG(INFO) << "Failed configuring with PAC script, falling-back to manual "
|
| + "proxy servers.";
|
| + config_.auto_detect = false;
|
| + config_.pac_url = GURL();
|
| + DCHECK(!config_.MayRequirePACResolver());
|
| }
|
|
|
| - // We are good to go.
|
| - return true;
|
| -}
|
| -
|
| -void ProxyService::OnScriptFetchCompletion(int result) {
|
| - DCHECK(IsFetchingPacScript());
|
| - DCHECK(resolver_->expects_pac_bytes());
|
| -
|
| - LOG(INFO) << "Completed PAC script fetch for config_id="
|
| - << in_progress_fetch_config_id_
|
| - << " with error " << ErrorToString(result)
|
| - << ". Fetched a total of " << in_progress_fetch_bytes_.size()
|
| - << " bytes";
|
| -
|
| - // Notify the ProxyResolver of the new script data (will be empty string if
|
| - // result != OK).
|
| - resolver_->SetPacScriptByData(in_progress_fetch_bytes_);
|
| -
|
| - fetched_pac_config_id_ = in_progress_fetch_config_id_;
|
| - fetched_pac_error_ = result;
|
| - in_progress_fetch_config_id_ = ProxyConfig::INVALID_ID;
|
| - in_progress_fetch_bytes_.clear();
|
| -
|
| // Resume any requests which we had to defer until the PAC script was
|
| // downloaded.
|
| ResumeAllPendingRequests();
|
| @@ -455,6 +437,8 @@
|
| if (!was_direct && result->Fallback(&proxy_retry_info_))
|
| return OK;
|
|
|
| + // TODO(eroman): Hmm, this doesn't seem right. For starters just because
|
| + // auto_detect is true doesn't mean we are actually using it.
|
| if (!config_.auto_detect && !config_.proxy_rules.empty()) {
|
| // If auto detect is on, then we should try a DIRECT connection
|
| // as the attempt to reach the proxy failed.
|
| @@ -587,13 +571,24 @@
|
| config_is_bad_ = false;
|
| proxy_retry_info_.clear();
|
|
|
| - // Tell the resolver to use the new PAC URL (for resolvers that fetch the
|
| - // PAC script internally).
|
| - // TODO(eroman): this isn't quite right. See http://crbug.com/9985
|
| - if ((config_.pac_url.is_valid() || config_.auto_detect) &&
|
| - !resolver_->expects_pac_bytes()) {
|
| - const GURL pac_url = config_.auto_detect ? GURL() : config_.pac_url;
|
| - resolver_->SetPacScriptByUrl(pac_url);
|
| + // Cancel any PAC fetching / ProxyResolver::SetPacScript() which was
|
| + // in progress for the previous configuration.
|
| + init_proxy_resolver_.reset();
|
| +
|
| + // Start downloading + testing the PAC scripts for this new configuration.
|
| + if (config_.MayRequirePACResolver()) {
|
| + // Since InitProxyResolver will be playing around with the proxy resolver
|
| + // as it tests the parsing of various PAC scripts, make sure there is
|
| + // nothing in-flight in |resolver_|. These paused requests are resumed by
|
| + // OnInitProxyResolverComplete().
|
| + SuspendAllPendingRequests();
|
| +
|
| + init_proxy_resolver_.reset(
|
| + new InitProxyResolver(resolver_.get(), proxy_script_fetcher_.get()));
|
| + int rv = init_proxy_resolver_->Init(
|
| + config_, &init_proxy_resolver_callback_);
|
| + if (rv != ERR_IO_PENDING)
|
| + OnInitProxyResolverComplete(rv);
|
| }
|
| }
|
|
|
|
|