summaryrefslogtreecommitdiffstats
path: root/chrome/browser/net
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/net')
-rw-r--r--chrome/browser/net/preconnect.cc29
-rw-r--r--chrome/browser/net/preconnect.h3
-rw-r--r--chrome/browser/net/predictor.cc39
-rw-r--r--chrome/browser/net/predictor.h8
-rw-r--r--chrome/browser/net/predictor_browsertest.cc85
-rw-r--r--chrome/browser/net/predictor_unittest.cc3
6 files changed, 133 insertions, 34 deletions
diff --git a/chrome/browser/net/preconnect.cc b/chrome/browser/net/preconnect.cc
index dfa91a3..17673c3 100644
--- a/chrome/browser/net/preconnect.cc
+++ b/chrome/browser/net/preconnect.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "content/public/browser/browser_thread.h"
+#include "net/base/load_flags.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_info.h"
#include "net/http/http_stream_factory.h"
@@ -30,20 +31,18 @@ void PreconnectOnUIThread(
net::URLRequestContextGetter* getter) {
// Prewarm connection to Search URL.
BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
+ BrowserThread::IO, FROM_HERE,
base::Bind(&PreconnectOnIOThread, url, first_party_for_cookies,
- motivation, count, make_scoped_refptr(getter)));
+ motivation, count, make_scoped_refptr(getter), true));
return;
}
-
-void PreconnectOnIOThread(
- const GURL& url,
- const GURL& first_party_for_cookies,
- UrlInfo::ResolutionMotivation motivation,
- int count,
- net::URLRequestContextGetter* getter) {
+void PreconnectOnIOThread(const GURL& url,
+ const GURL& first_party_for_cookies,
+ UrlInfo::ResolutionMotivation motivation,
+ int count,
+ net::URLRequestContextGetter* getter,
+ bool allow_credentials) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
LOG(DFATAL) << "This must be run only on the IO thread.";
return;
@@ -71,6 +70,16 @@ void PreconnectOnIOThread(
if (delegate->CanEnablePrivacyMode(url, first_party_for_cookies))
request_info.privacy_mode = net::PRIVACY_MODE_ENABLED;
+ // TODO(yoav): Fix this layering violation, since when credentials are not
+ // allowed we should turn on a flag indicating that, rather then turn on
+ // private mode, even if lower layers would treat both the same.
+ if (!allow_credentials) {
+ request_info.privacy_mode = net::PRIVACY_MODE_ENABLED;
+ request_info.load_flags = net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SAVE_COOKIES |
+ net::LOAD_DO_NOT_SEND_AUTH_DATA;
+ }
+
// Translate the motivation from UrlRequest motivations to HttpRequest
// motivations.
switch (motivation) {
diff --git a/chrome/browser/net/preconnect.h b/chrome/browser/net/preconnect.h
index 6e8442c..72718c1 100644
--- a/chrome/browser/net/preconnect.h
+++ b/chrome/browser/net/preconnect.h
@@ -34,7 +34,8 @@ void PreconnectOnIOThread(const GURL& url,
const GURL& first_party_for_cookies,
UrlInfo::ResolutionMotivation motivation,
int count,
- net::URLRequestContextGetter* getter);
+ net::URLRequestContextGetter* getter,
+ bool allow_credentials);
} // namespace chrome_browser_net
diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc
index d18979a..c435a8c 100644
--- a/chrome/browser/net/predictor.cc
+++ b/chrome/browser/net/predictor.cc
@@ -87,6 +87,9 @@ const int Predictor::kMaxSpeculativeResolveQueueDelayMs =
(kExpectedResolutionTimeMs * Predictor::kTypicalSpeculativeGroupSize) /
Predictor::kMaxSpeculativeParallelResolves;
+// The default value of the credentials flag when preconnecting.
+static bool kAllowCredentialsOnPreconnectByDefault = true;
+
static int g_max_queueing_delay_ms =
Predictor::kMaxSpeculativeResolveQueueDelayMs;
static size_t g_max_parallel_resolves =
@@ -265,8 +268,9 @@ void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) {
return; // We've done a preconnect recently.
last_omnibox_preconnect_ = now;
const int kConnectionsNeeded = 1;
- PreconnectUrl(
- CanonicalizeUrl(url), GURL(), motivation, kConnectionsNeeded);
+ PreconnectUrl(CanonicalizeUrl(url), GURL(), motivation,
+ kAllowCredentialsOnPreconnectByDefault,
+ kConnectionsNeeded);
return; // Skip pre-resolution, since we'll open a connection.
}
} else {
@@ -305,8 +309,8 @@ void Predictor::PreconnectUrlAndSubresources(const GURL& url,
UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED);
const int kConnectionsNeeded = 1;
- PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies,
- motivation, kConnectionsNeeded);
+ PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies, motivation,
+ kConnectionsNeeded, kAllowCredentialsOnPreconnectByDefault);
PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies);
}
@@ -840,19 +844,20 @@ void Predictor::SaveDnsPrefetchStateForNextStartupAndTrim(
void Predictor::PreconnectUrl(const GURL& url,
const GURL& first_party_for_cookies,
UrlInfo::ResolutionMotivation motivation,
+ bool allow_credentials,
int count) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
BrowserThread::CurrentlyOn(BrowserThread::IO));
if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- PreconnectUrlOnIOThread(url, first_party_for_cookies, motivation, count);
+ PreconnectUrlOnIOThread(url, first_party_for_cookies, motivation,
+ allow_credentials, count);
} else {
BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&Predictor::PreconnectUrlOnIOThread,
- base::Unretained(this), url, first_party_for_cookies,
- motivation, count));
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&Predictor::PreconnectUrlOnIOThread, base::Unretained(this),
+ url, first_party_for_cookies, motivation, allow_credentials,
+ count));
}
}
@@ -860,6 +865,7 @@ void Predictor::PreconnectUrlOnIOThread(
const GURL& original_url,
const GURL& first_party_for_cookies,
UrlInfo::ResolutionMotivation motivation,
+ bool allow_credentials,
int count) {
// Skip the HSTS redirect.
GURL url = GetHSTSRedirectOnIOThread(original_url);
@@ -869,11 +875,8 @@ void Predictor::PreconnectUrlOnIOThread(
url, first_party_for_cookies, motivation, count);
}
- PreconnectOnIOThread(url,
- first_party_for_cookies,
- motivation,
- count,
- url_request_context_getter_.get());
+ PreconnectOnIOThread(url, first_party_for_cookies, motivation, count,
+ url_request_context_getter_.get(), allow_credentials);
}
void Predictor::PredictFrameSubresources(const GURL& url,
@@ -941,7 +944,8 @@ void Predictor::PrepareFrameSubresources(const GURL& original_url,
// provide a more carefully estimated preconnection count.
if (preconnect_enabled_) {
PreconnectUrlOnIOThread(url, first_party_for_cookies,
- UrlInfo::SELF_REFERAL_MOTIVATED, 2);
+ UrlInfo::SELF_REFERAL_MOTIVATED,
+ kAllowCredentialsOnPreconnectByDefault, 2);
}
return;
}
@@ -966,7 +970,8 @@ void Predictor::PrepareFrameSubresources(const GURL& original_url,
if (url.host() == future_url->first.host())
++count;
PreconnectUrlOnIOThread(future_url->first, first_party_for_cookies,
- motivation, count);
+ motivation,
+ kAllowCredentialsOnPreconnectByDefault, count);
} else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) {
evalution = PRERESOLUTION;
future_url->second.preresolution_increment();
diff --git a/chrome/browser/net/predictor.h b/chrome/browser/net/predictor.h
index d1983e3..8601ff0 100644
--- a/chrome/browser/net/predictor.h
+++ b/chrome/browser/net/predictor.h
@@ -242,12 +242,16 @@ class Predictor {
// May be called from either the IO or UI thread and will PostTask
// to the IO thread if necessary.
- void PreconnectUrl(const GURL& url, const GURL& first_party_for_cookies,
- UrlInfo::ResolutionMotivation motivation, int count);
+ void PreconnectUrl(const GURL& url,
+ const GURL& first_party_for_cookies,
+ UrlInfo::ResolutionMotivation motivation,
+ bool allow_credentials,
+ int count);
void PreconnectUrlOnIOThread(const GURL& url,
const GURL& first_party_for_cookies,
UrlInfo::ResolutionMotivation motivation,
+ bool allow_credentials,
int count);
// ------------- End IO thread methods.
diff --git a/chrome/browser/net/predictor_browsertest.cc b/chrome/browser/net/predictor_browsertest.cc
index c4ebc55..98cbab1 100644
--- a/chrome/browser/net/predictor_browsertest.cc
+++ b/chrome/browser/net/predictor_browsertest.cc
@@ -103,8 +103,16 @@ class ConnectionListener
private:
static uint16_t GetPort(
const net::test_server::StreamListenSocket& connection) {
+ // Get the remote port of the peer, since the local port will always be the
+ // port the test server is listening on. This isn't strictly correct - it's
+ // possible for multiple peers to connect with the same remote port but
+ // different remote IPs - but the tests here assume that connections to the
+ // test server (running on localhost) will always come from localhost, and
+ // thus the peer port is all thats needed to distinguish two connections.
+ // This also would be problematic if the OS reused ports, but that's not
+ // something to worry about for these tests.
net::IPEndPoint address;
- EXPECT_EQ(net::OK, connection.GetLocalAddress(&address));
+ EXPECT_EQ(net::OK, connection.GetPeerAddress(&address));
return address.port();
}
@@ -350,7 +358,7 @@ IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, MAYBE_DnsPrefetch) {
// Tests that preconnect warms up a socket connection to a test server.
// Note: This test uses a data URI to serve the preconnect hint, to make sure
// that the network stack doesn't just re-use its connection to the test server.
-IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, Preconnect) {
+IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, PreconnectNonCORS) {
GURL preconnect_url = embedded_test_server()->base_url();
std::string preconnect_content =
"<link rel=\"preconnect\" href=\"" + preconnect_url.spec() + "\">";
@@ -364,7 +372,7 @@ IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, Preconnect) {
// and that that socket is later used when fetching a resource.
// Note: This test uses a data URI to serve the preconnect hint, to make sure
// that the network stack doesn't just re-use its connection to the test server.
-IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, PreconnectAndUse) {
+IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, PreconnectAndFetchNonCORS) {
GURL preconnect_url = embedded_test_server()->base_url();
// First navigation to content with a preconnect hint.
std::string preconnect_content =
@@ -383,5 +391,76 @@ IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, PreconnectAndUse) {
EXPECT_EQ(1u, connection_listener_->GetReadSocketCount());
}
+// Tests that preconnect warms up a CORS connection to a test
+// server, and that socket is later used when fetching a CORS resource.
+// Note: This test uses a data URI to serve the preconnect hint, to make sure
+// that the network stack doesn't just re-use its connection to the test server.
+IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, PreconnectAndFetchCORS) {
+ GURL preconnect_url = embedded_test_server()->base_url();
+ // First navigation to content with a preconnect hint.
+ std::string preconnect_content = "<link rel=\"preconnect\" href=\"" +
+ preconnect_url.spec() + "\" crossorigin>";
+ NavigateToDataURLWithContent(preconnect_content);
+ connection_listener_->WaitUntilFirstConnectionAccepted();
+ EXPECT_EQ(1u, connection_listener_->GetAcceptedSocketCount());
+ EXPECT_EQ(0u, connection_listener_->GetReadSocketCount());
+
+ // Second navigation to content with a font.
+ std::string font_content = "<script>var font = new FontFace('FontA', 'url(" +
+ preconnect_url.spec() +
+ "test.woff2)');font.load();</script>";
+ NavigateToDataURLWithContent(font_content);
+ connection_listener_->WaitUntilFirstConnectionRead();
+ EXPECT_EQ(1u, connection_listener_->GetAcceptedSocketCount());
+ EXPECT_EQ(1u, connection_listener_->GetReadSocketCount());
+}
+
+// Tests that preconnect warms up a non-CORS connection to a test
+// server, but that socket is not used when fetching a CORS resource.
+// Note: This test uses a data URI to serve the preconnect hint, to make sure
+// that the network stack doesn't just re-use its connection to the test server.
+IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, PreconnectNonCORSAndFetchCORS) {
+ GURL preconnect_url = embedded_test_server()->base_url();
+ // First navigation to content with a preconnect hint.
+ std::string preconnect_content =
+ "<link rel=\"preconnect\" href=\"" + preconnect_url.spec() + "\">";
+ NavigateToDataURLWithContent(preconnect_content);
+ connection_listener_->WaitUntilFirstConnectionAccepted();
+ EXPECT_EQ(1u, connection_listener_->GetAcceptedSocketCount());
+ EXPECT_EQ(0u, connection_listener_->GetReadSocketCount());
+
+ // Second navigation to content with a font.
+ std::string font_content = "<script>var font = new FontFace('FontA', 'url(" +
+ preconnect_url.spec() +
+ "test.woff2)');font.load();</script>";
+ NavigateToDataURLWithContent(font_content);
+ connection_listener_->WaitUntilFirstConnectionRead();
+ EXPECT_EQ(2u, connection_listener_->GetAcceptedSocketCount());
+ EXPECT_EQ(1u, connection_listener_->GetReadSocketCount());
+}
+
+// Tests that preconnect warms up a CORS connection to a test server,
+// but that socket is not used when fetching a non-CORS resource.
+// Note: This test uses a data URI to serve the preconnect hint, to make sure
+// that the network stack doesn't just re-use its connection to the test server.
+IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, PreconnectCORSAndFetchNonCORS) {
+ GURL preconnect_url = embedded_test_server()->base_url();
+ // First navigation to content with a preconnect hint.
+ std::string preconnect_content = "<link rel=\"preconnect\" href=\"" +
+ preconnect_url.spec() + "\" crossorigin>";
+ NavigateToDataURLWithContent(preconnect_content);
+ connection_listener_->WaitUntilFirstConnectionAccepted();
+ EXPECT_EQ(1u, connection_listener_->GetAcceptedSocketCount());
+ EXPECT_EQ(0u, connection_listener_->GetReadSocketCount());
+
+ // Second navigation to content with an img.
+ std::string img_content =
+ "<img src=\"" + preconnect_url.spec() + "test.gif\">";
+ NavigateToDataURLWithContent(img_content);
+ connection_listener_->WaitUntilFirstConnectionRead();
+ EXPECT_EQ(2u, connection_listener_->GetAcceptedSocketCount());
+ EXPECT_EQ(1u, connection_listener_->GetReadSocketCount());
+}
+
} // namespace chrome_browser_net
diff --git a/chrome/browser/net/predictor_unittest.cc b/chrome/browser/net/predictor_unittest.cc
index 76c7333..61460ae 100644
--- a/chrome/browser/net/predictor_unittest.cc
+++ b/chrome/browser/net/predictor_unittest.cc
@@ -731,7 +731,8 @@ TEST_F(PredictorTest, HSTSRedirect) {
predictor.SetObserver(&observer);
predictor.SetTransportSecurityState(&state);
- predictor.PreconnectUrl(kHttpUrl, GURL(), UrlInfo::OMNIBOX_MOTIVATED, 2);
+ predictor.PreconnectUrl(kHttpUrl, GURL(), UrlInfo::OMNIBOX_MOTIVATED, true,
+ 2);
ASSERT_EQ(1u, observer.preconnected_urls_.size());
EXPECT_EQ(kHttpsUrl, observer.preconnected_urls_[0]);