blob: c703bcbec83c5f0ea4a897322684c9176e8a8fe2 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/preloading/prefetch/prefetch_request.h"
#include <variant>
#include "content/browser/preloading/prefetch/prefetch_params.h"
#include "content/browser/preloading/prefetch/prefetch_type.h"
#include "content/browser/preloading/preload_pipeline_info_impl.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/prefetch_request_status_listener.h"
#include "url/gurl.h"
namespace content {
namespace {
ukm::SourceId GetUkmSourceId(RenderFrameHostImpl& rfhi) {
// Prerendering page should not trigger prefetches.
CHECK(
!rfhi.IsInLifecycleState(RenderFrameHost::LifecycleState::kPrerendering));
return rfhi.GetPageUkmSourceId();
}
} // namespace
PrefetchRendererInitiatorInfo::PrefetchRendererInitiatorInfo(
RenderFrameHostImpl& render_frame_host,
base::WeakPtr<PrefetchDocumentManager> prefetch_document_manager)
: render_frame_host_id_(render_frame_host.GetGlobalId()),
prefetch_document_manager_(std::move(prefetch_document_manager)),
devtools_navigation_token_(
render_frame_host.GetDevToolsNavigationToken()),
ukm_source_id_(GetUkmSourceId(render_frame_host)),
url_hash_(
base::FastHash(render_frame_host.GetLastCommittedURL().spec())) {}
PrefetchRendererInitiatorInfo::PrefetchRendererInitiatorInfo(
PrefetchRendererInitiatorInfo&&) = default;
PrefetchRendererInitiatorInfo::~PrefetchRendererInitiatorInfo() = default;
RenderFrameHostImpl* PrefetchRendererInitiatorInfo::GetRenderFrameHost() const {
return RenderFrameHostImpl::FromID(render_frame_host_id_);
}
PrefetchBrowserInitiatorInfo::~PrefetchBrowserInitiatorInfo() = default;
PrefetchBrowserInitiatorInfo::PrefetchBrowserInitiatorInfo(
PrefetchBrowserInitiatorInfo&&) = default;
PrefetchBrowserInitiatorInfo::PrefetchBrowserInitiatorInfo(
const std::string& embedder_histogram_suffix,
std::unique_ptr<PrefetchRequestStatusListener> request_status_listener)
: embedder_histogram_suffix_(embedder_histogram_suffix),
request_status_listener_(std::move(request_status_listener)) {
CHECK(!embedder_histogram_suffix_.empty());
}
PrefetchRequest::PrefetchRequest(
const PrefetchType& prefetch_type,
const PrefetchKey& key,
const std::optional<net::HttpNoVarySearchData> no_vary_search_hint,
std::optional<PrefetchPriority> priority,
scoped_refptr<PreloadPipelineInfo> preload_pipeline_info,
base::WeakPtr<PreloadingAttempt> attempt,
bool is_javascript_enabled,
const blink::mojom::Referrer& initial_referrer,
const std::optional<url::Origin>& referring_origin,
base::WeakPtr<BrowserContext> browser_context,
std::optional<SpeculationRulesTags> speculation_rules_tags,
const net::HttpRequestHeaders& additional_headers,
base::TimeDelta ttl,
std::optional<PreloadingHoldbackStatus> holdback_status_override,
bool should_append_variations_header,
bool should_disable_block_until_head_timeout,
std::variant<PrefetchRendererInitiatorInfo, PrefetchBrowserInitiatorInfo>
initiator_info)
: prefetch_type_(prefetch_type),
key_(key),
no_vary_search_hint_(std::move(no_vary_search_hint)),
priority_(std::move(priority)),
preload_pipeline_info_(base::WrapRefCounted(
static_cast<PreloadPipelineInfoImpl*>(preload_pipeline_info.get()))),
attempt_(std::move(attempt)),
is_javascript_enabled_(is_javascript_enabled),
initial_referrer_(initial_referrer),
referring_origin_(referring_origin),
browser_context_(std::move(browser_context)),
speculation_rules_tags_(std::move(speculation_rules_tags)),
additional_headers_(additional_headers),
ttl_(std::move(ttl)),
holdback_status_override_(std::move(holdback_status_override)),
should_append_variations_header_(should_append_variations_header),
should_disable_block_until_head_timeout_(
should_disable_block_until_head_timeout),
initiator_info_(std::move(initiator_info)) {
CHECK(preload_pipeline_info_);
if (prefetch_type_.IsRendererInitiated()) {
CHECK(GetRendererInitiatorInfo());
CHECK(!GetBrowserInitiatorInfo());
CHECK(additional_headers_.IsEmpty());
CHECK_EQ(ttl_, PrefetchContainerDefaultTtlInPrefetchService());
CHECK(!holdback_status_override_);
CHECK(should_append_variations_header_);
CHECK(!should_disable_block_until_head_timeout_);
} else {
CHECK(!GetRendererInitiatorInfo());
CHECK(GetBrowserInitiatorInfo());
CHECK(!speculation_rules_tags_);
}
}
PrefetchRequest::~PrefetchRequest() = default;
const PrefetchRendererInitiatorInfo* PrefetchRequest::GetRendererInitiatorInfo()
const {
return std::get_if<PrefetchRendererInitiatorInfo>(&initiator_info_);
}
const PrefetchBrowserInitiatorInfo* PrefetchRequest::GetBrowserInitiatorInfo()
const {
return std::get_if<PrefetchBrowserInitiatorInfo>(&initiator_info_);
}
} // namespace content