blob: 3bf11cb042cdb0e44d0f108e994e034290908b88 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2022 The Chromium Authors
Max Curran6c2835ea2022-03-07 19:52:382// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Sreeja Kamishettyf66553a2022-07-14 17:41:275#ifndef CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_SERVICE_H_
6#define CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_SERVICE_H_
Max Curran6c2835ea2022-03-07 19:52:387
Max Curran646fb642022-03-16 00:44:098#include <map>
Arthur Sonzognic686e8f2024-01-11 08:36:379#include <optional>
Max Curran6c2835ea2022-03-07 19:52:3810
Adithya Srinivasand5e37cb2023-07-05 14:45:2311#include "base/dcheck_is_on.h"
Max Curran646fb642022-03-16 00:44:0912#include "base/memory/weak_ptr.h"
Sreeja Kamishettyf66553a2022-07-14 17:41:2713#include "content/browser/preloading/prefetch/prefetch_container.h"
Hiroshige Hayashizaki583b4962025-08-19 18:58:2614#include "content/browser/preloading/prefetch/prefetch_key.h"
Hiroshige Hayashizakic853c0302023-09-13 08:51:0715#include "content/browser/preloading/prefetch/prefetch_streaming_url_loader_common_types.h"
Max Curran6c2835ea2022-03-07 19:52:3816#include "content/common/content_export.h"
Avi Drissmandcc8e682024-09-04 14:14:4817#include "content/public/browser/frame_tree_node_id.h"
Taiyo Mizuhashi94ce74f2025-01-28 04:20:1418#include "content/public/browser/prefetch_handle.h"
Steven Weie829c85f72025-03-17 18:57:5919#include "content/public/browser/storage_partition.h"
Max Curran18a6f2b2022-05-02 23:13:2420#include "services/network/public/mojom/url_response_head.mojom.h"
Max Curran6c2835ea2022-03-07 19:52:3821#include "url/gurl.h"
22
Hiroshige Hayashizakie51e2f262025-03-04 23:14:3823namespace network {
24class SharedURLLoaderFactory;
25} // namespace network
26
Max Curran18a6f2b2022-05-02 23:13:2427namespace network::mojom {
Max Currancc1ab0c2022-09-12 22:03:1128class NetworkContext;
Max Curran18a6f2b2022-05-02 23:13:2429} // namespace network::mojom
30
Max Curran6c2835ea2022-03-07 19:52:3831namespace content {
32
Max Curran146bf442022-03-28 23:22:1433class BrowserContext;
Liviu Tinta4eaa53c22023-08-02 21:01:0634class PrefetchMatchResolver;
Max Curran0146f852022-08-01 19:49:3335class PrefetchOriginProber;
Max Curran18a6f2b2022-05-02 23:13:2436class PrefetchProxyConfigurator;
kenoss1b8ebc22025-04-04 00:11:3537class PrefetchScheduler;
Hiroshige Hayashizakib3ff61d2025-08-12 06:28:0838class PrefetchServiceDelegate;
Max Curran146bf442022-03-28 23:22:1439class ServiceWorkerContext;
Hiroshige Hayashizaki583b4962025-08-19 18:58:2640enum class ServiceWorkerCapability;
Max Curran146bf442022-03-28 23:22:1441
Max Curran7d2578b2023-04-12 19:19:2842// These values are persisted to logs. Entries should not be renumbered and
43// numeric values should never be reused.
44enum class PrefetchRedirectResult {
45 kSuccessRedirectFollowed = 0,
46 kFailedNullPrefetch = 1,
Jeremy Roman337e4952024-07-04 20:36:4947 // OBSOLETE: kFailedRedirectsDisabled = 2,
Max Curran7d2578b2023-04-12 19:19:2848 kFailedInvalidMethod = 3,
49 kFailedInvalidResponseCode = 4,
50 kFailedInvalidChangeInNetworkContext = 5,
51 kFailedIneligible = 6,
Devlin Cronin7f318c12023-06-09 00:57:0152 kFailedInsufficientReferrerPolicy = 7,
53 kMaxValue = kFailedInsufficientReferrerPolicy,
Max Curran7d2578b2023-04-12 19:19:2854};
55
56// These values are persisted to logs. Entries should not be renumbered and
57// numeric values should never be reused.
58enum class PrefetchRedirectNetworkContextTransition {
59 kDefaultToDefault = 0,
60 kDefaultToIsolated = 1,
61 kIsolatedToDefault = 2,
62 kIsolatedToIsolated = 3,
63 kMaxValue = kIsolatedToIsolated,
64};
65
Max Curran6c2835ea2022-03-07 19:52:3866// Manages all prefetches within a single BrowserContext. Responsible for
67// checking the eligibility of the prefetch, making the network request for the
68// prefetch, and provide prefetched resources to URL loader interceptor when
69// needed.
Hiroshige Hayashizaki70db51b2025-07-14 23:09:4970//
71// `PrefetchService` is an `PrefetchContainer::Observer` to `PrefetchContainer`s
72// in `owned_prefetches_`.
73class CONTENT_EXPORT PrefetchService : public PrefetchContainer::Observer {
Max Curran6c2835ea2022-03-07 19:52:3874 public:
Avi Drissmandcc8e682024-09-04 14:14:4875 static PrefetchService* GetFromFrameTreeNodeId(
76 FrameTreeNodeId frame_tree_node_id);
Hiroshige Hayashizaki805be6862023-03-28 08:16:2277 static void SetFromFrameTreeNodeIdForTesting(
Avi Drissmandcc8e682024-09-04 14:14:4878 FrameTreeNodeId frame_tree_node_id,
Hiroshige Hayashizaki805be6862023-03-28 08:16:2279 std::unique_ptr<PrefetchService> prefetch_service);
80
Adithya Srinivasan8e0c92e2023-06-27 19:15:0481 // |browser_context| must outlive this instance. In general this should always
82 // be true, since |PrefetchService| will be indirectly owned by
83 // |BrowserContext|.
Max Curran146bf442022-03-28 23:22:1484 explicit PrefetchService(BrowserContext* browser_context);
Hiroshige Hayashizaki70db51b2025-07-14 23:09:4985 ~PrefetchService() override;
Max Curran6c2835ea2022-03-07 19:52:3886
87 PrefetchService(const PrefetchService&) = delete;
88 const PrefetchService& operator=(const PrefetchService&) = delete;
89
Max Curran18a6f2b2022-05-02 23:13:2490 BrowserContext* GetBrowserContext() const { return browser_context_; }
91
Max Curranead64a62022-06-22 01:10:5292 PrefetchServiceDelegate* GetPrefetchServiceDelegate() const {
93 return delegate_.get();
94 }
Jeremy Romane561b412024-02-15 18:31:3495 void SetPrefetchServiceDelegateForTesting(
96 std::unique_ptr<PrefetchServiceDelegate> delegate);
Max Curranead64a62022-06-22 01:10:5297
Max Curran18a6f2b2022-05-02 23:13:2498 PrefetchProxyConfigurator* GetPrefetchProxyConfigurator() const {
99 return prefetch_proxy_configurator_.get();
100 }
101
Hiroshige Hayashizaki805be6862023-03-28 08:16:22102 virtual PrefetchOriginProber* GetPrefetchOriginProber() const;
Max Curran18a6f2b2022-05-02 23:13:24103 virtual void PrefetchUrl(base::WeakPtr<PrefetchContainer> prefetch_container);
104
Max Curran7dbdea4d2023-03-21 23:47:37105 // Copies any cookies in the isolated network context associated with
106 // |prefetch_container| to the default network context.
Hiroshige Hayashizaki16b6e54f2025-08-12 06:56:57107 virtual void CopyIsolatedCookies(const PrefetchServingHandle& serving_handle);
Max Curran7dbdea4d2023-03-21 23:47:37108
Hiroshige Hayashizaki40a2532f2025-03-07 21:42:00109 // Adds `PrefetchContainer` under control of `PrefetchService` and returns
110 // PrefetchHandle so that the caller can control prefetch resources associated
111 // with this.
kenossb68c9e82024-10-10 10:11:15112 //
Hiroshige Hayashizaki40a2532f2025-03-07 21:42:00113 // `AddPrefetchContainer*()` synchronously destruct `prefetch_container` if
114 // the key conflicted to the one already added with migration of some
115 // attributes. See also `MigrateNewlyaAdded()`.
116 [[nodiscard]] std::unique_ptr<PrefetchHandle> AddPrefetchContainerWithHandle(
Taiyo Mizuhashi94ce74f2025-01-28 04:20:14117 std::unique_ptr<PrefetchContainer> prefetch_container);
kenossb68c9e82024-10-10 10:11:15118 void AddPrefetchContainerWithoutStartingPrefetchForTesting(
119 std::unique_ptr<PrefetchContainer> prefetch_container);
Hiroshige Hayashizaki7a34d0182023-11-07 20:54:34120
Wayne Jackson Jr.0118d2a2025-02-21 10:53:46121 // Returns `true` if a new prefetch request with `url` and
122 // `no_vary_search_hint` has a duplicate in the prefetch cache and thus the
123 // caller can choose not to start the prefetch request.
124 //
125 // Note: This is currently used for WebView initiated prefetches
126 // so consideration should be taken if updating the
127 // underlying implementation (or its dependencies).
128 bool IsPrefetchDuplicate(
129 GURL& url,
130 std::optional<net::HttpNoVarySearchData> no_vary_search_hint);
131
Hiroshige Hayashizakia129d91c2025-03-05 22:28:12132 // Whether the prefetch attempt for `key` has failed or discarded.
133 // Note: the semantics of this method is not super clear and thus is exposed
134 // only for the existing `PrefetchDocumentManager` use case for now.
135 bool IsPrefetchAttemptFailedOrDiscardedInternal(
136 base::PassKey<PrefetchDocumentManager>,
Hiroshige Hayashizakic625e812025-08-19 18:42:35137 PrefetchKey key) const;
Hiroshige Hayashizakia129d91c2025-03-05 22:28:12138
Taiyo Mizuhashi94ce74f2025-01-28 04:20:14139 // An interface to notify `PrefetchService` that the given `PrefetchContainer`
140 // is no longer needed from outside of the service.
141 void MayReleasePrefetch(base::WeakPtr<PrefetchContainer> prefetch_container);
Hiroshige Hayashizaki7a34d0182023-11-07 20:54:34142
Adithya Srinivasand5e37cb2023-07-05 14:45:23143 // Called by PrefetchDocumentManager when it finishes processing the latest
144 // update of speculation candidates.
145 void OnCandidatesUpdated();
146
Max Curran146bf442022-03-28 23:22:14147 // Helper functions to control the behavior of the eligibility check when
148 // testing.
149 static void SetServiceWorkerContextForTesting(ServiceWorkerContext* context);
150 static void SetHostNonUniqueFilterForTesting(
Md Hasibul Hasana963a9342024-04-03 10:15:14151 bool (*filter)(std::string_view));
Max Curran146bf442022-03-28 23:22:14152
Max Curran18a6f2b2022-05-02 23:13:24153 // Sets the URLLoaderFactory to be used during testing instead of the
154 // |PrefetchNetworkContext| associated with each |PrefetchContainer|. Note
155 // that this does not take ownership of |url_loader_factory|, and caller must
156 // keep ownership over the course of the test.
157 static void SetURLLoaderFactoryForTesting(
Hiroshige Hayashizakie51e2f262025-03-04 23:14:38158 network::SharedURLLoaderFactory* url_loader_factory);
Max Curran18a6f2b2022-05-02 23:13:24159
Max Currancc1ab0c2022-09-12 22:03:11160 // Sets the NetworkContext to use just for the proxy lookup. Note that this
161 // does not take ownership of |network_context|, and the caller must keep
162 // ownership over the course of the test.
163 static void SetNetworkContextForProxyLookupForTesting(
164 network::mojom::NetworkContext* network_context);
165
kenossb68c9e82024-10-10 10:11:15166 // Set a callback for injecting delay for eligibility check in tests.
kenoss14462ae2025-03-21 02:39:51167 //
168 // Make sure to call
169 // `SetDelayEligibilityCheckForTesting(base::NullCallback())` at the end of an
170 // unit test that used this method, as this sets a global variable and it is
171 // shared in unit tests.
kenossb68c9e82024-10-10 10:11:15172 using DelayEligibilityCheckForTesting =
173 base::RepeatingCallback<void(base::OnceClosure)>;
174 static void SetDelayEligibilityCheckForTesting(
175 DelayEligibilityCheckForTesting callback);
kenoss4858a802024-10-11 06:50:56176 // Set an ineligibility to make eligibility check always fail in tests.
177 static void SetForceIneligibilityForTesting(PreloadingEligibility);
Hiroshige Hayashizakic0b6aea2023-10-17 21:56:43178
Hiroshige Hayashizakic625e812025-08-19 18:42:35179 base::WeakPtr<PrefetchContainer> MatchUrl(const PrefetchKey& key) const;
Hiroshige Hayashizakia00e4c82023-10-31 20:20:17180 std::vector<std::pair<GURL, base::WeakPtr<PrefetchContainer>>>
Hiroshige Hayashizakic625e812025-08-19 18:42:35181 GetAllForUrlWithoutRefAndQueryForTesting(const PrefetchKey& key) const;
Hiroshige Hayashizakia00e4c82023-10-31 20:20:17182
Steven Weie829c85f72025-03-17 18:57:59183 // Evicts completed and in-progress prefetches as part of
184 // Clear-Site-Data header and Clearing Browser Data if the prefetch's
185 // referring origin matches the storage_key_filter.
186 void EvictPrefetchesForBrowsingDataRemoval(
187 const StoragePartition::StorageKeyMatcherFunction& storage_key_filter,
188 PrefetchStatus status);
189
kenoss4dc068662024-10-04 05:03:50190 // Returns candidate `PrefetchContainer`s and servable states for matching
191 // process. Corresponds to 3.4. of
kenossf6fbd5652024-09-04 00:40:28192 // https://wicg.github.io/nav-speculation/prefetch.html#wait-for-a-matching-prefetch-record
kenoss4dc068662024-10-04 05:03:50193 //
194 // Note that `PrefetchContainer::GetServableState()` depends on
195 // `base::TimeTicks::now()` and can expire (can change from `kServable` to
196 // `kNotServable`) in the minute between two calls. Deciding something with
Hiroshige Hayashizakib3ff61d2025-08-12 06:28:08197 // multiple `PrefetchContainer::GetServableState()` calls can
198 // lead inconsistent state. To avoid that, we record
199 // `PrefetchServableState` in the `flat_map` at the beginning of
200 // matching process and refer to it.
201 std::pair<std::vector<PrefetchContainer*>,
Hiroshige Hayashizakic625e812025-08-19 18:42:35202 base::flat_map<PrefetchKey, PrefetchServableState>>
203 CollectMatchCandidates(const PrefetchKey& key,
kenoss804a72dc2024-10-11 12:43:49204 bool is_nav_prerender,
kenoss4dc068662024-10-04 05:03:50205 base::WeakPtr<PrefetchServingPageMetricsContainer>
206 serving_page_metrics_container);
kenossf6fbd5652024-09-04 00:40:28207
kenoss1b8ebc22025-04-04 00:11:35208 // Exposes methods for `PrefetchScheduler`. See documentation of private
209 // methods with the same names.
210 void EvictPrefetch(base::PassKey<PrefetchScheduler>,
211 base::WeakPtr<PrefetchContainer> prefetch_container);
212 bool StartSinglePrefetch(base::PassKey<PrefetchScheduler>,
213 base::WeakPtr<PrefetchContainer> prefetch_container);
214
215 PrefetchScheduler& GetPrefetchSchedulerForTesting() { return *scheduler_; }
216
Hiroshige Hayashizakia00e4c82023-10-31 20:20:17217 base::WeakPtr<PrefetchService> GetWeakPtr();
218
Max Curran646fb642022-03-16 00:44:09219 private:
Hiroshige Hayashizaki31484212024-01-30 13:35:21220 friend class PrefetchURLLoaderInterceptorTestBase;
221
Hiroshige Hayashizaki692e3eb2025-07-18 21:03:49222 struct CheckEligibilityParams;
223
Max Curran146bf442022-03-28 23:22:14224 // Checks whether the given |prefetch_container| is eligible for prefetch.
kenoss0c7bbc72024-07-24 08:52:40225 // Once the eligibility is determined then |OnGotEligibility()| will be
226 // called.
Hiroshige Hayashizaki692e3eb2025-07-18 21:03:49227 void CheckEligibilityOfPrefetch(CheckEligibilityParams params);
Max Curran146bf442022-03-28 23:22:14228
Hiroshige Hayashizaki692e3eb2025-07-18 21:03:49229 void CheckHasServiceWorker(CheckEligibilityParams params);
Liviu Tintaf7d62a72023-08-29 21:48:39230
231 void OnGotServiceWorkerResult(
Hiroshige Hayashizaki692e3eb2025-07-18 21:03:49232 CheckEligibilityParams params,
Liviu Tinta91202302023-09-26 17:49:11233 base::Time check_has_service_worker_start_time,
kenoss0c7bbc72024-07-24 08:52:40234 ServiceWorkerCapability service_worker_capability);
Liviu Tintaf7d62a72023-08-29 21:48:39235
Max Curran146bf442022-03-28 23:22:14236 // Called after getting the existing cookies associated with
237 // |prefetch_container|. If there are any cookies, then the prefetch is not
238 // eligible.
239 void OnGotCookiesForEligibilityCheck(
Hiroshige Hayashizaki692e3eb2025-07-18 21:03:49240 CheckEligibilityParams params,
Max Curran146bf442022-03-28 23:22:14241 const net::CookieAccessResultList& cookie_list,
kenoss0c7bbc72024-07-24 08:52:40242 const net::CookieAccessResultList& excluded_cookies);
Max Curran146bf442022-03-28 23:22:14243
Max Currancc1ab0c2022-09-12 22:03:11244 // Starts the check for whether or not there is a proxy configured for the URL
245 // of |prefetch_container|. If there is an existing proxy, then the prefetch
246 // is not eligible.
Hiroshige Hayashizaki692e3eb2025-07-18 21:03:49247 void StartProxyLookupCheck(CheckEligibilityParams params);
Max Currancc1ab0c2022-09-12 22:03:11248
249 // Called after looking up the proxy configuration for the URL of
250 // |prefetch_container|. If there is an existing proxy, then the prefetch is
251 // not eligible.
Hiroshige Hayashizaki692e3eb2025-07-18 21:03:49252 void OnGotProxyLookupResult(CheckEligibilityParams params, bool has_proxy);
Max Currancc1ab0c2022-09-12 22:03:11253
kenoss0c7bbc72024-07-24 08:52:40254 // Called when the eligibility is determined for each fetch of prefetch, i.e.
255 // initial fetch and redirects.
256 //
257 // If ineligible, these methods may convert the prefetch into decoy.
258 //
259 // If the initial fetch (respectively, the redirect) is eligible or the
260 // prefetch is decoy, the prefetch is added to `prefetch_queue_`
261 // (respectively, is retained in the queue) and proceeds to the next fetch.
Hiroshige Hayashizaki692e3eb2025-07-18 21:03:49262 void OnGotEligibilityForNonRedirect(CheckEligibilityParams params,
263 PreloadingEligibility eligibility);
kenoss0c7bbc72024-07-24 08:52:40264 void OnGotEligibilityForRedirect(
kenossf8d9f35a2024-06-25 07:05:37265 net::RedirectInfo redirect_info,
Hiroshige Hayashizaki1ae6168b2023-06-13 18:15:42266 network::mojom::URLResponseHeadPtr redirect_head,
Hiroshige Hayashizaki692e3eb2025-07-18 21:03:49267 CheckEligibilityParams params,
Hiroshige Hayashizaki939c5ed42023-11-01 03:29:21268 PreloadingEligibility eligibility);
Max Curran18a6f2b2022-05-02 23:13:24269
Hiroshige Hayashizaki31484212024-01-30 13:35:21270 // Adds `prefetch_container` to the cache but doesn't initiate prefetching.
Hiroshige Hayashizaki40a2532f2025-03-07 21:42:00271 // Use `AddPrefetchContainerWithHandle()` for non-test cases.
Hiroshige Hayashizaki31484212024-01-30 13:35:21272 void AddPrefetchContainerWithoutStartingPrefetch(
273 std::unique_ptr<PrefetchContainer> prefetch_container);
274
Hiroshige Hayashizaki70db51b2025-07-14 23:09:49275 // Adds to `owned_prefetches_`.
276 void AddPrefetchContainerToOwnedPrefetches(
277 std::unique_ptr<PrefetchContainer> prefetch_container);
278
Max Curran18a6f2b2022-05-02 23:13:24279 // Starts the network requests for as many prefetches in |prefetch_queue_| as
280 // possible.
281 void Prefetch();
282
Adithya Srinivasand5e37cb2023-07-05 14:45:23283 // Pops the first valid prefetch (determined by PrefetchDocumentManager) from
284 // |prefetch_queue_|. Returns a tuple containing the popped prefetch and
285 // (optionally) an already completed prefetch that needs to be evicted to make
286 // space for the new prefetch. If there are no valid prefetches in the queue,
287 // then (nullptr, nullptr) is returned.
288 std::tuple<base::WeakPtr<PrefetchContainer>, base::WeakPtr<PrefetchContainer>>
289 PopNextPrefetchContainer();
Max Curran18a6f2b2022-05-02 23:13:24290
elabadysayedf7d6b00f2025-02-05 11:27:00291 // The prefetch is reset after
292 // `PrefetchContainerDefaultTtlInPrefetchService()`
293 // or the overridden TTL duration. If
294 // `PrefetchContainerDefaultTtlInPrefetchService()` returns a value less than
295 // or equal to zero, the prefetch is kept indefinitely.
Adithya Srinivasand5e37cb2023-07-05 14:45:23296 void OnPrefetchTimeout(base::WeakPtr<PrefetchContainer> prefetch);
Max Curran18a6f2b2022-05-02 23:13:24297
kenoss03cdaca32025-03-28 03:05:14298 // Evict `prefetch_container` before starting a new prefetch.
299 //
300 // Precondition: `prefetch_container` must be valid.
301 void EvictPrefetch(base::WeakPtr<PrefetchContainer> prefetch_container);
302 // Starts the given |prefetch_container|.
303 //
kenoss1b8ebc22025-04-04 00:11:35304 // Returns true iff a prefetch is started and the caller should regard this is
305 // active.
306 //
kenoss03cdaca32025-03-28 03:05:14307 // Precondition: `prefetch_container` must be valid.
kenoss1b8ebc22025-04-04 00:11:35308 bool StartSinglePrefetch(base::WeakPtr<PrefetchContainer> prefetch_container);
Max Curran18a6f2b2022-05-02 23:13:24309
Jeremy Roman45c89d012023-08-30 21:22:02310 // Creates a new URL loader and starts a network request for
311 // |prefetch_container|. |MakePrefetchRequest| must have been previously
312 // called.
313 void SendPrefetchRequest(base::WeakPtr<PrefetchContainer> prefetch_container);
Max Currana84311e2023-05-16 20:40:25314
Max Curran18a6f2b2022-05-02 23:13:24315 // Gets the URL loader for the given |prefetch_container|. If an override was
316 // set by |SetURLLoaderFactoryForTesting|, then that will be returned instead.
Hiroshige Hayashizakie51e2f262025-03-04 23:14:38317 scoped_refptr<network::SharedURLLoaderFactory>
318 GetURLLoaderFactoryForCurrentPrefetch(
Hiroshige Hayashizakib8c4bf602023-05-26 01:34:58319 base::WeakPtr<PrefetchContainer> prefetch_container);
Max Curran18a6f2b2022-05-02 23:13:24320
321 // Called when the request for |prefetch_container| is redirected.
Max Currana84311e2023-05-16 20:40:25322 void OnPrefetchRedirect(base::WeakPtr<PrefetchContainer> prefetch_container,
323 const net::RedirectInfo& redirect_info,
Hiroshige Hayashizaki1ae6168b2023-06-13 18:15:42324 network::mojom::URLResponseHeadPtr redirect_head);
Max Curran5d4da4b42023-03-10 23:41:46325
Max Curran892ca5422022-12-12 20:55:34326 // Called when the response for |prefetch_container| has started. Based on
327 // |head|, returns a status to inform the |PrefetchStreamingURLLoader| whether
Arthur Sonzognic686e8f2024-01-11 08:36:37328 // the prefetch is servable. If servable, then `std::nullopt` will be
Hiroshige Hayashizaki556ac552023-10-24 01:36:32329 // returned, otherwise a failure status is returned.
Arthur Sonzognic686e8f2024-01-11 08:36:37330 std::optional<PrefetchErrorOnResponseReceived> OnPrefetchResponseStarted(
Max Curran892ca5422022-12-12 20:55:34331 base::WeakPtr<PrefetchContainer> prefetch_container,
332 network::mojom::URLResponseHead* head);
333
Hiroshige Hayashizaki70db51b2025-07-14 23:09:49334 // PrefetchContainer::Observer overrides:
335 void OnWillBeDestroyed(PrefetchContainer& prefetch_container) override;
336 void OnGotInitialEligibility(PrefetchContainer& prefetch_container,
337 PreloadingEligibility eligibility) override;
338 void OnDeterminedHead(PrefetchContainer& prefetch_container) override;
339 void OnPrefetchCompletedOrFailed(
340 PrefetchContainer& prefetch_container,
341 const network::URLLoaderCompletionStatus& completion_status,
342 const std::optional<int>& response_code) override;
343
Max Curran7dbdea4d2023-03-21 23:47:37344 // Called when the cookies from |prefetch_conatiner| are read from the
345 // isolated network context and are ready to be written to the default network
346 // context.
Max Curranc4445fc2022-06-02 18:43:43347 void OnGotIsolatedCookiesForCopy(
Hiroshige Hayashizaki16b6e54f2025-08-12 06:56:57348 PrefetchServingHandle serving_handle,
Max Curranc4445fc2022-06-02 18:43:43349 const net::CookieAccessResultList& cookie_list,
350 const net::CookieAccessResultList& excluded_cookies);
351
Liviu Tinta1fe1a6d2023-09-20 19:44:04352 enum class HandlePrefetchContainerResult {
353 // No prefetch was available to be used.
354 kNotAvailable,
355 // There was a prefetch available but it is not usable.
356 kNotUsable,
357 // The prefetch will be served.
358 kToBeServed,
359 // The prefetch cannot be served because Cookies have changed.
360 kNotToBeServedCookiesChanged,
361 // The prefetch's head has not yet been received.
362 kWaitForHead
363 };
364
365 using FallbackToRegularNavigationWhenPrefetchNotUsable = base::StrongAlias<
366 class FallbackToRegularNavigationWhenPrefetchNotUsableTag,
367 bool>;
Max Curran2e83b5d2022-12-29 18:53:38368 // Helper function for |GetPrefetchToServe| to return |prefetch_container| via
Liviu Tinta1fe1a6d2023-09-20 19:44:04369 // |on_prefetch_to_serve_ready| callback in |prefetch_match_resolver|. Starts
370 // the cookie copy process for the given prefetch if needed, and updates its
371 // state.
372 HandlePrefetchContainerResult ReturnPrefetchToServe(
Hiroshige Hayashizakic625e812025-08-19 18:42:35373 const PrefetchKey& key,
Liviu Tinta1fe1a6d2023-09-20 19:44:04374 const GURL& prefetch_url,
Hiroshige Hayashizaki16b6e54f2025-08-12 06:56:57375 PrefetchServingHandle serving_handle,
Liviu Tinta1fe1a6d2023-09-20 19:44:04376 PrefetchMatchResolver& prefetch_match_resolver,
377 FallbackToRegularNavigationWhenPrefetchNotUsable
378 when_prefetch_not_used_fallback_to_regular_navigation =
379 FallbackToRegularNavigationWhenPrefetchNotUsable(true));
Liviu Tintad608e012023-05-10 19:16:41380
kenossf7b4d60d2024-07-16 15:15:08381 // Callback for non-blocking call `PrefetchContainer::StartBlockUntilHead()`.
382 // Waits non-redirect response header for No-Vary-Search to determine a
383 // potentially matching prefetch is a matching prefetch. Corresponds 3.6 in
kenoss5a5ad9802024-06-28 10:29:11384 // https://wicg.github.io/nav-speculation/prefetch.html#wait-for-a-matching-prefetch-record
385 //
Liviu Tintad608e012023-05-10 19:16:41386 // Once we make the decision to use a prefetch, call |PrepareToServe| and
387 // |GetPrefetchToServe| again in order to enforce that prefetches that are
388 // served are served from |prefetches_ready_to_serve_|.
kenossf7b4d60d2024-07-16 15:15:08389 void OnMaybeDeterminedHead(
Hiroshige Hayashizakic625e812025-08-19 18:42:35390 const PrefetchKey& key,
Liviu Tinta4eaa53c22023-08-02 21:01:06391 base::WeakPtr<PrefetchMatchResolver> prefetch_match_resolver,
kenoss6c5fb092024-07-05 05:42:14392 PrefetchContainer& prefetch_container);
Max Curran2e83b5d2022-12-29 18:53:38393
Liviu Tinta4eaa53c22023-08-02 21:01:06394 // Helper function for |GetPrefetchToServe| which handles a
395 // |prefetch_container| that could potentially be served to the navigation.
Liviu Tinta1fe1a6d2023-09-20 19:44:04396 HandlePrefetchContainerResult HandlePrefetchContainerToServe(
Hiroshige Hayashizakic625e812025-08-19 18:42:35397 const PrefetchKey& key,
Liviu Tinta1fe1a6d2023-09-20 19:44:04398 PrefetchContainer& prefetch_container,
Liviu Tinta4eaa53c22023-08-02 21:01:06399 PrefetchMatchResolver& prefetch_match_resolver);
Liviu Tintad608e012023-05-10 19:16:41400
Hiroshige Hayashizakif59d9022023-11-08 00:08:09401 // Checks if there is a prefetch in |owned_prefetches_| with the same URL as
Rakina Zata Amni39d8e7e2022-10-20 18:18:30402 // |prefetch_container| but from a different referring RenderFrameHost.
Max Curran679a3d52022-07-11 23:03:31403 // Records the result to a UMA histogram.
404 void RecordExistingPrefetchWithMatchingURL(
Hiroshige Hayashizaki70db51b2025-07-14 23:09:49405 const PrefetchContainer& prefetch_container) const;
Max Curran679a3d52022-07-11 23:03:31406
kenosse8d8bbb52025-05-13 12:35:04407 // If `should_progress` is true, calls `PrefetchScheduler::ProgressAsync()`
408 // (implicitly). This argument is meaningful only if `UsePrefetchScheduler()`.
Taiyo Mizuhashi94ce74f2025-01-28 04:20:14409 void ResetPrefetchContainer(
kenosse8d8bbb52025-05-13 12:35:04410 base::WeakPtr<PrefetchContainer> prefetch_container,
411 bool should_progress = true);
Taiyo Mizuhashi94ce74f2025-01-28 04:20:14412
kenoss1b8ebc22025-04-04 00:11:35413 // Methods for scheduling
414 void ScheduleAndProgress(base::WeakPtr<PrefetchContainer> prefetch_container);
kenoss0a567362025-05-16 11:18:55415 void ScheduleAndProgressAsync(
kenoss1b8ebc22025-04-04 00:11:35416 base::WeakPtr<PrefetchContainer> prefetch_container);
kenoss0a567362025-05-16 11:18:55417 void ResetPrefetchContainerAndProgressAsync(
418 base::WeakPtr<PrefetchContainer> prefetch_container);
419 void ResetPrefetchContainersAndProgressAsync(
kenoss1b8ebc22025-04-04 00:11:35420 std::vector<base::WeakPtr<PrefetchContainer>> prefetch_containers);
421 // CAUTION: This doesn't call `ResetPrefetchContainer()` to preserve current
422 // behavior.
kenoss0a567362025-05-16 11:18:55423 void RemoveFromSchedulerAndProgressAsync(
424 PrefetchContainer& prefetch_container);
kenoss1b8ebc22025-04-04 00:11:35425
Wayne Jackson Jr.0118d2a2025-02-21 10:53:46426 // Returns `true` if the `prefetch_container` is stale. I.e.
427 // the prefetch either is not or never will be servable to a
428 // navigation.
429 //
430 // Note: This is currently used for WebView initiated prefetches so
431 // consideration should be taken if updating the underlying implementation (or
432 // its dependencies).
433 bool IsPrefetchStale(base::WeakPtr<PrefetchContainer> prefetch_container);
434
kenossf7cea3932025-03-28 03:47:37435 // Returns if the `prefetch_container` is in active set.
436 bool IsPrefetchContainerInActiveSet(
437 const PrefetchContainer& prefetch_container);
438
Hiroshige Hayashizaki3876eee2023-03-27 04:42:04439 void DumpPrefetchesForDebug() const;
440
Hiroshige Hayashizaki72ea9b92025-07-05 02:47:56441 // Wrappers for `owned_prefetches_`. Use these wrappers and do not directly
442 // access `owned_prefetches_`, to avoid accidentally destructing existing
443 // `PrefetchContainer` e.g. by writing to `owned_prefetches_[key]`.
Hiroshige Hayashizakic625e812025-08-19 18:42:35444 const std::map<PrefetchKey, std::unique_ptr<PrefetchContainer>>&
Hiroshige Hayashizaki72ea9b92025-07-05 02:47:56445 owned_prefetches() const {
446 return owned_prefetches_;
447 }
448
Ayu Ishii29af5af2023-11-27 23:13:51449 raw_ptr<BrowserContext> browser_context_;
Max Curran146bf442022-03-28 23:22:14450
Max Curranead64a62022-06-22 01:10:52451 // Delegate provided by embedder that controls specific behavior of |this|.
452 // May be nullptr if embedder doesn't provide a delegate.
453 std::unique_ptr<PrefetchServiceDelegate> delegate_;
454
Max Curran18a6f2b2022-05-02 23:13:24455 // The custom proxy configurator for Prefetch Proxy. Only used on prefetches
456 // that require the proxy.
457 std::unique_ptr<PrefetchProxyConfigurator> prefetch_proxy_configurator_;
458
Max Curran0146f852022-08-01 19:49:33459 // The origin prober class which manages all logic for origin probing.
460 std::unique_ptr<PrefetchOriginProber> origin_prober_;
461
Max Curran18a6f2b2022-05-02 23:13:24462 // A FIFO queue of prefetches that have been confirmed to be eligible but have
463 // not started yet.
kenoss1b8ebc22025-04-04 00:11:35464 //
465 // It is used only if `!UsePrefetchScheduler()`.
466 //
467 // TODO(crbug.com/406754449): Remove it.
Max Curran18a6f2b2022-05-02 23:13:24468 std::vector<base::WeakPtr<PrefetchContainer>> prefetch_queue_;
469
Adithya Srinivasan9d1b6fa2024-08-29 15:04:35470 // Current prefetch with an in-progress request (if any).
kenoss1b8ebc22025-04-04 00:11:35471 //
472 // It is used only if `!UsePrefetchScheduler()`.
473 //
474 // TODO(crbug.com/406754449): Remove it.
Hiroshige Hayashizakic625e812025-08-19 18:42:35475 std::optional<PrefetchKey> active_prefetch_;
Max Curran18a6f2b2022-05-02 23:13:24476
Taiyo Mizuhashi1847c402025-03-04 23:51:09477 // Prefetches owned by `this`. All `PrefetchContainer`s added by
478 // `AddPrefetchContainer*` will be stored here.
Hiroshige Hayashizaki72ea9b92025-07-05 02:47:56479 //
Hiroshige Hayashizaki70db51b2025-07-14 23:09:49480 // `PrefetchContainer`s in `owned_prefetches_` must be always:
481 // - Added by `AddPrefetchContainerToOwnedPrefetches()`.
482 // - Destructed either by:
483 // - `ResetPrefetchContainer()` or
484 // - `~PrefetchService()` dtor.
485 //
Hiroshige Hayashizaki72ea9b92025-07-05 02:47:56486 // Use `owned_prefetches()` wherever possible, to avoid unintentional
487 // destruction of `PrefetchContainer`s in `owned_prefetches_`.
Hiroshige Hayashizaki70db51b2025-07-14 23:09:49488 //
Hiroshige Hayashizaki72ea9b92025-07-05 02:47:56489 // Note that `PrefetchContainer` not added to `owned_prefetches_` can be
490 // destroyed elsewhere even if it has a relevant `PrefetchService` (e.g. in
491 // `PrefetchContainer::MigrateNewlyAdded()`).
Hiroshige Hayashizakic625e812025-08-19 18:42:35492 std::map<PrefetchKey, std::unique_ptr<PrefetchContainer>> owned_prefetches_;
Max Curran18a6f2b2022-05-02 23:13:24493
Adithya Srinivasand5e37cb2023-07-05 14:45:23494// Protects against Prefetch() being called recursively.
495#if DCHECK_IS_ON()
496 bool prefetch_reentrancy_guard_ = false;
497#endif
498
kenoss1b8ebc22025-04-04 00:11:35499 // Manages queue of prefetches, active set, and scheduling.
500 //
501 // It is used only if `UsePrefetchScheduler()`.
502 //
503 // TODO(crbug.com/406754449): Remove the last sentence.
504 std::unique_ptr<PrefetchScheduler> scheduler_;
505
Max Curran18a6f2b2022-05-02 23:13:24506 SEQUENCE_CHECKER(sequence_checker_);
507
Max Curran146bf442022-03-28 23:22:14508 base::WeakPtrFactory<PrefetchService> weak_method_factory_{this};
Max Curran6c2835ea2022-03-07 19:52:38509};
510
511} // namespace content
512
Sreeja Kamishettyf66553a2022-07-14 17:41:27513#endif // CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_SERVICE_H_