Commit 666e4840 authored by Matt Menke's avatar Matt Menke Committed by Commit Bot

Add basic support for NetworkIsolationKeys to LoadingPredictor.

This CL makes LoadingPredictor always use the NetworkIsolationKey for
the initial main frame URL when preconnecting. In a future CL, I'll
make it use a NetworkIsolationKey of the expected destination URL,
after redirects, instead.

BUG=987735

Change-Id: I221a6bd4175005758ebf86b55cc21bdd98b167eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1716620
Commit-Queue: Matt Menke <mmenke@chromium.org>
Reviewed-by: default avatarAlex Ilin <alexilin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#682722}
parent f59f02b2
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include "chrome/browser/predictors/navigation_id.h" #include "chrome/browser/predictors/navigation_id.h"
#include "chrome/browser/predictors/resource_prefetch_predictor.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "net/base/network_isolation_key.h"
#include "url/origin.h"
namespace predictors { namespace predictors {
...@@ -39,8 +41,10 @@ bool AddInitialUrlToPreconnectPrediction(const GURL& initial_url, ...@@ -39,8 +41,10 @@ bool AddInitialUrlToPreconnectPrediction(const GURL& initial_url,
std::max(prediction->requests.front().num_sockets, kMinSockets); std::max(prediction->requests.front().num_sockets, kMinSockets);
} else if (initial_origin.is_valid() && } else if (initial_origin.is_valid() &&
initial_origin.SchemeIsHTTPOrHTTPS()) { initial_origin.SchemeIsHTTPOrHTTPS()) {
url::Origin origin = url::Origin::Create(initial_origin);
prediction->requests.emplace(prediction->requests.begin(), initial_origin, prediction->requests.emplace(prediction->requests.begin(), initial_origin,
kMinSockets); kMinSockets,
net::NetworkIsolationKey(origin, origin));
} }
return !prediction->requests.empty(); return !prediction->requests.empty();
......
...@@ -18,9 +18,11 @@ ...@@ -18,9 +18,11 @@
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "net/base/network_isolation_key.h"
#include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "url/origin.h"
using testing::_; using testing::_;
using testing::Return; using testing::Return;
...@@ -71,6 +73,12 @@ LoadingPredictorConfig CreateConfig() { ...@@ -71,6 +73,12 @@ LoadingPredictorConfig CreateConfig() {
return config; return config;
} }
// Creates a NetworkIsolationKey for a main frame navigation to URL.
net::NetworkIsolationKey CreateNetworkIsolationKey(const GURL& main_frame_url) {
url::Origin origin = url::Origin::Create(main_frame_url);
return net::NetworkIsolationKey(origin, origin);
}
} // namespace } // namespace
class LoadingPredictorTest : public testing::Test { class LoadingPredictorTest : public testing::Test {
...@@ -332,10 +340,11 @@ TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlToEmptyPrediction) { ...@@ -332,10 +340,11 @@ TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlToEmptyPrediction) {
GURL main_frame_url("http://search.com/kittens"); GURL main_frame_url("http://search.com/kittens");
EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(main_frame_url, _)) EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(main_frame_url, _))
.WillOnce(Return(false)); .WillOnce(Return(false));
EXPECT_CALL( EXPECT_CALL(*mock_preconnect_manager_,
*mock_preconnect_manager_, StartProxy(main_frame_url,
StartProxy(main_frame_url, std::vector<PreconnectRequest>( std::vector<PreconnectRequest>(
{{GURL("http://search.com"), 2}}))); {{GURL("http://search.com"), 2,
CreateNetworkIsolationKey(main_frame_url)}})));
predictor_->PrepareForPageLoad(main_frame_url, HintOrigin::NAVIGATION); predictor_->PrepareForPageLoad(main_frame_url, HintOrigin::NAVIGATION);
} }
...@@ -343,19 +352,23 @@ TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlToEmptyPrediction) { ...@@ -343,19 +352,23 @@ TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlToEmptyPrediction) {
// if the list already containts the origin. // if the list already containts the origin.
TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlMatchesPrediction) { TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlMatchesPrediction) {
GURL main_frame_url("http://search.com/kittens"); GURL main_frame_url("http://search.com/kittens");
PreconnectPrediction prediction = net::NetworkIsolationKey network_isolation_key =
CreatePreconnectPrediction("search.com", true, CreateNetworkIsolationKey(main_frame_url);
{{GURL("http://search.com"), 1}, PreconnectPrediction prediction = CreatePreconnectPrediction(
{GURL("http://cdn.search.com"), 1}, "search.com", true,
{GURL("http://ads.search.com"), 0}}); {{GURL("http://search.com"), 1, network_isolation_key},
{GURL("http://cdn.search.com"), 1, network_isolation_key},
{GURL("http://ads.search.com"), 0, network_isolation_key}});
EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(main_frame_url, _)) EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(main_frame_url, _))
.WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true))); .WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true)));
EXPECT_CALL( EXPECT_CALL(
*mock_preconnect_manager_, *mock_preconnect_manager_,
StartProxy(main_frame_url, std::vector<PreconnectRequest>( StartProxy(
{{GURL("http://search.com"), 2}, main_frame_url,
{GURL("http://cdn.search.com"), 1}, std::vector<PreconnectRequest>(
{GURL("http://ads.search.com"), 0}}))); {{GURL("http://search.com"), 2, network_isolation_key},
{GURL("http://cdn.search.com"), 1, network_isolation_key},
{GURL("http://ads.search.com"), 0, network_isolation_key}})));
predictor_->PrepareForPageLoad(main_frame_url, HintOrigin::EXTERNAL); predictor_->PrepareForPageLoad(main_frame_url, HintOrigin::EXTERNAL);
} }
...@@ -364,20 +377,24 @@ TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlMatchesPrediction) { ...@@ -364,20 +377,24 @@ TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlMatchesPrediction) {
// url redirects to another host. // url redirects to another host.
TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlDoesntMatchPrediction) { TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlDoesntMatchPrediction) {
GURL main_frame_url("http://search.com/kittens"); GURL main_frame_url("http://search.com/kittens");
PreconnectPrediction prediction = net::NetworkIsolationKey network_isolation_key =
CreatePreconnectPrediction("search.com", true, CreateNetworkIsolationKey(main_frame_url);
{{GURL("http://en.search.com"), 1}, PreconnectPrediction prediction = CreatePreconnectPrediction(
{GURL("http://cdn.search.com"), 1}, "search.com", true,
{GURL("http://ads.search.com"), 0}}); {{GURL("http://en.search.com"), 1, network_isolation_key},
{GURL("http://cdn.search.com"), 1, network_isolation_key},
{GURL("http://ads.search.com"), 0, network_isolation_key}});
EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(main_frame_url, _)) EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(main_frame_url, _))
.WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true))); .WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true)));
EXPECT_CALL( EXPECT_CALL(
*mock_preconnect_manager_, *mock_preconnect_manager_,
StartProxy(main_frame_url, std::vector<PreconnectRequest>( StartProxy(
{{GURL("http://search.com"), 2}, main_frame_url,
{GURL("http://en.search.com"), 1}, std::vector<PreconnectRequest>(
{GURL("http://cdn.search.com"), 1}, {{GURL("http://search.com"), 2, network_isolation_key},
{GURL("http://ads.search.com"), 0}}))); {GURL("http://en.search.com"), 1, network_isolation_key},
{GURL("http://cdn.search.com"), 1, network_isolation_key},
{GURL("http://ads.search.com"), 0, network_isolation_key}})));
predictor_->PrepareForPageLoad(main_frame_url, HintOrigin::EXTERNAL); predictor_->PrepareForPageLoad(main_frame_url, HintOrigin::EXTERNAL);
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "net/base/network_isolation_key.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
using testing::_; using testing::_;
...@@ -77,7 +78,7 @@ void LoadingStatsCollectorTest::TestRedirectStatusHistogram( ...@@ -77,7 +78,7 @@ void LoadingStatsCollectorTest::TestRedirectStatusHistogram(
const std::string& script_url = "https://cdn.google.com/script.js"; const std::string& script_url = "https://cdn.google.com/script.js";
PreconnectPrediction prediction = CreatePreconnectPrediction( PreconnectPrediction prediction = CreatePreconnectPrediction(
GURL(prediction_url).host(), initial_url != prediction_url, GURL(prediction_url).host(), initial_url != prediction_url,
{{GURL(script_url).GetOrigin(), 1}}); {{GURL(script_url).GetOrigin(), 1, net::NetworkIsolationKey()}});
EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(GURL(initial_url), _)) EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(GURL(initial_url), _))
.WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true))); .WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true)));
...@@ -105,12 +106,12 @@ TEST_F(LoadingStatsCollectorTest, TestPreconnectPrecisionRecallHistograms) { ...@@ -105,12 +106,12 @@ TEST_F(LoadingStatsCollectorTest, TestPreconnectPrecisionRecallHistograms) {
}; };
// Predicts 4 origins: 2 useful, 2 useless. // Predicts 4 origins: 2 useful, 2 useless.
PreconnectPrediction prediction = PreconnectPrediction prediction = CreatePreconnectPrediction(
CreatePreconnectPrediction(GURL(main_frame_url).host(), false, GURL(main_frame_url).host(), false,
{{GURL(main_frame_url).GetOrigin(), 1}, {{GURL(main_frame_url).GetOrigin(), 1, net::NetworkIsolationKey()},
{GURL(gen(1)).GetOrigin(), 1}, {GURL(gen(1)).GetOrigin(), 1, net::NetworkIsolationKey()},
{GURL(gen(2)).GetOrigin(), 1}, {GURL(gen(2)).GetOrigin(), 1, net::NetworkIsolationKey()},
{GURL(gen(3)).GetOrigin(), 0}}); {GURL(gen(3)).GetOrigin(), 0, net::NetworkIsolationKey()}});
EXPECT_CALL(*mock_predictor_, EXPECT_CALL(*mock_predictor_,
PredictPreconnectOrigins(GURL(main_frame_url), _)) PredictPreconnectOrigins(GURL(main_frame_url), _))
.WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true))); .WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true)));
......
...@@ -211,7 +211,8 @@ std::ostream& operator<<(std::ostream& os, const NavigationID& navigation_id) { ...@@ -211,7 +211,8 @@ std::ostream& operator<<(std::ostream& os, const NavigationID& navigation_id) {
std::ostream& operator<<(std::ostream& os, const PreconnectRequest& request) { std::ostream& operator<<(std::ostream& os, const PreconnectRequest& request) {
return os << "[" << request.origin << "," << request.num_sockets << "," return os << "[" << request.origin << "," << request.num_sockets << ","
<< request.allow_credentials << "]"; << request.allow_credentials << ","
<< request.network_isolation_key.ToDebugString() << "]";
} }
std::ostream& operator<<(std::ostream& os, std::ostream& operator<<(std::ostream& os,
...@@ -284,7 +285,8 @@ bool operator==(const OriginStat& lhs, const OriginStat& rhs) { ...@@ -284,7 +285,8 @@ bool operator==(const OriginStat& lhs, const OriginStat& rhs) {
bool operator==(const PreconnectRequest& lhs, const PreconnectRequest& rhs) { bool operator==(const PreconnectRequest& lhs, const PreconnectRequest& rhs) {
return lhs.origin == rhs.origin && lhs.num_sockets == rhs.num_sockets && return lhs.origin == rhs.origin && lhs.num_sockets == rhs.num_sockets &&
lhs.allow_credentials == rhs.allow_credentials; lhs.allow_credentials == rhs.allow_credentials &&
lhs.network_isolation_key == rhs.network_isolation_key;
} }
bool operator==(const PreconnectPrediction& lhs, bool operator==(const PreconnectPrediction& lhs,
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "components/history/core/browser/url_utils.h" #include "components/history/core/browser/url_utils.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "url/origin.h"
using content::BrowserThread; using content::BrowserThread;
...@@ -61,10 +62,10 @@ void InitializeOnDBSequence( ...@@ -61,10 +62,10 @@ void InitializeOnDBSequence(
PreconnectRequest::PreconnectRequest( PreconnectRequest::PreconnectRequest(
const GURL& origin, const GURL& origin,
int num_sockets, int num_sockets,
net::NetworkIsolationKey network_isolation_key) const net::NetworkIsolationKey& network_isolation_key)
: origin(origin), : origin(origin),
num_sockets(num_sockets), num_sockets(num_sockets),
network_isolation_key(std::move(network_isolation_key)) { network_isolation_key(network_isolation_key) {
DCHECK_GE(num_sockets, 0); DCHECK_GE(num_sockets, 0);
} }
...@@ -224,6 +225,16 @@ bool ResourcePrefetchPredictor::PredictPreconnectOrigins( ...@@ -224,6 +225,16 @@ bool ResourcePrefetchPredictor::PredictPreconnectOrigins(
} }
bool has_any_prediction = false; bool has_any_prediction = false;
// TODO(https://crbug.com/987735): Use the NetworkIsolationKey of the final
// destination in the case of redirects. This will require recording the port,
// which is not currently logged. That will not result in using the correct
// NetworkIsolationKey in the case of intermediary redirects, but given the
// relatively low accurace of redirect predictions, seems likely not worth
// fixing.
url::Origin origin = url::Origin::Create(url);
net::NetworkIsolationKey network_isolation_key(origin, origin);
for (const OriginStat& origin : data.origins()) { for (const OriginStat& origin : data.origins()) {
float confidence = static_cast<float>(origin.number_of_hits()) / float confidence = static_cast<float>(origin.number_of_hits()) /
(origin.number_of_hits() + origin.number_of_misses()); (origin.number_of_hits() + origin.number_of_misses());
...@@ -232,10 +243,13 @@ bool ResourcePrefetchPredictor::PredictPreconnectOrigins( ...@@ -232,10 +243,13 @@ bool ResourcePrefetchPredictor::PredictPreconnectOrigins(
has_any_prediction = true; has_any_prediction = true;
if (prediction) { if (prediction) {
if (confidence > kMinOriginConfidenceToTriggerPreconnect) if (confidence > kMinOriginConfidenceToTriggerPreconnect) {
prediction->requests.emplace_back(GURL(origin.origin()), 1); prediction->requests.emplace_back(GURL(origin.origin()), 1,
else network_isolation_key);
prediction->requests.emplace_back(GURL(origin.origin()), 0); } else {
prediction->requests.emplace_back(GURL(origin.origin()), 0,
network_isolation_key);
}
} }
} }
......
...@@ -60,13 +60,9 @@ struct PreconnectRequest { ...@@ -60,13 +60,9 @@ struct PreconnectRequest {
// preconnected URL are expected to use. If a request is issued with a // preconnected URL are expected to use. If a request is issued with a
// different key, it may not use the preconnected socket. It has no effect // different key, it may not use the preconnected socket. It has no effect
// when |num_sockets| == 0. // when |num_sockets| == 0.
//
// TODO(https://crbug.com/966896): Update consumers and make
// |network_isolation_key| a mandatory argument.
PreconnectRequest(const GURL& origin, PreconnectRequest(const GURL& origin,
int num_sockets, int num_sockets,
net::NetworkIsolationKey network_isolation_key = const net::NetworkIsolationKey& network_isolation_key);
net::NetworkIsolationKey());
GURL origin; GURL origin;
// A zero-value means that we need to preresolve a host only. // A zero-value means that we need to preresolve a host only.
......
...@@ -25,8 +25,11 @@ ...@@ -25,8 +25,11 @@
#include "components/sessions/core/session_id.h" #include "components/sessions/core/session_id.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "net/base/network_isolation_key.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
using testing::StrictMock; using testing::StrictMock;
using testing::UnorderedElementsAre; using testing::UnorderedElementsAre;
...@@ -676,6 +679,8 @@ TEST_F(ResourcePrefetchPredictorTest, GetRedirectEndpoint) { ...@@ -676,6 +679,8 @@ TEST_F(ResourcePrefetchPredictorTest, GetRedirectEndpoint) {
TEST_F(ResourcePrefetchPredictorTest, TestPredictPreconnectOrigins) { TEST_F(ResourcePrefetchPredictorTest, TestPredictPreconnectOrigins) {
const GURL main_frame_url("http://google.com/?query=cats"); const GURL main_frame_url("http://google.com/?query=cats");
const url::Origin origin = url::Origin::Create(main_frame_url);
const net::NetworkIsolationKey network_isolation_key(origin, origin);
auto prediction = std::make_unique<PreconnectPrediction>(); auto prediction = std::make_unique<PreconnectPrediction>();
// No prefetch data. // No prefetch data.
EXPECT_FALSE(predictor_->IsUrlPreconnectable(main_frame_url)); EXPECT_FALSE(predictor_->IsUrlPreconnectable(main_frame_url));
...@@ -704,7 +709,8 @@ TEST_F(ResourcePrefetchPredictorTest, TestPredictPreconnectOrigins) { ...@@ -704,7 +709,8 @@ TEST_F(ResourcePrefetchPredictorTest, TestPredictPreconnectOrigins) {
EXPECT_EQ(*prediction, EXPECT_EQ(*prediction,
CreatePreconnectPrediction( CreatePreconnectPrediction(
"google.com", false, "google.com", false,
{{GURL(gen_origin(1)), 1}, {GURL(gen_origin(2)), 0}})); {{GURL(gen_origin(1)), 1, network_isolation_key},
{GURL(gen_origin(2)), 0, network_isolation_key}}));
// Add a redirect. // Add a redirect.
RedirectData redirect = CreateRedirectData("google.com", 3); RedirectData redirect = CreateRedirectData("google.com", 3);
...@@ -729,9 +735,9 @@ TEST_F(ResourcePrefetchPredictorTest, TestPredictPreconnectOrigins) { ...@@ -729,9 +735,9 @@ TEST_F(ResourcePrefetchPredictorTest, TestPredictPreconnectOrigins) {
EXPECT_TRUE(predictor_->IsUrlPreconnectable(main_frame_url)); EXPECT_TRUE(predictor_->IsUrlPreconnectable(main_frame_url));
EXPECT_TRUE( EXPECT_TRUE(
predictor_->PredictPreconnectOrigins(main_frame_url, prediction.get())); predictor_->PredictPreconnectOrigins(main_frame_url, prediction.get()));
EXPECT_EQ(*prediction, EXPECT_EQ(*prediction, CreatePreconnectPrediction("www.google.com", true,
CreatePreconnectPrediction("www.google.com", true, {{GURL(gen_origin(4)), 1,
{{GURL(gen_origin(4)), 1}})); network_isolation_key}}));
} }
} // namespace predictors } // namespace predictors
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment