1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/predictors/network_hints_handler_impl.h"
#include <optional>
#include "base/memory/ptr_util.h"
#include "chrome/browser/predictors/loading_predictor.h"
#include "chrome/browser/predictors/loading_predictor_factory.h"
#include "chrome/browser/predictors/preconnect_manager.h"
#include "chrome/browser/predictors/predictors_traffic_annotations.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "net/base/isolation_info.h"
namespace predictors {
namespace {
// Preconnects can be received from the renderer before commit messages, so
// need to use the key from the pending navigation, and not the committed
// navigation, unlike other consumers. This does mean on navigating away from a
// site, preconnect is more likely to incorrectly use the
// NetworkAnonymizationKey of the previous commit.
net::NetworkAnonymizationKey GetPendingNetworkAnonymizationKey(
content::RenderFrameHost* render_frame_host) {
return render_frame_host->GetPendingIsolationInfoForSubresources()
.network_anonymization_key();
}
} // namespace
NetworkHintsHandlerImpl::~NetworkHintsHandlerImpl() = default;
// static
void NetworkHintsHandlerImpl::Create(
content::RenderFrameHost* frame_host,
mojo::PendingReceiver<network_hints::mojom::NetworkHintsHandler> receiver) {
mojo::MakeSelfOwnedReceiver(
base::WrapUnique(new NetworkHintsHandlerImpl(frame_host)),
std::move(receiver));
}
void NetworkHintsHandlerImpl::PrefetchDNS(
const std::vector<url::SchemeHostPort>& urls) {
if (!preconnect_manager_)
return;
content::RenderFrameHost* render_frame_host =
content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
if (!render_frame_host)
return;
std::vector<GURL> gurls;
for (const auto& url : urls) {
gurls.emplace_back(url.GetURL());
}
preconnect_manager_->StartPreresolveHosts(
gurls, GetPendingNetworkAnonymizationKey(render_frame_host),
kNetworkHintsTrafficAnnotation, /*storage_partition_config=*/nullptr);
}
void NetworkHintsHandlerImpl::Preconnect(const url::SchemeHostPort& url,
bool allow_credentials) {
if (!preconnect_manager_)
return;
if (url.scheme() != url::kHttpScheme && url.scheme() != url::kHttpsScheme) {
return;
}
// TODO(mmenke): Think about enabling cross-site preconnects, though that
// will result in at least some cross-site information leakage.
content::RenderFrameHost* render_frame_host =
content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
if (!render_frame_host)
return;
preconnect_manager_->StartPreconnectUrl(
url.GetURL(), allow_credentials,
GetPendingNetworkAnonymizationKey(render_frame_host),
kNetworkHintsTrafficAnnotation, /*storage_partition_config=*/nullptr,
/*keepalive_config=*/std::nullopt, mojo::NullRemote());
}
NetworkHintsHandlerImpl::NetworkHintsHandlerImpl(
content::RenderFrameHost* frame_host)
: render_process_id_(frame_host->GetProcess()->GetDeprecatedID()),
render_frame_id_(frame_host->GetRoutingID()) {
// Get the PreconnectManager for this process.
auto* render_process_host = frame_host->GetProcess();
auto* profile =
Profile::FromBrowserContext(render_process_host->GetBrowserContext());
auto* loading_predictor =
predictors::LoadingPredictorFactory::GetForProfile(profile);
if (loading_predictor && loading_predictor->preconnect_manager())
preconnect_manager_ = loading_predictor->preconnect_manager()->GetWeakPtr();
}
} // namespace predictors
|