| Index: net/proxy/proxy_service.cc
|
| diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
|
| index 892d0f74ba61f2d24a28321c279c52b442d1e481..e6d4b4fbbd32ac0a62f5c3591b62cecd16e64f98 100644
|
| --- a/net/proxy/proxy_service.cc
|
| +++ b/net/proxy/proxy_service.cc
|
| @@ -13,6 +13,7 @@
|
| #include "base/string_util.h"
|
| #include "base/values.h"
|
| #include "googleurl/src/gurl.h"
|
| +#include "net/base/completion_callback.h"
|
| #include "net/base/net_errors.h"
|
| #include "net/base/net_log.h"
|
| #include "net/base/net_util.h"
|
| @@ -324,7 +325,7 @@ class ProxyService::PacRequest
|
| OldCompletionCallback* user_callback,
|
| const BoundNetLog& net_log)
|
| : service_(service),
|
| - user_callback_(user_callback),
|
| + old_user_callback_(user_callback),
|
| ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_(
|
| this, &PacRequest::QueryComplete)),
|
| results_(results),
|
| @@ -335,6 +336,24 @@ class ProxyService::PacRequest
|
| DCHECK(user_callback);
|
| }
|
|
|
| + PacRequest(ProxyService* service,
|
| + const GURL& url,
|
| + ProxyInfo* results,
|
| + const net::CompletionCallback& user_callback,
|
| + const BoundNetLog& net_log)
|
| + : service_(service),
|
| + old_user_callback_(NULL),
|
| + user_callback_(user_callback),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_(
|
| + this, &PacRequest::QueryComplete)),
|
| + results_(results),
|
| + url_(url),
|
| + resolve_job_(NULL),
|
| + config_id_(ProxyConfig::kInvalidConfigID),
|
| + net_log_(net_log) {
|
| + DCHECK(!user_callback.is_null());
|
| + }
|
| +
|
| // Starts the resolve proxy request.
|
| int Start() {
|
| DCHECK(!was_cancelled());
|
| @@ -377,14 +396,17 @@ class ProxyService::PacRequest
|
|
|
| // Mark as cancelled, to prevent accessing this again later.
|
| service_ = NULL;
|
| - user_callback_ = NULL;
|
| + old_user_callback_ = NULL;
|
| + user_callback_.Reset();
|
| results_ = NULL;
|
|
|
| net_log_.EndEvent(NetLog::TYPE_PROXY_SERVICE, NULL);
|
| }
|
|
|
| // Returns true if Cancel() has been called.
|
| - bool was_cancelled() const { return user_callback_ == NULL; }
|
| + bool was_cancelled() const {
|
| + return old_user_callback_ == NULL && user_callback_.is_null();
|
| + }
|
|
|
| // Helper to call after ProxyResolver completion (both synchronous and
|
| // asynchronous). Fixes up the result that is to be returned to user.
|
| @@ -421,10 +443,15 @@ class ProxyService::PacRequest
|
|
|
| // Remove this completed PacRequest from the service's pending list.
|
| /// (which will probably cause deletion of |this|).
|
| - OldCompletionCallback* callback = user_callback_;
|
| - service_->RemovePendingRequest(this);
|
| -
|
| - callback->Run(result_code);
|
| + if (old_user_callback_) {
|
| + OldCompletionCallback* callback = old_user_callback_;
|
| + service_->RemovePendingRequest(this);
|
| + callback->Run(result_code);
|
| + } else if (!user_callback_.is_null()){
|
| + net::CompletionCallback callback = user_callback_;
|
| + service_->RemovePendingRequest(this);
|
| + callback.Run(result_code);
|
| + }
|
| }
|
|
|
| ProxyResolver* resolver() const { return service_->resolver_.get(); }
|
| @@ -433,7 +460,8 @@ class ProxyService::PacRequest
|
| // requests are cancelled during ~ProxyService, so this is guaranteed
|
| // to be valid throughout our lifetime.
|
| ProxyService* service_;
|
| - OldCompletionCallback* user_callback_;
|
| + OldCompletionCallback* old_user_callback_;
|
| + net::CompletionCallback user_callback_;
|
| OldCompletionCallbackImpl<PacRequest> io_callback_;
|
| ProxyInfo* results_;
|
| GURL url_;
|
| @@ -620,6 +648,54 @@ int ProxyService::ResolveProxy(const GURL& raw_url,
|
| return rv; // ERR_IO_PENDING
|
| }
|
|
|
| +int ProxyService::ResolveProxy(const GURL& raw_url,
|
| + ProxyInfo* result,
|
| + const net::CompletionCallback& callback,
|
| + PacRequest** pac_request,
|
| + const BoundNetLog& net_log) {
|
| + DCHECK(CalledOnValidThread());
|
| + DCHECK(!callback.is_null());
|
| +
|
| + net_log.BeginEvent(NetLog::TYPE_PROXY_SERVICE, NULL);
|
| +
|
| + config_service_->OnLazyPoll();
|
| + if (current_state_ == STATE_NONE)
|
| + ApplyProxyConfigIfAvailable();
|
| +
|
| + // Strip away any reference fragments and the username/password, as they
|
| + // are not relevant to proxy resolution.
|
| + GURL url = SimplifyUrlForRequest(raw_url);
|
| +
|
| + // Check if the request can be completed right away. (This is the case when
|
| + // using a direct connection for example).
|
| + int rv = TryToCompleteSynchronously(url, result);
|
| + if (rv != ERR_IO_PENDING)
|
| + return DidFinishResolvingProxy(result, rv, net_log);
|
| +
|
| + scoped_refptr<PacRequest> req(
|
| + new PacRequest(this, url, result, callback, net_log));
|
| +
|
| + if (current_state_ == STATE_READY) {
|
| + // Start the resolve request.
|
| + rv = req->Start();
|
| + if (rv != ERR_IO_PENDING)
|
| + return req->QueryDidComplete(rv);
|
| + } else {
|
| + req->net_log()->BeginEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC,
|
| + NULL);
|
| + }
|
| +
|
| + DCHECK_EQ(ERR_IO_PENDING, rv);
|
| + DCHECK(!ContainsPendingRequest(req));
|
| + pending_requests_.push_back(req);
|
| +
|
| + // Completion will be notified through |callback|, unless the caller cancels
|
| + // the request using |pac_request|.
|
| + if (pac_request)
|
| + *pac_request = req.get();
|
| + return rv; // ERR_IO_PENDING
|
| +}
|
| +
|
| int ProxyService::TryToCompleteSynchronously(const GURL& url,
|
| ProxyInfo* result) {
|
| DCHECK_NE(STATE_NONE, current_state_);
|
|
|