summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/dbus/proxy_resolution_service_provider.cc9
-rw-r--r--net/proxy/proxy_service.cc92
-rw-r--r--net/proxy/proxy_service.h5
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.