diff options
-rw-r--r-- | chrome/browser/chromeos/dbus/proxy_resolution_service_provider.cc | 9 | ||||
-rw-r--r-- | net/proxy/proxy_service.cc | 92 | ||||
-rw-r--r-- | net/proxy/proxy_service.h | 5 |
3 files changed, 94 insertions, 12 deletions
diff --git a/chrome/browser/chromeos/dbus/proxy_resolution_service_provider.cc b/chrome/browser/chromeos/dbus/proxy_resolution_service_provider.cc index f003ea0..83361a2 100644 --- a/chrome/browser/chromeos/dbus/proxy_resolution_service_provider.cc +++ b/chrome/browser/chromeos/dbus/proxy_resolution_service_provider.cc @@ -5,6 +5,7 @@ #include "chrome/browser/chromeos/dbus/proxy_resolution_service_provider.h" #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/threading/platform_thread.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile_manager.h" @@ -28,8 +29,8 @@ class ProxyResolverImpl : public ProxyResolverInterface { class Request { public: explicit Request(const std::string& source_url) - : ALLOW_THIS_IN_INITIALIZER_LIST( - completion_callback_(this, &Request::OnCompletion)), + : ALLOW_THIS_IN_INITIALIZER_LIST(callback_( + base::Bind(&Request::OnCompletion, base::Unretained(this)))), source_url_(source_url) { } @@ -46,7 +47,7 @@ class ProxyResolverImpl : public ProxyResolverInterface { BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, notify_task_); } - net::OldCompletionCallbackImpl<Request> completion_callback_; + net::CompletionCallback callback_; std::string source_url_; // URL being resolved. net::ProxyInfo proxy_info_; // ProxyInfo resolved for source_url_. @@ -135,7 +136,7 @@ class ProxyResolverImpl : public ProxyResolverInterface { << request->source_url_; const int result = proxy_service->ResolveProxy( GURL(request->source_url_), &request->proxy_info_, - &request->completion_callback_, NULL, net::BoundNetLog()); + request->callback_, NULL, net::BoundNetLog()); if (result != net::ERR_IO_PENDING) { VLOG(1) << "Network proxy resolution completed synchronously."; request->OnCompletion(result); diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc index 892d0f7..e6d4b4f 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_); diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h index ff5012f..fe81f54 100644 --- a/net/proxy/proxy_service.h +++ b/net/proxy/proxy_service.h @@ -79,6 +79,11 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver, OldCompletionCallback* callback, PacRequest** pac_request, const BoundNetLog& net_log); + int ResolveProxy(const GURL& url, + ProxyInfo* results, + const net::CompletionCallback& callback, + PacRequest** pac_request, + const BoundNetLog& net_log); // This method is called after a failure to connect or resolve a host name. // It gives the proxy service an opportunity to reconsider the proxy to use. |