summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/login/login_utils.cc8
-rw-r--r--chrome/browser/net/preconnect.cc54
-rw-r--r--chrome/browser/net/preconnect.h48
-rw-r--r--chrome/browser/net/predictor.cc17
-rw-r--r--net/http/http_request_info.h9
-rw-r--r--net/http/stream_factory.h3
-rw-r--r--net/socket/client_socket_pool_base.cc1
7 files changed, 67 insertions, 73 deletions
diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc
index 270de35..d741caf 100644
--- a/chrome/browser/chromeos/login/login_utils.cc
+++ b/chrome/browser/chromeos/login/login_utils.cc
@@ -416,9 +416,11 @@ class WarmingObserver : public NetworkLibrary::NetworkManagerObserver {
// If we're now connected, prewarm the auth url.
void OnNetworkManagerChanged(NetworkLibrary* netlib) {
if (netlib->Connected()) {
+ const int kConnectionsNeeded = 1;
chrome_browser_net::Preconnect::PreconnectOnUIThread(
GURL(GaiaAuthFetcher::kClientLoginUrl),
- chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED);
+ chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED,
+ kConnectionsNeeded);
netlib->RemoveNetworkManagerObserver(this);
delete this;
}
@@ -429,9 +431,11 @@ void LoginUtilsImpl::PrewarmAuthentication() {
if (CrosLibrary::Get()->EnsureLoaded()) {
NetworkLibrary *network = CrosLibrary::Get()->GetNetworkLibrary();
if (network->Connected()) {
+ const int kConnectionsNeeded = 1;
chrome_browser_net::Preconnect::PreconnectOnUIThread(
GURL(GaiaAuthFetcher::kClientLoginUrl),
- chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED);
+ chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED,
+ kConnectionsNeeded);
} else {
new WarmingObserver();
}
diff --git a/chrome/browser/net/preconnect.cc b/chrome/browser/net/preconnect.cc
index 307f20f..5946c85 100644
--- a/chrome/browser/net/preconnect.cc
+++ b/chrome/browser/net/preconnect.cc
@@ -6,45 +6,44 @@
#include "base/logging.h"
#include "base/metrics/histogram.h"
-#include "base/string_util.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/common/net/url_request_context_getter.h"
-#include "net/base/host_port_pair.h"
#include "net/http/http_network_session.h"
-#include "net/http/http_request_info.h"
-#include "net/http/http_stream.h"
#include "net/http/http_transaction_factory.h"
-#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_context.h"
namespace chrome_browser_net {
// static
void Preconnect::PreconnectOnUIThread(const GURL& url,
- UrlInfo::ResolutionMotivation motivation) {
+ UrlInfo::ResolutionMotivation motivation, int count) {
// Prewarm connection to Search URL.
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
- NewRunnableFunction(Preconnect::PreconnectOnIOThread, url, motivation));
+ NewRunnableFunction(Preconnect::PreconnectOnIOThread, url, motivation,
+ count));
return;
}
// static
void Preconnect::PreconnectOnIOThread(const GURL& url,
- UrlInfo::ResolutionMotivation motivation) {
+ UrlInfo::ResolutionMotivation motivation, int count) {
Preconnect* preconnect = new Preconnect(motivation);
// TODO(jar): Should I use PostTask for LearnedSubresources to delay the
// preconnection a tad?
- preconnect->Connect(url);
+ preconnect->Connect(url, count);
}
Preconnect::Preconnect(UrlInfo::ResolutionMotivation motivation)
- : motivation_(motivation) {}
+ : motivation_(motivation),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ io_callback_(this, &Preconnect::OnPreconnectComplete)) {}
+
Preconnect::~Preconnect() {}
-void Preconnect::Connect(const GURL& url) {
+void Preconnect::Connect(const GURL& url, int count) {
URLRequestContextGetter* getter = Profile::GetDefaultRequestContext();
if (!getter)
return;
@@ -87,6 +86,7 @@ void Preconnect::Connect(const GURL& url) {
request_info_->motivation = net::HttpRequestInfo::PRECONNECT_MOTIVATED;
break;
case UrlInfo::EARLY_LOAD_MOTIVATED:
+ request_info_->motivation = net::HttpRequestInfo::EARLY_LOAD_MOTIVATED;
break;
default:
// Other motivations should never happen here.
@@ -105,32 +105,16 @@ void Preconnect::Connect(const GURL& url) {
proxy_info_.reset(new net::ProxyInfo());
net::StreamFactory* stream_factory = session->http_stream_factory();
- stream_request_.reset(
- stream_factory->RequestStream(request_info_.get(), ssl_config_.get(),
- proxy_info_.get(), session, this,
- net_log_));
-}
-
-void Preconnect::OnStreamReady(net::HttpStream* stream) {
- delete stream;
- delete this;
-}
-
-void Preconnect::OnStreamFailed(int status) {
- delete this;
-}
-
-void Preconnect::OnCertificateError(int status, const net::SSLInfo& ssl_info) {
- delete this;
-}
-
-void Preconnect::OnNeedsProxyAuth(const net::HttpResponseInfo& proxy_response,
- net::HttpAuthController* auth_controller) {
- delete this;
+ int rv = stream_factory->PreconnectStreams(count, request_info_.get(),
+ ssl_config_.get(),
+ proxy_info_.get(), session,
+ net_log_, &io_callback_);
+ if (rv != net::ERR_IO_PENDING)
+ delete this;
}
-void Preconnect::OnNeedsClientAuth(net::SSLCertRequestInfo* cert_info) {
+void Preconnect::OnPreconnectComplete(int error_code) {
delete this;
}
-} // chrome_browser_net
+} // namespace chrome_browser_net
diff --git a/chrome/browser/net/preconnect.h b/chrome/browser/net/preconnect.h
index 333e0bb..a950167 100644
--- a/chrome/browser/net/preconnect.h
+++ b/chrome/browser/net/preconnect.h
@@ -9,55 +9,51 @@
#define CHROME_BROWSER_NET_PRECONNECT_H_
#pragma once
-#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/net/url_info.h"
-#include "net/base/host_port_pair.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_log.h"
#include "net/http/http_request_info.h"
#include "net/http/stream_factory.h"
-#include "net/socket/client_socket_handle.h"
-#include "net/socket/tcp_client_socket_pool.h"
-#include "net/url_request/url_request_context.h"
namespace net {
class ProxyInfo;
struct SSLConfig;
-}
+} // namespace net
namespace chrome_browser_net {
-class Preconnect : public net::StreamRequest::Delegate {
+class Preconnect {
public:
// Try to preconnect. Typically motivated by OMNIBOX to reach search service.
+ // |count| may be used to request more than one connection be established in
+ // parallel.
static void PreconnectOnUIThread(const GURL& url,
- UrlInfo::ResolutionMotivation motivation);
+ UrlInfo::ResolutionMotivation motivation,
+ int count);
// Try to preconnect. Typically used by predictor when a subresource probably
- // needs a connection.
+ // needs a connection. |count| may be used to request more than one connection
+ // be established in parallel.
static void PreconnectOnIOThread(const GURL& url,
- UrlInfo::ResolutionMotivation motivation);
-
- // StreamRequestDelegate interface
- virtual void OnStreamReady(net::HttpStream* stream);
- virtual void OnStreamFailed(int status);
- virtual void OnCertificateError(int status, const net::SSLInfo& ssl_info);
- virtual void OnNeedsProxyAuth(const net::HttpResponseInfo& proxy_response,
- net::HttpAuthController* auth_controller);
- virtual void OnNeedsClientAuth(net::SSLCertRequestInfo* cert_info);
+ UrlInfo::ResolutionMotivation motivation,
+ int count);
private:
- friend class base::RefCountedThreadSafe<Preconnect>;
-
explicit Preconnect(UrlInfo::ResolutionMotivation motivation);
virtual ~Preconnect();
- // Request actual connection.
- void Connect(const GURL& url);
+ void OnPreconnectComplete(int error_code);
- // Generally either LEARNED_REFERAL_MOTIVATED or OMNIBOX_MOTIVATED to indicate
- // why we were trying to do a preconnection.
+ // Request actual connection, via interface that tags request as needed for
+ // preconnect only (so that they can be merged with connections needed for
+ // navigations).
+ void Connect(const GURL& url, int count);
+
+ // Generally either LEARNED_REFERAL_MOTIVATED, OMNIBOX_MOTIVATED or
+ // EARLY_LOAD_MOTIVATED to indicate why we were trying to do a preconnection.
const UrlInfo::ResolutionMotivation motivation_;
// HttpRequestInfo used for connecting.
@@ -75,9 +71,11 @@ class Preconnect : public net::StreamRequest::Delegate {
// Our preconnect.
scoped_ptr<net::StreamRequest> stream_request_;
+ net::CompletionCallbackImpl<Preconnect> io_callback_;
+
DISALLOW_COPY_AND_ASSIGN(Preconnect);
};
-} // chrome_browser_net
+} // namespace chrome_browser_net
#endif // CHROME_BROWSER_NET_PRECONNECT_H_
diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc
index 2c8ce5f..46dcf1f 100644
--- a/chrome/browser/net/predictor.cc
+++ b/chrome/browser/net/predictor.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/net/predictor.h"
#include <algorithm>
+#include <cmath>
#include <set>
#include <sstream>
@@ -182,8 +183,9 @@ void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) {
kMaxSearchKeepaliveSeconds)
return; // We've done a preconnect recently.
last_omnibox_preconnect_ = now;
-
- Preconnect::PreconnectOnUIThread(CanonicalizeUrl(url), motivation);
+ const int kConnectionsNeeded = 1;
+ Preconnect::PreconnectOnUIThread(CanonicalizeUrl(url), motivation,
+ kConnectionsNeeded);
return; // Skip pre-resolution, since we'll open a connection.
}
} else {
@@ -215,7 +217,9 @@ void Predictor::PreconnectUrlAndSubresources(const GURL& url) {
if (preconnect_enabled()) {
std::string host = url.HostNoBrackets();
UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED);
- Preconnect::PreconnectOnUIThread(CanonicalizeUrl(url), motivation);
+ const int kConnectionsNeeded = 1;
+ Preconnect::PreconnectOnUIThread(CanonicalizeUrl(url), motivation,
+ kConnectionsNeeded);
PredictFrameSubresources(url.GetWithEmptyPath());
}
}
@@ -250,11 +254,12 @@ void Predictor::PrepareFrameSubresources(const GURL& url) {
10, 5000, 50);
future_url->second.ReferrerWasObserved();
if (preconnect_enabled_ &&
- kPreconnectWorthyExpectedValue < connection_expectation) {
+ connection_expectation > kPreconnectWorthyExpectedValue) {
evalution = PRECONNECTION;
future_url->second.IncrementPreconnectionCount();
- Preconnect::PreconnectOnIOThread(future_url->first, motivation);
- } else if (kDNSPreresolutionWorthyExpectedValue < connection_expectation) {
+ int count = static_cast<int>(std::ceil(connection_expectation));
+ Preconnect::PreconnectOnIOThread(future_url->first, motivation, count);
+ } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) {
evalution = PRERESOLUTION;
future_url->second.preresolution_increment();
UrlInfo* queued_info = AppendToResolutionQueue(future_url->first,
diff --git a/net/http/http_request_info.h b/net/http/http_request_info.h
index f740d7c..7c73aa6 100644
--- a/net/http/http_request_info.h
+++ b/net/http/http_request_info.h
@@ -18,9 +18,12 @@ namespace net {
struct HttpRequestInfo {
enum RequestMotivation{
// TODO(mbelshe): move these into Client Socket.
- PRECONNECT_MOTIVATED, // This request was motivated by a prefetch.
- OMNIBOX_MOTIVATED, // This request was motivated by the omnibox.
- NORMAL_MOTIVATION // No special motivation associated with the request.
+ PRECONNECT_MOTIVATED, // Request was motivated by a prefetch.
+ OMNIBOX_MOTIVATED, // Request was motivated by the omnibox.
+ NORMAL_MOTIVATION, // No special motivation associated with the request.
+ EARLY_LOAD_MOTIVATED, // When browser asks a tab to open an URL, this short
+ // circuits that path (of waiting for the renderer to
+ // do the URL request), and starts loading ASAP.
};
HttpRequestInfo();
diff --git a/net/http/stream_factory.h b/net/http/stream_factory.h
index 480df06..94b3cc8 100644
--- a/net/http/stream_factory.h
+++ b/net/http/stream_factory.h
@@ -122,7 +122,8 @@ class StreamFactory {
// Requests that enough connections for |num_streams| be opened. If
// ERR_IO_PENDING is returned, |info|, |ssl_config|, and |proxy_info| must
- // be kept alive until |callback| is invoked.
+ // be kept alive until |callback| is invoked. That callback will be given the
+ // final error code.
virtual int PreconnectStreams(int num_streams,
const HttpRequestInfo* info,
SSLConfig* ssl_config,
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc
index 2228729..02ac587 100644
--- a/net/socket/client_socket_pool_base.cc
+++ b/net/socket/client_socket_pool_base.cc
@@ -233,7 +233,6 @@ void ClientSocketPoolBaseHelper::RequestSockets(
DCHECK(!request.handle());
if (num_sockets > max_sockets_per_group_) {
- NOTREACHED();
num_sockets = max_sockets_per_group_;
}